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