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