Add ICU message format support
[chromium-blink-merge.git] / content / browser / fileapi / local_file_stream_reader_unittest.cc
blobd8e30ce7ec56ad846d1713e5caa65719d8d8264b
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.
5 #include "storage/browser/fileapi/local_file_stream_reader.h"
7 #include <string>
9 #include "base/files/file.h"
10 #include "base/files/file_path.h"
11 #include "base/files/file_util.h"
12 #include "base/files/scoped_temp_dir.h"
13 #include "base/location.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/run_loop.h"
16 #include "base/single_thread_task_runner.h"
17 #include "base/threading/thread.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"
23 using storage::LocalFileStreamReader;
25 namespace content {
27 namespace {
29 const char kTestData[] = "0123456789";
30 const int kTestDataSize = arraysize(kTestData) - 1;
32 void ReadFromReader(LocalFileStreamReader* reader,
33 std::string* data, size_t size,
34 int* result) {
35 ASSERT_TRUE(reader != NULL);
36 ASSERT_TRUE(result != NULL);
37 *result = net::OK;
38 net::TestCompletionCallback callback;
39 size_t total_bytes_read = 0;
40 while (total_bytes_read < size) {
41 scoped_refptr<net::IOBufferWithSize> buf(
42 new net::IOBufferWithSize(size - total_bytes_read));
43 int rv = reader->Read(buf.get(), buf->size(), callback.callback());
44 if (rv == net::ERR_IO_PENDING)
45 rv = callback.WaitForResult();
46 if (rv < 0)
47 *result = rv;
48 if (rv <= 0)
49 break;
50 total_bytes_read += rv;
51 data->append(buf->data(), rv);
55 void NeverCalled(int) { ADD_FAILURE(); }
56 void EmptyCallback() {}
58 void QuitLoop() {
59 base::MessageLoop::current()->Quit();
62 } // namespace
64 class LocalFileStreamReaderTest : public testing::Test {
65 public:
66 LocalFileStreamReaderTest()
67 : file_thread_("FileUtilProxyTestFileThread") {}
69 void SetUp() override {
70 ASSERT_TRUE(file_thread_.Start());
71 ASSERT_TRUE(dir_.CreateUniqueTempDir());
73 base::WriteFile(test_path(), kTestData, kTestDataSize);
74 base::File::Info info;
75 ASSERT_TRUE(base::GetFileInfo(test_path(), &info));
76 test_file_modification_time_ = info.last_modified;
79 void TearDown() override {
80 // Give another chance for deleted streams to perform Close.
81 base::RunLoop().RunUntilIdle();
82 file_thread_.Stop();
83 base::RunLoop().RunUntilIdle();
86 protected:
87 LocalFileStreamReader* CreateFileReader(
88 const base::FilePath& path,
89 int64 initial_offset,
90 const base::Time& expected_modification_time) {
91 return new LocalFileStreamReader(
92 file_task_runner(),
93 path,
94 initial_offset,
95 expected_modification_time);
98 void TouchTestFile() {
99 base::Time new_modified_time =
100 test_file_modification_time() - base::TimeDelta::FromSeconds(1);
101 ASSERT_TRUE(base::TouchFile(test_path(),
102 test_file_modification_time(),
103 new_modified_time));
106 base::SingleThreadTaskRunner* file_task_runner() const {
107 return file_thread_.task_runner().get();
110 base::FilePath test_dir() const { return dir_.path(); }
111 base::FilePath test_path() const { return dir_.path().AppendASCII("test"); }
112 base::Time test_file_modification_time() const {
113 return test_file_modification_time_;
116 void EnsureFileTaskFinished() {
117 file_task_runner()->PostTaskAndReply(
118 FROM_HERE, base::Bind(&EmptyCallback), base::Bind(&QuitLoop));
119 base::MessageLoop::current()->Run();
122 private:
123 base::MessageLoopForIO message_loop_;
124 base::Thread file_thread_;
125 base::ScopedTempDir dir_;
126 base::Time test_file_modification_time_;
129 TEST_F(LocalFileStreamReaderTest, NonExistent) {
130 base::FilePath nonexistent_path = test_dir().AppendASCII("nonexistent");
131 scoped_ptr<LocalFileStreamReader> reader(
132 CreateFileReader(nonexistent_path, 0, base::Time()));
133 int result = 0;
134 std::string data;
135 ReadFromReader(reader.get(), &data, 10, &result);
136 ASSERT_EQ(net::ERR_FILE_NOT_FOUND, result);
137 ASSERT_EQ(0U, data.size());
140 TEST_F(LocalFileStreamReaderTest, Empty) {
141 base::FilePath empty_path = test_dir().AppendASCII("empty");
142 base::File file(empty_path, base::File::FLAG_CREATE | base::File::FLAG_READ);
143 ASSERT_TRUE(file.IsValid());
144 file.Close();
146 scoped_ptr<LocalFileStreamReader> reader(
147 CreateFileReader(empty_path, 0, base::Time()));
148 int result = 0;
149 std::string data;
150 ReadFromReader(reader.get(), &data, 10, &result);
151 ASSERT_EQ(net::OK, result);
152 ASSERT_EQ(0U, data.size());
154 net::TestInt64CompletionCallback callback;
155 int64 length_result = reader->GetLength(callback.callback());
156 if (length_result == net::ERR_IO_PENDING)
157 length_result = callback.WaitForResult();
158 ASSERT_EQ(0, result);
161 TEST_F(LocalFileStreamReaderTest, GetLengthNormal) {
162 scoped_ptr<LocalFileStreamReader> reader(
163 CreateFileReader(test_path(), 0, test_file_modification_time()));
164 net::TestInt64CompletionCallback callback;
165 int64 result = reader->GetLength(callback.callback());
166 if (result == net::ERR_IO_PENDING)
167 result = callback.WaitForResult();
168 ASSERT_EQ(kTestDataSize, result);
171 TEST_F(LocalFileStreamReaderTest, GetLengthAfterModified) {
172 // Touch file so that the file's modification time becomes different
173 // from what we expect.
174 TouchTestFile();
176 scoped_ptr<LocalFileStreamReader> reader(
177 CreateFileReader(test_path(), 0, test_file_modification_time()));
178 net::TestInt64CompletionCallback callback;
179 int64 result = reader->GetLength(callback.callback());
180 if (result == net::ERR_IO_PENDING)
181 result = callback.WaitForResult();
182 ASSERT_EQ(net::ERR_UPLOAD_FILE_CHANGED, result);
184 // With NULL expected modification time this should work.
185 reader.reset(CreateFileReader(test_path(), 0, base::Time()));
186 result = reader->GetLength(callback.callback());
187 if (result == net::ERR_IO_PENDING)
188 result = callback.WaitForResult();
189 ASSERT_EQ(kTestDataSize, result);
192 TEST_F(LocalFileStreamReaderTest, GetLengthWithOffset) {
193 scoped_ptr<LocalFileStreamReader> reader(
194 CreateFileReader(test_path(), 3, base::Time()));
195 net::TestInt64CompletionCallback callback;
196 int64 result = reader->GetLength(callback.callback());
197 if (result == net::ERR_IO_PENDING)
198 result = callback.WaitForResult();
199 // Initial offset does not affect the result of GetLength.
200 ASSERT_EQ(kTestDataSize, result);
203 TEST_F(LocalFileStreamReaderTest, ReadNormal) {
204 scoped_ptr<LocalFileStreamReader> reader(
205 CreateFileReader(test_path(), 0, test_file_modification_time()));
206 int result = 0;
207 std::string data;
208 ReadFromReader(reader.get(), &data, kTestDataSize, &result);
209 ASSERT_EQ(net::OK, result);
210 ASSERT_EQ(kTestData, data);
213 TEST_F(LocalFileStreamReaderTest, ReadAfterModified) {
214 // Touch file so that the file's modification time becomes different
215 // from what we expect.
216 TouchTestFile();
218 scoped_ptr<LocalFileStreamReader> reader(
219 CreateFileReader(test_path(), 0, test_file_modification_time()));
220 int result = 0;
221 std::string data;
222 ReadFromReader(reader.get(), &data, kTestDataSize, &result);
223 ASSERT_EQ(net::ERR_UPLOAD_FILE_CHANGED, result);
224 ASSERT_EQ(0U, data.size());
226 // With NULL expected modification time this should work.
227 data.clear();
228 reader.reset(CreateFileReader(test_path(), 0, base::Time()));
229 ReadFromReader(reader.get(), &data, kTestDataSize, &result);
230 ASSERT_EQ(net::OK, result);
231 ASSERT_EQ(kTestData, data);
234 TEST_F(LocalFileStreamReaderTest, ReadWithOffset) {
235 scoped_ptr<LocalFileStreamReader> reader(
236 CreateFileReader(test_path(), 3, base::Time()));
237 int result = 0;
238 std::string data;
239 ReadFromReader(reader.get(), &data, kTestDataSize, &result);
240 ASSERT_EQ(net::OK, result);
241 ASSERT_EQ(&kTestData[3], data);
244 TEST_F(LocalFileStreamReaderTest, DeleteWithUnfinishedRead) {
245 scoped_ptr<LocalFileStreamReader> reader(
246 CreateFileReader(test_path(), 0, base::Time()));
248 net::TestCompletionCallback callback;
249 scoped_refptr<net::IOBufferWithSize> buf(
250 new net::IOBufferWithSize(kTestDataSize));
251 int rv = reader->Read(buf.get(), buf->size(), base::Bind(&NeverCalled));
252 ASSERT_TRUE(rv == net::ERR_IO_PENDING || rv >= 0);
254 // Delete immediately.
255 // Should not crash; nor should NeverCalled be callback.
256 reader.reset();
257 EnsureFileTaskFinished();
260 } // namespace content