1 // Copyright 2013 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 "chrome/browser/safe_browsing/download_feedback.h"
7 #include "base/command_line.h"
8 #include "base/file_util.h"
9 #include "base/files/scoped_temp_dir.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/run_loop.h"
12 #include "base/single_thread_task_runner.h"
13 #include "chrome/browser/safe_browsing/two_phase_uploader.h"
14 #include "chrome/common/chrome_switches.h"
15 #include "chrome/common/safe_browsing/csd.pb.h"
16 #include "content/public/browser/browser_thread.h"
17 #include "content/public/test/test_browser_thread_bundle.h"
18 #include "net/url_request/url_request_test_util.h"
19 #include "testing/gtest/include/gtest/gtest.h"
21 namespace safe_browsing
{
25 class FakeUploader
: public TwoPhaseUploader
{
27 FakeUploader(net::URLRequestContextGetter
* url_request_context_getter
,
28 base::TaskRunner
* file_task_runner
,
30 const std::string
& metadata
,
31 const base::FilePath
& file_path
,
32 const ProgressCallback
& progress_callback
,
33 const FinishCallback
& finish_callback
);
34 virtual ~FakeUploader() {}
36 virtual void Start() OVERRIDE
{
40 scoped_refptr
<net::URLRequestContextGetter
> url_request_context_getter_
;
41 scoped_refptr
<base::TaskRunner
> file_task_runner_
;
43 std::string metadata_
;
44 base::FilePath file_path_
;
45 ProgressCallback progress_callback_
;
46 FinishCallback finish_callback_
;
51 FakeUploader::FakeUploader(
52 net::URLRequestContextGetter
* url_request_context_getter
,
53 base::TaskRunner
* file_task_runner
,
55 const std::string
& metadata
,
56 const base::FilePath
& file_path
,
57 const ProgressCallback
& progress_callback
,
58 const FinishCallback
& finish_callback
)
59 : url_request_context_getter_(url_request_context_getter
),
60 file_task_runner_(file_task_runner
),
63 file_path_(file_path
),
64 progress_callback_(progress_callback
),
65 finish_callback_(finish_callback
),
66 start_called_(false) {
69 class FakeUploaderFactory
: public TwoPhaseUploaderFactory
{
71 FakeUploaderFactory() : uploader_(NULL
) {}
72 virtual ~FakeUploaderFactory() {}
74 virtual TwoPhaseUploader
* CreateTwoPhaseUploader(
75 net::URLRequestContextGetter
* url_request_context_getter
,
76 base::TaskRunner
* file_task_runner
,
78 const std::string
& metadata
,
79 const base::FilePath
& file_path
,
80 const TwoPhaseUploader::ProgressCallback
& progress_callback
,
81 const TwoPhaseUploader::FinishCallback
& finish_callback
) OVERRIDE
;
83 FakeUploader
* uploader_
;
86 TwoPhaseUploader
* FakeUploaderFactory::CreateTwoPhaseUploader(
87 net::URLRequestContextGetter
* url_request_context_getter
,
88 base::TaskRunner
* file_task_runner
,
90 const std::string
& metadata
,
91 const base::FilePath
& file_path
,
92 const TwoPhaseUploader::ProgressCallback
& progress_callback
,
93 const TwoPhaseUploader::FinishCallback
& finish_callback
) {
94 EXPECT_FALSE(uploader_
);
96 uploader_
= new FakeUploader(url_request_context_getter
, file_task_runner
,
97 base_url
, metadata
, file_path
, progress_callback
,
104 class DownloadFeedbackTest
: public testing::Test
{
106 DownloadFeedbackTest()
107 : file_task_runner_(content::BrowserThread::GetMessageLoopProxyForThread(
108 content::BrowserThread::FILE)),
109 io_task_runner_(content::BrowserThread::GetMessageLoopProxyForThread(
110 content::BrowserThread::IO
)),
111 url_request_context_getter_(
112 new net::TestURLRequestContextGetter(io_task_runner_
)),
113 feedback_finish_called_(false) {
114 EXPECT_NE(io_task_runner_
, file_task_runner_
);
117 virtual void SetUp() OVERRIDE
{
118 ASSERT_TRUE(temp_dir_
.CreateUniqueTempDir());
119 upload_file_path_
= temp_dir_
.path().AppendASCII("test file");
120 upload_file_data_
= "data";
121 ASSERT_EQ(static_cast<int>(upload_file_data_
.size()),
122 file_util::WriteFile(upload_file_path_
, upload_file_data_
.data(),
123 upload_file_data_
.size()));
124 TwoPhaseUploader::RegisterFactory(&two_phase_uploader_factory_
);
127 virtual void TearDown() OVERRIDE
{
128 TwoPhaseUploader::RegisterFactory(NULL
);
131 FakeUploader
* uploader() const {
132 return two_phase_uploader_factory_
.uploader_
;
135 void FinishCallback(DownloadFeedback
* feedback
) {
136 EXPECT_FALSE(feedback_finish_called_
);
137 feedback_finish_called_
= true;
142 base::ScopedTempDir temp_dir_
;
143 base::FilePath upload_file_path_
;
144 std::string upload_file_data_
;
145 content::TestBrowserThreadBundle thread_bundle_
;
146 scoped_refptr
<base::SingleThreadTaskRunner
> file_task_runner_
;
147 scoped_refptr
<base::SingleThreadTaskRunner
> io_task_runner_
;
148 FakeUploaderFactory two_phase_uploader_factory_
;
149 scoped_refptr
<net::TestURLRequestContextGetter
> url_request_context_getter_
;
151 bool feedback_finish_called_
;
154 TEST_F(DownloadFeedbackTest
, CompleteUpload
) {
155 ClientDownloadReport expected_report_metadata
;
156 expected_report_metadata
.mutable_download_request()->set_url("http://test");
157 expected_report_metadata
.mutable_download_request()->set_length(
158 upload_file_data_
.size());
159 expected_report_metadata
.mutable_download_request()->mutable_digests(
161 expected_report_metadata
.mutable_download_response()->set_verdict(
162 ClientDownloadResponse::DANGEROUS_HOST
);
163 std::string
ping_request(
164 expected_report_metadata
.download_request().SerializeAsString());
165 std::string
ping_response(
166 expected_report_metadata
.download_response().SerializeAsString());
168 const char kTestFeedbackURL
[] = "https://example.com/test/upload";
169 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
170 switches::kSbDownloadFeedbackURL
, kTestFeedbackURL
);
172 DownloadFeedback
* feedback
=
173 DownloadFeedback::Create(url_request_context_getter_
.get(),
174 file_task_runner_
.get(),
178 EXPECT_FALSE(uploader());
180 feedback
->Start(base::Bind(&DownloadFeedbackTest::FinishCallback
,
181 base::Unretained(this),
183 ASSERT_TRUE(uploader());
184 EXPECT_FALSE(feedback_finish_called_
);
185 EXPECT_TRUE(uploader()->start_called_
);
187 EXPECT_EQ(url_request_context_getter_
,
188 uploader()->url_request_context_getter_
);
189 EXPECT_EQ(file_task_runner_
, uploader()->file_task_runner_
);
190 EXPECT_EQ(upload_file_path_
, uploader()->file_path_
);
191 EXPECT_EQ(expected_report_metadata
.SerializeAsString(),
192 uploader()->metadata_
);
193 EXPECT_EQ(kTestFeedbackURL
, uploader()->base_url_
.spec());
195 EXPECT_TRUE(base::PathExists(upload_file_path_
));
197 EXPECT_FALSE(feedback_finish_called_
);
198 uploader()->finish_callback_
.Run(
199 TwoPhaseUploader::STATE_SUCCESS
, net::OK
, 0, "");
200 EXPECT_TRUE(feedback_finish_called_
);
201 base::RunLoop().RunUntilIdle();
202 EXPECT_FALSE(base::PathExists(upload_file_path_
));
205 TEST_F(DownloadFeedbackTest
, CancelUpload
) {
206 ClientDownloadReport expected_report_metadata
;
207 expected_report_metadata
.mutable_download_request()->set_url("http://test");
208 expected_report_metadata
.mutable_download_request()->set_length(
209 upload_file_data_
.size());
210 expected_report_metadata
.mutable_download_request()->mutable_digests(
212 expected_report_metadata
.mutable_download_response()->set_verdict(
213 ClientDownloadResponse::DANGEROUS_HOST
);
214 std::string
ping_request(
215 expected_report_metadata
.download_request().SerializeAsString());
216 std::string
ping_response(
217 expected_report_metadata
.download_response().SerializeAsString());
219 DownloadFeedback
* feedback
=
220 DownloadFeedback::Create(url_request_context_getter_
.get(),
221 file_task_runner_
.get(),
225 EXPECT_FALSE(uploader());
227 feedback
->Start(base::Bind(&DownloadFeedbackTest::FinishCallback
,
228 base::Unretained(this),
230 ASSERT_TRUE(uploader());
231 EXPECT_FALSE(feedback_finish_called_
);
232 EXPECT_TRUE(uploader()->start_called_
);
233 EXPECT_TRUE(base::PathExists(upload_file_path_
));
236 EXPECT_FALSE(feedback_finish_called_
);
238 base::RunLoop().RunUntilIdle();
239 EXPECT_FALSE(base::PathExists(upload_file_path_
));
242 } // namespace safe_browsing