1 // Copyright 2015 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/file_system_provider/scoped_file_opener.h"
6
7 #include <memory>
8 #include <vector>
9
10 #include "base/bind.h"
11 #include "base/files/file.h"
12 #include "base/run_loop.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "base/threading/thread_task_runner_handle.h"
15 #include "chrome/browser/chromeos/file_system_provider/fake_provided_file_system.h"
16 #include "chrome/browser/chromeos/file_system_provider/provided_file_system_info.h"
17 #include "content/public/test/browser_task_environment.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19
20 namespace chromeos {
21 namespace file_system_provider {
22 namespace {
23
24 class TestingProvidedFileSystem : public FakeProvidedFileSystem {
25 public:
TestingProvidedFileSystem()26 TestingProvidedFileSystem()
27 : FakeProvidedFileSystem(ProvidedFileSystemInfo()) {}
28
~TestingProvidedFileSystem()29 ~TestingProvidedFileSystem() override {}
30
OpenFile(const base::FilePath & file_path,OpenFileMode mode,OpenFileCallback callback)31 AbortCallback OpenFile(const base::FilePath& file_path,
32 OpenFileMode mode,
33 OpenFileCallback callback) override {
34 open_callback_ = std::move(callback);
35 return base::BindOnce(&TestingProvidedFileSystem::AbortOpen,
36 base::Unretained(this));
37 }
38
CloseFile(int file_handle,storage::AsyncFileUtil::StatusCallback callback)39 AbortCallback CloseFile(
40 int file_handle,
41 storage::AsyncFileUtil::StatusCallback callback) override {
42 close_requests_.push_back(file_handle);
43 std::move(callback).Run(base::File::FILE_OK);
44 return AbortCallback();
45 }
46
has_open_callback() const47 bool has_open_callback() const { return !!open_callback_; }
open_callback()48 OpenFileCallback open_callback() {
49 return base::BindOnce(&TestingProvidedFileSystem::CompleteOpen,
50 base::Unretained(this));
51 }
close_requests() const52 const std::vector<int> close_requests() const { return close_requests_; }
53
54 private:
55 OpenFileCallback open_callback_;
56 std::vector<int> close_requests_;
57
CompleteOpen(int file_handle,base::File::Error result)58 void CompleteOpen(int file_handle, base::File::Error result) {
59 std::move(open_callback_).Run(file_handle, result);
60 }
61
AbortOpen()62 void AbortOpen() {
63 std::move(open_callback_).Run(0, base::File::FILE_ERROR_ABORT);
64 }
65 };
66
67 typedef std::vector<std::pair<int, base::File::Error>> OpenLog;
68
LogOpen(OpenLog * log,int file_handle,base::File::Error result)69 void LogOpen(OpenLog* log, int file_handle, base::File::Error result) {
70 log->push_back(std::make_pair(file_handle, result));
71 }
72
73 } // namespace
74
TEST(ScopedFileOpenerTest,AbortWhileOpening)75 TEST(ScopedFileOpenerTest, AbortWhileOpening) {
76 TestingProvidedFileSystem file_system;
77 content::BrowserTaskEnvironment task_environment;
78 OpenLog log;
79 {
80 ScopedFileOpener file_opener(&file_system, base::FilePath(),
81 OPEN_FILE_MODE_READ,
82 base::BindOnce(&LogOpen, &log));
83 base::RunLoop().RunUntilIdle();
84 EXPECT_TRUE(file_system.has_open_callback());
85 }
86 ASSERT_EQ(1u, log.size());
87 EXPECT_EQ(0, log[0].first);
88 EXPECT_EQ(base::File::FILE_ERROR_ABORT, log[0].second);
89
90 base::RunLoop().RunUntilIdle();
91 EXPECT_EQ(0u, file_system.close_requests().size());
92 }
93
TEST(ScopedFileOpenerTest,CloseAfterOpening)94 TEST(ScopedFileOpenerTest, CloseAfterOpening) {
95 TestingProvidedFileSystem file_system;
96 content::BrowserTaskEnvironment task_environment;
97 OpenLog log;
98 {
99 ScopedFileOpener file_opener(&file_system, base::FilePath(),
100 OPEN_FILE_MODE_READ,
101 base::BindOnce(&LogOpen, &log));
102 base::RunLoop().RunUntilIdle();
103 ASSERT_TRUE(file_system.has_open_callback());
104 file_system.open_callback().Run(123, base::File::FILE_OK);
105 }
106
107 ASSERT_EQ(1u, log.size());
108 EXPECT_EQ(123, log[0].first);
109 EXPECT_EQ(base::File::FILE_OK, log[0].second);
110
111 ASSERT_EQ(1u, file_system.close_requests().size());
112 EXPECT_EQ(123, file_system.close_requests()[0]);
113 }
114
TEST(ScopedFileOpenerTest,CloseAfterAborting)115 TEST(ScopedFileOpenerTest, CloseAfterAborting) {
116 TestingProvidedFileSystem file_system;
117 content::BrowserTaskEnvironment task_environment;
118 OpenLog log;
119 {
120 ScopedFileOpener file_opener(&file_system, base::FilePath(),
121 OPEN_FILE_MODE_READ,
122 base::BindOnce(&LogOpen, &log));
123 base::RunLoop().RunUntilIdle();
124 ASSERT_TRUE(file_system.has_open_callback());
125 file_system.open_callback().Run(0, base::File::FILE_ERROR_ABORT);
126 }
127
128 ASSERT_EQ(1u, log.size());
129 EXPECT_EQ(0, log[0].first);
130 EXPECT_EQ(base::File::FILE_ERROR_ABORT, log[0].second);
131 EXPECT_EQ(0u, file_system.close_requests().size());
132 }
133
134 } // namespace file_system_provider
135 } // namespace chromeos
136