• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "chre/util/array_queue.h"
18 #include "gtest/gtest.h"
19 
20 #include <algorithm>
21 #include <type_traits>
22 #include <vector>
23 
24 using chre::ArrayQueue;
25 using chre::ArrayQueueExt;
26 
27 namespace {
28 constexpr int kMaxTestCapacity = 10;
29 int destructor_count[kMaxTestCapacity];
30 int constructor_count;
31 int total_destructor_count;
32 
33 class FakeElement {
34  public:
FakeElement()35   FakeElement() {
36     constructor_count++;
37   };
FakeElement(int i)38   FakeElement(int i) {
39     val_ = i;
40     constructor_count++;
41   };
~FakeElement()42   ~FakeElement() {
43     total_destructor_count++;
44     if (val_ >= 0 && val_ < kMaxTestCapacity) {
45       destructor_count[val_]++;
46     }
47   };
setValue(int i)48   void setValue(int i) {
49     val_ = i;
50   }
51 
52  private:
53   int val_ = kMaxTestCapacity - 1;
54 };
55 }  // namespace
56 
TEST(ArrayQueueTest,IsEmptyInitially)57 TEST(ArrayQueueTest, IsEmptyInitially) {
58   ArrayQueue<int, 4> q;
59   EXPECT_TRUE(q.empty());
60   EXPECT_EQ(0, q.size());
61 }
62 
TEST(ArrayQueueTest,SimplePushPop)63 TEST(ArrayQueueTest, SimplePushPop) {
64   ArrayQueue<int, 3> q;
65   EXPECT_TRUE(q.push(1));
66   EXPECT_TRUE(q.push(2));
67   q.pop();
68   EXPECT_TRUE(q.push(3));
69 }
70 
TEST(ArrayQueueTest,SimplePushPopBackPush)71 TEST(ArrayQueueTest, SimplePushPopBackPush) {
72   ArrayQueue<int, 3> q;
73   EXPECT_TRUE(q.push(0));
74   EXPECT_TRUE(q.push(1));
75   EXPECT_TRUE(q.push(2));
76   q.pop_back();
77   EXPECT_EQ(2, q.size());
78   EXPECT_EQ(0, q[0]);
79   EXPECT_EQ(1, q[1]);
80 
81   EXPECT_TRUE(q.push(3));
82   EXPECT_EQ(3, q.size());
83   EXPECT_EQ(0, q[0]);
84   EXPECT_EQ(1, q[1]);
85   EXPECT_EQ(3, q[2]);
86 
87   q.pop_back();
88   q.pop_back();
89   q.pop_back();
90 
91   EXPECT_EQ(0, q.size());
92   EXPECT_TRUE(q.push(4));
93   EXPECT_TRUE(q.push(5));
94   EXPECT_TRUE(q.push(6));
95   EXPECT_EQ(3, q.size());
96   EXPECT_EQ(4, q[0]);
97   EXPECT_EQ(5, q[1]);
98   EXPECT_EQ(6, q[2]);
99 
100   q.pop();
101 
102   EXPECT_TRUE(q.push(7));
103   EXPECT_EQ(5, q[0]);
104   EXPECT_EQ(6, q[1]);
105   EXPECT_EQ(7, q[2]);
106 }
107 
TEST(ArrayQueueTest,TestSize)108 TEST(ArrayQueueTest, TestSize) {
109   ArrayQueue<int, 2> q;
110   q.push(1);
111   EXPECT_EQ(1, q.size());
112   q.push(2);
113   EXPECT_EQ(2, q.size());
114   q.pop();
115   EXPECT_EQ(1, q.size());
116   q.pop();
117 }
118 
TEST(ArrayQueueTest,TestEmpty)119 TEST(ArrayQueueTest, TestEmpty) {
120   ArrayQueue<int, 2> q;
121   q.push(1);
122   EXPECT_FALSE(q.empty());
123   q.push(2);
124   EXPECT_FALSE(q.empty());
125   q.pop();
126   EXPECT_FALSE(q.empty());
127   q.pop();
128   EXPECT_TRUE(q.empty());
129 }
130 
TEST(ArrayQueueTest,KickPushWhenNotFull)131 TEST(ArrayQueueTest, KickPushWhenNotFull) {
132   ArrayQueue<int, 2> q;
133   q.kick_push(1);
134   EXPECT_EQ(1, q.size());
135   EXPECT_EQ(1, q[0]);
136   q.kick_push(2);
137   EXPECT_EQ(2, q.size());
138   EXPECT_EQ(2, q[1]);
139 }
140 
TEST(ArrayQueueTest,KickPushWhenFull)141 TEST(ArrayQueueTest, KickPushWhenFull) {
142   ArrayQueue<int, 2> q;
143   q.kick_push(1);
144   q.push(2);
145   EXPECT_EQ(2, q.size());
146   q.kick_push(3);
147   EXPECT_EQ(2, q.size());
148   EXPECT_EQ(2, q[0]);
149   EXPECT_EQ(3, q[1]);
150 }
151 
TEST(ArrayQueueTest,PopWhenEmpty)152 TEST(ArrayQueueTest, PopWhenEmpty) {
153   ArrayQueue<int, 4> q;
154   q.pop();
155   EXPECT_EQ(0, q.size());
156 }
157 
TEST(ArrayQueueTest,PopBackWhenEmpty)158 TEST(ArrayQueueTest, PopBackWhenEmpty) {
159   ArrayQueue<int, 4> q;
160   q.pop_back();
161   EXPECT_EQ(0, q.size());
162 }
163 
TEST(ArrayQueueTest,PushWhenFull)164 TEST(ArrayQueueTest, PushWhenFull) {
165   ArrayQueue<int, 2> q;
166   q.push(1);
167   q.push(2);
168   EXPECT_FALSE(q.push(3));
169 }
170 
TEST(ArrayQueueDeathTest,FrontWhenEmpty)171 TEST(ArrayQueueDeathTest, FrontWhenEmpty) {
172   ArrayQueue<int, 4> q;
173   EXPECT_DEATH(q.front(), "");
174 }
175 
TEST(ArrayQueueDeathTest,BackWhenEmpty)176 TEST(ArrayQueueDeathTest, BackWhenEmpty) {
177   ArrayQueue<int, 4> q;
178   EXPECT_DEATH(q.back(), "");
179 }
180 
TEST(ArrayQueueTest,TestFront)181 TEST(ArrayQueueTest, TestFront) {
182   ArrayQueue<int, 3> q;
183   q.push(1);
184   EXPECT_EQ(1, q.front());
185   q.pop();
186   q.push(2);
187   EXPECT_EQ(2, q.front());
188   q.push(3);
189   EXPECT_EQ(2, q.front());
190 }
191 
TEST(ArrayQueueTest,TestBack)192 TEST(ArrayQueueTest, TestBack) {
193   ArrayQueue<int, 3> q;
194   q.push(1);
195   EXPECT_EQ(1, q.back());
196   q.pop();
197   q.push(2);
198   EXPECT_EQ(2, q.back());
199   q.push(3);
200   EXPECT_EQ(3, q.back());
201 }
202 
TEST(ArrayQueueDeathTest,InvalidSubscript)203 TEST(ArrayQueueDeathTest, InvalidSubscript) {
204   ArrayQueue<int, 2> q;
205   EXPECT_DEATH(q[0], "");
206 }
207 
TEST(ArrayQueueTest,Subscript)208 TEST(ArrayQueueTest, Subscript) {
209   ArrayQueue<int, 2> q;
210   q.push(1);
211   q.push(2);
212   EXPECT_EQ(1, q[0]);
213   EXPECT_EQ(2, q[1]);
214   q.pop();
215   EXPECT_EQ(2, q[0]);
216 }
217 
TEST(ArrayQueueTest,RemoveWithInvalidIndex)218 TEST(ArrayQueueTest, RemoveWithInvalidIndex) {
219   ArrayQueue<int, 3> q;
220   EXPECT_FALSE(q.remove(0));
221 }
222 
TEST(ArrayQueueTest,RemoveWithIndex)223 TEST(ArrayQueueTest, RemoveWithIndex) {
224   ArrayQueue<int, 3> q;
225   q.push(1);
226   q.push(2);
227   q.remove(0);
228   EXPECT_EQ(2, q.front());
229   EXPECT_EQ(1, q.size());
230   q.push(3);
231   q.remove(1);
232   EXPECT_EQ(2, q.front());
233   EXPECT_EQ(1, q.size());
234 }
235 
TEST(ArrayQueueTest,DestructorCalledOnPop)236 TEST(ArrayQueueTest, DestructorCalledOnPop) {
237   for (size_t i = 0; i < kMaxTestCapacity; ++i) {
238     destructor_count[i] = 0;
239   }
240 
241   ArrayQueue<FakeElement, 3> q;
242   FakeElement e;
243   q.push(e);
244   q.push(e);
245 
246   q.front().setValue(0);
247   q.pop();
248   EXPECT_EQ(1, destructor_count[0]);
249 
250   q.front().setValue(1);
251   q.pop();
252   EXPECT_EQ(1, destructor_count[1]);
253 }
254 
TEST(ArrayQueueTest,ElementsDestructedWhenQueueDestructed)255 TEST(ArrayQueueTest, ElementsDestructedWhenQueueDestructed) {
256   for (size_t i = 0; i < kMaxTestCapacity; ++i) {
257     destructor_count[i] = 0;
258   }
259 
260   // Put q and e in the scope so their destructor will be called going
261   // out of scope.
262   {
263     ArrayQueue<FakeElement, 4> q;
264     FakeElement e;
265 
266     for (size_t i = 0; i < 3; ++i) {
267       q.push(e);
268       q[i].setValue(i);
269     }
270   }
271 
272   // q should now be destroyed - check destructor count.
273   for (size_t i = 0; i < 3; ++i) {
274     EXPECT_EQ(1, destructor_count[i]);
275   }
276   EXPECT_EQ(0, destructor_count[3]);
277   EXPECT_EQ(1, destructor_count[kMaxTestCapacity - 1]);
278 }
279 
TEST(ArrayQueueTest,EmplaceTest)280 TEST(ArrayQueueTest, EmplaceTest) {
281   constructor_count = 0;
282   ArrayQueue<FakeElement, 2> q;
283 
284   EXPECT_TRUE(q.emplace(0));
285   EXPECT_EQ(1, constructor_count);
286   EXPECT_EQ(1, q.size());
287 
288   EXPECT_TRUE(q.emplace(1));
289   EXPECT_EQ(2, constructor_count);
290   EXPECT_EQ(2, q.size());
291 
292   EXPECT_FALSE(q.emplace(2));
293   EXPECT_EQ(2, constructor_count);
294   EXPECT_EQ(2, q.size());
295 }
296 
TEST(ArrayQueueTest,EmptyQueueIterator)297 TEST(ArrayQueueTest, EmptyQueueIterator) {
298   ArrayQueue<int, 4> q;
299 
300   ArrayQueue<int, 4>::iterator it = q.begin();
301   EXPECT_TRUE(it == q.end());
302   EXPECT_FALSE(it != q.end());
303 }
304 
TEST(ArrayQueueTest,SimpleIterator)305 TEST(ArrayQueueTest, SimpleIterator) {
306   ArrayQueue<int, 4> q;
307   for (size_t i = 0; i < 3; ++i) {
308     q.push(i);
309   }
310   EXPECT_NE(q.begin(), q.end());
311 
312   size_t index = 0;
313   for (ArrayQueue<int, 4>::iterator it = q.begin(); it != q.end(); ++it) {
314     EXPECT_EQ(q[index++], *it);
315   }
316   index = 0;
317   for (ArrayQueue<int, 4>::iterator it = q.begin(); it != q.end(); it++) {
318     EXPECT_EQ(q[index++], *it);
319   }
320 
321   index = 0;
322   ArrayQueue<int, 4>::iterator it = q.begin();
323   while (it != q.end()) {
324     EXPECT_EQ(q[index++], *it++);
325   }
326 
327   for (size_t i = 0; i < 3; ++i) {
328     q.pop();
329     q.push(i + 3);
330   }
331 
332   index = 0;
333   it = q.begin();
334   while (it != q.end()) {
335     EXPECT_EQ(q[index++], *it++);
336   }
337 
338   // Iterator concept checks: default constructible, copy assignable, copy
339   // constructible
340   ArrayQueue<int, 4>::iterator it2;
341   it2 = it;
342   EXPECT_EQ(it, it2);
343 
344   ArrayQueue<int, 4>::iterator it3(it);
345   EXPECT_EQ(it, it3);
346 }
347 
TEST(ArrayQueueTest,IteratorSwap)348 TEST(ArrayQueueTest, IteratorSwap) {
349   ArrayQueue<int, 2> q;
350   q.push(1);
351   q.push(2);
352 
353   auto it1 = q.begin(), it2 = q.end();
354   std::swap(it1, it2);
355   EXPECT_EQ(it1, q.end());
356   EXPECT_EQ(it2, q.begin());
357 }
358 
TEST(ArrayQueueTest,IteratorAndPush)359 TEST(ArrayQueueTest, IteratorAndPush) {
360   ArrayQueue<int, 4> q;
361   for (size_t i = 0; i < 2; ++i) {
362     q.push(i);
363   }
364 
365   ArrayQueue<int, 4>::iterator it_b = q.begin();
366   ArrayQueue<int, 4>::iterator it_e = q.end();
367   q.push(3);
368 
369   size_t index = 0;
370   while (it_b != it_e) {
371     EXPECT_EQ(q[index++], *it_b++);
372   }
373 }
374 
TEST(ArrayQueueTest,IteratorAndPop)375 TEST(ArrayQueueTest, IteratorAndPop) {
376   ArrayQueue<int, 4> q;
377   for (size_t i = 0; i < 3; ++i) {
378     q.push(i);
379   }
380 
381   ArrayQueue<int, 4>::iterator it_b = q.begin();
382   q.pop();
383   it_b++;
384 
385   for (size_t i = 0; i < 2; ++i) {
386     EXPECT_EQ(q[i], *it_b++);
387   }
388 }
389 
TEST(ArrayQueueTest,IteratorAndRemove)390 TEST(ArrayQueueTest, IteratorAndRemove) {
391   ArrayQueue<int, 4> q;
392   for (size_t i = 0; i < 2; ++i) {
393     q.push(i);
394   }
395 
396   ArrayQueue<int, 4>::iterator it_b = q.begin();
397   q.remove(1);
398 
399   EXPECT_EQ(q[0], *it_b);
400 }
401 
TEST(ArrayQueueTest,IteratorAndEmplace)402 TEST(ArrayQueueTest, IteratorAndEmplace) {
403   ArrayQueue<int, 4> q;
404   for (size_t i = 0; i < 2; ++i) {
405     q.push(i);
406   }
407 
408   ArrayQueue<int, 4>::iterator it_b = q.begin();
409   ArrayQueue<int, 4>::iterator it_e = q.end();
410   q.emplace(3);
411 
412   size_t index = 0;
413   while (it_b != it_e) {
414     EXPECT_EQ(q[index++], *it_b++);
415   }
416 }
417 
TEST(ArrayQueueTest,SimpleConstIterator)418 TEST(ArrayQueueTest, SimpleConstIterator) {
419   ArrayQueue<int, 4> q;
420   for (size_t i = 0; i < 3; ++i) {
421     q.push(i);
422   }
423 
424   size_t index = 0;
425   for (ArrayQueue<int, 4>::const_iterator cit = q.cbegin(); cit != q.cend();
426        ++cit) {
427     EXPECT_EQ(q[index++], *cit);
428   }
429 
430   index = 0;
431   ArrayQueue<int, 4>::const_iterator cit = q.cbegin();
432   while (cit != q.cend()) {
433     EXPECT_EQ(q[index++], *cit++);
434   }
435 
436   for (size_t i = 0; i < 3; ++i) {
437     q.pop();
438     q.push(i + 3);
439   }
440 
441   index = 0;
442   cit = q.cbegin();
443   while (cit != q.cend()) {
444     EXPECT_EQ(q[index++], *cit++);
445   }
446 }
447 
TEST(ArrayQueueTest,Full)448 TEST(ArrayQueueTest, Full) {
449   ArrayQueue<size_t, 4> q;
450   for (size_t i = 0; i < 4; i++) {
451     EXPECT_FALSE(q.full());
452     q.push(i);
453   }
454 
455   EXPECT_TRUE(q.full());
456 }
457 
TEST(ArrayQueueTest,ArrayCopy)458 TEST(ArrayQueueTest, ArrayCopy) {
459   constexpr size_t kSize = 8;
460   ArrayQueue<size_t, kSize> q;
461   std::vector<size_t> v;
462   v.resize(kSize);
463 
464   for (size_t i = 0; i < kSize; i++) {
465     q.push(i);
466 
467     v.assign(kSize, 0xdeadbeef);
468     std::copy(q.begin(), q.end(), v.begin());
469 
470     for (size_t j = 0; j < i; j++) {
471       EXPECT_EQ(q[j], v[j]);
472       EXPECT_EQ(*std::next(q.begin(), j), v[j]);
473     }
474   }
475 }
476 
TEST(ArrayQueueTest,IteratorTraits)477 TEST(ArrayQueueTest, IteratorTraits) {
478   ArrayQueue<int, 2> q;
479   q.push(1234);
480   q.push(5678);
481 
482   using traits = std::iterator_traits<decltype(q)::iterator>;
483   typename traits::difference_type diff = std::distance(q.begin(), q.end());
484   EXPECT_EQ(diff, q.size());
485 
486   typename traits::value_type v = *q.begin();
487   EXPECT_EQ(v, q[0]);
488 
489   typename traits::reference r = *q.begin();
490   r = 999;
491   EXPECT_EQ(r, q[0]);
492 
493   typename traits::pointer p = &r;
494   EXPECT_EQ(*p, q[0]);
495 
496   // Note: if the implementation is upgraded to another category like random
497   // access, then this static assert should be updated. It exists primarily to
498   // confirm that we are declaring an iterator_category
499   static_assert(
500       std::is_same<traits::iterator_category, std::forward_iterator_tag>::value,
501       "ArrayQueueIterator should be a forward iterator");
502 }
503 
TEST(ArrayQueueTest,ArrayClear)504 TEST(ArrayQueueTest, ArrayClear) {
505   ArrayQueue<size_t, 4> q;
506 
507   q.clear();
508   EXPECT_TRUE(q.empty());
509 
510   for (size_t i = 0; i < 4; i++) {
511     q.push(i);
512   }
513 
514   q.clear();
515   EXPECT_TRUE(q.empty());
516 
517   // Make sure that insertion/access still work after a clear.
518   for (size_t i = 0; i < 4; i++) {
519     q.push(i);
520   }
521   for (size_t i = 0; i < 4; i++) {
522     EXPECT_EQ(q[i], i);
523   }
524 }
525 
TEST(ArrayQueueTest,ElementsDestructedArrayClear)526 TEST(ArrayQueueTest, ElementsDestructedArrayClear) {
527   for (size_t i = 0; i < kMaxTestCapacity; ++i) {
528     destructor_count[i] = 0;
529   }
530   total_destructor_count = 0;
531 
532   ArrayQueue<FakeElement, 4> q;
533   for (size_t i = 0; i < 3; ++i) {
534     q.emplace(i);
535   }
536 
537   q.clear();
538 
539   for (size_t i = 0; i < 3; ++i) {
540     EXPECT_EQ(1, destructor_count[i]);
541   }
542   EXPECT_EQ(3, total_destructor_count);
543 }
544 
TEST(ArrayQueueExtTest,BasicTest)545 TEST(ArrayQueueExtTest, BasicTest) {
546   constexpr size_t kNumElements = 32;
547   int32_t array[kNumElements];
548   ArrayQueueExt<int32_t> q(array, kNumElements);
549 
550   ASSERT_EQ(q.data(), array);
551   EXPECT_EQ(q.capacity(), kNumElements);
552 
553   for (int i = 0; i < kNumElements; i++) {
554     q.push(i);
555   }
556 
557   for (int i = 0; i < kNumElements; i++) {
558     EXPECT_EQ(array[i], q[i]);
559   }
560 }
561