1 // Copyright 2010-2018, Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 //     * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 //     * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 //     * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 
30 #include "base/scheduler_stub.h"
31 
32 #include "testing/base/public/gunit.h"
33 
34 namespace mozc {
35 namespace {
36 
37 static int g_counter = 0;
38 static bool g_result = true;
39 
TestFunc(void * data)40 bool TestFunc(void *data) {
41   ++g_counter;
42   return g_result;
43 }
44 
45 class SchedulerStubTest : public ::testing::Test {
46  protected:
SetUp()47   virtual void SetUp() {
48     g_counter = 0;
49     g_result = true;
50   }
51 
TearDown()52   virtual void TearDown() {
53     g_counter = 0;
54     g_result = true;
55   }
56 };
57 
TEST_F(SchedulerStubTest,AddRemoveJob)58 TEST_F(SchedulerStubTest, AddRemoveJob) {
59   SchedulerStub scheduler_stub;
60   EXPECT_FALSE(scheduler_stub.HasJob("Test"));
61   scheduler_stub.AddJob(Scheduler::JobSetting(
62       "Test", 1000, 100000, 5000, 0, &TestFunc, NULL));
63   EXPECT_TRUE(scheduler_stub.HasJob("Test"));
64   EXPECT_EQ(0, g_counter);
65   scheduler_stub.PutClockForward(1000);
66   EXPECT_EQ(0, g_counter);
67   scheduler_stub.PutClockForward(1000);
68   EXPECT_EQ(0, g_counter);
69   scheduler_stub.PutClockForward(1000);
70   EXPECT_EQ(0, g_counter);
71   scheduler_stub.PutClockForward(1000);
72   EXPECT_EQ(0, g_counter);
73   scheduler_stub.PutClockForward(1000);  // delay_start
74   EXPECT_EQ(1, g_counter);
75 
76   scheduler_stub.PutClockForward(1000);  // default_interval
77   EXPECT_EQ(2, g_counter);
78 
79   scheduler_stub.PutClockForward(1000);  // default_interval
80   EXPECT_EQ(3, g_counter);
81 
82   scheduler_stub.RemoveJob("Test");
83   scheduler_stub.PutClockForward(1000);
84   EXPECT_EQ(3, g_counter);
85   scheduler_stub.PutClockForward(1000);
86   EXPECT_EQ(3, g_counter);
87   EXPECT_FALSE(scheduler_stub.HasJob("Test"));
88 }
89 
TEST_F(SchedulerStubTest,BackOff)90 TEST_F(SchedulerStubTest, BackOff) {
91   SchedulerStub scheduler_stub;
92   scheduler_stub.AddJob(Scheduler::JobSetting(
93       "Test", 1000, 6000, 3000, 0, &TestFunc, NULL));
94   g_result = false;
95   EXPECT_EQ(0, g_counter);
96   scheduler_stub.PutClockForward(1000);
97   EXPECT_EQ(0, g_counter);
98   scheduler_stub.PutClockForward(1000);
99   EXPECT_EQ(0, g_counter);
100   scheduler_stub.PutClockForward(1000);  // delay_start
101   EXPECT_EQ(1, g_counter);
102 
103   scheduler_stub.PutClockForward(1000);  // backoff (wait 1000 + 1000)
104   EXPECT_EQ(1, g_counter);
105   scheduler_stub.PutClockForward(1000);
106   EXPECT_EQ(2, g_counter);
107 
108   scheduler_stub.PutClockForward(1000);  // backoff (wait 1000 + 1000 * 2)
109   EXPECT_EQ(2, g_counter);
110   scheduler_stub.PutClockForward(1000);
111   EXPECT_EQ(2, g_counter);
112   scheduler_stub.PutClockForward(1000);
113   EXPECT_EQ(3, g_counter);
114 
115   scheduler_stub.PutClockForward(1000);  // backoff (wait 1000 + 1000 * 4)
116   EXPECT_EQ(3, g_counter);
117   scheduler_stub.PutClockForward(1000);
118   EXPECT_EQ(3, g_counter);
119   scheduler_stub.PutClockForward(1000);
120   EXPECT_EQ(3, g_counter);
121   scheduler_stub.PutClockForward(1000);
122   EXPECT_EQ(3, g_counter);
123   scheduler_stub.PutClockForward(1000);
124   EXPECT_EQ(4, g_counter);
125 
126   // backoff (wait 1000 + 1000 * 8) > 6000, use same delay
127   scheduler_stub.PutClockForward(1000);
128   EXPECT_EQ(4, g_counter);
129   scheduler_stub.PutClockForward(1000);
130   EXPECT_EQ(4, g_counter);
131   scheduler_stub.PutClockForward(1000);
132   EXPECT_EQ(4, g_counter);
133   scheduler_stub.PutClockForward(1000);
134   EXPECT_EQ(4, g_counter);
135   scheduler_stub.PutClockForward(1000);
136   EXPECT_EQ(5, g_counter);
137 
138   g_result = true;
139 
140   // use same delay
141   scheduler_stub.PutClockForward(1000);
142   EXPECT_EQ(5, g_counter);
143   scheduler_stub.PutClockForward(1000);
144   EXPECT_EQ(5, g_counter);
145   scheduler_stub.PutClockForward(1000);
146   EXPECT_EQ(5, g_counter);
147   scheduler_stub.PutClockForward(1000);
148   EXPECT_EQ(5, g_counter);
149   scheduler_stub.PutClockForward(1000);
150   EXPECT_EQ(6, g_counter);
151 
152   scheduler_stub.PutClockForward(1000);
153   EXPECT_EQ(7, g_counter);
154   scheduler_stub.PutClockForward(1000);
155   EXPECT_EQ(8, g_counter);
156 }
157 
TEST_F(SchedulerStubTest,AddRemoveJobs)158 TEST_F(SchedulerStubTest, AddRemoveJobs) {
159   SchedulerStub scheduler_stub;
160   scheduler_stub.AddJob(Scheduler::JobSetting(
161       "Test1", 1000, 100000, 1000, 0, &TestFunc, NULL));
162   EXPECT_EQ(0, g_counter);
163   scheduler_stub.PutClockForward(1000);  // delay
164   EXPECT_EQ(1, g_counter);
165 
166   scheduler_stub.AddJob(Scheduler::JobSetting(
167       "Test2", 1000, 100000, 1000, 0, &TestFunc, NULL));
168 
169   scheduler_stub.PutClockForward(1000);  // delay + interval
170   EXPECT_EQ(3, g_counter);
171 
172   scheduler_stub.PutClockForward(1000);
173   EXPECT_EQ(5, g_counter);
174 
175   scheduler_stub.RemoveJob("Test3");  // nothing happens
176   scheduler_stub.PutClockForward(1000);
177   EXPECT_EQ(7, g_counter);
178 
179   scheduler_stub.RemoveJob("Test2");
180   scheduler_stub.PutClockForward(1000);
181   EXPECT_EQ(8, g_counter);
182 
183   scheduler_stub.RemoveAllJobs();
184   scheduler_stub.PutClockForward(1000);
185   EXPECT_EQ(8, g_counter);
186 }
187 }  // namespace
188 }  // namespace mozc
189