blob: 9a29852b671b6d270536a815c9942617d5a97b9d [file] [log] [blame]
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -08001/**
2* Copyright 2011, Big Switch Networks, Inc.
3* Originally created by David Erickson, Stanford University
4*
5* Licensed under the Apache License, Version 2.0 (the "License"); you may
6* not use this file except in compliance with the License. You may obtain
7* a copy of the License at
8*
9* http://www.apache.org/licenses/LICENSE-2.0
10*
11* Unless required by applicable law or agreed to in writing, software
12* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14* License for the specific language governing permissions and limitations
15* under the License.
16**/
17
18package net.floodlightcontroller.core.util;
19
20import java.util.concurrent.Executors;
21import java.util.concurrent.ScheduledExecutorService;
22import java.util.concurrent.TimeUnit;
23
Jonathan Harta88fd242014-04-03 11:24:54 -070024import net.floodlightcontroller.test.FloodlightTestCase;
25
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080026import org.junit.Before;
27import org.junit.Test;
28
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080029public class SingletonTaskTest extends FloodlightTestCase {
30
31 public int ran = 0;
32 public int finished = 0;
33 public long time = 0;
34
35 @Before
36 public void setup() {
37 ran = 0;
38 finished = 0;
39 time = 0;
40 }
41
42 @Test
43 public void testBasic() throws InterruptedException {
44 ScheduledExecutorService ses =
45 Executors.newSingleThreadScheduledExecutor();
46
47 SingletonTask st1 = new SingletonTask(ses, new Runnable() {
48 @Override
49 public void run() {
50 ran += 1;
51 }
52 });
53 st1.reschedule(0, null);
54 ses.shutdown();
55 ses.awaitTermination(5, TimeUnit.SECONDS);
56
57 assertEquals("Check that task ran", 1, ran);
58 }
59
60 @Test
61 public void testDelay() throws InterruptedException {
62 ScheduledExecutorService ses =
63 Executors.newSingleThreadScheduledExecutor();
64
65 SingletonTask st1 = new SingletonTask(ses, new Runnable() {
66 @Override
67 public void run() {
68 ran += 1;
69 time = System.nanoTime();
70 }
71 });
72 long start = System.nanoTime();
73 st1.reschedule(10, TimeUnit.MILLISECONDS);
74 assertFalse("Check that task hasn't run yet", ran > 0);
75
76 ses.shutdown();
77 ses.awaitTermination(5, TimeUnit.SECONDS);
78
79 assertEquals("Check that task ran", 1, ran);
80 assertTrue("Check that time passed appropriately",
81 (time - start) >= TimeUnit.NANOSECONDS.convert(10, TimeUnit.MILLISECONDS));
82 }
83
84 @Test
85 public void testReschedule() throws InterruptedException {
86 ScheduledExecutorService ses =
87 Executors.newSingleThreadScheduledExecutor();
88
89 final Object tc = this;
90 SingletonTask st1 = new SingletonTask(ses, new Runnable() {
91 @Override
92 public void run() {
93 synchronized (tc) {
94 ran += 1;
95 }
96 time = System.nanoTime();
97 }
98 });
99 long start = System.nanoTime();
100 st1.reschedule(20, TimeUnit.MILLISECONDS);
101 Thread.sleep(5);
102 assertFalse("Check that task hasn't run yet", ran > 0);
103 st1.reschedule(20, TimeUnit.MILLISECONDS);
104 Thread.sleep(5);
105 assertFalse("Check that task hasn't run yet", ran > 0);
106 st1.reschedule(20, TimeUnit.MILLISECONDS);
107 Thread.sleep(5);
108 assertFalse("Check that task hasn't run yet", ran > 0);
109 st1.reschedule(20, TimeUnit.MILLISECONDS);
110 Thread.sleep(5);
111 assertFalse("Check that task hasn't run yet", ran > 0);
112 st1.reschedule(20, TimeUnit.MILLISECONDS);
113 Thread.sleep(5);
114 assertFalse("Check that task hasn't run yet", ran > 0);
115 st1.reschedule(20, TimeUnit.MILLISECONDS);
116 Thread.sleep(5);
117 assertFalse("Check that task hasn't run yet", ran > 0);
118 st1.reschedule(20, TimeUnit.MILLISECONDS);
119 Thread.sleep(5);
120 assertFalse("Check that task hasn't run yet", ran > 0);
121 st1.reschedule(20, TimeUnit.MILLISECONDS);
122 Thread.sleep(5);
123 assertFalse("Check that task hasn't run yet", ran > 0);
124
125 ses.shutdown();
126 ses.awaitTermination(5, TimeUnit.SECONDS);
127
128 assertEquals("Check that task ran only once", 1, ran);
129 assertTrue("Check that time passed appropriately: " + (time - start),
130 (time - start) >= TimeUnit.NANOSECONDS.convert(55, TimeUnit.MILLISECONDS));
131 }
132
133 @Test
134 public void testConcurrentAddDelay() throws InterruptedException {
135 ScheduledExecutorService ses =
136 Executors.newSingleThreadScheduledExecutor();
137
138 final Object tc = this;
139 SingletonTask st1 = new SingletonTask(ses, new Runnable() {
140 @Override
141 public void run() {
142 synchronized (tc) {
143 ran += 1;
144 }
145 try {
146 Thread.sleep(50);
147 } catch (InterruptedException e) {
148 e.printStackTrace();
149 }
150 synchronized (tc) {
151 finished += 1;
152 time = System.nanoTime();
153 }
154 }
155 });
156
157 long start = System.nanoTime();
158 st1.reschedule(5, TimeUnit.MILLISECONDS);
159 Thread.sleep(20);
160 assertEquals("Check that task started", 1, ran);
161 assertEquals("Check that task not finished", 0, finished);
162 st1.reschedule(75, TimeUnit.MILLISECONDS);
163 assertTrue("Check task running state true", st1.context.taskRunning);
164 assertTrue("Check task should run state true", st1.context.taskShouldRun);
165 assertEquals("Check that task started", 1, ran);
166 assertEquals("Check that task not finished", 0, finished);
167
168 Thread.sleep(150);
169
170 assertTrue("Check task running state false", !st1.context.taskRunning);
171 assertTrue("Check task should run state false", !st1.context.taskShouldRun);
172 assertEquals("Check that task ran exactly twice", 2, ran);
173 assertEquals("Check that task finished exactly twice", 2, finished);
174
175 assertTrue("Check that time passed appropriately: " + (time - start),
176 (time - start) >= TimeUnit.NANOSECONDS.convert(130, TimeUnit.MILLISECONDS));
177 assertTrue("Check that time passed appropriately: " + (time - start),
178 (time - start) <= TimeUnit.NANOSECONDS.convert(160, TimeUnit.MILLISECONDS));
179
180 ses.shutdown();
181 ses.awaitTermination(5, TimeUnit.SECONDS);
182 }
183
184 @Test
185 public void testConcurrentAddDelay2() throws InterruptedException {
186 ScheduledExecutorService ses =
187 Executors.newSingleThreadScheduledExecutor();
188
189 final Object tc = this;
190 SingletonTask st1 = new SingletonTask(ses, new Runnable() {
191 @Override
192 public void run() {
193 synchronized (tc) {
194 ran += 1;
195 }
196 try {
197 Thread.sleep(50);
198 } catch (InterruptedException e) {
199 // TODO Auto-generated catch block
200 e.printStackTrace();
201 }
202 synchronized (tc) {
203 finished += 1;
204 time = System.nanoTime();
205 }
206 }
207 });
208
209 long start = System.nanoTime();
210 st1.reschedule(5, TimeUnit.MILLISECONDS);
211 Thread.sleep(20);
212 assertEquals("Check that task started", 1, ran);
213 assertEquals("Check that task not finished", 0, finished);
214 st1.reschedule(25, TimeUnit.MILLISECONDS);
215 assertTrue("Check task running state true", st1.context.taskRunning);
216 assertTrue("Check task should run state true", st1.context.taskShouldRun);
217 assertEquals("Check that task started", 1, ran);
218 assertEquals("Check that task not finished", 0, finished);
219
220 Thread.sleep(150);
221
222 assertTrue("Check task running state false", !st1.context.taskRunning);
223 assertTrue("Check task should run state false", !st1.context.taskShouldRun);
224 assertEquals("Check that task ran exactly twice", 2, ran);
225 assertEquals("Check that task finished exactly twice", 2, finished);
226
227 assertTrue("Check that time passed appropriately: " + (time - start),
228 (time - start) >= TimeUnit.NANOSECONDS.convert(100, TimeUnit.MILLISECONDS));
229 assertTrue("Check that time passed appropriately: " + (time - start),
230 (time - start) <= TimeUnit.NANOSECONDS.convert(125, TimeUnit.MILLISECONDS));
231
232 ses.shutdown();
233 ses.awaitTermination(5, TimeUnit.SECONDS);
234 }
235
236
237 @Test
238 public void testConcurrentAddNoDelay() throws InterruptedException {
239 ScheduledExecutorService ses =
240 Executors.newSingleThreadScheduledExecutor();
241
242 final Object tc = this;
243 SingletonTask st1 = new SingletonTask(ses, new Runnable() {
244 @Override
245 public void run() {
246 synchronized (tc) {
247 ran += 1;
248 }
249 try {
250 Thread.sleep(50);
251 } catch (InterruptedException e) {
252 // TODO Auto-generated catch block
253 e.printStackTrace();
254 }
255 synchronized (tc) {
256 finished += 1;
257 time = System.nanoTime();
258 }
259 }
260 });
261
262 long start = System.nanoTime();
263 st1.reschedule(0, null);
264 Thread.sleep(20);
265 assertEquals("Check that task started", 1, ran);
266 assertEquals("Check that task not finished", 0, finished);
267 st1.reschedule(0, null);
268 assertTrue("Check task running state true", st1.context.taskRunning);
269 assertTrue("Check task should run state true", st1.context.taskShouldRun);
270 assertEquals("Check that task started", 1, ran);
271 assertEquals("Check that task not finished", 0, finished);
272
273 Thread.sleep(150);
274
275 assertTrue("Check task running state false", !st1.context.taskRunning);
276 assertTrue("Check task should run state false", !st1.context.taskShouldRun);
277 assertEquals("Check that task ran exactly twice", 2, ran);
278 assertEquals("Check that task finished exactly twice", 2, finished);
279
280 assertTrue("Check that time passed appropriately: " + (time - start),
281 (time - start) >= TimeUnit.NANOSECONDS.convert(90, TimeUnit.MILLISECONDS));
282 assertTrue("Check that time passed appropriately: " + (time - start),
283 (time - start) <= TimeUnit.NANOSECONDS.convert(130, TimeUnit.MILLISECONDS));
284
285 ses.shutdown();
286 ses.awaitTermination(5, TimeUnit.SECONDS);
287 }
288}