provider_async_file_util_unittest.cc revision 010d83a9304c5a91596085d917d248abff47903a
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 3// found in the LICENSE file. 4 5#include <string> 6#include <vector> 7 8#include "base/files/file.h" 9#include "base/files/file_path.h" 10#include "base/files/scoped_temp_dir.h" 11#include "base/memory/scoped_ptr.h" 12#include "base/memory/weak_ptr.h" 13#include "base/platform_file.h" 14#include "base/run_loop.h" 15#include "chrome/browser/chromeos/file_system_provider/fake_provided_file_system.h" 16#include "chrome/browser/chromeos/file_system_provider/fileapi/provider_async_file_util.h" 17#include "chrome/browser/chromeos/file_system_provider/service.h" 18#include "chrome/browser/chromeos/file_system_provider/service_factory.h" 19#include "chrome/test/base/testing_browser_process.h" 20#include "chrome/test/base/testing_profile.h" 21#include "chrome/test/base/testing_profile_manager.h" 22#include "content/public/test/test_browser_thread_bundle.h" 23#include "content/public/test/test_file_system_context.h" 24#include "extensions/browser/extension_registry.h" 25#include "testing/gtest/include/gtest/gtest.h" 26#include "webkit/browser/fileapi/async_file_util.h" 27#include "webkit/browser/fileapi/external_mount_points.h" 28#include "webkit/browser/fileapi/file_system_context.h" 29#include "webkit/browser/fileapi/file_system_url.h" 30#include "webkit/common/blob/shareable_file_reference.h" 31 32namespace chromeos { 33namespace file_system_provider { 34namespace { 35 36const char kExtensionId[] = "mbflcebpggnecokmikipoihdbecnjfoj"; 37 38// Logs callbacks invocations on the tested operations. 39// TODO(mtomasz): Store and verify more arguments, once the operations return 40// anything else than just an error. 41class EventLogger { 42 public: 43 EventLogger() : weak_ptr_factory_(this) {} 44 virtual ~EventLogger() {} 45 46 void OnStatus(base::File::Error error) { 47 error_.reset(new base::File::Error(error)); 48 } 49 50 void OnCreateOrOpen(base::File::Error error, 51 base::PassPlatformFile platform_file, 52 const base::Closure& on_close_callback) { 53 error_.reset(new base::File::Error(error)); 54 } 55 56 void OnEnsureFileExists(base::File::Error error, bool created) { 57 error_.reset(new base::File::Error(error)); 58 } 59 60 void OnGetFileInfo(base::File::Error error, 61 const base::File::Info& file_info) { 62 error_.reset(new base::File::Error(error)); 63 } 64 65 void OnReadDirectory(base::File::Error error, 66 const fileapi::AsyncFileUtil::EntryList& file_list, 67 bool has_more) { 68 error_.reset(new base::File::Error(error)); 69 } 70 71 void OnCreateSnapshotFile( 72 base::File::Error error, 73 const base::File::Info& file_info, 74 const base::FilePath& platform_path, 75 const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref) { 76 error_.reset(new base::File::Error(error)); 77 } 78 79 void OnCopyFileProgress(int64 size) {} 80 81 base::WeakPtr<EventLogger> GetWeakPtr() { 82 return weak_ptr_factory_.GetWeakPtr(); 83 } 84 85 base::File::Error* error() { return error_.get(); } 86 87 private: 88 scoped_ptr<base::File::Error> error_; 89 base::WeakPtrFactory<EventLogger> weak_ptr_factory_; 90 91 DISALLOW_COPY_AND_ASSIGN(EventLogger); 92}; 93 94// Creates a cracked FileSystemURL for tests. 95fileapi::FileSystemURL CreateFileSystemURL(const std::string& mount_point_name, 96 const base::FilePath& file_path) { 97 const std::string origin = std::string("chrome-extension://") + kExtensionId; 98 const fileapi::ExternalMountPoints* const mount_points = 99 fileapi::ExternalMountPoints::GetSystemInstance(); 100 return mount_points->CreateCrackedFileSystemURL( 101 GURL(origin), 102 fileapi::kFileSystemTypeExternal, 103 base::FilePath::FromUTF8Unsafe(mount_point_name).Append(file_path)); 104} 105 106// Creates a Service instance. Used to be able to destroy the service in 107// TearDown(). 108KeyedService* CreateService(content::BrowserContext* context) { 109 return new Service(Profile::FromBrowserContext(context), 110 extensions::ExtensionRegistry::Get(context)); 111} 112 113} // namespace 114 115// Tests in this file are very lightweight and just test integration between 116// AsyncFileUtil and ProvideFileSystemInterface. Currently it tests if not 117// implemented operations return a correct error code. For not allowed 118// operations it is FILE_ERROR_SECURITY, and for not implemented the error is 119// FILE_ERROR_NOT_FOUND. 120class FileSystemProviderProviderAsyncFileUtilTest : public testing::Test { 121 protected: 122 FileSystemProviderProviderAsyncFileUtilTest() {} 123 virtual ~FileSystemProviderProviderAsyncFileUtilTest() {} 124 125 virtual void SetUp() OVERRIDE { 126 ASSERT_TRUE(data_dir_.CreateUniqueTempDir()); 127 profile_manager_.reset( 128 new TestingProfileManager(TestingBrowserProcess::GetGlobal())); 129 ASSERT_TRUE(profile_manager_->SetUp()); 130 profile_ = profile_manager_->CreateTestingProfile("testing-profile"); 131 async_file_util_.reset(new internal::ProviderAsyncFileUtil); 132 133 file_system_context_ = 134 content::CreateFileSystemContextForTesting(NULL, data_dir_.path()); 135 136 ServiceFactory::GetInstance()->SetTestingFactory(profile_, &CreateService); 137 Service* service = Service::Get(profile_); // Owned by its factory. 138 service->SetFileSystemFactoryForTests( 139 base::Bind(&FakeProvidedFileSystem::Create)); 140 141 const int file_system_id = 142 service->MountFileSystem(kExtensionId, "testing-file-system"); 143 ASSERT_LT(0, file_system_id); 144 const ProvidedFileSystemInfo& file_system_info = 145 service->GetProvidedFileSystem(kExtensionId, file_system_id) 146 ->GetFileSystemInfo(); 147 const std::string mount_point_name = 148 file_system_info.mount_path().BaseName().AsUTF8Unsafe(); 149 150 file_url_ = CreateFileSystemURL( 151 mount_point_name, base::FilePath::FromUTF8Unsafe("hello/world.txt")); 152 ASSERT_TRUE(file_url_.is_valid()); 153 directory_url_ = CreateFileSystemURL( 154 mount_point_name, base::FilePath::FromUTF8Unsafe("hello")); 155 ASSERT_TRUE(directory_url_.is_valid()); 156 root_url_ = CreateFileSystemURL(mount_point_name, base::FilePath()); 157 ASSERT_TRUE(root_url_.is_valid()); 158 } 159 160 virtual void TearDown() OVERRIDE { 161 // Setting the testing factory to NULL will destroy the created service 162 // associated with the testing profile. 163 ServiceFactory::GetInstance()->SetTestingFactory(profile_, NULL); 164 } 165 166 scoped_ptr<fileapi::FileSystemOperationContext> CreateOperationContext() { 167 return make_scoped_ptr( 168 new fileapi::FileSystemOperationContext(file_system_context_.get())); 169 } 170 171 content::TestBrowserThreadBundle thread_bundle_; 172 base::ScopedTempDir data_dir_; 173 scoped_ptr<TestingProfileManager> profile_manager_; 174 TestingProfile* profile_; // Owned by TestingProfileManager. 175 scoped_ptr<fileapi::AsyncFileUtil> async_file_util_; 176 scoped_refptr<fileapi::FileSystemContext> file_system_context_; 177 fileapi::FileSystemURL file_url_; 178 fileapi::FileSystemURL directory_url_; 179 fileapi::FileSystemURL root_url_; 180}; 181 182TEST_F(FileSystemProviderProviderAsyncFileUtilTest, CreateOrOpen_Create) { 183 EventLogger logger; 184 185 async_file_util_->CreateOrOpen( 186 CreateOperationContext(), 187 file_url_, 188 base::PLATFORM_FILE_CREATE, 189 base::Bind(&EventLogger::OnCreateOrOpen, logger.GetWeakPtr())); 190 191 ASSERT_TRUE(logger.error()); 192 EXPECT_EQ(base::File::FILE_ERROR_SECURITY, *logger.error()); 193} 194 195TEST_F(FileSystemProviderProviderAsyncFileUtilTest, CreateOrOpen_CreateAlways) { 196 EventLogger logger; 197 198 async_file_util_->CreateOrOpen( 199 CreateOperationContext(), 200 file_url_, 201 base::PLATFORM_FILE_CREATE_ALWAYS, 202 base::Bind(&EventLogger::OnCreateOrOpen, logger.GetWeakPtr())); 203 204 ASSERT_TRUE(logger.error()); 205 EXPECT_EQ(base::File::FILE_ERROR_SECURITY, *logger.error()); 206} 207 208TEST_F(FileSystemProviderProviderAsyncFileUtilTest, CreateOrOpen_OpenAlways) { 209 EventLogger logger; 210 211 async_file_util_->CreateOrOpen( 212 CreateOperationContext(), 213 file_url_, 214 base::PLATFORM_FILE_OPEN_ALWAYS, 215 base::Bind(&EventLogger::OnCreateOrOpen, logger.GetWeakPtr())); 216 217 ASSERT_TRUE(logger.error()); 218 EXPECT_EQ(base::File::FILE_ERROR_SECURITY, *logger.error()); 219} 220 221TEST_F(FileSystemProviderProviderAsyncFileUtilTest, 222 CreateOrOpen_OpenTruncated) { 223 EventLogger logger; 224 225 async_file_util_->CreateOrOpen( 226 CreateOperationContext(), 227 file_url_, 228 base::PLATFORM_FILE_OPEN_TRUNCATED, 229 base::Bind(&EventLogger::OnCreateOrOpen, logger.GetWeakPtr())); 230 231 ASSERT_TRUE(logger.error()); 232 EXPECT_EQ(base::File::FILE_ERROR_SECURITY, *logger.error()); 233} 234 235TEST_F(FileSystemProviderProviderAsyncFileUtilTest, CreateOrOpen_Open) { 236 EventLogger logger; 237 238 async_file_util_->CreateOrOpen( 239 CreateOperationContext(), 240 file_url_, 241 base::PLATFORM_FILE_OPEN, 242 base::Bind(&EventLogger::OnCreateOrOpen, logger.GetWeakPtr())); 243 244 ASSERT_TRUE(logger.error()); 245 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, *logger.error()); 246} 247 248TEST_F(FileSystemProviderProviderAsyncFileUtilTest, EnsureFileExists) { 249 EventLogger logger; 250 251 async_file_util_->EnsureFileExists( 252 CreateOperationContext(), 253 file_url_, 254 base::Bind(&EventLogger::OnEnsureFileExists, logger.GetWeakPtr())); 255 256 ASSERT_TRUE(logger.error()); 257 EXPECT_EQ(base::File::FILE_ERROR_SECURITY, *logger.error()); 258} 259 260TEST_F(FileSystemProviderProviderAsyncFileUtilTest, CreateDirectory) { 261 EventLogger logger; 262 263 async_file_util_->CreateDirectory( 264 CreateOperationContext(), 265 directory_url_, 266 false, // exclusive 267 false, // recursive 268 base::Bind(&EventLogger::OnStatus, logger.GetWeakPtr())); 269 270 ASSERT_TRUE(logger.error()); 271 EXPECT_EQ(base::File::FILE_ERROR_SECURITY, *logger.error()); 272} 273 274TEST_F(FileSystemProviderProviderAsyncFileUtilTest, GetFileInfo) { 275 EventLogger logger; 276 277 async_file_util_->GetFileInfo( 278 CreateOperationContext(), 279 root_url_, 280 base::Bind(&EventLogger::OnGetFileInfo, logger.GetWeakPtr())); 281 base::RunLoop().RunUntilIdle(); 282 283 ASSERT_TRUE(logger.error()); 284 EXPECT_EQ(base::File::FILE_OK, *logger.error()); 285} 286 287TEST_F(FileSystemProviderProviderAsyncFileUtilTest, ReadDirectory) { 288 EventLogger logger; 289 290 async_file_util_->ReadDirectory( 291 CreateOperationContext(), 292 root_url_, 293 base::Bind(&EventLogger::OnReadDirectory, logger.GetWeakPtr())); 294 base::RunLoop().RunUntilIdle(); 295 296 ASSERT_TRUE(logger.error()); 297 EXPECT_EQ(base::File::FILE_OK, *logger.error()); 298} 299 300TEST_F(FileSystemProviderProviderAsyncFileUtilTest, Touch) { 301 EventLogger logger; 302 303 async_file_util_->CreateDirectory( 304 CreateOperationContext(), 305 file_url_, 306 false, // exclusive 307 false, // recursive 308 base::Bind(&EventLogger::OnStatus, logger.GetWeakPtr())); 309 310 ASSERT_TRUE(logger.error()); 311 EXPECT_EQ(base::File::FILE_ERROR_SECURITY, *logger.error()); 312} 313 314TEST_F(FileSystemProviderProviderAsyncFileUtilTest, Truncate) { 315 EventLogger logger; 316 317 async_file_util_->Truncate( 318 CreateOperationContext(), 319 file_url_, 320 0, // length 321 base::Bind(&EventLogger::OnStatus, logger.GetWeakPtr())); 322 323 ASSERT_TRUE(logger.error()); 324 EXPECT_EQ(base::File::FILE_ERROR_SECURITY, *logger.error()); 325} 326 327TEST_F(FileSystemProviderProviderAsyncFileUtilTest, CopyFileLocal) { 328 EventLogger logger; 329 330 async_file_util_->CopyFileLocal( 331 CreateOperationContext(), 332 file_url_, // src_url 333 file_url_, // dst_url 334 fileapi::FileSystemOperation::OPTION_NONE, 335 base::Bind(&EventLogger::OnCopyFileProgress, logger.GetWeakPtr()), 336 base::Bind(&EventLogger::OnStatus, logger.GetWeakPtr())); 337 338 ASSERT_TRUE(logger.error()); 339 EXPECT_EQ(base::File::FILE_ERROR_SECURITY, *logger.error()); 340} 341 342TEST_F(FileSystemProviderProviderAsyncFileUtilTest, MoveFileLocal) { 343 EventLogger logger; 344 345 async_file_util_->MoveFileLocal( 346 CreateOperationContext(), 347 file_url_, // src_url 348 file_url_, // dst_url 349 fileapi::FileSystemOperation::OPTION_NONE, 350 base::Bind(&EventLogger::OnStatus, logger.GetWeakPtr())); 351 352 ASSERT_TRUE(logger.error()); 353 EXPECT_EQ(base::File::FILE_ERROR_SECURITY, *logger.error()); 354} 355 356TEST_F(FileSystemProviderProviderAsyncFileUtilTest, CopyInForeignFile) { 357 EventLogger logger; 358 359 async_file_util_->CopyInForeignFile( 360 CreateOperationContext(), 361 base::FilePath(), // src_file_path 362 file_url_, // dst_url 363 base::Bind(&EventLogger::OnStatus, logger.GetWeakPtr())); 364 365 ASSERT_TRUE(logger.error()); 366 EXPECT_EQ(base::File::FILE_ERROR_SECURITY, *logger.error()); 367} 368 369TEST_F(FileSystemProviderProviderAsyncFileUtilTest, DeleteFile) { 370 EventLogger logger; 371 372 async_file_util_->DeleteFile( 373 CreateOperationContext(), 374 file_url_, 375 base::Bind(&EventLogger::OnStatus, logger.GetWeakPtr())); 376 377 ASSERT_TRUE(logger.error()); 378 EXPECT_EQ(base::File::FILE_ERROR_SECURITY, *logger.error()); 379} 380 381TEST_F(FileSystemProviderProviderAsyncFileUtilTest, DeleteDirectory) { 382 EventLogger logger; 383 384 async_file_util_->DeleteDirectory( 385 CreateOperationContext(), 386 directory_url_, 387 base::Bind(&EventLogger::OnStatus, logger.GetWeakPtr())); 388 389 ASSERT_TRUE(logger.error()); 390 EXPECT_EQ(base::File::FILE_ERROR_SECURITY, *logger.error()); 391} 392 393TEST_F(FileSystemProviderProviderAsyncFileUtilTest, DeleteRecursively) { 394 EventLogger logger; 395 396 async_file_util_->DeleteRecursively( 397 CreateOperationContext(), 398 directory_url_, 399 base::Bind(&EventLogger::OnStatus, logger.GetWeakPtr())); 400 401 ASSERT_TRUE(logger.error()); 402 EXPECT_EQ(base::File::FILE_ERROR_SECURITY, *logger.error()); 403} 404 405TEST_F(FileSystemProviderProviderAsyncFileUtilTest, CreateSnapshotFile) { 406 EventLogger logger; 407 408 async_file_util_->CreateSnapshotFile( 409 CreateOperationContext(), 410 file_url_, 411 base::Bind(&EventLogger::OnCreateSnapshotFile, logger.GetWeakPtr())); 412 413 ASSERT_TRUE(logger.error()); 414 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, *logger.error()); 415} 416 417} // namespace file_system_provider 418} // namespace chromeos 419