Fix build break
[chromium-blink-merge.git] / chrome / browser / sync_file_system / local_file_sync_service_unittest.cc
blobffc5288ed032b5958d35c49113500dcfa8ff8a0e
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.
5 #include "base/basictypes.h"
6 #include "base/bind.h"
7 #include "base/file_util.h"
8 #include "base/location.h"
9 #include "base/message_loop_proxy.h"
10 #include "base/run_loop.h"
11 #include "base/stl_util.h"
12 #include "base/threading/thread.h"
13 #include "chrome/browser/sync_file_system/local_file_sync_service.h"
14 #include "chrome/browser/sync_file_system/mock_local_change_processor.h"
15 #include "chrome/browser/sync_file_system/sync_file_system_test_util.h"
16 #include "chrome/test/base/testing_profile.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "webkit/fileapi/file_system_context.h"
20 #include "webkit/fileapi/syncable/canned_syncable_file_system.h"
21 #include "webkit/fileapi/syncable/file_change.h"
22 #include "webkit/fileapi/syncable/local_file_change_tracker.h"
23 #include "webkit/fileapi/syncable/local_file_sync_context.h"
24 #include "webkit/fileapi/syncable/local_file_sync_status.h"
25 #include "webkit/fileapi/syncable/mock_sync_status_observer.h"
26 #include "webkit/fileapi/syncable/sync_file_metadata.h"
27 #include "webkit/fileapi/syncable/sync_status_code.h"
28 #include "webkit/fileapi/syncable/syncable_file_system_util.h"
30 using fileapi::FileSystemURL;
31 using ::testing::_;
32 using ::testing::AtLeast;
33 using ::testing::InvokeWithoutArgs;
34 using ::testing::StrictMock;
36 namespace sync_file_system {
38 namespace {
40 const char kOrigin[] = "http://example.com";
41 const char kServiceName[] = "test";
43 void DidPrepareForProcessRemoteChange(const tracked_objects::Location& where,
44 const base::Closure& oncompleted,
45 SyncStatusCode expected_status,
46 const SyncFileMetadata& expected_metadata,
47 SyncStatusCode status,
48 const SyncFileMetadata& metadata,
49 const FileChangeList& changes) {
50 SCOPED_TRACE(testing::Message() << where.ToString());
51 ASSERT_EQ(expected_status, status);
52 ASSERT_EQ(expected_metadata.file_type, metadata.file_type);
53 ASSERT_EQ(expected_metadata.size, metadata.size);
54 ASSERT_TRUE(changes.empty());
55 oncompleted.Run();
58 void OnSyncCompleted(const tracked_objects::Location& where,
59 const base::Closure& oncompleted,
60 SyncStatusCode expected_status,
61 const FileSystemURL& expected_url,
62 SyncStatusCode status,
63 const FileSystemURL& url) {
64 SCOPED_TRACE(testing::Message() << where.ToString());
65 ASSERT_EQ(expected_status, status);
66 ASSERT_EQ(expected_url, url);
67 oncompleted.Run();
70 void OnGetFileMetadata(const tracked_objects::Location& where,
71 const base::Closure& oncompleted,
72 SyncStatusCode* status_out,
73 SyncFileMetadata* metadata_out,
74 SyncStatusCode status,
75 const SyncFileMetadata& metadata) {
76 SCOPED_TRACE(testing::Message() << where.ToString());
77 *status_out = status;
78 *metadata_out = metadata;
79 oncompleted.Run();
82 ACTION_P(MockStatusCallback, status) {
83 base::MessageLoopProxy::current()->PostTask(
84 FROM_HERE, base::Bind(arg4, status));
87 ACTION_P2(MockStatusCallbackAndRecordChange, status, changes) {
88 base::MessageLoopProxy::current()->PostTask(
89 FROM_HERE, base::Bind(arg4, status));
90 changes->push_back(arg0);
93 } // namespace
95 class LocalFileSyncServiceTest
96 : public testing::Test,
97 public LocalFileSyncService::Observer {
98 protected:
99 LocalFileSyncServiceTest() : num_changes_(0) {}
101 virtual ~LocalFileSyncServiceTest() {}
103 virtual void SetUp() OVERRIDE {
104 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
106 thread_helper_.SetUp();
108 file_system_.reset(new CannedSyncableFileSystem(
109 GURL(kOrigin), kServiceName,
110 thread_helper_.io_task_runner(),
111 thread_helper_.file_task_runner()));
113 local_service_.reset(new LocalFileSyncService(&profile_));
115 file_system_->SetUp();
117 base::RunLoop run_loop;
118 SyncStatusCode status = SYNC_STATUS_UNKNOWN;
119 local_service_->MaybeInitializeFileSystemContext(
120 GURL(kOrigin), kServiceName, file_system_->file_system_context(),
121 AssignAndQuitCallback(&run_loop, &status));
122 run_loop.Run();
124 local_service_->AddChangeObserver(this);
126 EXPECT_EQ(base::PLATFORM_FILE_OK, file_system_->OpenFileSystem());
128 file_system_->file_system_context()->sync_context()->
129 set_mock_notify_changes_duration_in_sec(0);
132 virtual void TearDown() OVERRIDE {
133 local_service_->Shutdown();
134 file_system_->TearDown();
135 RevokeSyncableFileSystem(kServiceName);
137 thread_helper_.TearDown();
140 // LocalChangeObserver overrides.
141 virtual void OnLocalChangeAvailable(int64 num_changes) OVERRIDE {
142 num_changes_ = num_changes;
145 void PrepareForProcessRemoteChange(
146 const FileSystemURL& url,
147 const tracked_objects::Location& where,
148 SyncStatusCode expected_status,
149 const SyncFileMetadata& expected_metadata) {
150 base::RunLoop run_loop;
151 local_service_->PrepareForProcessRemoteChange(
152 url,
153 kServiceName,
154 base::Bind(&DidPrepareForProcessRemoteChange,
155 where,
156 run_loop.QuitClosure(),
157 expected_status,
158 expected_metadata));
159 run_loop.Run();
162 SyncStatusCode ApplyRemoteChange(const FileChange& change,
163 const base::FilePath& local_path,
164 const FileSystemURL& url) {
165 base::RunLoop run_loop;
166 SyncStatusCode sync_status = SYNC_STATUS_UNKNOWN;
167 local_service_->ApplyRemoteChange(
168 change, local_path, url,
169 AssignAndQuitCallback(&run_loop, &sync_status));
170 run_loop.Run();
171 return sync_status;
174 int64 GetNumChangesInTracker() const {
175 return file_system_->file_system_context()->change_tracker()->num_changes();
178 TestingProfile profile_;
180 MultiThreadTestHelper thread_helper_;
182 base::ScopedTempDir temp_dir_;
184 scoped_ptr<CannedSyncableFileSystem> file_system_;
185 scoped_ptr<LocalFileSyncService> local_service_;
187 int64 num_changes_;
190 // More complete tests for PrepareForProcessRemoteChange and ApplyRemoteChange
191 // are also in content_unittest:LocalFileSyncContextTest.
192 TEST_F(LocalFileSyncServiceTest, RemoteSyncStepsSimple) {
193 const FileSystemURL kFile(file_system_->URL("file"));
194 const FileSystemURL kDir(file_system_->URL("dir"));
195 const char kTestFileData[] = "0123456789";
196 const int kTestFileDataSize = static_cast<int>(arraysize(kTestFileData) - 1);
198 base::FilePath local_path;
199 ASSERT_TRUE(file_util::CreateTemporaryFileInDir(temp_dir_.path(),
200 &local_path));
201 ASSERT_EQ(kTestFileDataSize,
202 file_util::WriteFile(local_path, kTestFileData, kTestFileDataSize));
204 // Run PrepareForProcessRemoteChange for kFile.
205 SyncFileMetadata expected_metadata;
206 expected_metadata.file_type = SYNC_FILE_TYPE_UNKNOWN;
207 expected_metadata.size = 0;
208 PrepareForProcessRemoteChange(kFile, FROM_HERE,
209 SYNC_STATUS_OK,
210 expected_metadata);
212 // Run ApplyRemoteChange for kFile.
213 FileChange change(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
214 SYNC_FILE_TYPE_FILE);
215 EXPECT_EQ(SYNC_STATUS_OK,
216 ApplyRemoteChange(change, local_path, kFile));
218 // Verify the file is synced.
219 EXPECT_EQ(base::PLATFORM_FILE_OK,
220 file_system_->VerifyFile(kFile, kTestFileData));
222 // Run PrepareForProcessRemoteChange for kDir.
223 PrepareForProcessRemoteChange(kDir, FROM_HERE,
224 SYNC_STATUS_OK,
225 expected_metadata);
227 // Run ApplyRemoteChange for kDir.
228 change = FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
229 SYNC_FILE_TYPE_DIRECTORY);
230 EXPECT_EQ(SYNC_STATUS_OK,
231 ApplyRemoteChange(change, base::FilePath(), kDir));
233 // Verify the directory.
234 EXPECT_EQ(base::PLATFORM_FILE_OK,
235 file_system_->DirectoryExists(kDir));
237 // Run PrepareForProcessRemoteChange and ApplyRemoteChange for
238 // kDir once again for deletion.
239 expected_metadata.file_type = SYNC_FILE_TYPE_DIRECTORY;
240 expected_metadata.size = 0;
241 PrepareForProcessRemoteChange(kDir, FROM_HERE,
242 SYNC_STATUS_OK,
243 expected_metadata);
245 change = FileChange(FileChange::FILE_CHANGE_DELETE, SYNC_FILE_TYPE_UNKNOWN);
246 EXPECT_EQ(SYNC_STATUS_OK, ApplyRemoteChange(change, base::FilePath(), kDir));
248 // Now the directory must have deleted.
249 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
250 file_system_->DirectoryExists(kDir));
253 TEST_F(LocalFileSyncServiceTest, LocalChangeObserver) {
254 const FileSystemURL kFile(file_system_->URL("file"));
255 const FileSystemURL kDir(file_system_->URL("dir"));
256 const char kTestFileData[] = "0123456789";
257 const int kTestFileDataSize = static_cast<int>(arraysize(kTestFileData) - 1);
259 EXPECT_EQ(base::PLATFORM_FILE_OK, file_system_->CreateFile(kFile));
261 EXPECT_EQ(1, num_changes_);
263 EXPECT_EQ(base::PLATFORM_FILE_OK, file_system_->CreateDirectory(kDir));
264 EXPECT_EQ(kTestFileDataSize,
265 file_system_->WriteString(kFile, kTestFileData));
267 EXPECT_EQ(2, num_changes_);
270 #if defined(OS_WIN)
271 // Flaky: http://crbug.com/171487
272 #define MAYBE_LocalChangeObserverMultipleContexts\
273 DISABLED_LocalChangeObserverMultipleContexts
274 #else
275 #define MAYBE_LocalChangeObserverMultipleContexts\
276 LocalChangeObserverMultipleContexts
277 #endif
279 TEST_F(LocalFileSyncServiceTest, MAYBE_LocalChangeObserverMultipleContexts) {
280 const char kOrigin2[] = "http://foo";
281 CannedSyncableFileSystem file_system2(GURL(kOrigin2),
282 kServiceName,
283 thread_helper_.io_task_runner(),
284 thread_helper_.file_task_runner());
285 file_system2.SetUp();
287 base::RunLoop run_loop;
288 SyncStatusCode status = SYNC_STATUS_UNKNOWN;
289 local_service_->MaybeInitializeFileSystemContext(
290 GURL(kOrigin2), kServiceName, file_system2.file_system_context(),
291 AssignAndQuitCallback(&run_loop, &status));
292 run_loop.Run();
294 EXPECT_EQ(base::PLATFORM_FILE_OK, file_system2.OpenFileSystem());
295 file_system2.file_system_context()->sync_context()->
296 set_mock_notify_changes_duration_in_sec(0);
298 const FileSystemURL kFile1(file_system_->URL("file1"));
299 const FileSystemURL kFile2(file_system_->URL("file2"));
300 const FileSystemURL kFile3(file_system2.URL("file3"));
301 const FileSystemURL kFile4(file_system2.URL("file4"));
303 EXPECT_EQ(base::PLATFORM_FILE_OK, file_system_->CreateFile(kFile1));
304 EXPECT_EQ(base::PLATFORM_FILE_OK, file_system_->CreateFile(kFile2));
305 EXPECT_EQ(base::PLATFORM_FILE_OK, file_system2.CreateFile(kFile3));
306 EXPECT_EQ(base::PLATFORM_FILE_OK, file_system2.CreateFile(kFile4));
308 EXPECT_EQ(4, num_changes_);
310 file_system2.TearDown();
313 TEST_F(LocalFileSyncServiceTest, ProcessLocalChange_CreateFile) {
314 const FileSystemURL kFile(file_system_->URL("foo"));
315 const char kTestFileData[] = "0123456789";
316 const int kTestFileDataSize = static_cast<int>(arraysize(kTestFileData) - 1);
318 base::RunLoop run_loop;
320 // We should get called OnSyncEnabled on kFile.
321 StrictMock<MockSyncStatusObserver> status_observer;
322 EXPECT_CALL(status_observer, OnSyncEnabled(kFile))
323 .Times(AtLeast(1));
324 file_system_->AddSyncStatusObserver(&status_observer);
326 // Creates and writes into a file.
327 EXPECT_EQ(base::PLATFORM_FILE_OK, file_system_->CreateFile(kFile));
328 EXPECT_EQ(kTestFileDataSize,
329 file_system_->WriteString(kFile, std::string(kTestFileData)));
331 // Retrieve the expected platform_path.
332 base::PlatformFileInfo info;
333 base::FilePath platform_path;
334 EXPECT_EQ(base::PLATFORM_FILE_OK,
335 file_system_->GetMetadata(kFile, &info, &platform_path));
337 ASSERT_FALSE(info.is_directory);
338 ASSERT_EQ(kTestFileDataSize, info.size);
340 SyncFileMetadata metadata;
341 metadata.file_type = SYNC_FILE_TYPE_FILE;
342 metadata.size = info.size;
343 metadata.last_modified = info.last_modified;
345 // The local_change_processor's ApplyLocalChange should be called once
346 // with ADD_OR_UPDATE change for TYPE_FILE.
347 StrictMock<MockLocalChangeProcessor> local_change_processor;
348 const FileChange change(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
349 SYNC_FILE_TYPE_FILE);
350 EXPECT_CALL(local_change_processor,
351 ApplyLocalChange(change, platform_path, metadata, kFile, _))
352 .WillOnce(MockStatusCallback(SYNC_STATUS_OK));
354 local_service_->SetLocalChangeProcessor(&local_change_processor);
355 local_service_->ProcessLocalChange(
356 base::Bind(&OnSyncCompleted, FROM_HERE, run_loop.QuitClosure(),
357 SYNC_STATUS_OK, kFile));
359 run_loop.Run();
361 file_system_->RemoveSyncStatusObserver(&status_observer);
363 EXPECT_EQ(0, GetNumChangesInTracker());
366 TEST_F(LocalFileSyncServiceTest, ProcessLocalChange_CreateAndRemoveFile) {
367 const FileSystemURL kFile(file_system_->URL("foo"));
369 base::RunLoop run_loop;
371 // We should get called OnSyncEnabled and OnWriteEnabled on kFile.
372 StrictMock<MockSyncStatusObserver> status_observer;
373 EXPECT_CALL(status_observer, OnSyncEnabled(kFile))
374 .Times(AtLeast(1));
375 file_system_->AddSyncStatusObserver(&status_observer);
377 // Creates and then deletes a file.
378 EXPECT_EQ(base::PLATFORM_FILE_OK, file_system_->CreateFile(kFile));
379 EXPECT_EQ(base::PLATFORM_FILE_OK, file_system_->Remove(kFile, false));
381 // The local_change_processor's ApplyLocalChange should be called once
382 // with DELETE change for TYPE_FILE.
383 // The file will NOT exist in the remote side and the processor might
384 // return SYNC_FILE_ERROR_NOT_FOUND (as mocked).
385 StrictMock<MockLocalChangeProcessor> local_change_processor;
386 const FileChange change(FileChange::FILE_CHANGE_DELETE, SYNC_FILE_TYPE_FILE);
387 EXPECT_CALL(local_change_processor, ApplyLocalChange(change, _, _, kFile, _))
388 .WillOnce(MockStatusCallback(SYNC_FILE_ERROR_NOT_FOUND));
390 // The sync should succeed anyway.
391 local_service_->SetLocalChangeProcessor(&local_change_processor);
392 local_service_->ProcessLocalChange(
393 base::Bind(&OnSyncCompleted, FROM_HERE, run_loop.QuitClosure(),
394 SYNC_STATUS_OK, kFile));
396 run_loop.Run();
398 file_system_->RemoveSyncStatusObserver(&status_observer);
400 EXPECT_EQ(0, GetNumChangesInTracker());
403 TEST_F(LocalFileSyncServiceTest, ProcessLocalChange_CreateAndRemoveDirectory) {
404 const FileSystemURL kDir(file_system_->URL("foo"));
406 base::RunLoop run_loop;
408 // OnSyncEnabled is expected to be called at least or more than once.
409 StrictMock<MockSyncStatusObserver> status_observer;
410 EXPECT_CALL(status_observer, OnSyncEnabled(kDir)).Times(AtLeast(1));
411 file_system_->AddSyncStatusObserver(&status_observer);
413 // Creates and then deletes a directory.
414 EXPECT_EQ(base::PLATFORM_FILE_OK, file_system_->CreateDirectory(kDir));
415 EXPECT_EQ(base::PLATFORM_FILE_OK, file_system_->Remove(kDir, false));
417 // The local_change_processor's ApplyLocalChange should never be called.
418 StrictMock<MockLocalChangeProcessor> local_change_processor;
420 local_service_->SetLocalChangeProcessor(&local_change_processor);
421 local_service_->ProcessLocalChange(
422 base::Bind(&OnSyncCompleted, FROM_HERE, run_loop.QuitClosure(),
423 SYNC_STATUS_NO_CHANGE_TO_SYNC, FileSystemURL()));
425 run_loop.Run();
427 file_system_->RemoveSyncStatusObserver(&status_observer);
429 EXPECT_EQ(0, GetNumChangesInTracker());
432 TEST_F(LocalFileSyncServiceTest, ProcessLocalChange_MultipleChanges) {
433 const FileSystemURL kPath(file_system_->URL("foo"));
434 const FileSystemURL kOther(file_system_->URL("bar"));
436 base::RunLoop run_loop;
438 // We should get called OnSyncEnabled and OnWriteEnabled on kPath and
439 // OnSyncEnabled on kOther.
440 StrictMock<MockSyncStatusObserver> status_observer;
441 EXPECT_CALL(status_observer, OnSyncEnabled(kPath)).Times(AtLeast(1));
442 EXPECT_CALL(status_observer, OnSyncEnabled(kOther)).Times(AtLeast(1));
443 file_system_->AddSyncStatusObserver(&status_observer);
445 // Creates a file, delete the file and creates a directory with the same
446 // name.
447 EXPECT_EQ(base::PLATFORM_FILE_OK, file_system_->CreateFile(kPath));
448 EXPECT_EQ(base::PLATFORM_FILE_OK, file_system_->Remove(kPath, false));
449 EXPECT_EQ(base::PLATFORM_FILE_OK, file_system_->CreateDirectory(kPath));
451 // Creates one more file.
452 EXPECT_EQ(base::PLATFORM_FILE_OK, file_system_->CreateFile(kOther));
454 // The local_change_processor's ApplyLocalChange will be called
455 // twice for FILE_TYPE and FILE_DIRECTORY.
456 StrictMock<MockLocalChangeProcessor> local_change_processor;
457 std::vector<FileChange> changes;
458 EXPECT_CALL(local_change_processor, ApplyLocalChange(_, _, _, kPath, _))
459 .Times(2)
460 .WillOnce(MockStatusCallbackAndRecordChange(SYNC_STATUS_OK, &changes))
461 .WillOnce(MockStatusCallbackAndRecordChange(SYNC_STATUS_OK, &changes));
462 local_service_->SetLocalChangeProcessor(&local_change_processor);
463 local_service_->ProcessLocalChange(
464 base::Bind(&OnSyncCompleted, FROM_HERE, run_loop.QuitClosure(),
465 SYNC_STATUS_OK, kPath));
467 run_loop.Run();
469 EXPECT_EQ(2U, changes.size());
470 EXPECT_EQ(FileChange(FileChange::FILE_CHANGE_DELETE, SYNC_FILE_TYPE_FILE),
471 changes[0]);
472 EXPECT_EQ(FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
473 SYNC_FILE_TYPE_DIRECTORY),
474 changes[1]);
476 file_system_->RemoveSyncStatusObserver(&status_observer);
478 // We have one more change for kOther.
479 EXPECT_EQ(1, GetNumChangesInTracker());
482 TEST_F(LocalFileSyncServiceTest, ProcessLocalChange_GetLocalMetadata) {
483 const FileSystemURL kURL(file_system_->URL("foo"));
484 const base::Time kTime = base::Time::FromDoubleT(333);
485 const int kSize = 555;
487 base::RunLoop run_loop;
489 // Creates a file.
490 EXPECT_EQ(base::PLATFORM_FILE_OK, file_system_->CreateFile(kURL));
491 EXPECT_EQ(base::PLATFORM_FILE_OK, file_system_->TruncateFile(kURL, kSize));
492 EXPECT_EQ(base::PLATFORM_FILE_OK,
493 file_system_->TouchFile(kURL, base::Time(), kTime));
495 SyncStatusCode status = SYNC_STATUS_UNKNOWN;
496 SyncFileMetadata metadata;
497 local_service_->GetLocalFileMetadata(
498 kURL,
499 base::Bind(&OnGetFileMetadata, FROM_HERE, run_loop.QuitClosure(),
500 &status, &metadata));
502 run_loop.Run();
504 EXPECT_EQ(SYNC_STATUS_OK, status);
505 EXPECT_EQ(kTime, metadata.last_modified);
506 EXPECT_EQ(kSize, metadata.size);
509 TEST_F(LocalFileSyncServiceTest, RecordFakeChange) {
510 const FileSystemURL kURL(file_system_->URL("foo"));
512 // Create a file and reset the changes (as preparation).
513 EXPECT_EQ(base::PLATFORM_FILE_OK, file_system_->CreateFile(kURL));
514 file_system_->ClearChangeForURLInTracker(kURL);
516 EXPECT_EQ(0, GetNumChangesInTracker());
518 fileapi::FileSystemURLSet urlset;
519 file_system_->GetChangedURLsInTracker(&urlset);
520 EXPECT_TRUE(urlset.empty());
522 const FileChange change(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
523 SYNC_FILE_TYPE_FILE);
525 // Call RecordFakeLocalChange to add an ADD_OR_UPDATE change.
527 base::RunLoop run_loop;
528 SyncStatusCode status = SYNC_STATUS_UNKNOWN;
529 local_service_->RecordFakeLocalChange(
530 kURL, change, AssignAndQuitCallback(&run_loop, &status));
531 run_loop.Run();
532 EXPECT_EQ(SYNC_STATUS_OK, status);
535 EXPECT_EQ(1, GetNumChangesInTracker());
536 file_system_->GetChangedURLsInTracker(&urlset);
537 EXPECT_EQ(1U, urlset.size());
538 EXPECT_TRUE(urlset.find(kURL) != urlset.end());
540 // Next local sync should pick up the recorded change.
541 StrictMock<MockLocalChangeProcessor> local_change_processor;
542 std::vector<FileChange> changes;
543 EXPECT_CALL(local_change_processor, ApplyLocalChange(_, _, _, kURL, _))
544 .WillOnce(MockStatusCallbackAndRecordChange(SYNC_STATUS_OK, &changes));
546 base::RunLoop run_loop;
547 local_service_->SetLocalChangeProcessor(&local_change_processor);
548 local_service_->ProcessLocalChange(
549 base::Bind(&OnSyncCompleted, FROM_HERE, run_loop.QuitClosure(),
550 SYNC_STATUS_OK, kURL));
551 run_loop.Run();
554 EXPECT_EQ(1U, changes.size());
555 EXPECT_EQ(change, changes[0]);
558 // TODO(kinuko): Add tests for multiple file changes and multiple
559 // FileSystemContexts.
561 // Unit test for OriginChangeMap ---------------------------------------------
563 class OriginChangeMapTest : public testing::Test {
564 protected:
565 OriginChangeMapTest() {}
566 virtual ~OriginChangeMapTest() {}
568 bool NextOriginToProcess(GURL* origin) {
569 return map_.NextOriginToProcess(origin);
572 int64 GetTotalChangeCount() const {
573 return map_.GetTotalChangeCount();
576 void SetOriginChangeCount(const GURL& origin, int64 changes) {
577 map_.SetOriginChangeCount(origin, changes);
580 void SetOriginEnabled(const GURL& origin, bool enabled) {
581 map_.SetOriginEnabled(origin, enabled);
584 LocalFileSyncService::OriginChangeMap map_;
587 TEST_F(OriginChangeMapTest, Basic) {
588 const GURL kOrigin1("chrome-extension://foo");
589 const GURL kOrigin2("chrome-extension://bar");
590 const GURL kOrigin3("chrome-extension://baz");
592 ASSERT_EQ(0, GetTotalChangeCount());
594 SetOriginChangeCount(kOrigin1, 1);
595 SetOriginChangeCount(kOrigin2, 2);
597 ASSERT_EQ(1 + 2, GetTotalChangeCount());
599 SetOriginChangeCount(kOrigin3, 4);
601 ASSERT_EQ(1 + 2 + 4, GetTotalChangeCount());
603 const GURL kOrigins[] = { kOrigin1, kOrigin2, kOrigin3 };
604 std::set<GURL> all_origins;
605 all_origins.insert(kOrigins, kOrigins + ARRAYSIZE_UNSAFE(kOrigins));
607 GURL origin;
608 while (!all_origins.empty()) {
609 ASSERT_TRUE(NextOriginToProcess(&origin));
610 ASSERT_TRUE(ContainsKey(all_origins, origin));
611 all_origins.erase(origin);
614 // Set kOrigin2's change count 0.
615 SetOriginChangeCount(kOrigin2, 0);
616 ASSERT_EQ(1 + 4, GetTotalChangeCount());
618 // kOrigin2 won't return this time.
619 all_origins.insert(kOrigin1);
620 all_origins.insert(kOrigin3);
621 while (!all_origins.empty()) {
622 ASSERT_TRUE(NextOriginToProcess(&origin));
623 ASSERT_TRUE(ContainsKey(all_origins, origin));
624 all_origins.erase(origin);
627 // Calling NextOriginToProcess() again will just return
628 // the same set of origins (as far as we don't change the
629 // change count).
630 all_origins.insert(kOrigin1);
631 all_origins.insert(kOrigin3);
632 while (!all_origins.empty()) {
633 ASSERT_TRUE(NextOriginToProcess(&origin));
634 ASSERT_TRUE(ContainsKey(all_origins, origin));
635 all_origins.erase(origin);
638 // Set kOrigin2's change count 8.
639 SetOriginChangeCount(kOrigin2, 8);
640 ASSERT_EQ(1 + 4 + 8, GetTotalChangeCount());
642 all_origins.insert(kOrigins, kOrigins + ARRAYSIZE_UNSAFE(kOrigins));
643 while (!all_origins.empty()) {
644 ASSERT_TRUE(NextOriginToProcess(&origin));
645 ASSERT_TRUE(ContainsKey(all_origins, origin));
646 all_origins.erase(origin);
650 TEST_F(OriginChangeMapTest, WithDisabled) {
651 const GURL kOrigin1("chrome-extension://foo");
652 const GURL kOrigin2("chrome-extension://bar");
653 const GURL kOrigin3("chrome-extension://baz");
654 const GURL kOrigins[] = { kOrigin1, kOrigin2, kOrigin3 };
656 ASSERT_EQ(0, GetTotalChangeCount());
658 SetOriginChangeCount(kOrigin1, 1);
659 SetOriginChangeCount(kOrigin2, 2);
660 SetOriginChangeCount(kOrigin3, 4);
662 ASSERT_EQ(1 + 2 + 4, GetTotalChangeCount());
664 std::set<GURL> all_origins;
665 all_origins.insert(kOrigins, kOrigins + ARRAYSIZE_UNSAFE(kOrigins));
667 GURL origin;
668 while (!all_origins.empty()) {
669 ASSERT_TRUE(NextOriginToProcess(&origin));
670 ASSERT_TRUE(ContainsKey(all_origins, origin));
671 all_origins.erase(origin);
674 SetOriginEnabled(kOrigin2, false);
675 ASSERT_EQ(1 + 4, GetTotalChangeCount());
677 // kOrigin2 won't return this time.
678 all_origins.insert(kOrigin1);
679 all_origins.insert(kOrigin3);
680 while (!all_origins.empty()) {
681 ASSERT_TRUE(NextOriginToProcess(&origin));
682 ASSERT_TRUE(ContainsKey(all_origins, origin));
683 all_origins.erase(origin);
686 // kOrigin1 and kOrigin2 are now disabled.
687 SetOriginEnabled(kOrigin1, false);
688 ASSERT_EQ(4, GetTotalChangeCount());
690 ASSERT_TRUE(NextOriginToProcess(&origin));
691 ASSERT_EQ(kOrigin3, origin);
693 // Re-enable kOrigin2.
694 SetOriginEnabled(kOrigin2, true);
695 ASSERT_EQ(2 + 4, GetTotalChangeCount());
697 // kOrigin1 won't return this time.
698 all_origins.insert(kOrigin2);
699 all_origins.insert(kOrigin3);
700 while (!all_origins.empty()) {
701 ASSERT_TRUE(NextOriginToProcess(&origin));
702 ASSERT_TRUE(ContainsKey(all_origins, origin));
703 all_origins.erase(origin);
707 } // namespace sync_file_system