Move encrypted media content browser tests into browser tests.
[chromium-blink-merge.git] / net / base / file_stream_unittest.cc
blob8eed06e0694c408e2b9eb1f65c450d0d1f06302f
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
3 // found in the LICENSE file.
5 #include "net/base/file_stream.h"
7 #include "base/bind.h"
8 #include "base/callback.h"
9 #include "base/file_util.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/message_loop/message_loop_proxy.h"
12 #include "base/path_service.h"
13 #include "base/platform_file.h"
14 #include "base/run_loop.h"
15 #include "base/synchronization/waitable_event.h"
16 #include "base/test/test_timeouts.h"
17 #include "net/base/capturing_net_log.h"
18 #include "net/base/io_buffer.h"
19 #include "net/base/net_errors.h"
20 #include "net/base/test_completion_callback.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22 #include "testing/platform_test.h"
24 namespace net {
26 namespace {
28 const char kTestData[] = "0123456789";
29 const int kTestDataSize = arraysize(kTestData) - 1;
31 // Creates an IOBufferWithSize that contains the kTestDataSize.
32 IOBufferWithSize* CreateTestDataBuffer() {
33 IOBufferWithSize* buf = new IOBufferWithSize(kTestDataSize);
34 memcpy(buf->data(), kTestData, kTestDataSize);
35 return buf;
38 } // namespace
40 class FileStreamTest : public PlatformTest {
41 public:
42 virtual void SetUp() {
43 PlatformTest::SetUp();
45 file_util::CreateTemporaryFile(&temp_file_path_);
46 file_util::WriteFile(temp_file_path_, kTestData, kTestDataSize);
48 virtual void TearDown() {
49 EXPECT_TRUE(base::DeleteFile(temp_file_path_, false));
51 // FileStreamContexts must be asynchronously closed on the file task runner
52 // before they can be deleted. Pump the RunLoop to avoid leaks.
53 base::RunLoop().RunUntilIdle();
54 PlatformTest::TearDown();
57 const base::FilePath temp_file_path() const { return temp_file_path_; }
59 private:
60 base::FilePath temp_file_path_;
63 namespace {
65 TEST_F(FileStreamTest, BasicOpenClose) {
66 base::PlatformFile file = base::kInvalidPlatformFileValue;
68 FileStream stream(NULL, base::MessageLoopProxy::current());
69 int rv = stream.OpenSync(temp_file_path(),
70 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ);
71 EXPECT_EQ(OK, rv);
72 EXPECT_TRUE(stream.IsOpen());
73 file = stream.GetPlatformFileForTesting();
75 EXPECT_NE(base::kInvalidPlatformFileValue, file);
76 base::PlatformFileInfo info;
77 // The file should be closed.
78 EXPECT_FALSE(base::GetPlatformFileInfo(file, &info));
81 TEST_F(FileStreamTest, FileHandleNotLeftOpen) {
82 bool created = false;
83 ASSERT_EQ(kTestDataSize,
84 file_util::WriteFile(temp_file_path(), kTestData, kTestDataSize));
85 int flags = base::PLATFORM_FILE_OPEN_ALWAYS | base::PLATFORM_FILE_READ;
86 base::PlatformFile file = base::CreatePlatformFile(
87 temp_file_path(), flags, &created, NULL);
90 // Seek to the beginning of the file and read.
91 FileStream read_stream(file, flags, NULL,
92 base::MessageLoopProxy::current());
93 EXPECT_TRUE(read_stream.IsOpen());
96 EXPECT_NE(base::kInvalidPlatformFileValue, file);
97 base::PlatformFileInfo info;
98 // The file should be closed.
99 EXPECT_FALSE(base::GetPlatformFileInfo(file, &info));
102 // Test the use of FileStream with a file handle provided at construction.
103 TEST_F(FileStreamTest, UseFileHandle) {
104 bool created = false;
106 // 1. Test reading with a file handle.
107 ASSERT_EQ(kTestDataSize,
108 file_util::WriteFile(temp_file_path(), kTestData, kTestDataSize));
109 int flags = base::PLATFORM_FILE_OPEN_ALWAYS | base::PLATFORM_FILE_READ;
110 base::PlatformFile file = base::CreatePlatformFile(
111 temp_file_path(), flags, &created, NULL);
113 // Seek to the beginning of the file and read.
114 scoped_ptr<FileStream> read_stream(
115 new FileStream(file, flags, NULL, base::MessageLoopProxy::current()));
116 ASSERT_EQ(0, read_stream->SeekSync(FROM_BEGIN, 0));
117 ASSERT_EQ(kTestDataSize, read_stream->Available());
118 // Read into buffer and compare.
119 char buffer[kTestDataSize];
120 ASSERT_EQ(kTestDataSize,
121 read_stream->ReadSync(buffer, kTestDataSize));
122 ASSERT_EQ(0, memcmp(kTestData, buffer, kTestDataSize));
123 read_stream.reset();
125 // 2. Test writing with a file handle.
126 base::DeleteFile(temp_file_path(), false);
127 flags = base::PLATFORM_FILE_OPEN_ALWAYS | base::PLATFORM_FILE_WRITE;
128 file = base::CreatePlatformFile(temp_file_path(), flags, &created, NULL);
130 scoped_ptr<FileStream> write_stream(
131 new FileStream(file, flags, NULL, base::MessageLoopProxy::current()));
132 ASSERT_EQ(0, write_stream->SeekSync(FROM_BEGIN, 0));
133 ASSERT_EQ(kTestDataSize,
134 write_stream->WriteSync(kTestData, kTestDataSize));
135 write_stream.reset();
137 // Read into buffer and compare to make sure the handle worked fine.
138 ASSERT_EQ(kTestDataSize,
139 file_util::ReadFile(temp_file_path(), buffer, kTestDataSize));
140 ASSERT_EQ(0, memcmp(kTestData, buffer, kTestDataSize));
143 TEST_F(FileStreamTest, UseClosedStream) {
144 FileStream stream(NULL, base::MessageLoopProxy::current());
146 EXPECT_FALSE(stream.IsOpen());
148 // Try seeking...
149 int64 new_offset = stream.SeekSync(FROM_BEGIN, 5);
150 EXPECT_EQ(ERR_UNEXPECTED, new_offset);
152 // Try available...
153 int64 avail = stream.Available();
154 EXPECT_EQ(ERR_UNEXPECTED, avail);
156 // Try reading...
157 char buf[10];
158 int rv = stream.ReadSync(buf, arraysize(buf));
159 EXPECT_EQ(ERR_UNEXPECTED, rv);
162 TEST_F(FileStreamTest, BasicRead) {
163 int64 file_size;
164 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
165 EXPECT_TRUE(ok);
167 FileStream stream(NULL, base::MessageLoopProxy::current());
168 int flags = base::PLATFORM_FILE_OPEN |
169 base::PLATFORM_FILE_READ;
170 int rv = stream.OpenSync(temp_file_path(), flags);
171 EXPECT_EQ(OK, rv);
173 int64 total_bytes_avail = stream.Available();
174 EXPECT_EQ(file_size, total_bytes_avail);
176 int total_bytes_read = 0;
178 std::string data_read;
179 for (;;) {
180 char buf[4];
181 rv = stream.ReadSync(buf, arraysize(buf));
182 EXPECT_LE(0, rv);
183 if (rv <= 0)
184 break;
185 total_bytes_read += rv;
186 data_read.append(buf, rv);
188 EXPECT_EQ(file_size, total_bytes_read);
189 EXPECT_EQ(kTestData, data_read);
192 TEST_F(FileStreamTest, AsyncRead) {
193 int64 file_size;
194 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
195 EXPECT_TRUE(ok);
197 FileStream stream(NULL, base::MessageLoopProxy::current());
198 int flags = base::PLATFORM_FILE_OPEN |
199 base::PLATFORM_FILE_READ |
200 base::PLATFORM_FILE_ASYNC;
201 TestCompletionCallback callback;
202 int rv = stream.Open(temp_file_path(), flags, callback.callback());
203 EXPECT_EQ(ERR_IO_PENDING, rv);
204 EXPECT_EQ(OK, callback.WaitForResult());
206 int64 total_bytes_avail = stream.Available();
207 EXPECT_EQ(file_size, total_bytes_avail);
209 int total_bytes_read = 0;
211 std::string data_read;
212 for (;;) {
213 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
214 rv = stream.Read(buf.get(), buf->size(), callback.callback());
215 if (rv == ERR_IO_PENDING)
216 rv = callback.WaitForResult();
217 EXPECT_LE(0, rv);
218 if (rv <= 0)
219 break;
220 total_bytes_read += rv;
221 data_read.append(buf->data(), rv);
223 EXPECT_EQ(file_size, total_bytes_read);
224 EXPECT_EQ(kTestData, data_read);
227 TEST_F(FileStreamTest, AsyncRead_EarlyDelete) {
228 int64 file_size;
229 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
230 EXPECT_TRUE(ok);
232 scoped_ptr<FileStream> stream(
233 new FileStream(NULL, base::MessageLoopProxy::current()));
234 int flags = base::PLATFORM_FILE_OPEN |
235 base::PLATFORM_FILE_READ |
236 base::PLATFORM_FILE_ASYNC;
237 TestCompletionCallback callback;
238 int rv = stream->Open(temp_file_path(), flags, callback.callback());
239 EXPECT_EQ(ERR_IO_PENDING, rv);
240 EXPECT_EQ(OK, callback.WaitForResult());
242 int64 total_bytes_avail = stream->Available();
243 EXPECT_EQ(file_size, total_bytes_avail);
245 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
246 rv = stream->Read(buf.get(), buf->size(), callback.callback());
247 stream.reset(); // Delete instead of closing it.
248 if (rv < 0) {
249 EXPECT_EQ(ERR_IO_PENDING, rv);
250 // The callback should not be called if the request is cancelled.
251 base::RunLoop().RunUntilIdle();
252 EXPECT_FALSE(callback.have_result());
253 } else {
254 EXPECT_EQ(std::string(kTestData, rv), std::string(buf->data(), rv));
258 TEST_F(FileStreamTest, BasicRead_FromOffset) {
259 int64 file_size;
260 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
261 EXPECT_TRUE(ok);
263 FileStream stream(NULL, base::MessageLoopProxy::current());
264 int flags = base::PLATFORM_FILE_OPEN |
265 base::PLATFORM_FILE_READ;
266 int rv = stream.OpenSync(temp_file_path(), flags);
267 EXPECT_EQ(OK, rv);
269 const int64 kOffset = 3;
270 int64 new_offset = stream.SeekSync(FROM_BEGIN, kOffset);
271 EXPECT_EQ(kOffset, new_offset);
273 int64 total_bytes_avail = stream.Available();
274 EXPECT_EQ(file_size - kOffset, total_bytes_avail);
276 int64 total_bytes_read = 0;
278 std::string data_read;
279 for (;;) {
280 char buf[4];
281 rv = stream.ReadSync(buf, arraysize(buf));
282 EXPECT_LE(0, rv);
283 if (rv <= 0)
284 break;
285 total_bytes_read += rv;
286 data_read.append(buf, rv);
288 EXPECT_EQ(file_size - kOffset, total_bytes_read);
289 EXPECT_TRUE(data_read == kTestData + kOffset);
290 EXPECT_EQ(kTestData + kOffset, data_read);
293 TEST_F(FileStreamTest, AsyncRead_FromOffset) {
294 int64 file_size;
295 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
296 EXPECT_TRUE(ok);
298 FileStream stream(NULL, base::MessageLoopProxy::current());
299 int flags = base::PLATFORM_FILE_OPEN |
300 base::PLATFORM_FILE_READ |
301 base::PLATFORM_FILE_ASYNC;
302 TestCompletionCallback callback;
303 int rv = stream.Open(temp_file_path(), flags, callback.callback());
304 EXPECT_EQ(ERR_IO_PENDING, rv);
305 EXPECT_EQ(OK, callback.WaitForResult());
307 TestInt64CompletionCallback callback64;
308 const int64 kOffset = 3;
309 rv = stream.Seek(FROM_BEGIN, kOffset, callback64.callback());
310 ASSERT_EQ(ERR_IO_PENDING, rv);
311 int64 new_offset = callback64.WaitForResult();
312 EXPECT_EQ(kOffset, new_offset);
314 int64 total_bytes_avail = stream.Available();
315 EXPECT_EQ(file_size - kOffset, total_bytes_avail);
317 int total_bytes_read = 0;
319 std::string data_read;
320 for (;;) {
321 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
322 rv = stream.Read(buf.get(), buf->size(), callback.callback());
323 if (rv == ERR_IO_PENDING)
324 rv = callback.WaitForResult();
325 EXPECT_LE(0, rv);
326 if (rv <= 0)
327 break;
328 total_bytes_read += rv;
329 data_read.append(buf->data(), rv);
331 EXPECT_EQ(file_size - kOffset, total_bytes_read);
332 EXPECT_EQ(kTestData + kOffset, data_read);
335 TEST_F(FileStreamTest, SeekAround) {
336 FileStream stream(NULL, base::MessageLoopProxy::current());
337 int flags = base::PLATFORM_FILE_OPEN |
338 base::PLATFORM_FILE_READ;
339 int rv = stream.OpenSync(temp_file_path(), flags);
340 EXPECT_EQ(OK, rv);
342 const int64 kOffset = 3;
343 int64 new_offset = stream.SeekSync(FROM_BEGIN, kOffset);
344 EXPECT_EQ(kOffset, new_offset);
346 new_offset = stream.SeekSync(FROM_CURRENT, kOffset);
347 EXPECT_EQ(2 * kOffset, new_offset);
349 new_offset = stream.SeekSync(FROM_CURRENT, -kOffset);
350 EXPECT_EQ(kOffset, new_offset);
352 const int kTestDataLen = arraysize(kTestData) - 1;
354 new_offset = stream.SeekSync(FROM_END, -kTestDataLen);
355 EXPECT_EQ(0, new_offset);
358 TEST_F(FileStreamTest, AsyncSeekAround) {
359 FileStream stream(NULL, base::MessageLoopProxy::current());
360 int flags = base::PLATFORM_FILE_OPEN |
361 base::PLATFORM_FILE_ASYNC |
362 base::PLATFORM_FILE_READ;
363 TestCompletionCallback callback;
364 int rv = stream.Open(temp_file_path(), flags, callback.callback());
365 EXPECT_EQ(ERR_IO_PENDING, rv);
366 EXPECT_EQ(OK, callback.WaitForResult());
368 TestInt64CompletionCallback callback64;
370 const int64 kOffset = 3;
371 rv = stream.Seek(FROM_BEGIN, kOffset, callback64.callback());
372 ASSERT_EQ(ERR_IO_PENDING, rv);
373 int64 new_offset = callback64.WaitForResult();
374 EXPECT_EQ(kOffset, new_offset);
376 rv = stream.Seek(FROM_CURRENT, kOffset, callback64.callback());
377 ASSERT_EQ(ERR_IO_PENDING, rv);
378 new_offset = callback64.WaitForResult();
379 EXPECT_EQ(2 * kOffset, new_offset);
381 rv = stream.Seek(FROM_CURRENT, -kOffset, callback64.callback());
382 ASSERT_EQ(ERR_IO_PENDING, rv);
383 new_offset = callback64.WaitForResult();
384 EXPECT_EQ(kOffset, new_offset);
386 const int kTestDataLen = arraysize(kTestData) - 1;
388 rv = stream.Seek(FROM_END, -kTestDataLen, callback64.callback());
389 ASSERT_EQ(ERR_IO_PENDING, rv);
390 new_offset = callback64.WaitForResult();
391 EXPECT_EQ(0, new_offset);
394 TEST_F(FileStreamTest, BasicWrite) {
395 scoped_ptr<FileStream> stream(
396 new FileStream(NULL, base::MessageLoopProxy::current()));
397 int flags = base::PLATFORM_FILE_CREATE_ALWAYS |
398 base::PLATFORM_FILE_WRITE;
399 int rv = stream->OpenSync(temp_file_path(), flags);
400 EXPECT_EQ(OK, rv);
402 int64 file_size;
403 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
404 EXPECT_TRUE(ok);
405 EXPECT_EQ(0, file_size);
407 rv = stream->WriteSync(kTestData, kTestDataSize);
408 EXPECT_EQ(kTestDataSize, rv);
409 stream.reset();
411 ok = file_util::GetFileSize(temp_file_path(), &file_size);
412 EXPECT_TRUE(ok);
413 EXPECT_EQ(kTestDataSize, file_size);
416 TEST_F(FileStreamTest, AsyncWrite) {
417 FileStream stream(NULL, base::MessageLoopProxy::current());
418 int flags = base::PLATFORM_FILE_CREATE_ALWAYS |
419 base::PLATFORM_FILE_WRITE |
420 base::PLATFORM_FILE_ASYNC;
421 TestCompletionCallback callback;
422 int rv = stream.Open(temp_file_path(), flags, callback.callback());
423 EXPECT_EQ(ERR_IO_PENDING, rv);
424 EXPECT_EQ(OK, callback.WaitForResult());
426 int64 file_size;
427 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
428 EXPECT_TRUE(ok);
429 EXPECT_EQ(0, file_size);
431 int total_bytes_written = 0;
433 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
434 scoped_refptr<DrainableIOBuffer> drainable =
435 new DrainableIOBuffer(buf.get(), buf->size());
436 while (total_bytes_written != kTestDataSize) {
437 rv = stream.Write(
438 drainable.get(), drainable->BytesRemaining(), callback.callback());
439 if (rv == ERR_IO_PENDING)
440 rv = callback.WaitForResult();
441 EXPECT_LT(0, rv);
442 if (rv <= 0)
443 break;
444 drainable->DidConsume(rv);
445 total_bytes_written += rv;
447 ok = file_util::GetFileSize(temp_file_path(), &file_size);
448 EXPECT_TRUE(ok);
449 EXPECT_EQ(file_size, total_bytes_written);
452 TEST_F(FileStreamTest, AsyncWrite_EarlyDelete) {
453 scoped_ptr<FileStream> stream(
454 new FileStream(NULL, base::MessageLoopProxy::current()));
455 int flags = base::PLATFORM_FILE_CREATE_ALWAYS |
456 base::PLATFORM_FILE_WRITE |
457 base::PLATFORM_FILE_ASYNC;
458 TestCompletionCallback callback;
459 int rv = stream->Open(temp_file_path(), flags, callback.callback());
460 EXPECT_EQ(ERR_IO_PENDING, rv);
461 EXPECT_EQ(OK, callback.WaitForResult());
463 int64 file_size;
464 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
465 EXPECT_TRUE(ok);
466 EXPECT_EQ(0, file_size);
468 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
469 rv = stream->Write(buf.get(), buf->size(), callback.callback());
470 stream.reset();
471 if (rv < 0) {
472 EXPECT_EQ(ERR_IO_PENDING, rv);
473 // The callback should not be called if the request is cancelled.
474 base::RunLoop().RunUntilIdle();
475 EXPECT_FALSE(callback.have_result());
476 } else {
477 ok = file_util::GetFileSize(temp_file_path(), &file_size);
478 EXPECT_TRUE(ok);
479 EXPECT_EQ(file_size, rv);
483 TEST_F(FileStreamTest, BasicWrite_FromOffset) {
484 scoped_ptr<FileStream> stream(
485 new FileStream(NULL, base::MessageLoopProxy::current()));
486 int flags = base::PLATFORM_FILE_OPEN |
487 base::PLATFORM_FILE_WRITE;
488 int rv = stream->OpenSync(temp_file_path(), flags);
489 EXPECT_EQ(OK, rv);
491 int64 file_size;
492 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
493 EXPECT_TRUE(ok);
494 EXPECT_EQ(kTestDataSize, file_size);
496 const int64 kOffset = 0;
497 int64 new_offset = stream->SeekSync(FROM_END, kOffset);
498 EXPECT_EQ(kTestDataSize, new_offset);
500 rv = stream->WriteSync(kTestData, kTestDataSize);
501 EXPECT_EQ(kTestDataSize, rv);
502 stream.reset();
504 ok = file_util::GetFileSize(temp_file_path(), &file_size);
505 EXPECT_TRUE(ok);
506 EXPECT_EQ(kTestDataSize * 2, file_size);
509 TEST_F(FileStreamTest, AsyncWrite_FromOffset) {
510 int64 file_size;
511 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
512 EXPECT_TRUE(ok);
514 FileStream stream(NULL, base::MessageLoopProxy::current());
515 int flags = base::PLATFORM_FILE_OPEN |
516 base::PLATFORM_FILE_WRITE |
517 base::PLATFORM_FILE_ASYNC;
518 TestCompletionCallback callback;
519 int rv = stream.Open(temp_file_path(), flags, callback.callback());
520 EXPECT_EQ(ERR_IO_PENDING, rv);
521 EXPECT_EQ(OK, callback.WaitForResult());
523 TestInt64CompletionCallback callback64;
524 const int64 kOffset = 0;
525 rv = stream.Seek(FROM_END, kOffset, callback64.callback());
526 ASSERT_EQ(ERR_IO_PENDING, rv);
527 int64 new_offset = callback64.WaitForResult();
528 EXPECT_EQ(kTestDataSize, new_offset);
530 int total_bytes_written = 0;
532 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
533 scoped_refptr<DrainableIOBuffer> drainable =
534 new DrainableIOBuffer(buf.get(), buf->size());
535 while (total_bytes_written != kTestDataSize) {
536 rv = stream.Write(
537 drainable.get(), drainable->BytesRemaining(), callback.callback());
538 if (rv == ERR_IO_PENDING)
539 rv = callback.WaitForResult();
540 EXPECT_LT(0, rv);
541 if (rv <= 0)
542 break;
543 drainable->DidConsume(rv);
544 total_bytes_written += rv;
546 ok = file_util::GetFileSize(temp_file_path(), &file_size);
547 EXPECT_TRUE(ok);
548 EXPECT_EQ(file_size, kTestDataSize * 2);
551 TEST_F(FileStreamTest, BasicReadWrite) {
552 int64 file_size;
553 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
554 EXPECT_TRUE(ok);
556 scoped_ptr<FileStream> stream(
557 new FileStream(NULL, base::MessageLoopProxy::current()));
558 int flags = base::PLATFORM_FILE_OPEN |
559 base::PLATFORM_FILE_READ |
560 base::PLATFORM_FILE_WRITE;
561 int rv = stream->OpenSync(temp_file_path(), flags);
562 EXPECT_EQ(OK, rv);
564 int64 total_bytes_avail = stream->Available();
565 EXPECT_EQ(file_size, total_bytes_avail);
567 int total_bytes_read = 0;
569 std::string data_read;
570 for (;;) {
571 char buf[4];
572 rv = stream->ReadSync(buf, arraysize(buf));
573 EXPECT_LE(0, rv);
574 if (rv <= 0)
575 break;
576 total_bytes_read += rv;
577 data_read.append(buf, rv);
579 EXPECT_EQ(file_size, total_bytes_read);
580 EXPECT_TRUE(data_read == kTestData);
582 rv = stream->WriteSync(kTestData, kTestDataSize);
583 EXPECT_EQ(kTestDataSize, rv);
584 stream.reset();
586 ok = file_util::GetFileSize(temp_file_path(), &file_size);
587 EXPECT_TRUE(ok);
588 EXPECT_EQ(kTestDataSize * 2, file_size);
591 TEST_F(FileStreamTest, BasicWriteRead) {
592 int64 file_size;
593 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
594 EXPECT_TRUE(ok);
596 scoped_ptr<FileStream> stream(
597 new FileStream(NULL, base::MessageLoopProxy::current()));
598 int flags = base::PLATFORM_FILE_OPEN |
599 base::PLATFORM_FILE_READ |
600 base::PLATFORM_FILE_WRITE;
601 int rv = stream->OpenSync(temp_file_path(), flags);
602 EXPECT_EQ(OK, rv);
604 int64 total_bytes_avail = stream->Available();
605 EXPECT_EQ(file_size, total_bytes_avail);
607 int64 offset = stream->SeekSync(FROM_END, 0);
608 EXPECT_EQ(offset, file_size);
610 rv = stream->WriteSync(kTestData, kTestDataSize);
611 EXPECT_EQ(kTestDataSize, rv);
613 offset = stream->SeekSync(FROM_BEGIN, 0);
614 EXPECT_EQ(0, offset);
616 int64 total_bytes_read = 0;
618 std::string data_read;
619 for (;;) {
620 char buf[4];
621 rv = stream->ReadSync(buf, arraysize(buf));
622 EXPECT_LE(0, rv);
623 if (rv <= 0)
624 break;
625 total_bytes_read += rv;
626 data_read.append(buf, rv);
628 stream.reset();
630 ok = file_util::GetFileSize(temp_file_path(), &file_size);
631 EXPECT_TRUE(ok);
632 EXPECT_EQ(kTestDataSize * 2, file_size);
633 EXPECT_EQ(kTestDataSize * 2, total_bytes_read);
635 const std::string kExpectedFileData =
636 std::string(kTestData) + std::string(kTestData);
637 EXPECT_EQ(kExpectedFileData, data_read);
640 TEST_F(FileStreamTest, BasicAsyncReadWrite) {
641 int64 file_size;
642 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
643 EXPECT_TRUE(ok);
645 scoped_ptr<FileStream> stream(
646 new FileStream(NULL, base::MessageLoopProxy::current()));
647 int flags = base::PLATFORM_FILE_OPEN |
648 base::PLATFORM_FILE_READ |
649 base::PLATFORM_FILE_WRITE |
650 base::PLATFORM_FILE_ASYNC;
651 TestCompletionCallback callback;
652 int rv = stream->Open(temp_file_path(), flags, callback.callback());
653 EXPECT_EQ(ERR_IO_PENDING, rv);
654 EXPECT_EQ(OK, callback.WaitForResult());
656 int64 total_bytes_avail = stream->Available();
657 EXPECT_EQ(file_size, total_bytes_avail);
659 int64 total_bytes_read = 0;
661 std::string data_read;
662 for (;;) {
663 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
664 rv = stream->Read(buf.get(), buf->size(), callback.callback());
665 if (rv == ERR_IO_PENDING)
666 rv = callback.WaitForResult();
667 EXPECT_LE(0, rv);
668 if (rv <= 0)
669 break;
670 total_bytes_read += rv;
671 data_read.append(buf->data(), rv);
673 EXPECT_EQ(file_size, total_bytes_read);
674 EXPECT_TRUE(data_read == kTestData);
676 int total_bytes_written = 0;
678 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
679 scoped_refptr<DrainableIOBuffer> drainable =
680 new DrainableIOBuffer(buf.get(), buf->size());
681 while (total_bytes_written != kTestDataSize) {
682 rv = stream->Write(
683 drainable.get(), drainable->BytesRemaining(), callback.callback());
684 if (rv == ERR_IO_PENDING)
685 rv = callback.WaitForResult();
686 EXPECT_LT(0, rv);
687 if (rv <= 0)
688 break;
689 drainable->DidConsume(rv);
690 total_bytes_written += rv;
693 stream.reset();
695 ok = file_util::GetFileSize(temp_file_path(), &file_size);
696 EXPECT_TRUE(ok);
697 EXPECT_EQ(kTestDataSize * 2, file_size);
700 TEST_F(FileStreamTest, BasicAsyncWriteRead) {
701 int64 file_size;
702 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
703 EXPECT_TRUE(ok);
705 scoped_ptr<FileStream> stream(
706 new FileStream(NULL, base::MessageLoopProxy::current()));
707 int flags = base::PLATFORM_FILE_OPEN |
708 base::PLATFORM_FILE_READ |
709 base::PLATFORM_FILE_WRITE |
710 base::PLATFORM_FILE_ASYNC;
711 TestCompletionCallback callback;
712 int rv = stream->Open(temp_file_path(), flags, callback.callback());
713 EXPECT_EQ(ERR_IO_PENDING, rv);
714 EXPECT_EQ(OK, callback.WaitForResult());
716 int64 total_bytes_avail = stream->Available();
717 EXPECT_EQ(file_size, total_bytes_avail);
719 TestInt64CompletionCallback callback64;
720 rv = stream->Seek(FROM_END, 0, callback64.callback());
721 ASSERT_EQ(ERR_IO_PENDING, rv);
722 int64 offset = callback64.WaitForResult();
723 EXPECT_EQ(offset, file_size);
725 int total_bytes_written = 0;
727 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
728 scoped_refptr<DrainableIOBuffer> drainable =
729 new DrainableIOBuffer(buf.get(), buf->size());
730 while (total_bytes_written != kTestDataSize) {
731 rv = stream->Write(
732 drainable.get(), drainable->BytesRemaining(), callback.callback());
733 if (rv == ERR_IO_PENDING)
734 rv = callback.WaitForResult();
735 EXPECT_LT(0, rv);
736 if (rv <= 0)
737 break;
738 drainable->DidConsume(rv);
739 total_bytes_written += rv;
742 EXPECT_EQ(kTestDataSize, total_bytes_written);
744 rv = stream->Seek(FROM_BEGIN, 0, callback64.callback());
745 ASSERT_EQ(ERR_IO_PENDING, rv);
746 offset = callback64.WaitForResult();
747 EXPECT_EQ(0, offset);
749 int total_bytes_read = 0;
751 std::string data_read;
752 for (;;) {
753 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
754 rv = stream->Read(buf.get(), buf->size(), callback.callback());
755 if (rv == ERR_IO_PENDING)
756 rv = callback.WaitForResult();
757 EXPECT_LE(0, rv);
758 if (rv <= 0)
759 break;
760 total_bytes_read += rv;
761 data_read.append(buf->data(), rv);
763 stream.reset();
765 ok = file_util::GetFileSize(temp_file_path(), &file_size);
766 EXPECT_TRUE(ok);
767 EXPECT_EQ(kTestDataSize * 2, file_size);
769 EXPECT_EQ(kTestDataSize * 2, total_bytes_read);
770 const std::string kExpectedFileData =
771 std::string(kTestData) + std::string(kTestData);
772 EXPECT_EQ(kExpectedFileData, data_read);
775 class TestWriteReadCompletionCallback {
776 public:
777 TestWriteReadCompletionCallback(FileStream* stream,
778 int* total_bytes_written,
779 int* total_bytes_read,
780 std::string* data_read)
781 : result_(0),
782 have_result_(false),
783 waiting_for_result_(false),
784 stream_(stream),
785 total_bytes_written_(total_bytes_written),
786 total_bytes_read_(total_bytes_read),
787 data_read_(data_read),
788 callback_(base::Bind(&TestWriteReadCompletionCallback::OnComplete,
789 base::Unretained(this))),
790 test_data_(CreateTestDataBuffer()),
791 drainable_(new DrainableIOBuffer(test_data_.get(), kTestDataSize)) {}
793 int WaitForResult() {
794 DCHECK(!waiting_for_result_);
795 while (!have_result_) {
796 waiting_for_result_ = true;
797 base::RunLoop().Run();
798 waiting_for_result_ = false;
800 have_result_ = false; // auto-reset for next callback
801 return result_;
804 const CompletionCallback& callback() const { return callback_; }
806 private:
807 void OnComplete(int result) {
808 DCHECK_LT(0, result);
809 *total_bytes_written_ += result;
811 int rv;
813 if (*total_bytes_written_ != kTestDataSize) {
814 // Recurse to finish writing all data.
815 int total_bytes_written = 0, total_bytes_read = 0;
816 std::string data_read;
817 TestWriteReadCompletionCallback callback(
818 stream_, &total_bytes_written, &total_bytes_read, &data_read);
819 rv = stream_->Write(
820 drainable_.get(), drainable_->BytesRemaining(), callback.callback());
821 DCHECK_EQ(ERR_IO_PENDING, rv);
822 rv = callback.WaitForResult();
823 drainable_->DidConsume(total_bytes_written);
824 *total_bytes_written_ += total_bytes_written;
825 *total_bytes_read_ += total_bytes_read;
826 *data_read_ += data_read;
827 } else { // We're done writing all data. Start reading the data.
828 stream_->SeekSync(FROM_BEGIN, 0);
830 TestCompletionCallback callback;
831 for (;;) {
832 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
833 rv = stream_->Read(buf.get(), buf->size(), callback.callback());
834 if (rv == ERR_IO_PENDING) {
835 base::MessageLoop::ScopedNestableTaskAllower allow(
836 base::MessageLoop::current());
837 rv = callback.WaitForResult();
839 EXPECT_LE(0, rv);
840 if (rv <= 0)
841 break;
842 *total_bytes_read_ += rv;
843 data_read_->append(buf->data(), rv);
847 result_ = *total_bytes_written_;
848 have_result_ = true;
849 if (waiting_for_result_)
850 base::MessageLoop::current()->Quit();
853 int result_;
854 bool have_result_;
855 bool waiting_for_result_;
856 FileStream* stream_;
857 int* total_bytes_written_;
858 int* total_bytes_read_;
859 std::string* data_read_;
860 const CompletionCallback callback_;
861 scoped_refptr<IOBufferWithSize> test_data_;
862 scoped_refptr<DrainableIOBuffer> drainable_;
864 DISALLOW_COPY_AND_ASSIGN(TestWriteReadCompletionCallback);
867 TEST_F(FileStreamTest, AsyncWriteRead) {
868 int64 file_size;
869 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
870 EXPECT_TRUE(ok);
872 scoped_ptr<FileStream> stream(
873 new FileStream(NULL, base::MessageLoopProxy::current()));
874 int flags = base::PLATFORM_FILE_OPEN |
875 base::PLATFORM_FILE_READ |
876 base::PLATFORM_FILE_WRITE |
877 base::PLATFORM_FILE_ASYNC;
878 TestCompletionCallback open_callback;
879 int rv = stream->Open(temp_file_path(), flags, open_callback.callback());
880 EXPECT_EQ(ERR_IO_PENDING, rv);
881 EXPECT_EQ(OK, open_callback.WaitForResult());
883 int64 total_bytes_avail = stream->Available();
884 EXPECT_EQ(file_size, total_bytes_avail);
886 int64 offset = stream->SeekSync(FROM_END, 0);
887 EXPECT_EQ(offset, file_size);
889 int total_bytes_written = 0;
890 int total_bytes_read = 0;
891 std::string data_read;
892 TestWriteReadCompletionCallback callback(stream.get(), &total_bytes_written,
893 &total_bytes_read, &data_read);
895 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
896 rv = stream->Write(buf.get(), buf->size(), callback.callback());
897 if (rv == ERR_IO_PENDING)
898 rv = callback.WaitForResult();
899 EXPECT_LT(0, rv);
900 EXPECT_EQ(kTestDataSize, total_bytes_written);
902 stream.reset();
904 ok = file_util::GetFileSize(temp_file_path(), &file_size);
905 EXPECT_TRUE(ok);
906 EXPECT_EQ(kTestDataSize * 2, file_size);
908 EXPECT_EQ(kTestDataSize * 2, total_bytes_read);
909 const std::string kExpectedFileData =
910 std::string(kTestData) + std::string(kTestData);
911 EXPECT_EQ(kExpectedFileData, data_read);
914 class TestWriteCloseCompletionCallback {
915 public:
916 TestWriteCloseCompletionCallback(FileStream* stream, int* total_bytes_written)
917 : result_(0),
918 have_result_(false),
919 waiting_for_result_(false),
920 stream_(stream),
921 total_bytes_written_(total_bytes_written),
922 callback_(base::Bind(&TestWriteCloseCompletionCallback::OnComplete,
923 base::Unretained(this))),
924 test_data_(CreateTestDataBuffer()),
925 drainable_(new DrainableIOBuffer(test_data_.get(), kTestDataSize)) {}
927 int WaitForResult() {
928 DCHECK(!waiting_for_result_);
929 while (!have_result_) {
930 waiting_for_result_ = true;
931 base::RunLoop().Run();
932 waiting_for_result_ = false;
934 have_result_ = false; // auto-reset for next callback
935 return result_;
938 const CompletionCallback& callback() const { return callback_; }
940 private:
941 void OnComplete(int result) {
942 DCHECK_LT(0, result);
943 *total_bytes_written_ += result;
945 int rv;
947 if (*total_bytes_written_ != kTestDataSize) {
948 // Recurse to finish writing all data.
949 int total_bytes_written = 0;
950 TestWriteCloseCompletionCallback callback(stream_, &total_bytes_written);
951 rv = stream_->Write(
952 drainable_.get(), drainable_->BytesRemaining(), callback.callback());
953 DCHECK_EQ(ERR_IO_PENDING, rv);
954 rv = callback.WaitForResult();
955 drainable_->DidConsume(total_bytes_written);
956 *total_bytes_written_ += total_bytes_written;
959 result_ = *total_bytes_written_;
960 have_result_ = true;
961 if (waiting_for_result_)
962 base::MessageLoop::current()->Quit();
965 int result_;
966 bool have_result_;
967 bool waiting_for_result_;
968 FileStream* stream_;
969 int* total_bytes_written_;
970 const CompletionCallback callback_;
971 scoped_refptr<IOBufferWithSize> test_data_;
972 scoped_refptr<DrainableIOBuffer> drainable_;
974 DISALLOW_COPY_AND_ASSIGN(TestWriteCloseCompletionCallback);
977 TEST_F(FileStreamTest, AsyncWriteClose) {
978 int64 file_size;
979 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
980 EXPECT_TRUE(ok);
982 scoped_ptr<FileStream> stream(
983 new FileStream(NULL, base::MessageLoopProxy::current()));
984 int flags = base::PLATFORM_FILE_OPEN |
985 base::PLATFORM_FILE_READ |
986 base::PLATFORM_FILE_WRITE |
987 base::PLATFORM_FILE_ASYNC;
988 TestCompletionCallback open_callback;
989 int rv = stream->Open(temp_file_path(), flags, open_callback.callback());
990 EXPECT_EQ(ERR_IO_PENDING, rv);
991 EXPECT_EQ(OK, open_callback.WaitForResult());
993 int64 total_bytes_avail = stream->Available();
994 EXPECT_EQ(file_size, total_bytes_avail);
996 int64 offset = stream->SeekSync(FROM_END, 0);
997 EXPECT_EQ(offset, file_size);
999 int total_bytes_written = 0;
1000 TestWriteCloseCompletionCallback callback(stream.get(), &total_bytes_written);
1002 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
1003 rv = stream->Write(buf.get(), buf->size(), callback.callback());
1004 if (rv == ERR_IO_PENDING)
1005 total_bytes_written = callback.WaitForResult();
1006 EXPECT_LT(0, total_bytes_written);
1007 EXPECT_EQ(kTestDataSize, total_bytes_written);
1009 stream.reset();
1011 ok = file_util::GetFileSize(temp_file_path(), &file_size);
1012 EXPECT_TRUE(ok);
1013 EXPECT_EQ(kTestDataSize * 2, file_size);
1016 // Tests truncating a file.
1017 TEST_F(FileStreamTest, Truncate) {
1018 int flags = base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE;
1020 scoped_ptr<FileStream> write_stream(
1021 new FileStream(NULL, base::MessageLoopProxy::current()));
1022 ASSERT_EQ(OK, write_stream->OpenSync(temp_file_path(), flags));
1024 // Write some data to the file.
1025 const char test_data[] = "0123456789";
1026 write_stream->WriteSync(test_data, arraysize(test_data));
1028 // Truncate the file.
1029 ASSERT_EQ(4, write_stream->Truncate(4));
1031 // Write again.
1032 write_stream->WriteSync(test_data, 4);
1034 // Close the stream.
1035 write_stream.reset();
1037 // Read in the contents and make sure we get back what we expected.
1038 std::string read_contents;
1039 EXPECT_TRUE(base::ReadFileToString(temp_file_path(), &read_contents));
1041 EXPECT_EQ("01230123", read_contents);
1044 TEST_F(FileStreamTest, AsyncOpenAndDelete) {
1045 scoped_ptr<FileStream> stream(
1046 new FileStream(NULL, base::MessageLoopProxy::current()));
1047 int flags = base::PLATFORM_FILE_OPEN |
1048 base::PLATFORM_FILE_WRITE |
1049 base::PLATFORM_FILE_ASYNC;
1050 TestCompletionCallback open_callback;
1051 int rv = stream->Open(temp_file_path(), flags, open_callback.callback());
1052 EXPECT_EQ(ERR_IO_PENDING, rv);
1054 // Delete the stream without waiting for the open operation to be
1055 // complete. Should be safe.
1056 stream.reset();
1057 // open_callback won't be called.
1058 base::RunLoop().RunUntilIdle();
1059 EXPECT_FALSE(open_callback.have_result());
1062 // Verify that async Write() errors are mapped correctly.
1063 TEST_F(FileStreamTest, AsyncWriteError) {
1064 scoped_ptr<FileStream> stream(
1065 new FileStream(NULL, base::MessageLoopProxy::current()));
1066 int flags = base::PLATFORM_FILE_CREATE_ALWAYS |
1067 base::PLATFORM_FILE_WRITE |
1068 base::PLATFORM_FILE_ASYNC;
1069 TestCompletionCallback callback;
1070 int rv = stream->Open(temp_file_path(), flags, callback.callback());
1071 EXPECT_EQ(ERR_IO_PENDING, rv);
1072 EXPECT_EQ(OK, callback.WaitForResult());
1074 // Try passing NULL buffer to Write() and check that it fails.
1075 scoped_refptr<IOBuffer> buf = new WrappedIOBuffer(NULL);
1076 rv = stream->Write(buf.get(), 1, callback.callback());
1077 if (rv == ERR_IO_PENDING)
1078 rv = callback.WaitForResult();
1079 EXPECT_LT(rv, 0);
1082 // Verify that async Read() errors are mapped correctly.
1083 TEST_F(FileStreamTest, AsyncReadError) {
1084 scoped_ptr<FileStream> stream(
1085 new FileStream(NULL, base::MessageLoopProxy::current()));
1086 int flags = base::PLATFORM_FILE_OPEN |
1087 base::PLATFORM_FILE_READ |
1088 base::PLATFORM_FILE_ASYNC;
1089 TestCompletionCallback callback;
1090 int rv = stream->Open(temp_file_path(), flags, callback.callback());
1091 EXPECT_EQ(ERR_IO_PENDING, rv);
1092 EXPECT_EQ(OK, callback.WaitForResult());
1094 // Try passing NULL buffer to Read() and check that it fails.
1095 scoped_refptr<IOBuffer> buf = new WrappedIOBuffer(NULL);
1096 rv = stream->Read(buf.get(), 1, callback.callback());
1097 if (rv == ERR_IO_PENDING)
1098 rv = callback.WaitForResult();
1099 EXPECT_LT(rv, 0);
1102 } // namespace
1104 } // namespace net