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 <stdint.h>
20 #include <string.h> // brings strlen, strncpy, and memset into scope.
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>
testMemset()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
TEST(NanoStringsTest,MemsetZeroBytes)53 TEST(NanoStringsTest, MemsetZeroBytes) {
54 testMemset<0>();
55 }
56
TEST(NanoStringsTest,MemsetPartialArray)57 TEST(NanoStringsTest, MemsetPartialArray) {
58 testMemset<(kMemsetBufferLen / 2) - 1>();
59 }
60
TEST(NanoStringsTest,MemsetFullArray)61 TEST(NanoStringsTest, MemsetFullArray) {
62 testMemset<kMemsetBufferLen>();
63 }
64
65 static constexpr size_t kMemcpyBufferLen = 8;
66 static constexpr uint8_t kMemcpySrc[kMemcpyBufferLen] = {
67 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
68
69 template <size_t kLenToCopy>
testMemcpy()70 static void testMemcpy() {
71 uint8_t expected[arrayLength(kMemcpySrc)];
72 uint8_t actual[arrayLength(expected)];
73
74 static_assert(kLenToCopy <= arrayLength(kMemcpySrc), "Bad test invocation");
75
76 ::memset(expected, kUnsetValue, sizeof(expected));
77 ::memset(actual, kUnsetValue, sizeof(actual));
78
79 ::memcpy(expected, kMemcpySrc, kLenToCopy);
80 nanoapp_testing::memcpy(actual, kMemcpySrc, kLenToCopy);
81
82 EXPECT_EQ(0, memcmp(expected, actual, sizeof(expected)));
83 }
84
TEST(NanoStringsTest,MemcpyZeroBytes)85 TEST(NanoStringsTest, MemcpyZeroBytes) {
86 testMemcpy<0>();
87 }
88
TEST(NanoStringsTest,MemcpyPartialArray)89 TEST(NanoStringsTest, MemcpyPartialArray) {
90 testMemcpy<(kMemcpyBufferLen / 2) - 1>();
91 }
92
TEST(NanoStringsTest,MemcpyFullArray)93 TEST(NanoStringsTest, MemcpyFullArray) {
94 testMemcpy<kMemcpyBufferLen>();
95 }
96
TEST(NanoStringsTest,StrlenEmptyString)97 TEST(NanoStringsTest, StrlenEmptyString) {
98 const char *str = "";
99 EXPECT_EQ(::strlen(str), nanoapp_testing::strlen(str));
100 }
101
TEST(NanoStringsTest,StrlenNormal)102 TEST(NanoStringsTest, StrlenNormal) {
103 const char *str = "random string\n";
104 EXPECT_EQ(::strlen(str), nanoapp_testing::strlen(str));
105 }
106
107 static constexpr size_t kStrncpyMax = 10;
108 static constexpr char kShortString[] = "short";
109 static constexpr char kLongString[] = "Kind of long string";
110 static constexpr char kExactString[] = "0123456789";
111
testStrncpy(const char * str,size_t len)112 static void testStrncpy(const char *str, size_t len) {
113 char expected[kStrncpyMax];
114 char actual[arrayLength(expected)];
115
116 ::memset(expected, kUnsetValue, sizeof(expected));
117 ::memset(actual, kUnsetValue, sizeof(actual));
118
119 ::strncpy(expected, str, len);
120 nanoapp_testing::strncpy(actual, str, len);
121
122 EXPECT_EQ(0, memcmp(expected, actual, sizeof(expected)));
123 }
124
TEST(NanoStringsTest,Strncpy)125 TEST(NanoStringsTest, Strncpy) {
126 testStrncpy(kShortString, ::strlen(kShortString));
127 }
128
TEST(NanoStringsTest,StrncpySetsTrailingBytes)129 TEST(NanoStringsTest, StrncpySetsTrailingBytes) {
130 ASSERT_LT(::strlen(kShortString), kStrncpyMax);
131 testStrncpy(kShortString, kStrncpyMax);
132 }
133
TEST(NanoStringsTest,StrncpyMax)134 TEST(NanoStringsTest, StrncpyMax) {
135 ASSERT_GT(::strlen(kLongString), kStrncpyMax);
136 testStrncpy(kLongString, kStrncpyMax);
137 }
138
TEST(NanoStringsTest,StrncpyNothing)139 TEST(NanoStringsTest, StrncpyNothing) {
140 testStrncpy(kLongString, 0);
141 }
142
TEST(NanoStringsTest,StrncpyExactFit)143 TEST(NanoStringsTest, StrncpyExactFit) {
144 ASSERT_EQ(::strlen(kExactString), kStrncpyMax);
145 testStrncpy(kExactString, kStrncpyMax);
146 }
147
testHexAscii(uint32_t value,const char * str)148 static void testHexAscii(uint32_t value, const char *str) {
149 static constexpr size_t kAsciiLen =
150 nanoapp_testing::kUint32ToHexAsciiBufferMinLen;
151
152 char array[kAsciiLen + 1];
153 array[kAsciiLen] = kUnsetValue;
154 uint32ToHexAscii(array, sizeof(array), value);
155 EXPECT_EQ(kUnsetValue, array[kAsciiLen]);
156 array[kAsciiLen] = '\0';
157 EXPECT_STREQ(str, array);
158 }
159
TEST(NanoStringsTest,Uint32ToHexAscii)160 TEST(NanoStringsTest, Uint32ToHexAscii) {
161 testHexAscii(0x1234ABCD, "0x1234ABCD");
162 }
163
TEST(NanoStringsTest,Uint32ToHexAsciiMin)164 TEST(NanoStringsTest, Uint32ToHexAsciiMin) {
165 testHexAscii(0, "0x00000000");
166 }
167
TEST(NanoStringsTest,Uint32ToHexAsciiMax)168 TEST(NanoStringsTest, Uint32ToHexAsciiMax) {
169 testHexAscii(0xFFFFFFFF, "0xFFFFFFFF");
170 }
171