Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(29)

Side by Side Diff: webkit/fileapi/file_system_file_stream_reader_unittest.cc

Issue 11098067: fileapi: Add modification time check for FileSystemFileStreamReader (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "webkit/blob/local_file_stream_reader.h" 5 #include "webkit/fileapi/file_system_file_stream_reader.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/file_path.h"
10 #include "base/file_util.h"
11 #include "base/memory/scoped_ptr.h" 9 #include "base/memory/scoped_ptr.h"
12 #include "base/message_loop.h" 10 #include "base/message_loop.h"
13 #include "base/platform_file.h" 11 #include "base/platform_file.h"
14 #include "base/scoped_temp_dir.h" 12 #include "base/scoped_temp_dir.h"
15 #include "base/threading/thread.h"
16 #include "net/base/io_buffer.h" 13 #include "net/base/io_buffer.h"
17 #include "net/base/net_errors.h" 14 #include "net/base/net_errors.h"
18 #include "net/base/test_completion_callback.h" 15 #include "net/base/test_completion_callback.h"
19 #include "testing/gtest/include/gtest/gtest.h" 16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "webkit/fileapi/file_system_context.h"
18 #include "webkit/fileapi/file_system_file_util.h"
19 #include "webkit/fileapi/file_system_operation_context.h"
20 #include "webkit/fileapi/file_system_task_runners.h"
21 #include "webkit/fileapi/mock_file_system_options.h"
22 #include "webkit/fileapi/sandbox_mount_point_provider.h"
23 #include "webkit/quota/mock_special_storage_policy.h"
20 24
21 namespace webkit_blob { 25 namespace fileapi {
22 26
23 namespace { 27 namespace {
24 28
29 const char kURLOrigin[] = "http://remote/";
30 const char kTestFileName[] = "test.dat";
25 const char kTestData[] = "0123456789"; 31 const char kTestData[] = "0123456789";
26 const int kTestDataSize = arraysize(kTestData) - 1; 32 const int kTestDataSize = arraysize(kTestData) - 1;
27 33
28 void ReadFromReader(LocalFileStreamReader* reader, 34 void ReadFromReader(FileSystemFileStreamReader* reader,
29 std::string* data, size_t size, 35 std::string* data,
36 size_t size,
30 int* result) { 37 int* result) {
31 ASSERT_TRUE(reader != NULL); 38 ASSERT_TRUE(reader != NULL);
32 ASSERT_TRUE(result != NULL); 39 ASSERT_TRUE(result != NULL);
33 *result = net::OK; 40 *result = net::OK;
34 net::TestCompletionCallback callback; 41 net::TestCompletionCallback callback;
35 size_t total_bytes_read = 0; 42 size_t total_bytes_read = 0;
36 while (total_bytes_read < size) { 43 while (total_bytes_read < size) {
37 scoped_refptr<net::IOBufferWithSize> buf( 44 scoped_refptr<net::IOBufferWithSize> buf(
38 new net::IOBufferWithSize(size - total_bytes_read)); 45 new net::IOBufferWithSize(size - total_bytes_read));
39 int rv = reader->Read(buf, buf->size(), callback.callback()); 46 int rv = reader->Read(buf, buf->size(), callback.callback());
40 if (rv == net::ERR_IO_PENDING) 47 if (rv == net::ERR_IO_PENDING)
41 rv = callback.WaitForResult(); 48 rv = callback.WaitForResult();
42 if (rv < 0) 49 if (rv < 0)
43 *result = rv; 50 *result = rv;
44 if (rv <= 0) 51 if (rv <= 0)
45 break; 52 break;
46 total_bytes_read += rv; 53 total_bytes_read += rv;
47 data->append(buf->data(), rv); 54 data->append(buf->data(), rv);
48 } 55 }
49 } 56 }
50 57
51 void NeverCalled(int) { ADD_FAILURE(); } 58 void NeverCalled(int) { ADD_FAILURE(); }
52 void EmptyCallback() {}
53
54 void QuitLoop() {
55 MessageLoop::current()->Quit();
56 }
57 59
58 } // namespace 60 } // namespace
59 61
60 class LocalFileStreamReaderTest : public testing::Test { 62 class FileSystemFileStreamReaderTest : public testing::Test {
61 public: 63 public:
62 LocalFileStreamReaderTest() 64 FileSystemFileStreamReaderTest()
63 : message_loop_(MessageLoop::TYPE_IO), 65 : message_loop_(MessageLoop::TYPE_IO) {}
64 file_thread_("FileUtilProxyTestFileThread") {}
65 66
66 virtual void SetUp() OVERRIDE { 67 virtual void SetUp() OVERRIDE {
67 ASSERT_TRUE(file_thread_.Start()); 68 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
68 ASSERT_TRUE(dir_.CreateUniqueTempDir());
69 69
70 file_util::WriteFile(test_path(), kTestData, kTestDataSize); 70 file_system_context_ =
71 base::PlatformFileInfo info; 71 new FileSystemContext(
72 ASSERT_TRUE(file_util::GetFileInfo(test_path(), &info)); 72 FileSystemTaskRunners::CreateMockTaskRunners(),
73 test_file_modification_time_ = info.last_modified; 73 new quota::MockSpecialStoragePolicy,
74 NULL,
75 temp_dir_.path(),
76 CreateDisallowFileAccessOptions());
77
78 file_system_context_->sandbox_provider()->ValidateFileSystemRoot(
79 GURL(kURLOrigin), kFileSystemTypeTemporary, true, // create
80 base::Bind(&OnValidateFileSystem));
81 MessageLoop::current()->RunAllPending();
82
83 WriteFile(kTestFileName, kTestData, kTestDataSize,
84 &test_file_modification_time_);
74 } 85 }
75 86
76 virtual void TearDown() OVERRIDE { 87 virtual void TearDown() OVERRIDE {
77 // Give another chance for deleted streams to perform Close.
78 MessageLoop::current()->RunAllPending(); 88 MessageLoop::current()->RunAllPending();
kinuko 2012/10/15 07:24:07 Before submitting can you make sure FileStream::Cl
hashimoto 2012/10/15 08:05:04 Confirmed it locally and will try with bots. Since
79 file_thread_.Stop();
80 } 89 }
81 90
82 protected: 91 protected:
83 LocalFileStreamReader* CreateFileReader( 92 FileSystemFileStreamReader* CreateFileReader(
84 const FilePath& path, 93 const std::string& file_name,
85 int64 initial_offset, 94 int64 initial_offset,
86 const base::Time& expected_modification_time) { 95 const base::Time& expected_modification_time) {
87 return new LocalFileStreamReader( 96 return new FileSystemFileStreamReader(file_system_context_,
88 file_task_runner(), 97 GetFileSystemURL(file_name),
89 path, 98 initial_offset,
90 initial_offset, 99 expected_modification_time);
91 expected_modification_time);
92 } 100 }
93 101
94 void TouchTestFile() {
95 base::Time new_modified_time =
96 test_file_modification_time() - base::TimeDelta::FromSeconds(1);
97 ASSERT_TRUE(file_util::TouchFile(test_path(),
98 test_file_modification_time(),
99 new_modified_time));
100 }
101
102 base::MessageLoopProxy* file_task_runner() const {
103 return file_thread_.message_loop_proxy().get();
104 }
105
106 FilePath test_dir() const { return dir_.path(); }
107 FilePath test_path() const { return dir_.path().AppendASCII("test"); }
108 base::Time test_file_modification_time() const { 102 base::Time test_file_modification_time() const {
109 return test_file_modification_time_; 103 return test_file_modification_time_;
110 } 104 }
111 105
112 void EnsureFileTaskFinished() { 106 void WriteFile(const std::string& file_name,
113 file_task_runner()->PostTaskAndReply( 107 const char* buf,
114 FROM_HERE, base::Bind(&EmptyCallback), base::Bind(&QuitLoop)); 108 int buf_size,
115 MessageLoop::current()->Run(); 109 base::Time* modification_time) {
110 FileSystemFileUtil* file_util = file_system_context_->
111 sandbox_provider()->GetFileUtil(kFileSystemTypeTemporary);
112 FileSystemURL url = GetFileSystemURL(file_name);
113
114 FileSystemOperationContext context(file_system_context_);
115 context.set_allowed_bytes_growth(1024);
116
117 base::PlatformFile handle = base::kInvalidPlatformFileValue;
118 bool created = false;
119 ASSERT_EQ(base::PLATFORM_FILE_OK, file_util->CreateOrOpen(
120 &context,
121 url,
122 base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_WRITE,
123 &handle,
124 &created));
125 EXPECT_TRUE(created);
126 ASSERT_NE(base::kInvalidPlatformFileValue, handle);
127 ASSERT_EQ(buf_size,
128 base::WritePlatformFile(handle, 0 /* offset */, buf, buf_size));
129 base::ClosePlatformFile(handle);
130
131 base::PlatformFileInfo file_info;
132 FilePath platform_path;
133 ASSERT_EQ(base::PLATFORM_FILE_OK,
134 file_util->GetFileInfo(&context, url, &file_info,
135 &platform_path));
136 if (modification_time)
137 *modification_time = file_info.last_modified;
116 } 138 }
117 139
118 private: 140 private:
141 static void OnValidateFileSystem(base::PlatformFileError result) {
142 ASSERT_EQ(base::PLATFORM_FILE_OK, result);
143 }
144
145 FileSystemURL GetFileSystemURL(const std::string& file_name) {
146 return FileSystemURL(GURL(kURLOrigin),
147 kFileSystemTypeTemporary,
148 FilePath().AppendASCII(file_name));
149 }
150
119 MessageLoop message_loop_; 151 MessageLoop message_loop_;
120 base::Thread file_thread_; 152 ScopedTempDir temp_dir_;
121 ScopedTempDir dir_; 153 scoped_refptr<FileSystemContext> file_system_context_;
122 base::Time test_file_modification_time_; 154 base::Time test_file_modification_time_;
123 }; 155 };
124 156
125 TEST_F(LocalFileStreamReaderTest, NonExistent) { 157 TEST_F(FileSystemFileStreamReaderTest, NonExistent) {
126 FilePath nonexistent_path = test_dir().AppendASCII("nonexistent"); 158 const char kFileName[] = "nonexistent";
127 scoped_ptr<LocalFileStreamReader> reader( 159 scoped_ptr<FileSystemFileStreamReader> reader(
128 CreateFileReader(nonexistent_path, 0, base::Time())); 160 CreateFileReader(kFileName, 0, base::Time()));
129 int result = 0; 161 int result = 0;
130 std::string data; 162 std::string data;
131 ReadFromReader(reader.get(), &data, 10, &result); 163 ReadFromReader(reader.get(), &data, 10, &result);
132 ASSERT_EQ(net::ERR_FILE_NOT_FOUND, result); 164 ASSERT_EQ(net::ERR_FILE_NOT_FOUND, result);
133 ASSERT_EQ(0U, data.size()); 165 ASSERT_EQ(0U, data.size());
134 } 166 }
135 167
136 TEST_F(LocalFileStreamReaderTest, Empty) { 168 TEST_F(FileSystemFileStreamReaderTest, Empty) {
137 FilePath empty_path = test_dir().AppendASCII("empty"); 169 const char kFileName[] = "empty";
138 base::PlatformFileError error = base::PLATFORM_FILE_OK; 170 WriteFile(kFileName, NULL, 0, NULL);
139 base::PlatformFile file = base::CreatePlatformFile(
140 empty_path,
141 base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_READ,
142 NULL, &error);
143 ASSERT_EQ(base::PLATFORM_FILE_OK, error);
144 ASSERT_NE(base::kInvalidPlatformFileValue, file);
145 base::ClosePlatformFile(file);
146 171
147 scoped_ptr<LocalFileStreamReader> reader( 172 scoped_ptr<FileSystemFileStreamReader> reader(
148 CreateFileReader(empty_path, 0, base::Time())); 173 CreateFileReader(kFileName, 0, base::Time()));
149 int result = 0; 174 int result = 0;
150 std::string data; 175 std::string data;
151 ReadFromReader(reader.get(), &data, 10, &result); 176 ReadFromReader(reader.get(), &data, 10, &result);
152 ASSERT_EQ(net::OK, result); 177 ASSERT_EQ(net::OK, result);
153 ASSERT_EQ(0U, data.size()); 178 ASSERT_EQ(0U, data.size());
154 179
155 net::TestInt64CompletionCallback callback; 180 net::TestInt64CompletionCallback callback;
156 result = reader->GetLength(callback.callback()); 181 result = reader->GetLength(callback.callback());
157 if (result == net::ERR_IO_PENDING) 182 if (result == net::ERR_IO_PENDING)
158 result = callback.WaitForResult(); 183 result = callback.WaitForResult();
159 ASSERT_EQ(0, result); 184 ASSERT_EQ(0, result);
160 } 185 }
161 186
162 TEST_F(LocalFileStreamReaderTest, GetLengthNormal) { 187 TEST_F(FileSystemFileStreamReaderTest, GetLengthNormal) {
163 scoped_ptr<LocalFileStreamReader> reader( 188 scoped_ptr<FileSystemFileStreamReader> reader(
164 CreateFileReader(test_path(), 0, test_file_modification_time())); 189 CreateFileReader(kTestFileName, 0, test_file_modification_time()));
165 net::TestInt64CompletionCallback callback; 190 net::TestInt64CompletionCallback callback;
166 int result = reader->GetLength(callback.callback()); 191 int result = reader->GetLength(callback.callback());
167 if (result == net::ERR_IO_PENDING) 192 if (result == net::ERR_IO_PENDING)
168 result = callback.WaitForResult(); 193 result = callback.WaitForResult();
169 ASSERT_EQ(kTestDataSize, result); 194 ASSERT_EQ(kTestDataSize, result);
170 } 195 }
171 196
172 TEST_F(LocalFileStreamReaderTest, GetLengthAfterModified) { 197 TEST_F(FileSystemFileStreamReaderTest, GetLengthAfterModified) {
173 // Touch file so that the file's modification time becomes different 198 // Pass a fake expected modifictaion time so that the expectation fails.
174 // from what we expect. 199 base::Time fake_expected_modification_time =
175 TouchTestFile(); 200 test_file_modification_time() - base::TimeDelta::FromSeconds(10);
176 201
177 scoped_ptr<LocalFileStreamReader> reader( 202 scoped_ptr<FileSystemFileStreamReader> reader(
178 CreateFileReader(test_path(), 0, test_file_modification_time())); 203 CreateFileReader(kTestFileName, 0, fake_expected_modification_time));
179 net::TestInt64CompletionCallback callback; 204 net::TestInt64CompletionCallback callback;
180 int result = reader->GetLength(callback.callback()); 205 int result = reader->GetLength(callback.callback());
181 if (result == net::ERR_IO_PENDING) 206 if (result == net::ERR_IO_PENDING)
182 result = callback.WaitForResult(); 207 result = callback.WaitForResult();
183 ASSERT_EQ(net::ERR_UPLOAD_FILE_CHANGED, result); 208 ASSERT_EQ(net::ERR_UPLOAD_FILE_CHANGED, result);
184 209
185 // With NULL expected modification time this should work. 210 // With NULL expected modification time this should work.
186 reader.reset(CreateFileReader(test_path(), 0, base::Time())); 211 reader.reset(CreateFileReader(kTestFileName, 0, base::Time()));
187 result = reader->GetLength(callback.callback()); 212 result = reader->GetLength(callback.callback());
188 if (result == net::ERR_IO_PENDING) 213 if (result == net::ERR_IO_PENDING)
189 result = callback.WaitForResult(); 214 result = callback.WaitForResult();
190 ASSERT_EQ(kTestDataSize, result); 215 ASSERT_EQ(kTestDataSize, result);
191 } 216 }
192 217
193 TEST_F(LocalFileStreamReaderTest, GetLengthWithOffset) { 218 TEST_F(FileSystemFileStreamReaderTest, GetLengthWithOffset) {
194 scoped_ptr<LocalFileStreamReader> reader( 219 scoped_ptr<FileSystemFileStreamReader> reader(
195 CreateFileReader(test_path(), 3, base::Time())); 220 CreateFileReader(kTestFileName, 3, base::Time()));
196 net::TestInt64CompletionCallback callback; 221 net::TestInt64CompletionCallback callback;
197 int result = reader->GetLength(callback.callback()); 222 int result = reader->GetLength(callback.callback());
198 if (result == net::ERR_IO_PENDING) 223 if (result == net::ERR_IO_PENDING)
199 result = callback.WaitForResult(); 224 result = callback.WaitForResult();
200 // Initial offset does not affect the result of GetLength. 225 // Initial offset does not affect the result of GetLength.
201 ASSERT_EQ(kTestDataSize, result); 226 ASSERT_EQ(kTestDataSize, result);
202 } 227 }
203 228
204 TEST_F(LocalFileStreamReaderTest, ReadNormal) { 229 TEST_F(FileSystemFileStreamReaderTest, ReadNormal) {
205 scoped_ptr<LocalFileStreamReader> reader( 230 scoped_ptr<FileSystemFileStreamReader> reader(
206 CreateFileReader(test_path(), 0, test_file_modification_time())); 231 CreateFileReader(kTestFileName, 0, test_file_modification_time()));
207 int result = 0; 232 int result = 0;
208 std::string data; 233 std::string data;
209 ReadFromReader(reader.get(), &data, kTestDataSize, &result); 234 ReadFromReader(reader.get(), &data, kTestDataSize, &result);
210 ASSERT_EQ(net::OK, result); 235 ASSERT_EQ(net::OK, result);
211 ASSERT_EQ(kTestData, data); 236 ASSERT_EQ(kTestData, data);
212 } 237 }
213 238
214 TEST_F(LocalFileStreamReaderTest, ReadAfterModified) { 239 TEST_F(FileSystemFileStreamReaderTest, ReadAfterModified) {
215 // Touch file so that the file's modification time becomes different 240 // Pass a fake expected modifictaion time so that the expectation fails.
216 // from what we expect. 241 base::Time fake_expected_modification_time =
217 TouchTestFile(); 242 test_file_modification_time() - base::TimeDelta::FromSeconds(10);
218 243
219 scoped_ptr<LocalFileStreamReader> reader( 244 scoped_ptr<FileSystemFileStreamReader> reader(
220 CreateFileReader(test_path(), 0, test_file_modification_time())); 245 CreateFileReader(kTestFileName, 0, fake_expected_modification_time));
221 int result = 0; 246 int result = 0;
222 std::string data; 247 std::string data;
223 ReadFromReader(reader.get(), &data, kTestDataSize, &result); 248 ReadFromReader(reader.get(), &data, kTestDataSize, &result);
224 ASSERT_EQ(net::ERR_UPLOAD_FILE_CHANGED, result); 249 ASSERT_EQ(net::ERR_UPLOAD_FILE_CHANGED, result);
225 ASSERT_EQ(0U, data.size()); 250 ASSERT_EQ(0U, data.size());
226 251
227 // With NULL expected modification time this should work. 252 // With NULL expected modification time this should work.
228 data.clear(); 253 data.clear();
229 reader.reset(CreateFileReader(test_path(), 0, base::Time())); 254 reader.reset(CreateFileReader(kTestFileName, 0, base::Time()));
230 ReadFromReader(reader.get(), &data, kTestDataSize, &result); 255 ReadFromReader(reader.get(), &data, kTestDataSize, &result);
231 ASSERT_EQ(net::OK, result); 256 ASSERT_EQ(net::OK, result);
232 ASSERT_EQ(kTestData, data); 257 ASSERT_EQ(kTestData, data);
233 } 258 }
234 259
235 TEST_F(LocalFileStreamReaderTest, ReadWithOffset) { 260 TEST_F(FileSystemFileStreamReaderTest, ReadWithOffset) {
236 scoped_ptr<LocalFileStreamReader> reader( 261 scoped_ptr<FileSystemFileStreamReader> reader(
237 CreateFileReader(test_path(), 3, base::Time())); 262 CreateFileReader(kTestFileName, 3, base::Time()));
238 int result = 0; 263 int result = 0;
239 std::string data; 264 std::string data;
240 ReadFromReader(reader.get(), &data, kTestDataSize, &result); 265 ReadFromReader(reader.get(), &data, kTestDataSize, &result);
241 ASSERT_EQ(net::OK, result); 266 ASSERT_EQ(net::OK, result);
242 ASSERT_EQ(&kTestData[3], data); 267 ASSERT_EQ(&kTestData[3], data);
243 } 268 }
244 269
245 TEST_F(LocalFileStreamReaderTest, DeleteWithUnfinishedRead) { 270 TEST_F(FileSystemFileStreamReaderTest, DeleteWithUnfinishedRead) {
246 scoped_ptr<LocalFileStreamReader> reader( 271 scoped_ptr<FileSystemFileStreamReader> reader(
247 CreateFileReader(test_path(), 0, base::Time())); 272 CreateFileReader(kTestFileName, 0, base::Time()));
248 273
249 net::TestCompletionCallback callback; 274 net::TestCompletionCallback callback;
250 scoped_refptr<net::IOBufferWithSize> buf( 275 scoped_refptr<net::IOBufferWithSize> buf(
251 new net::IOBufferWithSize(kTestDataSize)); 276 new net::IOBufferWithSize(kTestDataSize));
252 int rv = reader->Read(buf, buf->size(), base::Bind(&NeverCalled)); 277 int rv = reader->Read(buf, buf->size(), base::Bind(&NeverCalled));
253 ASSERT_TRUE(rv == net::ERR_IO_PENDING || rv >= 0); 278 ASSERT_TRUE(rv == net::ERR_IO_PENDING || rv >= 0);
254 279
255 // Delete immediately. 280 // Delete immediately.
256 // Should not crash; nor should NeverCalled be callback. 281 // Should not crash; nor should NeverCalled be callback.
257 reader.reset(); 282 reader.reset();
258 EnsureFileTaskFinished();
259 } 283 }
260 284
261 } // namespace webkit_blob 285 } // namespace fileapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698