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/upload_file_element_reader.h"
7 #include "base/files/file_util.h"
8 #include "base/files/scoped_temp_dir.h"
9 #include "base/run_loop.h"
10 #include "base/thread_task_runner_handle.h"
11 #include "net/base/io_buffer.h"
12 #include "net/base/net_errors.h"
13 #include "net/base/test_completion_callback.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 #include "testing/platform_test.h"
19 class UploadFileElementReaderTest
: public PlatformTest
{
21 void SetUp() override
{
22 PlatformTest::SetUp();
23 // Some tests (*.ReadPartially) rely on bytes_.size() being even.
24 const char kData
[] = "123456789abcdefghi";
25 bytes_
.assign(kData
, kData
+ arraysize(kData
) - 1);
27 ASSERT_TRUE(temp_dir_
.CreateUniqueTempDir());
29 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_
.path(),
32 static_cast<int>(bytes_
.size()),
33 base::WriteFile(temp_file_path_
, &bytes_
[0], bytes_
.size()));
35 reader_
.reset(new UploadFileElementReader(
36 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path_
, 0,
37 kuint64max
, base::Time()));
38 TestCompletionCallback callback
;
39 ASSERT_EQ(ERR_IO_PENDING
, reader_
->Init(callback
.callback()));
40 EXPECT_EQ(OK
, callback
.WaitForResult());
41 EXPECT_EQ(bytes_
.size(), reader_
->GetContentLength());
42 EXPECT_EQ(bytes_
.size(), reader_
->BytesRemaining());
43 EXPECT_FALSE(reader_
->IsInMemory());
46 ~UploadFileElementReaderTest() override
{
48 base::RunLoop().RunUntilIdle();
51 std::vector
<char> bytes_
;
52 scoped_ptr
<UploadElementReader
> reader_
;
53 base::ScopedTempDir temp_dir_
;
54 base::FilePath temp_file_path_
;
57 TEST_F(UploadFileElementReaderTest
, ReadPartially
) {
58 const size_t kHalfSize
= bytes_
.size() / 2;
59 ASSERT_EQ(bytes_
.size(), kHalfSize
* 2);
60 std::vector
<char> buf(kHalfSize
);
61 scoped_refptr
<IOBuffer
> wrapped_buffer
= new WrappedIOBuffer(&buf
[0]);
62 TestCompletionCallback read_callback1
;
63 ASSERT_EQ(ERR_IO_PENDING
,
65 wrapped_buffer
.get(), buf
.size(), read_callback1
.callback()));
66 EXPECT_EQ(static_cast<int>(buf
.size()), read_callback1
.WaitForResult());
67 EXPECT_EQ(bytes_
.size() - buf
.size(), reader_
->BytesRemaining());
68 EXPECT_EQ(std::vector
<char>(bytes_
.begin(), bytes_
.begin() + kHalfSize
), buf
);
70 TestCompletionCallback read_callback2
;
71 EXPECT_EQ(ERR_IO_PENDING
,
73 wrapped_buffer
.get(), buf
.size(), read_callback2
.callback()));
74 EXPECT_EQ(static_cast<int>(buf
.size()), read_callback2
.WaitForResult());
75 EXPECT_EQ(0U, reader_
->BytesRemaining());
76 EXPECT_EQ(std::vector
<char>(bytes_
.begin() + kHalfSize
, bytes_
.end()), buf
);
79 TEST_F(UploadFileElementReaderTest
, ReadAll
) {
80 std::vector
<char> buf(bytes_
.size());
81 scoped_refptr
<IOBuffer
> wrapped_buffer
= new WrappedIOBuffer(&buf
[0]);
82 TestCompletionCallback read_callback
;
83 ASSERT_EQ(ERR_IO_PENDING
,
85 wrapped_buffer
.get(), buf
.size(), read_callback
.callback()));
86 EXPECT_EQ(static_cast<int>(buf
.size()), read_callback
.WaitForResult());
87 EXPECT_EQ(0U, reader_
->BytesRemaining());
88 EXPECT_EQ(bytes_
, buf
);
92 wrapped_buffer
.get(), buf
.size(), read_callback
.callback()));
95 TEST_F(UploadFileElementReaderTest
, ReadTooMuch
) {
96 const size_t kTooLargeSize
= bytes_
.size() * 2;
97 std::vector
<char> buf(kTooLargeSize
);
98 scoped_refptr
<IOBuffer
> wrapped_buffer
= new WrappedIOBuffer(&buf
[0]);
99 TestCompletionCallback read_callback
;
100 ASSERT_EQ(ERR_IO_PENDING
,
102 wrapped_buffer
.get(), buf
.size(), read_callback
.callback()));
103 EXPECT_EQ(static_cast<int>(bytes_
.size()), read_callback
.WaitForResult());
104 EXPECT_EQ(0U, reader_
->BytesRemaining());
105 buf
.resize(bytes_
.size()); // Resize to compare.
106 EXPECT_EQ(bytes_
, buf
);
109 TEST_F(UploadFileElementReaderTest
, MultipleInit
) {
110 std::vector
<char> buf(bytes_
.size());
111 scoped_refptr
<IOBuffer
> wrapped_buffer
= new WrappedIOBuffer(&buf
[0]);
114 TestCompletionCallback read_callback1
;
115 ASSERT_EQ(ERR_IO_PENDING
,
117 wrapped_buffer
.get(), buf
.size(), read_callback1
.callback()));
118 EXPECT_EQ(static_cast<int>(buf
.size()), read_callback1
.WaitForResult());
119 EXPECT_EQ(0U, reader_
->BytesRemaining());
120 EXPECT_EQ(bytes_
, buf
);
122 // Call Init() again to reset the state.
123 TestCompletionCallback init_callback
;
124 ASSERT_EQ(ERR_IO_PENDING
, reader_
->Init(init_callback
.callback()));
125 EXPECT_EQ(OK
, init_callback
.WaitForResult());
126 EXPECT_EQ(bytes_
.size(), reader_
->GetContentLength());
127 EXPECT_EQ(bytes_
.size(), reader_
->BytesRemaining());
130 TestCompletionCallback read_callback2
;
131 ASSERT_EQ(ERR_IO_PENDING
,
133 wrapped_buffer
.get(), buf
.size(), read_callback2
.callback()));
134 EXPECT_EQ(static_cast<int>(buf
.size()), read_callback2
.WaitForResult());
135 EXPECT_EQ(0U, reader_
->BytesRemaining());
136 EXPECT_EQ(bytes_
, buf
);
139 TEST_F(UploadFileElementReaderTest
, InitDuringAsyncOperation
) {
140 std::vector
<char> buf(bytes_
.size());
141 scoped_refptr
<IOBuffer
> wrapped_buffer
= new WrappedIOBuffer(&buf
[0]);
143 // Start reading all.
144 TestCompletionCallback read_callback1
;
145 EXPECT_EQ(ERR_IO_PENDING
,
147 wrapped_buffer
.get(), buf
.size(), read_callback1
.callback()));
149 // Call Init to cancel the previous read.
150 TestCompletionCallback init_callback1
;
151 EXPECT_EQ(ERR_IO_PENDING
, reader_
->Init(init_callback1
.callback()));
153 // Call Init again to cancel the previous init.
154 TestCompletionCallback init_callback2
;
155 EXPECT_EQ(ERR_IO_PENDING
, reader_
->Init(init_callback2
.callback()));
156 EXPECT_EQ(OK
, init_callback2
.WaitForResult());
157 EXPECT_EQ(bytes_
.size(), reader_
->GetContentLength());
158 EXPECT_EQ(bytes_
.size(), reader_
->BytesRemaining());
161 std::vector
<char> buf2(bytes_
.size() / 2);
162 scoped_refptr
<IOBuffer
> wrapped_buffer2
= new WrappedIOBuffer(&buf2
[0]);
163 TestCompletionCallback read_callback2
;
164 EXPECT_EQ(ERR_IO_PENDING
,
166 wrapped_buffer2
.get(), buf2
.size(), read_callback2
.callback()));
167 EXPECT_EQ(static_cast<int>(buf2
.size()), read_callback2
.WaitForResult());
168 EXPECT_EQ(bytes_
.size() - buf2
.size(), reader_
->BytesRemaining());
169 EXPECT_EQ(std::vector
<char>(bytes_
.begin(), bytes_
.begin() + buf2
.size()),
172 // Make sure callbacks are not called for cancelled operations.
173 EXPECT_FALSE(read_callback1
.have_result());
174 EXPECT_FALSE(init_callback1
.have_result());
177 TEST_F(UploadFileElementReaderTest
, Range
) {
178 const uint64_t kOffset
= 2;
179 const uint64_t kLength
= bytes_
.size() - kOffset
* 3;
180 reader_
.reset(new UploadFileElementReader(
181 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path_
, kOffset
,
182 kLength
, base::Time()));
183 TestCompletionCallback init_callback
;
184 ASSERT_EQ(ERR_IO_PENDING
, reader_
->Init(init_callback
.callback()));
185 EXPECT_EQ(OK
, init_callback
.WaitForResult());
186 EXPECT_EQ(kLength
, reader_
->GetContentLength());
187 EXPECT_EQ(kLength
, reader_
->BytesRemaining());
188 std::vector
<char> buf(kLength
);
189 scoped_refptr
<IOBuffer
> wrapped_buffer
= new WrappedIOBuffer(&buf
[0]);
190 TestCompletionCallback read_callback
;
193 reader_
->Read(wrapped_buffer
.get(), kLength
, read_callback
.callback()));
194 EXPECT_EQ(static_cast<int>(kLength
), read_callback
.WaitForResult());
195 const std::vector
<char> expected(bytes_
.begin() + kOffset
,
196 bytes_
.begin() + kOffset
+ kLength
);
197 EXPECT_EQ(expected
, buf
);
200 TEST_F(UploadFileElementReaderTest
, FileChanged
) {
201 base::File::Info info
;
202 ASSERT_TRUE(base::GetFileInfo(temp_file_path_
, &info
));
204 // Expect one second before the actual modification time to simulate change.
205 const base::Time expected_modification_time
=
206 info
.last_modified
- base::TimeDelta::FromSeconds(1);
207 reader_
.reset(new UploadFileElementReader(
208 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path_
, 0, kuint64max
,
209 expected_modification_time
));
210 TestCompletionCallback init_callback
;
211 ASSERT_EQ(ERR_IO_PENDING
, reader_
->Init(init_callback
.callback()));
212 EXPECT_EQ(ERR_UPLOAD_FILE_CHANGED
, init_callback
.WaitForResult());
215 TEST_F(UploadFileElementReaderTest
, InexactExpectedTimeStamp
) {
216 base::File::Info info
;
217 ASSERT_TRUE(base::GetFileInfo(temp_file_path_
, &info
));
219 const base::Time expected_modification_time
=
220 info
.last_modified
- base::TimeDelta::FromMilliseconds(900);
221 reader_
.reset(new UploadFileElementReader(
222 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path_
, 0, kuint64max
,
223 expected_modification_time
));
224 TestCompletionCallback init_callback
;
225 ASSERT_EQ(ERR_IO_PENDING
, reader_
->Init(init_callback
.callback()));
226 EXPECT_EQ(OK
, init_callback
.WaitForResult());
229 TEST_F(UploadFileElementReaderTest
, WrongPath
) {
230 const base::FilePath
wrong_path(FILE_PATH_LITERAL("wrong_path"));
232 new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
233 wrong_path
, 0, kuint64max
, base::Time()));
234 TestCompletionCallback init_callback
;
235 ASSERT_EQ(ERR_IO_PENDING
, reader_
->Init(init_callback
.callback()));
236 EXPECT_EQ(ERR_FILE_NOT_FOUND
, init_callback
.WaitForResult());