[M120 Migration][VD] Enable direct rendering for TVPlus
[platform/framework/web/chromium-efl.git] / base / observer_list_unittest.cc
1 // Copyright 2012 The Chromium Authors
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 "base/observer_list.h"
6
7 #include <memory>
8
9 #include "base/memory/raw_ptr.h"
10 #include "base/strings/string_piece.h"
11 #include "base/test/gtest_util.h"
12 #include "base/threading/simple_thread.h"
13 #include "build/build_config.h"
14 #include "testing/gmock/include/gmock/gmock.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "third_party/abseil-cpp/absl/types/optional.h"
17
18 namespace base {
19 namespace {
20
21 class CheckedBase : public CheckedObserver {
22  public:
23   virtual void Observe(int x) = 0;
24   ~CheckedBase() override = default;
25   virtual int GetValue() const { return 0; }
26 };
27
28 class UncheckedBase {
29  public:
30   virtual void Observe(int x) = 0;
31   virtual ~UncheckedBase() = default;
32   virtual int GetValue() const { return 0; }
33 };
34
35 // Helper for TYPED_TEST_SUITE machinery to pick the ObserverList under test.
36 // Keyed off the observer type since ObserverList has too many template args and
37 // it gets ugly.
38 template <class Foo>
39 struct PickObserverList {};
40 template <>
41 struct PickObserverList<CheckedBase> {
42   template <class TypeParam,
43             bool check_empty = false,
44             bool allow_reentrancy = true>
45   using ObserverListType =
46       ObserverList<TypeParam, check_empty, allow_reentrancy>;
47 };
48 template <>
49 struct PickObserverList<UncheckedBase> {
50   template <class TypeParam,
51             bool check_empty = false,
52             bool allow_reentrancy = true>
53   using ObserverListType = typename ObserverList<TypeParam,
54                                                  check_empty,
55                                                  allow_reentrancy>::Unchecked;
56 };
57
58 template <class Foo>
59 class AdderT : public Foo {
60  public:
61   explicit AdderT(int scaler) : total(0), scaler_(scaler) {}
62   ~AdderT() override = default;
63
64   void Observe(int x) override { total += x * scaler_; }
65   int GetValue() const override { return total; }
66
67   int total;
68
69  private:
70   int scaler_;
71 };
72
73 template <class ObserverListType,
74           class Foo = typename ObserverListType::value_type>
75 class DisrupterT : public Foo {
76  public:
77   DisrupterT(ObserverListType* list, Foo* doomed, bool remove_self)
78       : list_(list), doomed_(doomed), remove_self_(remove_self) {}
79   DisrupterT(ObserverListType* list, Foo* doomed)
80       : DisrupterT(list, doomed, false) {}
81   DisrupterT(ObserverListType* list, bool remove_self)
82       : DisrupterT(list, nullptr, remove_self) {}
83
84   ~DisrupterT() override = default;
85
86   void Observe(int x) override {
87     if (remove_self_)
88       list_->RemoveObserver(this);
89     if (doomed_)
90       list_->RemoveObserver(doomed_.get());
91   }
92
93   void SetDoomed(Foo* doomed) { doomed_ = doomed; }
94
95  private:
96   raw_ptr<ObserverListType> list_;
97   raw_ptr<Foo> doomed_;
98   bool remove_self_;
99 };
100
101 template <class ObserverListType,
102           class Foo = typename ObserverListType::value_type>
103 class AddInObserve : public Foo {
104  public:
105   explicit AddInObserve(ObserverListType* observer_list)
106       : observer_list(observer_list), to_add_() {}
107
108   void SetToAdd(Foo* to_add) { to_add_ = to_add; }
109
110   void Observe(int x) override {
111     if (to_add_) {
112       observer_list->AddObserver(to_add_.get());
113       to_add_ = nullptr;
114     }
115   }
116
117   raw_ptr<ObserverListType> observer_list;
118   raw_ptr<Foo> to_add_;
119 };
120
121 template <class ObserverListType>
122 class ObserverListCreator : public DelegateSimpleThread::Delegate {
123  public:
124   std::unique_ptr<ObserverListType> Create(
125       absl::optional<base::ObserverListPolicy> policy = absl::nullopt) {
126     policy_ = policy;
127     DelegateSimpleThread thread(this, "ListCreator");
128     thread.Start();
129     thread.Join();
130     return std::move(observer_list_);
131   }
132
133  private:
134   void Run() override {
135     if (policy_) {
136       observer_list_ = std::make_unique<ObserverListType>(*policy_);
137     } else {
138       observer_list_ = std::make_unique<ObserverListType>();
139     }
140   }
141
142   std::unique_ptr<ObserverListType> observer_list_;
143   absl::optional<base::ObserverListPolicy> policy_;
144 };
145
146 }  // namespace
147
148 class ObserverListTestBase {
149  public:
150   ObserverListTestBase() = default;
151   ObserverListTestBase(const ObserverListTestBase&) = delete;
152   ObserverListTestBase& operator=(const ObserverListTestBase&) = delete;
153
154   template <class T>
155   const decltype(T::list_.get()) list(const T& iter) {
156     return iter.list_.get();
157   }
158
159   template <class T>
160   typename T::value_type* GetCurrent(T* iter) {
161     return iter->GetCurrent();
162   }
163
164   // Override GetCurrent() for CheckedObserver. When StdIteratorRemoveFront
165   // tries to simulate a sequence to see if it "would" crash, CheckedObservers
166   // do, actually, crash with a DCHECK(). Note this check is different to the
167   // check during an observer _iteration_. Hence, DCHECK(), not CHECK().
168   CheckedBase* GetCurrent(ObserverList<CheckedBase>::iterator* iter) {
169     EXPECT_DCHECK_DEATH(return iter->GetCurrent());
170     return nullptr;
171   }
172 };
173
174 // Templatized test fixture that can pick between CheckedBase and UncheckedBase.
175 template <class ObserverType>
176 class ObserverListTest : public ObserverListTestBase, public ::testing::Test {
177  public:
178   template <class T>
179   using ObserverList =
180       typename PickObserverList<ObserverType>::template ObserverListType<T>;
181
182   using iterator = typename ObserverList<ObserverType>::iterator;
183   using const_iterator = typename ObserverList<ObserverType>::const_iterator;
184
185   ObserverListTest() = default;
186   ObserverListTest(const ObserverListTest&) = delete;
187   ObserverListTest& operator=(const ObserverListTest&) = delete;
188 };
189
190 using ObserverTypes = ::testing::Types<CheckedBase, UncheckedBase>;
191 TYPED_TEST_SUITE(ObserverListTest, ObserverTypes);
192
193 // TYPED_TEST causes the test parent class to be a template parameter, which
194 // makes the syntax for referring to the types awkward. Create aliases in local
195 // scope with clearer names. Unfortunately, we also need some trailing cruft to
196 // avoid "unused local type alias" warnings.
197 #define DECLARE_TYPES                                                       \
198   using Foo = TypeParam;                                                    \
199   using ObserverListFoo =                                                   \
200       typename PickObserverList<TypeParam>::template ObserverListType<Foo>; \
201   using Adder = AdderT<Foo>;                                                \
202   using Disrupter = DisrupterT<ObserverListFoo>;                            \
203   using const_iterator = typename TestFixture::const_iterator;              \
204   using iterator = typename TestFixture::iterator;                          \
205   (void)reinterpret_cast<Disrupter*>(0);                                    \
206   (void)reinterpret_cast<Adder*>(0);                                        \
207   (void)reinterpret_cast<const_iterator*>(0);                               \
208   (void)reinterpret_cast<iterator*>(0)
209
210 TYPED_TEST(ObserverListTest, BasicTest) {
211   DECLARE_TYPES;
212   ObserverListFoo observer_list;
213   const ObserverListFoo& const_observer_list = observer_list;
214
215   {
216     const const_iterator it1 = const_observer_list.begin();
217     EXPECT_EQ(it1, const_observer_list.end());
218     // Iterator copy.
219     const const_iterator it2 = it1;
220     EXPECT_EQ(it2, it1);
221     // Iterator assignment.
222     const_iterator it3;
223     it3 = it2;
224     EXPECT_EQ(it3, it1);
225     EXPECT_EQ(it3, it2);
226     // Self assignment.
227     it3 = *&it3;  // The *& defeats Clang's -Wself-assign warning.
228     EXPECT_EQ(it3, it1);
229     EXPECT_EQ(it3, it2);
230   }
231
232   {
233     const iterator it1 = observer_list.begin();
234     EXPECT_EQ(it1, observer_list.end());
235     // Iterator copy.
236     const iterator it2 = it1;
237     EXPECT_EQ(it2, it1);
238     // Iterator assignment.
239     iterator it3;
240     it3 = it2;
241     EXPECT_EQ(it3, it1);
242     EXPECT_EQ(it3, it2);
243     // Self assignment.
244     it3 = *&it3;  // The *& defeats Clang's -Wself-assign warning.
245     EXPECT_EQ(it3, it1);
246     EXPECT_EQ(it3, it2);
247   }
248
249   Adder a(1), b(-1), c(1), d(-1), e(-1);
250   Disrupter evil(&observer_list, &c);
251
252   observer_list.AddObserver(&a);
253   observer_list.AddObserver(&b);
254
255   EXPECT_TRUE(const_observer_list.HasObserver(&a));
256   EXPECT_FALSE(const_observer_list.HasObserver(&c));
257
258   {
259     const const_iterator it1 = const_observer_list.begin();
260     EXPECT_NE(it1, const_observer_list.end());
261     // Iterator copy.
262     const const_iterator it2 = it1;
263     EXPECT_EQ(it2, it1);
264     EXPECT_NE(it2, const_observer_list.end());
265     // Iterator assignment.
266     const_iterator it3;
267     it3 = it2;
268     EXPECT_EQ(it3, it1);
269     EXPECT_EQ(it3, it2);
270     // Self assignment.
271     it3 = *&it3;  // The *& defeats Clang's -Wself-assign warning.
272     EXPECT_EQ(it3, it1);
273     EXPECT_EQ(it3, it2);
274     // Iterator post increment.
275     const_iterator it4 = it3++;
276     EXPECT_EQ(it4, it1);
277     EXPECT_EQ(it4, it2);
278     EXPECT_NE(it4, it3);
279   }
280
281   {
282     const iterator it1 = observer_list.begin();
283     EXPECT_NE(it1, observer_list.end());
284     // Iterator copy.
285     const iterator it2 = it1;
286     EXPECT_EQ(it2, it1);
287     EXPECT_NE(it2, observer_list.end());
288     // Iterator assignment.
289     iterator it3;
290     it3 = it2;
291     EXPECT_EQ(it3, it1);
292     EXPECT_EQ(it3, it2);
293     // Self assignment.
294     it3 = *&it3;  // The *& defeats Clang's -Wself-assign warning.
295     EXPECT_EQ(it3, it1);
296     EXPECT_EQ(it3, it2);
297     // Iterator post increment.
298     iterator it4 = it3++;
299     EXPECT_EQ(it4, it1);
300     EXPECT_EQ(it4, it2);
301     EXPECT_NE(it4, it3);
302   }
303
304   for (auto& observer : observer_list)
305     observer.Observe(10);
306
307   observer_list.AddObserver(&evil);
308   observer_list.AddObserver(&c);
309   observer_list.AddObserver(&d);
310
311   // Removing an observer not in the list should do nothing.
312   observer_list.RemoveObserver(&e);
313
314   for (auto& observer : observer_list)
315     observer.Observe(10);
316
317   EXPECT_EQ(20, a.total);
318   EXPECT_EQ(-20, b.total);
319   EXPECT_EQ(0, c.total);
320   EXPECT_EQ(-10, d.total);
321   EXPECT_EQ(0, e.total);
322 }
323
324 TYPED_TEST(ObserverListTest, CreatedAndUsedOnDifferentThreads) {
325   DECLARE_TYPES;
326
327   ObserverListCreator<ObserverListFoo> list_creator;
328   Adder a(1);
329   // Check with default constructor
330   {
331     std::unique_ptr<ObserverListFoo> observer_list = list_creator.Create();
332     observer_list->AddObserver(&a);
333     for (auto& observer : *observer_list) {
334       observer.Observe(1);
335     }
336     EXPECT_EQ(1, a.GetValue());
337   }
338
339   // Check with constructor taking explicit policy
340   {
341     std::unique_ptr<ObserverListFoo> observer_list =
342         list_creator.Create(base::ObserverListPolicy::EXISTING_ONLY);
343     observer_list->AddObserver(&a);
344     for (auto& observer : *observer_list) {
345       observer.Observe(1);
346     }
347     EXPECT_EQ(2, a.GetValue());
348   }
349 }
350
351 TYPED_TEST(ObserverListTest, CompactsWhenNoActiveIterator) {
352   DECLARE_TYPES;
353   using ObserverListConstFoo =
354       typename TestFixture::template ObserverList<const Foo>;
355
356   ObserverListConstFoo ol;
357   const ObserverListConstFoo& col = ol;
358
359   const Adder a(1);
360   const Adder b(2);
361   const Adder c(3);
362
363   ol.AddObserver(&a);
364   ol.AddObserver(&b);
365
366   EXPECT_TRUE(col.HasObserver(&a));
367   EXPECT_FALSE(col.HasObserver(&c));
368
369   EXPECT_TRUE(!col.empty());
370
371   using It = typename ObserverListConstFoo::const_iterator;
372
373   {
374     It it = col.begin();
375     EXPECT_NE(it, col.end());
376     It ita = it;
377     EXPECT_EQ(ita, it);
378     EXPECT_NE(++it, col.end());
379     EXPECT_NE(ita, it);
380     It itb = it;
381     EXPECT_EQ(itb, it);
382     EXPECT_EQ(++it, col.end());
383
384     EXPECT_TRUE(!col.empty());
385     EXPECT_EQ(&*ita, &a);
386     EXPECT_EQ(&*itb, &b);
387
388     ol.RemoveObserver(&a);
389     EXPECT_TRUE(!col.empty());
390     EXPECT_FALSE(col.HasObserver(&a));
391     EXPECT_EQ(&*itb, &b);
392
393     ol.RemoveObserver(&b);
394     EXPECT_FALSE(!col.empty());
395     EXPECT_FALSE(col.HasObserver(&a));
396     EXPECT_FALSE(col.HasObserver(&b));
397
398     it = It();
399     ita = It();
400     EXPECT_FALSE(!col.empty());
401     ita = itb;
402     itb = It();
403     EXPECT_FALSE(!col.empty());
404     ita = It();
405     EXPECT_FALSE(!col.empty());
406   }
407
408   ol.AddObserver(&a);
409   ol.AddObserver(&b);
410   EXPECT_TRUE(!col.empty());
411   ol.Clear();
412   EXPECT_FALSE(!col.empty());
413
414   ol.AddObserver(&a);
415   ol.AddObserver(&b);
416   EXPECT_TRUE(!col.empty());
417   {
418     const It it = col.begin();
419     ol.Clear();
420     EXPECT_FALSE(!col.empty());
421   }
422   EXPECT_FALSE(!col.empty());
423 }
424
425 TYPED_TEST(ObserverListTest, DisruptSelf) {
426   DECLARE_TYPES;
427   ObserverListFoo observer_list;
428   Adder a(1), b(-1), c(1), d(-1);
429   Disrupter evil(&observer_list, true);
430
431   observer_list.AddObserver(&a);
432   observer_list.AddObserver(&b);
433
434   for (auto& observer : observer_list)
435     observer.Observe(10);
436
437   observer_list.AddObserver(&evil);
438   observer_list.AddObserver(&c);
439   observer_list.AddObserver(&d);
440
441   for (auto& observer : observer_list)
442     observer.Observe(10);
443
444   EXPECT_EQ(20, a.total);
445   EXPECT_EQ(-20, b.total);
446   EXPECT_EQ(10, c.total);
447   EXPECT_EQ(-10, d.total);
448 }
449
450 TYPED_TEST(ObserverListTest, DisruptBefore) {
451   DECLARE_TYPES;
452   ObserverListFoo observer_list;
453   Adder a(1), b(-1), c(1), d(-1);
454   Disrupter evil(&observer_list, &b);
455
456   observer_list.AddObserver(&a);
457   observer_list.AddObserver(&b);
458   observer_list.AddObserver(&evil);
459   observer_list.AddObserver(&c);
460   observer_list.AddObserver(&d);
461
462   for (auto& observer : observer_list)
463     observer.Observe(10);
464   for (auto& observer : observer_list)
465     observer.Observe(10);
466
467   EXPECT_EQ(20, a.total);
468   EXPECT_EQ(-10, b.total);
469   EXPECT_EQ(20, c.total);
470   EXPECT_EQ(-20, d.total);
471 }
472
473 TYPED_TEST(ObserverListTest, Existing) {
474   DECLARE_TYPES;
475   ObserverListFoo observer_list(ObserverListPolicy::EXISTING_ONLY);
476   Adder a(1);
477   AddInObserve<ObserverListFoo> b(&observer_list);
478   Adder c(1);
479   b.SetToAdd(&c);
480
481   observer_list.AddObserver(&a);
482   observer_list.AddObserver(&b);
483
484   for (auto& observer : observer_list)
485     observer.Observe(1);
486
487   EXPECT_FALSE(b.to_add_);
488   // B's adder should not have been notified because it was added during
489   // notification.
490   EXPECT_EQ(0, c.total);
491
492   // Notify again to make sure b's adder is notified.
493   for (auto& observer : observer_list)
494     observer.Observe(1);
495   EXPECT_EQ(1, c.total);
496 }
497
498 template <class ObserverListType,
499           class Foo = typename ObserverListType::value_type>
500 class AddInClearObserve : public Foo {
501  public:
502   explicit AddInClearObserve(ObserverListType* list)
503       : list_(list), added_(false), adder_(1) {}
504
505   void Observe(int /* x */) override {
506     list_->Clear();
507     list_->AddObserver(&adder_);
508     added_ = true;
509   }
510
511   bool added() const { return added_; }
512   const AdderT<Foo>& adder() const { return adder_; }
513
514  private:
515   const raw_ptr<ObserverListType> list_;
516
517   bool added_;
518   AdderT<Foo> adder_;
519 };
520
521 TYPED_TEST(ObserverListTest, ClearNotifyAll) {
522   DECLARE_TYPES;
523   ObserverListFoo observer_list;
524   AddInClearObserve<ObserverListFoo> a(&observer_list);
525
526   observer_list.AddObserver(&a);
527
528   for (auto& observer : observer_list)
529     observer.Observe(1);
530   EXPECT_TRUE(a.added());
531   EXPECT_EQ(1, a.adder().total)
532       << "Adder should observe once and have sum of 1.";
533 }
534
535 TYPED_TEST(ObserverListTest, ClearNotifyExistingOnly) {
536   DECLARE_TYPES;
537   ObserverListFoo observer_list(ObserverListPolicy::EXISTING_ONLY);
538   AddInClearObserve<ObserverListFoo> a(&observer_list);
539
540   observer_list.AddObserver(&a);
541
542   for (auto& observer : observer_list)
543     observer.Observe(1);
544   EXPECT_TRUE(a.added());
545   EXPECT_EQ(0, a.adder().total)
546       << "Adder should not observe, so sum should still be 0.";
547 }
548
549 template <class ObserverListType,
550           class Foo = typename ObserverListType::value_type>
551 class ListDestructor : public Foo {
552  public:
553   explicit ListDestructor(ObserverListType* list) : list_(list) {}
554   ~ListDestructor() override = default;
555
556   void Observe(int x) override { delete list_.ExtractAsDangling(); }
557
558  private:
559   raw_ptr<ObserverListType> list_;
560 };
561
562 TYPED_TEST(ObserverListTest, IteratorOutlivesList) {
563   DECLARE_TYPES;
564   ObserverListFoo* observer_list = new ObserverListFoo;
565   ListDestructor<ObserverListFoo> a(observer_list);
566   observer_list->AddObserver(&a);
567
568   for (auto& observer : *observer_list)
569     observer.Observe(0);
570
571   // There are no EXPECT* statements for this test, if we catch
572   // use-after-free errors for observer_list (eg with ASan) then
573   // this test has failed.  See http://crbug.com/85296.
574 }
575
576 TYPED_TEST(ObserverListTest, BasicStdIterator) {
577   DECLARE_TYPES;
578   ObserverListFoo observer_list;
579
580   // An optimization: begin() and end() do not involve weak pointers on
581   // empty list.
582   EXPECT_FALSE(this->list(observer_list.begin()));
583   EXPECT_FALSE(this->list(observer_list.end()));
584
585   // Iterate over empty list: no effect, no crash.
586   for (auto& i : observer_list)
587     i.Observe(10);
588
589   Adder a(1), b(-1), c(1), d(-1);
590
591   observer_list.AddObserver(&a);
592   observer_list.AddObserver(&b);
593   observer_list.AddObserver(&c);
594   observer_list.AddObserver(&d);
595
596   for (iterator i = observer_list.begin(), e = observer_list.end(); i != e; ++i)
597     i->Observe(1);
598
599   EXPECT_EQ(1, a.total);
600   EXPECT_EQ(-1, b.total);
601   EXPECT_EQ(1, c.total);
602   EXPECT_EQ(-1, d.total);
603
604   // Check an iteration over a 'const view' for a given container.
605   const ObserverListFoo& const_list = observer_list;
606   for (const_iterator i = const_list.begin(), e = const_list.end(); i != e;
607        ++i) {
608     EXPECT_EQ(1, std::abs(i->GetValue()));
609   }
610
611   for (const auto& o : const_list)
612     EXPECT_EQ(1, std::abs(o.GetValue()));
613 }
614
615 TYPED_TEST(ObserverListTest, StdIteratorRemoveItself) {
616   DECLARE_TYPES;
617   ObserverListFoo observer_list;
618   Adder a(1), b(-1), c(1), d(-1);
619   Disrupter disrupter(&observer_list, true);
620
621   observer_list.AddObserver(&a);
622   observer_list.AddObserver(&b);
623   observer_list.AddObserver(&disrupter);
624   observer_list.AddObserver(&c);
625   observer_list.AddObserver(&d);
626
627   for (auto& o : observer_list)
628     o.Observe(1);
629
630   for (auto& o : observer_list)
631     o.Observe(10);
632
633   EXPECT_EQ(11, a.total);
634   EXPECT_EQ(-11, b.total);
635   EXPECT_EQ(11, c.total);
636   EXPECT_EQ(-11, d.total);
637 }
638
639 TYPED_TEST(ObserverListTest, StdIteratorRemoveBefore) {
640   DECLARE_TYPES;
641   ObserverListFoo observer_list;
642   Adder a(1), b(-1), c(1), d(-1);
643   Disrupter disrupter(&observer_list, &b);
644
645   observer_list.AddObserver(&a);
646   observer_list.AddObserver(&b);
647   observer_list.AddObserver(&disrupter);
648   observer_list.AddObserver(&c);
649   observer_list.AddObserver(&d);
650
651   for (auto& o : observer_list)
652     o.Observe(1);
653
654   for (auto& o : observer_list)
655     o.Observe(10);
656
657   EXPECT_EQ(11, a.total);
658   EXPECT_EQ(-1, b.total);
659   EXPECT_EQ(11, c.total);
660   EXPECT_EQ(-11, d.total);
661 }
662
663 TYPED_TEST(ObserverListTest, StdIteratorRemoveAfter) {
664   DECLARE_TYPES;
665   ObserverListFoo observer_list;
666   Adder a(1), b(-1), c(1), d(-1);
667   Disrupter disrupter(&observer_list, &c);
668
669   observer_list.AddObserver(&a);
670   observer_list.AddObserver(&b);
671   observer_list.AddObserver(&disrupter);
672   observer_list.AddObserver(&c);
673   observer_list.AddObserver(&d);
674
675   for (auto& o : observer_list)
676     o.Observe(1);
677
678   for (auto& o : observer_list)
679     o.Observe(10);
680
681   EXPECT_EQ(11, a.total);
682   EXPECT_EQ(-11, b.total);
683   EXPECT_EQ(0, c.total);
684   EXPECT_EQ(-11, d.total);
685 }
686
687 TYPED_TEST(ObserverListTest, StdIteratorRemoveAfterFront) {
688   DECLARE_TYPES;
689   ObserverListFoo observer_list;
690   Adder a(1), b(-1), c(1), d(-1);
691   Disrupter disrupter(&observer_list, &a);
692
693   observer_list.AddObserver(&a);
694   observer_list.AddObserver(&disrupter);
695   observer_list.AddObserver(&b);
696   observer_list.AddObserver(&c);
697   observer_list.AddObserver(&d);
698
699   for (auto& o : observer_list)
700     o.Observe(1);
701
702   for (auto& o : observer_list)
703     o.Observe(10);
704
705   EXPECT_EQ(1, a.total);
706   EXPECT_EQ(-11, b.total);
707   EXPECT_EQ(11, c.total);
708   EXPECT_EQ(-11, d.total);
709 }
710
711 TYPED_TEST(ObserverListTest, StdIteratorRemoveBeforeBack) {
712   DECLARE_TYPES;
713   ObserverListFoo observer_list;
714   Adder a(1), b(-1), c(1), d(-1);
715   Disrupter disrupter(&observer_list, &d);
716
717   observer_list.AddObserver(&a);
718   observer_list.AddObserver(&b);
719   observer_list.AddObserver(&c);
720   observer_list.AddObserver(&disrupter);
721   observer_list.AddObserver(&d);
722
723   for (auto& o : observer_list)
724     o.Observe(1);
725
726   for (auto& o : observer_list)
727     o.Observe(10);
728
729   EXPECT_EQ(11, a.total);
730   EXPECT_EQ(-11, b.total);
731   EXPECT_EQ(11, c.total);
732   EXPECT_EQ(0, d.total);
733 }
734
735 TYPED_TEST(ObserverListTest, StdIteratorRemoveFront) {
736   DECLARE_TYPES;
737   using iterator = typename TestFixture::iterator;
738   ObserverListFoo observer_list;
739   Adder a(1), b(-1), c(1), d(-1);
740   Disrupter disrupter(&observer_list, true);
741
742   observer_list.AddObserver(&disrupter);
743   observer_list.AddObserver(&a);
744   observer_list.AddObserver(&b);
745   observer_list.AddObserver(&c);
746   observer_list.AddObserver(&d);
747
748   bool test_disruptor = true;
749   for (iterator i = observer_list.begin(), e = observer_list.end(); i != e;
750        ++i) {
751     i->Observe(1);
752     // Check that second call to i->Observe() would crash here.
753     if (test_disruptor) {
754       EXPECT_FALSE(this->GetCurrent(&i));
755       test_disruptor = false;
756     }
757   }
758
759   for (auto& o : observer_list)
760     o.Observe(10);
761
762   EXPECT_EQ(11, a.total);
763   EXPECT_EQ(-11, b.total);
764   EXPECT_EQ(11, c.total);
765   EXPECT_EQ(-11, d.total);
766 }
767
768 TYPED_TEST(ObserverListTest, StdIteratorRemoveBack) {
769   DECLARE_TYPES;
770   ObserverListFoo observer_list;
771   Adder a(1), b(-1), c(1), d(-1);
772   Disrupter disrupter(&observer_list, true);
773
774   observer_list.AddObserver(&a);
775   observer_list.AddObserver(&b);
776   observer_list.AddObserver(&c);
777   observer_list.AddObserver(&d);
778   observer_list.AddObserver(&disrupter);
779
780   for (auto& o : observer_list)
781     o.Observe(1);
782
783   for (auto& o : observer_list)
784     o.Observe(10);
785
786   EXPECT_EQ(11, a.total);
787   EXPECT_EQ(-11, b.total);
788   EXPECT_EQ(11, c.total);
789   EXPECT_EQ(-11, d.total);
790 }
791
792 TYPED_TEST(ObserverListTest, NestedLoop) {
793   DECLARE_TYPES;
794   ObserverListFoo observer_list;
795   Adder a(1), b(-1), c(1), d(-1);
796   Disrupter disrupter(&observer_list, true);
797
798   observer_list.AddObserver(&disrupter);
799   observer_list.AddObserver(&a);
800   observer_list.AddObserver(&b);
801   observer_list.AddObserver(&c);
802   observer_list.AddObserver(&d);
803
804   for (auto& observer : observer_list) {
805     observer.Observe(10);
806
807     for (auto& nested_observer : observer_list)
808       nested_observer.Observe(1);
809   }
810
811   EXPECT_EQ(15, a.total);
812   EXPECT_EQ(-15, b.total);
813   EXPECT_EQ(15, c.total);
814   EXPECT_EQ(-15, d.total);
815 }
816
817 TYPED_TEST(ObserverListTest, NonCompactList) {
818   DECLARE_TYPES;
819   ObserverListFoo observer_list;
820   Adder a(1), b(-1);
821
822   Disrupter disrupter2(&observer_list, true);  // Must outlive `disrupter1`.
823   Disrupter disrupter1(&observer_list, true);
824
825   // Disrupt itself and another one.
826   disrupter1.SetDoomed(&disrupter2);
827
828   observer_list.AddObserver(&disrupter1);
829   observer_list.AddObserver(&disrupter2);
830   observer_list.AddObserver(&a);
831   observer_list.AddObserver(&b);
832
833   for (auto& observer : observer_list) {
834     // Get the { nullptr, nullptr, &a, &b } non-compact list
835     // on the first inner pass.
836     observer.Observe(10);
837
838     for (auto& nested_observer : observer_list)
839       nested_observer.Observe(1);
840   }
841
842   EXPECT_EQ(13, a.total);
843   EXPECT_EQ(-13, b.total);
844 }
845
846 TYPED_TEST(ObserverListTest, BecomesEmptyThanNonEmpty) {
847   DECLARE_TYPES;
848   ObserverListFoo observer_list;
849   Adder a(1), b(-1);
850
851   Disrupter disrupter2(&observer_list, true);  // Must outlive `disrupter1`.
852   Disrupter disrupter1(&observer_list, true);
853
854   // Disrupt itself and another one.
855   disrupter1.SetDoomed(&disrupter2);
856
857   observer_list.AddObserver(&disrupter1);
858   observer_list.AddObserver(&disrupter2);
859
860   bool add_observers = true;
861   for (auto& observer : observer_list) {
862     // Get the { nullptr, nullptr } empty list on the first inner pass.
863     observer.Observe(10);
864
865     for (auto& nested_observer : observer_list)
866       nested_observer.Observe(1);
867
868     if (add_observers) {
869       observer_list.AddObserver(&a);
870       observer_list.AddObserver(&b);
871       add_observers = false;
872     }
873   }
874
875   EXPECT_EQ(12, a.total);
876   EXPECT_EQ(-12, b.total);
877 }
878
879 TYPED_TEST(ObserverListTest, AddObserverInTheLastObserve) {
880   DECLARE_TYPES;
881   ObserverListFoo observer_list;
882
883   AddInObserve<ObserverListFoo> a(&observer_list);
884   Adder b(-1);
885
886   a.SetToAdd(&b);
887   observer_list.AddObserver(&a);
888
889   auto it = observer_list.begin();
890   while (it != observer_list.end()) {
891     auto& observer = *it;
892     // Intentionally increment the iterator before calling Observe(). The
893     // ObserverList starts with only one observer, and it == observer_list.end()
894     // should be true after the next line.
895     ++it;
896     // However, the first Observe() call will add a second observer: at this
897     // point, it != observer_list.end() should be true, and Observe() should be
898     // called on the newly added observer on the next iteration of the loop.
899     observer.Observe(10);
900   }
901
902   EXPECT_EQ(-10, b.total);
903 }
904
905 class MockLogAssertHandler {
906  public:
907   MOCK_METHOD4(
908       HandleLogAssert,
909       void(const char*, int, const base::StringPiece, const base::StringPiece));
910 };
911
912 #if DCHECK_IS_ON()
913 TYPED_TEST(ObserverListTest, NonReentrantObserverList) {
914   DECLARE_TYPES;
915   using NonReentrantObserverListFoo = typename PickObserverList<
916       Foo>::template ObserverListType<Foo, /*check_empty=*/false,
917                                       /*allow_reentrancy=*/false>;
918   NonReentrantObserverListFoo non_reentrant_observer_list;
919   Adder a(1);
920   non_reentrant_observer_list.AddObserver(&a);
921
922   EXPECT_DCHECK_DEATH({
923     for (const Foo& observer : non_reentrant_observer_list) {
924       for (const Foo& nested_observer : non_reentrant_observer_list) {
925         std::ignore = observer;
926         std::ignore = nested_observer;
927       }
928     }
929   });
930 }
931
932 TYPED_TEST(ObserverListTest, ReentrantObserverList) {
933   DECLARE_TYPES;
934   using ReentrantObserverListFoo = typename PickObserverList<
935       Foo>::template ObserverListType<Foo, /*check_empty=*/false,
936                                       /*allow_reentrancy=*/true>;
937   ReentrantObserverListFoo reentrant_observer_list;
938   Adder a(1);
939   reentrant_observer_list.AddObserver(&a);
940   bool passed = false;
941   for (const Foo& observer : reentrant_observer_list) {
942     for (const Foo& nested_observer : reentrant_observer_list) {
943       std::ignore = observer;
944       std::ignore = nested_observer;
945       passed = true;
946     }
947   }
948   EXPECT_TRUE(passed);
949 }
950 #endif
951
952 class TestCheckedObserver : public CheckedObserver {
953  public:
954   explicit TestCheckedObserver(int* count) : count_(count) {}
955   TestCheckedObserver(const TestCheckedObserver&) = delete;
956   TestCheckedObserver& operator=(const TestCheckedObserver&) = delete;
957
958   void Observe() { ++(*count_); }
959
960  private:
961   raw_ptr<int> count_;
962 };
963
964 // A second, identical observer, used to test multiple inheritance.
965 class TestCheckedObserver2 : public CheckedObserver {
966  public:
967   explicit TestCheckedObserver2(int* count) : count_(count) {}
968   TestCheckedObserver2(const TestCheckedObserver2&) = delete;
969   TestCheckedObserver2& operator=(const TestCheckedObserver2&) = delete;
970
971   void Observe() { ++(*count_); }
972
973  private:
974   raw_ptr<int> count_;
975 };
976
977 using CheckedObserverListTest = ::testing::Test;
978
979 // Test Observers that CHECK() when a UAF might otherwise occur.
980 TEST_F(CheckedObserverListTest, CheckedObserver) {
981   // See comments below about why this is unique_ptr.
982   auto list = std::make_unique<ObserverList<TestCheckedObserver>>();
983   int count1 = 0;
984   int count2 = 0;
985   TestCheckedObserver l1(&count1);
986   list->AddObserver(&l1);
987   {
988     TestCheckedObserver l2(&count2);
989     list->AddObserver(&l2);
990     for (auto& observer : *list)
991       observer.Observe();
992     EXPECT_EQ(1, count1);
993     EXPECT_EQ(1, count2);
994   }
995   {
996     auto it = list->begin();
997     it->Observe();
998     // For CheckedObservers, a CHECK() occurs when advancing the iterator. (On
999     // calling the observer method would be too late since the pointer would
1000     // already be null by then).
1001     EXPECT_CHECK_DEATH(it++);
1002
1003     // On the non-death fork, no UAF occurs since the deleted observer is never
1004     // notified, but also the observer list still has |l2| in it. Check that.
1005     list->RemoveObserver(&l1);
1006     EXPECT_TRUE(!list->empty());
1007
1008     // Now (in the non-death fork()) there's a problem. To delete |it|, we need
1009     // to compact the list, but that needs to iterate, which would CHECK again.
1010     // We can't remove |l2| (it's null). But we can delete |list|, which makes
1011     // the weak pointer in the iterator itself null.
1012     list.reset();
1013   }
1014   EXPECT_EQ(2, count1);
1015   EXPECT_EQ(1, count2);
1016 }
1017
1018 class MultiObserver : public TestCheckedObserver,
1019                       public TestCheckedObserver2,
1020                       public AdderT<UncheckedBase> {
1021  public:
1022   MultiObserver(int* checked_count, int* two_count)
1023       : TestCheckedObserver(checked_count),
1024         TestCheckedObserver2(two_count),
1025         AdderT(1) {}
1026 };
1027
1028 // Test that observers behave as expected when observing multiple interfaces
1029 // with different traits.
1030 TEST_F(CheckedObserverListTest, MultiObserver) {
1031   // Observe two checked observer lists. This is to ensure the WeakPtrFactory
1032   // in CheckedObserver can correctly service multiple ObserverLists.
1033   ObserverList<TestCheckedObserver> checked_list;
1034   ObserverList<TestCheckedObserver2> two_list;
1035
1036   ObserverList<UncheckedBase>::Unchecked unsafe_list;
1037
1038   int counts[2] = {};
1039
1040   auto multi_observer = std::make_unique<MultiObserver>(&counts[0], &counts[1]);
1041   two_list.AddObserver(multi_observer.get());
1042   checked_list.AddObserver(multi_observer.get());
1043   unsafe_list.AddObserver(multi_observer.get());
1044
1045   auto iterate_over = [](auto* list) {
1046     for (auto& observer : *list)
1047       observer.Observe();
1048   };
1049   iterate_over(&two_list);
1050   iterate_over(&checked_list);
1051   for (auto& observer : unsafe_list)
1052     observer.Observe(10);
1053
1054   EXPECT_EQ(10, multi_observer->GetValue());
1055   for (const auto& count : counts)
1056     EXPECT_EQ(1, count);
1057
1058   unsafe_list.RemoveObserver(multi_observer.get());  // Avoid a use-after-free.
1059
1060   multi_observer.reset();
1061   EXPECT_CHECK_DEATH(iterate_over(&checked_list));
1062
1063   for (const auto& count : counts)
1064     EXPECT_EQ(1, count);
1065 }
1066
1067 }  // namespace base