blob: 48c69b45881ef4150b34e9b208e3fac447667e25 [file] [log] [blame]
[email protected]2a172e42014-02-21 04:06:101// 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/rappor/log_uploader.h"
6
[email protected]ccb49262014-03-26 04:10:177#include "base/compiler_specific.h"
avif57136c12015-12-25 23:27:458#include "base/macros.h"
skyostilb0daa012015-06-02 19:03:489#include "base/thread_task_runner_handle.h"
[email protected]2a172e42014-02-21 04:06:1010#include "net/url_request/test_url_fetcher_factory.h"
11#include "net/url_request/url_request_test_util.h"
12#include "testing/gtest/include/gtest/gtest.h"
13
14namespace rappor {
15
16namespace {
17
18const char kTestServerURL[] = "http://a.com/";
19const char kTestMimeType[] = "text/plain";
20
21class TestLogUploader : public LogUploader {
22 public:
23 TestLogUploader(net::URLRequestContextGetter* request_context) :
24 LogUploader(GURL(kTestServerURL), kTestMimeType, request_context) {
holte5a7ed7c2015-01-09 23:52:4625 Start();
[email protected]2a172e42014-02-21 04:06:1026 }
27
28 base::TimeDelta last_interval_set() const { return last_interval_set_; };
29
30 void StartUpload() {
31 last_interval_set_ = base::TimeDelta();
32 StartScheduledUpload();
33 }
34
35 static base::TimeDelta BackOff(base::TimeDelta t) {
36 return LogUploader::BackOffUploadInterval(t);
37 }
38
39 protected:
dcheng00ea022b2014-10-21 11:24:5640 bool IsUploadScheduled() const override {
[email protected]2a172e42014-02-21 04:06:1041 return last_interval_set() != base::TimeDelta();
42 }
43
44 // Schedules a future call to StartScheduledUpload if one isn't already
45 // pending.
dcheng00ea022b2014-10-21 11:24:5646 void ScheduleNextUpload(base::TimeDelta interval) override {
[email protected]2a172e42014-02-21 04:06:1047 EXPECT_EQ(last_interval_set(), base::TimeDelta());
48 last_interval_set_ = interval;
49 }
50
51 base::TimeDelta last_interval_set_;
52
53 DISALLOW_COPY_AND_ASSIGN(TestLogUploader);
54};
55
56} // namespace
57
58class LogUploaderTest : public testing::Test {
59 public:
60 LogUploaderTest()
61 : request_context_(new net::TestURLRequestContextGetter(
skyostilb0daa012015-06-02 19:03:4862 base::ThreadTaskRunnerHandle::Get())),
[email protected]2a172e42014-02-21 04:06:1063 factory_(NULL) {}
64
65 protected:
skyostilb0daa012015-06-02 19:03:4866 // Required for base::ThreadTaskRunnerHandle::Get().
[email protected]2a172e42014-02-21 04:06:1067 base::MessageLoopForUI loop_;
68 scoped_refptr<net::TestURLRequestContextGetter> request_context_;
69 net::FakeURLFetcherFactory factory_;
70
71 DISALLOW_COPY_AND_ASSIGN(LogUploaderTest);
72};
73
74TEST_F(LogUploaderTest, Success) {
dcheng3c331bb52014-08-26 19:28:4475 TestLogUploader uploader(request_context_.get());
[email protected]2a172e42014-02-21 04:06:1076
77 factory_.SetFakeResponse(GURL(kTestServerURL),
78 std::string(),
79 net::HTTP_OK,
80 net::URLRequestStatus::SUCCESS);
81
82 uploader.QueueLog("log1");
83 base::MessageLoop::current()->RunUntilIdle();
84 // Log should be discarded instead of retransmitted.
85 EXPECT_EQ(uploader.last_interval_set(), base::TimeDelta());
86}
87
88TEST_F(LogUploaderTest, Rejection) {
dcheng3c331bb52014-08-26 19:28:4489 TestLogUploader uploader(request_context_.get());
[email protected]2a172e42014-02-21 04:06:1090
91 factory_.SetFakeResponse(GURL(kTestServerURL),
92 std::string(),
93 net::HTTP_BAD_REQUEST,
94 net::URLRequestStatus::SUCCESS);
95
96 uploader.QueueLog("log1");
97 base::MessageLoop::current()->RunUntilIdle();
98 // Log should be discarded instead of retransmitted.
99 EXPECT_EQ(uploader.last_interval_set(), base::TimeDelta());
100}
101
102TEST_F(LogUploaderTest, Failure) {
dcheng3c331bb52014-08-26 19:28:44103 TestLogUploader uploader(request_context_.get());
[email protected]2a172e42014-02-21 04:06:10104
105 factory_.SetFakeResponse(GURL(kTestServerURL),
106 std::string(),
107 net::HTTP_INTERNAL_SERVER_ERROR,
108 net::URLRequestStatus::SUCCESS);
109
110 uploader.QueueLog("log1");
111 base::MessageLoop::current()->RunUntilIdle();
112 // Log should be scheduled for retransmission.
113 base::TimeDelta error_interval = uploader.last_interval_set();
114 EXPECT_GT(error_interval, base::TimeDelta());
115
116 for (int i = 0; i < 10; i++) {
117 uploader.QueueLog("logX");
118 }
119
120 // A second failure should lead to a longer interval, and the log should
121 // be discarded due to full queue.
122 uploader.StartUpload();
123 base::MessageLoop::current()->RunUntilIdle();
124 EXPECT_GT(uploader.last_interval_set(), error_interval);
125
126 factory_.SetFakeResponse(GURL(kTestServerURL),
127 std::string(),
128 net::HTTP_OK,
129 net::URLRequestStatus::SUCCESS);
130
131 // A success should revert to base interval while queue is not empty.
132 for (int i = 0; i < 9; i++) {
133 uploader.StartUpload();
134 base::MessageLoop::current()->RunUntilIdle();
135 EXPECT_LT(uploader.last_interval_set(), error_interval);
136 }
137
138 // Queue should be empty.
139 uploader.StartUpload();
140 base::MessageLoop::current()->RunUntilIdle();
141 EXPECT_EQ(uploader.last_interval_set(), base::TimeDelta());
142}
143
144TEST_F(LogUploaderTest, Backoff) {
145 base::TimeDelta current = base::TimeDelta();
146 base::TimeDelta next = base::TimeDelta::FromSeconds(1);
147 // Backoff until the maximum is reached.
148 while (next > current) {
149 current = next;
150 next = TestLogUploader::BackOff(current);
151 }
152 // Maximum backoff should have been reached.
153 EXPECT_EQ(next, current);
154}
155
156} // namespace rappor