Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(310)

Side by Side Diff: cc/scheduler/begin_frame_observer_map_unittest.cc

Issue 1337803002: cc: Adding BeginFrameObserverMap. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase onto master. Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « cc/scheduler/begin_frame_observer_map.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "cc/scheduler/begin_frame_observer_map.h"
6
7 #include <algorithm>
8
9 #include "base/basictypes.h"
10 #include "base/gtest_prod_util.h"
11 #include "testing/gmock/include/gmock/gmock.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 // We use a macro here so that we get good line number information from gtest.
15 #define EXPECT_EMPTY(obmap) \
16 EXPECT_FALSE(obmap.HasObservers()); \
17 for (auto it = obmap.begin(); it != obmap.end(); it++) \
18 NOTREACHED(); \
19 for (auto it = obmap.cbegin(); it != obmap.cend(); it++) \
20 NOTREACHED(); \
21 EXPECT_EQ(GetConstIterators(&obmap), 0U); \
22 EXPECT_EQ(GetIterators(&obmap), 0U);
23
24 namespace cc {
25
26 // This has to be in the same name space as BeginFrameObserverMap so it is
27 // correctly
28 // friended.
29 class BeginFrameObserverMapTest : public ::testing::Test {
30 public:
31 template <class ObserverType, class ObserverDataType>
32 size_t GetIterators(
33 BeginFrameObserverMap<ObserverType, ObserverDataType>* obmap) {
34 return obmap->iterators_;
35 }
36
37 template <class ObserverType, class ObserverDataType>
38 size_t GetConstIterators(
39 BeginFrameObserverMap<ObserverType, ObserverDataType>* obmap) {
40 return obmap->const_iterators_;
41 }
42 };
43
44 namespace {
45
46 class TestObserver {
47 public:
48 int observe_;
49
50 TestObserver() : observe_(0) {}
51 void Observe() { observe_++; }
52 int GetObserve() const { return observe_; }
53 };
54
55 struct TestObserverData {
56 TestObserverData() : data(0) {}
57
58 size_t data;
59 };
60
61 TEST_F(BeginFrameObserverMapTest, Types) {
62 ::testing::StaticAssertTypeEq<
63 BeginFrameObserverMap<TestObserver,
64 TestObserverData>::const_iterator::value_type,
65 std::pair<TestObserver* const, TestObserverData*>>();
66 }
67
68 TEST_F(BeginFrameObserverMapTest, MapInitiallyEmpty) {
69 BeginFrameObserverMap<TestObserver, TestObserverData> obmap;
70 EXPECT_EMPTY(obmap);
71 }
72
73 TEST_F(BeginFrameObserverMapTest, SingleObserver) {
74 size_t data_value1 = __LINE__;
75 size_t data_value2 = __LINE__;
76 BeginFrameObserverMap<TestObserver, TestObserverData> obmap;
77 TestObserver obs1;
78
79 // Observer not added yet
80 EXPECT_FALSE(obmap.HasObserver(&obs1));
81 EXPECT_EQ(obmap[&obs1], nullptr);
82
83 // Add the observer
84 obmap.AddObserver(&obs1);
85 EXPECT_TRUE(obmap.HasObserver(&obs1));
86 EXPECT_TRUE(obmap.HasObservers());
87 EXPECT_EQ(obmap[&obs1]->data, 0U);
88
89 // Normal iterator
90 for (auto it = obmap.begin(); it != obmap.end(); it++) {
91 EXPECT_EQ(GetIterators(&obmap), 1U);
92 EXPECT_EQ(GetConstIterators(&obmap), 0U);
93 EXPECT_EQ(&obs1, it->first);
94 it->second->data = data_value1;
95 }
96 EXPECT_EQ(GetIterators(&obmap), 0U);
97 EXPECT_EQ(obmap[&obs1]->data, data_value1);
98 // const iterator
99 for (auto it = obmap.cbegin(); it != obmap.cend(); it++) {
100 EXPECT_EQ(GetIterators(&obmap), 0U);
101 EXPECT_EQ(GetConstIterators(&obmap), 1U);
102 EXPECT_EQ(&obs1, it->first);
103 EXPECT_EQ(it->second->data, data_value1);
104 }
105 EXPECT_EQ(GetConstIterators(&obmap), 0U);
106 // Nested iterators
107 for (auto it = obmap.begin(); it != obmap.end(); it++) {
108 for (auto jt = obmap.begin(); jt != obmap.end(); jt++) {
109 EXPECT_EQ(GetIterators(&obmap), 2U);
110 EXPECT_EQ(GetConstIterators(&obmap), 0U);
111 EXPECT_EQ(&obs1, it->first);
112 it->second->data = data_value2;
113 }
114 EXPECT_EQ(GetIterators(&obmap), 1U);
115 }
116 EXPECT_EQ(GetIterators(&obmap), 0U);
117 EXPECT_EQ(obmap[&obs1]->data, data_value2);
118 // Nested const iterator
119 for (auto it = obmap.cbegin(); it != obmap.cend(); it++) {
120 for (auto jt = obmap.cbegin(); jt != obmap.cend(); jt++) {
121 EXPECT_EQ(GetIterators(&obmap), 0U);
122 EXPECT_EQ(GetConstIterators(&obmap), 2U);
123 EXPECT_EQ(&obs1, jt->first);
124 EXPECT_EQ(jt->second->data, data_value2);
125 }
126 EXPECT_EQ(GetConstIterators(&obmap), 1U);
127 }
128 EXPECT_EQ(GetConstIterators(&obmap), 0U);
129
130 // Remove the observer
131 obmap.RemoveObserver(&obs1);
132 EXPECT_EMPTY(obmap);
133 }
134
135 TEST_F(BeginFrameObserverMapTest, TwoObservers) {
136 size_t data_value1 = __LINE__;
137 size_t data_value2 = __LINE__;
138 size_t data_value3 = __LINE__;
139 BeginFrameObserverMap<TestObserver, TestObserverData> obmap;
140 TestObserver obs1;
141 TestObserver obs2;
142
143 obmap.AddObserver(&obs1);
144 EXPECT_TRUE(obmap.HasObserver(&obs1));
145 obmap.AddObserver(&obs2);
146 EXPECT_TRUE(obmap.HasObserver(&obs2));
147
148 EXPECT_TRUE(obmap.HasObservers());
149 // Normal iterator
150 for (auto it = obmap.begin(); it != obmap.end(); it++) {
151 EXPECT_EQ(GetIterators(&obmap), 1U);
152 EXPECT_EQ(GetConstIterators(&obmap), 0U);
153 EXPECT_EQ(it->second->data, 0U);
154 it->second->data = data_value1;
155 }
156 EXPECT_EQ(GetIterators(&obmap), 0U);
157 // const iterator
158 for (auto it = obmap.cbegin(); it != obmap.cend(); it++) {
159 EXPECT_EQ(GetIterators(&obmap), 0U);
160 EXPECT_EQ(GetConstIterators(&obmap), 1U);
161 EXPECT_EQ(it->second->data, data_value1);
162 }
163 EXPECT_EQ(GetConstIterators(&obmap), 0U);
164 // operator[]
165 EXPECT_EQ(obmap[&obs1]->data, data_value1);
166 EXPECT_EQ(obmap[&obs2]->data, data_value1);
167
168 // Nested iterators
169 for (auto it = obmap.begin(); it != obmap.end(); it++) {
170 for (auto jt = obmap.begin(); jt != obmap.end(); jt++) {
171 EXPECT_EQ(GetIterators(&obmap), 2U);
172 EXPECT_EQ(GetConstIterators(&obmap), 0U);
173 it->second->data = data_value2;
174 }
175 EXPECT_EQ(GetIterators(&obmap), 1U);
176 }
177 EXPECT_EQ(GetIterators(&obmap), 0U);
178 // Nested const iterator
179 for (auto it = obmap.cbegin(); it != obmap.cend(); it++) {
180 for (auto jt = obmap.cbegin(); jt != obmap.cend(); jt++) {
181 EXPECT_EQ(GetIterators(&obmap), 0U);
182 EXPECT_EQ(GetConstIterators(&obmap), 2U);
183 EXPECT_EQ(jt->second->data, data_value2);
184 }
185 EXPECT_EQ(GetConstIterators(&obmap), 1U);
186 }
187 EXPECT_EQ(GetConstIterators(&obmap), 0U);
188
189 // Remove a single observer
190 obmap.RemoveObserver(&obs2);
191
192 // Repeat the above
193 EXPECT_TRUE(obmap.HasObservers());
194 // Normal iterator
195 for (auto it = obmap.begin(); it != obmap.end(); it++) {
196 EXPECT_EQ(it->second->data, data_value2);
197 it->second->data = data_value3;
198 }
199 // const iterator
200 for (auto it = obmap.begin(); it != obmap.end(); it++) {
201 EXPECT_EQ(it->second->data, data_value3);
202 }
203 // operator[]
204 EXPECT_EQ(obmap[&obs1]->data, data_value3);
205 EXPECT_EQ(obmap[&obs2], nullptr);
206
207 // Remove the other observer
208 obmap.RemoveObserver(&obs1);
209 EXPECT_EMPTY(obmap);
210 }
211
212 TEST_F(BeginFrameObserverMapTest, AddWhileIterating) {
213 size_t data_value1 = __LINE__;
214 BeginFrameObserverMap<TestObserver, TestObserverData> obmap;
215 TestObserver obs1;
216 TestObserver obs2;
217 TestObserver obs3;
218 obmap.AddObserver(&obs1);
219 obmap.AddObserver(&obs3);
220
221 obmap[&obs1]->data = data_value1;
222 obmap[&obs3]->data = data_value1;
223
224 int i = 1;
225 for (auto it = obmap.begin(); it != obmap.end(); it++, i++) {
226 // Calling add twice while iterating should be safe
227 obmap.AddObserver(&obs2);
228 // Should be able to access the data right after adding.
229 EXPECT_TRUE(obmap.HasObserver(&obs2));
230 obmap[&obs2]->data = i;
231 }
232 EXPECT_TRUE(obmap.HasObservers());
233
234 EXPECT_EQ(obmap[&obs1]->data, data_value1);
235 EXPECT_EQ(obmap[&obs2]->data, 2U);
236 EXPECT_EQ(obmap[&obs3]->data, data_value1);
237 }
238
239 TEST_F(BeginFrameObserverMapTest, RemoveOneWhileIterating) {
240 size_t data_value1 = __LINE__;
241 BeginFrameObserverMap<TestObserver, TestObserverData> obmap;
242 TestObserver obs1;
243 TestObserver obs2;
244 TestObserver obs3;
245 obmap.AddObserver(&obs1);
246 obmap.AddObserver(&obs2);
247 obmap.AddObserver(&obs3);
248
249 obmap[&obs1]->data = data_value1;
250 obmap[&obs2]->data = data_value1;
251 obmap[&obs3]->data = data_value1;
252
253 for (auto it = obmap.begin(); it != obmap.end(); it++) {
254 obmap.RemoveObserver(&obs2);
255 // Observer doesn't go away until the iteration is finished...
256 EXPECT_TRUE(obmap.HasObserver(&obs2));
257 }
258 EXPECT_FALSE(obmap.HasObserver(&obs2));
259 EXPECT_TRUE(obmap.HasObservers());
260
261 EXPECT_EQ(obmap[&obs1]->data, data_value1);
262 EXPECT_EQ(obmap[&obs2], nullptr);
263 EXPECT_EQ(obmap[&obs3]->data, data_value1);
264 }
265
266 TEST_F(BeginFrameObserverMapTest, NestedRemoveOneWhileIterating) {
267 size_t data_value1 = __LINE__;
268 BeginFrameObserverMap<TestObserver, TestObserverData> obmap;
269 TestObserver obs1;
270 TestObserver obs2;
271 TestObserver obs3;
272 obmap.AddObserver(&obs1);
273 obmap.AddObserver(&obs2);
274 obmap.AddObserver(&obs3);
275
276 obmap[&obs1]->data = data_value1;
277 obmap[&obs2]->data = data_value1;
278 obmap[&obs3]->data = data_value1;
279
280 for (auto it = obmap.begin(); it != obmap.end(); it++) {
281 for (auto jt = obmap.begin(); jt != obmap.end(); jt++) {
282 obmap.RemoveObserver(&obs2);
283 }
284 }
285 EXPECT_TRUE(obmap.HasObservers());
286
287 EXPECT_EQ(obmap[&obs1]->data, data_value1);
288 EXPECT_EQ(obmap[&obs2], nullptr);
289 EXPECT_EQ(obmap[&obs3]->data, data_value1);
290 }
291
292 TEST_F(BeginFrameObserverMapTest, RemoveAllWhileIterating) {
293 BeginFrameObserverMap<TestObserver, TestObserverData> obmap;
294 TestObserver obs1;
295 TestObserver obs2;
296 TestObserver obs3;
297 obmap.AddObserver(&obs1);
298 obmap.AddObserver(&obs2);
299
300 for (auto it = obmap.begin(); it != obmap.end(); it++) {
301 obmap.RemoveObserver(it->first);
302 }
303 EXPECT_EMPTY(obmap);
304 }
305
306 TEST_F(BeginFrameObserverMapTest, NestedRemoveAllWhileIterating) {
307 BeginFrameObserverMap<TestObserver, TestObserverData> obmap;
308 TestObserver obs1;
309 TestObserver obs2;
310 TestObserver obs3;
311 obmap.AddObserver(&obs1);
312 obmap.AddObserver(&obs2);
313
314 for (auto it = obmap.begin(); it != obmap.end(); it++) {
315 for (auto jt = obmap.begin(); jt != obmap.end(); jt++) {
316 obmap.RemoveObserver(jt->first);
317 }
318 }
319 EXPECT_EMPTY(obmap);
320 }
321
322 TEST_F(BeginFrameObserverMapTest, AttemptToRemoveWhileConstIterating) {
323 BeginFrameObserverMap<TestObserver, TestObserverData> obmap;
324 TestObserver obs1;
325 TestObserver obs2;
326 obmap.AddObserver(&obs1);
327 obmap.AddObserver(&obs2);
328
329 EXPECT_DEATH({
330 for (auto it = obmap.cbegin(); it != obmap.cend(); it++) {
331 obmap.RemoveObserver(const_cast<TestObserver*>(it->first));
332 }
333 }, "");
334
335 const BeginFrameObserverMap<TestObserver, TestObserverData>* cobmap = &obmap;
336 EXPECT_DEATH({
337 for (auto it = cobmap->begin(); it != cobmap->end(); it++) {
338 obmap.RemoveObserver(const_cast<TestObserver*>(it->first));
339 }
340 }, "");
341 }
342
343 TEST_F(BeginFrameObserverMapTest, AttemptToAddWhileConstIterating) {
344 BeginFrameObserverMap<TestObserver, TestObserverData> obmap;
345 TestObserver obs1;
346 TestObserver obs2;
347 TestObserver obs3;
348 obmap.AddObserver(&obs1);
349 obmap.AddObserver(&obs2);
350
351 EXPECT_DEATH({
352 for (auto it = obmap.cbegin(); it != obmap.cend(); it++) {
353 obmap.AddObserver(&obs3);
354 }
355 }, "");
356
357 const BeginFrameObserverMap<TestObserver, TestObserverData>* cobmap = &obmap;
358 EXPECT_DEATH({
359 for (auto it = cobmap->begin(); it != cobmap->end(); it++) {
360 obmap.AddObserver(&obs3);
361 }
362 }, "");
363 }
364
365 struct TestObserverOwner {
366 TestObserverOwner() : ob1(), ob2(), obmap() {}
367
368 TestObserver ob1;
369 TestObserver ob2;
370 BeginFrameObserverMap<TestObserver, TestObserverData> obmap;
371
372 void Notify() {
373 for (auto it = obmap.begin(); it != obmap.end(); it++) {
374 it->first->Observe();
375 }
376 }
377
378 int LargestObserver() const {
379 int largest = 0;
380 for (auto it = obmap.begin(); it != obmap.end(); it++) {
381 largest = std::max(largest, it->first->GetObserve());
382 }
383 return largest;
384 }
385 size_t LargestData() const {
386 size_t largest1 = 0;
387 size_t largest2 = 0;
388 for (auto it = obmap.begin(); it != obmap.end(); it++) {
389 largest1 = std::max(largest1, it->second->data);
390 largest2 = std::max(largest2, obmap[it->first]->data);
391 }
392 DCHECK_EQ(largest1, largest2);
393 return largest1;
394 }
395 };
396
397 TEST_F(BeginFrameObserverMapTest, ObserverOwner) {
398 TestObserverOwner owner;
399
400 owner.Notify();
401 EXPECT_EQ(owner.LargestObserver(), 0);
402 EXPECT_EQ(owner.LargestData(), 0U);
403
404 owner.obmap.AddObserver(&owner.ob1);
405 owner.Notify();
406 EXPECT_EQ(owner.LargestObserver(), 1);
407 EXPECT_EQ(owner.LargestData(), 0U);
408
409 owner.obmap[&owner.ob1]->data = 2;
410 EXPECT_EQ(owner.LargestObserver(), 1);
411 EXPECT_EQ(owner.LargestData(), 2U);
412
413 owner.obmap.AddObserver(&owner.ob2);
414 EXPECT_EQ(owner.LargestObserver(), 1);
415 EXPECT_EQ(owner.LargestData(), 2U);
416 owner.Notify();
417 owner.Notify();
418 EXPECT_EQ(owner.LargestObserver(), 3);
419 EXPECT_EQ(owner.LargestData(), 2U);
420
421 owner.obmap[&owner.ob2]->data = 5;
422 EXPECT_EQ(owner.LargestObserver(), 3);
423 EXPECT_EQ(owner.LargestData(), 5U);
424
425 owner.obmap.RemoveObserver(&owner.ob1);
426 EXPECT_EQ(owner.LargestObserver(), 2);
427 EXPECT_EQ(owner.LargestData(), 5U);
428 }
429
430 } // namespace
431 } // namespace cc
OLDNEW
« no previous file with comments | « cc/scheduler/begin_frame_observer_map.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698