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. 4 5 #include "chrome/browser/chromeos/drive/test_util.h" 6 7 #include <string> 8 9 #include "base/file_util.h" 10 #include "base/files/scoped_temp_dir.h" 11 #include "base/message_loop/message_loop.h" 12 #include "base/pending_task.h" 13 #include "base/prefs/pref_registry_simple.h" 14 #include "base/prefs/testing_pref_service.h" 15 #include "base/run_loop.h" 16 #include "base/threading/sequenced_worker_pool.h" 17 #include "chrome/browser/chromeos/drive/drive.pb.h" 18 #include "chrome/common/pref_names.h" 19 #include "content/public/browser/browser_thread.h" 20 21 namespace drive { 22 23 namespace test_util { 24 25 namespace { 26 27 // This class is used to monitor if any task is posted to a message loop. 28 class TaskObserver : public base::MessageLoop::TaskObserver { 29 public: 30 TaskObserver() : posted_(false) {} 31 virtual ~TaskObserver() {} 32 33 // MessageLoop::TaskObserver overrides. 34 virtual void WillProcessTask(const base::PendingTask& pending_task) OVERRIDE { 35 } 36 virtual void DidProcessTask(const base::PendingTask& pending_task) OVERRIDE { 37 posted_ = true; 38 } 39 40 // Returns true if any task was posted. 41 bool posted() const { return posted_; } 42 43 private: 44 bool posted_; 45 DISALLOW_COPY_AND_ASSIGN(TaskObserver); 46 }; 47 48 } // namespace 49 50 void RunBlockingPoolTask() { 51 while (true) { 52 content::BrowserThread::GetBlockingPool()->FlushForTesting(); 53 54 TaskObserver task_observer; 55 base::MessageLoop::current()->AddTaskObserver(&task_observer); 56 base::RunLoop().RunUntilIdle(); 57 base::MessageLoop::current()->RemoveTaskObserver(&task_observer); 58 if (!task_observer.posted()) 59 break; 60 } 61 } 62 63 TestCacheResource::TestCacheResource(const std::string& source_file, 64 const std::string& resource_id, 65 const std::string& md5, 66 bool is_pinned, 67 bool is_dirty) : 68 source_file(source_file), 69 resource_id(resource_id), 70 md5(md5), 71 is_pinned(is_pinned), 72 is_dirty(is_dirty) { 73 } 74 75 std::vector<TestCacheResource> GetDefaultTestCacheResources() { 76 const TestCacheResource resources[] = { 77 // Cache resource in tmp dir, i.e. not pinned or dirty. 78 TestCacheResource("cache.txt", 79 "tmp:resource_id", 80 "md5_tmp_alphanumeric", 81 false, 82 false), 83 // Cache resource in tmp dir, i.e. not pinned or dirty, with resource_id 84 // containing non-alphanumeric characters. 85 TestCacheResource("cache2.png", 86 "tmp:`~!@#$%^&*()-_=+[{|]}\\;',<.>/?", 87 "md5_tmp_non_alphanumeric", 88 false, 89 false), 90 // Cache resource that is pinned and present. 91 TestCacheResource("pinned/cache.mp3", 92 "pinned:existing", 93 "md5_pinned_existing", 94 true, 95 false), 96 // Cache resource with a non-existent source file that is pinned. 97 TestCacheResource("", 98 "pinned:non-existent", 99 "md5_pinned_non_existent", 100 true, 101 false), 102 // Cache resource that is dirty. 103 TestCacheResource("dirty/cache.avi", 104 "dirty:existing", 105 "md5_dirty_existing", 106 false, 107 true), 108 // Cache resource that is pinned and dirty. 109 TestCacheResource("pinned/dirty/cache.pdf", 110 "dirty_and_pinned:existing", 111 "md5_dirty_and_pinned_existing", 112 true, 113 true) 114 }; 115 return std::vector<TestCacheResource>( 116 resources, 117 resources + ARRAYSIZE_UNSAFE(resources)); 118 } 119 120 bool PrepareTestCacheResources( 121 internal::FileCache* cache, 122 const std::vector<TestCacheResource>& resources) { 123 // cache->StoreOnUIThread requires real file to be stored. As a dummy data for 124 // testing, an empty temporary file is created. 125 base::ScopedTempDir temp_dir; 126 if (!temp_dir.CreateUniqueTempDir()) 127 return false; 128 base::FilePath source_path; 129 if (!file_util::CreateTemporaryFileInDir(temp_dir.path(), &source_path)) 130 return false; 131 132 for (size_t i = 0; i < resources.size(); ++i) { 133 // Copy file from data dir to cache. 134 if (!resources[i].source_file.empty()) { 135 FileError error = FILE_ERROR_OK; 136 cache->StoreOnUIThread( 137 resources[i].resource_id, 138 resources[i].md5, 139 source_path, 140 internal::FileCache::FILE_OPERATION_COPY, 141 google_apis::test_util::CreateCopyResultCallback(&error)); 142 test_util::RunBlockingPoolTask(); 143 if (error != FILE_ERROR_OK) 144 return false; 145 } 146 // Pin. 147 if (resources[i].is_pinned) { 148 FileError error = FILE_ERROR_OK; 149 cache->PinOnUIThread( 150 resources[i].resource_id, 151 google_apis::test_util::CreateCopyResultCallback(&error)); 152 test_util::RunBlockingPoolTask(); 153 if (error != FILE_ERROR_OK) 154 return false; 155 } 156 // Mark dirty. 157 if (resources[i].is_dirty) { 158 FileError error = FILE_ERROR_OK; 159 cache->MarkDirtyOnUIThread( 160 resources[i].resource_id, 161 google_apis::test_util::CreateCopyResultCallback(&error)); 162 test_util::RunBlockingPoolTask(); 163 if (error != FILE_ERROR_OK) 164 return false; 165 } 166 } 167 return true; 168 } 169 170 void RegisterDrivePrefs(PrefRegistrySimple* pref_registry) { 171 pref_registry->RegisterBooleanPref( 172 prefs::kDisableDrive, 173 false); 174 pref_registry->RegisterBooleanPref( 175 prefs::kDisableDriveOverCellular, 176 true); 177 pref_registry->RegisterBooleanPref( 178 prefs::kDisableDriveHostedFiles, 179 false); 180 } 181 182 FakeNetworkChangeNotifier::FakeNetworkChangeNotifier() 183 : type_(CONNECTION_WIFI) { 184 } 185 186 void FakeNetworkChangeNotifier::SetConnectionType(ConnectionType type) { 187 type_ = type; 188 NotifyObserversOfConnectionTypeChange(); 189 } 190 191 net::NetworkChangeNotifier::ConnectionType 192 FakeNetworkChangeNotifier::GetCurrentConnectionType() const { 193 return type_; 194 } 195 196 } // namespace test_util 197 } // namespace drive 198