| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 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 #ifndef CHROME_BROWSER_POLICY_LOGGING_WORK_SCHEDULER_H_ | |
| 6 #define CHROME_BROWSER_POLICY_LOGGING_WORK_SCHEDULER_H_ | |
| 7 | |
| 8 #include <queue> | |
| 9 #include <vector> | |
| 10 | |
| 11 #include "base/basictypes.h" | |
| 12 #include "base/callback.h" | |
| 13 #include "base/compiler_specific.h" | |
| 14 #include "base/memory/linked_ptr.h" | |
| 15 #include "base/memory/weak_ptr.h" | |
| 16 #include "chrome/browser/policy/delayed_work_scheduler.h" | |
| 17 | |
| 18 // Utilities for testing users of DelayedWorkScheduler. There are no | |
| 19 // thread-safety guarantees for the classes in this file. They expect to | |
| 20 // only be called from the UI thread and issue callbacks on that very same | |
| 21 // thread. | |
| 22 // | |
| 23 // Usage examples: | |
| 24 // | |
| 25 // Making CloudPolicyController and/or DeviceTokenFetcher run without real-time | |
| 26 // delays in tests: | |
| 27 // | |
| 28 // DeviceTokenFetcher fetcher(..., new DummyDelayedWorkScheduler); | |
| 29 // | |
| 30 // Running CloudPolicyController and/or DeviceTokenFetcher in a simulated | |
| 31 // environment, in which the time of any of their actions can be recorded, | |
| 32 // but without having to wait for the real-time delays: | |
| 33 // | |
| 34 // EventLogger logger; | |
| 35 // DeviceTokenFetcher fetcher(..., new LoggingEventScheduler(&logger)); | |
| 36 // CloudPolicyController controller(..., new LoggingEventScheduler(&logger)); | |
| 37 // | |
| 38 // Start the policy subsystem, and use logger.RegisterEvent() in case of | |
| 39 // any interesting events. The time of all these events will be recorded | |
| 40 // by |logger|. After that, the results can be extracted easily: | |
| 41 // | |
| 42 // std::vector<int64> logged_events; | |
| 43 // logger.Swap(&logged_events); | |
| 44 // | |
| 45 // Each element of |logged_events| corresponds to a logger event, and stores | |
| 46 // the virtual time when it was logged. Events are in ascending order. | |
| 47 | |
| 48 namespace policy { | |
| 49 | |
| 50 // Helper class for LoggingWorkScheduler. It essentially emulates a real | |
| 51 // message loop. All the submitted tasks are run with zero delay, but the | |
| 52 // order in which they would run with delays is preserved. | |
| 53 // All the task posting requests of the schedulers will be channeled through | |
| 54 // a common instance of EventLogger. This makes sure, that this instance can | |
| 55 // keep track of time in the simulation and record logged events with correct | |
| 56 // timestamps. | |
| 57 class EventLogger { | |
| 58 public: | |
| 59 EventLogger(); | |
| 60 ~EventLogger(); | |
| 61 | |
| 62 // Post a task to be executed |delay| milliseconds from now. The task can be | |
| 63 // cancelled later by calling Reset() on the callback. | |
| 64 void PostDelayedWork(linked_ptr<base::Closure> callback, int64 delay); | |
| 65 | |
| 66 // Register a new event that happened now according to the internal clock. | |
| 67 void RegisterEvent(); | |
| 68 | |
| 69 // Swap out the internal list of events. | |
| 70 void Swap(std::vector<int64>* events); | |
| 71 | |
| 72 // Counts the events in a sorted integer array that are >= |start| but | |
| 73 // < |start| + |length|. | |
| 74 static int CountEvents(const std::vector<int64>& events, | |
| 75 int64 start, int64 length); | |
| 76 | |
| 77 private: | |
| 78 class Task; | |
| 79 | |
| 80 // Updates |current_time_| and triggers the next scheduled task. This method | |
| 81 // is run repeatedly on the main message loop until there are scheduled | |
| 82 // tasks. | |
| 83 void Step(); | |
| 84 | |
| 85 // Stores the list of scheduled tasks with their respective delays and | |
| 86 // schedulers. | |
| 87 std::priority_queue<Task> scheduled_tasks_; | |
| 88 | |
| 89 // Machinery to put a call to |Step| at the end of the message loop. | |
| 90 bool step_pending_; | |
| 91 base::WeakPtrFactory<EventLogger> weak_ptr_factory_; | |
| 92 | |
| 93 // Ascending list of observation-times of the logged events. | |
| 94 std::vector<int64> events_; | |
| 95 // The current time of the simulated system. | |
| 96 int64 current_time_; | |
| 97 // The total number of tasks scheduled so far. | |
| 98 int64 task_counter_; | |
| 99 | |
| 100 DISALLOW_COPY_AND_ASSIGN(EventLogger); | |
| 101 }; | |
| 102 | |
| 103 // Issues delayed tasks with zero effective delay, but posts them through | |
| 104 // an EventLogger, to make it possible to log events and reconstruct their | |
| 105 // execution time. | |
| 106 class LoggingWorkScheduler : public DelayedWorkScheduler { | |
| 107 public: | |
| 108 // An EventLogger may be shared by more than one schedulers, therefore | |
| 109 // no ownership is taken. | |
| 110 explicit LoggingWorkScheduler(EventLogger* logger); | |
| 111 virtual ~LoggingWorkScheduler(); | |
| 112 | |
| 113 virtual void PostDelayedWork(const base::Closure& callback, int64 delay) | |
| 114 OVERRIDE; | |
| 115 virtual void CancelDelayedWork() OVERRIDE; | |
| 116 | |
| 117 private: | |
| 118 EventLogger* logger_; | |
| 119 linked_ptr<base::Closure> callback_; | |
| 120 | |
| 121 DISALLOW_COPY_AND_ASSIGN(LoggingWorkScheduler); | |
| 122 }; | |
| 123 | |
| 124 // This implementation of DelayedWorkScheduler always schedules the tasks | |
| 125 // with zero delay. | |
| 126 class DummyWorkScheduler : public DelayedWorkScheduler { | |
| 127 public: | |
| 128 DummyWorkScheduler(); | |
| 129 virtual ~DummyWorkScheduler(); | |
| 130 | |
| 131 virtual void PostDelayedWork(const base::Closure& callback, int64 delay) | |
| 132 OVERRIDE; | |
| 133 | |
| 134 private: | |
| 135 DISALLOW_COPY_AND_ASSIGN(DummyWorkScheduler); | |
| 136 }; | |
| 137 | |
| 138 } // namespace policy | |
| 139 | |
| 140 #endif // CHROME_BROWSER_POLICY_LOGGING_WORK_SCHEDULER_H_ | |
| OLD | NEW |