1 // Copyright 2013 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 "chrome/browser/chromeos/drive/sync/entry_update_performer.h"
7 #include "base/callback_helpers.h"
8 #include "base/file_util.h"
10 #include "base/task_runner_util.h"
11 #include "chrome/browser/chromeos/drive/file_cache.h"
12 #include "chrome/browser/chromeos/drive/file_system/download_operation.h"
13 #include "chrome/browser/chromeos/drive/file_system/operation_test_base.h"
14 #include "chrome/browser/chromeos/drive/job_scheduler.h"
15 #include "chrome/browser/chromeos/drive/resource_metadata.h"
16 #include "chrome/browser/drive/drive_api_util.h"
17 #include "chrome/browser/drive/fake_drive_service.h"
18 #include "google_apis/drive/drive_api_parser.h"
19 #include "google_apis/drive/gdata_wapi_parser.h"
20 #include "google_apis/drive/test_util.h"
21 #include "testing/gtest/include/gtest/gtest.h"
26 class EntryUpdatePerformerTest : public file_system::OperationTestBase {
28 virtual void SetUp() OVERRIDE {
29 OperationTestBase::SetUp();
30 performer_.reset(new EntryUpdatePerformer(blocking_task_runner(),
35 loader_controller()));
38 // Stores |content| to the cache and mark it as dirty.
39 FileError StoreAndMarkDirty(const std::string& local_id,
40 const std::string& content) {
42 if (!base::CreateTemporaryFileInDir(temp_dir(), &path) ||
43 !google_apis::test_util::WriteStringToFile(path, content))
44 return FILE_ERROR_FAILED;
46 // Store the file to cache.
47 FileError error = FILE_ERROR_FAILED;
48 base::PostTaskAndReplyWithResult(
49 blocking_task_runner(),
51 base::Bind(&FileCache::Store,
52 base::Unretained(cache()),
53 local_id, std::string(), path,
54 FileCache::FILE_OPERATION_COPY),
55 google_apis::test_util::CreateCopyResultCallback(&error));
56 test_util::RunBlockingPoolTask();
60 scoped_ptr<EntryUpdatePerformer> performer_;
63 TEST_F(EntryUpdatePerformerTest, UpdateEntry) {
64 base::FilePath src_path(
65 FILE_PATH_LITERAL("drive/root/Directory 1/SubDirectory File 1.txt"));
66 base::FilePath dest_path(
67 FILE_PATH_LITERAL("drive/root/Directory 1/Sub Directory Folder"));
69 ResourceEntry src_entry, dest_entry;
70 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &src_entry));
71 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(dest_path, &dest_entry));
73 // Update local entry.
74 base::Time new_last_modified = base::Time::FromInternalValue(
75 src_entry.file_info().last_modified()) + base::TimeDelta::FromSeconds(1);
76 base::Time new_last_accessed = base::Time::FromInternalValue(
77 src_entry.file_info().last_accessed()) + base::TimeDelta::FromSeconds(2);
79 src_entry.set_parent_local_id(dest_entry.local_id());
80 src_entry.set_title("Moved" + src_entry.title());
81 src_entry.mutable_file_info()->set_last_modified(
82 new_last_modified.ToInternalValue());
83 src_entry.mutable_file_info()->set_last_accessed(
84 new_last_accessed.ToInternalValue());
85 src_entry.set_metadata_edit_state(ResourceEntry::DIRTY);
87 FileError error = FILE_ERROR_FAILED;
88 base::PostTaskAndReplyWithResult(
89 blocking_task_runner(),
91 base::Bind(&ResourceMetadata::RefreshEntry,
92 base::Unretained(metadata()),
94 google_apis::test_util::CreateCopyResultCallback(&error));
95 test_util::RunBlockingPoolTask();
96 EXPECT_EQ(FILE_ERROR_OK, error);
98 // Perform server side update.
99 error = FILE_ERROR_FAILED;
100 performer_->UpdateEntry(
101 src_entry.local_id(),
102 ClientContext(USER_INITIATED),
103 google_apis::test_util::CreateCopyResultCallback(&error));
104 test_util::RunBlockingPoolTask();
105 EXPECT_EQ(FILE_ERROR_OK, error);
107 // Verify the file is updated on the server.
108 google_apis::GDataErrorCode gdata_error = google_apis::GDATA_OTHER_ERROR;
109 scoped_ptr<google_apis::ResourceEntry> gdata_entry;
110 fake_service()->GetResourceEntry(
111 src_entry.resource_id(),
112 google_apis::test_util::CreateCopyResultCallback(&gdata_error,
114 test_util::RunBlockingPoolTask();
115 EXPECT_EQ(google_apis::HTTP_SUCCESS, gdata_error);
116 ASSERT_TRUE(gdata_entry);
118 EXPECT_EQ(src_entry.title(), gdata_entry->title());
119 EXPECT_EQ(new_last_modified, gdata_entry->updated_time());
120 EXPECT_EQ(new_last_accessed, gdata_entry->last_viewed_time());
122 const google_apis::Link* parent_link =
123 gdata_entry->GetLinkByType(google_apis::Link::LINK_PARENT);
124 ASSERT_TRUE(parent_link);
125 EXPECT_EQ(dest_entry.resource_id(),
126 util::ExtractResourceIdFromUrl(parent_link->href()));
129 // Tests updating metadata of a file with a non-dirty cache file.
130 TEST_F(EntryUpdatePerformerTest, UpdateEntry_WithNonDirtyCache) {
131 base::FilePath src_path(
132 FILE_PATH_LITERAL("drive/root/Directory 1/SubDirectory File 1.txt"));
134 // Download the file content to prepare a non-dirty cache file.
135 file_system::DownloadOperation download_operation(
136 blocking_task_runner(), observer(), scheduler(), metadata(), cache(),
138 FileError error = FILE_ERROR_FAILED;
139 base::FilePath cache_file_path;
140 scoped_ptr<ResourceEntry> src_entry;
141 download_operation.EnsureFileDownloadedByPath(
143 ClientContext(USER_INITIATED),
144 GetFileContentInitializedCallback(),
145 google_apis::GetContentCallback(),
146 google_apis::test_util::CreateCopyResultCallback(
147 &error, &cache_file_path, &src_entry));
148 test_util::RunBlockingPoolTask();
149 EXPECT_EQ(FILE_ERROR_OK, error);
150 ASSERT_TRUE(src_entry);
152 // Update the entry locally.
153 src_entry->set_title("Updated" + src_entry->title());
154 src_entry->set_metadata_edit_state(ResourceEntry::DIRTY);
156 error = FILE_ERROR_FAILED;
157 base::PostTaskAndReplyWithResult(
158 blocking_task_runner(),
160 base::Bind(&ResourceMetadata::RefreshEntry,
161 base::Unretained(metadata()),
163 google_apis::test_util::CreateCopyResultCallback(&error));
164 test_util::RunBlockingPoolTask();
165 EXPECT_EQ(FILE_ERROR_OK, error);
167 // Perform server side update. This shouldn't fail. (crbug.com/358590)
168 error = FILE_ERROR_FAILED;
169 performer_->UpdateEntry(
170 src_entry->local_id(),
171 ClientContext(USER_INITIATED),
172 google_apis::test_util::CreateCopyResultCallback(&error));
173 test_util::RunBlockingPoolTask();
174 EXPECT_EQ(FILE_ERROR_OK, error);
176 // Verify the file is updated on the server.
177 google_apis::GDataErrorCode gdata_error = google_apis::GDATA_OTHER_ERROR;
178 scoped_ptr<google_apis::ResourceEntry> gdata_entry;
179 fake_service()->GetResourceEntry(
180 src_entry->resource_id(),
181 google_apis::test_util::CreateCopyResultCallback(&gdata_error,
183 test_util::RunBlockingPoolTask();
184 EXPECT_EQ(google_apis::HTTP_SUCCESS, gdata_error);
185 ASSERT_TRUE(gdata_entry);
186 EXPECT_EQ(src_entry->title(), gdata_entry->title());
189 TEST_F(EntryUpdatePerformerTest, UpdateEntry_NotFound) {
190 const std::string id = "this ID should result in NOT_FOUND";
191 FileError error = FILE_ERROR_FAILED;
192 performer_->UpdateEntry(
193 id, ClientContext(USER_INITIATED),
194 google_apis::test_util::CreateCopyResultCallback(&error));
195 test_util::RunBlockingPoolTask();
196 EXPECT_EQ(FILE_ERROR_NOT_FOUND, error);
199 TEST_F(EntryUpdatePerformerTest, UpdateEntry_ContentUpdate) {
200 const base::FilePath kFilePath(FILE_PATH_LITERAL("drive/root/File 1.txt"));
201 const std::string kResourceId("file:2_file_resource_id");
203 const std::string local_id = GetLocalId(kFilePath);
204 EXPECT_FALSE(local_id.empty());
206 const std::string kTestFileContent = "I'm being uploaded! Yay!";
207 EXPECT_EQ(FILE_ERROR_OK, StoreAndMarkDirty(local_id, kTestFileContent));
209 int64 original_changestamp =
210 fake_service()->about_resource().largest_change_id();
212 // The callback will be called upon completion of UpdateEntry().
213 FileError error = FILE_ERROR_FAILED;
214 performer_->UpdateEntry(
216 ClientContext(USER_INITIATED),
217 google_apis::test_util::CreateCopyResultCallback(&error));
218 test_util::RunBlockingPoolTask();
219 EXPECT_EQ(FILE_ERROR_OK, error);
221 // Check that the server has received an update.
222 EXPECT_LT(original_changestamp,
223 fake_service()->about_resource().largest_change_id());
225 // Check that the file size is updated to that of the updated content.
226 google_apis::GDataErrorCode gdata_error = google_apis::GDATA_OTHER_ERROR;
227 scoped_ptr<google_apis::ResourceEntry> server_entry;
228 fake_service()->GetResourceEntry(
230 google_apis::test_util::CreateCopyResultCallback(&gdata_error,
232 test_util::RunBlockingPoolTask();
233 EXPECT_EQ(google_apis::HTTP_SUCCESS, gdata_error);
234 EXPECT_EQ(static_cast<int64>(kTestFileContent.size()),
235 server_entry->file_size());
237 // Make sure that the cache is no longer dirty.
238 bool success = false;
239 FileCacheEntry cache_entry;
240 base::PostTaskAndReplyWithResult(
241 blocking_task_runner(),
243 base::Bind(&FileCache::GetCacheEntry,
244 base::Unretained(cache()),
247 google_apis::test_util::CreateCopyResultCallback(&success));
248 test_util::RunBlockingPoolTask();
249 ASSERT_TRUE(success);
250 EXPECT_FALSE(cache_entry.is_dirty());
253 TEST_F(EntryUpdatePerformerTest, UpdateEntry_ContentUpdateMd5Check) {
254 const base::FilePath kFilePath(FILE_PATH_LITERAL("drive/root/File 1.txt"));
255 const std::string kResourceId("file:2_file_resource_id");
257 const std::string local_id = GetLocalId(kFilePath);
258 EXPECT_FALSE(local_id.empty());
260 const std::string kTestFileContent = "I'm being uploaded! Yay!";
261 EXPECT_EQ(FILE_ERROR_OK, StoreAndMarkDirty(local_id, kTestFileContent));
263 int64 original_changestamp =
264 fake_service()->about_resource().largest_change_id();
266 // The callback will be called upon completion of UpdateEntry().
267 FileError error = FILE_ERROR_FAILED;
268 performer_->UpdateEntry(
270 ClientContext(USER_INITIATED),
271 google_apis::test_util::CreateCopyResultCallback(&error));
272 test_util::RunBlockingPoolTask();
273 EXPECT_EQ(FILE_ERROR_OK, error);
275 // Check that the server has received an update.
276 EXPECT_LT(original_changestamp,
277 fake_service()->about_resource().largest_change_id());
279 // Check that the file size is updated to that of the updated content.
280 google_apis::GDataErrorCode gdata_error = google_apis::GDATA_OTHER_ERROR;
281 scoped_ptr<google_apis::ResourceEntry> server_entry;
282 fake_service()->GetResourceEntry(
284 google_apis::test_util::CreateCopyResultCallback(&gdata_error,
286 test_util::RunBlockingPoolTask();
287 EXPECT_EQ(google_apis::HTTP_SUCCESS, gdata_error);
288 EXPECT_EQ(static_cast<int64>(kTestFileContent.size()),
289 server_entry->file_size());
291 // Make sure that the cache is no longer dirty.
292 bool success = false;
293 FileCacheEntry cache_entry;
294 base::PostTaskAndReplyWithResult(
295 blocking_task_runner(),
297 base::Bind(&FileCache::GetCacheEntry,
298 base::Unretained(cache()),
301 google_apis::test_util::CreateCopyResultCallback(&success));
302 test_util::RunBlockingPoolTask();
303 ASSERT_TRUE(success);
304 EXPECT_FALSE(cache_entry.is_dirty());
306 // Again mark the cache file dirty.
307 scoped_ptr<base::ScopedClosureRunner> file_closer;
308 error = FILE_ERROR_FAILED;
309 base::PostTaskAndReplyWithResult(
310 blocking_task_runner(),
312 base::Bind(&FileCache::OpenForWrite,
313 base::Unretained(cache()),
316 google_apis::test_util::CreateCopyResultCallback(&error));
317 test_util::RunBlockingPoolTask();
318 EXPECT_EQ(FILE_ERROR_OK, error);
321 // And call UpdateEntry again.
322 // In this case, although the file is marked as dirty, but the content
323 // hasn't been changed. Thus, the actual uploading should be skipped.
324 original_changestamp = fake_service()->about_resource().largest_change_id();
325 error = FILE_ERROR_FAILED;
326 performer_->UpdateEntry(
328 ClientContext(USER_INITIATED),
329 google_apis::test_util::CreateCopyResultCallback(&error));
330 test_util::RunBlockingPoolTask();
331 EXPECT_EQ(FILE_ERROR_OK, error);
333 EXPECT_EQ(original_changestamp,
334 fake_service()->about_resource().largest_change_id());
336 // Make sure that the cache is no longer dirty.
338 base::PostTaskAndReplyWithResult(
339 blocking_task_runner(),
341 base::Bind(&FileCache::GetCacheEntry,
342 base::Unretained(cache()),
345 google_apis::test_util::CreateCopyResultCallback(&success));
346 test_util::RunBlockingPoolTask();
347 ASSERT_TRUE(success);
348 EXPECT_FALSE(cache_entry.is_dirty());
351 TEST_F(EntryUpdatePerformerTest, UpdateEntry_OpenedForWrite) {
352 const base::FilePath kFilePath(FILE_PATH_LITERAL("drive/root/File 1.txt"));
353 const std::string kResourceId("file:2_file_resource_id");
355 const std::string local_id = GetLocalId(kFilePath);
356 EXPECT_FALSE(local_id.empty());
358 const std::string kTestFileContent = "I'm being uploaded! Yay!";
359 EXPECT_EQ(FILE_ERROR_OK, StoreAndMarkDirty(local_id, kTestFileContent));
361 // Emulate a situation where someone is writing to the file.
362 scoped_ptr<base::ScopedClosureRunner> file_closer;
363 FileError error = FILE_ERROR_FAILED;
364 base::PostTaskAndReplyWithResult(
365 blocking_task_runner(),
367 base::Bind(&FileCache::OpenForWrite,
368 base::Unretained(cache()),
371 google_apis::test_util::CreateCopyResultCallback(&error));
372 test_util::RunBlockingPoolTask();
373 EXPECT_EQ(FILE_ERROR_OK, error);
375 // Update. This should not clear the dirty bit.
376 error = FILE_ERROR_FAILED;
377 performer_->UpdateEntry(
379 ClientContext(USER_INITIATED),
380 google_apis::test_util::CreateCopyResultCallback(&error));
381 test_util::RunBlockingPoolTask();
382 EXPECT_EQ(FILE_ERROR_OK, error);
384 // Make sure that the cache is still dirty.
385 bool success = false;
386 FileCacheEntry cache_entry;
387 base::PostTaskAndReplyWithResult(
388 blocking_task_runner(),
390 base::Bind(&FileCache::GetCacheEntry,
391 base::Unretained(cache()),
394 google_apis::test_util::CreateCopyResultCallback(&success));
395 test_util::RunBlockingPoolTask();
396 EXPECT_TRUE(success);
397 EXPECT_TRUE(cache_entry.is_dirty());
402 // Update. This should clear the dirty bit.
403 error = FILE_ERROR_FAILED;
404 performer_->UpdateEntry(
406 ClientContext(USER_INITIATED),
407 google_apis::test_util::CreateCopyResultCallback(&error));
408 test_util::RunBlockingPoolTask();
409 EXPECT_EQ(FILE_ERROR_OK, error);
411 // Make sure that the cache is no longer dirty.
412 base::PostTaskAndReplyWithResult(
413 blocking_task_runner(),
415 base::Bind(&FileCache::GetCacheEntry,
416 base::Unretained(cache()),
419 google_apis::test_util::CreateCopyResultCallback(&success));
420 test_util::RunBlockingPoolTask();
421 EXPECT_TRUE(success);
422 EXPECT_FALSE(cache_entry.is_dirty());
425 TEST_F(EntryUpdatePerformerTest, UpdateEntry_UploadNewFile) {
426 // Create a new file locally.
427 const base::FilePath kFilePath(FILE_PATH_LITERAL("drive/root/New File.txt"));
429 ResourceEntry parent;
430 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(kFilePath.DirName(), &parent));
433 entry.set_parent_local_id(parent.local_id());
434 entry.set_title(kFilePath.BaseName().AsUTF8Unsafe());
435 entry.mutable_file_specific_info()->set_content_mime_type("text/plain");
436 entry.set_metadata_edit_state(ResourceEntry::DIRTY);
438 FileError error = FILE_ERROR_FAILED;
439 std::string local_id;
440 base::PostTaskAndReplyWithResult(
441 blocking_task_runner(),
443 base::Bind(&internal::ResourceMetadata::AddEntry,
444 base::Unretained(metadata()),
447 google_apis::test_util::CreateCopyResultCallback(&error));
448 test_util::RunBlockingPoolTask();
449 EXPECT_EQ(FILE_ERROR_OK, error);
451 // Update. This should result in creating a new file on the server.
452 error = FILE_ERROR_FAILED;
453 performer_->UpdateEntry(
455 ClientContext(USER_INITIATED),
456 google_apis::test_util::CreateCopyResultCallback(&error));
457 test_util::RunBlockingPoolTask();
458 EXPECT_EQ(FILE_ERROR_OK, error);
460 // The entry got a resource ID.
461 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(kFilePath, &entry));
462 EXPECT_FALSE(entry.resource_id().empty());
463 EXPECT_EQ(ResourceEntry::CLEAN, entry.metadata_edit_state());
465 // Make sure that the cache is no longer dirty.
466 bool success = false;
467 FileCacheEntry cache_entry;
468 base::PostTaskAndReplyWithResult(
469 blocking_task_runner(),
471 base::Bind(&FileCache::GetCacheEntry,
472 base::Unretained(cache()),
475 google_apis::test_util::CreateCopyResultCallback(&success));
476 test_util::RunBlockingPoolTask();
477 EXPECT_TRUE(success);
478 EXPECT_FALSE(cache_entry.is_dirty());
480 // Make sure that we really created a file.
481 google_apis::GDataErrorCode status = google_apis::GDATA_OTHER_ERROR;
482 scoped_ptr<google_apis::ResourceEntry> resource_entry;
483 fake_service()->GetResourceEntry(
485 google_apis::test_util::CreateCopyResultCallback(&status,
487 test_util::RunBlockingPoolTask();
488 EXPECT_EQ(google_apis::HTTP_SUCCESS, status);
489 ASSERT_TRUE(resource_entry);
490 EXPECT_FALSE(resource_entry->is_folder());
493 TEST_F(EntryUpdatePerformerTest, UpdateEntry_NewFileOpendForWrite) {
494 // Create a new file locally.
495 const base::FilePath kFilePath(FILE_PATH_LITERAL("drive/root/New File.txt"));
497 ResourceEntry parent;
498 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(kFilePath.DirName(), &parent));
501 entry.set_parent_local_id(parent.local_id());
502 entry.set_title(kFilePath.BaseName().AsUTF8Unsafe());
503 entry.mutable_file_specific_info()->set_content_mime_type("text/plain");
504 entry.set_metadata_edit_state(ResourceEntry::DIRTY);
506 FileError error = FILE_ERROR_FAILED;
507 std::string local_id;
508 base::PostTaskAndReplyWithResult(
509 blocking_task_runner(),
511 base::Bind(&internal::ResourceMetadata::AddEntry,
512 base::Unretained(metadata()),
515 google_apis::test_util::CreateCopyResultCallback(&error));
516 test_util::RunBlockingPoolTask();
517 EXPECT_EQ(FILE_ERROR_OK, error);
519 const std::string kTestFileContent = "This is a new file.";
520 EXPECT_EQ(FILE_ERROR_OK, StoreAndMarkDirty(local_id, kTestFileContent));
522 // Emulate a situation where someone is writing to the file.
523 scoped_ptr<base::ScopedClosureRunner> file_closer;
524 error = FILE_ERROR_FAILED;
525 base::PostTaskAndReplyWithResult(
526 blocking_task_runner(),
528 base::Bind(&FileCache::OpenForWrite,
529 base::Unretained(cache()),
532 google_apis::test_util::CreateCopyResultCallback(&error));
533 test_util::RunBlockingPoolTask();
534 EXPECT_EQ(FILE_ERROR_OK, error);
536 // Update, but no update is performed because the file is opened.
537 error = FILE_ERROR_FAILED;
538 performer_->UpdateEntry(
540 ClientContext(USER_INITIATED),
541 google_apis::test_util::CreateCopyResultCallback(&error));
542 test_util::RunBlockingPoolTask();
543 EXPECT_EQ(FILE_ERROR_OK, error);
545 // The entry hasn't got a resource ID yet.
546 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(kFilePath, &entry));
547 EXPECT_TRUE(entry.resource_id().empty());
552 // Update. This should result in creating a new file on the server.
553 error = FILE_ERROR_FAILED;
554 performer_->UpdateEntry(
556 ClientContext(USER_INITIATED),
557 google_apis::test_util::CreateCopyResultCallback(&error));
558 test_util::RunBlockingPoolTask();
559 EXPECT_EQ(FILE_ERROR_OK, error);
561 // The entry got a resource ID.
562 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(kFilePath, &entry));
563 EXPECT_FALSE(entry.resource_id().empty());
564 EXPECT_EQ(ResourceEntry::CLEAN, entry.metadata_edit_state());
567 TEST_F(EntryUpdatePerformerTest, UpdateEntry_CreateDirectory) {
568 // Create a new directory locally.
569 const base::FilePath kPath(FILE_PATH_LITERAL("drive/root/New Directory"));
571 ResourceEntry parent;
572 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(kPath.DirName(), &parent));
575 entry.set_parent_local_id(parent.local_id());
576 entry.set_title(kPath.BaseName().AsUTF8Unsafe());
577 entry.mutable_file_info()->set_is_directory(true);
578 entry.set_metadata_edit_state(ResourceEntry::DIRTY);
580 FileError error = FILE_ERROR_FAILED;
581 std::string local_id;
582 base::PostTaskAndReplyWithResult(
583 blocking_task_runner(),
585 base::Bind(&internal::ResourceMetadata::AddEntry,
586 base::Unretained(metadata()),
589 google_apis::test_util::CreateCopyResultCallback(&error));
590 test_util::RunBlockingPoolTask();
591 EXPECT_EQ(FILE_ERROR_OK, error);
593 // Update. This should result in creating a new directory on the server.
594 error = FILE_ERROR_FAILED;
595 performer_->UpdateEntry(
597 ClientContext(USER_INITIATED),
598 google_apis::test_util::CreateCopyResultCallback(&error));
599 test_util::RunBlockingPoolTask();
600 EXPECT_EQ(FILE_ERROR_OK, error);
602 // The entry got a resource ID.
603 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(kPath, &entry));
604 EXPECT_FALSE(entry.resource_id().empty());
605 EXPECT_EQ(ResourceEntry::CLEAN, entry.metadata_edit_state());
607 // Make sure that we really created a directory.
608 google_apis::GDataErrorCode status = google_apis::GDATA_OTHER_ERROR;
609 scoped_ptr<google_apis::ResourceEntry> resource_entry;
610 fake_service()->GetResourceEntry(
612 google_apis::test_util::CreateCopyResultCallback(&status,
614 test_util::RunBlockingPoolTask();
615 EXPECT_EQ(google_apis::HTTP_SUCCESS, status);
616 ASSERT_TRUE(resource_entry);
617 EXPECT_TRUE(resource_entry->is_folder());
620 } // namespace internal