OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
Sami
2016/04/20 09:51:27
++year
tdresser
2016/04/20 15:13:33
Done.
| |
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 "base/memory/scoped_ptr.h" | |
6 #include "base/test/simple_test_tick_clock.h" | |
7 #include "components/scheduler/base/test_time_source.h" | |
8 #include "components/scheduler/renderer/queueing_time_estimator.h" | |
9 #include "testing/gmock/include/gmock/gmock.h" | |
10 #include "testing/gtest/include/gtest/gtest.h" | |
11 | |
12 namespace scheduler { | |
13 | |
14 class QueueingTimeEstimatorTest : public testing::Test { | |
15 public: | |
16 QueueingTimeEstimatorTest() {} | |
17 ~QueueingTimeEstimatorTest() override {} | |
18 | |
19 void SetUp() override { | |
20 test_time_source_.reset(new TestTimeSource(&clock_)); | |
21 } | |
22 | |
23 base::SimpleTestTickClock clock_; | |
24 scoped_ptr<TestTimeSource> test_time_source_; | |
25 }; | |
26 | |
27 class TestQueueingTimeEstimatorClient | |
28 : public QueueingTimeEstimator::QueueingTimeEstimatorClient { | |
29 public: | |
30 void OnQueueingTimeForWindowEstimated( | |
31 base::TimeDelta queueing_time) override { | |
32 expected_queueing_times_.push_back(queueing_time); | |
33 } | |
34 const std::vector<base::TimeDelta>& expected_queueing_times() { | |
35 return expected_queueing_times_; | |
36 } | |
37 | |
38 private: | |
39 std::vector<base::TimeDelta> expected_queueing_times_; | |
40 }; | |
41 | |
42 class QueueingTimeEstimatorForTest : public QueueingTimeEstimator { | |
43 public: | |
44 QueueingTimeEstimatorForTest(TestQueueingTimeEstimatorClient* client, | |
45 TestTimeSource* test_time_source, | |
46 base::TimeDelta window_duration) | |
47 : QueueingTimeEstimator(client, test_time_source, window_duration) {} | |
48 }; | |
49 | |
50 // Three tasks of one second each, all within a 5 second window. Expected | |
51 // queueing time is the probability of falling into one of these tasks (3/5), | |
52 // multiplied by the expected queueing time within a task (0.5 seconds). Thus we | |
53 // expect a queueing time of 0.3 seconds. | |
54 TEST_F(QueueingTimeEstimatorTest, AllTasksWithinWindow) { | |
55 TestQueueingTimeEstimatorClient client; | |
56 QueueingTimeEstimatorForTest estimator(&client, test_time_source_.get(), | |
57 base::TimeDelta::FromSeconds(5)); | |
58 base::PendingTask task(FROM_HERE, base::Closure()); | |
59 | |
60 for (int i = 0; i < 3; ++i) { | |
61 estimator.WillProcessTask(task); | |
62 clock_.Advance(base::TimeDelta::FromMilliseconds(1000)); | |
63 estimator.DidProcessTask(task); | |
64 | |
65 clock_.Advance(base::TimeDelta::FromMilliseconds(500)); | |
66 } | |
67 | |
68 // Flush the data by adding a task in the next window. | |
69 clock_.Advance(base::TimeDelta::FromMilliseconds(5000)); | |
70 estimator.WillProcessTask(task); | |
71 clock_.Advance(base::TimeDelta::FromMilliseconds(500)); | |
72 estimator.DidProcessTask(task); | |
73 | |
74 EXPECT_THAT(client.expected_queueing_times(), | |
75 testing::ElementsAre(base::TimeDelta::FromMilliseconds(300))); | |
76 } | |
77 | |
78 // One 20 second long task, starting 3 seconds into the first window. | |
79 // Window 1: Probability of being within task = 2/5. Expected delay within task: | |
80 // avg(20, 18). Total expected queueing time = 7.6s. | |
81 // Window 2: Probability of being within task = 1. Expected delay within task: | |
82 // avg(18, 13). Total expected queueing time = 15.5s. | |
83 // Window 5: Probability of being within task = 3/5. Expected delay within task: | |
84 // avg(3, 0). Total expected queueing time = 0.9s. | |
85 TEST_F(QueueingTimeEstimatorTest, MultiWindowTask) { | |
86 TestQueueingTimeEstimatorClient client; | |
87 QueueingTimeEstimatorForTest estimator(&client, test_time_source_.get(), | |
88 base::TimeDelta::FromSeconds(5)); | |
89 base::PendingTask task(FROM_HERE, base::Closure()); | |
90 | |
91 estimator.WillProcessTask(task); | |
92 clock_.Advance(base::TimeDelta::FromMilliseconds(0)); | |
93 estimator.DidProcessTask(task); | |
94 | |
95 clock_.Advance(base::TimeDelta::FromMilliseconds(3000)); | |
96 | |
97 estimator.WillProcessTask(task); | |
98 clock_.Advance(base::TimeDelta::FromMilliseconds(20000)); | |
99 estimator.DidProcessTask(task); | |
100 | |
101 // Flush the data by adding a task in the next window. | |
102 clock_.Advance(base::TimeDelta::FromMilliseconds(5000)); | |
103 estimator.WillProcessTask(task); | |
104 clock_.Advance(base::TimeDelta::FromMilliseconds(500)); | |
105 estimator.DidProcessTask(task); | |
106 | |
107 EXPECT_THAT(client.expected_queueing_times(), | |
108 testing::ElementsAre(base::TimeDelta::FromMilliseconds(7600), | |
109 base::TimeDelta::FromMilliseconds(15500), | |
110 base::TimeDelta::FromMilliseconds(10500), | |
111 base::TimeDelta::FromMilliseconds(5500), | |
112 base::TimeDelta::FromMilliseconds(900))); | |
113 } | |
114 | |
115 /*TEST_F(QueueingTimeEstimatorTest, Clear) { | |
tdresser
2016/04/19 17:23:46
I don't think we should clear this estimator on na
Sami
2016/04/20 09:51:27
Not clearing it should give more accurate results
tdresser
2016/04/20 15:13:33
Acknowledged.
| |
116 QueueingTimeEstimatorForTest estimator(test_time_source_.get(), 1, 100); | |
117 base::PendingTask task(FROM_HERE, base::Closure()); | |
118 | |
119 estimator.WillProcessTask(task); | |
120 clock_.Advance(base::TimeDelta::FromMilliseconds(500)); | |
121 estimator.DidProcessTask(task); | |
122 | |
123 estimator.Clear(); | |
124 | |
125 EXPECT_EQ(base::TimeDelta(), estimator.expected_task_duration()); | |
126 }*/ | |
127 | |
128 // A single task with a nested message loop. The top level task lasts 4 seconds. | |
129 // Probability of landing within this task = 4/5, expected queueing time within | |
130 // this task = 2s. Total expected queueing time = 1.6. | |
131 TEST_F(QueueingTimeEstimatorTest, NestedRunLoop) { | |
132 TestQueueingTimeEstimatorClient client; | |
133 QueueingTimeEstimatorForTest estimator(&client, test_time_source_.get(), | |
134 base::TimeDelta::FromSeconds(5)); | |
135 base::PendingTask task(FROM_HERE, base::Closure()); | |
136 | |
137 // Make sure we ignore the tasks inside the nested run loop. | |
138 estimator.WillProcessTask(task); | |
139 estimator.WillProcessTask(task); | |
140 clock_.Advance(base::TimeDelta::FromMilliseconds(2000)); | |
141 estimator.DidProcessTask(task); | |
142 clock_.Advance(base::TimeDelta::FromMilliseconds(2000)); | |
143 estimator.DidProcessTask(task); | |
144 | |
145 // Flush the data by adding a task in the next window. | |
146 clock_.Advance(base::TimeDelta::FromMilliseconds(5000)); | |
147 estimator.WillProcessTask(task); | |
148 clock_.Advance(base::TimeDelta::FromMilliseconds(500)); | |
149 estimator.DidProcessTask(task); | |
150 | |
151 EXPECT_THAT(client.expected_queueing_times(), | |
152 testing::ElementsAre(base::TimeDelta::FromMilliseconds(1600))); | |
153 } | |
154 | |
155 } // namespace scheduler | |
OLD | NEW |