observer_list_unittest.cc 29 KB

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