| 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 |