1 /*
2  * Copyright 2019 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 "common/blocking_queue.h"
18 
19 #include <gtest/gtest.h>
20 
21 #include <thread>
22 
23 namespace bluetooth {
24 namespace common {
25 namespace {
26 class BlockingQueueTest : public ::testing::Test {
27 protected:
SetUp()28   void SetUp() override { EXPECT_TRUE(queue_.empty()); }
29 
30   // Postcondition for each test case: clear the blocking queue
TearDown()31   void TearDown() override { EXPECT_TRUE(queue_.empty()); }
32 
33   BlockingQueue<int> queue_;
34 };
35 
TEST_F(BlockingQueueTest,initial_empty)36 TEST_F(BlockingQueueTest, initial_empty) { EXPECT_TRUE(queue_.empty()); }
37 
TEST_F(BlockingQueueTest,same_thread_push_and_pop)38 TEST_F(BlockingQueueTest, same_thread_push_and_pop) {
39   int data = 1;
40   queue_.push(data);
41   EXPECT_FALSE(queue_.empty());
42   EXPECT_EQ(queue_.take(), data);
43   EXPECT_TRUE(queue_.empty());
44 }
45 
TEST_F(BlockingQueueTest,same_thread_push_and_pop_sequential)46 TEST_F(BlockingQueueTest, same_thread_push_and_pop_sequential) {
47   for (int data = 0; data < 10; data++) {
48     queue_.push(data);
49     EXPECT_FALSE(queue_.empty());
50     EXPECT_EQ(queue_.take(), data);
51     EXPECT_TRUE(queue_.empty());
52   }
53 }
54 
TEST_F(BlockingQueueTest,same_thread_push_and_pop_batch)55 TEST_F(BlockingQueueTest, same_thread_push_and_pop_batch) {
56   for (int data = 0; data < 10; data++) {
57     queue_.push(data);
58   }
59   EXPECT_FALSE(queue_.empty());
60   for (int data = 0; data < 10; data++) {
61     EXPECT_EQ(queue_.take(), data);
62   }
63   EXPECT_TRUE(queue_.empty());
64 }
65 
TEST_F(BlockingQueueTest,clear_queue)66 TEST_F(BlockingQueueTest, clear_queue) {
67   for (int data = 0; data < 10; data++) {
68     queue_.push(data);
69   }
70   EXPECT_FALSE(queue_.empty());
71   queue_.clear();
72   EXPECT_TRUE(queue_.empty());
73 }
74 
TEST_F(BlockingQueueTest,wait_for_non_empty)75 TEST_F(BlockingQueueTest, wait_for_non_empty) {
76   int data = 1;
77   std::thread waiter_thread([this, data] { EXPECT_EQ(queue_.take(), data); });
78   queue_.push(data);
79   waiter_thread.join();
80   EXPECT_TRUE(queue_.empty());
81 }
82 
TEST_F(BlockingQueueTest,wait_to_take_fail)83 TEST_F(BlockingQueueTest, wait_to_take_fail) {
84   EXPECT_FALSE(queue_.wait_to_take(std::chrono::milliseconds(3)));
85 }
86 
TEST_F(BlockingQueueTest,wait_to_take_after_non_empty)87 TEST_F(BlockingQueueTest, wait_to_take_after_non_empty) {
88   int data = 1;
89   queue_.push(data);
90   EXPECT_TRUE(queue_.wait_to_take(std::chrono::milliseconds(3)));
91   queue_.clear();
92 }
93 
TEST_F(BlockingQueueTest,wait_to_take_before_non_empty)94 TEST_F(BlockingQueueTest, wait_to_take_before_non_empty) {
95   int data = 1;
96   std::thread waiter_thread(
97           [this] { EXPECT_TRUE(queue_.wait_to_take(std::chrono::milliseconds(3))); });
98   queue_.push(data);
99   waiter_thread.join();
100   queue_.clear();
101 }
102 
TEST_F(BlockingQueueTest,wait_for_non_empty_batch)103 TEST_F(BlockingQueueTest, wait_for_non_empty_batch) {
104   std::thread waiter_thread([this] {
105     for (int data = 0; data < 10; data++) {
106       EXPECT_EQ(queue_.take(), data);
107     }
108   });
109   for (int data = 0; data < 10; data++) {
110     queue_.push(data);
111   }
112   waiter_thread.join();
113   EXPECT_TRUE(queue_.empty());
114 }
115 
116 class VectorBlockingQueueTest : public ::testing::Test {
117 protected:
SetUp()118   void SetUp() override { EXPECT_TRUE(queue_.empty()); }
119 
120   // Postcondition for each test case: clear the blocking queue
TearDown()121   void TearDown() override { EXPECT_TRUE(queue_.empty()); }
122 
123   BlockingQueue<std::vector<uint8_t>> queue_;
124 };
125 
TEST_F(VectorBlockingQueueTest,same_thread_push_and_pop)126 TEST_F(VectorBlockingQueueTest, same_thread_push_and_pop) {
127   std::vector<uint8_t> data = {1, 2, 3, 4, 5, 6};
128   queue_.push(data);
129   EXPECT_FALSE(queue_.empty());
130   EXPECT_EQ(queue_.take(), data);
131   EXPECT_TRUE(queue_.empty());
132 }
133 
134 }  // namespace
135 }  // namespace common
136 }  // namespace bluetooth
137