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.
8 #include "components/filesystem/files_test_base.h"
10 namespace filesystem
{
13 using DirectoryImplTest
= FilesTestBase
;
15 TEST_F(DirectoryImplTest
, Read
) {
16 DirectoryPtr directory
;
17 GetTemporaryRoot(&directory
);
24 } files_to_create
[] = {
25 {"my_file1", kOpenFlagRead
| kOpenFlagWrite
| kOpenFlagCreate
},
26 {"my_file2", kOpenFlagWrite
| kOpenFlagCreate
| kOpenFlagExclusive
},
27 {"my_file3", kOpenFlagWrite
| kOpenFlagCreate
| kOpenFlagAppend
},
28 {"my_file4", kOpenFlagWrite
| kOpenFlagCreate
| kOpenFlagTruncate
}};
29 for (size_t i
= 0; i
< arraysize(files_to_create
); i
++) {
30 error
= ERROR_INTERNAL
;
31 directory
->OpenFile(files_to_create
[i
].name
, nullptr,
32 files_to_create
[i
].open_flags
, Capture(&error
));
33 ASSERT_TRUE(directory
.WaitForIncomingResponse());
34 EXPECT_EQ(ERROR_OK
, error
);
37 error
= ERROR_INTERNAL
;
38 directory
->OpenDirectory("my_dir", nullptr,
39 kOpenFlagRead
| kOpenFlagWrite
| kOpenFlagCreate
,
41 ASSERT_TRUE(directory
.WaitForIncomingResponse());
42 EXPECT_EQ(ERROR_OK
, error
);
44 error
= ERROR_INTERNAL
;
45 mojo::Array
<DirectoryEntryPtr
> directory_contents
;
46 directory
->Read(Capture(&error
, &directory_contents
));
47 ASSERT_TRUE(directory
.WaitForIncomingResponse());
48 EXPECT_EQ(ERROR_OK
, error
);
50 // Expected contents of the directory.
51 std::map
<std::string
, FileType
> expected_contents
;
52 expected_contents
["my_file1"] = FILE_TYPE_REGULAR_FILE
;
53 expected_contents
["my_file2"] = FILE_TYPE_REGULAR_FILE
;
54 expected_contents
["my_file3"] = FILE_TYPE_REGULAR_FILE
;
55 expected_contents
["my_file4"] = FILE_TYPE_REGULAR_FILE
;
56 expected_contents
["my_dir"] = FILE_TYPE_DIRECTORY
;
57 expected_contents
["."] = FILE_TYPE_DIRECTORY
;
58 expected_contents
[".."] = FILE_TYPE_DIRECTORY
;
60 EXPECT_EQ(expected_contents
.size(), directory_contents
.size());
61 for (size_t i
= 0; i
< directory_contents
.size(); i
++) {
62 ASSERT_TRUE(directory_contents
[i
]);
63 ASSERT_TRUE(directory_contents
[i
]->name
);
64 auto it
= expected_contents
.find(directory_contents
[i
]->name
.get());
65 ASSERT_TRUE(it
!= expected_contents
.end());
66 EXPECT_EQ(it
->second
, directory_contents
[i
]->type
);
67 expected_contents
.erase(it
);
71 // Note: Ignore nanoseconds, since it may not always be supported. We expect at
72 // least second-resolution support though.
73 // TODO(vtl): Maybe share this with |FileImplTest.StatTouch| ... but then it'd
74 // be harder to split this file.
75 TEST_F(DirectoryImplTest
, StatTouch
) {
76 DirectoryPtr directory
;
77 GetTemporaryRoot(&directory
);
81 error
= ERROR_INTERNAL
;
82 FileInformationPtr file_info
;
83 directory
->Stat(Capture(&error
, &file_info
));
84 ASSERT_TRUE(directory
.WaitForIncomingResponse());
85 EXPECT_EQ(ERROR_OK
, error
);
86 ASSERT_FALSE(file_info
.is_null());
87 EXPECT_EQ(FILE_TYPE_DIRECTORY
, file_info
->type
);
88 EXPECT_EQ(0, file_info
->size
);
89 ASSERT_FALSE(file_info
->atime
.is_null());
90 EXPECT_GT(file_info
->atime
->seconds
, 0); // Expect that it's not 1970-01-01.
91 ASSERT_FALSE(file_info
->mtime
.is_null());
92 EXPECT_GT(file_info
->mtime
->seconds
, 0);
93 int64_t first_mtime
= file_info
->mtime
->seconds
;
95 // Touch only the atime.
96 error
= ERROR_INTERNAL
;
97 TimespecOrNowPtr
t(TimespecOrNow::New());
99 t
->timespec
= Timespec::New();
100 const int64_t kPartyTime1
= 1234567890; // Party like it's 2009-02-13.
101 t
->timespec
->seconds
= kPartyTime1
;
102 directory
->Touch(t
.Pass(), nullptr, Capture(&error
));
103 ASSERT_TRUE(directory
.WaitForIncomingResponse());
104 EXPECT_EQ(ERROR_OK
, error
);
107 error
= ERROR_INTERNAL
;
109 directory
->Stat(Capture(&error
, &file_info
));
110 ASSERT_TRUE(directory
.WaitForIncomingResponse());
111 EXPECT_EQ(ERROR_OK
, error
);
112 ASSERT_FALSE(file_info
.is_null());
113 ASSERT_FALSE(file_info
->atime
.is_null());
114 EXPECT_EQ(kPartyTime1
, file_info
->atime
->seconds
);
115 ASSERT_FALSE(file_info
->mtime
.is_null());
116 EXPECT_EQ(first_mtime
, file_info
->mtime
->seconds
);
118 // Touch only the mtime.
119 t
= TimespecOrNow::New();
121 t
->timespec
= Timespec::New();
122 const int64_t kPartyTime2
= 1425059525; // No time like the present.
123 t
->timespec
->seconds
= kPartyTime2
;
124 directory
->Touch(nullptr, t
.Pass(), Capture(&error
));
125 ASSERT_TRUE(directory
.WaitForIncomingResponse());
126 EXPECT_EQ(ERROR_OK
, error
);
129 error
= ERROR_INTERNAL
;
131 directory
->Stat(Capture(&error
, &file_info
));
132 ASSERT_TRUE(directory
.WaitForIncomingResponse());
133 EXPECT_EQ(ERROR_OK
, error
);
134 ASSERT_FALSE(file_info
.is_null());
135 ASSERT_FALSE(file_info
->atime
.is_null());
136 EXPECT_EQ(kPartyTime1
, file_info
->atime
->seconds
);
137 ASSERT_FALSE(file_info
->mtime
.is_null());
138 EXPECT_EQ(kPartyTime2
, file_info
->mtime
->seconds
);
140 // TODO(vtl): Also test Touch() "now" options.
141 // TODO(vtl): Also test touching both atime and mtime.
144 // TODO(vtl): Properly test OpenFile() and OpenDirectory() (including flags).
146 TEST_F(DirectoryImplTest
, BasicRenameDelete
) {
147 DirectoryPtr directory
;
148 GetTemporaryRoot(&directory
);
152 error
= ERROR_INTERNAL
;
153 directory
->OpenFile("my_file", nullptr, kOpenFlagWrite
| kOpenFlagCreate
,
155 ASSERT_TRUE(directory
.WaitForIncomingResponse());
156 EXPECT_EQ(ERROR_OK
, error
);
158 // Opening my_file should succeed.
159 error
= ERROR_INTERNAL
;
160 directory
->OpenFile("my_file", nullptr, kOpenFlagRead
, Capture(&error
));
161 ASSERT_TRUE(directory
.WaitForIncomingResponse());
162 EXPECT_EQ(ERROR_OK
, error
);
164 // Rename my_file to my_new_file.
165 directory
->Rename("my_file", "my_new_file", Capture(&error
));
166 ASSERT_TRUE(directory
.WaitForIncomingResponse());
167 EXPECT_EQ(ERROR_OK
, error
);
169 // Opening my_file should fail.
170 error
= ERROR_INTERNAL
;
171 directory
->OpenFile("my_file", nullptr, kOpenFlagRead
, Capture(&error
));
172 ASSERT_TRUE(directory
.WaitForIncomingResponse());
173 EXPECT_EQ(ERROR_UNKNOWN
, error
);
175 // Opening my_new_file should succeed.
176 error
= ERROR_INTERNAL
;
177 directory
->OpenFile("my_new_file", nullptr, kOpenFlagRead
, Capture(&error
));
178 ASSERT_TRUE(directory
.WaitForIncomingResponse());
179 EXPECT_EQ(ERROR_OK
, error
);
181 // Delete my_new_file (no flags).
182 directory
->Delete("my_new_file", 0, Capture(&error
));
183 ASSERT_TRUE(directory
.WaitForIncomingResponse());
184 EXPECT_EQ(ERROR_OK
, error
);
186 // Opening my_new_file should fail.
187 error
= ERROR_INTERNAL
;
188 directory
->OpenFile("my_new_file", nullptr, kOpenFlagRead
, Capture(&error
));
189 ASSERT_TRUE(directory
.WaitForIncomingResponse());
190 EXPECT_EQ(ERROR_UNKNOWN
, error
);
193 // TODO(vtl): Test that an open file can be moved (by someone else) without
194 // operations on it being affected.
195 // TODO(vtl): Test delete flags.
198 } // namespace filesystem