OLD | NEW |
---|---|
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 // TODO(akalin): This file is basically just a unit test for | 5 // TODO(akalin): This file is basically just a unit test for |
6 // BookmarkChangeProcessor. Write unit tests for | 6 // BookmarkChangeProcessor. Write unit tests for |
7 // BookmarkModelAssociator separately. | 7 // BookmarkModelAssociator separately. |
8 | 8 |
9 #include <map> | |
10 #include <queue> | |
9 #include <stack> | 11 #include <stack> |
10 #include <vector> | 12 #include <vector> |
11 | 13 |
12 #include "base/command_line.h" | 14 #include "base/command_line.h" |
13 #include "base/file_path.h" | 15 #include "base/file_path.h" |
14 #include "base/file_util.h" | 16 #include "base/file_util.h" |
15 #include "base/location.h" | 17 #include "base/location.h" |
16 #include "base/memory/scoped_ptr.h" | 18 #include "base/memory/scoped_ptr.h" |
17 #include "base/message_loop.h" | 19 #include "base/message_loop.h" |
18 #include "base/string16.h" | 20 #include "base/string16.h" |
(...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
552 } | 554 } |
553 | 555 |
554 private: | 556 private: |
555 // Used by both |ui_thread_| and |file_thread_|. | 557 // Used by both |ui_thread_| and |file_thread_|. |
556 MessageLoop message_loop_; | 558 MessageLoop message_loop_; |
557 content::TestBrowserThread ui_thread_; | 559 content::TestBrowserThread ui_thread_; |
558 // Needed by |model_|. | 560 // Needed by |model_|. |
559 content::TestBrowserThread file_thread_; | 561 content::TestBrowserThread file_thread_; |
560 | 562 |
561 TestingProfile profile_; | 563 TestingProfile profile_; |
562 scoped_ptr<TestBookmarkModelAssociator> model_associator_; | |
563 | 564 |
564 protected: | 565 protected: |
565 BookmarkModel* model_; | 566 BookmarkModel* model_; |
566 syncer::TestUserShare test_user_share_; | 567 syncer::TestUserShare test_user_share_; |
567 scoped_ptr<BookmarkChangeProcessor> change_processor_; | 568 scoped_ptr<BookmarkChangeProcessor> change_processor_; |
569 scoped_ptr<TestBookmarkModelAssociator> model_associator_; | |
568 StrictMock<DataTypeErrorHandlerMock> mock_error_handler_; | 570 StrictMock<DataTypeErrorHandlerMock> mock_error_handler_; |
569 }; | 571 }; |
570 | 572 |
571 TEST_F(ProfileSyncServiceBookmarkTest, InitialState) { | 573 TEST_F(ProfileSyncServiceBookmarkTest, InitialState) { |
572 LoadBookmarkModel(DELETE_EXISTING_STORAGE, DONT_SAVE_TO_STORAGE); | 574 LoadBookmarkModel(DELETE_EXISTING_STORAGE, DONT_SAVE_TO_STORAGE); |
573 StartSync(); | 575 StartSync(); |
574 | 576 |
575 EXPECT_TRUE(other_bookmarks_id()); | 577 EXPECT_TRUE(other_bookmarks_id()); |
576 EXPECT_TRUE(bookmark_bar_id()); | 578 EXPECT_TRUE(bookmark_bar_id()); |
577 EXPECT_TRUE(mobile_bookmarks_id()); | 579 EXPECT_TRUE(mobile_bookmarks_id()); |
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
969 | 971 |
970 EXPECT_EQ(2, model_->other_node()->child_count()); | 972 EXPECT_EQ(2, model_->other_node()->child_count()); |
971 ExpectModelMatch(); | 973 ExpectModelMatch(); |
972 } | 974 } |
973 | 975 |
974 struct TestData { | 976 struct TestData { |
975 const wchar_t* title; | 977 const wchar_t* title; |
976 const char* url; | 978 const char* url; |
977 }; | 979 }; |
978 | 980 |
981 // Map from bookmark node ID to its version. | |
982 typedef std::map<int64, int64> BookmarkNodeVersionMap; | |
983 | |
979 // TODO(ncarter): Integrate the existing TestNode/PopulateNodeFromString code | 984 // TODO(ncarter): Integrate the existing TestNode/PopulateNodeFromString code |
980 // in the bookmark model unittest, to make it simpler to set up test data | 985 // in the bookmark model unittest, to make it simpler to set up test data |
981 // here (and reduce the amount of duplication among tests), and to reduce the | 986 // here (and reduce the amount of duplication among tests), and to reduce the |
982 // duplication. | 987 // duplication. |
983 class ProfileSyncServiceBookmarkTestWithData | 988 class ProfileSyncServiceBookmarkTestWithData |
984 : public ProfileSyncServiceBookmarkTest { | 989 : public ProfileSyncServiceBookmarkTest { |
985 public: | 990 public: |
986 ProfileSyncServiceBookmarkTestWithData(); | 991 ProfileSyncServiceBookmarkTestWithData(); |
987 | 992 |
988 protected: | 993 protected: |
989 // Populates or compares children of the given bookmark node from/with the | 994 // Populates or compares children of the given bookmark node from/with the |
990 // given test data array with the given size. |running_count| is updated as | 995 // given test data array with the given size. |running_count| is updated as |
991 // urls are added. It is used to set the creation date (or test the creation | 996 // urls are added. It is used to set the creation date (or test the creation |
992 // date for CompareWithTestData()). | 997 // date for CompareWithTestData()). |
993 void PopulateFromTestData(const BookmarkNode* node, | 998 void PopulateFromTestData(const BookmarkNode* node, |
994 const TestData* data, | 999 const TestData* data, |
995 int size, | 1000 int size, |
996 int* running_count); | 1001 int* running_count); |
997 void CompareWithTestData(const BookmarkNode* node, | 1002 void CompareWithTestData(const BookmarkNode* node, |
998 const TestData* data, | 1003 const TestData* data, |
999 int size, | 1004 int size, |
1000 int* running_count); | 1005 int* running_count); |
1001 | 1006 |
1002 void ExpectBookmarkModelMatchesTestData(); | 1007 void ExpectBookmarkModelMatchesTestData(); |
1003 void WriteTestDataToBookmarkModel(); | 1008 void WriteTestDataToBookmarkModel(); |
1004 | 1009 |
1010 // Verify transaction versions of bookmark nodes and sync nodes are equal | |
1011 // recursively. If node is in |version_expected|, versions should match | |
1012 // there, too. | |
1013 void ExpectTransactionVersionMatch( | |
1014 const BookmarkNode* node, | |
1015 const BookmarkNodeVersionMap& version_expected); | |
1016 | |
1005 private: | 1017 private: |
1006 const base::Time start_time_; | 1018 const base::Time start_time_; |
1007 | 1019 |
1008 DISALLOW_COPY_AND_ASSIGN(ProfileSyncServiceBookmarkTestWithData); | 1020 DISALLOW_COPY_AND_ASSIGN(ProfileSyncServiceBookmarkTestWithData); |
1009 }; | 1021 }; |
1010 | 1022 |
1011 namespace { | 1023 namespace { |
1012 | 1024 |
1013 // Constants for bookmark model that looks like: | 1025 // Constants for bookmark model that looks like: |
1014 // |-- Bookmark bar | 1026 // |-- Bookmark bar |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1127 DCHECK(node); | 1139 DCHECK(node); |
1128 DCHECK(data); | 1140 DCHECK(data); |
1129 DCHECK(node->is_folder()); | 1141 DCHECK(node->is_folder()); |
1130 for (int i = 0; i < size; ++i) { | 1142 for (int i = 0; i < size; ++i) { |
1131 const TestData& item = data[i]; | 1143 const TestData& item = data[i]; |
1132 if (item.url) { | 1144 if (item.url) { |
1133 const base::Time add_time = | 1145 const base::Time add_time = |
1134 start_time_ + base::TimeDelta::FromMinutes(*running_count); | 1146 start_time_ + base::TimeDelta::FromMinutes(*running_count); |
1135 model_->AddURLWithCreationTime(node, i, WideToUTF16Hack(item.title), | 1147 model_->AddURLWithCreationTime(node, i, WideToUTF16Hack(item.title), |
1136 GURL(item.url), add_time); | 1148 GURL(item.url), add_time); |
1137 (*running_count)++; | |
1138 } else { | 1149 } else { |
1139 model_->AddFolder(node, i, WideToUTF16Hack(item.title)); | 1150 model_->AddFolder(node, i, WideToUTF16Hack(item.title)); |
1140 } | 1151 } |
1152 (*running_count)++; | |
1141 } | 1153 } |
1142 } | 1154 } |
1143 | 1155 |
1144 void ProfileSyncServiceBookmarkTestWithData::CompareWithTestData( | 1156 void ProfileSyncServiceBookmarkTestWithData::CompareWithTestData( |
1145 const BookmarkNode* node, | 1157 const BookmarkNode* node, |
1146 const TestData* data, | 1158 const TestData* data, |
1147 int size, | 1159 int size, |
1148 int* running_count) { | 1160 int* running_count) { |
1149 DCHECK(node); | 1161 DCHECK(node); |
1150 DCHECK(data); | 1162 DCHECK(data); |
1151 DCHECK(node->is_folder()); | 1163 DCHECK(node->is_folder()); |
1152 ASSERT_EQ(size, node->child_count()); | 1164 ASSERT_EQ(size, node->child_count()); |
1153 for (int i = 0; i < size; ++i) { | 1165 for (int i = 0; i < size; ++i) { |
1154 const BookmarkNode* child_node = node->GetChild(i); | 1166 const BookmarkNode* child_node = node->GetChild(i); |
1155 const TestData& item = data[i]; | 1167 const TestData& item = data[i]; |
1156 GURL url = GURL(item.url == NULL ? "" : item.url); | 1168 GURL url = GURL(item.url == NULL ? "" : item.url); |
1157 BookmarkNode test_node(url); | 1169 BookmarkNode test_node(url); |
1158 test_node.SetTitle(WideToUTF16Hack(item.title)); | 1170 test_node.SetTitle(WideToUTF16Hack(item.title)); |
1159 EXPECT_EQ(child_node->GetTitle(), test_node.GetTitle()); | 1171 EXPECT_EQ(child_node->GetTitle(), test_node.GetTitle()); |
1160 if (item.url) { | 1172 if (item.url) { |
1161 EXPECT_FALSE(child_node->is_folder()); | 1173 EXPECT_FALSE(child_node->is_folder()); |
1162 EXPECT_TRUE(child_node->is_url()); | 1174 EXPECT_TRUE(child_node->is_url()); |
1163 EXPECT_EQ(child_node->url(), test_node.url()); | 1175 EXPECT_EQ(child_node->url(), test_node.url()); |
1164 const base::Time expected_time = | 1176 const base::Time expected_time = |
1165 start_time_ + base::TimeDelta::FromMinutes(*running_count); | 1177 start_time_ + base::TimeDelta::FromMinutes(*running_count); |
1166 EXPECT_EQ(expected_time.ToInternalValue(), | 1178 EXPECT_EQ(expected_time.ToInternalValue(), |
1167 child_node->date_added().ToInternalValue()); | 1179 child_node->date_added().ToInternalValue()); |
1168 (*running_count)++; | |
1169 } else { | 1180 } else { |
1170 EXPECT_TRUE(child_node->is_folder()); | 1181 EXPECT_TRUE(child_node->is_folder()); |
1171 EXPECT_FALSE(child_node->is_url()); | 1182 EXPECT_FALSE(child_node->is_url()); |
1172 } | 1183 } |
1184 (*running_count)++; | |
1173 } | 1185 } |
1174 } | 1186 } |
1175 | 1187 |
1176 // TODO(munjal): We should implement some way of generating random data and can | 1188 // TODO(munjal): We should implement some way of generating random data and can |
1177 // use the same seed to generate the same sequence. | 1189 // use the same seed to generate the same sequence. |
1178 void ProfileSyncServiceBookmarkTestWithData::WriteTestDataToBookmarkModel() { | 1190 void ProfileSyncServiceBookmarkTestWithData::WriteTestDataToBookmarkModel() { |
1179 const BookmarkNode* bookmarks_bar_node = model_->bookmark_bar_node(); | 1191 const BookmarkNode* bookmarks_bar_node = model_->bookmark_bar_node(); |
1180 int count = 0; | 1192 int count = 0; |
1181 PopulateFromTestData(bookmarks_bar_node, | 1193 PopulateFromTestData(bookmarks_bar_node, |
1182 kBookmarkBarChildren, | 1194 kBookmarkBarChildren, |
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1588 updates.ApplyPendingChanges(change_processor_.get()); | 1600 updates.ApplyPendingChanges(change_processor_.get()); |
1589 | 1601 |
1590 const BookmarkNode* node = model_->bookmark_bar_node()->GetChild(0); | 1602 const BookmarkNode* node = model_->bookmark_bar_node()->GetChild(0); |
1591 ASSERT_TRUE(node); | 1603 ASSERT_TRUE(node); |
1592 EXPECT_TRUE(node->is_url()); | 1604 EXPECT_TRUE(node->is_url()); |
1593 EXPECT_EQ(WideToUTF16Hack(kTitle), node->GetTitle()); | 1605 EXPECT_EQ(WideToUTF16Hack(kTitle), node->GetTitle()); |
1594 EXPECT_EQ(kUrl, node->url().possibly_invalid_spec()); | 1606 EXPECT_EQ(kUrl, node->url().possibly_invalid_spec()); |
1595 EXPECT_EQ(node->date_added(), base::Time::FromInternalValue(30)); | 1607 EXPECT_EQ(node->date_added(), base::Time::FromInternalValue(30)); |
1596 } | 1608 } |
1597 | 1609 |
1610 // Output transaction versions of |node| and nodes under it to |node_versions|. | |
1611 void GetTransactionVersions( | |
1612 const BookmarkNode* root, | |
1613 BookmarkNodeVersionMap *node_versions) { | |
Nicolas Zea
2012/11/08 19:05:08
fix asterisk
haitaol1
2012/11/08 19:18:47
Done.
| |
1614 node_versions->clear(); | |
1615 std::queue<const BookmarkNode*> nodes; | |
1616 nodes.push(root); | |
1617 while (!nodes.empty()) { | |
1618 const BookmarkNode* n = nodes.front(); | |
1619 nodes.pop(); | |
1620 | |
1621 std::string version_str; | |
1622 int64 version; | |
1623 EXPECT_TRUE(n->GetMetaInfo(kBookmarkTransactionVersionKey, &version_str)); | |
1624 EXPECT_TRUE(base::StringToInt64(version_str, &version)); | |
1625 | |
1626 (*node_versions)[n->id()] = version; | |
1627 for (int i = 0; i < n->child_count(); ++i) | |
1628 nodes.push(n->GetChild(i)); | |
1629 } | |
1630 } | |
1631 | |
1632 void ProfileSyncServiceBookmarkTestWithData::ExpectTransactionVersionMatch( | |
1633 const BookmarkNode* node, | |
1634 const BookmarkNodeVersionMap& version_expected) { | |
1635 syncer::ReadTransaction trans(FROM_HERE, test_user_share_.user_share()); | |
1636 | |
1637 BookmarkNodeVersionMap bnodes_versions; | |
1638 GetTransactionVersions(node, &bnodes_versions); | |
1639 for (BookmarkNodeVersionMap::const_iterator it = bnodes_versions.begin(); | |
1640 it != bnodes_versions.end(); ++it) { | |
1641 syncer::ReadNode sync_node(&trans); | |
1642 ASSERT_TRUE(model_associator_->InitSyncNodeFromChromeId(it->first, | |
1643 &sync_node)); | |
1644 EXPECT_EQ(sync_node.GetEntry()->Get(syncer::syncable::TRANSACTION_VERSION), | |
1645 it->second); | |
1646 BookmarkNodeVersionMap::const_iterator expected_ver_it = | |
1647 version_expected.find(it->first); | |
1648 if (expected_ver_it != version_expected.end()) | |
1649 EXPECT_EQ(expected_ver_it->second, it->second); | |
1650 } | |
1651 } | |
1652 | |
1653 // Test transaction versions of model and nodes are incremented after changes | |
1654 // are applied. | |
1655 TEST_F(ProfileSyncServiceBookmarkTestWithData, UpdateTransactionVersion) { | |
1656 LoadBookmarkModel(DELETE_EXISTING_STORAGE, DONT_SAVE_TO_STORAGE); | |
1657 StartSync(); | |
1658 WriteTestDataToBookmarkModel(); | |
1659 MessageLoop::current()->RunUntilIdle(); | |
1660 | |
1661 BookmarkNodeVersionMap initial_versions; | |
1662 | |
1663 // Verify transaction versions in sync model and bookmark model are equal | |
1664 // after WriteTestDataToBookmarkModel() created bookmarks. | |
1665 { | |
1666 syncer::ReadTransaction trans(FROM_HERE, test_user_share_.user_share()); | |
1667 EXPECT_GT(trans.GetModelVersion(syncer::BOOKMARKS), 0); | |
1668 GetTransactionVersions(model_->root_node(), &initial_versions); | |
1669 EXPECT_EQ(trans.GetModelVersion(syncer::BOOKMARKS), | |
1670 initial_versions[model_->root_node()->id()]); | |
1671 } | |
1672 ExpectTransactionVersionMatch(model_->bookmark_bar_node(), | |
1673 BookmarkNodeVersionMap()); | |
1674 ExpectTransactionVersionMatch(model_->other_node(), | |
1675 BookmarkNodeVersionMap()); | |
1676 ExpectTransactionVersionMatch(model_->mobile_node(), | |
1677 BookmarkNodeVersionMap()); | |
1678 | |
1679 // Verify model version is incremented and bookmark node versions remain | |
1680 // the same. | |
1681 const BookmarkNode* bookmark_bar = model_->bookmark_bar_node(); | |
1682 model_->Remove(bookmark_bar, 0); | |
Nicolas Zea
2012/11/08 19:05:08
Is removing a child expected to update the parent
haitaol1
2012/11/08 19:18:47
No. The relationship is one-way from child to pare
| |
1683 MessageLoop::current()->RunUntilIdle(); | |
1684 BookmarkNodeVersionMap new_versions; | |
1685 GetTransactionVersions(model_->root_node(), &new_versions); | |
1686 EXPECT_EQ(initial_versions[model_->root_node()->id()] + 1, | |
1687 new_versions[model_->root_node()->id()]); | |
1688 // HACK(haitaol): siblings of removed node are actually updated in sync model | |
1689 // because of NEXT_ID/PREV_ID. After switching to ordinal, | |
1690 // siblings will not get updated and the hack below can be | |
1691 // removed. | |
1692 model_->SetNodeMetaInfo(bookmark_bar->GetChild(0), | |
1693 kBookmarkTransactionVersionKey, "43"); | |
1694 initial_versions[bookmark_bar->GetChild(0)->id()] = 43; | |
1695 ExpectTransactionVersionMatch(model_->bookmark_bar_node(), initial_versions); | |
1696 ExpectTransactionVersionMatch(model_->other_node(), initial_versions); | |
1697 ExpectTransactionVersionMatch(model_->mobile_node(), initial_versions); | |
1698 | |
1699 // Verify model version and version of changed bookmark are incremented and | |
1700 // versions of others remain same. | |
1701 const BookmarkNode* changed_bookmark = | |
1702 model_->bookmark_bar_node()->GetChild(0); | |
1703 model_->SetTitle(changed_bookmark, WideToUTF16Hack(L"test")); | |
1704 MessageLoop::current()->RunUntilIdle(); | |
1705 GetTransactionVersions(model_->root_node(), &new_versions); | |
1706 EXPECT_EQ(initial_versions[model_->root_node()->id()] + 2, | |
Nicolas Zea
2012/11/08 19:05:08
why has the root node version gone up here? Does m
haitaol1
2012/11/08 19:18:47
The version on root node is for the whole model. S
Nicolas Zea
2012/11/08 19:26:00
Ah, I see. Maybe modify the test comment to make t
haitaol1
2012/11/08 19:44:25
Done.
| |
1707 new_versions[model_->root_node()->id()]); | |
1708 EXPECT_EQ(initial_versions[changed_bookmark->id()] + 1, | |
1709 new_versions[changed_bookmark->id()]); | |
1710 initial_versions.erase(changed_bookmark->id()); | |
1711 ExpectTransactionVersionMatch(model_->bookmark_bar_node(), initial_versions); | |
1712 ExpectTransactionVersionMatch(model_->other_node(), initial_versions); | |
1713 ExpectTransactionVersionMatch(model_->mobile_node(), initial_versions); | |
1714 } | |
1715 | |
1598 } // namespace | 1716 } // namespace |
1599 | 1717 |
1600 } // namespace browser_sync | 1718 } // namespace browser_sync |
OLD | NEW |