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. 4 5 #include "chrome/browser/safe_browsing/two_phase_uploader.h" 6 7 #include "base/files/file_path.h" 8 #include "base/message_loop/message_loop.h" 9 #include "chrome/browser/safe_browsing/local_two_phase_testserver.h" 10 #include "content/public/test/test_browser_thread_bundle.h" 11 #include "content/public/test/test_utils.h" 12 #include "net/base/net_errors.h" 13 #include "net/url_request/url_fetcher.h" 14 #include "net/url_request/url_request_test_util.h" 15 #include "testing/gtest/include/gtest/gtest.h" 16 17 using content::BrowserThread; 18 using content::MessageLoopRunner; 19 20 namespace { 21 22 class Delegate { 23 public: 24 Delegate() : state_(TwoPhaseUploader::STATE_NONE) { 25 } 26 27 void ProgressCallback(int64 current, int64 total) {} 28 29 void FinishCallback(scoped_refptr<MessageLoopRunner> runner, 30 TwoPhaseUploader::State state, 31 int net_error, 32 int response_code, 33 const std::string& response) { 34 state_ = state; 35 net_error_ = net_error; 36 response_code_ = response_code; 37 response_ = response; 38 runner->Quit(); 39 } 40 41 TwoPhaseUploader::State state_; 42 int net_error_; 43 int response_code_; 44 std::string response_; 45 }; 46 47 base::FilePath GetTestFilePath() { 48 base::FilePath file_path; 49 PathService::Get(base::DIR_SOURCE_ROOT, &file_path); 50 file_path = file_path.Append(FILE_PATH_LITERAL("net")); 51 file_path = file_path.Append(FILE_PATH_LITERAL("data")); 52 file_path = file_path.Append(FILE_PATH_LITERAL("url_request_unittest")); 53 file_path = file_path.Append(FILE_PATH_LITERAL("BullRunSpeech.txt")); 54 return file_path; 55 } 56 57 } // namespace 58 59 class TwoPhaseUploaderTest : public testing::Test { 60 public: 61 TwoPhaseUploaderTest() 62 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP), 63 url_request_context_getter_(new net::TestURLRequestContextGetter( 64 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO))) { 65 } 66 67 protected: 68 content::TestBrowserThreadBundle thread_bundle_; 69 70 scoped_refptr<net::TestURLRequestContextGetter> url_request_context_getter_; 71 }; 72 73 TEST_F(TwoPhaseUploaderTest, UploadFile) { 74 scoped_refptr<MessageLoopRunner> runner = new MessageLoopRunner; 75 LocalTwoPhaseTestServer test_server; 76 ASSERT_TRUE(test_server.Start()); 77 Delegate delegate; 78 scoped_ptr<TwoPhaseUploader> uploader(TwoPhaseUploader::Create( 79 url_request_context_getter_.get(), 80 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB).get(), 81 test_server.GetURL("start"), 82 "metadata", 83 GetTestFilePath(), 84 base::Bind(&Delegate::ProgressCallback, base::Unretained(&delegate)), 85 base::Bind( 86 &Delegate::FinishCallback, base::Unretained(&delegate), runner))); 87 uploader->Start(); 88 runner->Run(); 89 EXPECT_EQ(TwoPhaseUploader::STATE_SUCCESS, delegate.state_); 90 EXPECT_EQ(net::OK, delegate.net_error_); 91 EXPECT_EQ(200, delegate.response_code_); 92 EXPECT_EQ( 93 "/start\n" // path of start request 94 "4c24b2612e94e2ae622e54397663f2b7bf0a2e17\n" // sha1sum of "metadata" 95 "944857cc626f2cafe232521986b4c6d3f9993c97\n", // sha1sum of test file 96 delegate.response_); 97 } 98 99 TEST_F(TwoPhaseUploaderTest, BadPhaseOneResponse) { 100 scoped_refptr<MessageLoopRunner> runner = new MessageLoopRunner; 101 LocalTwoPhaseTestServer test_server; 102 ASSERT_TRUE(test_server.Start()); 103 Delegate delegate; 104 scoped_ptr<TwoPhaseUploader> uploader(TwoPhaseUploader::Create( 105 url_request_context_getter_.get(), 106 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB).get(), 107 test_server.GetURL("start?p1code=500"), 108 "metadata", 109 GetTestFilePath(), 110 base::Bind(&Delegate::ProgressCallback, base::Unretained(&delegate)), 111 base::Bind( 112 &Delegate::FinishCallback, base::Unretained(&delegate), runner))); 113 uploader->Start(); 114 runner->Run(); 115 EXPECT_EQ(TwoPhaseUploader::UPLOAD_METADATA, delegate.state_); 116 EXPECT_EQ(net::OK, delegate.net_error_); 117 EXPECT_EQ(500, delegate.response_code_); 118 EXPECT_EQ("", delegate.response_); 119 } 120 121 TEST_F(TwoPhaseUploaderTest, BadPhaseTwoResponse) { 122 scoped_refptr<MessageLoopRunner> runner = new MessageLoopRunner; 123 LocalTwoPhaseTestServer test_server; 124 ASSERT_TRUE(test_server.Start()); 125 Delegate delegate; 126 scoped_ptr<TwoPhaseUploader> uploader(TwoPhaseUploader::Create( 127 url_request_context_getter_.get(), 128 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB).get(), 129 test_server.GetURL("start?p2code=500"), 130 "metadata", 131 GetTestFilePath(), 132 base::Bind(&Delegate::ProgressCallback, base::Unretained(&delegate)), 133 base::Bind( 134 &Delegate::FinishCallback, base::Unretained(&delegate), runner))); 135 uploader->Start(); 136 runner->Run(); 137 EXPECT_EQ(TwoPhaseUploader::UPLOAD_FILE, delegate.state_); 138 EXPECT_EQ(net::OK, delegate.net_error_); 139 EXPECT_EQ(500, delegate.response_code_); 140 EXPECT_EQ( 141 "/start\n" // path of start request 142 "4c24b2612e94e2ae622e54397663f2b7bf0a2e17\n" // sha1sum of "metadata" 143 "944857cc626f2cafe232521986b4c6d3f9993c97\n", // sha1sum of test file 144 delegate.response_); 145 } 146 147 TEST_F(TwoPhaseUploaderTest, PhaseOneConnectionClosed) { 148 scoped_refptr<MessageLoopRunner> runner = new MessageLoopRunner; 149 LocalTwoPhaseTestServer test_server; 150 ASSERT_TRUE(test_server.Start()); 151 Delegate delegate; 152 scoped_ptr<TwoPhaseUploader> uploader(TwoPhaseUploader::Create( 153 url_request_context_getter_.get(), 154 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB).get(), 155 test_server.GetURL("start?p1close=1"), 156 "metadata", 157 GetTestFilePath(), 158 base::Bind(&Delegate::ProgressCallback, base::Unretained(&delegate)), 159 base::Bind( 160 &Delegate::FinishCallback, base::Unretained(&delegate), runner))); 161 uploader->Start(); 162 runner->Run(); 163 EXPECT_EQ(TwoPhaseUploader::UPLOAD_METADATA, delegate.state_); 164 EXPECT_EQ(net::ERR_EMPTY_RESPONSE, delegate.net_error_); 165 EXPECT_EQ(net::URLFetcher::RESPONSE_CODE_INVALID, delegate.response_code_); 166 EXPECT_EQ("", delegate.response_); 167 } 168 169 TEST_F(TwoPhaseUploaderTest, PhaseTwoConnectionClosed) { 170 scoped_refptr<MessageLoopRunner> runner = new MessageLoopRunner; 171 LocalTwoPhaseTestServer test_server; 172 ASSERT_TRUE(test_server.Start()); 173 Delegate delegate; 174 scoped_ptr<TwoPhaseUploader> uploader(TwoPhaseUploader::Create( 175 url_request_context_getter_.get(), 176 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB).get(), 177 test_server.GetURL("start?p2close=1"), 178 "metadata", 179 GetTestFilePath(), 180 base::Bind(&Delegate::ProgressCallback, base::Unretained(&delegate)), 181 base::Bind( 182 &Delegate::FinishCallback, base::Unretained(&delegate), runner))); 183 uploader->Start(); 184 runner->Run(); 185 EXPECT_EQ(TwoPhaseUploader::UPLOAD_FILE, delegate.state_); 186 EXPECT_EQ(net::ERR_EMPTY_RESPONSE, delegate.net_error_); 187 EXPECT_EQ(net::URLFetcher::RESPONSE_CODE_INVALID, delegate.response_code_); 188 EXPECT_EQ("", delegate.response_); 189 } 190