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