Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / sql / mojo / vfs_unittest.cc
blob123299bfe9b8a4f2a6ab37d664cd7d0da772c76a
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.
5 #include "components/filesystem/public/interfaces/file_system.mojom.h"
6 #include "mojo/application/public/cpp/application_impl.h"
7 #include "mojo/application/public/cpp/application_test_base.h"
8 #include "mojo/util/capture_util.h"
9 #include "sql/mojo/mojo_vfs.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "third_party/sqlite/sqlite3.h"
13 namespace base {
15 // This deleter lets us be safe with sqlite3 objects, which aren't really the
16 // structs, but slabs of new uint8_t[size].
17 template <>
18 struct DefaultDeleter<sqlite3_file> {
19 inline void operator()(sqlite3_file* ptr) const {
20 // Why don't we call file->pMethods->xClose() here? Because it's not
21 // guaranteed to be valid. sqlite3_file "objects" can be in partially
22 // initialized states.
23 delete [] reinterpret_cast<uint8_t*>(ptr);
27 } // namespace base
29 namespace sql {
31 const char kFileName[] = "TestingDatabase.db";
33 class VFSTest : public mojo::test::ApplicationTestBase,
34 public filesystem::FileSystemClient {
35 public:
36 VFSTest() : binding_(this) {}
37 ~VFSTest() override {}
39 sqlite3_vfs* vfs() {
40 return sqlite3_vfs_find(NULL);
43 scoped_ptr<sqlite3_file> MakeFile() {
44 return scoped_ptr<sqlite3_file>(reinterpret_cast<sqlite3_file*>(
45 new uint8_t[vfs()->szOsFile]));
48 void SetUp() override {
49 mojo::test::ApplicationTestBase::SetUp();
51 mojo::URLRequestPtr request(mojo::URLRequest::New());
52 request->url = mojo::String::From("mojo:filesystem");
53 application_impl()->ConnectToService(request.Pass(), &files_);
55 filesystem::FileSystemClientPtr client;
56 binding_.Bind(GetProxy(&client));
58 filesystem::FileError error = filesystem::FILE_ERROR_FAILED;
59 filesystem::DirectoryPtr directory;
60 files_->OpenFileSystem("temp", GetProxy(&directory), client.Pass(),
61 mojo::Capture(&error));
62 ASSERT_TRUE(files_.WaitForIncomingResponse());
63 ASSERT_EQ(filesystem::FILE_ERROR_OK, error);
65 vfs_.reset(new ScopedMojoFilesystemVFS(directory.Pass()));
68 void TearDown() override {
69 vfs_.reset();
70 mojo::test::ApplicationTestBase::TearDown();
73 void OnFileSystemShutdown() override {
76 private:
77 filesystem::FileSystemPtr files_;
78 scoped_ptr<ScopedMojoFilesystemVFS> vfs_;
79 mojo::Binding<filesystem::FileSystemClient> binding_;
81 DISALLOW_COPY_AND_ASSIGN(VFSTest);
84 TEST_F(VFSTest, TestInstalled) {
85 EXPECT_EQ("mojo", std::string(vfs()->zName));
88 TEST_F(VFSTest, ExclusiveOpen) {
89 // Opening a non-existent file exclusively should work.
90 scoped_ptr<sqlite3_file> file(MakeFile());
91 int out_flags;
92 int rc = vfs()->xOpen(vfs(), kFileName, file.get(),
93 SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_CREATE,
94 &out_flags);
95 EXPECT_EQ(SQLITE_OK, rc);
97 // Opening it a second time exclusively shouldn't.
98 scoped_ptr<sqlite3_file> file2(MakeFile());
99 rc = vfs()->xOpen(vfs(), kFileName, file2.get(),
100 SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_CREATE,
101 &out_flags);
102 EXPECT_NE(SQLITE_OK, rc);
104 file->pMethods->xClose(file.get());
107 TEST_F(VFSTest, NonexclusiveOpen) {
108 // Opening a non-existent file should work.
109 scoped_ptr<sqlite3_file> file(MakeFile());
110 int out_flags;
111 int rc = vfs()->xOpen(vfs(), kFileName, file.get(),
112 SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE,
113 &out_flags);
114 EXPECT_EQ(SQLITE_OK, rc);
116 // Opening it a second time should work.
117 scoped_ptr<sqlite3_file> file2(MakeFile());
118 rc = vfs()->xOpen(vfs(), kFileName, file2.get(),
119 SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE,
120 &out_flags);
121 EXPECT_EQ(SQLITE_OK, rc);
123 file->pMethods->xClose(file.get());
124 file->pMethods->xClose(file2.get());
127 TEST_F(VFSTest, NullFilenameOpen) {
128 // Opening a file with a null filename should return a valid file object.
129 scoped_ptr<sqlite3_file> file(MakeFile());
130 int out_flags;
131 int rc = vfs()->xOpen(
132 vfs(), nullptr, file.get(),
133 SQLITE_OPEN_DELETEONCLOSE | SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE,
134 &out_flags);
135 EXPECT_EQ(SQLITE_OK, rc);
137 file->pMethods->xClose(file.get());
140 TEST_F(VFSTest, DeleteOnClose) {
142 scoped_ptr<sqlite3_file> file(MakeFile());
143 int out_flags;
144 int rc = vfs()->xOpen(
145 vfs(), kFileName, file.get(),
146 SQLITE_OPEN_DELETEONCLOSE | SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE,
147 &out_flags);
148 EXPECT_EQ(SQLITE_OK, rc);
149 file->pMethods->xClose(file.get());
152 // The file shouldn't exist now.
153 int result = 0;
154 vfs()->xAccess(vfs(), kFileName, SQLITE_ACCESS_EXISTS, &result);
155 EXPECT_FALSE(result);
158 TEST_F(VFSTest, TestNonExistence) {
159 // We shouldn't have a file exist yet in a fresh directory.
160 int result = 0;
161 vfs()->xAccess(vfs(), kFileName, SQLITE_ACCESS_EXISTS, &result);
162 EXPECT_FALSE(result);
165 TEST_F(VFSTest, TestExistence) {
167 scoped_ptr<sqlite3_file> file(MakeFile());
168 int out_flags;
169 int rc = vfs()->xOpen(vfs(), kFileName, file.get(),
170 SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE,
171 &out_flags);
172 EXPECT_EQ(SQLITE_OK, rc);
174 file->pMethods->xClose(file.get());
177 int result = 0;
178 vfs()->xAccess(vfs(), kFileName, SQLITE_ACCESS_EXISTS, &result);
179 EXPECT_TRUE(result);
182 TEST_F(VFSTest, TestDelete) {
184 scoped_ptr<sqlite3_file> file(MakeFile());
185 int out_flags;
186 int rc = vfs()->xOpen(vfs(), kFileName, file.get(),
187 SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE,
188 &out_flags);
189 EXPECT_EQ(SQLITE_OK, rc);
191 file->pMethods->xClose(file.get());
194 int result = 0;
195 vfs()->xAccess(vfs(), kFileName, SQLITE_ACCESS_EXISTS, &result);
196 EXPECT_TRUE(result);
198 vfs()->xDelete(vfs(), kFileName, 0);
200 vfs()->xAccess(vfs(), kFileName, SQLITE_ACCESS_EXISTS, &result);
201 EXPECT_FALSE(result);
204 TEST_F(VFSTest, TestWriteAndRead) {
205 const char kBuffer[] = "One Two Three Four Five Six Seven";
206 const int kBufferSize = arraysize(kBuffer);
209 scoped_ptr<sqlite3_file> file(MakeFile());
210 int out_flags;
211 int rc = vfs()->xOpen(vfs(), kFileName, file.get(),
212 SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE,
213 &out_flags);
214 EXPECT_EQ(SQLITE_OK, rc);
216 for (int i = 0; i < 10; ++i) {
217 rc = file->pMethods->xWrite(file.get(), kBuffer, kBufferSize,
218 i * kBufferSize);
219 EXPECT_EQ(SQLITE_OK, rc);
222 file->pMethods->xClose(file.get());
225 // Expect that the size of the file is 10 * arraysize(kBuffer);
227 scoped_ptr<sqlite3_file> file(MakeFile());
228 int out_flags;
229 int rc = vfs()->xOpen(vfs(), kFileName, file.get(),
230 SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE,
231 &out_flags);
232 EXPECT_EQ(SQLITE_OK, rc);
234 sqlite_int64 size;
235 rc = file->pMethods->xFileSize(file.get(), &size);
236 EXPECT_EQ(SQLITE_OK, rc);
237 EXPECT_EQ(10 * kBufferSize, size);
239 file->pMethods->xClose(file.get());
242 // We should be able to read things back.
244 scoped_ptr<sqlite3_file> file(MakeFile());
245 int out_flags;
246 int rc = vfs()->xOpen(vfs(), kFileName, file.get(),
247 SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE,
248 &out_flags);
249 EXPECT_EQ(SQLITE_OK, rc);
251 char data_buffer[kBufferSize];
252 memset(data_buffer, '8', kBufferSize);
253 for (int i = 0; i < 10; ++i) {
254 rc = file->pMethods->xRead(file.get(), data_buffer, kBufferSize,
255 i * kBufferSize);
256 EXPECT_EQ(SQLITE_OK, rc);
257 EXPECT_TRUE(strncmp(kBuffer, &data_buffer[0], kBufferSize) == 0);
260 file->pMethods->xClose(file.get());
264 TEST_F(VFSTest, PartialRead) {
265 const char kBuffer[] = "One Two Three Four Five Six Seven";
266 const int kBufferSize = arraysize(kBuffer);
268 // Write the data once.
270 scoped_ptr<sqlite3_file> file(MakeFile());
271 int out_flags;
272 int rc = vfs()->xOpen(vfs(), kFileName, file.get(),
273 SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE,
274 &out_flags);
275 EXPECT_EQ(SQLITE_OK, rc);
277 rc = file->pMethods->xWrite(file.get(), kBuffer, kBufferSize, 0);
278 EXPECT_EQ(SQLITE_OK, rc);
280 file->pMethods->xClose(file.get());
283 // Now attempt to read kBufferSize + 5 from a file sized to kBufferSize.
285 scoped_ptr<sqlite3_file> file(MakeFile());
286 int out_flags;
287 int rc = vfs()->xOpen(vfs(), kFileName, file.get(),
288 SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE,
289 &out_flags);
290 EXPECT_EQ(SQLITE_OK, rc);
292 const char kBufferWithFiveNulls[] =
293 "One Two Three Four Five Six Seven\0\0\0\0\0";
294 const int kBufferWithFiveNullsSize = arraysize(kBufferWithFiveNulls);
296 char data_buffer[kBufferWithFiveNullsSize];
297 memset(data_buffer, '8', kBufferWithFiveNullsSize);
298 rc = file->pMethods->xRead(file.get(), data_buffer,
299 kBufferWithFiveNullsSize, 0);
300 EXPECT_EQ(SQLITE_IOERR_SHORT_READ, rc);
302 EXPECT_TRUE(strncmp(kBufferWithFiveNulls, &data_buffer[0],
303 kBufferWithFiveNullsSize) == 0);
305 file->pMethods->xClose(file.get());
309 TEST_F(VFSTest, Truncate) {
310 const char kBuffer[] = "One Two Three Four Five Six Seven";
311 const int kBufferSize = arraysize(kBuffer);
312 const int kCharsToThree = 13;
314 scoped_ptr<sqlite3_file> file(MakeFile());
315 int out_flags;
316 int rc = vfs()->xOpen(vfs(), kFileName, file.get(),
317 SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE,
318 &out_flags);
319 EXPECT_EQ(SQLITE_OK, rc);
321 rc = file->pMethods->xWrite(file.get(), kBuffer, kBufferSize, 0);
322 EXPECT_EQ(SQLITE_OK, rc);
324 sqlite_int64 size;
325 rc = file->pMethods->xFileSize(file.get(), &size);
326 EXPECT_EQ(SQLITE_OK, rc);
327 EXPECT_EQ(kBufferSize, size);
329 rc = file->pMethods->xTruncate(file.get(), kCharsToThree);
330 EXPECT_EQ(SQLITE_OK, rc);
332 rc = file->pMethods->xFileSize(file.get(), &size);
333 EXPECT_EQ(SQLITE_OK, rc);
334 EXPECT_EQ(kCharsToThree, size);
336 file->pMethods->xClose(file.get());
339 } // namespace sql