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

Side by Side Diff: chrome/browser/sync/test/integration/bookmarks_helper.cc

Issue 474273003: sync: Refactor bookmarks integration tests Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Use RunLoop for favicon wait Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/sync/test/integration/bookmarks_helper.h" 5 #include "chrome/browser/sync/test/integration/bookmarks_helper.h"
6 6
7 #include "base/compiler_specific.h" 7 #include "base/compiler_specific.h"
8 #include "base/file_util.h" 8 #include "base/file_util.h"
9 #include "base/path_service.h" 9 #include "base/path_service.h"
10 #include "base/rand_util.h" 10 #include "base/rand_util.h"
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 : model_(model), 68 : model_(model),
69 node_(node), 69 node_(node),
70 wait_for_load_(false) { 70 wait_for_load_(false) {
71 model->AddObserver(this); 71 model->AddObserver(this);
72 } 72 }
73 virtual ~FaviconChangeObserver() { 73 virtual ~FaviconChangeObserver() {
74 model_->RemoveObserver(this); 74 model_->RemoveObserver(this);
75 } 75 }
76 void WaitForGetFavicon() { 76 void WaitForGetFavicon() {
77 wait_for_load_ = true; 77 wait_for_load_ = true;
78 content::RunMessageLoop(); 78 run_loop_.Run();
79 ASSERT_TRUE(node_->is_favicon_loaded()); 79 ASSERT_TRUE(node_->is_favicon_loaded());
80 ASSERT_FALSE(model_->GetFavicon(node_).IsEmpty()); 80 ASSERT_FALSE(model_->GetFavicon(node_).IsEmpty());
81 } 81 }
82 void WaitForSetFavicon() { 82 void WaitForSetFavicon() {
83 wait_for_load_ = false; 83 wait_for_load_ = false;
84 content::RunMessageLoop(); 84 run_loop_.Run();
85 } 85 }
86 virtual void BookmarkModelLoaded(BookmarkModel* model, 86 virtual void BookmarkModelLoaded(BookmarkModel* model,
87 bool ids_reassigned) OVERRIDE {} 87 bool ids_reassigned) OVERRIDE {}
88 virtual void BookmarkNodeMoved(BookmarkModel* model, 88 virtual void BookmarkNodeMoved(BookmarkModel* model,
89 const BookmarkNode* old_parent, 89 const BookmarkNode* old_parent,
90 int old_index, 90 int old_index,
91 const BookmarkNode* new_parent, 91 const BookmarkNode* new_parent,
92 int new_index) OVERRIDE {} 92 int new_index) OVERRIDE {}
93 virtual void BookmarkNodeAdded(BookmarkModel* model, 93 virtual void BookmarkNodeAdded(BookmarkModel* model,
94 const BookmarkNode* parent, 94 const BookmarkNode* parent,
(...skipping 14 matching lines...) Expand all
109 model->GetFavicon(node); 109 model->GetFavicon(node);
110 } 110 }
111 virtual void BookmarkNodeChildrenReordered( 111 virtual void BookmarkNodeChildrenReordered(
112 BookmarkModel* model, 112 BookmarkModel* model,
113 const BookmarkNode* node) OVERRIDE {} 113 const BookmarkNode* node) OVERRIDE {}
114 virtual void BookmarkNodeFaviconChanged( 114 virtual void BookmarkNodeFaviconChanged(
115 BookmarkModel* model, 115 BookmarkModel* model,
116 const BookmarkNode* node) OVERRIDE { 116 const BookmarkNode* node) OVERRIDE {
117 if (model == model_ && node == node_) { 117 if (model == model_ && node == node_) {
118 if (!wait_for_load_ || (wait_for_load_ && node->is_favicon_loaded())) 118 if (!wait_for_load_ || (wait_for_load_ && node->is_favicon_loaded()))
119 base::MessageLoopForUI::current()->Quit(); 119 run_loop_.Quit();
120 } 120 }
121 } 121 }
122 122
123 private: 123 private:
124 BookmarkModel* model_; 124 BookmarkModel* model_;
125 const BookmarkNode* node_; 125 const BookmarkNode* node_;
126 bool wait_for_load_; 126 bool wait_for_load_;
127 base::RunLoop run_loop_;
127 DISALLOW_COPY_AND_ASSIGN(FaviconChangeObserver); 128 DISALLOW_COPY_AND_ASSIGN(FaviconChangeObserver);
128 }; 129 };
129 130
130 // A collection of URLs for which we have added favicons. Since loading a 131 // A collection of URLs for which we have added favicons. Since loading a
131 // favicon is an asynchronous operation and doesn't necessarily invoke a 132 // favicon is an asynchronous operation and doesn't necessarily invoke a
132 // callback, this collection is used to determine if we must wait for a URL's 133 // callback, this collection is used to determine if we must wait for a URL's
133 // favicon to load or not. 134 // favicon to load or not.
134 std::set<GURL>* urls_with_favicons_ = NULL; 135 std::set<GURL>* urls_with_favicons_ = NULL;
135 136
136 // Returns the number of nodes of node type |node_type| in |model| whose 137 // Returns the number of nodes of node type |node_type| in |model| whose
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 1.0f).sk_bitmap(); 308 1.0f).sk_bitmap();
308 return FaviconRawBitmapsMatch(bitmap_a, bitmap_b); 309 return FaviconRawBitmapsMatch(bitmap_a, bitmap_b);
309 } 310 }
310 311
311 // Does a deep comparison of BookmarkNode fields in |model_a| and |model_b|. 312 // Does a deep comparison of BookmarkNode fields in |model_a| and |model_b|.
312 // Returns true if they are all equal. 313 // Returns true if they are all equal.
313 bool NodesMatch(const BookmarkNode* node_a, const BookmarkNode* node_b) { 314 bool NodesMatch(const BookmarkNode* node_a, const BookmarkNode* node_b) {
314 if (node_a == NULL || node_b == NULL) 315 if (node_a == NULL || node_b == NULL)
315 return node_a == node_b; 316 return node_a == node_b;
316 if (node_a->is_folder() != node_b->is_folder()) { 317 if (node_a->is_folder() != node_b->is_folder()) {
317 LOG(ERROR) << "Cannot compare folder with bookmark"; 318 VLOG(1) << "Cannot compare folder with bookmark";
318 return false; 319 return false;
319 } 320 }
320 if (node_a->GetTitle() != node_b->GetTitle()) { 321 if (node_a->GetTitle() != node_b->GetTitle()) {
321 LOG(ERROR) << "Title mismatch: " << node_a->GetTitle() << " vs. " 322 VLOG(1) << "Title mismatch: " << node_a->GetTitle() << " vs. "
322 << node_b->GetTitle(); 323 << node_b->GetTitle();
323 return false; 324 return false;
324 } 325 }
325 if (node_a->url() != node_b->url()) { 326 if (node_a->url() != node_b->url()) {
326 LOG(ERROR) << "URL mismatch: " << node_a->url() << " vs. " 327 VLOG(1) << "URL mismatch: " << node_a->url() << " vs. " << node_b->url();
327 << node_b->url();
328 return false; 328 return false;
329 } 329 }
330 if (node_a->parent()->GetIndexOf(node_a) != 330 if (node_a->parent()->GetIndexOf(node_a) !=
331 node_b->parent()->GetIndexOf(node_b)) { 331 node_b->parent()->GetIndexOf(node_b)) {
332 LOG(ERROR) << "Index mismatch: " 332 VLOG(1) << "Index mismatch: " << node_a->parent()->GetIndexOf(node_a)
333 << node_a->parent()->GetIndexOf(node_a) << " vs. " 333 << " vs. " << node_b->parent()->GetIndexOf(node_b);
334 << node_b->parent()->GetIndexOf(node_b);
335 return false; 334 return false;
336 } 335 }
337 return true; 336 return true;
338 } 337 }
339 338
340 // Checks if the hierarchies in |model_a| and |model_b| are equivalent in 339 // Checks if the hierarchies in |model_a| and |model_b| are equivalent in
341 // terms of the data model and favicon. Returns true if they both match. 340 // terms of the data model and favicon. Returns true if they both match.
342 // Note: Some peripheral fields like creation times are allowed to mismatch. 341 // Note: Some peripheral fields like creation times are allowed to mismatch.
343 bool BookmarkModelsMatch(BookmarkModel* model_a, BookmarkModel* model_b) { 342 bool BookmarkModelsMatch(BookmarkModel* model_a, BookmarkModel* model_b) {
344 bool ret_val = true; 343 bool ret_val = true;
345 ui::TreeNodeIterator<const BookmarkNode> iterator_a(model_a->root_node()); 344 ui::TreeNodeIterator<const BookmarkNode> iterator_a(model_a->root_node());
346 ui::TreeNodeIterator<const BookmarkNode> iterator_b(model_b->root_node()); 345 ui::TreeNodeIterator<const BookmarkNode> iterator_b(model_b->root_node());
347 while (iterator_a.has_next()) { 346 while (iterator_a.has_next()) {
348 const BookmarkNode* node_a = iterator_a.Next(); 347 const BookmarkNode* node_a = iterator_a.Next();
349 if (!iterator_b.has_next()) { 348 if (!iterator_b.has_next()) {
350 LOG(ERROR) << "Models do not match."; 349 VLOG(1) << "Models do not match.";
351 return false; 350 return false;
352 } 351 }
353 const BookmarkNode* node_b = iterator_b.Next(); 352 const BookmarkNode* node_b = iterator_b.Next();
354 ret_val = ret_val && NodesMatch(node_a, node_b); 353 ret_val = ret_val && NodesMatch(node_a, node_b);
355 if (node_a->is_folder() || node_b->is_folder()) 354 if (node_a->is_folder() || node_b->is_folder())
356 continue; 355 continue;
357 ret_val = ret_val && FaviconsMatch(model_a, model_b, node_a, node_b); 356 ret_val = ret_val && FaviconsMatch(model_a, model_b, node_a, node_b);
358 } 357 }
359 ret_val = ret_val && (!iterator_b.has_next()); 358 ret_val = ret_val && (!iterator_b.has_next());
360 return ret_val; 359 return ret_val;
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
651 } 650 }
652 651
653 bool AllModelsMatchVerifier() { 652 bool AllModelsMatchVerifier() {
654 // Ensure that all tasks have finished processing on the history thread 653 // Ensure that all tasks have finished processing on the history thread
655 // and that any notifications the history thread may have sent have been 654 // and that any notifications the history thread may have sent have been
656 // processed before comparing models. 655 // processed before comparing models.
657 WaitForHistoryToProcessPendingTasks(); 656 WaitForHistoryToProcessPendingTasks();
658 657
659 for (int i = 0; i < sync_datatype_helper::test()->num_clients(); ++i) { 658 for (int i = 0; i < sync_datatype_helper::test()->num_clients(); ++i) {
660 if (!ModelMatchesVerifier(i)) { 659 if (!ModelMatchesVerifier(i)) {
661 LOG(ERROR) << "Model " << i << " does not match the verifier."; 660 VLOG(1) << "Model " << i << " does not match the verifier.";
662 return false; 661 return false;
663 } 662 }
664 } 663 }
665 return true; 664 return true;
666 } 665 }
667 666
668 bool ModelsMatch(int profile_a, int profile_b) { 667 bool ModelsMatch(int profile_a, int profile_b) {
669 return BookmarkModelsMatch(GetBookmarkModel(profile_a), 668 return BookmarkModelsMatch(GetBookmarkModel(profile_a),
670 GetBookmarkModel(profile_b)); 669 GetBookmarkModel(profile_b));
671 } 670 }
672 671
673 bool AllModelsMatch() { 672 bool AllModelsMatch() {
674 // Ensure that all tasks have finished processing on the history thread 673 // Ensure that all tasks have finished processing on the history thread
675 // and that any notifications the history thread may have sent have been 674 // and that any notifications the history thread may have sent have been
676 // processed before comparing models. 675 // processed before comparing models.
677 WaitForHistoryToProcessPendingTasks(); 676 WaitForHistoryToProcessPendingTasks();
678 677
679 for (int i = 1; i < sync_datatype_helper::test()->num_clients(); ++i) { 678 for (int i = 1; i < sync_datatype_helper::test()->num_clients(); ++i) {
680 if (!ModelsMatch(0, i)) { 679 if (!ModelsMatch(0, i)) {
681 LOG(ERROR) << "Model " << i << " does not match Model 0."; 680 VLOG(1) << "Model " << i << " does not match Model 0.";
682 return false; 681 return false;
683 } 682 }
684 } 683 }
685 return true; 684 return true;
686 } 685 }
687 686
688 namespace {
689
690 // Helper class used in the implementation of AwaitAllModelsMatch.
691 class AllModelsMatchChecker : public MultiClientStatusChangeChecker {
692 public:
693 AllModelsMatchChecker();
694 virtual ~AllModelsMatchChecker();
695
696 virtual bool IsExitConditionSatisfied() OVERRIDE;
697 virtual std::string GetDebugMessage() const OVERRIDE;
698 };
699
700 AllModelsMatchChecker::AllModelsMatchChecker()
701 : MultiClientStatusChangeChecker(
702 sync_datatype_helper::test()->GetSyncServices()) {}
703
704 AllModelsMatchChecker::~AllModelsMatchChecker() {}
705
706 bool AllModelsMatchChecker::IsExitConditionSatisfied() {
707 return AllModelsMatch();
708 }
709
710 std::string AllModelsMatchChecker::GetDebugMessage() const {
711 return "Waiting for matching models";
712 }
713
714 } // namespace
715
716 bool AwaitAllModelsMatch() {
717 AllModelsMatchChecker checker;
718 checker.Wait();
719 return !checker.TimedOut();
720 }
721
722
723 bool ContainsDuplicateBookmarks(int profile) { 687 bool ContainsDuplicateBookmarks(int profile) {
724 ui::TreeNodeIterator<const BookmarkNode> iterator( 688 ui::TreeNodeIterator<const BookmarkNode> iterator(
725 GetBookmarkModel(profile)->root_node()); 689 GetBookmarkModel(profile)->root_node());
726 while (iterator.has_next()) { 690 while (iterator.has_next()) {
727 const BookmarkNode* node = iterator.Next(); 691 const BookmarkNode* node = iterator.Next();
728 if (node->is_folder()) 692 if (node->is_folder())
729 continue; 693 continue;
730 std::vector<const BookmarkNode*> nodes; 694 std::vector<const BookmarkNode*> nodes;
731 GetBookmarkModel(profile)->GetNodesByURL(node->url(), &nodes); 695 GetBookmarkModel(profile)->GetNodesByURL(node->url(), &nodes);
732 EXPECT_TRUE(nodes.size() >= 1); 696 EXPECT_TRUE(nodes.size() >= 1);
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
815 } 779 }
816 780
817 std::string IndexedSubfolderName(int i) { 781 std::string IndexedSubfolderName(int i) {
818 return base::StringPrintf("Subfolder Name %d", i); 782 return base::StringPrintf("Subfolder Name %d", i);
819 } 783 }
820 784
821 std::string IndexedSubsubfolderName(int i) { 785 std::string IndexedSubsubfolderName(int i) {
822 return base::StringPrintf("Subsubfolder Name %d", i); 786 return base::StringPrintf("Subsubfolder Name %d", i);
823 } 787 }
824 788
789 class BookmarkConditionChecker : public StatusChangeChecker,
790 public BookmarkModelObserver {
791 public:
792 BookmarkConditionChecker(base::Callback<bool()> exit_condition,
793 const std::string& debug_message);
794 virtual ~BookmarkConditionChecker();
795
796 // Implementation of StatusChangeChecker.
797 virtual std::string GetDebugMessage() const OVERRIDE;
798 virtual bool IsExitConditionSatisfied() OVERRIDE;
799
800 // Implementation of BookmarkModelObserver.
801 virtual void BookmarkModelLoaded(BookmarkModel* model,
802 bool ids_reassigned) OVERRIDE;
803 virtual void BookmarkNodeMoved(BookmarkModel* model,
804 const BookmarkNode* old_parent,
805 int old_index,
806 const BookmarkNode* new_parent,
807 int new_index) OVERRIDE;
808 virtual void BookmarkNodeAdded(BookmarkModel* model,
809 const BookmarkNode* parent,
810 int index) OVERRIDE;
811 virtual void BookmarkNodeRemoved(BookmarkModel* model,
812 const BookmarkNode* parent,
813 int old_index,
814 const BookmarkNode* node,
815 const std::set<GURL>& removed_urls) OVERRIDE;
816 virtual void BookmarkNodeChanged(BookmarkModel* model,
817 const BookmarkNode* node) OVERRIDE;
818 virtual void BookmarkNodeFaviconChanged(BookmarkModel* model,
819 const BookmarkNode* node) OVERRIDE;
820 virtual void BookmarkNodeChildrenReordered(BookmarkModel* model,
821 const BookmarkNode* node) OVERRIDE;
822 virtual void BookmarkAllUserNodesRemoved(
823 BookmarkModel* model,
824 const std::set<GURL>& removed_urls) OVERRIDE;
825
826 // Waits until the condition to be met or a timeout occurs.
827 void Wait();
828
829 private:
830 base::Callback<bool()> exit_condition_;
831 std::string debug_message_;
832 bool registered_;
833 };
834
835 BookmarkConditionChecker::BookmarkConditionChecker(
836 base::Callback<bool()> exit_condition,
837 const std::string& debug_message)
838 : exit_condition_(exit_condition),
839 debug_message_(debug_message),
840 registered_(false) {
841 }
842
843 BookmarkConditionChecker::~BookmarkConditionChecker() {
844 if (!registered_)
845 return;
846
847 for (int i = 0; i < sync_datatype_helper::test()->num_clients(); ++i) {
848 GetBookmarkModel(i)->RemoveObserver(this);
849 }
850 }
851
852 std::string BookmarkConditionChecker::GetDebugMessage() const {
853 return debug_message_;
854 }
855
856 bool BookmarkConditionChecker::IsExitConditionSatisfied() {
857 return exit_condition_.Run();
858 }
859
860 // Implementation of BookmarkModelObserver.
861 void BookmarkConditionChecker::BookmarkModelLoaded(BookmarkModel* model,
862 bool ids_reassigned) {
863 CheckExitCondition();
864 }
865
866 void BookmarkConditionChecker::BookmarkNodeMoved(BookmarkModel* model,
867 const BookmarkNode* old_parent,
868 int old_index,
869 const BookmarkNode* new_parent,
870 int new_index) {
871 CheckExitCondition();
872 }
873
874 void BookmarkConditionChecker::BookmarkNodeAdded(BookmarkModel* model,
875 const BookmarkNode* parent,
876 int index) {
877 CheckExitCondition();
878 }
879
880 void BookmarkConditionChecker::BookmarkNodeRemoved(
881 BookmarkModel* model,
882 const BookmarkNode* parent,
883 int old_index,
884 const BookmarkNode* node,
885 const std::set<GURL>& removed_urls) {
886 CheckExitCondition();
887 }
888
889 void BookmarkConditionChecker::BookmarkNodeChanged(BookmarkModel* model,
890 const BookmarkNode* node) {
891 CheckExitCondition();
892 }
893
894 void BookmarkConditionChecker::BookmarkNodeFaviconChanged(
895 BookmarkModel* model,
896 const BookmarkNode* node) {
897 CheckExitCondition();
898 }
899
900 void BookmarkConditionChecker::BookmarkNodeChildrenReordered(
901 BookmarkModel* model,
902 const BookmarkNode* node) {
903 CheckExitCondition();
904 }
905
906 void BookmarkConditionChecker::BookmarkAllUserNodesRemoved(
907 BookmarkModel* model,
908 const std::set<GURL>& removed_urls) {
909 CheckExitCondition();
910 }
911
912 void BookmarkConditionChecker::Wait() {
913 for (int i = 0; i < sync_datatype_helper::test()->num_clients(); ++i) {
914 GetBookmarkModel(i)->AddObserver(this);
915 }
916 registered_ = true;
917
918 if (IsExitConditionSatisfied()) {
919 VLOG(1) << "Finished without wait: " << GetDebugMessage();
920 return;
921 }
922
923 StartBlockingWait();
924 }
925
926 bool AwaitAllModelsMatch() {
927 BookmarkConditionChecker checker(base::Bind(&AllModelsMatch),
928 "Waiting for models to match");
929 checker.Wait();
930 return !checker.TimedOut();
931 }
932
933 bool AwaitAllModelsMatchVerifier() {
934 BookmarkConditionChecker checker(base::Bind(&AllModelsMatchVerifier),
935 "Waiting for models to match verifier");
936 checker.Wait();
937 return !checker.TimedOut();
938 }
939
825 } // namespace bookmarks_helper 940 } // namespace bookmarks_helper
OLDNEW
« no previous file with comments | « chrome/browser/sync/test/integration/bookmarks_helper.h ('k') | chrome/browser/sync/test/integration/status_change_checker.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698