| OLD | NEW | 
 | (Empty) | 
|    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. |  | 
|    4  |  | 
|    5 #include "chrome/browser/chromeos/drive/change_list_loader.h" |  | 
|    6  |  | 
|    7 #include "base/callback_helpers.h" |  | 
|    8 #include "base/files/scoped_temp_dir.h" |  | 
|    9 #include "base/memory/scoped_ptr.h" |  | 
|   10 #include "base/prefs/testing_pref_service.h" |  | 
|   11 #include "base/run_loop.h" |  | 
|   12 #include "base/single_thread_task_runner.h" |  | 
|   13 #include "base/thread_task_runner_handle.h" |  | 
|   14 #include "chrome/browser/chromeos/drive/change_list_loader_observer.h" |  | 
|   15 #include "components/drive/drive_test_util.h" |  | 
|   16 #include "components/drive/event_logger.h" |  | 
|   17 #include "components/drive/file_cache.h" |  | 
|   18 #include "components/drive/file_change.h" |  | 
|   19 #include "components/drive/file_system_core_util.h" |  | 
|   20 #include "components/drive/job_scheduler.h" |  | 
|   21 #include "components/drive/resource_metadata.h" |  | 
|   22 #include "components/drive/service/fake_drive_service.h" |  | 
|   23 #include "components/drive/service/test_util.h" |  | 
|   24 #include "content/public/test/test_browser_thread_bundle.h" |  | 
|   25 #include "google_apis/drive/drive_api_parser.h" |  | 
|   26 #include "google_apis/drive/test_util.h" |  | 
|   27 #include "testing/gtest/include/gtest/gtest.h" |  | 
|   28  |  | 
|   29 namespace drive { |  | 
|   30 namespace internal { |  | 
|   31  |  | 
|   32 class TestChangeListLoaderObserver : public ChangeListLoaderObserver { |  | 
|   33  public: |  | 
|   34   explicit TestChangeListLoaderObserver(ChangeListLoader* loader) |  | 
|   35       : loader_(loader), |  | 
|   36         load_from_server_complete_count_(0), |  | 
|   37         initial_load_complete_count_(0) { |  | 
|   38     loader_->AddObserver(this); |  | 
|   39   } |  | 
|   40  |  | 
|   41   ~TestChangeListLoaderObserver() override { loader_->RemoveObserver(this); } |  | 
|   42  |  | 
|   43   const FileChange& changed_files() const { return changed_files_; } |  | 
|   44   void clear_changed_files() { changed_files_.ClearForTest(); } |  | 
|   45  |  | 
|   46   int load_from_server_complete_count() const { |  | 
|   47     return load_from_server_complete_count_; |  | 
|   48   } |  | 
|   49   int initial_load_complete_count() const { |  | 
|   50     return initial_load_complete_count_; |  | 
|   51   } |  | 
|   52  |  | 
|   53   // ChageListObserver overrides: |  | 
|   54   void OnFileChanged(const FileChange& changed_files) override { |  | 
|   55     changed_files_.Apply(changed_files); |  | 
|   56   } |  | 
|   57   void OnLoadFromServerComplete() override { |  | 
|   58     ++load_from_server_complete_count_; |  | 
|   59   } |  | 
|   60   void OnInitialLoadComplete() override { ++initial_load_complete_count_; } |  | 
|   61  |  | 
|   62  private: |  | 
|   63   ChangeListLoader* loader_; |  | 
|   64   FileChange changed_files_; |  | 
|   65   int load_from_server_complete_count_; |  | 
|   66   int initial_load_complete_count_; |  | 
|   67  |  | 
|   68   DISALLOW_COPY_AND_ASSIGN(TestChangeListLoaderObserver); |  | 
|   69 }; |  | 
|   70  |  | 
|   71 class ChangeListLoaderTest : public testing::Test { |  | 
|   72  protected: |  | 
|   73   void SetUp() override { |  | 
|   74     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |  | 
|   75     pref_service_.reset(new TestingPrefServiceSimple); |  | 
|   76     test_util::RegisterDrivePrefs(pref_service_->registry()); |  | 
|   77  |  | 
|   78     logger_.reset(new EventLogger); |  | 
|   79  |  | 
|   80     drive_service_.reset(new FakeDriveService); |  | 
|   81     ASSERT_TRUE(test_util::SetUpTestEntries(drive_service_.get())); |  | 
|   82  |  | 
|   83     scheduler_.reset(new JobScheduler( |  | 
|   84         pref_service_.get(), |  | 
|   85         logger_.get(), |  | 
|   86         drive_service_.get(), |  | 
|   87         base::ThreadTaskRunnerHandle::Get().get())); |  | 
|   88     metadata_storage_.reset(new ResourceMetadataStorage( |  | 
|   89         temp_dir_.path(), base::ThreadTaskRunnerHandle::Get().get())); |  | 
|   90     ASSERT_TRUE(metadata_storage_->Initialize()); |  | 
|   91  |  | 
|   92     cache_.reset(new FileCache(metadata_storage_.get(), |  | 
|   93                                temp_dir_.path(), |  | 
|   94                                base::ThreadTaskRunnerHandle::Get().get(), |  | 
|   95                                NULL /* free_disk_space_getter */)); |  | 
|   96     ASSERT_TRUE(cache_->Initialize()); |  | 
|   97  |  | 
|   98     metadata_.reset(new ResourceMetadata( |  | 
|   99         metadata_storage_.get(), cache_.get(), |  | 
|  100         base::ThreadTaskRunnerHandle::Get().get())); |  | 
|  101     ASSERT_EQ(FILE_ERROR_OK, metadata_->Initialize()); |  | 
|  102  |  | 
|  103     about_resource_loader_.reset(new AboutResourceLoader(scheduler_.get())); |  | 
|  104     loader_controller_.reset(new LoaderController); |  | 
|  105     change_list_loader_.reset( |  | 
|  106         new ChangeListLoader(logger_.get(), |  | 
|  107                              base::ThreadTaskRunnerHandle::Get().get(), |  | 
|  108                              metadata_.get(), |  | 
|  109                              scheduler_.get(), |  | 
|  110                              about_resource_loader_.get(), |  | 
|  111                              loader_controller_.get())); |  | 
|  112   } |  | 
|  113  |  | 
|  114   // Adds a new file to the root directory of the service. |  | 
|  115   scoped_ptr<google_apis::FileResource> AddNewFile(const std::string& title) { |  | 
|  116     google_apis::DriveApiErrorCode error = google_apis::DRIVE_FILE_ERROR; |  | 
|  117     scoped_ptr<google_apis::FileResource> entry; |  | 
|  118     drive_service_->AddNewFile( |  | 
|  119         "text/plain", |  | 
|  120         "content text", |  | 
|  121         drive_service_->GetRootResourceId(), |  | 
|  122         title, |  | 
|  123         false,  // shared_with_me |  | 
|  124         google_apis::test_util::CreateCopyResultCallback(&error, &entry)); |  | 
|  125     base::RunLoop().RunUntilIdle(); |  | 
|  126     EXPECT_EQ(google_apis::HTTP_CREATED, error); |  | 
|  127     return entry.Pass(); |  | 
|  128   } |  | 
|  129  |  | 
|  130   content::TestBrowserThreadBundle thread_bundle_; |  | 
|  131   base::ScopedTempDir temp_dir_; |  | 
|  132   scoped_ptr<TestingPrefServiceSimple> pref_service_; |  | 
|  133   scoped_ptr<EventLogger> logger_; |  | 
|  134   scoped_ptr<FakeDriveService> drive_service_; |  | 
|  135   scoped_ptr<JobScheduler> scheduler_; |  | 
|  136   scoped_ptr<ResourceMetadataStorage, |  | 
|  137              test_util::DestroyHelperForTests> metadata_storage_; |  | 
|  138   scoped_ptr<FileCache, test_util::DestroyHelperForTests> cache_; |  | 
|  139   scoped_ptr<ResourceMetadata, test_util::DestroyHelperForTests> metadata_; |  | 
|  140   scoped_ptr<AboutResourceLoader> about_resource_loader_; |  | 
|  141   scoped_ptr<LoaderController> loader_controller_; |  | 
|  142   scoped_ptr<ChangeListLoader> change_list_loader_; |  | 
|  143 }; |  | 
|  144  |  | 
|  145 TEST_F(ChangeListLoaderTest, AboutResourceLoader) { |  | 
|  146   google_apis::DriveApiErrorCode error[6] = {}; |  | 
|  147   scoped_ptr<google_apis::AboutResource> about[6]; |  | 
|  148  |  | 
|  149   // No resource is cached at the beginning. |  | 
|  150   ASSERT_FALSE(about_resource_loader_->cached_about_resource()); |  | 
|  151  |  | 
|  152   // Since no resource is cached, this "Get" should trigger the update. |  | 
|  153   about_resource_loader_->GetAboutResource( |  | 
|  154       google_apis::test_util::CreateCopyResultCallback(error + 0, about + 0)); |  | 
|  155   // Since there is one in-flight update, the next "Get" just wait for it. |  | 
|  156   about_resource_loader_->GetAboutResource( |  | 
|  157       google_apis::test_util::CreateCopyResultCallback(error + 1, about + 1)); |  | 
|  158  |  | 
|  159   base::RunLoop().RunUntilIdle(); |  | 
|  160   EXPECT_EQ(google_apis::HTTP_SUCCESS, error[0]); |  | 
|  161   EXPECT_EQ(google_apis::HTTP_SUCCESS, error[1]); |  | 
|  162   const int64 first_changestamp = about[0]->largest_change_id(); |  | 
|  163   EXPECT_EQ(first_changestamp, about[1]->largest_change_id()); |  | 
|  164   ASSERT_TRUE(about_resource_loader_->cached_about_resource()); |  | 
|  165   EXPECT_EQ( |  | 
|  166       first_changestamp, |  | 
|  167       about_resource_loader_->cached_about_resource()->largest_change_id()); |  | 
|  168  |  | 
|  169   // Increment changestamp by 1. |  | 
|  170   AddNewFile("temp"); |  | 
|  171   // Explicitly calling UpdateAboutResource will start another API call. |  | 
|  172   about_resource_loader_->UpdateAboutResource( |  | 
|  173       google_apis::test_util::CreateCopyResultCallback(error + 2, about + 2)); |  | 
|  174   // It again waits for the in-flight UpdateAboutResoure call, even though this |  | 
|  175   // time there is a cached result. |  | 
|  176   about_resource_loader_->GetAboutResource( |  | 
|  177       google_apis::test_util::CreateCopyResultCallback(error + 3, about + 3)); |  | 
|  178  |  | 
|  179   base::RunLoop().RunUntilIdle(); |  | 
|  180   EXPECT_EQ(google_apis::HTTP_SUCCESS, error[2]); |  | 
|  181   EXPECT_EQ(google_apis::HTTP_SUCCESS, error[3]); |  | 
|  182   EXPECT_EQ(first_changestamp + 1, about[2]->largest_change_id()); |  | 
|  183   EXPECT_EQ(first_changestamp + 1, about[3]->largest_change_id()); |  | 
|  184   EXPECT_EQ( |  | 
|  185       first_changestamp + 1, |  | 
|  186       about_resource_loader_->cached_about_resource()->largest_change_id()); |  | 
|  187  |  | 
|  188   // Increment changestamp by 1. |  | 
|  189   AddNewFile("temp2"); |  | 
|  190   // Now no UpdateAboutResource task is running. Returns the cached result. |  | 
|  191   about_resource_loader_->GetAboutResource( |  | 
|  192       google_apis::test_util::CreateCopyResultCallback(error + 4, about + 4)); |  | 
|  193   // Explicitly calling UpdateAboutResource will start another API call. |  | 
|  194   about_resource_loader_->UpdateAboutResource( |  | 
|  195       google_apis::test_util::CreateCopyResultCallback(error + 5, about + 5)); |  | 
|  196  |  | 
|  197   base::RunLoop().RunUntilIdle(); |  | 
|  198   EXPECT_EQ(google_apis::HTTP_NO_CONTENT, error[4]); |  | 
|  199   EXPECT_EQ(google_apis::HTTP_SUCCESS, error[5]); |  | 
|  200   EXPECT_EQ(first_changestamp + 1, about[4]->largest_change_id()); |  | 
|  201   EXPECT_EQ(first_changestamp + 2, about[5]->largest_change_id()); |  | 
|  202   EXPECT_EQ( |  | 
|  203       first_changestamp + 2, |  | 
|  204       about_resource_loader_->cached_about_resource()->largest_change_id()); |  | 
|  205  |  | 
|  206   EXPECT_EQ(3, drive_service_->about_resource_load_count()); |  | 
|  207 } |  | 
|  208  |  | 
|  209 TEST_F(ChangeListLoaderTest, Load) { |  | 
|  210   EXPECT_FALSE(change_list_loader_->IsRefreshing()); |  | 
|  211  |  | 
|  212   // Start initial load. |  | 
|  213   TestChangeListLoaderObserver observer(change_list_loader_.get()); |  | 
|  214  |  | 
|  215   EXPECT_EQ(0, drive_service_->about_resource_load_count()); |  | 
|  216  |  | 
|  217   FileError error = FILE_ERROR_FAILED; |  | 
|  218   change_list_loader_->LoadIfNeeded( |  | 
|  219       google_apis::test_util::CreateCopyResultCallback(&error)); |  | 
|  220   EXPECT_TRUE(change_list_loader_->IsRefreshing()); |  | 
|  221   base::RunLoop().RunUntilIdle(); |  | 
|  222   EXPECT_EQ(FILE_ERROR_OK, error); |  | 
|  223  |  | 
|  224   EXPECT_FALSE(change_list_loader_->IsRefreshing()); |  | 
|  225   int64 changestamp = 0; |  | 
|  226   EXPECT_EQ(FILE_ERROR_OK, metadata_->GetLargestChangestamp(&changestamp)); |  | 
|  227   EXPECT_LT(0, changestamp); |  | 
|  228   EXPECT_EQ(1, drive_service_->file_list_load_count()); |  | 
|  229   EXPECT_EQ(1, drive_service_->about_resource_load_count()); |  | 
|  230   EXPECT_EQ(1, observer.initial_load_complete_count()); |  | 
|  231   EXPECT_EQ(1, observer.load_from_server_complete_count()); |  | 
|  232   EXPECT_TRUE(observer.changed_files().empty()); |  | 
|  233  |  | 
|  234   base::FilePath file_path = |  | 
|  235       util::GetDriveMyDriveRootPath().AppendASCII("File 1.txt"); |  | 
|  236   ResourceEntry entry; |  | 
|  237   EXPECT_EQ(FILE_ERROR_OK, |  | 
|  238             metadata_->GetResourceEntryByPath(file_path, &entry)); |  | 
|  239 } |  | 
|  240  |  | 
|  241 TEST_F(ChangeListLoaderTest, Load_LocalMetadataAvailable) { |  | 
|  242   // Prepare metadata. |  | 
|  243   FileError error = FILE_ERROR_FAILED; |  | 
|  244   change_list_loader_->LoadIfNeeded( |  | 
|  245       google_apis::test_util::CreateCopyResultCallback(&error)); |  | 
|  246   base::RunLoop().RunUntilIdle(); |  | 
|  247   EXPECT_EQ(FILE_ERROR_OK, error); |  | 
|  248  |  | 
|  249   // Reset loader. |  | 
|  250   about_resource_loader_.reset(new AboutResourceLoader(scheduler_.get())); |  | 
|  251   change_list_loader_.reset( |  | 
|  252       new ChangeListLoader(logger_.get(), |  | 
|  253                            base::ThreadTaskRunnerHandle::Get().get(), |  | 
|  254                            metadata_.get(), |  | 
|  255                            scheduler_.get(), |  | 
|  256                            about_resource_loader_.get(), |  | 
|  257                            loader_controller_.get())); |  | 
|  258  |  | 
|  259   // Add a file to the service. |  | 
|  260   scoped_ptr<google_apis::FileResource> gdata_entry = AddNewFile("New File"); |  | 
|  261   ASSERT_TRUE(gdata_entry); |  | 
|  262  |  | 
|  263   // Start loading. Because local metadata is available, the load results in |  | 
|  264   // returning FILE_ERROR_OK without fetching full list of resources. |  | 
|  265   const int previous_file_list_load_count = |  | 
|  266       drive_service_->file_list_load_count(); |  | 
|  267   TestChangeListLoaderObserver observer(change_list_loader_.get()); |  | 
|  268  |  | 
|  269   change_list_loader_->LoadIfNeeded( |  | 
|  270       google_apis::test_util::CreateCopyResultCallback(&error)); |  | 
|  271   EXPECT_TRUE(change_list_loader_->IsRefreshing()); |  | 
|  272   base::RunLoop().RunUntilIdle(); |  | 
|  273   EXPECT_EQ(FILE_ERROR_OK, error); |  | 
|  274   EXPECT_EQ(previous_file_list_load_count, |  | 
|  275             drive_service_->file_list_load_count()); |  | 
|  276   EXPECT_EQ(1, observer.initial_load_complete_count()); |  | 
|  277  |  | 
|  278   // Update should be checked by Load(). |  | 
|  279   int64 changestamp = 0; |  | 
|  280   EXPECT_EQ(FILE_ERROR_OK, metadata_->GetLargestChangestamp(&changestamp)); |  | 
|  281   EXPECT_EQ(drive_service_->about_resource().largest_change_id(), changestamp); |  | 
|  282   EXPECT_EQ(1, drive_service_->change_list_load_count()); |  | 
|  283   EXPECT_EQ(1, observer.load_from_server_complete_count()); |  | 
|  284   EXPECT_TRUE( |  | 
|  285       observer.changed_files().CountDirectory(util::GetDriveMyDriveRootPath())); |  | 
|  286  |  | 
|  287   base::FilePath file_path = |  | 
|  288       util::GetDriveMyDriveRootPath().AppendASCII(gdata_entry->title()); |  | 
|  289   ResourceEntry entry; |  | 
|  290   EXPECT_EQ(FILE_ERROR_OK, |  | 
|  291             metadata_->GetResourceEntryByPath(file_path, &entry)); |  | 
|  292 } |  | 
|  293  |  | 
|  294 TEST_F(ChangeListLoaderTest, CheckForUpdates) { |  | 
|  295   // CheckForUpdates() results in no-op before load. |  | 
|  296   FileError check_for_updates_error = FILE_ERROR_FAILED; |  | 
|  297   change_list_loader_->CheckForUpdates( |  | 
|  298       google_apis::test_util::CreateCopyResultCallback( |  | 
|  299           &check_for_updates_error)); |  | 
|  300   EXPECT_FALSE(change_list_loader_->IsRefreshing()); |  | 
|  301   base::RunLoop().RunUntilIdle(); |  | 
|  302   EXPECT_EQ(FILE_ERROR_FAILED, |  | 
|  303             check_for_updates_error);  // Callback was not run. |  | 
|  304   int64 changestamp = 0; |  | 
|  305   EXPECT_EQ(FILE_ERROR_OK, metadata_->GetLargestChangestamp(&changestamp)); |  | 
|  306   EXPECT_EQ(0, changestamp); |  | 
|  307   EXPECT_EQ(0, drive_service_->file_list_load_count()); |  | 
|  308   EXPECT_EQ(0, drive_service_->about_resource_load_count()); |  | 
|  309  |  | 
|  310   // Start initial load. |  | 
|  311   FileError load_error = FILE_ERROR_FAILED; |  | 
|  312   change_list_loader_->LoadIfNeeded( |  | 
|  313       google_apis::test_util::CreateCopyResultCallback(&load_error)); |  | 
|  314   EXPECT_TRUE(change_list_loader_->IsRefreshing()); |  | 
|  315  |  | 
|  316   // CheckForUpdates() while loading. |  | 
|  317   change_list_loader_->CheckForUpdates( |  | 
|  318       google_apis::test_util::CreateCopyResultCallback( |  | 
|  319           &check_for_updates_error)); |  | 
|  320  |  | 
|  321   base::RunLoop().RunUntilIdle(); |  | 
|  322   EXPECT_FALSE(change_list_loader_->IsRefreshing()); |  | 
|  323   EXPECT_EQ(FILE_ERROR_OK, load_error); |  | 
|  324   EXPECT_EQ(FILE_ERROR_OK, check_for_updates_error); |  | 
|  325   EXPECT_EQ(FILE_ERROR_OK, metadata_->GetLargestChangestamp(&changestamp)); |  | 
|  326   EXPECT_LT(0, changestamp); |  | 
|  327   EXPECT_EQ(1, drive_service_->file_list_load_count()); |  | 
|  328  |  | 
|  329   int64 previous_changestamp = 0; |  | 
|  330   EXPECT_EQ(FILE_ERROR_OK, |  | 
|  331             metadata_->GetLargestChangestamp(&previous_changestamp)); |  | 
|  332   // CheckForUpdates() results in no update. |  | 
|  333   change_list_loader_->CheckForUpdates( |  | 
|  334       google_apis::test_util::CreateCopyResultCallback( |  | 
|  335           &check_for_updates_error)); |  | 
|  336   EXPECT_TRUE(change_list_loader_->IsRefreshing()); |  | 
|  337   base::RunLoop().RunUntilIdle(); |  | 
|  338   EXPECT_FALSE(change_list_loader_->IsRefreshing()); |  | 
|  339   EXPECT_EQ(FILE_ERROR_OK, metadata_->GetLargestChangestamp(&changestamp)); |  | 
|  340   EXPECT_EQ(previous_changestamp, changestamp); |  | 
|  341  |  | 
|  342   // Add a file to the service. |  | 
|  343   scoped_ptr<google_apis::FileResource> gdata_entry = AddNewFile("New File"); |  | 
|  344   ASSERT_TRUE(gdata_entry); |  | 
|  345  |  | 
|  346   // CheckForUpdates() results in update. |  | 
|  347   TestChangeListLoaderObserver observer(change_list_loader_.get()); |  | 
|  348   change_list_loader_->CheckForUpdates( |  | 
|  349       google_apis::test_util::CreateCopyResultCallback( |  | 
|  350           &check_for_updates_error)); |  | 
|  351   EXPECT_TRUE(change_list_loader_->IsRefreshing()); |  | 
|  352   base::RunLoop().RunUntilIdle(); |  | 
|  353   EXPECT_FALSE(change_list_loader_->IsRefreshing()); |  | 
|  354   EXPECT_EQ(FILE_ERROR_OK, metadata_->GetLargestChangestamp(&changestamp)); |  | 
|  355   EXPECT_LT(previous_changestamp, changestamp); |  | 
|  356   EXPECT_EQ(1, observer.load_from_server_complete_count()); |  | 
|  357   EXPECT_TRUE( |  | 
|  358       observer.changed_files().CountDirectory(util::GetDriveMyDriveRootPath())); |  | 
|  359  |  | 
|  360   // The new file is found in the local metadata. |  | 
|  361   base::FilePath new_file_path = |  | 
|  362       util::GetDriveMyDriveRootPath().AppendASCII(gdata_entry->title()); |  | 
|  363   ResourceEntry entry; |  | 
|  364   EXPECT_EQ(FILE_ERROR_OK, |  | 
|  365             metadata_->GetResourceEntryByPath(new_file_path, &entry)); |  | 
|  366 } |  | 
|  367  |  | 
|  368 TEST_F(ChangeListLoaderTest, Lock) { |  | 
|  369   FileError error = FILE_ERROR_FAILED; |  | 
|  370   change_list_loader_->LoadIfNeeded( |  | 
|  371       google_apis::test_util::CreateCopyResultCallback(&error)); |  | 
|  372   base::RunLoop().RunUntilIdle(); |  | 
|  373   EXPECT_EQ(FILE_ERROR_OK, error); |  | 
|  374  |  | 
|  375   // Add a new file. |  | 
|  376   scoped_ptr<google_apis::FileResource> file = AddNewFile("New File"); |  | 
|  377   ASSERT_TRUE(file); |  | 
|  378  |  | 
|  379   // Lock the loader. |  | 
|  380   scoped_ptr<base::ScopedClosureRunner> lock = loader_controller_->GetLock(); |  | 
|  381  |  | 
|  382   // Start update. |  | 
|  383   TestChangeListLoaderObserver observer(change_list_loader_.get()); |  | 
|  384   FileError check_for_updates_error = FILE_ERROR_FAILED; |  | 
|  385   change_list_loader_->CheckForUpdates( |  | 
|  386       google_apis::test_util::CreateCopyResultCallback( |  | 
|  387           &check_for_updates_error)); |  | 
|  388   base::RunLoop().RunUntilIdle(); |  | 
|  389  |  | 
|  390   // Update is pending due to the lock. |  | 
|  391   EXPECT_TRUE(observer.changed_files().empty()); |  | 
|  392  |  | 
|  393   // Unlock the loader, this should resume the pending update. |  | 
|  394   lock.reset(); |  | 
|  395   base::RunLoop().RunUntilIdle(); |  | 
|  396   EXPECT_TRUE( |  | 
|  397       observer.changed_files().CountDirectory(util::GetDriveMyDriveRootPath())); |  | 
|  398 } |  | 
|  399  |  | 
|  400 }  // namespace internal |  | 
|  401 }  // namespace drive |  | 
| OLD | NEW |