1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <shared/nano_string.h> 18 19 #include <string.h> // brings strlen, strncpy, and memset into scope. 20 #include <stdint.h> 21 22 #include <gtest/gtest.h> 23 #include <shared/array_length.h> 24 25 // This "using directive" intentionally makes the symbols 'strlen', 'strncpy', 26 // and 'memset' "ambigious" at this point. This means that every use of these 27 // needs to be fully qualified in our tests below. That's as desired for 28 // clarity and to avoid accidentally invoking the wrong version. 29 // Note that a leading bare "::" is the fully qualified version of the 30 // C library methods. 31 using namespace nanoapp_testing; 32 33 static constexpr size_t kMemsetBufferLen = 16; 34 static constexpr int kUnsetValue = 0x5F; 35 static constexpr int kNewValue = 0xB8; 36 37 template<size_t kLenToSet> 38 static void testMemset() { 39 uint8_t expected[kMemsetBufferLen]; 40 uint8_t actual[arrayLength(expected)]; 41 42 static_assert(kLenToSet <= arrayLength(expected), "Bad test invocation"); 43 44 ::memset(expected, kUnsetValue, sizeof(expected)); 45 ::memset(actual, kUnsetValue, sizeof(actual)); 46 47 ::memset(expected, kNewValue, kLenToSet); 48 nanoapp_testing::memset(actual, kNewValue, kLenToSet); 49 50 EXPECT_EQ(0, memcmp(expected, actual, sizeof(expected))); 51 } 52 53 TEST(NanoStringsTest, MemsetZeroBytes) { 54 testMemset<0>(); 55 } 56 57 TEST(NanoStringsTest, MemsetPartialArray) { 58 testMemset<(kMemsetBufferLen / 2) - 1>(); 59 } 60 61 TEST(NanoStringsTest, MemsetFullArray) { 62 testMemset<kMemsetBufferLen>(); 63 } 64 65 66 static constexpr size_t kMemcpyBufferLen = 8; 67 static constexpr uint8_t kMemcpySrc[kMemcpyBufferLen] = { 68 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; 69 70 template<size_t kLenToCopy> 71 static void testMemcpy() { 72 uint8_t expected[arrayLength(kMemcpySrc)]; 73 uint8_t actual[arrayLength(expected)]; 74 75 static_assert(kLenToCopy <= arrayLength(kMemcpySrc), "Bad test invocation"); 76 77 ::memset(expected, kUnsetValue, sizeof(expected)); 78 ::memset(actual, kUnsetValue, sizeof(actual)); 79 80 ::memcpy(expected, kMemcpySrc, kLenToCopy); 81 nanoapp_testing::memcpy(actual, kMemcpySrc, kLenToCopy); 82 83 EXPECT_EQ(0, memcmp(expected, actual, sizeof(expected))); 84 } 85 86 TEST(NanoStringsTest, MemcpyZeroBytes) { 87 testMemcpy<0>(); 88 } 89 90 TEST(NanoStringsTest, MemcpyPartialArray) { 91 testMemcpy<(kMemcpyBufferLen / 2) - 1>(); 92 } 93 94 TEST(NanoStringsTest, MemcpyFullArray) { 95 testMemcpy<kMemcpyBufferLen>(); 96 } 97 98 99 TEST(NanoStringsTest, StrlenEmptyString) { 100 const char *str = ""; 101 EXPECT_EQ(::strlen(str), nanoapp_testing::strlen(str)); 102 } 103 104 TEST(NanoStringsTest, StrlenNormal) { 105 const char *str = "random string\n"; 106 EXPECT_EQ(::strlen(str), nanoapp_testing::strlen(str)); 107 } 108 109 static constexpr size_t kStrncpyMax = 10; 110 static constexpr char kShortString[] = "short"; 111 static constexpr char kLongString[] = "Kind of long string"; 112 static constexpr char kExactString[] = "0123456789"; 113 114 static void testStrncpy(const char *str, size_t len) { 115 char expected[kStrncpyMax]; 116 char actual[arrayLength(expected)]; 117 118 ::memset(expected, kUnsetValue, sizeof(expected)); 119 ::memset(actual, kUnsetValue, sizeof(actual)); 120 121 ::strncpy(expected, str, len); 122 nanoapp_testing::strncpy(actual, str, len); 123 124 EXPECT_EQ(0, memcmp(expected, actual, sizeof(expected))); 125 } 126 127 TEST(NanoStringsTest, Strncpy) { 128 testStrncpy(kShortString, ::strlen(kShortString)); 129 } 130 131 TEST(NanoStringsTest, StrncpySetsTrailingBytes) { 132 ASSERT_LT(::strlen(kShortString), kStrncpyMax); 133 testStrncpy(kShortString, kStrncpyMax); 134 } 135 136 TEST(NanoStringsTest, StrncpyMax) { 137 ASSERT_GT(::strlen(kLongString), kStrncpyMax); 138 testStrncpy(kLongString, kStrncpyMax); 139 } 140 141 TEST(NanoStringsTest, StrncpyNothing) { 142 testStrncpy(kLongString, 0); 143 } 144 145 TEST(NanoStringsTest, StrncpyExactFit) { 146 ASSERT_EQ(::strlen(kExactString), kStrncpyMax); 147 testStrncpy(kExactString, kStrncpyMax); 148 } 149 150 151 static void testHexAscii(uint32_t value, const char *str) { 152 static constexpr size_t kAsciiLen = 153 nanoapp_testing::kUint32ToHexAsciiBufferMinLen; 154 155 char array[kAsciiLen + 1]; 156 array[kAsciiLen] = kUnsetValue; 157 uint32ToHexAscii(array, sizeof(array), value); 158 EXPECT_EQ(kUnsetValue, array[kAsciiLen]); 159 array[kAsciiLen] = '\0'; 160 EXPECT_STREQ(str, array); 161 } 162 163 TEST(NanoStringsTest, Uint32ToHexAscii) { 164 testHexAscii(0x1234ABCD, "0x1234ABCD"); 165 } 166 167 TEST(NanoStringsTest, Uint32ToHexAsciiMin) { 168 testHexAscii(0, "0x00000000"); 169 } 170 171 TEST(NanoStringsTest, Uint32ToHexAsciiMax) { 172 testHexAscii(0xFFFFFFFF, "0xFFFFFFFF"); 173 } 174 175