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

Side by Side Diff: content/browser/fileapi/file_system_url_request_job_unittest.cc

Issue 2368913003: Populate storage_unittests target. (Closed)
Patch Set: Removed unnecessary include from storage/browser/blob/blob_storage_context_unittest.cc. Created 4 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
OLDNEW
(Empty)
1 // Copyright 2013 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 <stddef.h>
6 #include <string>
7 #include <utility>
8
9 #include "base/bind.h"
10 #include "base/files/file_path.h"
11 #include "base/files/file_util.h"
12 #include "base/files/scoped_temp_dir.h"
13 #include "base/format_macros.h"
14 #include "base/location.h"
15 #include "base/macros.h"
16 #include "base/memory/scoped_vector.h"
17 #include "base/memory/weak_ptr.h"
18 #include "base/rand_util.h"
19 #include "base/run_loop.h"
20 #include "base/single_thread_task_runner.h"
21 #include "base/strings/string_piece.h"
22 #include "base/strings/stringprintf.h"
23 #include "base/strings/utf_string_conversions.h"
24 #include "base/threading/thread_task_runner_handle.h"
25 #include "content/public/test/async_file_test_helper.h"
26 #include "content/public/test/test_file_system_backend.h"
27 #include "content/public/test/test_file_system_context.h"
28 #include "net/base/load_flags.h"
29 #include "net/base/mime_util.h"
30 #include "net/base/net_errors.h"
31 #include "net/base/request_priority.h"
32 #include "net/http/http_byte_range.h"
33 #include "net/http/http_request_headers.h"
34 #include "net/url_request/url_request.h"
35 #include "net/url_request/url_request_context.h"
36 #include "net/url_request/url_request_test_util.h"
37 #include "storage/browser/fileapi/external_mount_points.h"
38 #include "storage/browser/fileapi/file_system_context.h"
39 #include "storage/browser/fileapi/file_system_file_util.h"
40 #include "storage/browser/fileapi/file_system_url_request_job.h"
41 #include "testing/gtest/include/gtest/gtest.h"
42
43 using content::AsyncFileTestHelper;
44 using storage::FileSystemContext;
45 using storage::FileSystemURL;
46 using storage::FileSystemURLRequestJob;
47
48 namespace content {
49 namespace {
50
51 // We always use the TEMPORARY FileSystem in this test.
52 const char kFileSystemURLPrefix[] = "filesystem:http://remote/temporary/";
53 const char kTestFileData[] = "0123456789";
54
55 void FillBuffer(char* buffer, size_t len) {
56 base::RandBytes(buffer, len);
57 }
58
59 const char kValidExternalMountPoint[] = "mnt_name";
60
61 // An auto mounter that will try to mount anything for |storage_domain| =
62 // "automount", but will only succeed for the mount point "mnt_name".
63 bool TestAutoMountForURLRequest(
64 const net::URLRequest* /*url_request*/,
65 const storage::FileSystemURL& filesystem_url,
66 const std::string& storage_domain,
67 const base::Callback<void(base::File::Error result)>& callback) {
68 if (storage_domain != "automount")
69 return false;
70 std::vector<base::FilePath::StringType> components;
71 filesystem_url.path().GetComponents(&components);
72 std::string mount_point = base::FilePath(components[0]).AsUTF8Unsafe();
73
74 if (mount_point == kValidExternalMountPoint) {
75 storage::ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
76 kValidExternalMountPoint,
77 storage::kFileSystemTypeTest,
78 storage::FileSystemMountOption(),
79 base::FilePath());
80 callback.Run(base::File::FILE_OK);
81 } else {
82 callback.Run(base::File::FILE_ERROR_NOT_FOUND);
83 }
84 return true;
85 }
86
87 class FileSystemURLRequestJobFactory : public net::URLRequestJobFactory {
88 public:
89 FileSystemURLRequestJobFactory(const std::string& storage_domain,
90 FileSystemContext* context)
91 : storage_domain_(storage_domain), file_system_context_(context) {
92 }
93
94 net::URLRequestJob* MaybeCreateJobWithProtocolHandler(
95 const std::string& scheme,
96 net::URLRequest* request,
97 net::NetworkDelegate* network_delegate) const override {
98 return new storage::FileSystemURLRequestJob(
99 request, network_delegate, storage_domain_, file_system_context_);
100 }
101
102 net::URLRequestJob* MaybeInterceptRedirect(
103 net::URLRequest* request,
104 net::NetworkDelegate* network_delegate,
105 const GURL& location) const override {
106 return nullptr;
107 }
108
109 net::URLRequestJob* MaybeInterceptResponse(
110 net::URLRequest* request,
111 net::NetworkDelegate* network_delegate) const override {
112 return nullptr;
113 }
114
115 bool IsHandledProtocol(const std::string& scheme) const override {
116 return true;
117 }
118
119 bool IsHandledURL(const GURL& url) const override { return true; }
120
121 bool IsSafeRedirectTarget(const GURL& location) const override {
122 return false;
123 }
124
125 private:
126 std::string storage_domain_;
127 FileSystemContext* file_system_context_;
128 };
129
130 } // namespace
131
132 class FileSystemURLRequestJobTest : public testing::Test {
133 protected:
134 FileSystemURLRequestJobTest() : weak_factory_(this) {
135 }
136
137 void SetUp() override {
138 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
139
140 // We use the main thread so that we can get the root path synchronously.
141 // TODO(adamk): Run this on the FILE thread we've created as well.
142 file_system_context_ =
143 CreateFileSystemContextForTesting(NULL, temp_dir_.GetPath());
144
145 file_system_context_->OpenFileSystem(
146 GURL("http://remote/"),
147 storage::kFileSystemTypeTemporary,
148 storage::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT,
149 base::Bind(&FileSystemURLRequestJobTest::OnOpenFileSystem,
150 weak_factory_.GetWeakPtr()));
151 base::RunLoop().RunUntilIdle();
152 }
153
154 void TearDown() override {
155 // FileReader posts a task to close the file in destructor.
156 base::RunLoop().RunUntilIdle();
157 }
158
159 void SetUpAutoMountContext() {
160 base::FilePath mnt_point =
161 temp_dir_.GetPath().AppendASCII("auto_mount_dir");
162 ASSERT_TRUE(base::CreateDirectory(mnt_point));
163
164 ScopedVector<storage::FileSystemBackend> additional_providers;
165 additional_providers.push_back(new TestFileSystemBackend(
166 base::ThreadTaskRunnerHandle::Get().get(), mnt_point));
167
168 std::vector<storage::URLRequestAutoMountHandler> handlers;
169 handlers.push_back(base::Bind(&TestAutoMountForURLRequest));
170
171 file_system_context_ = CreateFileSystemContextWithAutoMountersForTesting(
172 NULL, std::move(additional_providers), handlers, temp_dir_.GetPath());
173
174 ASSERT_EQ(static_cast<int>(sizeof(kTestFileData)) - 1,
175 base::WriteFile(mnt_point.AppendASCII("foo"), kTestFileData,
176 sizeof(kTestFileData) - 1));
177 }
178
179 void OnOpenFileSystem(const GURL& root_url,
180 const std::string& name,
181 base::File::Error result) {
182 ASSERT_EQ(base::File::FILE_OK, result);
183 }
184
185 void TestRequestHelper(const GURL& url,
186 const net::HttpRequestHeaders* headers,
187 bool run_to_completion,
188 FileSystemContext* file_system_context) {
189 delegate_.reset(new net::TestDelegate());
190 // Make delegate_ exit the MessageLoop when the request is done.
191 delegate_->set_quit_on_complete(true);
192 delegate_->set_quit_on_redirect(true);
193
194 job_factory_.reset(new FileSystemURLRequestJobFactory(
195 url.GetOrigin().host(), file_system_context));
196 empty_context_.set_job_factory(job_factory_.get());
197
198 request_ = empty_context_.CreateRequest(
199 url, net::DEFAULT_PRIORITY, delegate_.get());
200 if (headers)
201 request_->SetExtraRequestHeaders(*headers);
202
203 request_->Start();
204 ASSERT_TRUE(request_->is_pending()); // verify that we're starting async
205 if (run_to_completion)
206 base::RunLoop().Run();
207 }
208
209 void TestRequest(const GURL& url) {
210 TestRequestHelper(url, NULL, true, file_system_context_.get());
211 }
212
213 void TestRequestWithContext(const GURL& url,
214 FileSystemContext* file_system_context) {
215 TestRequestHelper(url, NULL, true, file_system_context);
216 }
217
218 void TestRequestWithHeaders(const GURL& url,
219 const net::HttpRequestHeaders* headers) {
220 TestRequestHelper(url, headers, true, file_system_context_.get());
221 }
222
223 void TestRequestNoRun(const GURL& url) {
224 TestRequestHelper(url, NULL, false, file_system_context_.get());
225 }
226
227 void CreateDirectory(const base::StringPiece& dir_name) {
228 FileSystemURL url = file_system_context_->CreateCrackedFileSystemURL(
229 GURL("http://remote"),
230 storage::kFileSystemTypeTemporary,
231 base::FilePath().AppendASCII(dir_name));
232 ASSERT_EQ(
233 base::File::FILE_OK,
234 AsyncFileTestHelper::CreateDirectory(file_system_context_.get(), url));
235 }
236
237 void WriteFile(const base::StringPiece& file_name,
238 const char* buf, int buf_size) {
239 FileSystemURL url = file_system_context_->CreateCrackedFileSystemURL(
240 GURL("http://remote"),
241 storage::kFileSystemTypeTemporary,
242 base::FilePath().AppendASCII(file_name));
243 ASSERT_EQ(base::File::FILE_OK,
244 AsyncFileTestHelper::CreateFileWithData(
245 file_system_context_.get(), url, buf, buf_size));
246 }
247
248 GURL CreateFileSystemURL(const std::string& path) {
249 return GURL(kFileSystemURLPrefix + path);
250 }
251
252 // Temp directory is at the top because it must be deleted last.
253 base::ScopedTempDir temp_dir_;
254
255 // The message loop must be deleted second to last.
256 base::MessageLoopForIO message_loop_;
257
258 scoped_refptr<storage::FileSystemContext> file_system_context_;
259
260 net::URLRequestContext empty_context_;
261 std::unique_ptr<FileSystemURLRequestJobFactory> job_factory_;
262
263 // NOTE: order matters, request must die before delegate
264 std::unique_ptr<net::TestDelegate> delegate_;
265 std::unique_ptr<net::URLRequest> request_;
266
267 base::WeakPtrFactory<FileSystemURLRequestJobTest> weak_factory_;
268 };
269
270 namespace {
271
272 TEST_F(FileSystemURLRequestJobTest, FileTest) {
273 WriteFile("file1.dat", kTestFileData, arraysize(kTestFileData) - 1);
274 TestRequest(CreateFileSystemURL("file1.dat"));
275
276 ASSERT_FALSE(request_->is_pending());
277 EXPECT_EQ(1, delegate_->response_started_count());
278 EXPECT_FALSE(delegate_->received_data_before_response());
279 EXPECT_EQ(kTestFileData, delegate_->data_received());
280 EXPECT_EQ(200, request_->GetResponseCode());
281 std::string cache_control;
282 request_->GetResponseHeaderByName("cache-control", &cache_control);
283 EXPECT_EQ("no-cache", cache_control);
284 }
285
286 TEST_F(FileSystemURLRequestJobTest, FileTestFullSpecifiedRange) {
287 const size_t buffer_size = 4000;
288 std::unique_ptr<char[]> buffer(new char[buffer_size]);
289 FillBuffer(buffer.get(), buffer_size);
290 WriteFile("bigfile", buffer.get(), buffer_size);
291
292 const size_t first_byte_position = 500;
293 const size_t last_byte_position = buffer_size - first_byte_position;
294 std::string partial_buffer_string(buffer.get() + first_byte_position,
295 buffer.get() + last_byte_position + 1);
296
297 net::HttpRequestHeaders headers;
298 headers.SetHeader(
299 net::HttpRequestHeaders::kRange,
300 net::HttpByteRange::Bounded(
301 first_byte_position, last_byte_position).GetHeaderValue());
302 TestRequestWithHeaders(CreateFileSystemURL("bigfile"), &headers);
303
304 ASSERT_FALSE(request_->is_pending());
305 EXPECT_EQ(1, delegate_->response_started_count());
306 EXPECT_FALSE(delegate_->received_data_before_response());
307 EXPECT_TRUE(partial_buffer_string == delegate_->data_received());
308 }
309
310 TEST_F(FileSystemURLRequestJobTest, FileTestHalfSpecifiedRange) {
311 const size_t buffer_size = 4000;
312 std::unique_ptr<char[]> buffer(new char[buffer_size]);
313 FillBuffer(buffer.get(), buffer_size);
314 WriteFile("bigfile", buffer.get(), buffer_size);
315
316 const size_t first_byte_position = 500;
317 std::string partial_buffer_string(buffer.get() + first_byte_position,
318 buffer.get() + buffer_size);
319
320 net::HttpRequestHeaders headers;
321 headers.SetHeader(
322 net::HttpRequestHeaders::kRange,
323 net::HttpByteRange::RightUnbounded(first_byte_position).GetHeaderValue());
324 TestRequestWithHeaders(CreateFileSystemURL("bigfile"), &headers);
325 ASSERT_FALSE(request_->is_pending());
326 EXPECT_EQ(1, delegate_->response_started_count());
327 EXPECT_FALSE(delegate_->received_data_before_response());
328 // Don't use EXPECT_EQ, it will print out a lot of garbage if check failed.
329 EXPECT_TRUE(partial_buffer_string == delegate_->data_received());
330 }
331
332 TEST_F(FileSystemURLRequestJobTest, FileTestMultipleRangesNotSupported) {
333 WriteFile("file1.dat", kTestFileData, arraysize(kTestFileData) - 1);
334 net::HttpRequestHeaders headers;
335 headers.SetHeader(net::HttpRequestHeaders::kRange,
336 "bytes=0-5,10-200,200-300");
337 TestRequestWithHeaders(CreateFileSystemURL("file1.dat"), &headers);
338 EXPECT_TRUE(delegate_->request_failed());
339 EXPECT_EQ(net::ERR_REQUEST_RANGE_NOT_SATISFIABLE,
340 request_->status().error());
341 }
342
343 TEST_F(FileSystemURLRequestJobTest, RangeOutOfBounds) {
344 WriteFile("file1.dat", kTestFileData, arraysize(kTestFileData) - 1);
345 net::HttpRequestHeaders headers;
346 headers.SetHeader(
347 net::HttpRequestHeaders::kRange,
348 net::HttpByteRange::Bounded(500, 1000).GetHeaderValue());
349 TestRequestWithHeaders(CreateFileSystemURL("file1.dat"), &headers);
350
351 ASSERT_FALSE(request_->is_pending());
352 EXPECT_TRUE(delegate_->request_failed());
353 EXPECT_EQ(net::ERR_REQUEST_RANGE_NOT_SATISFIABLE,
354 request_->status().error());
355 }
356
357 TEST_F(FileSystemURLRequestJobTest, FileDirRedirect) {
358 CreateDirectory("dir");
359 TestRequest(CreateFileSystemURL("dir"));
360
361 EXPECT_EQ(1, delegate_->received_redirect_count());
362 EXPECT_TRUE(request_->status().is_success());
363 EXPECT_FALSE(delegate_->request_failed());
364
365 // We've deferred the redirect; now cancel the request to avoid following it.
366 request_->Cancel();
367 base::RunLoop().Run();
368 }
369
370 TEST_F(FileSystemURLRequestJobTest, InvalidURL) {
371 TestRequest(GURL("filesystem:/foo/bar/baz"));
372 ASSERT_FALSE(request_->is_pending());
373 EXPECT_TRUE(delegate_->request_failed());
374 EXPECT_EQ(net::ERR_INVALID_URL, request_->status().error());
375 }
376
377 TEST_F(FileSystemURLRequestJobTest, NoSuchRoot) {
378 TestRequest(GURL("filesystem:http://remote/persistent/somefile"));
379 ASSERT_FALSE(request_->is_pending());
380 EXPECT_TRUE(delegate_->request_failed());
381 EXPECT_EQ(net::ERR_FILE_NOT_FOUND, request_->status().error());
382 }
383
384 TEST_F(FileSystemURLRequestJobTest, NoSuchFile) {
385 TestRequest(CreateFileSystemURL("somefile"));
386 ASSERT_FALSE(request_->is_pending());
387 EXPECT_TRUE(delegate_->request_failed());
388 EXPECT_EQ(net::ERR_FILE_NOT_FOUND, request_->status().error());
389 }
390
391 TEST_F(FileSystemURLRequestJobTest, Cancel) {
392 WriteFile("file1.dat", kTestFileData, arraysize(kTestFileData) - 1);
393 TestRequestNoRun(CreateFileSystemURL("file1.dat"));
394
395 // Run StartAsync() and only StartAsync().
396 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE,
397 request_.release());
398 base::RunLoop().RunUntilIdle();
399 // If we get here, success! we didn't crash!
400 }
401
402 TEST_F(FileSystemURLRequestJobTest, GetMimeType) {
403 const char kFilename[] = "hoge.html";
404
405 std::string mime_type_direct;
406 base::FilePath::StringType extension =
407 base::FilePath().AppendASCII(kFilename).Extension();
408 if (!extension.empty())
409 extension = extension.substr(1);
410 EXPECT_TRUE(net::GetWellKnownMimeTypeFromExtension(
411 extension, &mime_type_direct));
412
413 TestRequest(CreateFileSystemURL(kFilename));
414
415 std::string mime_type_from_job;
416 request_->GetMimeType(&mime_type_from_job);
417 EXPECT_EQ(mime_type_direct, mime_type_from_job);
418 }
419
420 TEST_F(FileSystemURLRequestJobTest, Incognito) {
421 WriteFile("file", kTestFileData, arraysize(kTestFileData) - 1);
422
423 // Creates a new filesystem context for incognito mode.
424 scoped_refptr<FileSystemContext> file_system_context =
425 CreateIncognitoFileSystemContextForTesting(NULL, temp_dir_.GetPath());
426
427 // The request should return NOT_FOUND error if it's in incognito mode.
428 TestRequestWithContext(CreateFileSystemURL("file"),
429 file_system_context.get());
430 ASSERT_FALSE(request_->is_pending());
431 EXPECT_TRUE(delegate_->request_failed());
432 EXPECT_EQ(net::ERR_FILE_NOT_FOUND, request_->status().error());
433
434 // Make sure it returns success with regular (non-incognito) context.
435 TestRequest(CreateFileSystemURL("file"));
436 ASSERT_FALSE(request_->is_pending());
437 EXPECT_EQ(kTestFileData, delegate_->data_received());
438 EXPECT_EQ(200, request_->GetResponseCode());
439 }
440
441 TEST_F(FileSystemURLRequestJobTest, AutoMountFileTest) {
442 SetUpAutoMountContext();
443 TestRequest(GURL("filesystem:http://automount/external/mnt_name/foo"));
444
445 ASSERT_FALSE(request_->is_pending());
446 EXPECT_EQ(1, delegate_->response_started_count());
447 EXPECT_FALSE(delegate_->received_data_before_response());
448 EXPECT_EQ(kTestFileData, delegate_->data_received());
449 EXPECT_EQ(200, request_->GetResponseCode());
450 std::string cache_control;
451 request_->GetResponseHeaderByName("cache-control", &cache_control);
452 EXPECT_EQ("no-cache", cache_control);
453
454 ASSERT_TRUE(
455 storage::ExternalMountPoints::GetSystemInstance()->RevokeFileSystem(
456 kValidExternalMountPoint));
457 }
458
459 TEST_F(FileSystemURLRequestJobTest, AutoMountInvalidRoot) {
460 SetUpAutoMountContext();
461 TestRequest(GURL("filesystem:http://automount/external/invalid/foo"));
462
463 ASSERT_FALSE(request_->is_pending());
464 EXPECT_TRUE(delegate_->request_failed());
465 EXPECT_EQ(net::ERR_FILE_NOT_FOUND, request_->status().error());
466
467 ASSERT_FALSE(
468 storage::ExternalMountPoints::GetSystemInstance()->RevokeFileSystem(
469 "invalid"));
470 }
471
472 TEST_F(FileSystemURLRequestJobTest, AutoMountNoHandler) {
473 SetUpAutoMountContext();
474 TestRequest(GURL("filesystem:http://noauto/external/mnt_name/foo"));
475
476 ASSERT_FALSE(request_->is_pending());
477 EXPECT_TRUE(delegate_->request_failed());
478 EXPECT_EQ(net::ERR_FILE_NOT_FOUND, request_->status().error());
479
480 ASSERT_FALSE(
481 storage::ExternalMountPoints::GetSystemInstance()->RevokeFileSystem(
482 kValidExternalMountPoint));
483 }
484
485 } // namespace
486 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/fileapi/file_system_quota_client_unittest.cc ('k') | content/browser/fileapi/file_system_url_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698