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 "net/url_request/url_fetcher_response_writer.h"
6
7#include "base/files/file_util.h"
8#include "base/files/scoped_temp_dir.h"
9#include "base/message_loop/message_loop_proxy.h"
10#include "base/run_loop.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/platform_test.h"
15
16namespace net {
17
18namespace {
19
20const char kData[] = "Hello!";
21
22}  // namespace
23
24class URLFetcherStringWriterTest : public PlatformTest {
25 protected:
26  virtual void SetUp() OVERRIDE {
27    writer_.reset(new URLFetcherStringWriter);
28    buf_ = new StringIOBuffer(kData);
29  }
30
31  scoped_ptr<URLFetcherStringWriter> writer_;
32  scoped_refptr<StringIOBuffer> buf_;
33};
34
35TEST_F(URLFetcherStringWriterTest, Basic) {
36  int rv = 0;
37  // Initialize(), Write() and Finish().
38  TestCompletionCallback callback;
39  rv = writer_->Initialize(callback.callback());
40  EXPECT_EQ(OK, callback.GetResult(rv));
41  rv = writer_->Write(buf_.get(), buf_->size(), callback.callback());
42  EXPECT_EQ(buf_->size(), callback.GetResult(rv));
43  rv = writer_->Finish(callback.callback());
44  EXPECT_EQ(OK, callback.GetResult(rv));
45
46  // Verify the result.
47  EXPECT_EQ(kData, writer_->data());
48
49  // Initialize() again to reset.
50  rv = writer_->Initialize(callback.callback());
51  EXPECT_EQ(OK, callback.GetResult(rv));
52  EXPECT_TRUE(writer_->data().empty());
53}
54
55class URLFetcherFileWriterTest : public PlatformTest {
56 protected:
57  virtual void SetUp() OVERRIDE {
58    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
59    file_path_ = temp_dir_.path().AppendASCII("test.txt");
60    writer_.reset(new URLFetcherFileWriter(
61        base::MessageLoopProxy::current(), file_path_));
62    buf_ = new StringIOBuffer(kData);
63  }
64
65  base::ScopedTempDir temp_dir_;
66  base::FilePath file_path_;
67  scoped_ptr<URLFetcherFileWriter> writer_;
68  scoped_refptr<StringIOBuffer> buf_;
69};
70
71TEST_F(URLFetcherFileWriterTest, WriteToFile) {
72  int rv = 0;
73  // Initialize(), Write() and Finish().
74  TestCompletionCallback callback;
75  rv = writer_->Initialize(callback.callback());
76  EXPECT_EQ(OK, callback.GetResult(rv));
77  rv = writer_->Write(buf_.get(), buf_->size(), callback.callback());
78  EXPECT_EQ(buf_->size(), callback.GetResult(rv));
79  rv = writer_->Finish(callback.callback());
80  EXPECT_EQ(OK, callback.GetResult(rv));
81
82  // Verify the result.
83  EXPECT_EQ(file_path_.value(), writer_->file_path().value());
84  std::string file_contents;
85  EXPECT_TRUE(base::ReadFileToString(writer_->file_path(), &file_contents));
86  EXPECT_EQ(kData, file_contents);
87
88  // Destroy the writer. File should be deleted.
89  writer_.reset();
90  base::RunLoop().RunUntilIdle();
91  EXPECT_FALSE(base::PathExists(file_path_));
92}
93
94TEST_F(URLFetcherFileWriterTest, InitializeAgain) {
95  int rv = 0;
96  // Initialize(), Write() and Finish().
97  TestCompletionCallback callback;
98  rv = writer_->Initialize(callback.callback());
99  EXPECT_EQ(OK, callback.GetResult(rv));
100  rv = writer_->Write(buf_.get(), buf_->size(), callback.callback());
101  EXPECT_EQ(buf_->size(), callback.GetResult(rv));
102  rv = writer_->Finish(callback.callback());
103  EXPECT_EQ(OK, callback.GetResult(rv));
104
105  // Verify the result.
106  std::string file_contents;
107  EXPECT_TRUE(base::ReadFileToString(writer_->file_path(), &file_contents));
108  EXPECT_EQ(kData, file_contents);
109
110  // Initialize() again to reset. Write different data.
111  const std::string data2 = "Bye!";
112  scoped_refptr<StringIOBuffer> buf2(new StringIOBuffer(data2));
113
114  rv = writer_->Initialize(callback.callback());
115  EXPECT_EQ(OK, callback.GetResult(rv));
116  rv = writer_->Write(buf2.get(), buf2->size(), callback.callback());
117  EXPECT_EQ(buf2->size(), callback.GetResult(rv));
118  rv = writer_->Finish(callback.callback());
119  EXPECT_EQ(OK, callback.GetResult(rv));
120
121  // Verify the result.
122  file_contents.clear();
123  EXPECT_TRUE(base::ReadFileToString(writer_->file_path(), &file_contents));
124  EXPECT_EQ(data2, file_contents);
125}
126
127TEST_F(URLFetcherFileWriterTest, DisownFile) {
128  int rv = 0;
129  // Initialize() and Finish() to create a file.
130  TestCompletionCallback callback;
131  rv = writer_->Initialize(callback.callback());
132  EXPECT_EQ(OK, callback.GetResult(rv));
133  rv = writer_->Finish(callback.callback());
134  EXPECT_EQ(OK, callback.GetResult(rv));
135
136  // Disown file.
137  writer_->DisownFile();
138
139  // File is not deleted even after the writer gets destroyed.
140  writer_.reset();
141  base::RunLoop().RunUntilIdle();
142  EXPECT_TRUE(base::PathExists(file_path_));
143}
144
145class URLFetcherFileWriterTemporaryFileTest : public PlatformTest {
146 protected:
147  virtual void SetUp() OVERRIDE {
148    writer_.reset(new URLFetcherFileWriter(
149        base::MessageLoopProxy::current(), base::FilePath()));
150    buf_ = new StringIOBuffer(kData);
151  }
152
153  scoped_ptr<URLFetcherFileWriter> writer_;
154  scoped_refptr<StringIOBuffer> buf_;
155};
156
157TEST_F(URLFetcherFileWriterTemporaryFileTest, WriteToTemporaryFile) {
158  int rv = 0;
159  // Initialize(), Write() and Finish().
160  TestCompletionCallback callback;
161  rv = writer_->Initialize(callback.callback());
162  EXPECT_EQ(OK, callback.GetResult(rv));
163  rv = writer_->Write(buf_.get(), buf_->size(), callback.callback());
164  EXPECT_EQ(buf_->size(), callback.GetResult(rv));
165  rv = writer_->Finish(callback.callback());
166  EXPECT_EQ(OK, callback.GetResult(rv));
167
168  // Verify the result.
169  std::string file_contents;
170  EXPECT_TRUE(base::ReadFileToString(writer_->file_path(), &file_contents));
171  EXPECT_EQ(kData, file_contents);
172
173  // Destroy the writer. File should be deleted.
174  const base::FilePath file_path = writer_->file_path();
175  writer_.reset();
176  base::RunLoop().RunUntilIdle();
177  EXPECT_FALSE(base::PathExists(file_path));
178}
179
180}  // namespace net
181