1 #include "util-inl.h"
2 #include "debug_utils-inl.h"
3 #include "env-inl.h"
4 #include "gtest/gtest.h"
5
6 using node::Calloc;
7 using node::Malloc;
8 using node::MaybeStackBuffer;
9 using node::SPrintF;
10 using node::StringEqualNoCase;
11 using node::StringEqualNoCaseN;
12 using node::ToLower;
13 using node::UncheckedCalloc;
14 using node::UncheckedMalloc;
15
TEST(UtilTest,ListHead)16 TEST(UtilTest, ListHead) {
17 struct Item { node::ListNode<Item> node_; };
18 typedef node::ListHead<Item, &Item::node_> List;
19
20 List list;
21 EXPECT_TRUE(list.IsEmpty());
22
23 Item one;
24 EXPECT_TRUE(one.node_.IsEmpty());
25
26 list.PushBack(&one);
27 EXPECT_FALSE(list.IsEmpty());
28 EXPECT_FALSE(one.node_.IsEmpty());
29
30 {
31 List::Iterator it = list.begin();
32 EXPECT_NE(list.end(), it);
33 EXPECT_EQ(&one, *it);
34 ++it;
35 EXPECT_FALSE(it != list.end()); // Iterator only implements != operator.
36 }
37
38 Item two;
39 list.PushBack(&two);
40
41 {
42 List::Iterator it = list.begin();
43 EXPECT_NE(list.end(), it);
44 EXPECT_EQ(&one, *it);
45 ++it;
46 EXPECT_NE(list.end(), it);
47 EXPECT_EQ(&two, *it);
48 ++it;
49 EXPECT_FALSE(it != list.end()); // Iterator only implements != operator.
50 }
51
52 EXPECT_EQ(&one, list.PopFront());
53 EXPECT_TRUE(one.node_.IsEmpty());
54 EXPECT_FALSE(list.IsEmpty());
55
56 {
57 List::Iterator it = list.begin();
58 EXPECT_NE(list.end(), it);
59 EXPECT_EQ(&two, *it);
60 ++it;
61 EXPECT_FALSE(it != list.end()); // Iterator only implements != operator.
62 }
63
64 EXPECT_EQ(&two, list.PopFront());
65 EXPECT_TRUE(two.node_.IsEmpty());
66 EXPECT_TRUE(list.IsEmpty());
67 EXPECT_FALSE(list.begin() != list.end());
68 }
69
TEST(UtilTest,StringEqualNoCase)70 TEST(UtilTest, StringEqualNoCase) {
71 EXPECT_FALSE(StringEqualNoCase("a", "b"));
72 EXPECT_TRUE(StringEqualNoCase("", ""));
73 EXPECT_TRUE(StringEqualNoCase("equal", "equal"));
74 EXPECT_TRUE(StringEqualNoCase("equal", "EQUAL"));
75 EXPECT_TRUE(StringEqualNoCase("EQUAL", "EQUAL"));
76 EXPECT_FALSE(StringEqualNoCase("equal", "equals"));
77 EXPECT_FALSE(StringEqualNoCase("equals", "equal"));
78 }
79
TEST(UtilTest,StringEqualNoCaseN)80 TEST(UtilTest, StringEqualNoCaseN) {
81 EXPECT_FALSE(StringEqualNoCaseN("a", "b", strlen("a")));
82 EXPECT_TRUE(StringEqualNoCaseN("", "", strlen("")));
83 EXPECT_TRUE(StringEqualNoCaseN("equal", "equal", strlen("equal")));
84 EXPECT_TRUE(StringEqualNoCaseN("equal", "EQUAL", strlen("equal")));
85 EXPECT_TRUE(StringEqualNoCaseN("EQUAL", "EQUAL", strlen("equal")));
86 EXPECT_TRUE(StringEqualNoCaseN("equal", "equals", strlen("equal")));
87 EXPECT_FALSE(StringEqualNoCaseN("equal", "equals", strlen("equals")));
88 EXPECT_TRUE(StringEqualNoCaseN("equals", "equal", strlen("equal")));
89 EXPECT_FALSE(StringEqualNoCaseN("equals", "equal", strlen("equals")));
90 EXPECT_TRUE(StringEqualNoCaseN("abc\0abc", "abc\0efg", strlen("abcdefgh")));
91 EXPECT_FALSE(StringEqualNoCaseN("abc\0abc", "abcd\0efg", strlen("abcdefgh")));
92 }
93
TEST(UtilTest,ToLower)94 TEST(UtilTest, ToLower) {
95 EXPECT_EQ('0', ToLower('0'));
96 EXPECT_EQ('a', ToLower('a'));
97 EXPECT_EQ('a', ToLower('A'));
98 }
99
100 #define TEST_AND_FREE(expression) \
101 do { \
102 auto pointer = expression; \
103 EXPECT_NE(nullptr, pointer); \
104 free(pointer); \
105 } while (0)
106
TEST(UtilTest,Malloc)107 TEST(UtilTest, Malloc) {
108 TEST_AND_FREE(Malloc<char>(0));
109 TEST_AND_FREE(Malloc<char>(1));
110 TEST_AND_FREE(Malloc(0));
111 TEST_AND_FREE(Malloc(1));
112 }
113
TEST(UtilTest,Calloc)114 TEST(UtilTest, Calloc) {
115 TEST_AND_FREE(Calloc<char>(0));
116 TEST_AND_FREE(Calloc<char>(1));
117 TEST_AND_FREE(Calloc(0));
118 TEST_AND_FREE(Calloc(1));
119 }
120
TEST(UtilTest,UncheckedMalloc)121 TEST(UtilTest, UncheckedMalloc) {
122 TEST_AND_FREE(UncheckedMalloc<char>(0));
123 TEST_AND_FREE(UncheckedMalloc<char>(1));
124 TEST_AND_FREE(UncheckedMalloc(0));
125 TEST_AND_FREE(UncheckedMalloc(1));
126 }
127
TEST(UtilTest,UncheckedCalloc)128 TEST(UtilTest, UncheckedCalloc) {
129 TEST_AND_FREE(UncheckedCalloc<char>(0));
130 TEST_AND_FREE(UncheckedCalloc<char>(1));
131 TEST_AND_FREE(UncheckedCalloc(0));
132 TEST_AND_FREE(UncheckedCalloc(1));
133 }
134
135 template <typename T>
MaybeStackBufferBasic()136 static void MaybeStackBufferBasic() {
137 MaybeStackBuffer<T> buf;
138 size_t old_length;
139 size_t old_capacity;
140
141 // Default constructor.
142 EXPECT_EQ(0U, buf.length());
143 EXPECT_FALSE(buf.IsAllocated());
144 EXPECT_GT(buf.capacity(), buf.length());
145
146 // SetLength() expansion.
147 buf.SetLength(buf.capacity());
148 EXPECT_EQ(buf.capacity(), buf.length());
149 EXPECT_FALSE(buf.IsAllocated());
150
151 // Means of accessing raw buffer.
152 EXPECT_EQ(buf.out(), *buf);
153 EXPECT_EQ(&buf[0], *buf);
154
155 // Basic I/O.
156 for (size_t i = 0; i < buf.length(); i++)
157 buf[i] = static_cast<T>(i);
158 for (size_t i = 0; i < buf.length(); i++)
159 EXPECT_EQ(static_cast<T>(i), buf[i]);
160
161 // SetLengthAndZeroTerminate().
162 buf.SetLengthAndZeroTerminate(buf.capacity() - 1);
163 EXPECT_EQ(buf.capacity() - 1, buf.length());
164 for (size_t i = 0; i < buf.length(); i++)
165 EXPECT_EQ(static_cast<T>(i), buf[i]);
166 buf.SetLength(buf.capacity());
167 EXPECT_EQ(0, buf[buf.length() - 1]);
168
169 // Initial Realloc.
170 old_length = buf.length() - 1;
171 old_capacity = buf.capacity();
172 buf.AllocateSufficientStorage(buf.capacity() * 2);
173 EXPECT_EQ(buf.capacity(), buf.length());
174 EXPECT_TRUE(buf.IsAllocated());
175 for (size_t i = 0; i < old_length; i++)
176 EXPECT_EQ(static_cast<T>(i), buf[i]);
177 EXPECT_EQ(0, buf[old_length]);
178
179 // SetLength() reduction and expansion.
180 for (size_t i = 0; i < buf.length(); i++)
181 buf[i] = static_cast<T>(i);
182 buf.SetLength(10);
183 for (size_t i = 0; i < buf.length(); i++)
184 EXPECT_EQ(static_cast<T>(i), buf[i]);
185 buf.SetLength(buf.capacity());
186 for (size_t i = 0; i < buf.length(); i++)
187 EXPECT_EQ(static_cast<T>(i), buf[i]);
188
189 // Subsequent Realloc.
190 old_length = buf.length();
191 old_capacity = buf.capacity();
192 buf.AllocateSufficientStorage(old_capacity * 1.5);
193 EXPECT_EQ(buf.capacity(), buf.length());
194 EXPECT_EQ(static_cast<size_t>(old_capacity * 1.5), buf.length());
195 EXPECT_TRUE(buf.IsAllocated());
196 for (size_t i = 0; i < old_length; i++)
197 EXPECT_EQ(static_cast<T>(i), buf[i]);
198
199 // Basic I/O on Realloc'd buffer.
200 for (size_t i = 0; i < buf.length(); i++)
201 buf[i] = static_cast<T>(i);
202 for (size_t i = 0; i < buf.length(); i++)
203 EXPECT_EQ(static_cast<T>(i), buf[i]);
204
205 // Release().
206 T* rawbuf = buf.out();
207 buf.Release();
208 EXPECT_EQ(0U, buf.length());
209 EXPECT_FALSE(buf.IsAllocated());
210 EXPECT_GT(buf.capacity(), buf.length());
211 free(rawbuf);
212 }
213
TEST(UtilTest,MaybeStackBuffer)214 TEST(UtilTest, MaybeStackBuffer) {
215 MaybeStackBufferBasic<uint8_t>();
216 MaybeStackBufferBasic<uint16_t>();
217
218 // Constructor with size parameter.
219 {
220 MaybeStackBuffer<unsigned char> buf(100);
221 EXPECT_EQ(100U, buf.length());
222 EXPECT_FALSE(buf.IsAllocated());
223 EXPECT_GT(buf.capacity(), buf.length());
224 buf.SetLength(buf.capacity());
225 EXPECT_EQ(buf.capacity(), buf.length());
226 EXPECT_FALSE(buf.IsAllocated());
227 for (size_t i = 0; i < buf.length(); i++)
228 buf[i] = static_cast<unsigned char>(i);
229 for (size_t i = 0; i < buf.length(); i++)
230 EXPECT_EQ(static_cast<unsigned char>(i), buf[i]);
231
232 MaybeStackBuffer<unsigned char> bigbuf(10000);
233 EXPECT_EQ(10000U, bigbuf.length());
234 EXPECT_TRUE(bigbuf.IsAllocated());
235 EXPECT_EQ(bigbuf.length(), bigbuf.capacity());
236 for (size_t i = 0; i < bigbuf.length(); i++)
237 bigbuf[i] = static_cast<unsigned char>(i);
238 for (size_t i = 0; i < bigbuf.length(); i++)
239 EXPECT_EQ(static_cast<unsigned char>(i), bigbuf[i]);
240 }
241
242 // Invalidated buffer.
243 {
244 MaybeStackBuffer<char> buf;
245 buf.Invalidate();
246 EXPECT_TRUE(buf.IsInvalidated());
247 EXPECT_FALSE(buf.IsAllocated());
248 EXPECT_EQ(0U, buf.length());
249 EXPECT_EQ(0U, buf.capacity());
250 buf.Invalidate();
251 EXPECT_TRUE(buf.IsInvalidated());
252 }
253 }
254
TEST(UtilTest,SPrintF)255 TEST(UtilTest, SPrintF) {
256 // %d, %u and %s all do the same thing. The actual C++ type is used to infer
257 // the right representation.
258 EXPECT_EQ(SPrintF("%s", false), "false");
259 EXPECT_EQ(SPrintF("%s", true), "true");
260 EXPECT_EQ(SPrintF("%d", true), "true");
261 EXPECT_EQ(SPrintF("%u", true), "true");
262 EXPECT_EQ(SPrintF("%d", 10000000000LL), "10000000000");
263 EXPECT_EQ(SPrintF("%d", -10000000000LL), "-10000000000");
264 EXPECT_EQ(SPrintF("%u", 10000000000LL), "10000000000");
265 EXPECT_EQ(SPrintF("%u", -10000000000LL), "-10000000000");
266 EXPECT_EQ(SPrintF("%i", 10), "10");
267 EXPECT_EQ(SPrintF("%d", 10), "10");
268 EXPECT_EQ(SPrintF("%x", 15), "f");
269 EXPECT_EQ(SPrintF("%x", 16), "10");
270 EXPECT_EQ(SPrintF("%X", 15), "F");
271 EXPECT_EQ(SPrintF("%X", 16), "10");
272 EXPECT_EQ(SPrintF("%o", 7), "7");
273 EXPECT_EQ(SPrintF("%o", 8), "10");
274
275 EXPECT_EQ(atof(SPrintF("%s", 0.5).c_str()), 0.5);
276 EXPECT_EQ(atof(SPrintF("%s", -0.5).c_str()), -0.5);
277
278 void (*fn)() = []() {};
279 void* p = reinterpret_cast<void*>(&fn);
280 EXPECT_GE(SPrintF("%p", fn).size(), 4u);
281 EXPECT_GE(SPrintF("%p", p).size(), 4u);
282
283 const std::string foo = "foo";
284 const char* bar = "bar";
285 EXPECT_EQ(SPrintF("%s %s", foo, "bar"), "foo bar");
286 EXPECT_EQ(SPrintF("%s %s", foo, bar), "foo bar");
287 EXPECT_EQ(SPrintF("%s", nullptr), "(null)");
288
289 EXPECT_EQ(SPrintF("[%% %s %%]", foo), "[% foo %]");
290
291 struct HasToString {
292 std::string ToString() const {
293 return "meow";
294 }
295 };
296 EXPECT_EQ(SPrintF("%s", HasToString{}), "meow");
297
298 const std::string with_zero = std::string("a") + '\0' + 'b';
299 EXPECT_EQ(SPrintF("%s", with_zero), with_zero);
300 }
301