Home | History | Annotate | Download | only in safe_browsing
      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/download_feedback.h"
      6 
      7 #include "base/files/file_util.h"
      8 #include "base/files/scoped_temp_dir.h"
      9 #include "base/message_loop/message_loop.h"
     10 #include "base/run_loop.h"
     11 #include "base/single_thread_task_runner.h"
     12 #include "chrome/browser/safe_browsing/two_phase_uploader.h"
     13 #include "chrome/common/safe_browsing/csd.pb.h"
     14 #include "content/public/browser/browser_thread.h"
     15 #include "content/public/test/test_browser_thread_bundle.h"
     16 #include "net/url_request/url_request_test_util.h"
     17 #include "testing/gtest/include/gtest/gtest.h"
     18 
     19 namespace safe_browsing {
     20 
     21 namespace {
     22 
     23 class FakeUploader : public TwoPhaseUploader {
     24  public:
     25   FakeUploader(net::URLRequestContextGetter* url_request_context_getter,
     26                base::TaskRunner* file_task_runner,
     27                const GURL& base_url,
     28                const std::string& metadata,
     29                const base::FilePath& file_path,
     30                const ProgressCallback& progress_callback,
     31                const FinishCallback& finish_callback);
     32   virtual ~FakeUploader() {}
     33 
     34   virtual void Start() OVERRIDE {
     35     start_called_ = true;
     36   }
     37 
     38   scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
     39   scoped_refptr<base::TaskRunner> file_task_runner_;
     40   GURL base_url_;
     41   std::string metadata_;
     42   base::FilePath file_path_;
     43   ProgressCallback progress_callback_;
     44   FinishCallback finish_callback_;
     45 
     46   bool start_called_;
     47 };
     48 
     49 FakeUploader::FakeUploader(
     50     net::URLRequestContextGetter* url_request_context_getter,
     51     base::TaskRunner* file_task_runner,
     52     const GURL& base_url,
     53     const std::string& metadata,
     54     const base::FilePath& file_path,
     55     const ProgressCallback& progress_callback,
     56     const FinishCallback& finish_callback)
     57     : url_request_context_getter_(url_request_context_getter),
     58       file_task_runner_(file_task_runner),
     59       base_url_(base_url),
     60       metadata_(metadata),
     61       file_path_(file_path),
     62       progress_callback_(progress_callback),
     63       finish_callback_(finish_callback),
     64       start_called_(false) {
     65 }
     66 
     67 class FakeUploaderFactory : public TwoPhaseUploaderFactory {
     68  public:
     69   FakeUploaderFactory() : uploader_(NULL) {}
     70   virtual ~FakeUploaderFactory() {}
     71 
     72   virtual TwoPhaseUploader* CreateTwoPhaseUploader(
     73       net::URLRequestContextGetter* url_request_context_getter,
     74       base::TaskRunner* file_task_runner,
     75       const GURL& base_url,
     76       const std::string& metadata,
     77       const base::FilePath& file_path,
     78       const TwoPhaseUploader::ProgressCallback& progress_callback,
     79       const TwoPhaseUploader::FinishCallback& finish_callback) OVERRIDE;
     80 
     81   FakeUploader* uploader_;
     82 };
     83 
     84 TwoPhaseUploader* FakeUploaderFactory::CreateTwoPhaseUploader(
     85     net::URLRequestContextGetter* url_request_context_getter,
     86     base::TaskRunner* file_task_runner,
     87     const GURL& base_url,
     88     const std::string& metadata,
     89     const base::FilePath& file_path,
     90     const TwoPhaseUploader::ProgressCallback& progress_callback,
     91     const TwoPhaseUploader::FinishCallback& finish_callback) {
     92   EXPECT_FALSE(uploader_);
     93 
     94   uploader_ = new FakeUploader(url_request_context_getter, file_task_runner,
     95                                base_url, metadata, file_path, progress_callback,
     96                                finish_callback);
     97   return uploader_;
     98 }
     99 
    100 }  // namespace
    101 
    102 class DownloadFeedbackTest : public testing::Test {
    103  public:
    104   DownloadFeedbackTest()
    105       : file_task_runner_(content::BrowserThread::GetMessageLoopProxyForThread(
    106             content::BrowserThread::FILE)),
    107         io_task_runner_(content::BrowserThread::GetMessageLoopProxyForThread(
    108             content::BrowserThread::IO)),
    109         url_request_context_getter_(
    110             new net::TestURLRequestContextGetter(io_task_runner_)),
    111         feedback_finish_called_(false) {
    112     EXPECT_NE(io_task_runner_, file_task_runner_);
    113   }
    114 
    115   virtual void SetUp() OVERRIDE {
    116     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    117     upload_file_path_ = temp_dir_.path().AppendASCII("test file");
    118     upload_file_data_ = "data";
    119     ASSERT_EQ(static_cast<int>(upload_file_data_.size()),
    120               base::WriteFile(upload_file_path_, upload_file_data_.data(),
    121                               upload_file_data_.size()));
    122     TwoPhaseUploader::RegisterFactory(&two_phase_uploader_factory_);
    123   }
    124 
    125   virtual void TearDown() OVERRIDE {
    126     TwoPhaseUploader::RegisterFactory(NULL);
    127   }
    128 
    129   FakeUploader* uploader() const {
    130     return two_phase_uploader_factory_.uploader_;
    131   }
    132 
    133   void FinishCallback(DownloadFeedback* feedback) {
    134     EXPECT_FALSE(feedback_finish_called_);
    135     feedback_finish_called_ = true;
    136     delete feedback;
    137   }
    138 
    139  protected:
    140   base::ScopedTempDir temp_dir_;
    141   base::FilePath upload_file_path_;
    142   std::string upload_file_data_;
    143   content::TestBrowserThreadBundle thread_bundle_;
    144   scoped_refptr<base::SingleThreadTaskRunner> file_task_runner_;
    145   scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
    146   FakeUploaderFactory two_phase_uploader_factory_;
    147   scoped_refptr<net::TestURLRequestContextGetter> url_request_context_getter_;
    148 
    149   bool feedback_finish_called_;
    150 };
    151 
    152 TEST_F(DownloadFeedbackTest, CompleteUpload) {
    153   ClientDownloadReport expected_report_metadata;
    154   expected_report_metadata.mutable_download_request()->set_url("http://test");
    155   expected_report_metadata.mutable_download_request()->set_length(
    156       upload_file_data_.size());
    157   expected_report_metadata.mutable_download_request()->mutable_digests(
    158       )->set_sha1("hi");
    159   expected_report_metadata.mutable_download_response()->set_verdict(
    160       ClientDownloadResponse::DANGEROUS_HOST);
    161   std::string ping_request(
    162       expected_report_metadata.download_request().SerializeAsString());
    163   std::string ping_response(
    164       expected_report_metadata.download_response().SerializeAsString());
    165 
    166   DownloadFeedback* feedback =
    167       DownloadFeedback::Create(url_request_context_getter_.get(),
    168                                file_task_runner_.get(),
    169                                upload_file_path_,
    170                                ping_request,
    171                                ping_response);
    172   EXPECT_FALSE(uploader());
    173 
    174   feedback->Start(base::Bind(&DownloadFeedbackTest::FinishCallback,
    175                              base::Unretained(this),
    176                              feedback));
    177   ASSERT_TRUE(uploader());
    178   EXPECT_FALSE(feedback_finish_called_);
    179   EXPECT_TRUE(uploader()->start_called_);
    180 
    181   EXPECT_EQ(url_request_context_getter_,
    182             uploader()->url_request_context_getter_);
    183   EXPECT_EQ(file_task_runner_, uploader()->file_task_runner_);
    184   EXPECT_EQ(upload_file_path_, uploader()->file_path_);
    185   EXPECT_EQ(expected_report_metadata.SerializeAsString(),
    186             uploader()->metadata_);
    187   EXPECT_EQ(DownloadFeedback::kSbFeedbackURL, uploader()->base_url_.spec());
    188 
    189   EXPECT_TRUE(base::PathExists(upload_file_path_));
    190 
    191   EXPECT_FALSE(feedback_finish_called_);
    192   uploader()->finish_callback_.Run(
    193       TwoPhaseUploader::STATE_SUCCESS, net::OK, 0, "");
    194   EXPECT_TRUE(feedback_finish_called_);
    195   base::RunLoop().RunUntilIdle();
    196   EXPECT_FALSE(base::PathExists(upload_file_path_));
    197 }
    198 
    199 TEST_F(DownloadFeedbackTest, CancelUpload) {
    200   ClientDownloadReport expected_report_metadata;
    201   expected_report_metadata.mutable_download_request()->set_url("http://test");
    202   expected_report_metadata.mutable_download_request()->set_length(
    203       upload_file_data_.size());
    204   expected_report_metadata.mutable_download_request()->mutable_digests(
    205       )->set_sha1("hi");
    206   expected_report_metadata.mutable_download_response()->set_verdict(
    207       ClientDownloadResponse::DANGEROUS_HOST);
    208   std::string ping_request(
    209       expected_report_metadata.download_request().SerializeAsString());
    210   std::string ping_response(
    211       expected_report_metadata.download_response().SerializeAsString());
    212 
    213   DownloadFeedback* feedback =
    214       DownloadFeedback::Create(url_request_context_getter_.get(),
    215                                file_task_runner_.get(),
    216                                upload_file_path_,
    217                                ping_request,
    218                                ping_response);
    219   EXPECT_FALSE(uploader());
    220 
    221   feedback->Start(base::Bind(&DownloadFeedbackTest::FinishCallback,
    222                              base::Unretained(this),
    223                              feedback));
    224   ASSERT_TRUE(uploader());
    225   EXPECT_FALSE(feedback_finish_called_);
    226   EXPECT_TRUE(uploader()->start_called_);
    227   EXPECT_TRUE(base::PathExists(upload_file_path_));
    228 
    229   delete feedback;
    230   EXPECT_FALSE(feedback_finish_called_);
    231 
    232   base::RunLoop().RunUntilIdle();
    233   EXPECT_FALSE(base::PathExists(upload_file_path_));
    234 }
    235 
    236 }  // namespace safe_browsing
    237