1 // Copyright 2014 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 "content/browser/loader/temporary_file_stream.h" 6 7 #include <string.h> 8 9 #include <string> 10 11 #include "base/basictypes.h" 12 #include "base/bind.h" 13 #include "base/files/file_path.h" 14 #include "base/files/file_util.h" 15 #include "base/run_loop.h" 16 #include "content/public/test/test_browser_thread_bundle.h" 17 #include "net/base/file_stream.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 "storage/common/blob/shareable_file_reference.h" 22 #include "testing/gtest/include/gtest/gtest.h" 23 24 using storage::ShareableFileReference; 25 26 namespace content { 27 28 namespace { 29 30 const char kTestData[] = "0123456789"; 31 const int kTestDataSize = arraysize(kTestData) - 1; 32 33 class WaitForFileStream { 34 public: 35 base::File::Error error() const { return error_; } 36 net::FileStream* file_stream() const { return file_stream_.get(); } 37 ShareableFileReference* deletable_file() const { 38 return deletable_file_.get(); 39 } 40 41 void OnFileStreamCreated(base::File::Error error, 42 scoped_ptr<net::FileStream> file_stream, 43 ShareableFileReference* deletable_file) { 44 error_ = error; 45 file_stream_ = file_stream.Pass(); 46 deletable_file_ = deletable_file; 47 loop_.Quit(); 48 } 49 50 void Wait() { 51 loop_.Run(); 52 } 53 54 void Release() { 55 file_stream_.reset(NULL); 56 deletable_file_ = NULL; 57 } 58 private: 59 base::RunLoop loop_; 60 base::File::Error error_; 61 scoped_ptr<net::FileStream> file_stream_; 62 scoped_refptr<ShareableFileReference> deletable_file_; 63 }; 64 65 } // namespace 66 67 TEST(TemporaryFileStreamTest, Basic) { 68 TestBrowserThreadBundle thread_bundle(TestBrowserThreadBundle::IO_MAINLOOP); 69 70 // Create a temporary. 71 WaitForFileStream file_stream_waiter; 72 CreateTemporaryFileStream(base::Bind(&WaitForFileStream::OnFileStreamCreated, 73 base::Unretained(&file_stream_waiter))); 74 file_stream_waiter.Wait(); 75 76 // The temporary should exist. 77 EXPECT_EQ(base::File::FILE_OK, file_stream_waiter.error()); 78 base::FilePath file_path = file_stream_waiter.deletable_file()->path(); 79 EXPECT_TRUE(base::PathExists(file_path)); 80 81 // Write some data to the temporary. 82 int bytes_written = 0; 83 scoped_refptr<net::IOBufferWithSize> buf = 84 new net::IOBufferWithSize(kTestDataSize); 85 memcpy(buf->data(), kTestData, kTestDataSize); 86 scoped_refptr<net::DrainableIOBuffer> drainable = 87 new net::DrainableIOBuffer(buf.get(), buf->size()); 88 while (bytes_written != kTestDataSize) { 89 net::TestCompletionCallback write_callback; 90 int rv = file_stream_waiter.file_stream()->Write( 91 drainable.get(), drainable->BytesRemaining(), 92 write_callback.callback()); 93 if (rv == net::ERR_IO_PENDING) 94 rv = write_callback.WaitForResult(); 95 ASSERT_LT(0, rv); 96 drainable->DidConsume(rv); 97 bytes_written += rv; 98 } 99 100 // Verify the data matches. 101 std::string contents; 102 ASSERT_TRUE(base::ReadFileToString(file_path, &contents)); 103 EXPECT_EQ(kTestData, contents); 104 105 // Close the file. 106 net::TestCompletionCallback close_callback; 107 int rv = file_stream_waiter.file_stream()->Close(close_callback.callback()); 108 if (rv == net::ERR_IO_PENDING) 109 rv = close_callback.WaitForResult(); 110 EXPECT_EQ(net::OK, rv); 111 112 // Release everything. The file should be gone now. 113 file_stream_waiter.Release(); 114 base::MessageLoop::current()->RunUntilIdle(); 115 116 // The temporary should be gone now. 117 EXPECT_FALSE(base::PathExists(file_path)); 118 } 119 120 } // content 121