123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// found in the LICENSE file.
423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#ifndef COMPONENTS_DOMAIN_RELIABILITY_TEST_UTIL_H_
623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#define COMPONENTS_DOMAIN_RELIABILITY_TEST_UTIL_H_
723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
8f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "base/callback_forward.h"
9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/domain_reliability/config.h"
11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/domain_reliability/scheduler.h"
12effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "components/domain_reliability/uploader.h"
1323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "components/domain_reliability/util.h"
1423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "net/base/host_port_pair.h"
1523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
1623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)namespace net {
1723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)class URLRequestStatus;
1823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}  // namespace net
1923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
2023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)namespace domain_reliability {
2123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
2223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// A simple test callback that remembers whether it's been called.
2323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)class TestCallback {
2423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) public:
2523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  TestCallback();
2623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  ~TestCallback();
2723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
2823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Returns a callback that can be called only once.
2923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  const base::Closure& callback() const { return callback_; }
3023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Returns whether the callback returned by |callback()| has been called.
3123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  bool called() const { return called_; }
3223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
3323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) private:
3423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  void OnCalled();
3523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
3623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  base::Closure callback_;
3723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  bool called_;
3823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)};
3923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
40effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochclass MockUploader : public DomainReliabilityUploader {
41effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch public:
42effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  typedef base::Callback<void(const std::string& report_json,
43effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                              const GURL& upload_url,
44effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                              const UploadCallback& upload_callback)>
45effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      UploadRequestCallback;
46effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
47effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  MockUploader(const UploadRequestCallback& callback);
480de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
49effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  virtual ~MockUploader();
50effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual bool discard_uploads() const;
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
53a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // DomainReliabilityUploader implementation:
54effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  virtual void UploadReport(const std::string& report_json,
55effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                            const GURL& upload_url,
56effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                            const UploadCallback& callback) OVERRIDE;
57effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void set_discard_uploads(bool discard_uploads) OVERRIDE;
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
60effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch private:
61effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  UploadRequestCallback callback_;
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool discard_uploads_;
63effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch};
64effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
6523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)class MockTime : public MockableTime {
6623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) public:
6723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  MockTime();
680de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
6923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // N.B.: Tasks (and therefore Timers) scheduled to run in the future will
7023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // never be run if MockTime is destroyed before the mock time is advanced
7123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // to their scheduled time.
7223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  virtual ~MockTime();
7323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
74effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // MockableTime implementation:
75a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  virtual base::Time Now() OVERRIDE;
76a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  virtual base::TimeTicks NowTicks() OVERRIDE;
7723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  virtual scoped_ptr<MockableTime::Timer> CreateTimer() OVERRIDE;
7823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
7923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Pretends that |delta| has passed, and runs tasks that would've happened
8023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // during that interval (with |Now()| returning proper values while they
8123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // execute!)
8223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  void Advance(base::TimeDelta delta);
8323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
8423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Queues |task| to be run after |delay|. (Lighter-weight than mocking an
8523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // entire message pump.)
8623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  void AddTask(base::TimeDelta delay, const base::Closure& task);
8723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
8823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) private:
8923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Key used to store tasks in the task map. Includes the time the task should
9023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // run and a sequence number to disambiguate tasks with the same time.
9123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  struct TaskKey {
9223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    TaskKey(base::TimeTicks time, int sequence_number)
9323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        : time(time),
9423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)          sequence_number(sequence_number) {}
9523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
9623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    base::TimeTicks time;
9723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    int sequence_number;
9823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  };
9923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
10023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Comparator for TaskKey; sorts by time, then by sequence number.
10123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  struct TaskKeyCompare {
10223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    bool operator() (const TaskKey& lhs, const TaskKey& rhs) const {
10323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      return lhs.time < rhs.time ||
10423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)             (lhs.time == rhs.time &&
10523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)              lhs.sequence_number < rhs.sequence_number);
10623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    }
10723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  };
10823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
10923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  typedef std::map<TaskKey, base::Closure, TaskKeyCompare> TaskMap;
11023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
111a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  void AdvanceToInternal(base::TimeTicks target_ticks);
11223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
113a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  int elapsed_sec() { return (now_ticks_ - epoch_ticks_).InSeconds(); }
114a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
115a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  base::Time now_;
116a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  base::TimeTicks now_ticks_;
117a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  base::TimeTicks epoch_ticks_;
11823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  int task_sequence_number_;
11923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  TaskMap tasks_;
12023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)};
12123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)scoped_ptr<const DomainReliabilityConfig> MakeTestConfig();
1236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)scoped_ptr<const DomainReliabilityConfig> MakeTestConfigWithDomain(
1246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const std::string& domain);
125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)DomainReliabilityScheduler::Params MakeTestSchedulerParams();
126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
12723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}  // namespace domain_reliability
12823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
12923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#endif  // COMPONENTS_DOMAIN_RELIABILITY_TEST_UTIL_H_
130