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