1 /*
2 * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "test/pc/e2e/analyzer/video/multi_reader_queue.h"
12
13 #include "absl/types/optional.h"
14 #include "test/gtest.h"
15
16 namespace webrtc {
17 namespace {
18
TEST(MultiReaderQueueTest,EmptyQueueEmptyForAllHeads)19 TEST(MultiReaderQueueTest, EmptyQueueEmptyForAllHeads) {
20 MultiReaderQueue<int> queue = MultiReaderQueue<int>(/*readers_count=*/10);
21 EXPECT_EQ(queue.size(), 0lu);
22 for (int i = 0; i < 10; ++i) {
23 EXPECT_TRUE(queue.IsEmpty(/*reader=*/i));
24 EXPECT_EQ(queue.size(/*reader=*/i), 0lu);
25 EXPECT_FALSE(queue.PopFront(/*reader=*/i).has_value());
26 EXPECT_FALSE(queue.Front(/*reader=*/i).has_value());
27 }
28 }
29
TEST(MultiReaderQueueTest,SizeIsEqualForAllHeadsAfterAddOnly)30 TEST(MultiReaderQueueTest, SizeIsEqualForAllHeadsAfterAddOnly) {
31 MultiReaderQueue<int> queue = MultiReaderQueue<int>(/*readers_count=*/10);
32 queue.PushBack(1);
33 queue.PushBack(2);
34 queue.PushBack(3);
35 EXPECT_EQ(queue.size(), 3lu);
36 for (int i = 0; i < 10; ++i) {
37 EXPECT_FALSE(queue.IsEmpty(/*reader=*/i));
38 EXPECT_EQ(queue.size(/*reader=*/i), 3lu);
39 }
40 }
41
TEST(MultiReaderQueueTest,SizeIsCorrectAfterRemoveFromOnlyOneHead)42 TEST(MultiReaderQueueTest, SizeIsCorrectAfterRemoveFromOnlyOneHead) {
43 MultiReaderQueue<int> queue = MultiReaderQueue<int>(/*readers_count=*/10);
44 for (int i = 0; i < 5; ++i) {
45 queue.PushBack(i);
46 }
47 EXPECT_EQ(queue.size(), 5lu);
48 // Removing elements from queue #0
49 for (int i = 0; i < 5; ++i) {
50 EXPECT_EQ(queue.size(/*reader=*/0), static_cast<size_t>(5 - i));
51 EXPECT_EQ(queue.PopFront(/*reader=*/0), absl::optional<int>(i));
52 for (int j = 1; j < 10; ++j) {
53 EXPECT_EQ(queue.size(/*reader=*/j), 5lu);
54 }
55 }
56 EXPECT_EQ(queue.size(/*reader=*/0), 0lu);
57 EXPECT_TRUE(queue.IsEmpty(/*reader=*/0));
58 }
59
TEST(MultiReaderQueueTest,SingleHeadOneAddOneRemove)60 TEST(MultiReaderQueueTest, SingleHeadOneAddOneRemove) {
61 MultiReaderQueue<int> queue = MultiReaderQueue<int>(/*readers_count=*/1);
62 queue.PushBack(1);
63 EXPECT_EQ(queue.size(), 1lu);
64 EXPECT_TRUE(queue.Front(/*reader=*/0).has_value());
65 EXPECT_EQ(queue.Front(/*reader=*/0).value(), 1);
66 absl::optional<int> value = queue.PopFront(/*reader=*/0);
67 EXPECT_TRUE(value.has_value());
68 EXPECT_EQ(value.value(), 1);
69 EXPECT_EQ(queue.size(), 0lu);
70 EXPECT_TRUE(queue.IsEmpty(/*reader=*/0));
71 }
72
TEST(MultiReaderQueueTest,SingleHead)73 TEST(MultiReaderQueueTest, SingleHead) {
74 MultiReaderQueue<size_t> queue =
75 MultiReaderQueue<size_t>(/*readers_count=*/1);
76 for (size_t i = 0; i < 10; ++i) {
77 queue.PushBack(i);
78 EXPECT_EQ(queue.size(), i + 1);
79 }
80 for (size_t i = 0; i < 10; ++i) {
81 EXPECT_EQ(queue.Front(/*reader=*/0), absl::optional<size_t>(i));
82 EXPECT_EQ(queue.PopFront(/*reader=*/0), absl::optional<size_t>(i));
83 EXPECT_EQ(queue.size(), 10 - i - 1);
84 }
85 }
86
TEST(MultiReaderQueueTest,ThreeHeadsAddAllRemoveAllPerHead)87 TEST(MultiReaderQueueTest, ThreeHeadsAddAllRemoveAllPerHead) {
88 MultiReaderQueue<size_t> queue =
89 MultiReaderQueue<size_t>(/*readers_count=*/3);
90 for (size_t i = 0; i < 10; ++i) {
91 queue.PushBack(i);
92 EXPECT_EQ(queue.size(), i + 1);
93 }
94 for (size_t i = 0; i < 10; ++i) {
95 absl::optional<size_t> value = queue.PopFront(/*reader=*/0);
96 EXPECT_EQ(queue.size(), 10lu);
97 ASSERT_TRUE(value.has_value());
98 EXPECT_EQ(value.value(), i);
99 }
100 for (size_t i = 0; i < 10; ++i) {
101 absl::optional<size_t> value = queue.PopFront(/*reader=*/1);
102 EXPECT_EQ(queue.size(), 10lu);
103 ASSERT_TRUE(value.has_value());
104 EXPECT_EQ(value.value(), i);
105 }
106 for (size_t i = 0; i < 10; ++i) {
107 absl::optional<size_t> value = queue.PopFront(/*reader=*/2);
108 EXPECT_EQ(queue.size(), 10 - i - 1);
109 ASSERT_TRUE(value.has_value());
110 EXPECT_EQ(value.value(), i);
111 }
112 }
113
TEST(MultiReaderQueueTest,ThreeHeadsAddAllRemoveAll)114 TEST(MultiReaderQueueTest, ThreeHeadsAddAllRemoveAll) {
115 MultiReaderQueue<size_t> queue =
116 MultiReaderQueue<size_t>(/*readers_count=*/3);
117 for (size_t i = 0; i < 10; ++i) {
118 queue.PushBack(i);
119 EXPECT_EQ(queue.size(), i + 1);
120 }
121 for (size_t i = 0; i < 10; ++i) {
122 absl::optional<size_t> value1 = queue.PopFront(/*reader=*/0);
123 absl::optional<size_t> value2 = queue.PopFront(/*reader=*/1);
124 absl::optional<size_t> value3 = queue.PopFront(/*reader=*/2);
125 EXPECT_EQ(queue.size(), 10 - i - 1);
126 ASSERT_TRUE(value1.has_value());
127 ASSERT_TRUE(value2.has_value());
128 ASSERT_TRUE(value3.has_value());
129 EXPECT_EQ(value1.value(), i);
130 EXPECT_EQ(value2.value(), i);
131 EXPECT_EQ(value3.value(), i);
132 }
133 }
134
TEST(MultiReaderQueueTest,AddReaderSeeElementsOnlyFromReaderToCopy)135 TEST(MultiReaderQueueTest, AddReaderSeeElementsOnlyFromReaderToCopy) {
136 MultiReaderQueue<size_t> queue =
137 MultiReaderQueue<size_t>(/*readers_count=*/2);
138 for (size_t i = 0; i < 10; ++i) {
139 queue.PushBack(i);
140 }
141 for (size_t i = 0; i < 5; ++i) {
142 queue.PopFront(0);
143 }
144
145 queue.AddReader(/*reader=*/2, /*reader_to_copy=*/0);
146
147 EXPECT_EQ(queue.readers_count(), 3lu);
148 for (size_t i = 5; i < 10; ++i) {
149 absl::optional<size_t> value = queue.PopFront(/*reader=*/2);
150 EXPECT_EQ(queue.size(/*reader=*/2), 10 - i - 1);
151 ASSERT_TRUE(value.has_value());
152 EXPECT_EQ(value.value(), i);
153 }
154 }
155
TEST(MultiReaderQueueTest,AddReaderWithoutReaderToCopySeeFullQueue)156 TEST(MultiReaderQueueTest, AddReaderWithoutReaderToCopySeeFullQueue) {
157 MultiReaderQueue<size_t> queue =
158 MultiReaderQueue<size_t>(/*readers_count=*/2);
159 for (size_t i = 0; i < 10; ++i) {
160 queue.PushBack(i);
161 }
162 for (size_t i = 0; i < 5; ++i) {
163 queue.PopFront(/*reader=*/0);
164 }
165
166 queue.AddReader(/*reader=*/2);
167
168 EXPECT_EQ(queue.readers_count(), 3lu);
169 for (size_t i = 0; i < 10; ++i) {
170 absl::optional<size_t> value = queue.PopFront(/*reader=*/2);
171 EXPECT_EQ(queue.size(/*reader=*/2), 10 - i - 1);
172 ASSERT_TRUE(value.has_value());
173 EXPECT_EQ(value.value(), i);
174 }
175 }
176
TEST(MultiReaderQueueTest,RemoveReaderWontChangeOthers)177 TEST(MultiReaderQueueTest, RemoveReaderWontChangeOthers) {
178 MultiReaderQueue<size_t> queue =
179 MultiReaderQueue<size_t>(/*readers_count=*/2);
180 for (size_t i = 0; i < 10; ++i) {
181 queue.PushBack(i);
182 }
183 EXPECT_EQ(queue.size(/*reader=*/1), 10lu);
184
185 queue.RemoveReader(0);
186
187 EXPECT_EQ(queue.readers_count(), 1lu);
188 EXPECT_EQ(queue.size(/*reader=*/1), 10lu);
189 }
190
TEST(MultiReaderQueueTest,RemoveLastReaderMakesQueueEmpty)191 TEST(MultiReaderQueueTest, RemoveLastReaderMakesQueueEmpty) {
192 MultiReaderQueue<size_t> queue =
193 MultiReaderQueue<size_t>(/*readers_count=*/1);
194 for (size_t i = 0; i < 10; ++i) {
195 queue.PushBack(i);
196 }
197 EXPECT_EQ(queue.size(), 10lu);
198
199 queue.RemoveReader(0);
200
201 EXPECT_EQ(queue.size(), 0lu);
202 EXPECT_EQ(queue.readers_count(), 0lu);
203 }
204
205 } // namespace
206 } // namespace webrtc
207