Index: chrome/browser/chromeos/file_system_provider/throttled_file_system_unittest.cc |
diff --git a/chrome/browser/chromeos/file_system_provider/throttled_file_system_unittest.cc b/chrome/browser/chromeos/file_system_provider/throttled_file_system_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..503c8b213ec56669454f15ac8230ad6279bdaa13 |
--- /dev/null |
+++ b/chrome/browser/chromeos/file_system_provider/throttled_file_system_unittest.cc |
@@ -0,0 +1,177 @@ |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "chrome/browser/chromeos/file_system_provider/throttled_file_system.h" |
+ |
+#include <vector> |
+ |
+#include "base/files/file.h" |
+#include "base/memory/scoped_ptr.h" |
+#include "base/memory/scoped_vector.h" |
+#include "base/run_loop.h" |
+#include "chrome/browser/chromeos/file_system_provider/abort_callback.h" |
+#include "chrome/browser/chromeos/file_system_provider/fake_provided_file_system.h" |
+#include "chrome/browser/chromeos/file_system_provider/provided_file_system_info.h" |
+#include "content/public/test/test_browser_thread_bundle.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace chromeos { |
+namespace file_system_provider { |
+namespace { |
+ |
+const char kExtensionId[] = "mbflcebpggnecokmikipoihdbecnjfoj"; |
+const char kFileSystemId[] = "camera-pictures"; |
+const char kDisplayName[] = "Camera Pictures"; |
+ |
+typedef std::vector<base::File::Error> StatusLog; |
+typedef std::vector<std::pair<int, base::File::Error>> OpenLog; |
+ |
+// Writes a |result| to the |log| vector for a status callback. |
+void LogStatus(StatusLog* log, base::File::Error result) { |
+ log->push_back(result); |
+} |
+ |
+// Writes a |result| to the |log| vector for opening a file. |
+void LogOpen(OpenLog* log, int handle, base::File::Error result) { |
+ log->push_back(std::make_pair(handle, result)); |
+} |
+ |
+} // namespace |
+ |
+class FileSystemProviderThrottledFileSystemTest : public testing::Test { |
+ protected: |
+ FileSystemProviderThrottledFileSystemTest() {} |
+ virtual ~FileSystemProviderThrottledFileSystemTest() {} |
+ |
+ virtual void SetUp() override {} |
+ |
+ // Initializes the throttled file system with |limit| number of opened files |
+ // at once. If 0, then no limit. |
+ void SetUpFileSystem(size_t limit) { |
+ MountOptions options(kFileSystemId, kDisplayName); |
+ if (limit) |
+ options.opened_files_limit = limit; |
+ |
+ ProvidedFileSystemInfo file_system_info(kExtensionId, options, |
+ base::FilePath() /* mount_path */); |
+ |
+ file_system_.reset(new ThrottledFileSystem( |
+ make_scoped_ptr(new FakeProvidedFileSystem(file_system_info)))); |
+ } |
+ |
+ content::TestBrowserThreadBundle thread_bundle_; |
+ scoped_ptr<ThrottledFileSystem> file_system_; |
+}; |
+ |
+TEST_F(FileSystemProviderThrottledFileSystemTest, OpenFile_LimitedToOneAtOnce) { |
+ SetUpFileSystem(1); |
+ |
+ OpenLog first_open_log; |
+ file_system_->OpenFile(base::FilePath(kFakeFilePath), |
+ ThrottledFileSystem::OPEN_FILE_MODE_READ, |
+ base::Bind(&LogOpen, &first_open_log)); |
+ |
+ OpenLog second_open_log; |
+ file_system_->OpenFile(base::FilePath(kFakeFilePath), |
+ ThrottledFileSystem::OPEN_FILE_MODE_READ, |
+ base::Bind(&LogOpen, &second_open_log)); |
+ |
+ base::RunLoop().RunUntilIdle(); |
+ |
+ ASSERT_EQ(1u, first_open_log.size()); |
+ EXPECT_EQ(base::File::FILE_OK, first_open_log[0].second); |
+ EXPECT_EQ(0u, second_open_log.size()); |
+ |
+ // Close the first file. |
+ StatusLog close_log; |
+ file_system_->CloseFile(first_open_log[0].first, |
+ base::Bind(&LogStatus, &close_log)); |
+ |
+ base::RunLoop().RunUntilIdle(); |
+ ASSERT_EQ(1u, close_log.size()); |
+ EXPECT_EQ(base::File::FILE_OK, close_log[0]); |
+ |
+ // The second enqueued file should be opened. |
+ ASSERT_EQ(1u, first_open_log.size()); |
+ EXPECT_EQ(base::File::FILE_OK, first_open_log[0].second); |
+ ASSERT_EQ(1u, second_open_log.size()); |
+ EXPECT_EQ(base::File::FILE_OK, second_open_log[0].second); |
+} |
+ |
+TEST_F(FileSystemProviderThrottledFileSystemTest, OpenFile_NoLimit) { |
+ SetUpFileSystem(0); // No limit. |
+ |
+ OpenLog first_open_log; |
+ file_system_->OpenFile(base::FilePath(kFakeFilePath), |
+ ThrottledFileSystem::OPEN_FILE_MODE_READ, |
+ base::Bind(&LogOpen, &first_open_log)); |
+ |
+ OpenLog second_open_log; |
+ file_system_->OpenFile(base::FilePath(kFakeFilePath), |
+ ThrottledFileSystem::OPEN_FILE_MODE_READ, |
+ base::Bind(&LogOpen, &second_open_log)); |
+ |
+ base::RunLoop().RunUntilIdle(); |
+ |
+ ASSERT_EQ(1u, first_open_log.size()); |
+ EXPECT_EQ(base::File::FILE_OK, first_open_log[0].second); |
+ ASSERT_EQ(1u, second_open_log.size()); |
+ EXPECT_EQ(base::File::FILE_OK, second_open_log[0].second); |
+ |
+ // Close files. |
+ StatusLog first_close_log; |
+ file_system_->CloseFile(first_open_log[0].first, |
+ base::Bind(&LogStatus, &first_close_log)); |
+ |
+ StatusLog second_close_log; |
+ file_system_->CloseFile(second_open_log[0].first, |
+ base::Bind(&LogStatus, &second_close_log)); |
+ |
+ base::RunLoop().RunUntilIdle(); |
+ ASSERT_EQ(1u, first_close_log.size()); |
+ EXPECT_EQ(base::File::FILE_OK, first_close_log[0]); |
+ ASSERT_EQ(1u, second_close_log.size()); |
+ EXPECT_EQ(base::File::FILE_OK, second_close_log[0]); |
+ |
+ // Confirm, that files are not opened again. |
+ EXPECT_EQ(1u, first_open_log.size()); |
+ EXPECT_EQ(1u, second_open_log.size()); |
+} |
+ |
+TEST_F(FileSystemProviderThrottledFileSystemTest, AbortAfterRun) { |
+ SetUpFileSystem(1); |
+ |
+ OpenLog first_open_log; |
+ AbortCallback abort_callback = file_system_->OpenFile( |
+ base::FilePath(kFakeFilePath), ThrottledFileSystem::OPEN_FILE_MODE_READ, |
+ base::Bind(&LogOpen, &first_open_log)); |
+ |
+ OpenLog second_open_log; |
+ file_system_->OpenFile(base::FilePath(kFakeFilePath), |
+ ThrottledFileSystem::OPEN_FILE_MODE_READ, |
+ base::Bind(&LogOpen, &second_open_log)); |
+ |
+ base::RunLoop().RunUntilIdle(); |
+ |
+ ASSERT_EQ(1u, first_open_log.size()); |
+ EXPECT_EQ(base::File::FILE_OK, first_open_log[0].second); |
+ EXPECT_EQ(0u, second_open_log.size()); |
+ |
+ // The first file is opened, so the opening operation has completed, then |
+ // aborting it should result in an error. This is tested, as from the queue |
+ // point of view, the opening task stays in the queue until closing the file. |
+ StatusLog abort_log; |
+ abort_callback.Run(base::Bind(&LogStatus, &abort_log)); |
+ base::RunLoop().RunUntilIdle(); |
+ |
+ ASSERT_EQ(1u, abort_log.size()); |
+ EXPECT_EQ(base::File::FILE_ERROR_INVALID_OPERATION, abort_log[0]); |
+ |
+ // Confirm, that the second task is not executed after a invalid abort of the |
+ // first one. |
+ EXPECT_EQ(1u, first_open_log.size()); |
+ EXPECT_EQ(0u, second_open_log.size()); |
+} |
+} // namespace file_system_provider |
+} // namespace chromeos |