1 // Copyright 2017 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 "services/network/upload_progress_tracker.h"
6
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/macros.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/single_thread_task_runner.h"
12 #include "base/test/test_mock_time_task_runner.h"
13 #include "base/threading/thread_task_runner_handle.h"
14 #include "net/base/upload_progress.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16
17 namespace network {
18 namespace {
19
20 class TestingUploadProgressTracker : public UploadProgressTracker {
21 public:
TestingUploadProgressTracker(const base::Location & location,UploadProgressReportCallback report_callback,scoped_refptr<base::SingleThreadTaskRunner> task_runner)22 TestingUploadProgressTracker(
23 const base::Location& location,
24 UploadProgressReportCallback report_callback,
25 scoped_refptr<base::SingleThreadTaskRunner> task_runner)
26 : UploadProgressTracker(location,
27 std::move(report_callback),
28 nullptr,
29 std::move(task_runner)),
30 current_time_(base::TimeTicks::Now()) {}
31
set_upload_progress(const net::UploadProgress & upload_progress)32 void set_upload_progress(const net::UploadProgress& upload_progress) {
33 upload_progress_ = upload_progress;
34 }
35
set_current_time(const base::TimeTicks & current_time)36 void set_current_time(const base::TimeTicks& current_time) {
37 current_time_ = current_time;
38 }
39
40 private:
41 // UploadProgressTracker overrides.
GetCurrentTime() const42 base::TimeTicks GetCurrentTime() const override { return current_time_; }
GetUploadProgress() const43 net::UploadProgress GetUploadProgress() const override {
44 return upload_progress_;
45 }
46
47 base::TimeTicks current_time_;
48 net::UploadProgress upload_progress_;
49
50 DISALLOW_COPY_AND_ASSIGN(TestingUploadProgressTracker);
51 };
52
53 } // namespace
54
55 class UploadProgressTrackerTest : public ::testing::Test {
56 public:
UploadProgressTrackerTest()57 UploadProgressTrackerTest()
58 : task_runner_handle_(mock_task_runner_),
59 upload_progress_tracker_(
60 FROM_HERE,
61 base::BindRepeating(
62 &UploadProgressTrackerTest::OnUploadProgressReported,
63 base::Unretained(this)),
64 mock_task_runner_) {}
65
66 private:
OnUploadProgressReported(const net::UploadProgress & progress)67 void OnUploadProgressReported(const net::UploadProgress& progress) {
68 ++report_count_;
69 reported_position_ = progress.position();
70 reported_total_size_ = progress.size();
71 }
72
73 protected:
74 int report_count_ = 0;
75 int64_t reported_position_ = 0;
76 int64_t reported_total_size_ = 0;
77
78 // Mocks the current thread's task runner which will also be used as the
79 // UploadProgressTracker's task runner.
80 scoped_refptr<base::TestMockTimeTaskRunner> mock_task_runner_ =
81 new base::TestMockTimeTaskRunner;
82 base::ThreadTaskRunnerHandle task_runner_handle_;
83
84 TestingUploadProgressTracker upload_progress_tracker_;
85
86 DISALLOW_COPY_AND_ASSIGN(UploadProgressTrackerTest);
87 };
88
TEST_F(UploadProgressTrackerTest,NoACK)89 TEST_F(UploadProgressTrackerTest, NoACK) {
90 upload_progress_tracker_.set_upload_progress(net::UploadProgress(500, 1000));
91
92 // The first timer task calls ReportUploadProgress.
93 EXPECT_EQ(0, report_count_);
94 mock_task_runner_->FastForwardBy(
95 UploadProgressTracker::GetUploadProgressIntervalForTesting());
96 EXPECT_EQ(1, report_count_);
97 EXPECT_EQ(500, reported_position_);
98 EXPECT_EQ(1000, reported_total_size_);
99
100 upload_progress_tracker_.set_upload_progress(net::UploadProgress(750, 1000));
101
102 // The second timer task does nothing, since the first report didn't send the
103 // ACK.
104 mock_task_runner_->FastForwardBy(
105 UploadProgressTracker::GetUploadProgressIntervalForTesting());
106 EXPECT_EQ(1, report_count_);
107 }
108
TEST_F(UploadProgressTrackerTest,NoUpload)109 TEST_F(UploadProgressTrackerTest, NoUpload) {
110 upload_progress_tracker_.set_upload_progress(net::UploadProgress(0, 0));
111
112 // UploadProgressTracker does nothing on the empty upload content.
113 EXPECT_EQ(0, report_count_);
114 mock_task_runner_->FastForwardBy(
115 UploadProgressTracker::GetUploadProgressIntervalForTesting());
116 EXPECT_EQ(0, report_count_);
117 }
118
TEST_F(UploadProgressTrackerTest,NoProgress)119 TEST_F(UploadProgressTrackerTest, NoProgress) {
120 upload_progress_tracker_.set_upload_progress(net::UploadProgress(500, 1000));
121
122 // The first timer task calls ReportUploadProgress.
123 EXPECT_EQ(0, report_count_);
124 mock_task_runner_->FastForwardBy(
125 UploadProgressTracker::GetUploadProgressIntervalForTesting());
126 EXPECT_EQ(1, report_count_);
127 EXPECT_EQ(500, reported_position_);
128 EXPECT_EQ(1000, reported_total_size_);
129
130 upload_progress_tracker_.OnAckReceived();
131
132 // The second time doesn't call ReportUploadProgress since there's no
133 // progress.
134 EXPECT_EQ(1, report_count_);
135 mock_task_runner_->FastForwardBy(
136 UploadProgressTracker::GetUploadProgressIntervalForTesting());
137 EXPECT_EQ(1, report_count_);
138 }
139
TEST_F(UploadProgressTrackerTest,Finished)140 TEST_F(UploadProgressTrackerTest, Finished) {
141 upload_progress_tracker_.set_upload_progress(net::UploadProgress(999, 1000));
142
143 // The first timer task calls ReportUploadProgress.
144 EXPECT_EQ(0, report_count_);
145 mock_task_runner_->FastForwardBy(
146 UploadProgressTracker::GetUploadProgressIntervalForTesting());
147 EXPECT_EQ(1, report_count_);
148 EXPECT_EQ(999, reported_position_);
149 EXPECT_EQ(1000, reported_total_size_);
150
151 upload_progress_tracker_.OnAckReceived();
152 upload_progress_tracker_.set_upload_progress(net::UploadProgress(1000, 1000));
153
154 // The second timer task calls ReportUploadProgress for reporting the
155 // completion.
156 EXPECT_EQ(1, report_count_);
157 mock_task_runner_->FastForwardBy(
158 UploadProgressTracker::GetUploadProgressIntervalForTesting());
159 EXPECT_EQ(2, report_count_);
160 EXPECT_EQ(1000, reported_position_);
161 EXPECT_EQ(1000, reported_total_size_);
162 }
163
TEST_F(UploadProgressTrackerTest,Progress)164 TEST_F(UploadProgressTrackerTest, Progress) {
165 upload_progress_tracker_.set_upload_progress(net::UploadProgress(500, 1000));
166
167 // The first timer task calls ReportUploadProgress.
168 EXPECT_EQ(0, report_count_);
169 mock_task_runner_->FastForwardBy(
170 UploadProgressTracker::GetUploadProgressIntervalForTesting());
171 EXPECT_EQ(1, report_count_);
172 EXPECT_EQ(500, reported_position_);
173 EXPECT_EQ(1000, reported_total_size_);
174
175 upload_progress_tracker_.OnAckReceived();
176 upload_progress_tracker_.set_upload_progress(net::UploadProgress(750, 1000));
177
178 // The second timer task calls ReportUploadProgress since the progress is
179 // big enough to report.
180 EXPECT_EQ(1, report_count_);
181 mock_task_runner_->FastForwardBy(
182 UploadProgressTracker::GetUploadProgressIntervalForTesting());
183 EXPECT_EQ(2, report_count_);
184 EXPECT_EQ(750, reported_position_);
185 EXPECT_EQ(1000, reported_total_size_);
186 }
187
TEST_F(UploadProgressTrackerTest,TimePassed)188 TEST_F(UploadProgressTrackerTest, TimePassed) {
189 upload_progress_tracker_.set_upload_progress(net::UploadProgress(500, 1000));
190
191 // The first timer task calls ReportUploadProgress.
192 EXPECT_EQ(0, report_count_);
193 mock_task_runner_->FastForwardBy(
194 UploadProgressTracker::GetUploadProgressIntervalForTesting());
195 EXPECT_EQ(1, report_count_);
196 EXPECT_EQ(500, reported_position_);
197 EXPECT_EQ(1000, reported_total_size_);
198
199 upload_progress_tracker_.OnAckReceived();
200 upload_progress_tracker_.set_upload_progress(net::UploadProgress(501, 1000));
201
202 // The second timer task doesn't call ReportUploadProgress since the progress
203 // is too small to report it.
204 EXPECT_EQ(1, report_count_);
205 mock_task_runner_->FastForwardBy(
206 UploadProgressTracker::GetUploadProgressIntervalForTesting());
207 EXPECT_EQ(1, report_count_);
208
209 upload_progress_tracker_.set_current_time(base::TimeTicks::Now() +
210 base::TimeDelta::FromSeconds(5));
211
212 // The third timer task calls ReportUploadProgress since it's been long time
213 // from the last report.
214 EXPECT_EQ(1, report_count_);
215 mock_task_runner_->FastForwardBy(
216 UploadProgressTracker::GetUploadProgressIntervalForTesting());
217 EXPECT_EQ(2, report_count_);
218 EXPECT_EQ(501, reported_position_);
219 EXPECT_EQ(1000, reported_total_size_);
220 }
221
TEST_F(UploadProgressTrackerTest,Rewound)222 TEST_F(UploadProgressTrackerTest, Rewound) {
223 upload_progress_tracker_.set_upload_progress(net::UploadProgress(500, 1000));
224
225 // The first timer task calls ReportUploadProgress.
226 EXPECT_EQ(0, report_count_);
227 mock_task_runner_->FastForwardBy(
228 UploadProgressTracker::GetUploadProgressIntervalForTesting());
229 EXPECT_EQ(1, report_count_);
230 EXPECT_EQ(500, reported_position_);
231 EXPECT_EQ(1000, reported_total_size_);
232
233 upload_progress_tracker_.OnAckReceived();
234 upload_progress_tracker_.set_upload_progress(net::UploadProgress(250, 1000));
235
236 // The second timer task doesn't call ReportUploadProgress since the progress
237 // was rewound.
238 EXPECT_EQ(1, report_count_);
239 mock_task_runner_->FastForwardBy(
240 UploadProgressTracker::GetUploadProgressIntervalForTesting());
241 EXPECT_EQ(1, report_count_);
242
243 upload_progress_tracker_.set_current_time(base::TimeTicks::Now() +
244 base::TimeDelta::FromSeconds(5));
245
246 // Even after a good amount of time passed, the rewound progress should not be
247 // reported.
248 EXPECT_EQ(1, report_count_);
249 mock_task_runner_->FastForwardBy(
250 UploadProgressTracker::GetUploadProgressIntervalForTesting());
251 EXPECT_EQ(1, report_count_);
252 }
253
TEST_F(UploadProgressTrackerTest,Completed)254 TEST_F(UploadProgressTrackerTest, Completed) {
255 upload_progress_tracker_.set_upload_progress(net::UploadProgress(500, 1000));
256
257 // The first timer task calls ReportUploadProgress.
258 EXPECT_EQ(0, report_count_);
259 mock_task_runner_->FastForwardBy(
260 UploadProgressTracker::GetUploadProgressIntervalForTesting());
261 EXPECT_EQ(1, report_count_);
262 EXPECT_EQ(500, reported_position_);
263 EXPECT_EQ(1000, reported_total_size_);
264
265 upload_progress_tracker_.set_upload_progress(net::UploadProgress(1000, 1000));
266
267 // OnUploadCompleted runs ReportUploadProgress even without Ack nor timer.
268 upload_progress_tracker_.OnUploadCompleted();
269 EXPECT_EQ(2, report_count_);
270 EXPECT_EQ(1000, reported_position_);
271 EXPECT_EQ(1000, reported_total_size_);
272
273 mock_task_runner_->FastForwardBy(
274 UploadProgressTracker::GetUploadProgressIntervalForTesting());
275 EXPECT_EQ(2, report_count_);
276 EXPECT_FALSE(mock_task_runner_->HasPendingTask());
277 }
278
279 } // namespace network
280