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 #include "sync/engine/process_commit_response_command.h" | 5 #include "sync/engine/process_commit_response_command.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/location.h" | 9 #include "base/location.h" |
10 #include "base/stringprintf.h" | 10 #include "base/stringprintf.h" |
11 #include "sync/protocol/bookmark_specifics.pb.h" | 11 #include "sync/protocol/bookmark_specifics.pb.h" |
12 #include "sync/protocol/sync.pb.h" | 12 #include "sync/protocol/sync.pb.h" |
13 #include "sync/sessions/sync_session.h" | 13 #include "sync/sessions/sync_session.h" |
14 #include "sync/syncable/entry.h" | 14 #include "sync/syncable/entry.h" |
15 #include "sync/syncable/mutable_entry.h" | 15 #include "sync/syncable/mutable_entry.h" |
16 #include "sync/syncable/read_transaction.h" | 16 #include "sync/syncable/read_transaction.h" |
17 #include "sync/syncable/syncable_id.h" | 17 #include "sync/syncable/syncable_id.h" |
| 18 #include "sync/syncable/syncable_proto_util.h" |
18 #include "sync/syncable/write_transaction.h" | 19 #include "sync/syncable/write_transaction.h" |
19 #include "sync/test/engine/fake_model_worker.h" | 20 #include "sync/test/engine/fake_model_worker.h" |
20 #include "sync/test/engine/syncer_command_test.h" | 21 #include "sync/test/engine/syncer_command_test.h" |
21 #include "sync/test/engine/test_id_factory.h" | 22 #include "sync/test/engine/test_id_factory.h" |
22 #include "testing/gtest/include/gtest/gtest.h" | 23 #include "testing/gtest/include/gtest/gtest.h" |
23 | 24 |
| 25 using std::string; |
| 26 using sync_pb::ClientToServerMessage; |
| 27 using sync_pb::CommitResponse; |
| 28 |
24 namespace syncer { | 29 namespace syncer { |
25 | 30 |
26 using sessions::SyncSession; | 31 using sessions::SyncSession; |
27 using std::string; | |
28 using syncable::BASE_VERSION; | 32 using syncable::BASE_VERSION; |
29 using syncable::Entry; | 33 using syncable::Entry; |
30 using syncable::IS_DIR; | 34 using syncable::IS_DIR; |
31 using syncable::IS_UNSYNCED; | 35 using syncable::IS_UNSYNCED; |
32 using syncable::Id; | 36 using syncable::Id; |
33 using syncable::MutableEntry; | 37 using syncable::MutableEntry; |
34 using syncable::NON_UNIQUE_NAME; | 38 using syncable::NON_UNIQUE_NAME; |
35 using syncable::UNITTEST; | 39 using syncable::UNITTEST; |
36 using syncable::WriteTransaction; | 40 using syncable::WriteTransaction; |
37 | 41 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 // Create a new unsynced item in the database, and synthesize a commit | 115 // Create a new unsynced item in the database, and synthesize a commit |
112 // record and a commit response for it in the syncer session. If item_id | 116 // record and a commit response for it in the syncer session. If item_id |
113 // is a local ID, the item will be a create operation. Otherwise, it | 117 // is a local ID, the item will be a create operation. Otherwise, it |
114 // will be an edit. | 118 // will be an edit. |
115 void CreateUnprocessedCommitResult( | 119 void CreateUnprocessedCommitResult( |
116 const Id& item_id, | 120 const Id& item_id, |
117 const Id& parent_id, | 121 const Id& parent_id, |
118 const string& name, | 122 const string& name, |
119 syncer::ModelType model_type, | 123 syncer::ModelType model_type, |
120 sessions::OrderedCommitSet *commit_set, | 124 sessions::OrderedCommitSet *commit_set, |
121 syncer::ClientToServerMessage *commit, | 125 sync_pb::ClientToServerMessage *commit, |
122 syncer::ClientToServerResponse *response) { | 126 sync_pb::ClientToServerResponse *response) { |
123 bool is_folder = true; | 127 bool is_folder = true; |
124 int64 metahandle = 0; | 128 int64 metahandle = 0; |
125 CreateUnsyncedItem(item_id, parent_id, name, is_folder, model_type, | 129 CreateUnsyncedItem(item_id, parent_id, name, is_folder, model_type, |
126 &metahandle); | 130 &metahandle); |
127 | 131 |
128 // ProcessCommitResponseCommand consumes commit_ids from the session | 132 // ProcessCommitResponseCommand consumes commit_ids from the session |
129 // state, so we need to update that. O(n^2) because it's a test. | 133 // state, so we need to update that. O(n^2) because it's a test. |
130 commit_set->AddCommitItem(metahandle, item_id, model_type); | 134 commit_set->AddCommitItem(metahandle, item_id, model_type); |
131 | 135 |
132 WriteTransaction trans(FROM_HERE, UNITTEST, directory()); | 136 WriteTransaction trans(FROM_HERE, UNITTEST, directory()); |
133 MutableEntry entry(&trans, syncable::GET_BY_ID, item_id); | 137 MutableEntry entry(&trans, syncable::GET_BY_ID, item_id); |
134 ASSERT_TRUE(entry.good()); | 138 ASSERT_TRUE(entry.good()); |
135 entry.Put(syncable::SYNCING, true); | 139 entry.Put(syncable::SYNCING, true); |
136 | 140 |
137 // Add to the commit message. | 141 // Add to the commit message. |
138 commit->set_message_contents(ClientToServerMessage::COMMIT); | 142 commit->set_message_contents(ClientToServerMessage::COMMIT); |
139 SyncEntity* entity = static_cast<SyncEntity*>( | 143 sync_pb::SyncEntity* entity = commit->mutable_commit()->add_entries(); |
140 commit->mutable_commit()->add_entries()); | |
141 entity->set_non_unique_name(name); | 144 entity->set_non_unique_name(name); |
142 entity->set_folder(is_folder); | 145 entity->set_folder(is_folder); |
143 entity->set_parent_id(parent_id); | 146 entity->set_parent_id_string(SyncableIdToProto(parent_id)); |
144 entity->set_version(entry.Get(syncable::BASE_VERSION)); | 147 entity->set_version(entry.Get(syncable::BASE_VERSION)); |
145 entity->mutable_specifics()->CopyFrom(entry.Get(syncable::SPECIFICS)); | 148 entity->mutable_specifics()->CopyFrom(entry.Get(syncable::SPECIFICS)); |
146 entity->set_id(item_id); | 149 entity->set_id_string(SyncableIdToProto(item_id)); |
147 | 150 |
148 // Add to the response message. | 151 // Add to the response message. |
149 response->set_error_code(sync_pb::SyncEnums::SUCCESS); | 152 response->set_error_code(sync_pb::SyncEnums::SUCCESS); |
150 sync_pb::CommitResponse_EntryResponse* entry_response = | 153 sync_pb::CommitResponse_EntryResponse* entry_response = |
151 response->mutable_commit()->add_entryresponse(); | 154 response->mutable_commit()->add_entryresponse(); |
152 entry_response->set_response_type(CommitResponse::SUCCESS); | 155 entry_response->set_response_type(CommitResponse::SUCCESS); |
153 entry_response->set_name("Garbage."); | 156 entry_response->set_name("Garbage."); |
154 entry_response->set_non_unique_name(entity->name()); | 157 entry_response->set_non_unique_name(entity->name()); |
155 if (item_id.ServerKnows()) | 158 if (item_id.ServerKnows()) |
156 entry_response->set_id_string(entity->id_string()); | 159 entry_response->set_id_string(entity->id_string()); |
157 else | 160 else |
158 entry_response->set_id_string(id_factory_.NewServerId().GetServerId()); | 161 entry_response->set_id_string(id_factory_.NewServerId().GetServerId()); |
159 entry_response->set_version(next_new_revision_++); | 162 entry_response->set_version(next_new_revision_++); |
160 entry_response->set_position_in_parent(next_server_position_++); | 163 entry_response->set_position_in_parent(next_server_position_++); |
161 | 164 |
162 // If the ID of our parent item committed earlier in the batch was | 165 // If the ID of our parent item committed earlier in the batch was |
163 // rewritten, rewrite it in the entry response. This matches | 166 // rewritten, rewrite it in the entry response. This matches |
164 // the server behavior. | 167 // the server behavior. |
165 entry_response->set_parent_id_string(entity->parent_id_string()); | 168 entry_response->set_parent_id_string(entity->parent_id_string()); |
166 for (int i = 0; i < commit->commit().entries_size(); ++i) { | 169 for (int i = 0; i < commit->commit().entries_size(); ++i) { |
167 if (commit->commit().entries(i).id_string() == | 170 if (commit->commit().entries(i).id_string() == |
168 entity->parent_id_string()) { | 171 entity->parent_id_string()) { |
169 entry_response->set_parent_id_string( | 172 entry_response->set_parent_id_string( |
170 response->commit().entryresponse(i).id_string()); | 173 response->commit().entryresponse(i).id_string()); |
171 } | 174 } |
172 } | 175 } |
173 } | 176 } |
174 | 177 |
175 void SetLastErrorCode(CommitResponse::ResponseType error_code, | 178 void SetLastErrorCode(sync_pb::CommitResponse::ResponseType error_code, |
176 sync_pb::ClientToServerResponse* response) { | 179 sync_pb::ClientToServerResponse* response) { |
177 sync_pb::CommitResponse_EntryResponse* entry_response = | 180 sync_pb::CommitResponse_EntryResponse* entry_response = |
178 response->mutable_commit()->mutable_entryresponse( | 181 response->mutable_commit()->mutable_entryresponse( |
179 response->mutable_commit()->entryresponse_size() - 1); | 182 response->mutable_commit()->entryresponse_size() - 1); |
180 entry_response->set_response_type(error_code); | 183 entry_response->set_response_type(error_code); |
181 } | 184 } |
182 | 185 |
183 TestIdFactory id_factory_; | 186 TestIdFactory id_factory_; |
184 private: | 187 private: |
185 int64 next_old_revision_; | 188 int64 next_old_revision_; |
186 int64 next_new_revision_; | 189 int64 next_new_revision_; |
187 int64 next_server_position_; | 190 int64 next_server_position_; |
188 DISALLOW_COPY_AND_ASSIGN(ProcessCommitResponseCommandTest); | 191 DISALLOW_COPY_AND_ASSIGN(ProcessCommitResponseCommandTest); |
189 }; | 192 }; |
190 | 193 |
191 TEST_F(ProcessCommitResponseCommandTest, MultipleCommitIdProjections) { | 194 TEST_F(ProcessCommitResponseCommandTest, MultipleCommitIdProjections) { |
192 sessions::OrderedCommitSet commit_set(session()->routing_info()); | 195 sessions::OrderedCommitSet commit_set(session()->routing_info()); |
193 syncer::ClientToServerMessage request; | 196 sync_pb::ClientToServerMessage request; |
194 syncer::ClientToServerResponse response; | 197 sync_pb::ClientToServerResponse response; |
195 | 198 |
196 Id bookmark_folder_id = id_factory_.NewLocalId(); | 199 Id bookmark_folder_id = id_factory_.NewLocalId(); |
197 Id bookmark_id1 = id_factory_.NewLocalId(); | 200 Id bookmark_id1 = id_factory_.NewLocalId(); |
198 Id bookmark_id2 = id_factory_.NewLocalId(); | 201 Id bookmark_id2 = id_factory_.NewLocalId(); |
199 Id pref_id1 = id_factory_.NewLocalId(), pref_id2 = id_factory_.NewLocalId(); | 202 Id pref_id1 = id_factory_.NewLocalId(), pref_id2 = id_factory_.NewLocalId(); |
200 Id autofill_id1 = id_factory_.NewLocalId(); | 203 Id autofill_id1 = id_factory_.NewLocalId(); |
201 Id autofill_id2 = id_factory_.NewLocalId(); | 204 Id autofill_id2 = id_factory_.NewLocalId(); |
202 CreateUnprocessedCommitResult(bookmark_folder_id, id_factory_.root(), | 205 CreateUnprocessedCommitResult(bookmark_folder_id, id_factory_.root(), |
203 "A bookmark folder", syncer::BOOKMARKS, | 206 "A bookmark folder", syncer::BOOKMARKS, |
204 &commit_set, &request, &response); | 207 &commit_set, &request, &response); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 // In particular, the folder has 50 children, which alternate between being | 270 // In particular, the folder has 50 children, which alternate between being |
268 // new items and preexisting items. This mixture of new and old is meant to | 271 // new items and preexisting items. This mixture of new and old is meant to |
269 // be a torture test of the code in ProcessCommitResponseCommand that changes | 272 // be a torture test of the code in ProcessCommitResponseCommand that changes |
270 // an item's ID from a local ID to a server-generated ID on the first commit. | 273 // an item's ID from a local ID to a server-generated ID on the first commit. |
271 // We commit only the first 25 children in the sibling order, leaving the | 274 // We commit only the first 25 children in the sibling order, leaving the |
272 // second 25 children as unsynced items. http://crbug.com/33081 describes | 275 // second 25 children as unsynced items. http://crbug.com/33081 describes |
273 // how this scenario used to fail, reversing the order for the second half | 276 // how this scenario used to fail, reversing the order for the second half |
274 // of the children. | 277 // of the children. |
275 TEST_F(ProcessCommitResponseCommandTest, NewFolderCommitKeepsChildOrder) { | 278 TEST_F(ProcessCommitResponseCommandTest, NewFolderCommitKeepsChildOrder) { |
276 sessions::OrderedCommitSet commit_set(session()->routing_info()); | 279 sessions::OrderedCommitSet commit_set(session()->routing_info()); |
277 syncer::ClientToServerMessage request; | 280 sync_pb::ClientToServerMessage request; |
278 syncer::ClientToServerResponse response; | 281 sync_pb::ClientToServerResponse response; |
279 | 282 |
280 // Create the parent folder, a new item whose ID will change on commit. | 283 // Create the parent folder, a new item whose ID will change on commit. |
281 Id folder_id = id_factory_.NewLocalId(); | 284 Id folder_id = id_factory_.NewLocalId(); |
282 CreateUnprocessedCommitResult(folder_id, id_factory_.root(), "A", | 285 CreateUnprocessedCommitResult(folder_id, id_factory_.root(), "A", |
283 syncer::BOOKMARKS, | 286 syncer::BOOKMARKS, |
284 &commit_set, &request, &response); | 287 &commit_set, &request, &response); |
285 | 288 |
286 // Verify that the item is reachable. | 289 // Verify that the item is reachable. |
287 { | 290 { |
288 syncable::ReadTransaction trans(FROM_HERE, directory()); | 291 syncable::ReadTransaction trans(FROM_HERE, directory()); |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 }; | 398 }; |
396 INSTANTIATE_TEST_CASE_P(ProcessCommitResponse, | 399 INSTANTIATE_TEST_CASE_P(ProcessCommitResponse, |
397 MixedResult, | 400 MixedResult, |
398 testing::Range(0, 1 << TEST_PARAM_BIT_COUNT)); | 401 testing::Range(0, 1 << TEST_PARAM_BIT_COUNT)); |
399 | 402 |
400 // This test commits 2 items (one bookmark, one autofill) and validates what | 403 // This test commits 2 items (one bookmark, one autofill) and validates what |
401 // happens to the extensions activity records. Commits could fail or succeed, | 404 // happens to the extensions activity records. Commits could fail or succeed, |
402 // depending on the test parameter. | 405 // depending on the test parameter. |
403 TEST_P(MixedResult, ExtensionActivity) { | 406 TEST_P(MixedResult, ExtensionActivity) { |
404 sessions::OrderedCommitSet commit_set(session()->routing_info()); | 407 sessions::OrderedCommitSet commit_set(session()->routing_info()); |
405 syncer::ClientToServerMessage request; | 408 sync_pb::ClientToServerMessage request; |
406 syncer::ClientToServerResponse response; | 409 sync_pb::ClientToServerResponse response; |
407 | 410 |
408 EXPECT_NE(routing_info().find(syncer::BOOKMARKS)->second, | 411 EXPECT_NE(routing_info().find(syncer::BOOKMARKS)->second, |
409 routing_info().find(syncer::AUTOFILL)->second) | 412 routing_info().find(syncer::AUTOFILL)->second) |
410 << "To not be lame, this test requires more than one active group."; | 413 << "To not be lame, this test requires more than one active group."; |
411 | 414 |
412 // Bookmark item setup. | 415 // Bookmark item setup. |
413 CreateUnprocessedCommitResult(id_factory_.NewServerId(), | 416 CreateUnprocessedCommitResult(id_factory_.NewServerId(), |
414 id_factory_.root(), "Some bookmark", syncer::BOOKMARKS, | 417 id_factory_.root(), "Some bookmark", syncer::BOOKMARKS, |
415 &commit_set, &request, &response); | 418 &commit_set, &request, &response); |
416 if (ShouldFailBookmarkCommit()) | 419 if (ShouldFailBookmarkCommit()) |
(...skipping 28 matching lines...) Expand all Loading... |
445 EXPECT_EQ("xyz", final_monitor_records["xyz"].extension_id); | 448 EXPECT_EQ("xyz", final_monitor_records["xyz"].extension_id); |
446 EXPECT_EQ(2049U, final_monitor_records["ABC"].bookmark_write_count); | 449 EXPECT_EQ(2049U, final_monitor_records["ABC"].bookmark_write_count); |
447 EXPECT_EQ(4U, final_monitor_records["xyz"].bookmark_write_count); | 450 EXPECT_EQ(4U, final_monitor_records["xyz"].bookmark_write_count); |
448 } else { | 451 } else { |
449 EXPECT_TRUE(final_monitor_records.empty()) | 452 EXPECT_TRUE(final_monitor_records.empty()) |
450 << "Should not restore records after successful bookmark commit."; | 453 << "Should not restore records after successful bookmark commit."; |
451 } | 454 } |
452 } | 455 } |
453 | 456 |
454 } // namespace syncer | 457 } // namespace syncer |
OLD | NEW |