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
MakeBeacon(MockableTime * time)26 DomainReliabilityBeacon MakeBeacon(MockableTime* time) {
27 DomainReliabilityBeacon beacon;
28 beacon.status = "ok";
29 beacon.chrome_error = net::OK;
30 beacon.server_ip = "127.0.0.1";
31 beacon.http_response_code = 200;
32 beacon.elapsed = base::TimeDelta::FromMilliseconds(250);
33 beacon.start_time = time->NowTicks() - beacon.elapsed;
34 return beacon;
35 }
36
37 class DomainReliabilityContextTest : public testing::Test {
38 protected:
DomainReliabilityContextTest()39 DomainReliabilityContextTest()
40 : dispatcher_(&time_),
41 params_(MakeTestSchedulerParams()),
42 uploader_(base::Bind(&DomainReliabilityContextTest::OnUploadRequest,
43 base::Unretained(this))),
44 upload_reporter_string_("test-reporter"),
45 context_(&time_,
46 params_,
47 upload_reporter_string_,
48 &dispatcher_,
49 &uploader_,
50 MakeTestConfig().Pass()),
51 upload_pending_(false) {}
52
min_delay() const53 TimeDelta min_delay() const { return params_.minimum_upload_delay; }
max_delay() const54 TimeDelta max_delay() const { return params_.maximum_upload_delay; }
retry_interval() const55 TimeDelta retry_interval() const { return params_.upload_retry_interval; }
zero_delta() const56 TimeDelta zero_delta() const { return TimeDelta::FromMicroseconds(0); }
57
upload_pending()58 bool upload_pending() { return upload_pending_; }
59
upload_report()60 const std::string& upload_report() {
61 DCHECK(upload_pending_);
62 return upload_report_;
63 }
64
upload_url()65 const GURL& upload_url() {
66 DCHECK(upload_pending_);
67 return upload_url_;
68 }
69
CallUploadCallback(bool success)70 void CallUploadCallback(bool success) {
71 DCHECK(upload_pending_);
72 upload_callback_.Run(success);
73 upload_pending_ = false;
74 }
75
CheckNoBeacons(size_t index)76 bool CheckNoBeacons(size_t index) {
77 BeaconVector beacons;
78 context_.GetQueuedDataForTesting(index, &beacons, NULL, NULL);
79 return beacons.empty();
80 }
81
CheckCounts(size_t index,unsigned expected_successful,unsigned expected_failed)82 bool CheckCounts(size_t index,
83 unsigned expected_successful,
84 unsigned expected_failed) {
85 unsigned successful, failed;
86 context_.GetQueuedDataForTesting(index, NULL, &successful, &failed);
87 return successful == expected_successful && failed == expected_failed;
88 }
89
90 MockTime time_;
91 DomainReliabilityDispatcher dispatcher_;
92 DomainReliabilityScheduler::Params params_;
93 MockUploader uploader_;
94 std::string upload_reporter_string_;
95 DomainReliabilityContext context_;
96
97 private:
OnUploadRequest(const std::string & report_json,const GURL & upload_url,const DomainReliabilityUploader::UploadCallback & callback)98 void OnUploadRequest(
99 const std::string& report_json,
100 const GURL& upload_url,
101 const DomainReliabilityUploader::UploadCallback& callback) {
102 DCHECK(!upload_pending_);
103 upload_report_ = report_json;
104 upload_url_ = upload_url;
105 upload_callback_ = callback;
106 upload_pending_ = true;
107 }
108
109 bool upload_pending_;
110 std::string upload_report_;
111 GURL upload_url_;
112 DomainReliabilityUploader::UploadCallback upload_callback_;
113 };
114
TEST_F(DomainReliabilityContextTest,Create)115 TEST_F(DomainReliabilityContextTest, Create) {
116 EXPECT_TRUE(CheckNoBeacons(0));
117 EXPECT_TRUE(CheckCounts(0, 0, 0));
118 EXPECT_TRUE(CheckNoBeacons(1));
119 EXPECT_TRUE(CheckCounts(1, 0, 0));
120 }
121
TEST_F(DomainReliabilityContextTest,NoResource)122 TEST_F(DomainReliabilityContextTest, NoResource) {
123 GURL url("http://example/no_resource");
124 DomainReliabilityBeacon beacon = MakeBeacon(&time_);
125 context_.OnBeacon(url, beacon);
126
127 EXPECT_TRUE(CheckNoBeacons(0));
128 EXPECT_TRUE(CheckCounts(0, 0, 0));
129 EXPECT_TRUE(CheckNoBeacons(1));
130 EXPECT_TRUE(CheckCounts(1, 0, 0));
131 }
132
TEST_F(DomainReliabilityContextTest,NeverReport)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(0));
139 EXPECT_TRUE(CheckCounts(0, 0, 0));
140 EXPECT_TRUE(CheckNoBeacons(1));
141 EXPECT_TRUE(CheckCounts(1, 1, 0));
142 }
143
TEST_F(DomainReliabilityContextTest,AlwaysReport)144 TEST_F(DomainReliabilityContextTest, AlwaysReport) {
145 GURL url("http://example/always_report");
146 DomainReliabilityBeacon beacon = MakeBeacon(&time_);
147 context_.OnBeacon(url, beacon);
148
149 BeaconVector beacons;
150 context_.GetQueuedDataForTesting(0, &beacons, NULL, NULL);
151 EXPECT_EQ(1u, beacons.size());
152 EXPECT_TRUE(CheckCounts(0, 1, 0));
153 EXPECT_TRUE(CheckNoBeacons(1));
154 EXPECT_TRUE(CheckCounts(1, 0, 0));
155 }
156
TEST_F(DomainReliabilityContextTest,ReportUpload)157 TEST_F(DomainReliabilityContextTest, ReportUpload) {
158 GURL url("http://example/always_report");
159 DomainReliabilityBeacon beacon = MakeBeacon(&time_);
160 context_.OnBeacon(url, beacon);
161
162 // N.B.: Assumes max_delay is 5 minutes.
163 const char* kExpectedReport = "{\"config_version\":\"1\","
164 "\"reporter\":\"test-reporter\","
165 "\"resource_reports\":[{\"beacons\":[{\"http_response_code\":200,"
166 "\"request_age_ms\":300250,\"request_elapsed_ms\":250,\"server_ip\":"
167 "\"127.0.0.1\",\"status\":\"ok\"}],\"failed_requests\":0,"
168 "\"resource_name\":\"always_report\",\"successful_requests\":1}]}";
169
170 time_.Advance(max_delay());
171 EXPECT_TRUE(upload_pending());
172 EXPECT_EQ(kExpectedReport, upload_report());
173 EXPECT_EQ(GURL("https://example/upload"), upload_url());
174 CallUploadCallback(true);
175 }
176
177 } // namespace
178 } // namespace domain_reliability
179