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

Side by Side Diff: chrome/browser/sync/engine/apply_updates_command_unittest.cc

Issue 6537027: Revert 75287 - [Sync] Initial support for encrypting any datatype (no UI hook... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years, 10 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
« no previous file with comments | « no previous file | chrome/browser/sync/engine/change_reorder_buffer.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2009 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 <string>
6
7 #include "base/format_macros.h"
8 #include "base/string_util.h"
9 #include "chrome/browser/sync/engine/apply_updates_command.h" 5 #include "chrome/browser/sync/engine/apply_updates_command.h"
10 #include "chrome/browser/sync/engine/syncer.h"
11 #include "chrome/browser/sync/engine/syncer_util.h"
12 #include "chrome/browser/sync/protocol/bookmark_specifics.pb.h" 6 #include "chrome/browser/sync/protocol/bookmark_specifics.pb.h"
13 #include "chrome/browser/sync/sessions/sync_session.h" 7 #include "chrome/browser/sync/sessions/sync_session.h"
14 #include "chrome/browser/sync/syncable/directory_manager.h" 8 #include "chrome/browser/sync/syncable/directory_manager.h"
15 #include "chrome/browser/sync/syncable/nigori_util.h"
16 #include "chrome/browser/sync/syncable/syncable.h" 9 #include "chrome/browser/sync/syncable/syncable.h"
17 #include "chrome/browser/sync/syncable/syncable_id.h" 10 #include "chrome/browser/sync/syncable/syncable_id.h"
18 #include "chrome/test/sync/engine/syncer_command_test.h" 11 #include "chrome/test/sync/engine/syncer_command_test.h"
19 #include "chrome/test/sync/engine/test_id_factory.h"
20 #include "testing/gtest/include/gtest/gtest.h" 12 #include "testing/gtest/include/gtest/gtest.h"
21 13
22 namespace browser_sync { 14 namespace browser_sync {
23 15
24 using sessions::SyncSession; 16 using sessions::SyncSession;
25 using std::string; 17 using std::string;
26 using syncable::Entry; 18 using syncable::Entry;
27 using syncable::GetEncryptedDataTypes;
28 using syncable::Id; 19 using syncable::Id;
29 using syncable::MutableEntry; 20 using syncable::MutableEntry;
30 using syncable::ReadTransaction; 21 using syncable::ReadTransaction;
31 using syncable::ScopedDirLookup; 22 using syncable::ScopedDirLookup;
32 using syncable::UNITTEST; 23 using syncable::UNITTEST;
33 using syncable::WriteTransaction; 24 using syncable::WriteTransaction;
34 25
35 // A test fixture for tests exercising ApplyUpdatesCommand. 26 // A test fixture for tests exercising ApplyUpdatesCommand.
36 class ApplyUpdatesCommandTest : public SyncerCommandTest { 27 class ApplyUpdatesCommandTest : public SyncerCommandTest {
37 public: 28 public:
38 protected: 29 protected:
39 ApplyUpdatesCommandTest() : next_revision_(1) {} 30 ApplyUpdatesCommandTest() : next_revision_(1) {}
40 virtual ~ApplyUpdatesCommandTest() {} 31 virtual ~ApplyUpdatesCommandTest() {}
41 32
42 virtual void SetUp() { 33 virtual void SetUp() {
43 workers()->clear(); 34 workers()->clear();
44 mutable_routing_info()->clear(); 35 mutable_routing_info()->clear();
45 // GROUP_PASSIVE worker. 36 // GROUP_PASSIVE worker.
46 workers()->push_back(make_scoped_refptr(new ModelSafeWorker())); 37 workers()->push_back(make_scoped_refptr(new ModelSafeWorker()));
47 (*mutable_routing_info())[syncable::BOOKMARKS] = GROUP_PASSIVE; 38 (*mutable_routing_info())[syncable::BOOKMARKS] = GROUP_PASSIVE;
48 (*mutable_routing_info())[syncable::PASSWORDS] = GROUP_PASSIVE; 39 (*mutable_routing_info())[syncable::PASSWORDS] = GROUP_PASSIVE;
49 (*mutable_routing_info())[syncable::NIGORI] = GROUP_PASSIVE; 40 (*mutable_routing_info())[syncable::NIGORI] = GROUP_PASSIVE;
50 SyncerCommandTest::SetUp(); 41 SyncerCommandTest::SetUp();
51 } 42 }
52 43
53 // Create a new unapplied bookmark node with a parent. 44 // Create a new unapplied update.
54 void CreateUnappliedNewItemWithParent(const string& item_id, 45 void CreateUnappliedNewItemWithParent(const string& item_id,
55 const string& parent_id) { 46 const string& parent_id) {
56 ScopedDirLookup dir(syncdb()->manager(), syncdb()->name()); 47 ScopedDirLookup dir(syncdb()->manager(), syncdb()->name());
57 ASSERT_TRUE(dir.good()); 48 ASSERT_TRUE(dir.good());
58 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); 49 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__);
59 MutableEntry entry(&trans, syncable::CREATE_NEW_UPDATE_ITEM, 50 MutableEntry entry(&trans, syncable::CREATE_NEW_UPDATE_ITEM,
60 Id::CreateFromServerId(item_id)); 51 Id::CreateFromServerId(item_id));
61 ASSERT_TRUE(entry.good()); 52 ASSERT_TRUE(entry.good());
62 entry.Put(syncable::SERVER_VERSION, next_revision_++); 53 entry.Put(syncable::SERVER_VERSION, next_revision_++);
63 entry.Put(syncable::IS_UNAPPLIED_UPDATE, true); 54 entry.Put(syncable::IS_UNAPPLIED_UPDATE, true);
64 55
65 entry.Put(syncable::SERVER_NON_UNIQUE_NAME, item_id); 56 entry.Put(syncable::SERVER_NON_UNIQUE_NAME, item_id);
66 entry.Put(syncable::SERVER_PARENT_ID, Id::CreateFromServerId(parent_id)); 57 entry.Put(syncable::SERVER_PARENT_ID, Id::CreateFromServerId(parent_id));
67 entry.Put(syncable::SERVER_IS_DIR, true); 58 entry.Put(syncable::SERVER_IS_DIR, true);
68 sync_pb::EntitySpecifics default_bookmark_specifics; 59 sync_pb::EntitySpecifics default_bookmark_specifics;
69 default_bookmark_specifics.MutableExtension(sync_pb::bookmark); 60 default_bookmark_specifics.MutableExtension(sync_pb::bookmark);
70 entry.Put(syncable::SERVER_SPECIFICS, default_bookmark_specifics); 61 entry.Put(syncable::SERVER_SPECIFICS, default_bookmark_specifics);
71 } 62 }
72 63
73 // Create a new unapplied update without a parent.
74 void CreateUnappliedNewItem(const string& item_id, 64 void CreateUnappliedNewItem(const string& item_id,
75 const sync_pb::EntitySpecifics& specifics, 65 const sync_pb::EntitySpecifics& specifics) {
76 bool is_unique) {
77 ScopedDirLookup dir(syncdb()->manager(), syncdb()->name()); 66 ScopedDirLookup dir(syncdb()->manager(), syncdb()->name());
78 ASSERT_TRUE(dir.good()); 67 ASSERT_TRUE(dir.good());
79 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); 68 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__);
80 MutableEntry entry(&trans, syncable::CREATE_NEW_UPDATE_ITEM, 69 MutableEntry entry(&trans, syncable::CREATE_NEW_UPDATE_ITEM,
81 Id::CreateFromServerId(item_id)); 70 Id::CreateFromServerId(item_id));
82 ASSERT_TRUE(entry.good()); 71 ASSERT_TRUE(entry.good());
83 entry.Put(syncable::SERVER_VERSION, next_revision_++); 72 entry.Put(syncable::SERVER_VERSION, next_revision_++);
84 entry.Put(syncable::IS_UNAPPLIED_UPDATE, true); 73 entry.Put(syncable::IS_UNAPPLIED_UPDATE, true);
74
85 entry.Put(syncable::SERVER_NON_UNIQUE_NAME, item_id); 75 entry.Put(syncable::SERVER_NON_UNIQUE_NAME, item_id);
86 entry.Put(syncable::SERVER_PARENT_ID, syncable::kNullId); 76 entry.Put(syncable::SERVER_PARENT_ID, syncable::kNullId);
87 entry.Put(syncable::SERVER_IS_DIR, false); 77 entry.Put(syncable::SERVER_IS_DIR, false);
88 entry.Put(syncable::SERVER_SPECIFICS, specifics); 78 entry.Put(syncable::SERVER_SPECIFICS, specifics);
89 if (is_unique) // For top-level nodes.
90 entry.Put(syncable::UNIQUE_SERVER_TAG, item_id);
91 }
92
93 // Create an unsynced item in the database. If item_id is a local ID, it
94 // will be treated as a create-new. Otherwise, if it's a server ID, we'll
95 // fake the server data so that it looks like it exists on the server.
96 // Returns the methandle of the created item in |metahandle_out| if not NULL.
97 void CreateUnsyncedItem(const Id& item_id,
98 const Id& parent_id,
99 const string& name,
100 bool is_folder,
101 syncable::ModelType model_type,
102 int64* metahandle_out) {
103 ScopedDirLookup dir(syncdb()->manager(), syncdb()->name());
104 ASSERT_TRUE(dir.good());
105 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__);
106 Id predecessor_id = dir->GetLastChildId(&trans, parent_id);
107 MutableEntry entry(&trans, syncable::CREATE, parent_id, name);
108 ASSERT_TRUE(entry.good());
109 entry.Put(syncable::ID, item_id);
110 entry.Put(syncable::BASE_VERSION,
111 item_id.ServerKnows() ? next_revision_++ : 0);
112 entry.Put(syncable::IS_UNSYNCED, true);
113 entry.Put(syncable::IS_DIR, is_folder);
114 entry.Put(syncable::IS_DEL, false);
115 entry.Put(syncable::PARENT_ID, parent_id);
116 entry.PutPredecessor(predecessor_id);
117 sync_pb::EntitySpecifics default_specifics;
118 syncable::AddDefaultExtensionValue(model_type, &default_specifics);
119 entry.Put(syncable::SPECIFICS, default_specifics);
120 if (item_id.ServerKnows()) {
121 entry.Put(syncable::SERVER_SPECIFICS, default_specifics);
122 entry.Put(syncable::SERVER_IS_DIR, is_folder);
123 entry.Put(syncable::SERVER_PARENT_ID, parent_id);
124 entry.Put(syncable::SERVER_IS_DEL, false);
125 }
126 if (metahandle_out)
127 *metahandle_out = entry.Get(syncable::META_HANDLE);
128 } 79 }
129 80
130 ApplyUpdatesCommand apply_updates_command_; 81 ApplyUpdatesCommand apply_updates_command_;
131 TestIdFactory id_factory_; 82
132 private: 83 private:
133 int64 next_revision_; 84 int64 next_revision_;
134 DISALLOW_COPY_AND_ASSIGN(ApplyUpdatesCommandTest); 85 DISALLOW_COPY_AND_ASSIGN(ApplyUpdatesCommandTest);
135 }; 86 };
136 87
137 TEST_F(ApplyUpdatesCommandTest, Simple) { 88 TEST_F(ApplyUpdatesCommandTest, Simple) {
138 string root_server_id = syncable::kNullId.GetServerId(); 89 string root_server_id = syncable::kNullId.GetServerId();
139 CreateUnappliedNewItemWithParent("parent", root_server_id); 90 CreateUnappliedNewItemWithParent("parent", root_server_id);
140 CreateUnappliedNewItemWithParent("child", "parent"); 91 CreateUnappliedNewItemWithParent("child", "parent");
141 92
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 171
221 browser_sync::KeyParams params = {"localhost", "dummy", "foobar"}; 172 browser_sync::KeyParams params = {"localhost", "dummy", "foobar"};
222 cryptographer->AddKey(params); 173 cryptographer->AddKey(params);
223 174
224 sync_pb::EntitySpecifics specifics; 175 sync_pb::EntitySpecifics specifics;
225 sync_pb::PasswordSpecificsData data; 176 sync_pb::PasswordSpecificsData data;
226 data.set_origin("http://example.com"); 177 data.set_origin("http://example.com");
227 178
228 cryptographer->Encrypt(data, 179 cryptographer->Encrypt(data,
229 specifics.MutableExtension(sync_pb::password)->mutable_encrypted()); 180 specifics.MutableExtension(sync_pb::password)->mutable_encrypted());
230 CreateUnappliedNewItem("item", specifics, false); 181 CreateUnappliedNewItem("item", specifics);
231 182
232 apply_updates_command_.ExecuteImpl(session()); 183 apply_updates_command_.ExecuteImpl(session());
233 184
234 sessions::StatusController* status = session()->status_controller(); 185 sessions::StatusController* status = session()->status_controller();
235 sessions::ScopedModelSafeGroupRestriction r(status, GROUP_PASSIVE); 186 sessions::ScopedModelSafeGroupRestriction r(status, GROUP_PASSIVE);
236 EXPECT_EQ(1, status->update_progress().AppliedUpdatesSize()) 187 EXPECT_EQ(1, status->update_progress().AppliedUpdatesSize())
237 << "All updates should have been attempted"; 188 << "All updates should have been attempted";
238 EXPECT_EQ(0, status->conflict_progress().ConflictingItemsSize()) 189 EXPECT_EQ(0, status->conflict_progress().ConflictingItemsSize())
239 << "No update should be in conflict because they're all decryptable"; 190 << "No update should be in conflict because they're all decryptable";
240 EXPECT_EQ(1, status->update_progress().SuccessfullyAppliedUpdateCount()) 191 EXPECT_EQ(1, status->update_progress().SuccessfullyAppliedUpdateCount())
241 << "The updates that can be decrypted should be applied"; 192 << "The updates that can be decrypted should be applied";
242 } 193 }
243 194
244 TEST_F(ApplyUpdatesCommandTest, UndecryptablePassword) { 195 TEST_F(ApplyUpdatesCommandTest, UndecryptablePassword) {
245 // Undecryptable password updates should not be applied. 196 // Undecryptable password updates should not be applied.
246 sync_pb::EntitySpecifics specifics; 197 sync_pb::EntitySpecifics specifics;
247 specifics.MutableExtension(sync_pb::password); 198 specifics.MutableExtension(sync_pb::password);
248 CreateUnappliedNewItem("item", specifics, false); 199 CreateUnappliedNewItem("item", specifics);
249 200
250 apply_updates_command_.ExecuteImpl(session()); 201 apply_updates_command_.ExecuteImpl(session());
251 202
252 sessions::StatusController* status = session()->status_controller(); 203 sessions::StatusController* status = session()->status_controller();
253 sessions::ScopedModelSafeGroupRestriction r(status, GROUP_PASSIVE); 204 sessions::ScopedModelSafeGroupRestriction r(status, GROUP_PASSIVE);
254 EXPECT_EQ(1, status->update_progress().AppliedUpdatesSize()) 205 EXPECT_EQ(1, status->update_progress().AppliedUpdatesSize())
255 << "All updates should have been attempted"; 206 << "All updates should have been attempted";
256 EXPECT_EQ(1, status->conflict_progress().ConflictingItemsSize()) 207 EXPECT_EQ(1, status->conflict_progress().ConflictingItemsSize())
257 << "The updates that can't be decrypted should be in conflict"; 208 << "The updates that can't be decrypted should be in conflict";
258 EXPECT_EQ(0, status->update_progress().SuccessfullyAppliedUpdateCount()) 209 EXPECT_EQ(0, status->update_progress().SuccessfullyAppliedUpdateCount())
259 << "No update that can't be decrypted should be applied"; 210 << "No update that can't be decrypted should be applied";
260 } 211 }
261 212
262 TEST_F(ApplyUpdatesCommandTest, SomeUndecryptablePassword) { 213 TEST_F(ApplyUpdatesCommandTest, SomeUndecryptablePassword) {
263 // Only decryptable password updates should be applied. 214 // Only decryptable password updates should be applied.
264 { 215 {
265 Cryptographer* cryptographer = 216 Cryptographer* cryptographer =
266 session()->context()->directory_manager()->cryptographer(); 217 session()->context()->directory_manager()->cryptographer();
267 218
268 KeyParams params = {"localhost", "dummy", "foobar"}; 219 KeyParams params = {"localhost", "dummy", "foobar"};
269 cryptographer->AddKey(params); 220 cryptographer->AddKey(params);
270 221
271 sync_pb::EntitySpecifics specifics; 222 sync_pb::EntitySpecifics specifics;
272 sync_pb::PasswordSpecificsData data; 223 sync_pb::PasswordSpecificsData data;
273 data.set_origin("http://example.com/1"); 224 data.set_origin("http://example.com/1");
274 225
275 cryptographer->Encrypt(data, 226 cryptographer->Encrypt(data,
276 specifics.MutableExtension(sync_pb::password)->mutable_encrypted()); 227 specifics.MutableExtension(sync_pb::password)->mutable_encrypted());
277 CreateUnappliedNewItem("item1", specifics, false); 228 CreateUnappliedNewItem("item1", specifics);
278 } 229 }
279 { 230 {
280 // Create a new cryptographer, independent of the one in the session. 231 // Create a new cryptographer, independent of the one in the session.
281 Cryptographer cryptographer; 232 Cryptographer cryptographer;
282 KeyParams params = {"localhost", "dummy", "bazqux"}; 233 KeyParams params = {"localhost", "dummy", "bazqux"};
283 cryptographer.AddKey(params); 234 cryptographer.AddKey(params);
284 235
285 sync_pb::EntitySpecifics specifics; 236 sync_pb::EntitySpecifics specifics;
286 sync_pb::PasswordSpecificsData data; 237 sync_pb::PasswordSpecificsData data;
287 data.set_origin("http://example.com/2"); 238 data.set_origin("http://example.com/2");
288 239
289 cryptographer.Encrypt(data, 240 cryptographer.Encrypt(data,
290 specifics.MutableExtension(sync_pb::password)->mutable_encrypted()); 241 specifics.MutableExtension(sync_pb::password)->mutable_encrypted());
291 CreateUnappliedNewItem("item2", specifics, false); 242 CreateUnappliedNewItem("item2", specifics);
292 } 243 }
293 244
294 apply_updates_command_.ExecuteImpl(session()); 245 apply_updates_command_.ExecuteImpl(session());
295 246
296 sessions::StatusController* status = session()->status_controller(); 247 sessions::StatusController* status = session()->status_controller();
297 sessions::ScopedModelSafeGroupRestriction r(status, GROUP_PASSIVE); 248 sessions::ScopedModelSafeGroupRestriction r(status, GROUP_PASSIVE);
298 EXPECT_EQ(2, status->update_progress().AppliedUpdatesSize()) 249 EXPECT_EQ(2, status->update_progress().AppliedUpdatesSize())
299 << "All updates should have been attempted"; 250 << "All updates should have been attempted";
300 EXPECT_EQ(1, status->conflict_progress().ConflictingItemsSize()) 251 EXPECT_EQ(1, status->conflict_progress().ConflictingItemsSize())
301 << "The decryptable password update should be applied"; 252 << "The decryptable password update should be applied";
302 EXPECT_EQ(1, status->update_progress().SuccessfullyAppliedUpdateCount()) 253 EXPECT_EQ(1, status->update_progress().SuccessfullyAppliedUpdateCount())
303 << "The undecryptable password update shouldn't be applied"; 254 << "The undecryptable password update shouldn't be applied";
304 } 255 }
305 256
306 TEST_F(ApplyUpdatesCommandTest, NigoriUpdate) { 257 TEST_F(ApplyUpdatesCommandTest, NigoriUpdate) {
307 syncable::ModelTypeSet encrypted_types;
308 {
309 ScopedDirLookup dir(syncdb()->manager(), syncdb()->name());
310 ASSERT_TRUE(dir.good());
311 ReadTransaction trans(dir, __FILE__, __LINE__);
312 EXPECT_EQ(encrypted_types, GetEncryptedDataTypes(&trans));
313 }
314
315 // Nigori node updates should update the Cryptographer. 258 // Nigori node updates should update the Cryptographer.
316 Cryptographer other_cryptographer; 259 Cryptographer other_cryptographer;
317 KeyParams params = {"localhost", "dummy", "foobar"}; 260 KeyParams params = {"localhost", "dummy", "foobar"};
318 other_cryptographer.AddKey(params); 261 other_cryptographer.AddKey(params);
319 262
320 sync_pb::EntitySpecifics specifics; 263 sync_pb::EntitySpecifics specifics;
321 sync_pb::NigoriSpecifics* nigori = 264 other_cryptographer.GetKeys(
322 specifics.MutableExtension(sync_pb::nigori); 265 specifics.MutableExtension(sync_pb::nigori)->mutable_encrypted());
323 other_cryptographer.GetKeys(nigori->mutable_encrypted()); 266
324 nigori->set_encrypt_bookmarks(true); 267 CreateUnappliedNewItem("item", specifics);
325 encrypted_types.insert(syncable::BOOKMARKS);
326 CreateUnappliedNewItem(syncable::ModelTypeToRootTag(syncable::NIGORI),
327 specifics, true);
328 268
329 Cryptographer* cryptographer = 269 Cryptographer* cryptographer =
330 session()->context()->directory_manager()->cryptographer(); 270 session()->context()->directory_manager()->cryptographer();
331 EXPECT_FALSE(cryptographer->has_pending_keys()); 271 EXPECT_FALSE(cryptographer->has_pending_keys());
332 272
333 apply_updates_command_.ExecuteImpl(session()); 273 apply_updates_command_.ExecuteImpl(session());
334 274
335 sessions::StatusController* status = session()->status_controller(); 275 sessions::StatusController* status = session()->status_controller();
336 sessions::ScopedModelSafeGroupRestriction r(status, GROUP_PASSIVE);
337 EXPECT_EQ(1, status->update_progress().AppliedUpdatesSize())
338 << "All updates should have been attempted";
339 EXPECT_EQ(0, status->conflict_progress().ConflictingItemsSize())
340 << "The nigori update shouldn't be in conflict";
341 EXPECT_EQ(1, status->update_progress().SuccessfullyAppliedUpdateCount())
342 << "The nigori update should be applied";
343
344 EXPECT_FALSE(cryptographer->is_ready());
345 EXPECT_TRUE(cryptographer->has_pending_keys());
346 }
347
348 TEST_F(ApplyUpdatesCommandTest, EncryptUnsyncedChanges) {
349 syncable::ModelTypeSet encrypted_types;
350 {
351 ScopedDirLookup dir(syncdb()->manager(), syncdb()->name());
352 ASSERT_TRUE(dir.good());
353 ReadTransaction trans(dir, __FILE__, __LINE__);
354 EXPECT_EQ(encrypted_types, GetEncryptedDataTypes(&trans));
355
356 // With empty encrypted_types, this should be true.
357 EXPECT_TRUE(VerifyUnsyncedChangesAreEncrypted(&trans, encrypted_types));
358
359 Syncer::UnsyncedMetaHandles handles;
360 SyncerUtil::GetUnsyncedEntries(&trans, &handles);
361 EXPECT_TRUE(handles.empty());
362 }
363
364 // Create unsynced bookmarks without encryption.
365 // First item is a folder
366 Id folder_id = id_factory_.NewLocalId();
367 CreateUnsyncedItem(folder_id, id_factory_.root(), "folder",
368 true, syncable::BOOKMARKS, NULL);
369 // Next five items are children of the folder
370 size_t i;
371 size_t batch_s = 5;
372 for (i = 0; i < batch_s; ++i) {
373 CreateUnsyncedItem(id_factory_.NewLocalId(), folder_id,
374 StringPrintf("Item %"PRIuS"", i), false,
375 syncable::BOOKMARKS, NULL);
376 }
377 // Next five items are children of the root.
378 for (; i < 2*batch_s; ++i) {
379 CreateUnsyncedItem(id_factory_.NewLocalId(), id_factory_.root(),
380 StringPrintf("Item %"PRIuS"", i), false,
381 syncable::BOOKMARKS, NULL);
382 }
383
384 Cryptographer* cryptographer =
385 session()->context()->directory_manager()->cryptographer();
386 KeyParams params = {"localhost", "dummy", "foobar"};
387 cryptographer->AddKey(params);
388 sync_pb::EntitySpecifics specifics;
389 sync_pb::NigoriSpecifics* nigori =
390 specifics.MutableExtension(sync_pb::nigori);
391 cryptographer->GetKeys(nigori->mutable_encrypted());
392 nigori->set_encrypt_bookmarks(true);
393 encrypted_types.insert(syncable::BOOKMARKS);
394 CreateUnappliedNewItem(syncable::ModelTypeToRootTag(syncable::NIGORI),
395 specifics, true);
396 EXPECT_FALSE(cryptographer->has_pending_keys());
397 EXPECT_TRUE(cryptographer->is_ready());
398
399 {
400 // Ensure we have unsynced nodes that aren't properly encrypted.
401 ScopedDirLookup dir(syncdb()->manager(), syncdb()->name());
402 ASSERT_TRUE(dir.good());
403 ReadTransaction trans(dir, __FILE__, __LINE__);
404 EXPECT_FALSE(VerifyUnsyncedChangesAreEncrypted(&trans, encrypted_types));
405
406 Syncer::UnsyncedMetaHandles handles;
407 SyncerUtil::GetUnsyncedEntries(&trans, &handles);
408 EXPECT_EQ(2*batch_s+1, handles.size());
409 }
410
411 apply_updates_command_.ExecuteImpl(session());
412
413 sessions::StatusController* status = session()->status_controller();
414 sessions::ScopedModelSafeGroupRestriction r(status, GROUP_PASSIVE); 276 sessions::ScopedModelSafeGroupRestriction r(status, GROUP_PASSIVE);
415 EXPECT_EQ(1, status->update_progress().AppliedUpdatesSize()) 277 EXPECT_EQ(1, status->update_progress().AppliedUpdatesSize())
416 << "All updates should have been attempted"; 278 << "All updates should have been attempted";
417 EXPECT_EQ(0, status->conflict_progress().ConflictingItemsSize()) 279 EXPECT_EQ(0, status->conflict_progress().ConflictingItemsSize())
418 << "The nigori update shouldn't be in conflict"; 280 << "The nigori update shouldn't be in conflict";
419 EXPECT_EQ(1, status->update_progress().SuccessfullyAppliedUpdateCount()) 281 EXPECT_EQ(1, status->update_progress().SuccessfullyAppliedUpdateCount())
420 << "The nigori update should be applied"; 282 << "The nigori update should be applied";
421 EXPECT_FALSE(cryptographer->has_pending_keys());
422 EXPECT_TRUE(cryptographer->is_ready());
423 {
424 ScopedDirLookup dir(syncdb()->manager(), syncdb()->name());
425 ASSERT_TRUE(dir.good());
426 ReadTransaction trans(dir, __FILE__, __LINE__);
427 283
428 // If ProcessUnsyncedChangesForEncryption worked, all our unsynced changes
429 // should be encrypted now.
430 EXPECT_EQ(encrypted_types, GetEncryptedDataTypes(&trans));
431 EXPECT_TRUE(VerifyUnsyncedChangesAreEncrypted(&trans, encrypted_types));
432
433 Syncer::UnsyncedMetaHandles handles;
434 SyncerUtil::GetUnsyncedEntries(&trans, &handles);
435 EXPECT_EQ(2*batch_s+1, handles.size());
436 }
437 }
438
439 TEST_F(ApplyUpdatesCommandTest, CannotEncryptUnsyncedChanges) {
440 syncable::ModelTypeSet encrypted_types;
441 {
442 ScopedDirLookup dir(syncdb()->manager(), syncdb()->name());
443 ASSERT_TRUE(dir.good());
444 ReadTransaction trans(dir, __FILE__, __LINE__);
445 EXPECT_EQ(encrypted_types, GetEncryptedDataTypes(&trans));
446
447 // With empty encrypted_types, this should be true.
448 EXPECT_TRUE(VerifyUnsyncedChangesAreEncrypted(&trans, encrypted_types));
449
450 Syncer::UnsyncedMetaHandles handles;
451 SyncerUtil::GetUnsyncedEntries(&trans, &handles);
452 EXPECT_TRUE(handles.empty());
453 }
454
455 // Create unsynced bookmarks without encryption.
456 // First item is a folder
457 Id folder_id = id_factory_.NewLocalId();
458 CreateUnsyncedItem(folder_id, id_factory_.root(), "folder", true,
459 syncable::BOOKMARKS, NULL);
460 // Next five items are children of the folder
461 size_t i;
462 size_t batch_s = 5;
463 for (i = 0; i < batch_s; ++i) {
464 CreateUnsyncedItem(id_factory_.NewLocalId(), folder_id,
465 StringPrintf("Item %"PRIuS"", i), false,
466 syncable::BOOKMARKS, NULL);
467 }
468 // Next five items are children of the root.
469 for (; i < 2*batch_s; ++i) {
470 CreateUnsyncedItem(id_factory_.NewLocalId(), id_factory_.root(),
471 StringPrintf("Item %"PRIuS"", i), false,
472 syncable::BOOKMARKS, NULL);
473 }
474
475 // We encrypt with new keys, triggering the local cryptographer to be unready
476 // and unable to decrypt data (once updated).
477 Cryptographer other_cryptographer;
478 KeyParams params = {"localhost", "dummy", "foobar"};
479 other_cryptographer.AddKey(params);
480 sync_pb::EntitySpecifics specifics;
481 sync_pb::NigoriSpecifics* nigori =
482 specifics.MutableExtension(sync_pb::nigori);
483 other_cryptographer.GetKeys(nigori->mutable_encrypted());
484 nigori->set_encrypt_bookmarks(true);
485 encrypted_types.insert(syncable::BOOKMARKS);
486 CreateUnappliedNewItem(syncable::ModelTypeToRootTag(syncable::NIGORI),
487 specifics, true);
488 Cryptographer* cryptographer =
489 session()->context()->directory_manager()->cryptographer();
490 EXPECT_FALSE(cryptographer->has_pending_keys());
491
492 {
493 // Ensure we have unsynced nodes that aren't properly encrypted.
494 ScopedDirLookup dir(syncdb()->manager(), syncdb()->name());
495 ASSERT_TRUE(dir.good());
496 ReadTransaction trans(dir, __FILE__, __LINE__);
497 EXPECT_FALSE(VerifyUnsyncedChangesAreEncrypted(&trans, encrypted_types));
498 Syncer::UnsyncedMetaHandles handles;
499 SyncerUtil::GetUnsyncedEntries(&trans, &handles);
500 EXPECT_EQ(2*batch_s+1, handles.size());
501 }
502
503 apply_updates_command_.ExecuteImpl(session());
504
505 sessions::StatusController* status = session()->status_controller();
506 sessions::ScopedModelSafeGroupRestriction r(status, GROUP_PASSIVE);
507 EXPECT_EQ(1, status->update_progress().AppliedUpdatesSize())
508 << "All updates should have been attempted";
509 EXPECT_EQ(1, status->conflict_progress().ConflictingItemsSize())
510 << "The unsynced chnages trigger a conflict with the nigori update.";
511 EXPECT_EQ(0, status->update_progress().SuccessfullyAppliedUpdateCount())
512 << "The nigori update should not be applied";
513 EXPECT_FALSE(cryptographer->is_ready()); 284 EXPECT_FALSE(cryptographer->is_ready());
514 EXPECT_TRUE(cryptographer->has_pending_keys()); 285 EXPECT_TRUE(cryptographer->has_pending_keys());
515 {
516 // Ensure the unsynced nodes are still not encrypted.
517 ScopedDirLookup dir(syncdb()->manager(), syncdb()->name());
518 ASSERT_TRUE(dir.good());
519 ReadTransaction trans(dir, __FILE__, __LINE__);
520
521 // Since we're in conflict, the specifics don't reflect the unapplied
522 // changes.
523 EXPECT_FALSE(VerifyUnsyncedChangesAreEncrypted(&trans, encrypted_types));
524 encrypted_types.clear();
525 EXPECT_EQ(encrypted_types, GetEncryptedDataTypes(&trans));
526
527 Syncer::UnsyncedMetaHandles handles;
528 SyncerUtil::GetUnsyncedEntries(&trans, &handles);
529 EXPECT_EQ(2*batch_s+1, handles.size());
530 }
531 } 286 }
532 287
533 } // namespace browser_sync 288 } // namespace browser_sync
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/sync/engine/change_reorder_buffer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698