| OLD | NEW | 
|     1 // Copyright 2014 The Chromium Authors. All rights reserved. |     1 // Copyright 2014 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 <algorithm> |     5 #include <algorithm> | 
|     6 #include <stack> |     6 #include <stack> | 
|     7  |     7  | 
|     8 #include "base/file_util.h" |     8 #include "base/file_util.h" | 
|     9 #include "base/message_loop/message_loop.h" |     9 #include "base/message_loop/message_loop.h" | 
|    10 #include "base/run_loop.h" |    10 #include "base/run_loop.h" | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
|    27 #include "chrome/browser/sync_file_system/sync_file_system_test_util.h" |    27 #include "chrome/browser/sync_file_system/sync_file_system_test_util.h" | 
|    28 #include "chrome/browser/sync_file_system/syncable_file_system_util.h" |    28 #include "chrome/browser/sync_file_system/syncable_file_system_util.h" | 
|    29 #include "chrome/test/base/testing_profile.h" |    29 #include "chrome/test/base/testing_profile.h" | 
|    30 #include "content/public/test/test_browser_thread.h" |    30 #include "content/public/test/test_browser_thread.h" | 
|    31 #include "content/public/test/test_browser_thread_bundle.h" |    31 #include "content/public/test/test_browser_thread_bundle.h" | 
|    32 #include "extensions/common/extension.h" |    32 #include "extensions/common/extension.h" | 
|    33 #include "google_apis/drive/drive_api_parser.h" |    33 #include "google_apis/drive/drive_api_parser.h" | 
|    34 #include "testing/gtest/include/gtest/gtest.h" |    34 #include "testing/gtest/include/gtest/gtest.h" | 
|    35 #include "third_party/leveldatabase/src/helpers/memenv/memenv.h" |    35 #include "third_party/leveldatabase/src/helpers/memenv/memenv.h" | 
|    36 #include "third_party/leveldatabase/src/include/leveldb/env.h" |    36 #include "third_party/leveldatabase/src/include/leveldb/env.h" | 
|    37 #include "webkit/browser/fileapi/file_system_context.h" |    37 #include "storage/browser/fileapi/file_system_context.h" | 
|    38  |    38  | 
|    39 #define FPL(a) FILE_PATH_LITERAL(a) |    39 #define FPL(a) FILE_PATH_LITERAL(a) | 
|    40  |    40  | 
|    41 namespace sync_file_system { |    41 namespace sync_file_system { | 
|    42 namespace drive_backend { |    42 namespace drive_backend { | 
|    43  |    43  | 
|    44 typedef fileapi::FileSystemOperation::FileEntryList FileEntryList; |    44 typedef storage::FileSystemOperation::FileEntryList FileEntryList; | 
|    45  |    45  | 
|    46 namespace { |    46 namespace { | 
|    47  |    47  | 
|    48 template <typename T> |    48 template <typename T> | 
|    49 void SetValueAndCallClosure(const base::Closure& closure, |    49 void SetValueAndCallClosure(const base::Closure& closure, | 
|    50                             T* arg_out, |    50                             T* arg_out, | 
|    51                             T arg) { |    51                             T arg) { | 
|    52   *arg_out = base::internal::CallbackForward(arg); |    52   *arg_out = base::internal::CallbackForward(arg); | 
|    53   closure.Run(); |    53   closure.Run(); | 
|    54 } |    54 } | 
|    55  |    55  | 
|    56 void SetSyncStatusAndUrl(const base::Closure& closure, |    56 void SetSyncStatusAndUrl(const base::Closure& closure, | 
|    57                          SyncStatusCode* status_out, |    57                          SyncStatusCode* status_out, | 
|    58                          fileapi::FileSystemURL* url_out, |    58                          storage::FileSystemURL* url_out, | 
|    59                          SyncStatusCode status, |    59                          SyncStatusCode status, | 
|    60                          const fileapi::FileSystemURL& url) { |    60                          const storage::FileSystemURL& url) { | 
|    61   *status_out = status; |    61   *status_out = status; | 
|    62   *url_out = url; |    62   *url_out = url; | 
|    63   closure.Run(); |    63   closure.Run(); | 
|    64 } |    64 } | 
|    65  |    65  | 
|    66 }  // namespace |    66 }  // namespace | 
|    67  |    67  | 
|    68 class DriveBackendSyncTest : public testing::Test, |    68 class DriveBackendSyncTest : public testing::Test, | 
|    69                              public LocalFileSyncService::Observer, |    69                              public LocalFileSyncService::Observer, | 
|    70                              public RemoteFileSyncService::Observer { |    70                              public RemoteFileSyncService::Observer { | 
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   158  |   158  | 
|   159   virtual void OnRemoteChangeQueueUpdated(int64 pending_changes_hint) OVERRIDE { |   159   virtual void OnRemoteChangeQueueUpdated(int64 pending_changes_hint) OVERRIDE { | 
|   160     pending_remote_changes_ = pending_changes_hint; |   160     pending_remote_changes_ = pending_changes_hint; | 
|   161   } |   161   } | 
|   162  |   162  | 
|   163   virtual void OnLocalChangeAvailable(int64 pending_changes_hint) OVERRIDE { |   163   virtual void OnLocalChangeAvailable(int64 pending_changes_hint) OVERRIDE { | 
|   164     pending_local_changes_ = pending_changes_hint; |   164     pending_local_changes_ = pending_changes_hint; | 
|   165   } |   165   } | 
|   166  |   166  | 
|   167  protected: |   167  protected: | 
|   168   fileapi::FileSystemURL CreateURL(const std::string& app_id, |   168   storage::FileSystemURL CreateURL(const std::string& app_id, | 
|   169                                    const base::FilePath::StringType& path) { |   169                                    const base::FilePath::StringType& path) { | 
|   170     return CreateURL(app_id, base::FilePath(path)); |   170     return CreateURL(app_id, base::FilePath(path)); | 
|   171   } |   171   } | 
|   172  |   172  | 
|   173   fileapi::FileSystemURL CreateURL(const std::string& app_id, |   173   storage::FileSystemURL CreateURL(const std::string& app_id, | 
|   174                                    const base::FilePath& path) { |   174                                    const base::FilePath& path) { | 
|   175     GURL origin = extensions::Extension::GetBaseURLFromExtensionId(app_id); |   175     GURL origin = extensions::Extension::GetBaseURLFromExtensionId(app_id); | 
|   176     return CreateSyncableFileSystemURL(origin, path); |   176     return CreateSyncableFileSystemURL(origin, path); | 
|   177   } |   177   } | 
|   178  |   178  | 
|   179   bool GetAppRootFolderID(const std::string& app_id, |   179   bool GetAppRootFolderID(const std::string& app_id, | 
|   180                           std::string* folder_id) { |   180                           std::string* folder_id) { | 
|   181     base::RunLoop run_loop; |   181     base::RunLoop run_loop; | 
|   182     bool success = false; |   182     bool success = false; | 
|   183     FileTracker tracker; |   183     FileTracker tracker; | 
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   266                       const base::FilePath::StringType& path) { |   266                       const base::FilePath::StringType& path) { | 
|   267     ASSERT_TRUE(ContainsKey(file_systems_, app_id)); |   267     ASSERT_TRUE(ContainsKey(file_systems_, app_id)); | 
|   268     EXPECT_EQ(base::File::FILE_OK, |   268     EXPECT_EQ(base::File::FILE_OK, | 
|   269               file_systems_[app_id]->CreateDirectory( |   269               file_systems_[app_id]->CreateDirectory( | 
|   270                   CreateURL(app_id, path))); |   270                   CreateURL(app_id, path))); | 
|   271   } |   271   } | 
|   272  |   272  | 
|   273   void AddOrUpdateLocalFile(const std::string& app_id, |   273   void AddOrUpdateLocalFile(const std::string& app_id, | 
|   274                             const base::FilePath::StringType& path, |   274                             const base::FilePath::StringType& path, | 
|   275                             const std::string& content) { |   275                             const std::string& content) { | 
|   276     fileapi::FileSystemURL url(CreateURL(app_id, path)); |   276     storage::FileSystemURL url(CreateURL(app_id, path)); | 
|   277     ASSERT_TRUE(ContainsKey(file_systems_, app_id)); |   277     ASSERT_TRUE(ContainsKey(file_systems_, app_id)); | 
|   278     EXPECT_EQ(base::File::FILE_OK, file_systems_[app_id]->CreateFile(url)); |   278     EXPECT_EQ(base::File::FILE_OK, file_systems_[app_id]->CreateFile(url)); | 
|   279     int64 bytes_written = file_systems_[app_id]->WriteString(url, content); |   279     int64 bytes_written = file_systems_[app_id]->WriteString(url, content); | 
|   280     EXPECT_EQ(static_cast<int64>(content.size()), bytes_written); |   280     EXPECT_EQ(static_cast<int64>(content.size()), bytes_written); | 
|   281     base::RunLoop().RunUntilIdle(); |   281     base::RunLoop().RunUntilIdle(); | 
|   282   } |   282   } | 
|   283  |   283  | 
|   284   void UpdateLocalFile(const std::string& app_id, |   284   void UpdateLocalFile(const std::string& app_id, | 
|   285                        const base::FilePath::StringType& path, |   285                        const base::FilePath::StringType& path, | 
|   286                        const std::string& content) { |   286                        const std::string& content) { | 
|   287     ASSERT_TRUE(ContainsKey(file_systems_, app_id)); |   287     ASSERT_TRUE(ContainsKey(file_systems_, app_id)); | 
|   288     int64 bytes_written = file_systems_[app_id]->WriteString( |   288     int64 bytes_written = file_systems_[app_id]->WriteString( | 
|   289         CreateURL(app_id, path), content); |   289         CreateURL(app_id, path), content); | 
|   290     EXPECT_EQ(static_cast<int64>(content.size()), bytes_written); |   290     EXPECT_EQ(static_cast<int64>(content.size()), bytes_written); | 
|   291     base::RunLoop().RunUntilIdle(); |   291     base::RunLoop().RunUntilIdle(); | 
|   292   } |   292   } | 
|   293  |   293  | 
|   294   void RemoveLocal(const std::string& app_id, |   294   void RemoveLocal(const std::string& app_id, | 
|   295                    const base::FilePath::StringType& path) { |   295                    const base::FilePath::StringType& path) { | 
|   296     ASSERT_TRUE(ContainsKey(file_systems_, app_id)); |   296     ASSERT_TRUE(ContainsKey(file_systems_, app_id)); | 
|   297     EXPECT_EQ(base::File::FILE_OK, |   297     EXPECT_EQ(base::File::FILE_OK, | 
|   298               file_systems_[app_id]->Remove( |   298               file_systems_[app_id]->Remove( | 
|   299                   CreateURL(app_id, path), |   299                   CreateURL(app_id, path), | 
|   300                   true /* recursive */)); |   300                   true /* recursive */)); | 
|   301     base::RunLoop().RunUntilIdle(); |   301     base::RunLoop().RunUntilIdle(); | 
|   302   } |   302   } | 
|   303  |   303  | 
|   304   SyncStatusCode ProcessLocalChange() { |   304   SyncStatusCode ProcessLocalChange() { | 
|   305     SyncStatusCode status = SYNC_STATUS_UNKNOWN; |   305     SyncStatusCode status = SYNC_STATUS_UNKNOWN; | 
|   306     fileapi::FileSystemURL url; |   306     storage::FileSystemURL url; | 
|   307     base::RunLoop run_loop; |   307     base::RunLoop run_loop; | 
|   308     local_sync_service_->ProcessLocalChange(base::Bind( |   308     local_sync_service_->ProcessLocalChange(base::Bind( | 
|   309         &SetSyncStatusAndUrl, run_loop.QuitClosure(), &status, &url)); |   309         &SetSyncStatusAndUrl, run_loop.QuitClosure(), &status, &url)); | 
|   310     run_loop.Run(); |   310     run_loop.Run(); | 
|   311     return status; |   311     return status; | 
|   312   } |   312   } | 
|   313  |   313  | 
|   314   SyncStatusCode ProcessRemoteChange() { |   314   SyncStatusCode ProcessRemoteChange() { | 
|   315     SyncStatusCode status = SYNC_STATUS_UNKNOWN; |   315     SyncStatusCode status = SYNC_STATUS_UNKNOWN; | 
|   316     fileapi::FileSystemURL url; |   316     storage::FileSystemURL url; | 
|   317     base::RunLoop run_loop; |   317     base::RunLoop run_loop; | 
|   318     remote_sync_service_->ProcessRemoteChange(base::Bind( |   318     remote_sync_service_->ProcessRemoteChange(base::Bind( | 
|   319         &SetSyncStatusAndUrl, run_loop.QuitClosure(), &status, &url)); |   319         &SetSyncStatusAndUrl, run_loop.QuitClosure(), &status, &url)); | 
|   320     run_loop.Run(); |   320     run_loop.Run(); | 
|   321     return status; |   321     return status; | 
|   322   } |   322   } | 
|   323  |   323  | 
|   324   int64 GetLargestChangeID() { |   324   int64 GetLargestChangeID() { | 
|   325     scoped_ptr<google_apis::AboutResource> about_resource; |   325     scoped_ptr<google_apis::AboutResource> about_resource; | 
|   326     EXPECT_EQ(google_apis::HTTP_SUCCESS, |   326     EXPECT_EQ(google_apis::HTTP_SUCCESS, | 
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   455                   folder_id, &remote_entries)); |   455                   folder_id, &remote_entries)); | 
|   456     std::map<std::string, const google_apis::ResourceEntry*> |   456     std::map<std::string, const google_apis::ResourceEntry*> | 
|   457         remote_entry_by_title; |   457         remote_entry_by_title; | 
|   458     for (size_t i = 0; i < remote_entries.size(); ++i) { |   458     for (size_t i = 0; i < remote_entries.size(); ++i) { | 
|   459       google_apis::ResourceEntry* remote_entry = remote_entries[i]; |   459       google_apis::ResourceEntry* remote_entry = remote_entries[i]; | 
|   460       EXPECT_FALSE(ContainsKey(remote_entry_by_title, remote_entry->title())) |   460       EXPECT_FALSE(ContainsKey(remote_entry_by_title, remote_entry->title())) | 
|   461           << "title: " << remote_entry->title(); |   461           << "title: " << remote_entry->title(); | 
|   462       remote_entry_by_title[remote_entry->title()] = remote_entry; |   462       remote_entry_by_title[remote_entry->title()] = remote_entry; | 
|   463     } |   463     } | 
|   464  |   464  | 
|   465     fileapi::FileSystemURL url(CreateURL(app_id, path)); |   465     storage::FileSystemURL url(CreateURL(app_id, path)); | 
|   466     FileEntryList local_entries; |   466     FileEntryList local_entries; | 
|   467     EXPECT_EQ(base::File::FILE_OK, |   467     EXPECT_EQ(base::File::FILE_OK, | 
|   468               file_system->ReadDirectory(url, &local_entries)); |   468               file_system->ReadDirectory(url, &local_entries)); | 
|   469     for (FileEntryList::iterator itr = local_entries.begin(); |   469     for (FileEntryList::iterator itr = local_entries.begin(); | 
|   470          itr != local_entries.end(); |   470          itr != local_entries.end(); | 
|   471          ++itr) { |   471          ++itr) { | 
|   472       const fileapi::DirectoryEntry& local_entry = *itr; |   472       const storage::DirectoryEntry& local_entry = *itr; | 
|   473       fileapi::FileSystemURL entry_url( |   473       storage::FileSystemURL entry_url( | 
|   474           CreateURL(app_id, path.Append(local_entry.name))); |   474           CreateURL(app_id, path.Append(local_entry.name))); | 
|   475       std::string title = |   475       std::string title = | 
|   476           fileapi::VirtualPath::BaseName(entry_url.path()).AsUTF8Unsafe(); |   476           storage::VirtualPath::BaseName(entry_url.path()).AsUTF8Unsafe(); | 
|   477       SCOPED_TRACE(testing::Message() << "Verifying entry: " << title); |   477       SCOPED_TRACE(testing::Message() << "Verifying entry: " << title); | 
|   478  |   478  | 
|   479       ASSERT_TRUE(ContainsKey(remote_entry_by_title, title)); |   479       ASSERT_TRUE(ContainsKey(remote_entry_by_title, title)); | 
|   480       const google_apis::ResourceEntry& remote_entry = |   480       const google_apis::ResourceEntry& remote_entry = | 
|   481           *remote_entry_by_title[title]; |   481           *remote_entry_by_title[title]; | 
|   482       if (local_entry.is_directory) { |   482       if (local_entry.is_directory) { | 
|   483         ASSERT_TRUE(remote_entry.is_folder()); |   483         ASSERT_TRUE(remote_entry.is_folder()); | 
|   484         VerifyConsistencyForFolder(app_id, entry_url.path(), |   484         VerifyConsistencyForFolder(app_id, entry_url.path(), | 
|   485                                    remote_entry.resource_id(), |   485                                    remote_entry.resource_id(), | 
|   486                                    file_system); |   486                                    file_system); | 
|   487       } else { |   487       } else { | 
|   488         ASSERT_TRUE(remote_entry.is_file()); |   488         ASSERT_TRUE(remote_entry.is_file()); | 
|   489         VerifyConsistencyForFile(app_id, entry_url.path(), |   489         VerifyConsistencyForFile(app_id, entry_url.path(), | 
|   490                                  remote_entry.resource_id(), |   490                                  remote_entry.resource_id(), | 
|   491                                  file_system); |   491                                  file_system); | 
|   492       } |   492       } | 
|   493       remote_entry_by_title.erase(title); |   493       remote_entry_by_title.erase(title); | 
|   494     } |   494     } | 
|   495  |   495  | 
|   496     EXPECT_TRUE(remote_entry_by_title.empty()); |   496     EXPECT_TRUE(remote_entry_by_title.empty()); | 
|   497   } |   497   } | 
|   498  |   498  | 
|   499   void VerifyConsistencyForFile(const std::string& app_id, |   499   void VerifyConsistencyForFile(const std::string& app_id, | 
|   500                                 const base::FilePath& path, |   500                                 const base::FilePath& path, | 
|   501                                 const std::string& file_id, |   501                                 const std::string& file_id, | 
|   502                                 CannedSyncableFileSystem* file_system) { |   502                                 CannedSyncableFileSystem* file_system) { | 
|   503     fileapi::FileSystemURL url(CreateURL(app_id, path)); |   503     storage::FileSystemURL url(CreateURL(app_id, path)); | 
|   504     std::string file_content; |   504     std::string file_content; | 
|   505     EXPECT_EQ(google_apis::HTTP_SUCCESS, |   505     EXPECT_EQ(google_apis::HTTP_SUCCESS, | 
|   506               fake_drive_service_helper_->ReadFile(file_id, &file_content)); |   506               fake_drive_service_helper_->ReadFile(file_id, &file_content)); | 
|   507     EXPECT_EQ(base::File::FILE_OK, |   507     EXPECT_EQ(base::File::FILE_OK, | 
|   508               file_system->VerifyFile(url, file_content)); |   508               file_system->VerifyFile(url, file_content)); | 
|   509   } |   509   } | 
|   510  |   510  | 
|   511   size_t CountApp() { |   511   size_t CountApp() { | 
|   512     return file_systems_.size(); |   512     return file_systems_.size(); | 
|   513   } |   513   } | 
|   514  |   514  | 
|   515   size_t CountLocalFile(const std::string& app_id) { |   515   size_t CountLocalFile(const std::string& app_id) { | 
|   516     if (!ContainsKey(file_systems_, app_id)) |   516     if (!ContainsKey(file_systems_, app_id)) | 
|   517       return 0; |   517       return 0; | 
|   518  |   518  | 
|   519     CannedSyncableFileSystem* file_system = file_systems_[app_id]; |   519     CannedSyncableFileSystem* file_system = file_systems_[app_id]; | 
|   520     std::stack<base::FilePath> folders; |   520     std::stack<base::FilePath> folders; | 
|   521     folders.push(base::FilePath());  // root folder |   521     folders.push(base::FilePath());  // root folder | 
|   522  |   522  | 
|   523     size_t result = 1; |   523     size_t result = 1; | 
|   524     while (!folders.empty()) { |   524     while (!folders.empty()) { | 
|   525       fileapi::FileSystemURL url(CreateURL(app_id, folders.top())); |   525       storage::FileSystemURL url(CreateURL(app_id, folders.top())); | 
|   526       folders.pop(); |   526       folders.pop(); | 
|   527  |   527  | 
|   528       FileEntryList entries; |   528       FileEntryList entries; | 
|   529       EXPECT_EQ(base::File::FILE_OK, |   529       EXPECT_EQ(base::File::FILE_OK, | 
|   530                 file_system->ReadDirectory(url, &entries)); |   530                 file_system->ReadDirectory(url, &entries)); | 
|   531       for (FileEntryList::iterator itr = entries.begin(); |   531       for (FileEntryList::iterator itr = entries.begin(); | 
|   532            itr != entries.end(); ++itr) { |   532            itr != entries.end(); ++itr) { | 
|   533         ++result; |   533         ++result; | 
|   534         if (itr->is_directory) |   534         if (itr->is_directory) | 
|   535           folders.push(url.path().Append(itr->name)); |   535           folders.push(url.path().Append(itr->name)); | 
| (...skipping 1188 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1724  |  1724  | 
|  1725   EXPECT_EQ(1u, CountApp()); |  1725   EXPECT_EQ(1u, CountApp()); | 
|  1726   EXPECT_EQ(1u, CountLocalFile(app_id)); |  1726   EXPECT_EQ(1u, CountLocalFile(app_id)); | 
|  1727  |  1727  | 
|  1728   EXPECT_EQ(2u, CountMetadata()); |  1728   EXPECT_EQ(2u, CountMetadata()); | 
|  1729   EXPECT_EQ(2u, CountTracker()); |  1729   EXPECT_EQ(2u, CountTracker()); | 
|  1730 } |  1730 } | 
|  1731  |  1731  | 
|  1732 }  // namespace drive_backend |  1732 }  // namespace drive_backend | 
|  1733 }  // namespace sync_file_system |  1733 }  // namespace sync_file_system | 
| OLD | NEW |