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/test_util.h" 6 7 #include "base/bind.h" 8 #include "base/callback.h" 9 #include "components/domain_reliability/scheduler.h" 10 #include "net/url_request/url_request_status.h" 11 #include "testing/gtest/include/gtest/gtest.h" 12 13 namespace domain_reliability { 14 15 namespace { 16 17 class MockTimer : public MockableTime::Timer { 18 public: 19 MockTimer(MockTime* time) 20 : time_(time), 21 running_(false), 22 callback_sequence_number_(0), 23 weak_factory_(this) { 24 DCHECK(time); 25 } 26 27 virtual ~MockTimer() {} 28 29 // MockableTime::Timer implementation: 30 virtual void Start(const tracked_objects::Location& posted_from, 31 base::TimeDelta delay, 32 const base::Closure& user_task) OVERRIDE { 33 DCHECK(!user_task.is_null()); 34 35 if (running_) 36 ++callback_sequence_number_; 37 running_ = true; 38 user_task_ = user_task; 39 time_->AddTask(delay, 40 base::Bind(&MockTimer::OnDelayPassed, 41 weak_factory_.GetWeakPtr(), 42 callback_sequence_number_)); 43 } 44 45 virtual void Stop() OVERRIDE { 46 if (running_) { 47 ++callback_sequence_number_; 48 running_ = false; 49 } 50 } 51 52 virtual bool IsRunning() OVERRIDE { return running_; } 53 54 private: 55 void OnDelayPassed(int expected_callback_sequence_number) { 56 if (callback_sequence_number_ != expected_callback_sequence_number) 57 return; 58 59 DCHECK(running_); 60 running_ = false; 61 62 // Grab user task in case it re-entrantly starts the timer again. 63 base::Closure task_to_run = user_task_; 64 user_task_.Reset(); 65 task_to_run.Run(); 66 } 67 68 MockTime* time_; 69 bool running_; 70 int callback_sequence_number_; 71 base::Closure user_task_; 72 base::WeakPtrFactory<MockTimer> weak_factory_; 73 }; 74 75 } // namespace 76 77 TestCallback::TestCallback() 78 : callback_(base::Bind(&TestCallback::OnCalled, 79 base::Unretained(this))), 80 called_(false) {} 81 82 TestCallback::~TestCallback() {} 83 84 void TestCallback::OnCalled() { 85 EXPECT_FALSE(called_); 86 called_ = true; 87 } 88 89 MockUploader::MockUploader(const UploadRequestCallback& callback) 90 : callback_(callback), 91 discard_uploads_(true) {} 92 93 MockUploader::~MockUploader() {} 94 95 bool MockUploader::discard_uploads() const { return discard_uploads_; } 96 97 void MockUploader::UploadReport(const std::string& report_json, 98 const GURL& upload_url, 99 const UploadCallback& callback) { 100 callback_.Run(report_json, upload_url, callback); 101 } 102 103 void MockUploader::set_discard_uploads(bool discard_uploads) { 104 discard_uploads_ = discard_uploads; 105 } 106 107 MockTime::MockTime() 108 : now_(base::Time::Now()), 109 now_ticks_(base::TimeTicks::Now()), 110 epoch_ticks_(now_ticks_), 111 task_sequence_number_(0) { 112 VLOG(1) << "Creating mock time: T=" << elapsed_sec() << "s"; 113 } 114 115 MockTime::~MockTime() {} 116 117 base::Time MockTime::Now() { return now_; } 118 base::TimeTicks MockTime::NowTicks() { return now_ticks_; } 119 120 scoped_ptr<MockableTime::Timer> MockTime::CreateTimer() { 121 return scoped_ptr<MockableTime::Timer>(new MockTimer(this)); 122 } 123 124 void MockTime::Advance(base::TimeDelta delta) { 125 base::TimeTicks target_ticks = now_ticks_ + delta; 126 127 while (!tasks_.empty() && tasks_.begin()->first.time <= target_ticks) { 128 TaskKey key = tasks_.begin()->first; 129 base::Closure task = tasks_.begin()->second; 130 tasks_.erase(tasks_.begin()); 131 132 DCHECK(now_ticks_ <= key.time); 133 DCHECK(key.time <= target_ticks); 134 AdvanceToInternal(key.time); 135 VLOG(1) << "Advancing mock time: task at T=" << elapsed_sec() << "s"; 136 137 task.Run(); 138 } 139 140 DCHECK(now_ticks_ <= target_ticks); 141 AdvanceToInternal(target_ticks); 142 VLOG(1) << "Advanced mock time: T=" << elapsed_sec() << "s"; 143 } 144 145 void MockTime::AddTask(base::TimeDelta delay, const base::Closure& task) { 146 tasks_[TaskKey(now_ticks_ + delay, task_sequence_number_++)] = task; 147 } 148 149 void MockTime::AdvanceToInternal(base::TimeTicks target_ticks) { 150 base::TimeDelta delta = target_ticks - now_ticks_; 151 now_ += delta; 152 now_ticks_ += delta; 153 } 154 155 DomainReliabilityScheduler::Params MakeTestSchedulerParams() { 156 DomainReliabilityScheduler::Params params; 157 params.minimum_upload_delay = base::TimeDelta::FromMinutes(1); 158 params.maximum_upload_delay = base::TimeDelta::FromMinutes(5); 159 params.upload_retry_interval = base::TimeDelta::FromSeconds(15); 160 return params; 161 } 162 163 scoped_ptr<const DomainReliabilityConfig> MakeTestConfig() { 164 return MakeTestConfigWithDomain("example"); 165 } 166 167 scoped_ptr<const DomainReliabilityConfig> MakeTestConfigWithDomain( 168 const std::string& domain) { 169 DomainReliabilityConfig* config = new DomainReliabilityConfig(); 170 DomainReliabilityConfig::Resource* resource; 171 172 resource = new DomainReliabilityConfig::Resource(); 173 resource->name = "always_report"; 174 resource->url_patterns.push_back( 175 new std::string("http://*/always_report")); 176 resource->success_sample_rate = 1.0; 177 resource->failure_sample_rate = 1.0; 178 config->resources.push_back(resource); 179 180 resource = new DomainReliabilityConfig::Resource(); 181 resource->name = "never_report"; 182 resource->url_patterns.push_back( 183 new std::string("http://*/never_report")); 184 resource->success_sample_rate = 0.0; 185 resource->failure_sample_rate = 0.0; 186 config->resources.push_back(resource); 187 188 DomainReliabilityConfig::Collector* collector; 189 collector = new DomainReliabilityConfig::Collector(); 190 collector->upload_url = GURL("https://exampleuploader/upload"); 191 config->collectors.push_back(collector); 192 193 config->version = "1"; 194 config->valid_until = 1234567890.0; 195 config->domain = domain; 196 197 DCHECK(config->IsValid()); 198 199 return scoped_ptr<const DomainReliabilityConfig>(config); 200 } 201 202 } // namespace domain_reliability 203