Home | History | Annotate | Download | only in domain_reliability
      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 "components/domain_reliability/context.h"
      6 
      7 #include <map>
      8 #include <string>
      9 
     10 #include "base/bind.h"
     11 #include "base/memory/scoped_ptr.h"
     12 #include "base/message_loop/message_loop_proxy.h"
     13 #include "components/domain_reliability/beacon.h"
     14 #include "components/domain_reliability/dispatcher.h"
     15 #include "components/domain_reliability/scheduler.h"
     16 #include "components/domain_reliability/test_util.h"
     17 #include "net/base/net_errors.h"
     18 #include "net/url_request/url_request_test_util.h"
     19 #include "testing/gtest/include/gtest/gtest.h"
     20 
     21 namespace domain_reliability {
     22 namespace {
     23 
     24 typedef std::vector<DomainReliabilityBeacon> BeaconVector;
     25 
     26 DomainReliabilityBeacon MakeBeacon(MockableTime* time) {
     27   DomainReliabilityBeacon beacon;
     28   beacon.domain = "localhost";
     29   beacon.status = "ok";
     30   beacon.chrome_error = net::OK;
     31   beacon.server_ip = "127.0.0.1";
     32   beacon.protocol = "HTTP";
     33   beacon.http_response_code = 200;
     34   beacon.elapsed = base::TimeDelta::FromMilliseconds(250);
     35   beacon.start_time = time->NowTicks() - beacon.elapsed;
     36   return beacon;
     37 }
     38 
     39 class DomainReliabilityContextTest : public testing::Test {
     40  protected:
     41   DomainReliabilityContextTest()
     42       : dispatcher_(&time_),
     43         params_(MakeTestSchedulerParams()),
     44         uploader_(base::Bind(&DomainReliabilityContextTest::OnUploadRequest,
     45                              base::Unretained(this))),
     46         upload_reporter_string_("test-reporter"),
     47         context_(&time_,
     48                  params_,
     49                  upload_reporter_string_,
     50                  &dispatcher_,
     51                  &uploader_,
     52                  MakeTestConfig().Pass()),
     53         upload_pending_(false) {}
     54 
     55   TimeDelta min_delay() const { return params_.minimum_upload_delay; }
     56   TimeDelta max_delay() const { return params_.maximum_upload_delay; }
     57   TimeDelta retry_interval() const { return params_.upload_retry_interval; }
     58   TimeDelta zero_delta() const { return TimeDelta::FromMicroseconds(0); }
     59 
     60   bool upload_pending() { return upload_pending_; }
     61 
     62   const std::string& upload_report() {
     63     DCHECK(upload_pending_);
     64     return upload_report_;
     65   }
     66 
     67   const GURL& upload_url() {
     68     DCHECK(upload_pending_);
     69     return upload_url_;
     70   }
     71 
     72   void CallUploadCallback(bool success) {
     73     DCHECK(upload_pending_);
     74     upload_callback_.Run(success);
     75     upload_pending_ = false;
     76   }
     77 
     78   bool CheckNoBeacons() {
     79     BeaconVector beacons;
     80     context_.GetQueuedBeaconsForTesting(&beacons);
     81     return beacons.empty();
     82   }
     83 
     84   bool CheckCounts(size_t index,
     85                    unsigned expected_successful,
     86                    unsigned expected_failed) {
     87     unsigned successful, failed;
     88     context_.GetRequestCountsForTesting(index, &successful, &failed);
     89     return successful == expected_successful && failed == expected_failed;
     90   }
     91 
     92   MockTime time_;
     93   DomainReliabilityDispatcher dispatcher_;
     94   DomainReliabilityScheduler::Params params_;
     95   MockUploader uploader_;
     96   std::string upload_reporter_string_;
     97   DomainReliabilityContext context_;
     98 
     99  private:
    100   void OnUploadRequest(
    101       const std::string& report_json,
    102       const GURL& upload_url,
    103       const DomainReliabilityUploader::UploadCallback& callback) {
    104     DCHECK(!upload_pending_);
    105     upload_report_ = report_json;
    106     upload_url_ = upload_url;
    107     upload_callback_ = callback;
    108     upload_pending_ = true;
    109   }
    110 
    111   bool upload_pending_;
    112   std::string upload_report_;
    113   GURL upload_url_;
    114   DomainReliabilityUploader::UploadCallback upload_callback_;
    115 };
    116 
    117 TEST_F(DomainReliabilityContextTest, Create) {
    118   EXPECT_TRUE(CheckNoBeacons());
    119   EXPECT_TRUE(CheckCounts(0, 0, 0));
    120   EXPECT_TRUE(CheckCounts(1, 0, 0));
    121 }
    122 
    123 TEST_F(DomainReliabilityContextTest, NoResource) {
    124   GURL url("http://example/no_resource");
    125   DomainReliabilityBeacon beacon = MakeBeacon(&time_);
    126   context_.OnBeacon(url, beacon);
    127 
    128   EXPECT_TRUE(CheckNoBeacons());
    129   EXPECT_TRUE(CheckCounts(0, 0, 0));
    130   EXPECT_TRUE(CheckCounts(1, 0, 0));
    131 }
    132 
    133 TEST_F(DomainReliabilityContextTest, NeverReport) {
    134   GURL url("http://example/never_report");
    135   DomainReliabilityBeacon beacon = MakeBeacon(&time_);
    136   context_.OnBeacon(url, beacon);
    137 
    138   EXPECT_TRUE(CheckNoBeacons());
    139   EXPECT_TRUE(CheckCounts(0, 0, 0));
    140   EXPECT_TRUE(CheckCounts(1, 1, 0));
    141 }
    142 
    143 TEST_F(DomainReliabilityContextTest, AlwaysReport) {
    144   GURL url("http://example/always_report");
    145   DomainReliabilityBeacon beacon = MakeBeacon(&time_);
    146   context_.OnBeacon(url, beacon);
    147 
    148   BeaconVector beacons;
    149   context_.GetQueuedBeaconsForTesting(&beacons);
    150   EXPECT_EQ(1u, beacons.size());
    151   EXPECT_TRUE(CheckCounts(0, 1, 0));
    152   EXPECT_TRUE(CheckCounts(1, 0, 0));
    153 }
    154 
    155 TEST_F(DomainReliabilityContextTest, ReportUpload) {
    156   GURL url("http://example/always_report");
    157   DomainReliabilityBeacon beacon = MakeBeacon(&time_);
    158   context_.OnBeacon(url, beacon);
    159 
    160   BeaconVector beacons;
    161   context_.GetQueuedBeaconsForTesting(&beacons);
    162   EXPECT_EQ(1u, beacons.size());
    163   EXPECT_TRUE(CheckCounts(0, 1, 0));
    164   EXPECT_TRUE(CheckCounts(1, 0, 0));
    165 
    166   // N.B.: Assumes max_delay is 5 minutes.
    167   const char* kExpectedReport = "{"
    168       "\"config_version\":\"1\","
    169       "\"entries\":[{\"domain\":\"localhost\","
    170           "\"http_response_code\":200,\"protocol\":\"HTTP\","
    171           "\"request_age_ms\":300250,\"request_elapsed_ms\":250,"
    172           "\"resource\":\"always_report\",\"server_ip\":\"127.0.0.1\","
    173           "\"status\":\"ok\"}],"
    174       "\"reporter\":\"test-reporter\","
    175       "\"resources\":[{\"failed_requests\":0,\"name\":\"always_report\","
    176           "\"successful_requests\":1}]}";
    177 
    178   time_.Advance(max_delay());
    179   EXPECT_TRUE(upload_pending());
    180   EXPECT_EQ(kExpectedReport, upload_report());
    181   EXPECT_EQ(GURL("https://exampleuploader/upload"), upload_url());
    182   CallUploadCallback(true);
    183 
    184   EXPECT_TRUE(CheckNoBeacons());
    185   EXPECT_TRUE(CheckCounts(0, 0, 0));
    186   EXPECT_TRUE(CheckCounts(1, 0, 0));
    187 }
    188 
    189 }  // namespace
    190 }  // namespace domain_reliability
    191