1 /******************************************************************************
2  *
3  *  Copyright (C) 2016 Google, Inc.
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 #include <gmock/gmock.h>
19 #include <gtest/gtest.h>
20 
21 #include <base/logging.h>
22 
23 #include "osi/include/leaky_bonded_queue.h"
24 
25 namespace testing {
26 
27 using system_bt_osi::LeakyBondedQueue;
28 
29 #define ITEM_EQ(a, b)              \
30   do {                             \
31     EXPECT_EQ(a, b);               \
32     EXPECT_EQ(a->index, b->index); \
33   } while (0)
34 
35 class Item {
36  public:
Item(int i)37   Item(int i) { index = i; }
~Item()38   virtual ~Item() {}
39   int index;
40 };
41 
42 class MockItem : public Item {
43  public:
MockItem(int i)44   MockItem(int i) : Item(i) {}
~MockItem()45   ~MockItem() { Destruct(); }
46   MOCK_METHOD0(Destruct, void());
47 };
48 
TEST(LeakyBondedQueueTest,TestEnqueueDequeue)49 TEST(LeakyBondedQueueTest, TestEnqueueDequeue) {
50   MockItem* item1 = new MockItem(1);
51   MockItem* item2 = new MockItem(2);
52   MockItem* item3 = new MockItem(3);
53   MockItem* item4 = new MockItem(4);
54   LeakyBondedQueue<MockItem>* queue = new LeakyBondedQueue<MockItem>(3);
55   EXPECT_EQ(queue->Capacity(), static_cast<size_t>(3));
56   EXPECT_EQ(queue->Length(), static_cast<size_t>(0));
57   queue->Enqueue(item1);
58   EXPECT_EQ(queue->Length(), static_cast<size_t>(1));
59   queue->Enqueue(item2);
60   EXPECT_EQ(queue->Length(), static_cast<size_t>(2));
61   queue->Enqueue(item3);
62   EXPECT_EQ(queue->Length(), static_cast<size_t>(3));
63   EXPECT_CALL(*item1, Destruct()).Times(1);
64   queue->Enqueue(item4);
65   EXPECT_EQ(queue->Length(), static_cast<size_t>(3));
66   MockItem* item2_2 = queue->Dequeue();
67   MockItem* item3_3 = queue->Dequeue();
68   MockItem* item4_4 = queue->Dequeue();
69   EXPECT_THAT(item2_2, NotNull());
70   ITEM_EQ(item2_2, item2);
71   EXPECT_THAT(item3_3, NotNull());
72   ITEM_EQ(item3_3, item3);
73   EXPECT_THAT(item4_4, NotNull());
74   ITEM_EQ(item4_4, item4);
75   LOG(INFO) << "All done release items";
76   EXPECT_CALL(*item2_2, Destruct()).Times(1);
77   delete item2_2;
78   EXPECT_CALL(*item3_3, Destruct()).Times(1);
79   delete item3_3;
80   EXPECT_CALL(*item4_4, Destruct()).Times(1);
81   delete item4_4;
82   delete queue;
83 }
84 
TEST(LeakyBondedQueueTest,TestEnqueueDequeue2)85 TEST(LeakyBondedQueueTest, TestEnqueueDequeue2) {
86   MockItem* item1 = new MockItem(1);
87   MockItem* item2 = new MockItem(2);
88   MockItem* item3 = new MockItem(3);
89   MockItem* item4 = new MockItem(4);
90   LeakyBondedQueue<MockItem>* queue = new LeakyBondedQueue<MockItem>(2);
91   EXPECT_EQ(queue->Capacity(), static_cast<size_t>(2));
92   EXPECT_EQ(queue->Length(), static_cast<size_t>(0));
93   queue->Enqueue(item1);
94   EXPECT_EQ(queue->Length(), static_cast<size_t>(1));
95   MockItem* item1_1 = queue->Dequeue();
96   ITEM_EQ(item1, item1_1);
97   EXPECT_EQ(queue->Length(), static_cast<size_t>(0));
98   queue->Enqueue(item2);
99   EXPECT_EQ(queue->Length(), static_cast<size_t>(1));
100   queue->Enqueue(item3);
101   EXPECT_EQ(queue->Length(), static_cast<size_t>(2));
102   EXPECT_CALL(*item2, Destruct()).Times(1);
103   queue->Enqueue(item4);
104   EXPECT_EQ(queue->Length(), static_cast<size_t>(2));
105   EXPECT_CALL(*item3, Destruct()).Times(1);
106   queue->Enqueue(item1);
107   EXPECT_EQ(queue->Length(), static_cast<size_t>(2));
108   MockItem* item4_4_4 = queue->Dequeue();
109   MockItem* item1_1_1 = queue->Dequeue();
110   ITEM_EQ(item4_4_4, item4);
111   ITEM_EQ(item1_1_1, item1);
112   EXPECT_CALL(*item1_1_1, Destruct()).Times(1);
113   delete item1_1_1;
114   EXPECT_CALL(*item4_4_4, Destruct()).Times(1);
115   delete item4_4_4;
116   delete queue;
117 }
118 
TEST(LeakyBondedQueueTest,TestEnqueuePop)119 TEST(LeakyBondedQueueTest, TestEnqueuePop) {
120   MockItem* item1 = new MockItem(1);
121   MockItem* item2 = new MockItem(2);
122   MockItem* item3 = new MockItem(3);
123   MockItem* item4 = new MockItem(4);
124   LeakyBondedQueue<MockItem>* queue = new LeakyBondedQueue<MockItem>(2);
125   EXPECT_EQ(queue->Capacity(), static_cast<size_t>(2));
126   EXPECT_EQ(queue->Length(), static_cast<size_t>(0));
127   queue->Enqueue(item1);
128   EXPECT_EQ(queue->Length(), static_cast<size_t>(1));
129   MockItem* item1_1 = queue->Dequeue();
130   ITEM_EQ(item1, item1_1);
131   EXPECT_EQ(queue->Length(), static_cast<size_t>(0));
132   queue->Enqueue(item2);
133   EXPECT_EQ(queue->Length(), static_cast<size_t>(1));
134   queue->Enqueue(item3);
135   EXPECT_EQ(queue->Length(), static_cast<size_t>(2));
136   MockItem* item2_2 = queue->EnqueueWithPop(item4);
137   EXPECT_THAT(item2_2, NotNull());
138   ITEM_EQ(item2_2, item2);
139   EXPECT_CALL(*item2, Destruct()).Times(1);
140   delete item2_2;
141   EXPECT_EQ(queue->Length(), static_cast<size_t>(2));
142   MockItem* item3_3 = queue->EnqueueWithPop(item1);
143   EXPECT_THAT(item3_3, NotNull());
144   ITEM_EQ(item3_3, item3);
145   EXPECT_CALL(*item3, Destruct()).Times(1);
146   delete item3_3;
147   EXPECT_EQ(queue->Length(), static_cast<size_t>(2));
148   MockItem* item4_4_4 = queue->Dequeue();
149   MockItem* item1_1_1 = queue->Dequeue();
150   ITEM_EQ(item4_4_4, item4);
151   ITEM_EQ(item1_1_1, item1);
152   EXPECT_CALL(*item1_1_1, Destruct()).Times(1);
153   delete item1_1_1;
154   EXPECT_CALL(*item4_4_4, Destruct()).Times(1);
155   delete item4_4_4;
156   delete queue;
157 }
158 
TEST(LeakyBondedQueueTest,TestQueueClear)159 TEST(LeakyBondedQueueTest, TestQueueClear) {
160   MockItem* item1 = new MockItem(1);
161   MockItem* item2 = new MockItem(2);
162   MockItem* item3 = new MockItem(3);
163   MockItem* item4 = new MockItem(4);
164   LeakyBondedQueue<MockItem>* queue = new LeakyBondedQueue<MockItem>(2);
165   EXPECT_EQ(queue->Capacity(), static_cast<size_t>(2));
166   EXPECT_EQ(queue->Length(), static_cast<size_t>(0));
167   queue->Enqueue(item1);
168   EXPECT_EQ(queue->Length(), static_cast<size_t>(1));
169   MockItem* item1_1 = queue->Dequeue();
170   ITEM_EQ(item1, item1_1);
171   EXPECT_EQ(queue->Length(), static_cast<size_t>(0));
172   queue->Enqueue(item2);
173   EXPECT_EQ(queue->Length(), static_cast<size_t>(1));
174   queue->Enqueue(item3);
175   EXPECT_EQ(queue->Length(), static_cast<size_t>(2));
176   EXPECT_CALL(*item2, Destruct()).Times(1);
177   queue->Enqueue(item4);
178   EXPECT_EQ(queue->Length(), static_cast<size_t>(2));
179   EXPECT_CALL(*item3, Destruct()).Times(1);
180   queue->Enqueue(item1);
181   EXPECT_EQ(queue->Length(), static_cast<size_t>(2));
182   EXPECT_CALL(*item1, Destruct()).Times(1);
183   EXPECT_CALL(*item4, Destruct()).Times(1);
184   queue->Clear();
185   delete queue;
186 }
187 
TEST(LeakyBondedQueueTest,TestQueueFree)188 TEST(LeakyBondedQueueTest, TestQueueFree) {
189   MockItem* item1 = new MockItem(1);
190   MockItem* item2 = new MockItem(2);
191   MockItem* item3 = new MockItem(3);
192   MockItem* item4 = new MockItem(4);
193   LeakyBondedQueue<MockItem>* queue = new LeakyBondedQueue<MockItem>(2);
194   EXPECT_EQ(queue->Capacity(), static_cast<size_t>(2));
195   EXPECT_EQ(queue->Length(), static_cast<size_t>(0));
196   queue->Enqueue(item1);
197   EXPECT_EQ(queue->Length(), static_cast<size_t>(1));
198   MockItem* item1_1 = queue->Dequeue();
199   ITEM_EQ(item1, item1_1);
200   EXPECT_EQ(queue->Length(), static_cast<size_t>(0));
201   queue->Enqueue(item2);
202   EXPECT_EQ(queue->Length(), static_cast<size_t>(1));
203   queue->Enqueue(item3);
204   EXPECT_EQ(queue->Length(), static_cast<size_t>(2));
205   EXPECT_CALL(*item2, Destruct()).Times(1);
206   queue->Enqueue(item4);
207   EXPECT_EQ(queue->Length(), static_cast<size_t>(2));
208   EXPECT_CALL(*item3, Destruct()).Times(1);
209   queue->Enqueue(item1);
210   EXPECT_EQ(queue->Length(), static_cast<size_t>(2));
211   EXPECT_CALL(*item1, Destruct()).Times(1);
212   EXPECT_CALL(*item4, Destruct()).Times(1);
213   delete queue;
214 }
215 
TEST(LeakyBondedQueueTest,TestPushNull)216 TEST(LeakyBondedQueueTest, TestPushNull) {
217   MockItem* item1 = nullptr;
218   LeakyBondedQueue<MockItem>* queue = new LeakyBondedQueue<MockItem>(2);
219   queue->Enqueue(item1);
220   MockItem* item1_1 = queue->Dequeue();
221   EXPECT_THAT(item1_1, IsNull());
222 }
223 
TEST(LeakyBondedQueueTest,TestPushNullOverflowQueue)224 TEST(LeakyBondedQueueTest, TestPushNullOverflowQueue) {
225   MockItem* item1 = nullptr;
226   MockItem* item2 = nullptr;
227   LeakyBondedQueue<MockItem>* queue = new LeakyBondedQueue<MockItem>(1);
228   queue->Enqueue(item1);
229   queue->Enqueue(item2);
230   MockItem* item2_2 = queue->Dequeue();
231   EXPECT_THAT(item2_2, IsNull());
232 }
233 
TEST(LeakyBondedQueueTest,TestPushNullDeleteQueue)234 TEST(LeakyBondedQueueTest, TestPushNullDeleteQueue) {
235   MockItem* item1 = nullptr;
236   MockItem* item2 = nullptr;
237   LeakyBondedQueue<MockItem>* queue = new LeakyBondedQueue<MockItem>(2);
238   queue->Enqueue(item1);
239   queue->Enqueue(item2);
240   delete queue;
241 }
242 }
243