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

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: Fix leak in test 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 special_storage_policy_ = new quota::MockSpecialStoragePolicy;
71 base::PlatformFileInfo info; 71 file_system_context_ =
72 ASSERT_TRUE(file_util::GetFileInfo(test_path(), &info)); 72 new FileSystemContext(
73 test_file_modification_time_ = info.last_modified; 73 FileSystemTaskRunners::CreateMockTaskRunners(),
74 special_storage_policy_,
75 NULL,
76 temp_dir_.path(),
77 CreateDisallowFileAccessOptions());
78
79 file_system_context_->sandbox_provider()->ValidateFileSystemRoot(
80 GURL(kURLOrigin), kFileSystemTypeTemporary, true, // create
81 base::Bind(&OnValidateFileSystem));
82 MessageLoop::current()->RunAllPending();
83
84 WriteFile(kTestFileName, kTestData, kTestDataSize,
85 &test_file_modification_time_);
74 } 86 }
75 87
76 virtual void TearDown() OVERRIDE { 88 virtual void TearDown() OVERRIDE {
77 // Give another chance for deleted streams to perform Close.
78 MessageLoop::current()->RunAllPending(); 89 MessageLoop::current()->RunAllPending();
79 file_thread_.Stop();
80 } 90 }
81 91
82 protected: 92 protected:
83 LocalFileStreamReader* CreateFileReader( 93 FileSystemFileStreamReader* CreateFileReader(
84 const FilePath& path, 94 const std::string& file_name,
85 int64 initial_offset, 95 int64 initial_offset,
86 const base::Time& expected_modification_time) { 96 const base::Time& expected_modification_time) {
87 return new LocalFileStreamReader( 97 return new FileSystemFileStreamReader(file_system_context_,
88 file_task_runner(), 98 GetFileSystemURL(file_name),
89 path, 99 initial_offset,
90 initial_offset, 100 expected_modification_time);
91 expected_modification_time);
92 } 101 }
93 102
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 { 103 base::Time test_file_modification_time() const {
109 return test_file_modification_time_; 104 return test_file_modification_time_;
110 } 105 }
111 106
112 void EnsureFileTaskFinished() { 107 void WriteFile(const std::string& file_name,
113 file_task_runner()->PostTaskAndReply( 108 const char* buf,
114 FROM_HERE, base::Bind(&EmptyCallback), base::Bind(&QuitLoop)); 109 int buf_size,
115 MessageLoop::current()->Run(); 110 base::Time* modification_time) {
111 FileSystemFileUtil* file_util = file_system_context_->
112 sandbox_provider()->GetFileUtil(kFileSystemTypeTemporary);
113 FileSystemURL url = GetFileSystemURL(file_name);
114
115 FileSystemOperationContext context(file_system_context_);
116 context.set_allowed_bytes_growth(1024);
117
118 base::PlatformFile handle = base::kInvalidPlatformFileValue;
119 bool created = false;
120 ASSERT_EQ(base::PLATFORM_FILE_OK, file_util->CreateOrOpen(
121 &context,
122 url,
123 base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_WRITE,
124 &handle,
125 &created));
126 EXPECT_TRUE(created);
127 ASSERT_NE(base::kInvalidPlatformFileValue, handle);
128 ASSERT_EQ(buf_size,
129 base::WritePlatformFile(handle, 0 /* offset */, buf, buf_size));
130 base::ClosePlatformFile(handle);
131
132 base::PlatformFileInfo file_info;
133 FilePath platform_path;
134 ASSERT_EQ(base::PLATFORM_FILE_OK,
135 file_util->GetFileInfo(&context, url, &file_info,
136 &platform_path));
137 if (modification_time)
138 *modification_time = file_info.last_modified;
116 } 139 }
117 140
118 private: 141 private:
142 static void OnValidateFileSystem(base::PlatformFileError result) {
143 ASSERT_EQ(base::PLATFORM_FILE_OK, result);
144 }
145
146 FileSystemURL GetFileSystemURL(const std::string& file_name) {
147 return FileSystemURL(GURL(kURLOrigin),
148 kFileSystemTypeTemporary,
149 FilePath().AppendASCII(file_name));
150 }
151
119 MessageLoop message_loop_; 152 MessageLoop message_loop_;
120 base::Thread file_thread_; 153 ScopedTempDir temp_dir_;
121 ScopedTempDir dir_; 154 scoped_refptr<quota::MockSpecialStoragePolicy> special_storage_policy_;
155 scoped_refptr<FileSystemContext> file_system_context_;
122 base::Time test_file_modification_time_; 156 base::Time test_file_modification_time_;
123 }; 157 };
124 158
125 TEST_F(LocalFileStreamReaderTest, NonExistent) { 159 TEST_F(FileSystemFileStreamReaderTest, NonExistent) {
126 FilePath nonexistent_path = test_dir().AppendASCII("nonexistent"); 160 const char kFileName[] = "nonexistent";
127 scoped_ptr<LocalFileStreamReader> reader( 161 scoped_ptr<FileSystemFileStreamReader> reader(
128 CreateFileReader(nonexistent_path, 0, base::Time())); 162 CreateFileReader(kFileName, 0, base::Time()));
129 int result = 0; 163 int result = 0;
130 std::string data; 164 std::string data;
131 ReadFromReader(reader.get(), &data, 10, &result); 165 ReadFromReader(reader.get(), &data, 10, &result);
132 ASSERT_EQ(net::ERR_FILE_NOT_FOUND, result); 166 ASSERT_EQ(net::ERR_FILE_NOT_FOUND, result);
133 ASSERT_EQ(0U, data.size()); 167 ASSERT_EQ(0U, data.size());
134 } 168 }
135 169
136 TEST_F(LocalFileStreamReaderTest, Empty) { 170 TEST_F(FileSystemFileStreamReaderTest, Empty) {
137 FilePath empty_path = test_dir().AppendASCII("empty"); 171 const char kFileName[] = "empty";
138 base::PlatformFileError error = base::PLATFORM_FILE_OK; 172 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 173
147 scoped_ptr<LocalFileStreamReader> reader( 174 scoped_ptr<FileSystemFileStreamReader> reader(
148 CreateFileReader(empty_path, 0, base::Time())); 175 CreateFileReader(kFileName, 0, base::Time()));
149 int result = 0; 176 int result = 0;
150 std::string data; 177 std::string data;
151 ReadFromReader(reader.get(), &data, 10, &result); 178 ReadFromReader(reader.get(), &data, 10, &result);
152 ASSERT_EQ(net::OK, result); 179 ASSERT_EQ(net::OK, result);
153 ASSERT_EQ(0U, data.size()); 180 ASSERT_EQ(0U, data.size());
154 181
155 net::TestInt64CompletionCallback callback; 182 net::TestInt64CompletionCallback callback;
156 result = reader->GetLength(callback.callback()); 183 result = reader->GetLength(callback.callback());
157 if (result == net::ERR_IO_PENDING) 184 if (result == net::ERR_IO_PENDING)
158 result = callback.WaitForResult(); 185 result = callback.WaitForResult();
159 ASSERT_EQ(0, result); 186 ASSERT_EQ(0, result);
160 } 187 }
161 188
162 TEST_F(LocalFileStreamReaderTest, GetLengthNormal) { 189 TEST_F(FileSystemFileStreamReaderTest, GetLengthNormal) {
163 scoped_ptr<LocalFileStreamReader> reader( 190 scoped_ptr<FileSystemFileStreamReader> reader(
164 CreateFileReader(test_path(), 0, test_file_modification_time())); 191 CreateFileReader(kTestFileName, 0, test_file_modification_time()));
165 net::TestInt64CompletionCallback callback; 192 net::TestInt64CompletionCallback callback;
166 int result = reader->GetLength(callback.callback()); 193 int result = reader->GetLength(callback.callback());
167 if (result == net::ERR_IO_PENDING) 194 if (result == net::ERR_IO_PENDING)
168 result = callback.WaitForResult(); 195 result = callback.WaitForResult();
169 ASSERT_EQ(kTestDataSize, result); 196 ASSERT_EQ(kTestDataSize, result);
170 } 197 }
171 198
172 TEST_F(LocalFileStreamReaderTest, GetLengthAfterModified) { 199 TEST_F(FileSystemFileStreamReaderTest, GetLengthAfterModified) {
173 // Touch file so that the file's modification time becomes different 200 // Pass a fake expected modifictaion time so that the expectation fails.
174 // from what we expect. 201 base::Time fake_expected_modification_time =
175 TouchTestFile(); 202 test_file_modification_time() - base::TimeDelta::FromSeconds(10);
176 203
177 scoped_ptr<LocalFileStreamReader> reader( 204 scoped_ptr<FileSystemFileStreamReader> reader(
178 CreateFileReader(test_path(), 0, test_file_modification_time())); 205 CreateFileReader(kTestFileName, 0, fake_expected_modification_time));
179 net::TestInt64CompletionCallback callback; 206 net::TestInt64CompletionCallback callback;
180 int result = reader->GetLength(callback.callback()); 207 int result = reader->GetLength(callback.callback());
181 if (result == net::ERR_IO_PENDING) 208 if (result == net::ERR_IO_PENDING)
182 result = callback.WaitForResult(); 209 result = callback.WaitForResult();
183 ASSERT_EQ(net::ERR_UPLOAD_FILE_CHANGED, result); 210 ASSERT_EQ(net::ERR_UPLOAD_FILE_CHANGED, result);
184 211
185 // With NULL expected modification time this should work. 212 // With NULL expected modification time this should work.
186 reader.reset(CreateFileReader(test_path(), 0, base::Time())); 213 reader.reset(CreateFileReader(kTestFileName, 0, base::Time()));
187 result = reader->GetLength(callback.callback()); 214 result = reader->GetLength(callback.callback());
188 if (result == net::ERR_IO_PENDING) 215 if (result == net::ERR_IO_PENDING)
189 result = callback.WaitForResult(); 216 result = callback.WaitForResult();
190 ASSERT_EQ(kTestDataSize, result); 217 ASSERT_EQ(kTestDataSize, result);
191 } 218 }
192 219
193 TEST_F(LocalFileStreamReaderTest, GetLengthWithOffset) { 220 TEST_F(FileSystemFileStreamReaderTest, GetLengthWithOffset) {
194 scoped_ptr<LocalFileStreamReader> reader( 221 scoped_ptr<FileSystemFileStreamReader> reader(
195 CreateFileReader(test_path(), 3, base::Time())); 222 CreateFileReader(kTestFileName, 3, base::Time()));
196 net::TestInt64CompletionCallback callback; 223 net::TestInt64CompletionCallback callback;
197 int result = reader->GetLength(callback.callback()); 224 int result = reader->GetLength(callback.callback());
198 if (result == net::ERR_IO_PENDING) 225 if (result == net::ERR_IO_PENDING)
199 result = callback.WaitForResult(); 226 result = callback.WaitForResult();
200 // Initial offset does not affect the result of GetLength. 227 // Initial offset does not affect the result of GetLength.
201 ASSERT_EQ(kTestDataSize, result); 228 ASSERT_EQ(kTestDataSize, result);
202 } 229 }
203 230
204 TEST_F(LocalFileStreamReaderTest, ReadNormal) { 231 TEST_F(FileSystemFileStreamReaderTest, ReadNormal) {
205 scoped_ptr<LocalFileStreamReader> reader( 232 scoped_ptr<FileSystemFileStreamReader> reader(
206 CreateFileReader(test_path(), 0, test_file_modification_time())); 233 CreateFileReader(kTestFileName, 0, test_file_modification_time()));
207 int result = 0; 234 int result = 0;
208 std::string data; 235 std::string data;
209 ReadFromReader(reader.get(), &data, kTestDataSize, &result); 236 ReadFromReader(reader.get(), &data, kTestDataSize, &result);
210 ASSERT_EQ(net::OK, result); 237 ASSERT_EQ(net::OK, result);
211 ASSERT_EQ(kTestData, data); 238 ASSERT_EQ(kTestData, data);
212 } 239 }
213 240
214 TEST_F(LocalFileStreamReaderTest, ReadAfterModified) { 241 TEST_F(FileSystemFileStreamReaderTest, ReadAfterModified) {
215 // Touch file so that the file's modification time becomes different 242 // Pass a fake expected modifictaion time so that the expectation fails.
216 // from what we expect. 243 base::Time fake_expected_modification_time =
217 TouchTestFile(); 244 test_file_modification_time() - base::TimeDelta::FromSeconds(10);
218 245
219 scoped_ptr<LocalFileStreamReader> reader( 246 scoped_ptr<FileSystemFileStreamReader> reader(
220 CreateFileReader(test_path(), 0, test_file_modification_time())); 247 CreateFileReader(kTestFileName, 0, fake_expected_modification_time));
221 int result = 0; 248 int result = 0;
222 std::string data; 249 std::string data;
223 ReadFromReader(reader.get(), &data, kTestDataSize, &result); 250 ReadFromReader(reader.get(), &data, kTestDataSize, &result);
224 ASSERT_EQ(net::ERR_UPLOAD_FILE_CHANGED, result); 251 ASSERT_EQ(net::ERR_UPLOAD_FILE_CHANGED, result);
225 ASSERT_EQ(0U, data.size()); 252 ASSERT_EQ(0U, data.size());
226 253
227 // With NULL expected modification time this should work. 254 // With NULL expected modification time this should work.
228 data.clear(); 255 data.clear();
229 reader.reset(CreateFileReader(test_path(), 0, base::Time())); 256 reader.reset(CreateFileReader(kTestFileName, 0, base::Time()));
230 ReadFromReader(reader.get(), &data, kTestDataSize, &result); 257 ReadFromReader(reader.get(), &data, kTestDataSize, &result);
231 ASSERT_EQ(net::OK, result); 258 ASSERT_EQ(net::OK, result);
232 ASSERT_EQ(kTestData, data); 259 ASSERT_EQ(kTestData, data);
233 } 260 }
234 261
235 TEST_F(LocalFileStreamReaderTest, ReadWithOffset) { 262 TEST_F(FileSystemFileStreamReaderTest, ReadWithOffset) {
236 scoped_ptr<LocalFileStreamReader> reader( 263 scoped_ptr<FileSystemFileStreamReader> reader(
237 CreateFileReader(test_path(), 3, base::Time())); 264 CreateFileReader(kTestFileName, 3, base::Time()));
238 int result = 0; 265 int result = 0;
239 std::string data; 266 std::string data;
240 ReadFromReader(reader.get(), &data, kTestDataSize, &result); 267 ReadFromReader(reader.get(), &data, kTestDataSize, &result);
241 ASSERT_EQ(net::OK, result); 268 ASSERT_EQ(net::OK, result);
242 ASSERT_EQ(&kTestData[3], data); 269 ASSERT_EQ(&kTestData[3], data);
243 } 270 }
244 271
245 TEST_F(LocalFileStreamReaderTest, DeleteWithUnfinishedRead) { 272 TEST_F(FileSystemFileStreamReaderTest, DeleteWithUnfinishedRead) {
246 scoped_ptr<LocalFileStreamReader> reader( 273 scoped_ptr<FileSystemFileStreamReader> reader(
247 CreateFileReader(test_path(), 0, base::Time())); 274 CreateFileReader(kTestFileName, 0, base::Time()));
248 275
249 net::TestCompletionCallback callback; 276 net::TestCompletionCallback callback;
250 scoped_refptr<net::IOBufferWithSize> buf( 277 scoped_refptr<net::IOBufferWithSize> buf(
251 new net::IOBufferWithSize(kTestDataSize)); 278 new net::IOBufferWithSize(kTestDataSize));
252 int rv = reader->Read(buf, buf->size(), base::Bind(&NeverCalled)); 279 int rv = reader->Read(buf, buf->size(), base::Bind(&NeverCalled));
253 ASSERT_TRUE(rv == net::ERR_IO_PENDING || rv >= 0); 280 ASSERT_TRUE(rv == net::ERR_IO_PENDING || rv >= 0);
254 281
255 // Delete immediately. 282 // Delete immediately.
256 // Should not crash; nor should NeverCalled be callback. 283 // Should not crash; nor should NeverCalled be callback.
257 reader.reset(); 284 reader.reset();
258 EnsureFileTaskFinished();
259 } 285 }
260 286
261 } // namespace webkit_blob 287 } // namespace fileapi
OLDNEW
« no previous file with comments | « webkit/fileapi/file_system_file_stream_reader.cc ('k') | webkit/fileapi/file_system_mount_point_provider.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698