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 92 MockUploader::~MockUploader() {} 93 94 void MockUploader::UploadReport(const std::string& report_json, 95 const GURL& upload_url, 96 const UploadCallback& callback) { 97 callback_.Run(report_json, upload_url, callback); 98 } 99 100 MockTime::MockTime() 101 : now_(base::Time::Now()), 102 now_ticks_(base::TimeTicks::Now()), 103 epoch_ticks_(now_ticks_), 104 task_sequence_number_(0) { 105 VLOG(1) << "Creating mock time: T=" << elapsed_sec() << "s"; 106 } 107 108 MockTime::~MockTime() {} 109 110 base::Time MockTime::Now() { return now_; } 111 base::TimeTicks MockTime::NowTicks() { return now_ticks_; } 112 113 scoped_ptr<MockableTime::Timer> MockTime::CreateTimer() { 114 return scoped_ptr<MockableTime::Timer>(new MockTimer(this)); 115 } 116 117 void MockTime::Advance(base::TimeDelta delta) { 118 base::TimeTicks target_ticks = now_ticks_ + delta; 119 120 while (!tasks_.empty() && tasks_.begin()->first.time <= target_ticks) { 121 TaskKey key = tasks_.begin()->first; 122 base::Closure task = tasks_.begin()->second; 123 tasks_.erase(tasks_.begin()); 124 125 DCHECK(now_ticks_ <= key.time); 126 DCHECK(key.time <= target_ticks); 127 AdvanceToInternal(key.time); 128 VLOG(1) << "Advancing mock time: task at T=" << elapsed_sec() << "s"; 129 130 task.Run(); 131 } 132 133 DCHECK(now_ticks_ <= target_ticks); 134 AdvanceToInternal(target_ticks); 135 VLOG(1) << "Advanced mock time: T=" << elapsed_sec() << "s"; 136 } 137 138 void MockTime::AddTask(base::TimeDelta delay, const base::Closure& task) { 139 tasks_[TaskKey(now_ticks_ + delay, task_sequence_number_++)] = task; 140 } 141 142 void MockTime::AdvanceToInternal(base::TimeTicks target_ticks) { 143 base::TimeDelta delta = target_ticks - now_ticks_; 144 now_ += delta; 145 now_ticks_ += delta; 146 } 147 148 DomainReliabilityScheduler::Params MakeTestSchedulerParams() { 149 DomainReliabilityScheduler::Params params; 150 params.minimum_upload_delay = base::TimeDelta::FromMinutes(1); 151 params.maximum_upload_delay = base::TimeDelta::FromMinutes(5); 152 params.upload_retry_interval = base::TimeDelta::FromSeconds(15); 153 return params; 154 } 155 156 scoped_ptr<const DomainReliabilityConfig> MakeTestConfig() { 157 DomainReliabilityConfig* config = new DomainReliabilityConfig(); 158 DomainReliabilityConfig::Resource* resource; 159 160 resource = new DomainReliabilityConfig::Resource(); 161 resource->name = "always_report"; 162 resource->url_patterns.push_back( 163 new std::string("http://example/always_report")); 164 resource->success_sample_rate = 1.0; 165 resource->failure_sample_rate = 1.0; 166 config->resources.push_back(resource); 167 168 resource = new DomainReliabilityConfig::Resource(); 169 resource->name = "never_report"; 170 resource->url_patterns.push_back( 171 new std::string("http://example/never_report")); 172 resource->success_sample_rate = 0.0; 173 resource->failure_sample_rate = 0.0; 174 config->resources.push_back(resource); 175 176 DomainReliabilityConfig::Collector* collector; 177 collector = new DomainReliabilityConfig::Collector(); 178 collector->upload_url = GURL("https://example/upload"); 179 config->collectors.push_back(collector); 180 181 config->version = "1"; 182 config->valid_until = 1234567890.0; 183 config->domain = "example"; 184 185 DCHECK(config->IsValid()); 186 187 return scoped_ptr<const DomainReliabilityConfig>(config); 188 } 189 190 } // namespace domain_reliability 191