- add sources.
[platform/framework/web/crosswalk.git] / src / net / base / file_stream_unittest.cc
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.
4
5 #include "net/base/file_stream.h"
6
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"
23
24 namespace net {
25
26 namespace {
27
28 const char kTestData[] = "0123456789";
29 const int kTestDataSize = arraysize(kTestData) - 1;
30
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;
36 }
37
38 }  // namespace
39
40 class FileStreamTest : public PlatformTest {
41  public:
42   virtual void SetUp() {
43     PlatformTest::SetUp();
44
45     file_util::CreateTemporaryFile(&temp_file_path_);
46     file_util::WriteFile(temp_file_path_, kTestData, kTestDataSize);
47   }
48   virtual void TearDown() {
49     EXPECT_TRUE(base::DeleteFile(temp_file_path_, false));
50
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();
55   }
56
57   const base::FilePath temp_file_path() const { return temp_file_path_; }
58
59  private:
60   base::FilePath temp_file_path_;
61 };
62
63 namespace {
64
65 TEST_F(FileStreamTest, BasicOpenClose) {
66   base::PlatformFile file = base::kInvalidPlatformFileValue;
67   {
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();
74   }
75   EXPECT_NE(base::kInvalidPlatformFileValue, file);
76   base::PlatformFileInfo info;
77   // The file should be closed.
78   EXPECT_FALSE(base::GetPlatformFileInfo(file, &info));
79 }
80
81 TEST_F(FileStreamTest, BasicOpenExplicitClose) {
82   base::PlatformFile file = base::kInvalidPlatformFileValue;
83   FileStream stream(NULL);
84   int rv = stream.OpenSync(temp_file_path(),
85       base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ);
86   EXPECT_EQ(OK, rv);
87   EXPECT_TRUE(stream.IsOpen());
88   file = stream.GetPlatformFileForTesting();
89   EXPECT_NE(base::kInvalidPlatformFileValue, file);
90   EXPECT_EQ(OK, stream.CloseSync());
91   EXPECT_FALSE(stream.IsOpen());
92   base::PlatformFileInfo info;
93   // The file should be closed.
94   EXPECT_FALSE(base::GetPlatformFileInfo(file, &info));
95 }
96
97 TEST_F(FileStreamTest, AsyncOpenExplicitClose) {
98   base::PlatformFile file = base::kInvalidPlatformFileValue;
99   TestCompletionCallback callback;
100   FileStream stream(NULL);
101   int flags = base::PLATFORM_FILE_OPEN |
102               base::PLATFORM_FILE_READ |
103               base::PLATFORM_FILE_ASYNC;
104   int rv = stream.Open(temp_file_path(), flags, callback.callback());
105   EXPECT_EQ(ERR_IO_PENDING, rv);
106   EXPECT_EQ(OK, callback.WaitForResult());
107   EXPECT_TRUE(stream.IsOpen());
108   file = stream.GetPlatformFileForTesting();
109   EXPECT_EQ(ERR_IO_PENDING, stream.Close(callback.callback()));
110   EXPECT_EQ(OK, callback.WaitForResult());
111   EXPECT_FALSE(stream.IsOpen());
112   base::PlatformFileInfo info;
113   // The file should be closed.
114   EXPECT_FALSE(base::GetPlatformFileInfo(file, &info));
115 }
116
117 TEST_F(FileStreamTest, AsyncOpenExplicitCloseOrphaned) {
118   base::PlatformFile file = base::kInvalidPlatformFileValue;
119   TestCompletionCallback callback;
120   base::PlatformFileInfo info;
121   scoped_ptr<FileStream> stream(new FileStream(
122       NULL, base::MessageLoopProxy::current()));
123   int flags = base::PLATFORM_FILE_OPEN |
124               base::PLATFORM_FILE_READ |
125               base::PLATFORM_FILE_ASYNC;
126   int rv = stream->Open(temp_file_path(), flags, callback.callback());
127   EXPECT_EQ(ERR_IO_PENDING, rv);
128   EXPECT_EQ(OK, callback.WaitForResult());
129   EXPECT_TRUE(stream->IsOpen());
130   file = stream->GetPlatformFileForTesting();
131   EXPECT_EQ(ERR_IO_PENDING, stream->Close(callback.callback()));
132   stream.reset();
133   // File isn't actually closed yet.
134   EXPECT_TRUE(base::GetPlatformFileInfo(file, &info));
135   base::RunLoop runloop;
136   runloop.RunUntilIdle();
137   // The file should now be closed, though the callback has not been called.
138   EXPECT_FALSE(base::GetPlatformFileInfo(file, &info));
139 }
140
141 TEST_F(FileStreamTest, FileHandleNotLeftOpen) {
142   bool created = false;
143   ASSERT_EQ(kTestDataSize,
144       file_util::WriteFile(temp_file_path(), kTestData, kTestDataSize));
145   int flags = base::PLATFORM_FILE_OPEN_ALWAYS | base::PLATFORM_FILE_READ;
146   base::PlatformFile file = base::CreatePlatformFile(
147       temp_file_path(), flags, &created, NULL);
148
149   {
150     // Seek to the beginning of the file and read.
151     FileStream read_stream(file, flags, NULL,
152                            base::MessageLoopProxy::current());
153     EXPECT_TRUE(read_stream.IsOpen());
154   }
155
156   EXPECT_NE(base::kInvalidPlatformFileValue, file);
157   base::PlatformFileInfo info;
158   // The file should be closed.
159   EXPECT_FALSE(base::GetPlatformFileInfo(file, &info));
160 }
161
162 // Test the use of FileStream with a file handle provided at construction.
163 TEST_F(FileStreamTest, UseFileHandle) {
164   bool created = false;
165
166   // 1. Test reading with a file handle.
167   ASSERT_EQ(kTestDataSize,
168       file_util::WriteFile(temp_file_path(), kTestData, kTestDataSize));
169   int flags = base::PLATFORM_FILE_OPEN_ALWAYS | base::PLATFORM_FILE_READ;
170   base::PlatformFile file = base::CreatePlatformFile(
171       temp_file_path(), flags, &created, NULL);
172
173   // Seek to the beginning of the file and read.
174   scoped_ptr<FileStream> read_stream(
175       new FileStream(file, flags, NULL, base::MessageLoopProxy::current()));
176   ASSERT_EQ(0, read_stream->SeekSync(FROM_BEGIN, 0));
177   ASSERT_EQ(kTestDataSize, read_stream->Available());
178   // Read into buffer and compare.
179   char buffer[kTestDataSize];
180   ASSERT_EQ(kTestDataSize,
181             read_stream->ReadSync(buffer, kTestDataSize));
182   ASSERT_EQ(0, memcmp(kTestData, buffer, kTestDataSize));
183   read_stream.reset();
184
185   // 2. Test writing with a file handle.
186   base::DeleteFile(temp_file_path(), false);
187   flags = base::PLATFORM_FILE_OPEN_ALWAYS | base::PLATFORM_FILE_WRITE;
188   file = base::CreatePlatformFile(temp_file_path(), flags, &created, NULL);
189
190   scoped_ptr<FileStream> write_stream(
191       new FileStream(file, flags, NULL, base::MessageLoopProxy::current()));
192   ASSERT_EQ(0, write_stream->SeekSync(FROM_BEGIN, 0));
193   ASSERT_EQ(kTestDataSize,
194             write_stream->WriteSync(kTestData, kTestDataSize));
195   write_stream.reset();
196
197   // Read into buffer and compare to make sure the handle worked fine.
198   ASSERT_EQ(kTestDataSize,
199       file_util::ReadFile(temp_file_path(), buffer, kTestDataSize));
200   ASSERT_EQ(0, memcmp(kTestData, buffer, kTestDataSize));
201 }
202
203 TEST_F(FileStreamTest, UseClosedStream) {
204   FileStream stream(NULL, base::MessageLoopProxy::current());
205
206   EXPECT_FALSE(stream.IsOpen());
207
208   // Try seeking...
209   int64 new_offset = stream.SeekSync(FROM_BEGIN, 5);
210   EXPECT_EQ(ERR_UNEXPECTED, new_offset);
211
212   // Try available...
213   int64 avail = stream.Available();
214   EXPECT_EQ(ERR_UNEXPECTED, avail);
215
216   // Try reading...
217   char buf[10];
218   int rv = stream.ReadSync(buf, arraysize(buf));
219   EXPECT_EQ(ERR_UNEXPECTED, rv);
220 }
221
222 TEST_F(FileStreamTest, BasicRead) {
223   int64 file_size;
224   bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
225   EXPECT_TRUE(ok);
226
227   FileStream stream(NULL, base::MessageLoopProxy::current());
228   int flags = base::PLATFORM_FILE_OPEN |
229               base::PLATFORM_FILE_READ;
230   int rv = stream.OpenSync(temp_file_path(), flags);
231   EXPECT_EQ(OK, rv);
232
233   int64 total_bytes_avail = stream.Available();
234   EXPECT_EQ(file_size, total_bytes_avail);
235
236   int total_bytes_read = 0;
237
238   std::string data_read;
239   for (;;) {
240     char buf[4];
241     rv = stream.ReadSync(buf, arraysize(buf));
242     EXPECT_LE(0, rv);
243     if (rv <= 0)
244       break;
245     total_bytes_read += rv;
246     data_read.append(buf, rv);
247   }
248   EXPECT_EQ(file_size, total_bytes_read);
249   EXPECT_EQ(kTestData, data_read);
250 }
251
252 TEST_F(FileStreamTest, AsyncRead) {
253   int64 file_size;
254   bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
255   EXPECT_TRUE(ok);
256
257   FileStream stream(NULL, base::MessageLoopProxy::current());
258   int flags = base::PLATFORM_FILE_OPEN |
259               base::PLATFORM_FILE_READ |
260               base::PLATFORM_FILE_ASYNC;
261   TestCompletionCallback callback;
262   int rv = stream.Open(temp_file_path(), flags, callback.callback());
263   EXPECT_EQ(ERR_IO_PENDING, rv);
264   EXPECT_EQ(OK, callback.WaitForResult());
265
266   int64 total_bytes_avail = stream.Available();
267   EXPECT_EQ(file_size, total_bytes_avail);
268
269   int total_bytes_read = 0;
270
271   std::string data_read;
272   for (;;) {
273     scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
274     rv = stream.Read(buf.get(), buf->size(), callback.callback());
275     if (rv == ERR_IO_PENDING)
276       rv = callback.WaitForResult();
277     EXPECT_LE(0, rv);
278     if (rv <= 0)
279       break;
280     total_bytes_read += rv;
281     data_read.append(buf->data(), rv);
282   }
283   EXPECT_EQ(file_size, total_bytes_read);
284   EXPECT_EQ(kTestData, data_read);
285 }
286
287 TEST_F(FileStreamTest, AsyncRead_EarlyDelete) {
288   int64 file_size;
289   bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
290   EXPECT_TRUE(ok);
291
292   scoped_ptr<FileStream> stream(
293       new FileStream(NULL, base::MessageLoopProxy::current()));
294   int flags = base::PLATFORM_FILE_OPEN |
295               base::PLATFORM_FILE_READ |
296               base::PLATFORM_FILE_ASYNC;
297   TestCompletionCallback callback;
298   int rv = stream->Open(temp_file_path(), flags, callback.callback());
299   EXPECT_EQ(ERR_IO_PENDING, rv);
300   EXPECT_EQ(OK, callback.WaitForResult());
301
302   int64 total_bytes_avail = stream->Available();
303   EXPECT_EQ(file_size, total_bytes_avail);
304
305   scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
306   rv = stream->Read(buf.get(), buf->size(), callback.callback());
307   stream.reset();  // Delete instead of closing it.
308   if (rv < 0) {
309     EXPECT_EQ(ERR_IO_PENDING, rv);
310     // The callback should not be called if the request is cancelled.
311     base::RunLoop().RunUntilIdle();
312     EXPECT_FALSE(callback.have_result());
313   } else {
314     EXPECT_EQ(std::string(kTestData, rv), std::string(buf->data(), rv));
315   }
316 }
317
318 TEST_F(FileStreamTest, BasicRead_FromOffset) {
319   int64 file_size;
320   bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
321   EXPECT_TRUE(ok);
322
323   FileStream stream(NULL, base::MessageLoopProxy::current());
324   int flags = base::PLATFORM_FILE_OPEN |
325               base::PLATFORM_FILE_READ;
326   int rv = stream.OpenSync(temp_file_path(), flags);
327   EXPECT_EQ(OK, rv);
328
329   const int64 kOffset = 3;
330   int64 new_offset = stream.SeekSync(FROM_BEGIN, kOffset);
331   EXPECT_EQ(kOffset, new_offset);
332
333   int64 total_bytes_avail = stream.Available();
334   EXPECT_EQ(file_size - kOffset, total_bytes_avail);
335
336   int64 total_bytes_read = 0;
337
338   std::string data_read;
339   for (;;) {
340     char buf[4];
341     rv = stream.ReadSync(buf, arraysize(buf));
342     EXPECT_LE(0, rv);
343     if (rv <= 0)
344       break;
345     total_bytes_read += rv;
346     data_read.append(buf, rv);
347   }
348   EXPECT_EQ(file_size - kOffset, total_bytes_read);
349   EXPECT_TRUE(data_read == kTestData + kOffset);
350   EXPECT_EQ(kTestData + kOffset, data_read);
351 }
352
353 TEST_F(FileStreamTest, AsyncRead_FromOffset) {
354   int64 file_size;
355   bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
356   EXPECT_TRUE(ok);
357
358   FileStream stream(NULL, base::MessageLoopProxy::current());
359   int flags = base::PLATFORM_FILE_OPEN |
360               base::PLATFORM_FILE_READ |
361               base::PLATFORM_FILE_ASYNC;
362   TestCompletionCallback callback;
363   int rv = stream.Open(temp_file_path(), flags, callback.callback());
364   EXPECT_EQ(ERR_IO_PENDING, rv);
365   EXPECT_EQ(OK, callback.WaitForResult());
366
367   TestInt64CompletionCallback callback64;
368   const int64 kOffset = 3;
369   rv = stream.Seek(FROM_BEGIN, kOffset, callback64.callback());
370   ASSERT_EQ(ERR_IO_PENDING, rv);
371   int64 new_offset = callback64.WaitForResult();
372   EXPECT_EQ(kOffset, new_offset);
373
374   int64 total_bytes_avail = stream.Available();
375   EXPECT_EQ(file_size - kOffset, total_bytes_avail);
376
377   int total_bytes_read = 0;
378
379   std::string data_read;
380   for (;;) {
381     scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
382     rv = stream.Read(buf.get(), buf->size(), callback.callback());
383     if (rv == ERR_IO_PENDING)
384       rv = callback.WaitForResult();
385     EXPECT_LE(0, rv);
386     if (rv <= 0)
387       break;
388     total_bytes_read += rv;
389     data_read.append(buf->data(), rv);
390   }
391   EXPECT_EQ(file_size - kOffset, total_bytes_read);
392   EXPECT_EQ(kTestData + kOffset, data_read);
393 }
394
395 TEST_F(FileStreamTest, SeekAround) {
396   FileStream stream(NULL, base::MessageLoopProxy::current());
397   int flags = base::PLATFORM_FILE_OPEN |
398               base::PLATFORM_FILE_READ;
399   int rv = stream.OpenSync(temp_file_path(), flags);
400   EXPECT_EQ(OK, rv);
401
402   const int64 kOffset = 3;
403   int64 new_offset = stream.SeekSync(FROM_BEGIN, kOffset);
404   EXPECT_EQ(kOffset, new_offset);
405
406   new_offset = stream.SeekSync(FROM_CURRENT, kOffset);
407   EXPECT_EQ(2 * kOffset, new_offset);
408
409   new_offset = stream.SeekSync(FROM_CURRENT, -kOffset);
410   EXPECT_EQ(kOffset, new_offset);
411
412   const int kTestDataLen = arraysize(kTestData) - 1;
413
414   new_offset = stream.SeekSync(FROM_END, -kTestDataLen);
415   EXPECT_EQ(0, new_offset);
416 }
417
418 TEST_F(FileStreamTest, AsyncSeekAround) {
419   FileStream stream(NULL, base::MessageLoopProxy::current());
420   int flags = base::PLATFORM_FILE_OPEN |
421               base::PLATFORM_FILE_ASYNC |
422               base::PLATFORM_FILE_READ;
423   TestCompletionCallback callback;
424   int rv = stream.Open(temp_file_path(), flags, callback.callback());
425   EXPECT_EQ(ERR_IO_PENDING, rv);
426   EXPECT_EQ(OK, callback.WaitForResult());
427
428   TestInt64CompletionCallback callback64;
429
430   const int64 kOffset = 3;
431   rv = stream.Seek(FROM_BEGIN, kOffset, callback64.callback());
432   ASSERT_EQ(ERR_IO_PENDING, rv);
433   int64 new_offset = callback64.WaitForResult();
434   EXPECT_EQ(kOffset, new_offset);
435
436   rv = stream.Seek(FROM_CURRENT, kOffset, callback64.callback());
437   ASSERT_EQ(ERR_IO_PENDING, rv);
438   new_offset = callback64.WaitForResult();
439   EXPECT_EQ(2 * kOffset, new_offset);
440
441   rv = stream.Seek(FROM_CURRENT, -kOffset, callback64.callback());
442   ASSERT_EQ(ERR_IO_PENDING, rv);
443   new_offset = callback64.WaitForResult();
444   EXPECT_EQ(kOffset, new_offset);
445
446   const int kTestDataLen = arraysize(kTestData) - 1;
447
448   rv = stream.Seek(FROM_END, -kTestDataLen, callback64.callback());
449   ASSERT_EQ(ERR_IO_PENDING, rv);
450   new_offset = callback64.WaitForResult();
451   EXPECT_EQ(0, new_offset);
452 }
453
454 TEST_F(FileStreamTest, BasicWrite) {
455   scoped_ptr<FileStream> stream(
456       new FileStream(NULL, base::MessageLoopProxy::current()));
457   int flags = base::PLATFORM_FILE_CREATE_ALWAYS |
458               base::PLATFORM_FILE_WRITE;
459   int rv = stream->OpenSync(temp_file_path(), flags);
460   EXPECT_EQ(OK, rv);
461
462   int64 file_size;
463   bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
464   EXPECT_TRUE(ok);
465   EXPECT_EQ(0, file_size);
466
467   rv = stream->WriteSync(kTestData, kTestDataSize);
468   EXPECT_EQ(kTestDataSize, rv);
469   stream.reset();
470
471   ok = file_util::GetFileSize(temp_file_path(), &file_size);
472   EXPECT_TRUE(ok);
473   EXPECT_EQ(kTestDataSize, file_size);
474 }
475
476 TEST_F(FileStreamTest, AsyncWrite) {
477   FileStream stream(NULL, base::MessageLoopProxy::current());
478   int flags = base::PLATFORM_FILE_CREATE_ALWAYS |
479               base::PLATFORM_FILE_WRITE |
480               base::PLATFORM_FILE_ASYNC;
481   TestCompletionCallback callback;
482   int rv = stream.Open(temp_file_path(), flags, callback.callback());
483   EXPECT_EQ(ERR_IO_PENDING, rv);
484   EXPECT_EQ(OK, callback.WaitForResult());
485
486   int64 file_size;
487   bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
488   EXPECT_TRUE(ok);
489   EXPECT_EQ(0, file_size);
490
491   int total_bytes_written = 0;
492
493   scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
494   scoped_refptr<DrainableIOBuffer> drainable =
495       new DrainableIOBuffer(buf.get(), buf->size());
496   while (total_bytes_written != kTestDataSize) {
497     rv = stream.Write(
498         drainable.get(), drainable->BytesRemaining(), callback.callback());
499     if (rv == ERR_IO_PENDING)
500       rv = callback.WaitForResult();
501     EXPECT_LT(0, rv);
502     if (rv <= 0)
503       break;
504     drainable->DidConsume(rv);
505     total_bytes_written += rv;
506   }
507   ok = file_util::GetFileSize(temp_file_path(), &file_size);
508   EXPECT_TRUE(ok);
509   EXPECT_EQ(file_size, total_bytes_written);
510 }
511
512 TEST_F(FileStreamTest, AsyncWrite_EarlyDelete) {
513   scoped_ptr<FileStream> stream(
514       new FileStream(NULL, base::MessageLoopProxy::current()));
515   int flags = base::PLATFORM_FILE_CREATE_ALWAYS |
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());
522
523   int64 file_size;
524   bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
525   EXPECT_TRUE(ok);
526   EXPECT_EQ(0, file_size);
527
528   scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
529   rv = stream->Write(buf.get(), buf->size(), callback.callback());
530   stream.reset();
531   if (rv < 0) {
532     EXPECT_EQ(ERR_IO_PENDING, rv);
533     // The callback should not be called if the request is cancelled.
534     base::RunLoop().RunUntilIdle();
535     EXPECT_FALSE(callback.have_result());
536   } else {
537     ok = file_util::GetFileSize(temp_file_path(), &file_size);
538     EXPECT_TRUE(ok);
539     EXPECT_EQ(file_size, rv);
540   }
541 }
542
543 TEST_F(FileStreamTest, BasicWrite_FromOffset) {
544   scoped_ptr<FileStream> stream(
545       new FileStream(NULL, base::MessageLoopProxy::current()));
546   int flags = base::PLATFORM_FILE_OPEN |
547               base::PLATFORM_FILE_WRITE;
548   int rv = stream->OpenSync(temp_file_path(), flags);
549   EXPECT_EQ(OK, rv);
550
551   int64 file_size;
552   bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
553   EXPECT_TRUE(ok);
554   EXPECT_EQ(kTestDataSize, file_size);
555
556   const int64 kOffset = 0;
557   int64 new_offset = stream->SeekSync(FROM_END, kOffset);
558   EXPECT_EQ(kTestDataSize, new_offset);
559
560   rv = stream->WriteSync(kTestData, kTestDataSize);
561   EXPECT_EQ(kTestDataSize, rv);
562   stream.reset();
563
564   ok = file_util::GetFileSize(temp_file_path(), &file_size);
565   EXPECT_TRUE(ok);
566   EXPECT_EQ(kTestDataSize * 2, file_size);
567 }
568
569 TEST_F(FileStreamTest, AsyncWrite_FromOffset) {
570   int64 file_size;
571   bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
572   EXPECT_TRUE(ok);
573
574   FileStream stream(NULL, base::MessageLoopProxy::current());
575   int flags = base::PLATFORM_FILE_OPEN |
576               base::PLATFORM_FILE_WRITE |
577               base::PLATFORM_FILE_ASYNC;
578   TestCompletionCallback callback;
579   int rv = stream.Open(temp_file_path(), flags, callback.callback());
580   EXPECT_EQ(ERR_IO_PENDING, rv);
581   EXPECT_EQ(OK, callback.WaitForResult());
582
583   TestInt64CompletionCallback callback64;
584   const int64 kOffset = 0;
585   rv = stream.Seek(FROM_END, kOffset, callback64.callback());
586   ASSERT_EQ(ERR_IO_PENDING, rv);
587   int64 new_offset = callback64.WaitForResult();
588   EXPECT_EQ(kTestDataSize, new_offset);
589
590   int total_bytes_written = 0;
591
592   scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
593   scoped_refptr<DrainableIOBuffer> drainable =
594       new DrainableIOBuffer(buf.get(), buf->size());
595   while (total_bytes_written != kTestDataSize) {
596     rv = stream.Write(
597         drainable.get(), drainable->BytesRemaining(), callback.callback());
598     if (rv == ERR_IO_PENDING)
599       rv = callback.WaitForResult();
600     EXPECT_LT(0, rv);
601     if (rv <= 0)
602       break;
603     drainable->DidConsume(rv);
604     total_bytes_written += rv;
605   }
606   ok = file_util::GetFileSize(temp_file_path(), &file_size);
607   EXPECT_TRUE(ok);
608   EXPECT_EQ(file_size, kTestDataSize * 2);
609 }
610
611 TEST_F(FileStreamTest, BasicReadWrite) {
612   int64 file_size;
613   bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
614   EXPECT_TRUE(ok);
615
616   scoped_ptr<FileStream> stream(
617       new FileStream(NULL, base::MessageLoopProxy::current()));
618   int flags = base::PLATFORM_FILE_OPEN |
619               base::PLATFORM_FILE_READ |
620               base::PLATFORM_FILE_WRITE;
621   int rv = stream->OpenSync(temp_file_path(), flags);
622   EXPECT_EQ(OK, rv);
623
624   int64 total_bytes_avail = stream->Available();
625   EXPECT_EQ(file_size, total_bytes_avail);
626
627   int total_bytes_read = 0;
628
629   std::string data_read;
630   for (;;) {
631     char buf[4];
632     rv = stream->ReadSync(buf, arraysize(buf));
633     EXPECT_LE(0, rv);
634     if (rv <= 0)
635       break;
636     total_bytes_read += rv;
637     data_read.append(buf, rv);
638   }
639   EXPECT_EQ(file_size, total_bytes_read);
640   EXPECT_TRUE(data_read == kTestData);
641
642   rv = stream->WriteSync(kTestData, kTestDataSize);
643   EXPECT_EQ(kTestDataSize, rv);
644   stream.reset();
645
646   ok = file_util::GetFileSize(temp_file_path(), &file_size);
647   EXPECT_TRUE(ok);
648   EXPECT_EQ(kTestDataSize * 2, file_size);
649 }
650
651 TEST_F(FileStreamTest, BasicWriteRead) {
652   int64 file_size;
653   bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
654   EXPECT_TRUE(ok);
655
656   scoped_ptr<FileStream> stream(
657       new FileStream(NULL, base::MessageLoopProxy::current()));
658   int flags = base::PLATFORM_FILE_OPEN |
659               base::PLATFORM_FILE_READ |
660               base::PLATFORM_FILE_WRITE;
661   int rv = stream->OpenSync(temp_file_path(), flags);
662   EXPECT_EQ(OK, rv);
663
664   int64 total_bytes_avail = stream->Available();
665   EXPECT_EQ(file_size, total_bytes_avail);
666
667   int64 offset = stream->SeekSync(FROM_END, 0);
668   EXPECT_EQ(offset, file_size);
669
670   rv = stream->WriteSync(kTestData, kTestDataSize);
671   EXPECT_EQ(kTestDataSize, rv);
672
673   offset = stream->SeekSync(FROM_BEGIN, 0);
674   EXPECT_EQ(0, offset);
675
676   int64 total_bytes_read = 0;
677
678   std::string data_read;
679   for (;;) {
680     char buf[4];
681     rv = stream->ReadSync(buf, arraysize(buf));
682     EXPECT_LE(0, rv);
683     if (rv <= 0)
684       break;
685     total_bytes_read += rv;
686     data_read.append(buf, rv);
687   }
688   stream.reset();
689
690   ok = file_util::GetFileSize(temp_file_path(), &file_size);
691   EXPECT_TRUE(ok);
692   EXPECT_EQ(kTestDataSize * 2, file_size);
693   EXPECT_EQ(kTestDataSize * 2, total_bytes_read);
694
695   const std::string kExpectedFileData =
696       std::string(kTestData) + std::string(kTestData);
697   EXPECT_EQ(kExpectedFileData, data_read);
698 }
699
700 TEST_F(FileStreamTest, BasicAsyncReadWrite) {
701   int64 file_size;
702   bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
703   EXPECT_TRUE(ok);
704
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());
715
716   int64 total_bytes_avail = stream->Available();
717   EXPECT_EQ(file_size, total_bytes_avail);
718
719   int64 total_bytes_read = 0;
720
721   std::string data_read;
722   for (;;) {
723     scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
724     rv = stream->Read(buf.get(), buf->size(), callback.callback());
725     if (rv == ERR_IO_PENDING)
726       rv = callback.WaitForResult();
727     EXPECT_LE(0, rv);
728     if (rv <= 0)
729       break;
730     total_bytes_read += rv;
731     data_read.append(buf->data(), rv);
732   }
733   EXPECT_EQ(file_size, total_bytes_read);
734   EXPECT_TRUE(data_read == kTestData);
735
736   int total_bytes_written = 0;
737
738   scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
739   scoped_refptr<DrainableIOBuffer> drainable =
740       new DrainableIOBuffer(buf.get(), buf->size());
741   while (total_bytes_written != kTestDataSize) {
742     rv = stream->Write(
743         drainable.get(), drainable->BytesRemaining(), callback.callback());
744     if (rv == ERR_IO_PENDING)
745       rv = callback.WaitForResult();
746     EXPECT_LT(0, rv);
747     if (rv <= 0)
748       break;
749     drainable->DidConsume(rv);
750     total_bytes_written += rv;
751   }
752
753   stream.reset();
754
755   ok = file_util::GetFileSize(temp_file_path(), &file_size);
756   EXPECT_TRUE(ok);
757   EXPECT_EQ(kTestDataSize * 2, file_size);
758 }
759
760 TEST_F(FileStreamTest, BasicAsyncWriteRead) {
761   int64 file_size;
762   bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
763   EXPECT_TRUE(ok);
764
765   scoped_ptr<FileStream> stream(
766       new FileStream(NULL, base::MessageLoopProxy::current()));
767   int flags = base::PLATFORM_FILE_OPEN |
768               base::PLATFORM_FILE_READ |
769               base::PLATFORM_FILE_WRITE |
770               base::PLATFORM_FILE_ASYNC;
771   TestCompletionCallback callback;
772   int rv = stream->Open(temp_file_path(), flags, callback.callback());
773   EXPECT_EQ(ERR_IO_PENDING, rv);
774   EXPECT_EQ(OK, callback.WaitForResult());
775
776   int64 total_bytes_avail = stream->Available();
777   EXPECT_EQ(file_size, total_bytes_avail);
778
779   TestInt64CompletionCallback callback64;
780   rv = stream->Seek(FROM_END, 0, callback64.callback());
781   ASSERT_EQ(ERR_IO_PENDING, rv);
782   int64 offset = callback64.WaitForResult();
783   EXPECT_EQ(offset, file_size);
784
785   int total_bytes_written = 0;
786
787   scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
788   scoped_refptr<DrainableIOBuffer> drainable =
789       new DrainableIOBuffer(buf.get(), buf->size());
790   while (total_bytes_written != kTestDataSize) {
791     rv = stream->Write(
792         drainable.get(), drainable->BytesRemaining(), callback.callback());
793     if (rv == ERR_IO_PENDING)
794       rv = callback.WaitForResult();
795     EXPECT_LT(0, rv);
796     if (rv <= 0)
797       break;
798     drainable->DidConsume(rv);
799     total_bytes_written += rv;
800   }
801
802   EXPECT_EQ(kTestDataSize, total_bytes_written);
803
804   rv = stream->Seek(FROM_BEGIN, 0, callback64.callback());
805   ASSERT_EQ(ERR_IO_PENDING, rv);
806   offset = callback64.WaitForResult();
807   EXPECT_EQ(0, offset);
808
809   int total_bytes_read = 0;
810
811   std::string data_read;
812   for (;;) {
813     scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
814     rv = stream->Read(buf.get(), buf->size(), callback.callback());
815     if (rv == ERR_IO_PENDING)
816       rv = callback.WaitForResult();
817     EXPECT_LE(0, rv);
818     if (rv <= 0)
819       break;
820     total_bytes_read += rv;
821     data_read.append(buf->data(), rv);
822   }
823   stream.reset();
824
825   ok = file_util::GetFileSize(temp_file_path(), &file_size);
826   EXPECT_TRUE(ok);
827   EXPECT_EQ(kTestDataSize * 2, file_size);
828
829   EXPECT_EQ(kTestDataSize * 2, total_bytes_read);
830   const std::string kExpectedFileData =
831       std::string(kTestData) + std::string(kTestData);
832   EXPECT_EQ(kExpectedFileData, data_read);
833 }
834
835 class TestWriteReadCompletionCallback {
836  public:
837   TestWriteReadCompletionCallback(FileStream* stream,
838                                   int* total_bytes_written,
839                                   int* total_bytes_read,
840                                   std::string* data_read)
841       : result_(0),
842         have_result_(false),
843         waiting_for_result_(false),
844         stream_(stream),
845         total_bytes_written_(total_bytes_written),
846         total_bytes_read_(total_bytes_read),
847         data_read_(data_read),
848         callback_(base::Bind(&TestWriteReadCompletionCallback::OnComplete,
849                              base::Unretained(this))),
850         test_data_(CreateTestDataBuffer()),
851         drainable_(new DrainableIOBuffer(test_data_.get(), kTestDataSize)) {}
852
853   int WaitForResult() {
854     DCHECK(!waiting_for_result_);
855     while (!have_result_) {
856       waiting_for_result_ = true;
857       base::RunLoop().Run();
858       waiting_for_result_ = false;
859     }
860     have_result_ = false;  // auto-reset for next callback
861     return result_;
862   }
863
864   const CompletionCallback& callback() const { return callback_; }
865
866  private:
867   void OnComplete(int result) {
868     DCHECK_LT(0, result);
869     *total_bytes_written_ += result;
870
871     int rv;
872
873     if (*total_bytes_written_ != kTestDataSize) {
874       // Recurse to finish writing all data.
875       int total_bytes_written = 0, total_bytes_read = 0;
876       std::string data_read;
877       TestWriteReadCompletionCallback callback(
878           stream_, &total_bytes_written, &total_bytes_read, &data_read);
879       rv = stream_->Write(
880           drainable_.get(), drainable_->BytesRemaining(), callback.callback());
881       DCHECK_EQ(ERR_IO_PENDING, rv);
882       rv = callback.WaitForResult();
883       drainable_->DidConsume(total_bytes_written);
884       *total_bytes_written_ += total_bytes_written;
885       *total_bytes_read_ += total_bytes_read;
886       *data_read_ += data_read;
887     } else {  // We're done writing all data.  Start reading the data.
888       stream_->SeekSync(FROM_BEGIN, 0);
889
890       TestCompletionCallback callback;
891       for (;;) {
892         scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
893         rv = stream_->Read(buf.get(), buf->size(), callback.callback());
894         if (rv == ERR_IO_PENDING) {
895           base::MessageLoop::ScopedNestableTaskAllower allow(
896               base::MessageLoop::current());
897           rv = callback.WaitForResult();
898         }
899         EXPECT_LE(0, rv);
900         if (rv <= 0)
901           break;
902         *total_bytes_read_ += rv;
903         data_read_->append(buf->data(), rv);
904       }
905     }
906
907     result_ = *total_bytes_written_;
908     have_result_ = true;
909     if (waiting_for_result_)
910       base::MessageLoop::current()->Quit();
911   }
912
913   int result_;
914   bool have_result_;
915   bool waiting_for_result_;
916   FileStream* stream_;
917   int* total_bytes_written_;
918   int* total_bytes_read_;
919   std::string* data_read_;
920   const CompletionCallback callback_;
921   scoped_refptr<IOBufferWithSize> test_data_;
922   scoped_refptr<DrainableIOBuffer> drainable_;
923
924   DISALLOW_COPY_AND_ASSIGN(TestWriteReadCompletionCallback);
925 };
926
927 TEST_F(FileStreamTest, AsyncWriteRead) {
928   int64 file_size;
929   bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
930   EXPECT_TRUE(ok);
931
932   scoped_ptr<FileStream> stream(
933       new FileStream(NULL, base::MessageLoopProxy::current()));
934   int flags = base::PLATFORM_FILE_OPEN |
935               base::PLATFORM_FILE_READ |
936               base::PLATFORM_FILE_WRITE |
937               base::PLATFORM_FILE_ASYNC;
938   TestCompletionCallback open_callback;
939   int rv = stream->Open(temp_file_path(), flags, open_callback.callback());
940   EXPECT_EQ(ERR_IO_PENDING, rv);
941   EXPECT_EQ(OK, open_callback.WaitForResult());
942
943   int64 total_bytes_avail = stream->Available();
944   EXPECT_EQ(file_size, total_bytes_avail);
945
946   int64 offset = stream->SeekSync(FROM_END, 0);
947   EXPECT_EQ(offset, file_size);
948
949   int total_bytes_written = 0;
950   int total_bytes_read = 0;
951   std::string data_read;
952   TestWriteReadCompletionCallback callback(stream.get(), &total_bytes_written,
953                                            &total_bytes_read, &data_read);
954
955   scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
956   rv = stream->Write(buf.get(), buf->size(), callback.callback());
957   if (rv == ERR_IO_PENDING)
958     rv = callback.WaitForResult();
959   EXPECT_LT(0, rv);
960   EXPECT_EQ(kTestDataSize, total_bytes_written);
961
962   stream.reset();
963
964   ok = file_util::GetFileSize(temp_file_path(), &file_size);
965   EXPECT_TRUE(ok);
966   EXPECT_EQ(kTestDataSize * 2, file_size);
967
968   EXPECT_EQ(kTestDataSize * 2, total_bytes_read);
969   const std::string kExpectedFileData =
970       std::string(kTestData) + std::string(kTestData);
971   EXPECT_EQ(kExpectedFileData, data_read);
972 }
973
974 class TestWriteCloseCompletionCallback {
975  public:
976   TestWriteCloseCompletionCallback(FileStream* stream, int* total_bytes_written)
977       : result_(0),
978         have_result_(false),
979         waiting_for_result_(false),
980         stream_(stream),
981         total_bytes_written_(total_bytes_written),
982         callback_(base::Bind(&TestWriteCloseCompletionCallback::OnComplete,
983                              base::Unretained(this))),
984         test_data_(CreateTestDataBuffer()),
985         drainable_(new DrainableIOBuffer(test_data_.get(), kTestDataSize)) {}
986
987   int WaitForResult() {
988     DCHECK(!waiting_for_result_);
989     while (!have_result_) {
990       waiting_for_result_ = true;
991       base::RunLoop().Run();
992       waiting_for_result_ = false;
993     }
994     have_result_ = false;  // auto-reset for next callback
995     return result_;
996   }
997
998   const CompletionCallback& callback() const { return callback_; }
999
1000  private:
1001   void OnComplete(int result) {
1002     DCHECK_LT(0, result);
1003     *total_bytes_written_ += result;
1004
1005     int rv;
1006
1007     if (*total_bytes_written_ != kTestDataSize) {
1008       // Recurse to finish writing all data.
1009       int total_bytes_written = 0;
1010       TestWriteCloseCompletionCallback callback(stream_, &total_bytes_written);
1011       rv = stream_->Write(
1012           drainable_.get(), drainable_->BytesRemaining(), callback.callback());
1013       DCHECK_EQ(ERR_IO_PENDING, rv);
1014       rv = callback.WaitForResult();
1015       drainable_->DidConsume(total_bytes_written);
1016       *total_bytes_written_ += total_bytes_written;
1017     }
1018
1019     result_ = *total_bytes_written_;
1020     have_result_ = true;
1021     if (waiting_for_result_)
1022       base::MessageLoop::current()->Quit();
1023   }
1024
1025   int result_;
1026   bool have_result_;
1027   bool waiting_for_result_;
1028   FileStream* stream_;
1029   int* total_bytes_written_;
1030   const CompletionCallback callback_;
1031   scoped_refptr<IOBufferWithSize> test_data_;
1032   scoped_refptr<DrainableIOBuffer> drainable_;
1033
1034   DISALLOW_COPY_AND_ASSIGN(TestWriteCloseCompletionCallback);
1035 };
1036
1037 TEST_F(FileStreamTest, AsyncWriteClose) {
1038   int64 file_size;
1039   bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
1040   EXPECT_TRUE(ok);
1041
1042   scoped_ptr<FileStream> stream(
1043       new FileStream(NULL, base::MessageLoopProxy::current()));
1044   int flags = base::PLATFORM_FILE_OPEN |
1045               base::PLATFORM_FILE_READ |
1046               base::PLATFORM_FILE_WRITE |
1047               base::PLATFORM_FILE_ASYNC;
1048   TestCompletionCallback open_callback;
1049   int rv = stream->Open(temp_file_path(), flags, open_callback.callback());
1050   EXPECT_EQ(ERR_IO_PENDING, rv);
1051   EXPECT_EQ(OK, open_callback.WaitForResult());
1052
1053   int64 total_bytes_avail = stream->Available();
1054   EXPECT_EQ(file_size, total_bytes_avail);
1055
1056   int64 offset = stream->SeekSync(FROM_END, 0);
1057   EXPECT_EQ(offset, file_size);
1058
1059   int total_bytes_written = 0;
1060   TestWriteCloseCompletionCallback callback(stream.get(), &total_bytes_written);
1061
1062   scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
1063   rv = stream->Write(buf.get(), buf->size(), callback.callback());
1064   if (rv == ERR_IO_PENDING)
1065     total_bytes_written = callback.WaitForResult();
1066   EXPECT_LT(0, total_bytes_written);
1067   EXPECT_EQ(kTestDataSize, total_bytes_written);
1068
1069   stream.reset();
1070
1071   ok = file_util::GetFileSize(temp_file_path(), &file_size);
1072   EXPECT_TRUE(ok);
1073   EXPECT_EQ(kTestDataSize * 2, file_size);
1074 }
1075
1076 // Tests truncating a file.
1077 TEST_F(FileStreamTest, Truncate) {
1078   int flags = base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE;
1079
1080   scoped_ptr<FileStream> write_stream(
1081       new FileStream(NULL, base::MessageLoopProxy::current()));
1082   ASSERT_EQ(OK, write_stream->OpenSync(temp_file_path(), flags));
1083
1084   // Write some data to the file.
1085   const char test_data[] = "0123456789";
1086   write_stream->WriteSync(test_data, arraysize(test_data));
1087
1088   // Truncate the file.
1089   ASSERT_EQ(4, write_stream->Truncate(4));
1090
1091   // Write again.
1092   write_stream->WriteSync(test_data, 4);
1093
1094   // Close the stream.
1095   write_stream.reset();
1096
1097   // Read in the contents and make sure we get back what we expected.
1098   std::string read_contents;
1099   EXPECT_TRUE(base::ReadFileToString(temp_file_path(), &read_contents));
1100
1101   EXPECT_EQ("01230123", read_contents);
1102 }
1103
1104 TEST_F(FileStreamTest, AsyncOpenAndDelete) {
1105   scoped_ptr<FileStream> stream(
1106       new FileStream(NULL, base::MessageLoopProxy::current()));
1107   int flags = base::PLATFORM_FILE_OPEN |
1108       base::PLATFORM_FILE_WRITE |
1109       base::PLATFORM_FILE_ASYNC;
1110   TestCompletionCallback open_callback;
1111   int rv = stream->Open(temp_file_path(), flags, open_callback.callback());
1112   EXPECT_EQ(ERR_IO_PENDING, rv);
1113
1114   // Delete the stream without waiting for the open operation to be
1115   // complete. Should be safe.
1116   stream.reset();
1117   // open_callback won't be called.
1118   base::RunLoop().RunUntilIdle();
1119   EXPECT_FALSE(open_callback.have_result());
1120 }
1121
1122 // Verify that async Write() errors are mapped correctly.
1123 TEST_F(FileStreamTest, AsyncWriteError) {
1124   // Try opening file as read-only and then writing to it using FileStream.
1125   base::PlatformFile file = base::CreatePlatformFile(
1126       temp_file_path(),
1127       base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ |
1128           base::PLATFORM_FILE_ASYNC,
1129       NULL,
1130       NULL);
1131   ASSERT_NE(base::kInvalidPlatformFileValue, file);
1132
1133   int flags = base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE |
1134               base::PLATFORM_FILE_ASYNC;
1135   scoped_ptr<FileStream> stream(
1136       new FileStream(file, flags, NULL, base::MessageLoopProxy::current()));
1137
1138   scoped_refptr<IOBuffer> buf = new IOBuffer(1);
1139   buf->data()[0] = 0;
1140
1141   TestCompletionCallback callback;
1142   int rv = stream->Write(buf.get(), 1, callback.callback());
1143   if (rv == ERR_IO_PENDING)
1144     rv = callback.WaitForResult();
1145   EXPECT_LT(rv, 0);
1146
1147   base::ClosePlatformFile(file);
1148 }
1149
1150 // Verify that async Read() errors are mapped correctly.
1151 TEST_F(FileStreamTest, AsyncReadError) {
1152   // Try opening file for write and then reading from it using FileStream.
1153   base::PlatformFile file = base::CreatePlatformFile(
1154       temp_file_path(),
1155       base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE |
1156           base::PLATFORM_FILE_ASYNC,
1157       NULL,
1158       NULL);
1159   ASSERT_NE(base::kInvalidPlatformFileValue, file);
1160
1161   int flags = base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ |
1162               base::PLATFORM_FILE_ASYNC;
1163   scoped_ptr<FileStream> stream(
1164       new FileStream(file, flags, NULL, base::MessageLoopProxy::current()));
1165
1166   scoped_refptr<IOBuffer> buf = new IOBuffer(1);
1167   TestCompletionCallback callback;
1168   int rv = stream->Read(buf.get(), 1, callback.callback());
1169   if (rv == ERR_IO_PENDING)
1170     rv = callback.WaitForResult();
1171   EXPECT_LT(rv, 0);
1172
1173   base::ClosePlatformFile(file);
1174 }
1175
1176 }  // namespace
1177
1178 }  // namespace net