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

Side by Side Diff: webkit/fileapi/syncable/local_file_sync_context_unittest.cc

Issue 11235027: Wire up Syncable operation runner to the local file sync context (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: update Created 8 years, 2 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 "webkit/fileapi/syncable/local_file_sync_context.h" 5 #include "webkit/fileapi/syncable/local_file_sync_context.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/file_path.h" 10 #include "base/file_path.h"
11 #include "base/message_loop.h" 11 #include "base/message_loop.h"
12 #include "base/platform_file.h"
12 #include "base/single_thread_task_runner.h" 13 #include "base/single_thread_task_runner.h"
13 #include "base/threading/thread.h" 14 #include "base/threading/thread.h"
14 #include "testing/gtest/include/gtest/gtest.h" 15 #include "testing/gtest/include/gtest/gtest.h"
15 #include "webkit/fileapi/file_system_context.h" 16 #include "webkit/fileapi/file_system_context.h"
17 #include "webkit/fileapi/file_system_operation.h"
16 #include "webkit/fileapi/isolated_context.h" 18 #include "webkit/fileapi/isolated_context.h"
17 #include "webkit/fileapi/syncable/canned_syncable_file_system.h" 19 #include "webkit/fileapi/syncable/canned_syncable_file_system.h"
18 #include "webkit/fileapi/syncable/local_file_change_tracker.h" 20 #include "webkit/fileapi/syncable/local_file_change_tracker.h"
19 #include "webkit/fileapi/syncable/sync_status_code.h" 21 #include "webkit/fileapi/syncable/sync_status_code.h"
20 #include "webkit/fileapi/syncable/syncable_file_system_util.h" 22 #include "webkit/fileapi/syncable/syncable_file_system_util.h"
21 23
22 // This tests LocalFileSyncContext behavior in multi-thread / 24 // This tests LocalFileSyncContext behavior in multi-thread /
23 // multi-file-system-context environment. 25 // multi-file-system-context environment.
24 // Basic combined tests (single-thread / single-file-system-context) 26 // Basic combined tests (single-thread / single-file-system-context)
25 // that involve LocalFileSyncContext are also in 27 // that involve LocalFileSyncContext are also in
26 // syncable_file_system_unittests.cc. 28 // syncable_file_system_unittests.cc.
27 29
28 namespace fileapi { 30 namespace fileapi {
29 31
30 namespace { 32 namespace {
31 const char kOrigin1[] = "http://example.com"; 33 const char kOrigin1[] = "http://example.com";
32 const char kOrigin2[] = "http://chromium.org"; 34 const char kOrigin2[] = "http://chromium.org";
33 const char kServiceName[] = "test"; 35 const char kServiceName[] = "test";
34 } 36 }
35 37
36 class LocalFileSyncContextTest : public testing::Test { 38 class LocalFileSyncContextTest : public testing::Test {
37 protected: 39 protected:
38 LocalFileSyncContextTest() 40 LocalFileSyncContextTest()
39 : status_(SYNC_FILE_ERROR_FAILED) {} 41 : status_(SYNC_FILE_ERROR_FAILED),
42 file_error_(base::PLATFORM_FILE_ERROR_FAILED),
43 async_modify_finished_(false),
44 has_inflight_prepare_for_sync_(false) {}
40 45
41 virtual void SetUp() OVERRIDE { 46 virtual void SetUp() OVERRIDE {
42 EXPECT_TRUE(fileapi::RegisterSyncableFileSystem(kServiceName)); 47 EXPECT_TRUE(fileapi::RegisterSyncableFileSystem(kServiceName));
43 48
44 io_thread_.reset(new base::Thread("Thread_IO")); 49 io_thread_.reset(new base::Thread("Thread_IO"));
45 file_thread_.reset(new base::Thread("Thread_File")); 50 file_thread_.reset(new base::Thread("Thread_File"));
46 io_thread_->StartWithOptions( 51 io_thread_->StartWithOptions(
47 base::Thread::Options(MessageLoop::TYPE_IO, 0)); 52 base::Thread::Options(MessageLoop::TYPE_IO, 0));
48 file_thread_->Start(); 53 file_thread_->Start();
49 54
50 ui_task_runner_ = MessageLoop::current()->message_loop_proxy(); 55 ui_task_runner_ = MessageLoop::current()->message_loop_proxy();
51 io_task_runner_ = io_thread_->message_loop_proxy(); 56 io_task_runner_ = io_thread_->message_loop_proxy();
52 file_task_runner_ = file_thread_->message_loop_proxy(); 57 file_task_runner_ = file_thread_->message_loop_proxy();
53 } 58 }
54 59
55 virtual void TearDown() OVERRIDE { 60 virtual void TearDown() OVERRIDE {
56 EXPECT_TRUE(fileapi::RevokeSyncableFileSystem(kServiceName)); 61 EXPECT_TRUE(fileapi::RevokeSyncableFileSystem(kServiceName));
57 io_thread_->Stop(); 62 io_thread_->Stop();
58 file_thread_->Stop(); 63 file_thread_->Stop();
59 } 64 }
60 65
66 void StartPrepareForSync(LocalFileSyncContext* sync_context,
67 const FileSystemURL& url,
68 FileChangeList* changes) {
69 ASSERT_TRUE(changes != NULL);
70 ASSERT_FALSE(has_inflight_prepare_for_sync_);
71 status_ = SYNC_STATUS_UNKNOWN;
72 has_inflight_prepare_for_sync_ = true;
73 sync_context->PrepareForSync(
74 url,
75 base::Bind(&LocalFileSyncContextTest::DidPrepareForSync,
76 base::Unretained(this), changes));
77 }
78
79 SyncStatusCode PrepareForSync(LocalFileSyncContext* sync_context,
80 const FileSystemURL& url,
81 FileChangeList* changes) {
82 StartPrepareForSync(sync_context, url, changes);
83 MessageLoop::current()->Run();
84 return status_;
85 }
86
87 base::Closure GetPrepareForSyncClosure(LocalFileSyncContext* sync_context,
88 const FileSystemURL& url,
89 FileChangeList* changes) {
90 return base::Bind(&LocalFileSyncContextTest::StartPrepareForSync,
91 base::Unretained(this), base::Unretained(sync_context),
92 url, changes);
93 }
94
95 void DidPrepareForSync(FileChangeList* changes_out,
96 SyncStatusCode status,
97 const FileChangeList& changes) {
98 ASSERT_TRUE(ui_task_runner_->RunsTasksOnCurrentThread());
99 has_inflight_prepare_for_sync_ = false;
100 status_ = status;
101 *changes_out = changes;
102 MessageLoop::current()->Quit();
103 }
104
105 void StartModifyFileOnIOThread(CannedSyncableFileSystem* file_system,
106 const FileSystemURL& url) {
107 async_modify_finished_ = false;
108 ASSERT_TRUE(file_system != NULL);
109 if (!io_task_runner_->RunsTasksOnCurrentThread()) {
110 ASSERT_TRUE(ui_task_runner_->RunsTasksOnCurrentThread());
111 io_task_runner_->PostTask(
112 FROM_HERE,
113 base::Bind(&LocalFileSyncContextTest::StartModifyFileOnIOThread,
114 base::Unretained(this), file_system, url));
115 return;
116 }
117 ASSERT_TRUE(io_task_runner_->RunsTasksOnCurrentThread());
118 file_error_ = base::PLATFORM_FILE_ERROR_FAILED;
119 file_system->NewOperation()->Truncate(
120 url, 1, base::Bind(&LocalFileSyncContextTest::DidModifyFile,
121 base::Unretained(this)));
122 }
123
124 base::PlatformFileError WaitUntilModifyFileIsDone() {
125 while (!async_modify_finished_)
126 MessageLoop::current()->RunAllPending();
127 return file_error_;
128 }
129
130 void DidModifyFile(base::PlatformFileError error) {
131 if (!ui_task_runner_->RunsTasksOnCurrentThread()) {
132 ASSERT_TRUE(io_task_runner_->RunsTasksOnCurrentThread());
133 ui_task_runner_->PostTask(
134 FROM_HERE,
135 base::Bind(&LocalFileSyncContextTest::DidModifyFile,
136 base::Unretained(this), error));
137 return;
138 }
139 ASSERT_TRUE(ui_task_runner_->RunsTasksOnCurrentThread());
140 file_error_ = error;
141 async_modify_finished_ = true;
142 }
143
61 // These need to remain until the very end. 144 // These need to remain until the very end.
62 scoped_ptr<base::Thread> io_thread_; 145 scoped_ptr<base::Thread> io_thread_;
63 scoped_ptr<base::Thread> file_thread_; 146 scoped_ptr<base::Thread> file_thread_;
64 MessageLoop loop_; 147 MessageLoop loop_;
65 148
66 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; 149 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
67 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner_; 150 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner_;
68 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; 151 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
69 152
70 scoped_refptr<LocalFileSyncContext> sync_context_; 153 scoped_refptr<LocalFileSyncContext> sync_context_;
71 154
72 SyncStatusCode status_; 155 SyncStatusCode status_;
156 base::PlatformFileError file_error_;
157 bool async_modify_finished_;
158 bool has_inflight_prepare_for_sync_;
73 }; 159 };
74 160
75 TEST_F(LocalFileSyncContextTest, ConstructAndDestruct) { 161 TEST_F(LocalFileSyncContextTest, ConstructAndDestruct) {
76 sync_context_ = new LocalFileSyncContext( 162 sync_context_ = new LocalFileSyncContext(
77 ui_task_runner_, io_task_runner_); 163 ui_task_runner_, io_task_runner_);
78 sync_context_->ShutdownOnUIThread(); 164 sync_context_->ShutdownOnUIThread();
79 } 165 }
80 166
81 TEST_F(LocalFileSyncContextTest, InitializeFileSystemContext) { 167 TEST_F(LocalFileSyncContextTest, InitializeFileSystemContext) {
82 CannedSyncableFileSystem file_system(GURL(kOrigin1), kServiceName, 168 CannedSyncableFileSystem file_system(GURL(kOrigin1), kServiceName,
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 file_system1.file_system_context()->change_tracker()->GetChangedURLs(&urls); 249 file_system1.file_system_context()->change_tracker()->GetChangedURLs(&urls);
164 ASSERT_EQ(1U, urls.size()); 250 ASSERT_EQ(1U, urls.size());
165 EXPECT_EQ(kURL1, urls[0]); 251 EXPECT_EQ(kURL1, urls[0]);
166 252
167 // file_system2's tracker now must have the change for kURL2. 253 // file_system2's tracker now must have the change for kURL2.
168 urls.clear(); 254 urls.clear();
169 file_system2.file_system_context()->change_tracker()->GetChangedURLs(&urls); 255 file_system2.file_system_context()->change_tracker()->GetChangedURLs(&urls);
170 ASSERT_EQ(1U, urls.size()); 256 ASSERT_EQ(1U, urls.size());
171 EXPECT_EQ(kURL2, urls[0]); 257 EXPECT_EQ(kURL2, urls[0]);
172 258
259 FileChangeList changes;
260 EXPECT_EQ(SYNC_STATUS_OK, PrepareForSync(sync_context_, kURL1, &changes));
261 EXPECT_EQ(1U, changes.size());
262 EXPECT_TRUE(changes.list().back().IsFile());
263 EXPECT_TRUE(changes.list().back().IsAddOrUpdate());
264
265 changes.clear();
266 EXPECT_EQ(SYNC_STATUS_OK, PrepareForSync(sync_context_, kURL2, &changes));
267 EXPECT_EQ(1U, changes.size());
268 EXPECT_FALSE(changes.list().back().IsFile());
269 EXPECT_TRUE(changes.list().back().IsAddOrUpdate());
270
173 sync_context_->ShutdownOnUIThread(); 271 sync_context_->ShutdownOnUIThread();
174 sync_context_ = NULL; 272 sync_context_ = NULL;
175 273
176 file_system1.TearDown(); 274 file_system1.TearDown();
177 file_system2.TearDown(); 275 file_system2.TearDown();
178 } 276 }
179 277
278 TEST_F(LocalFileSyncContextTest, PrepareSyncWhileWriting) {
279 CannedSyncableFileSystem file_system(GURL(kOrigin1), kServiceName,
280 io_task_runner_);
281 file_system.SetUp();
282 sync_context_ = new LocalFileSyncContext(ui_task_runner_, io_task_runner_);
283 EXPECT_EQ(SYNC_STATUS_OK,
284 file_system.MaybeInitializeFileSystemContext(sync_context_));
285
286 EXPECT_EQ(base::PLATFORM_FILE_OK, file_system.OpenFileSystem());
287
288 const FileSystemURL kURL1(file_system.URL("foo"));
289
290 // Creates a file in file_system.
291 EXPECT_EQ(base::PLATFORM_FILE_OK, file_system.CreateFile(kURL1));
292
293 // Kick file write on IO thread.
294 StartModifyFileOnIOThread(&file_system, kURL1);
295
296 // Until the operation finishes PrepareForSync should return BUSY error.
297 FileChangeList changes;
298 EXPECT_EQ(SYNC_STATUS_FILE_BUSY,
299 PrepareForSync(sync_context_, kURL1, &changes));
300 EXPECT_TRUE(changes.empty());
301
302 // Register PrepareForSync method to be invoked when kURL1 becomes
303 // syncable. (Actually this may be done after all operations are done
304 // on IO thread in this test.)
305 sync_context_->RegisterURLForWaitingSync(
306 kURL1, GetPrepareForSyncClosure(sync_context_, kURL1, &changes));
307
308 // Wait for the completion.
309 EXPECT_EQ(base::PLATFORM_FILE_OK, WaitUntilModifyFileIsDone());
310
311 // The PrepareForSync must have been started; wait until DidPrepareForSync
312 // is done.
313 MessageLoop::current()->Run();
314 ASSERT_FALSE(has_inflight_prepare_for_sync_);
315
316 // Now PrepareForSync should have run and returned OK.
317 EXPECT_EQ(SYNC_STATUS_OK, status_);
318 EXPECT_EQ(1U, changes.size());
319 EXPECT_TRUE(changes.list().back().IsFile());
320 EXPECT_TRUE(changes.list().back().IsAddOrUpdate());
321
322 sync_context_->ShutdownOnUIThread();
323 sync_context_ = NULL;
324
325 file_system.TearDown();
326 }
327
180 } // namespace fileapi 328 } // namespace fileapi
OLDNEW
« no previous file with comments | « webkit/fileapi/syncable/local_file_sync_context.cc ('k') | webkit/fileapi/syncable/sync_status_code.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698