Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / chrome / browser / chromeos / drive / drive_file_stream_reader_unittest.cc
blob42b7b6031830de784fe012ca76847a5e00b954fa
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.
5 #include "chrome/browser/chromeos/drive/drive_file_stream_reader.h"
7 #include <string>
9 #include "base/bind.h"
10 #include "base/files/file_path.h"
11 #include "base/files/scoped_temp_dir.h"
12 #include "base/run_loop.h"
13 #include "base/threading/thread.h"
14 #include "chrome/browser/chromeos/drive/fake_file_system.h"
15 #include "chrome/browser/chromeos/drive/file_system_util.h"
16 #include "chrome/browser/chromeos/drive/local_file_reader.h"
17 #include "chrome/browser/chromeos/drive/test_util.h"
18 #include "chrome/browser/drive/fake_drive_service.h"
19 #include "chrome/browser/drive/test_util.h"
20 #include "content/public/test/test_browser_thread_bundle.h"
21 #include "content/public/test/test_utils.h"
22 #include "google_apis/drive/drive_api_parser.h"
23 #include "google_apis/drive/test_util.h"
24 #include "net/base/io_buffer.h"
25 #include "net/base/net_errors.h"
26 #include "net/base/test_completion_callback.h"
27 #include "net/http/http_byte_range.h"
28 #include "testing/gtest/include/gtest/gtest.h"
30 namespace drive {
31 namespace internal {
32 namespace {
34 // Increments the |num_called|, when this method is invoked.
35 void IncrementCallback(int* num_called) {
36 DCHECK(num_called);
37 ++*num_called;
40 } // namespace
42 class LocalReaderProxyTest : public ::testing::Test {
43 protected:
44 LocalReaderProxyTest()
45 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {
48 void SetUp() override {
49 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
50 ASSERT_TRUE(google_apis::test_util::CreateFileOfSpecifiedSize(
51 temp_dir_.path(), 1024, &file_path_, &file_content_));
53 worker_thread_.reset(new base::Thread("ReaderProxyTest"));
54 ASSERT_TRUE(worker_thread_->Start());
57 content::TestBrowserThreadBundle thread_bundle_;
59 base::ScopedTempDir temp_dir_;
60 base::FilePath file_path_;
61 std::string file_content_;
63 scoped_ptr<base::Thread> worker_thread_;
66 TEST_F(LocalReaderProxyTest, Read) {
67 // Open the file first.
68 scoped_ptr<util::LocalFileReader> file_reader(
69 new util::LocalFileReader(worker_thread_->message_loop_proxy().get()));
70 net::TestCompletionCallback callback;
71 file_reader->Open(file_path_, 0, callback.callback());
72 ASSERT_EQ(net::OK, callback.WaitForResult());
74 // Test instance.
75 LocalReaderProxy proxy(file_reader.Pass(), file_content_.size());
77 // Make sure the read content is as same as the file.
78 std::string content;
79 ASSERT_EQ(net::OK, test_util::ReadAllData(&proxy, &content));
80 EXPECT_EQ(file_content_, content);
83 TEST_F(LocalReaderProxyTest, ReadWithLimit) {
84 // This test case, we only read first half of the file.
85 const std::string expected_content =
86 file_content_.substr(0, file_content_.size() / 2);
88 // Open the file first.
89 scoped_ptr<util::LocalFileReader> file_reader(
90 new util::LocalFileReader(worker_thread_->message_loop_proxy().get()));
91 net::TestCompletionCallback callback;
92 file_reader->Open(file_path_, 0, callback.callback());
93 ASSERT_EQ(net::OK, callback.WaitForResult());
95 // Test instance.
96 LocalReaderProxy proxy(file_reader.Pass(), expected_content.size());
98 // Make sure the read content is as same as the file.
99 std::string content;
100 ASSERT_EQ(net::OK, test_util::ReadAllData(&proxy, &content));
101 EXPECT_EQ(expected_content, content);
104 class NetworkReaderProxyTest : public ::testing::Test {
105 protected:
106 NetworkReaderProxyTest()
107 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {
110 content::TestBrowserThreadBundle thread_bundle_;
113 TEST_F(NetworkReaderProxyTest, EmptyFile) {
114 NetworkReaderProxy proxy(0, 0, 0, base::Bind(&base::DoNothing));
116 net::TestCompletionCallback callback;
117 const int kBufferSize = 10;
118 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize));
119 int result = proxy.Read(buffer.get(), kBufferSize, callback.callback());
121 // For empty file, Read() should return 0 immediately.
122 EXPECT_EQ(0, result);
125 TEST_F(NetworkReaderProxyTest, Read) {
126 int cancel_called = 0;
128 NetworkReaderProxy proxy(0, 10, 10,
129 base::Bind(&IncrementCallback, &cancel_called));
131 net::TestCompletionCallback callback;
132 const int kBufferSize = 3;
133 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize));
135 // If no data is available yet, ERR_IO_PENDING should be returned.
136 int result = proxy.Read(buffer.get(), kBufferSize, callback.callback());
137 EXPECT_EQ(net::ERR_IO_PENDING, result);
139 // And when the data is supplied, the callback will be called.
140 scoped_ptr<std::string> data(new std::string("abcde"));
141 proxy.OnGetContent(data.Pass());
143 // The returned data should be fit to the buffer size.
144 result = callback.GetResult(result);
145 EXPECT_EQ(3, result);
146 EXPECT_EQ("abc", std::string(buffer->data(), result));
148 // The next Read should return immediately because there is pending data
149 result = proxy.Read(buffer.get(), kBufferSize, callback.callback());
150 EXPECT_EQ(2, result);
151 EXPECT_EQ("de", std::string(buffer->data(), result));
153 // Supply the data before calling Read operation.
154 data.reset(new std::string("fg"));
155 proxy.OnGetContent(data.Pass());
156 data.reset(new std::string("hij"));
157 proxy.OnGetContent(data.Pass()); // Now 10 bytes are supplied.
159 // The data should be concatenated if possible.
160 result = proxy.Read(buffer.get(), kBufferSize, callback.callback());
161 EXPECT_EQ(3, result);
162 EXPECT_EQ("fgh", std::string(buffer->data(), result));
164 result = proxy.Read(buffer.get(), kBufferSize, callback.callback());
165 EXPECT_EQ(2, result);
166 EXPECT_EQ("ij", std::string(buffer->data(), result));
168 // The whole data is read, so Read() should return 0 immediately by then.
169 result = proxy.Read(buffer.get(), kBufferSize, callback.callback());
170 EXPECT_EQ(0, result);
173 // Proxy is deleted without any called to OnCompleted(). Even in the case,
174 // cancel callback should not be invoked.
175 EXPECT_EQ(0, cancel_called);
178 TEST_F(NetworkReaderProxyTest, ReadWithLimit) {
179 NetworkReaderProxy proxy(10, 10, 10, base::Bind(&base::DoNothing));
181 net::TestCompletionCallback callback;
182 const int kBufferSize = 3;
183 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize));
185 // If no data is available yet, ERR_IO_PENDING should be returned.
186 int result = proxy.Read(buffer.get(), kBufferSize, callback.callback());
187 EXPECT_EQ(net::ERR_IO_PENDING, result);
189 // And when the data is supplied, the callback will be called.
190 scoped_ptr<std::string> data(new std::string("abcde"));
191 proxy.OnGetContent(data.Pass());
192 data.reset(new std::string("fgh"));
193 proxy.OnGetContent(data.Pass());
194 data.reset(new std::string("ijklmno"));
195 proxy.OnGetContent(data.Pass());
197 // The returned data should be fit to the buffer size.
198 result = callback.GetResult(result);
199 EXPECT_EQ(3, result);
200 EXPECT_EQ("klm", std::string(buffer->data(), result));
202 // The next Read should return immediately because there is pending data
203 result = proxy.Read(buffer.get(), kBufferSize, callback.callback());
204 EXPECT_EQ(2, result);
205 EXPECT_EQ("no", std::string(buffer->data(), result));
207 // Supply the data before calling Read operation.
208 data.reset(new std::string("pqrs"));
209 proxy.OnGetContent(data.Pass());
210 data.reset(new std::string("tuvwxyz"));
211 proxy.OnGetContent(data.Pass()); // 't' is the 20-th byte.
213 // The data should be concatenated if possible.
214 result = proxy.Read(buffer.get(), kBufferSize, callback.callback());
215 EXPECT_EQ(3, result);
216 EXPECT_EQ("pqr", std::string(buffer->data(), result));
218 result = proxy.Read(buffer.get(), kBufferSize, callback.callback());
219 EXPECT_EQ(2, result);
220 EXPECT_EQ("st", std::string(buffer->data(), result));
222 // The whole data is read, so Read() should return 0 immediately by then.
223 result = proxy.Read(buffer.get(), kBufferSize, callback.callback());
224 EXPECT_EQ(0, result);
227 TEST_F(NetworkReaderProxyTest, ErrorWithPendingCallback) {
228 NetworkReaderProxy proxy(0, 10, 10, base::Bind(&base::DoNothing));
230 net::TestCompletionCallback callback;
231 const int kBufferSize = 3;
232 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize));
234 // Set pending callback.
235 int result = proxy.Read(buffer.get(), kBufferSize, callback.callback());
236 EXPECT_EQ(net::ERR_IO_PENDING, result);
238 // Emulate that an error is found. The callback should be called internally.
239 proxy.OnCompleted(FILE_ERROR_FAILED);
240 result = callback.GetResult(result);
241 EXPECT_EQ(net::ERR_FAILED, result);
243 // The next Read call should also return the same error code.
244 EXPECT_EQ(net::ERR_FAILED,
245 proxy.Read(buffer.get(), kBufferSize, callback.callback()));
248 TEST_F(NetworkReaderProxyTest, ErrorWithPendingData) {
249 NetworkReaderProxy proxy(0, 10, 10, base::Bind(&base::DoNothing));
251 net::TestCompletionCallback callback;
252 const int kBufferSize = 3;
253 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize));
255 // Supply the data before an error.
256 scoped_ptr<std::string> data(new std::string("abcde"));
257 proxy.OnGetContent(data.Pass());
259 // Emulate that an error is found.
260 proxy.OnCompleted(FILE_ERROR_FAILED);
262 // The next Read call should return the error code, even if there is
263 // pending data (the pending data should be released in OnCompleted.
264 EXPECT_EQ(net::ERR_FAILED,
265 proxy.Read(buffer.get(), kBufferSize, callback.callback()));
268 TEST_F(NetworkReaderProxyTest, CancelJob) {
269 int num_called = 0;
271 NetworkReaderProxy proxy(
272 0, 0, 0, base::Bind(&IncrementCallback, &num_called));
273 proxy.OnCompleted(FILE_ERROR_OK);
274 // Destroy the instance after the network operation is completed.
275 // The cancelling callback shouldn't be called.
277 EXPECT_EQ(0, num_called);
279 num_called = 0;
281 NetworkReaderProxy proxy(
282 0, 0, 0, base::Bind(&IncrementCallback, &num_called));
283 // Destroy the instance before the network operation is completed.
284 // The cancelling callback should be called.
286 EXPECT_EQ(1, num_called);
289 } // namespace internal
291 class DriveFileStreamReaderTest : public ::testing::Test {
292 protected:
293 DriveFileStreamReaderTest()
294 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {
297 void SetUp() override {
298 worker_thread_.reset(new base::Thread("DriveFileStreamReaderTest"));
299 ASSERT_TRUE(worker_thread_->Start());
301 // Initialize FakeDriveService.
302 fake_drive_service_.reset(new FakeDriveService);
303 ASSERT_TRUE(test_util::SetUpTestEntries(fake_drive_service_.get()));
305 // Create a testee instance.
306 fake_file_system_.reset(
307 new test_util::FakeFileSystem(fake_drive_service_.get()));
310 FileSystemInterface* GetFileSystem() {
311 return fake_file_system_.get();
314 DriveFileStreamReader::FileSystemGetter GetFileSystemGetter() {
315 return base::Bind(&DriveFileStreamReaderTest::GetFileSystem,
316 base::Unretained(this));
319 content::TestBrowserThreadBundle thread_bundle_;
321 scoped_ptr<base::Thread> worker_thread_;
323 scoped_ptr<FakeDriveService> fake_drive_service_;
324 scoped_ptr<test_util::FakeFileSystem> fake_file_system_;
327 TEST_F(DriveFileStreamReaderTest, Read) {
328 const base::FilePath kDriveFile =
329 util::GetDriveMyDriveRootPath().AppendASCII("File 1.txt");
330 // Create the reader, and initialize it.
331 // In this case, the file is not yet locally cached.
332 scoped_ptr<DriveFileStreamReader> reader(new DriveFileStreamReader(
333 GetFileSystemGetter(), worker_thread_->message_loop_proxy().get()));
334 EXPECT_FALSE(reader->IsInitialized());
336 int error = net::ERR_FAILED;
337 scoped_ptr<ResourceEntry> entry;
339 base::RunLoop run_loop;
340 reader->Initialize(
341 kDriveFile,
342 net::HttpByteRange(),
343 google_apis::test_util::CreateQuitCallback(
344 &run_loop,
345 google_apis::test_util::CreateCopyResultCallback(&error, &entry)));
346 run_loop.Run();
348 EXPECT_EQ(net::OK, error);
349 ASSERT_TRUE(entry);
350 EXPECT_TRUE(reader->IsInitialized());
351 size_t content_size = entry->file_info().size();
353 // Read data from the reader.
354 std::string first_content;
355 ASSERT_EQ(net::OK, test_util::ReadAllData(reader.get(), &first_content));
356 EXPECT_EQ(content_size, first_content.size());
358 // Create second instance and initialize it.
359 // In this case, the file should be cached one.
360 reader.reset(new DriveFileStreamReader(
361 GetFileSystemGetter(), worker_thread_->message_loop_proxy().get()));
362 EXPECT_FALSE(reader->IsInitialized());
364 error = net::ERR_FAILED;
365 entry.reset();
367 base::RunLoop run_loop;
368 reader->Initialize(
369 kDriveFile,
370 net::HttpByteRange(),
371 google_apis::test_util::CreateQuitCallback(
372 &run_loop,
373 google_apis::test_util::CreateCopyResultCallback(&error, &entry)));
374 run_loop.Run();
376 EXPECT_EQ(net::OK, error);
377 ASSERT_TRUE(entry);
378 EXPECT_TRUE(reader->IsInitialized());
380 // The size should be same.
381 EXPECT_EQ(content_size, static_cast<size_t>(entry->file_info().size()));
383 // Read data from the reader, again.
384 std::string second_content;
385 ASSERT_EQ(net::OK, test_util::ReadAllData(reader.get(), &second_content));
387 // The same content is expected.
388 EXPECT_EQ(first_content, second_content);
391 TEST_F(DriveFileStreamReaderTest, ReadRange) {
392 // In this test case, we just confirm that the part of file is read.
393 const int64 kRangeOffset = 3;
394 const int64 kRangeLength = 4;
396 const base::FilePath kDriveFile =
397 util::GetDriveMyDriveRootPath().AppendASCII("File 1.txt");
398 // Create the reader, and initialize it.
399 // In this case, the file is not yet locally cached.
400 scoped_ptr<DriveFileStreamReader> reader(new DriveFileStreamReader(
401 GetFileSystemGetter(), worker_thread_->message_loop_proxy().get()));
402 EXPECT_FALSE(reader->IsInitialized());
404 int error = net::ERR_FAILED;
405 scoped_ptr<ResourceEntry> entry;
406 net::HttpByteRange byte_range;
407 byte_range.set_first_byte_position(kRangeOffset);
408 // Last byte position is inclusive.
409 byte_range.set_last_byte_position(kRangeOffset + kRangeLength - 1);
411 base::RunLoop run_loop;
412 reader->Initialize(
413 kDriveFile,
414 byte_range,
415 google_apis::test_util::CreateQuitCallback(
416 &run_loop,
417 google_apis::test_util::CreateCopyResultCallback(&error, &entry)));
418 run_loop.Run();
420 EXPECT_EQ(net::OK, error);
421 ASSERT_TRUE(entry);
422 EXPECT_TRUE(reader->IsInitialized());
424 // Read data from the reader.
425 std::string first_content;
426 ASSERT_EQ(net::OK, test_util::ReadAllData(reader.get(), &first_content));
428 // The length should be equal to range length.
429 EXPECT_EQ(kRangeLength, static_cast<int64>(first_content.size()));
431 // Create second instance and initialize it.
432 // In this case, the file should be cached one.
433 reader.reset(new DriveFileStreamReader(
434 GetFileSystemGetter(), worker_thread_->message_loop_proxy().get()));
435 EXPECT_FALSE(reader->IsInitialized());
437 error = net::ERR_FAILED;
438 entry.reset();
440 base::RunLoop run_loop;
441 reader->Initialize(
442 kDriveFile,
443 byte_range,
444 google_apis::test_util::CreateQuitCallback(
445 &run_loop,
446 google_apis::test_util::CreateCopyResultCallback(&error, &entry)));
447 run_loop.Run();
449 EXPECT_EQ(net::OK, error);
450 ASSERT_TRUE(entry);
451 EXPECT_TRUE(reader->IsInitialized());
453 // Read data from the reader, again.
454 std::string second_content;
455 ASSERT_EQ(net::OK, test_util::ReadAllData(reader.get(), &second_content));
457 // The same content is expected.
458 EXPECT_EQ(first_content, second_content);
461 TEST_F(DriveFileStreamReaderTest, OutOfRangeError) {
462 const int64 kRangeOffset = 1000000; // Out of range.
463 const int64 kRangeLength = 4;
465 const base::FilePath kDriveFile =
466 util::GetDriveMyDriveRootPath().AppendASCII("File 1.txt");
467 // Create the reader, and initialize it.
468 // In this case, the file is not yet locally cached.
469 scoped_ptr<DriveFileStreamReader> reader(new DriveFileStreamReader(
470 GetFileSystemGetter(), worker_thread_->message_loop_proxy().get()));
471 EXPECT_FALSE(reader->IsInitialized());
473 int error = net::ERR_FAILED;
474 scoped_ptr<ResourceEntry> entry;
475 net::HttpByteRange byte_range;
476 byte_range.set_first_byte_position(kRangeOffset);
477 // Last byte position is inclusive.
478 byte_range.set_last_byte_position(kRangeOffset + kRangeLength - 1);
480 base::RunLoop run_loop;
481 reader->Initialize(
482 kDriveFile,
483 byte_range,
484 google_apis::test_util::CreateQuitCallback(
485 &run_loop,
486 google_apis::test_util::CreateCopyResultCallback(&error, &entry)));
487 run_loop.Run();
489 EXPECT_EQ(net::ERR_REQUEST_RANGE_NOT_SATISFIABLE, error);
490 EXPECT_FALSE(entry);
493 TEST_F(DriveFileStreamReaderTest, ZeroByteFileRead) {
494 // Prepare an empty file
496 google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR;
497 scoped_ptr<google_apis::FileResource> entry;
498 fake_drive_service_->AddNewFile(
499 "text/plain",
500 "", // empty
501 fake_drive_service_->GetRootResourceId(),
502 "EmptyFile.txt",
503 false, // shared_with_me
504 google_apis::test_util::CreateCopyResultCallback(&error, &entry));
505 content::RunAllBlockingPoolTasksUntilIdle();
506 ASSERT_EQ(google_apis::HTTP_CREATED, error);
507 ASSERT_TRUE(entry);
508 ASSERT_EQ(0, entry->file_size());
511 const base::FilePath kDriveFile =
512 util::GetDriveMyDriveRootPath().AppendASCII("EmptyFile.txt");
513 // Create the reader, and initialize it.
514 // In this case, the file is not yet locally cached.
515 scoped_ptr<DriveFileStreamReader> reader(new DriveFileStreamReader(
516 GetFileSystemGetter(), worker_thread_->message_loop_proxy().get()));
517 EXPECT_FALSE(reader->IsInitialized());
519 int error = net::ERR_FAILED;
520 scoped_ptr<ResourceEntry> entry;
522 base::RunLoop run_loop;
523 reader->Initialize(
524 kDriveFile,
525 net::HttpByteRange(),
526 google_apis::test_util::CreateQuitCallback(
527 &run_loop,
528 google_apis::test_util::CreateCopyResultCallback(&error, &entry)));
529 run_loop.Run();
531 EXPECT_EQ(net::OK, error);
532 ASSERT_TRUE(entry);
533 ASSERT_EQ(0u, entry->file_info().size()); // It's a zero-byte file.
534 EXPECT_TRUE(reader->IsInitialized());
536 // Read data from the reader. Check that it successfuly reads empty data.
537 std::string first_content;
538 ASSERT_EQ(net::OK, test_util::ReadAllData(reader.get(), &first_content));
539 EXPECT_EQ(0u, first_content.size());
541 // Create second instance and initialize it.
542 // In this case, the file should be cached one.
543 reader.reset(new DriveFileStreamReader(
544 GetFileSystemGetter(), worker_thread_->message_loop_proxy().get()));
545 EXPECT_FALSE(reader->IsInitialized());
547 error = net::ERR_FAILED;
548 entry.reset();
550 base::RunLoop run_loop;
551 reader->Initialize(
552 kDriveFile,
553 net::HttpByteRange(),
554 google_apis::test_util::CreateQuitCallback(
555 &run_loop,
556 google_apis::test_util::CreateCopyResultCallback(&error, &entry)));
557 run_loop.Run();
559 EXPECT_EQ(net::OK, error);
560 ASSERT_TRUE(entry);
561 EXPECT_TRUE(reader->IsInitialized());
563 // Read data from the reader, again.
564 std::string second_content;
565 ASSERT_EQ(net::OK, test_util::ReadAllData(reader.get(), &second_content));
566 EXPECT_EQ(0u, second_content.size());
569 } // namespace drive