GBP core tests improvements
[groupbasedpolicy.git] / groupbasedpolicy / src / test / java / org / opendaylight / groupbasedpolicy / util / SingletonTaskTest.java
1 /*
2  * Copyright 2011, Big Switch Networks, Inc.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.groupbasedpolicy.util;
10
11 import static org.junit.Assert.assertEquals;
12 import static org.junit.Assert.assertFalse;
13 import static org.junit.Assert.assertTrue;
14
15 import java.util.concurrent.Executors;
16 import java.util.concurrent.ScheduledExecutorService;
17 import java.util.concurrent.TimeUnit;
18
19 import org.junit.Before;
20 import org.junit.Test;
21
22 public class SingletonTaskTest {
23
24     private int ran;
25     private int finished;
26     private long time;
27
28     @Before
29     public void init() {
30         ran = 0;
31         finished = 0;
32         time = 0;
33     }
34
35     @Test
36     public void testBasic() throws InterruptedException {
37         ScheduledExecutorService ses =
38             Executors.newSingleThreadScheduledExecutor();
39
40         SingletonTask st1 = new SingletonTask(ses, new Runnable() {
41             @Override
42             public void run() {
43                 ran += 1;
44             }
45         });
46         st1.reschedule(0, null);
47         ses.shutdown();
48         ses.awaitTermination(5, TimeUnit.SECONDS);
49
50         assertEquals("Check that task ran", 1, ran);
51     }
52
53     @Test
54     public void testDelay() throws InterruptedException {
55         ScheduledExecutorService ses =
56             Executors.newSingleThreadScheduledExecutor();
57         ran = 0;
58
59         SingletonTask st1 = new SingletonTask(ses, new Runnable() {
60             @Override
61             public void run() {
62                 ran++;
63                 time = System.nanoTime();
64             }
65         });
66         long start = System.nanoTime();
67         st1.reschedule(10, TimeUnit.MILLISECONDS);
68         assertFalse("Task has run already", ran > 0);
69
70         ses.shutdown();
71         ses.awaitTermination(5, TimeUnit.SECONDS);
72
73         assertEquals("Check that task ran only once failed", 1, ran);
74         assertTrue("Check that time passed appropriately",
75                    (time - start) >= TimeUnit.NANOSECONDS.convert(10, TimeUnit.MILLISECONDS));
76     }
77
78     @Test
79     public void testReschedule() throws InterruptedException {
80         ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
81         ran = 0;
82         time = 0;
83
84         final long EPSILON_NS = 1500000; // 1.5 ms
85         final int DELAY_MS = 20;
86         final int NUM_OF_ITERATIONS = 8;
87         final int SLEEP_MS = 5;
88         final int AWAIT_SEC = 5;
89         final int EXPECTED_PASS_TIME =
90                 NUM_OF_ITERATIONS * SLEEP_MS + (DELAY_MS - SLEEP_MS);
91
92         final Object tc = this;
93         SingletonTask st1 = new SingletonTask(ses, new Runnable() {
94
95             @Override
96             public void run() {
97                 synchronized (tc) {
98                     ran++;
99                 }
100                 time = System.nanoTime();
101             }
102         });
103
104         long start = System.nanoTime();
105         for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
106             st1.reschedule(DELAY_MS, TimeUnit.MILLISECONDS);
107             Thread.sleep(SLEEP_MS);
108             assertFalse("Task has run already", ran > 0);
109         }
110
111         ses.shutdown();
112         ses.awaitTermination(AWAIT_SEC, TimeUnit.SECONDS);
113
114         assertEquals("Check that task ran only once failed", 1, ran);
115         assertTrue("Check that time passed appropriately: " + (time - start),
116                  (time - start) >= 1000000 * EXPECTED_PASS_TIME - EPSILON_NS);
117     }
118
119     @Test
120     public void testConcurrentAddDelay() throws InterruptedException {
121         ScheduledExecutorService ses =
122             Executors.newSingleThreadScheduledExecutor();
123
124         final Object tc = this;
125         SingletonTask st1 = new SingletonTask(ses, new Runnable() {
126             @Override
127             public void run() {
128                 synchronized (tc) {
129                     ran += 1;
130                 }
131                 try {
132                     Thread.sleep(50);
133                 } catch (InterruptedException e) {
134                     e.printStackTrace();
135                 }
136                 synchronized (tc) {
137                     finished += 1;
138                     time = System.nanoTime();
139                 }
140             }
141         });
142
143         long start = System.nanoTime();
144         st1.reschedule(5, TimeUnit.MILLISECONDS);
145         Thread.sleep(20);
146         assertEquals("Check that task started", 1, ran);
147         assertEquals("Check that task not finished", 0, finished);
148         st1.reschedule(75, TimeUnit.MILLISECONDS);
149         assertTrue("Check task running state true", st1.context.taskRunning);
150         assertTrue("Check task should run state true", st1.context.taskShouldRun);
151         assertEquals("Check that task started", 1, ran);
152         assertEquals("Check that task not finished", 0, finished);
153
154         Thread.sleep(150);
155
156         assertTrue("Check task running state false", !st1.context.taskRunning);
157         assertTrue("Check task should run state false", !st1.context.taskShouldRun);
158         assertEquals("Check that task ran exactly twice", 2, ran);
159         assertEquals("Check that task finished exactly twice", 2, finished);
160
161         assertTrue("Check that time passed appropriately: " + (time - start),
162                 (time - start) >= TimeUnit.NANOSECONDS.convert(130, TimeUnit.MILLISECONDS));
163         assertTrue("Check that time passed appropriately: " + (time - start),
164                 (time - start) <= TimeUnit.NANOSECONDS.convert(500, TimeUnit.MILLISECONDS));
165
166         ses.shutdown();
167         ses.awaitTermination(15, TimeUnit.SECONDS);
168     }
169
170     @Test
171     public void testConcurrentAddDelay2() throws InterruptedException {
172         ScheduledExecutorService ses =
173             Executors.newSingleThreadScheduledExecutor();
174
175         final Object tc = this;
176         SingletonTask st1 = new SingletonTask(ses, new Runnable() {
177             @Override
178             public void run() {
179                 synchronized (tc) {
180                     ran += 1;
181                 }
182                 try {
183                     Thread.sleep(50);
184                 } catch (InterruptedException e) {
185                     e.printStackTrace();
186                 }
187                 synchronized (tc) {
188                     finished += 1;
189                     time = System.nanoTime();
190                 }
191             }
192         });
193
194         long start = System.nanoTime();
195         st1.reschedule(5, TimeUnit.MILLISECONDS);
196         Thread.sleep(20);
197         assertEquals("Check that task started", 1, ran);
198         assertEquals("Check that task not finished", 0, finished);
199         st1.reschedule(25, TimeUnit.MILLISECONDS);
200         assertTrue("Check task running state true", st1.context.taskRunning);
201         assertTrue("Check task should run state true", st1.context.taskShouldRun);
202         assertEquals("Check that task started", 1, ran);
203         assertEquals("Check that task not finished", 0, finished);
204
205         Thread.sleep(150);
206
207         assertTrue("Check task running state false", !st1.context.taskRunning);
208         assertTrue("Check task should run state false", !st1.context.taskShouldRun);
209         assertEquals("Check that task ran exactly twice", 2, ran);
210         assertEquals("Check that task finished exactly twice", 2, finished);
211
212         assertTrue("Check that time passed appropriately: " + (time - start),
213                 (time - start) >= TimeUnit.NANOSECONDS.convert(100, TimeUnit.MILLISECONDS));
214         assertTrue("Check that time passed appropriately: " + (time - start),
215                 (time - start) <= TimeUnit.NANOSECONDS.convert(500, TimeUnit.MILLISECONDS));
216
217         ses.shutdown();
218         ses.awaitTermination(5, TimeUnit.SECONDS);
219     }
220
221
222     @Test
223     public void testConcurrentAddNoDelay() throws InterruptedException {
224         ScheduledExecutorService ses =
225             Executors.newSingleThreadScheduledExecutor();
226
227         final Object tc = this;
228         SingletonTask st1 = new SingletonTask(ses, new Runnable() {
229             @Override
230             public void run() {
231                 synchronized (tc) {
232                     ran += 1;
233                 }
234                 try {
235                     Thread.sleep(50);
236                 } catch (InterruptedException e) {
237                     e.printStackTrace();
238                 }
239                 synchronized (tc) {
240                     finished += 1;
241                     time = System.nanoTime();
242                 }
243             }
244         });
245
246         long start = System.nanoTime();
247         st1.reschedule(0, null);
248         Thread.sleep(20);
249         assertEquals("Check that task started", 1, ran);
250         assertEquals("Check that task not finished", 0, finished);
251         st1.reschedule(0, null);
252         assertTrue("Check task running state true", st1.context.taskRunning);
253         assertTrue("Check task should run state true", st1.context.taskShouldRun);
254         assertEquals("Check that task started", 1, ran);
255         assertEquals("Check that task not finished", 0, finished);
256
257         Thread.sleep(150);
258
259         assertTrue("Check task running state false", !st1.context.taskRunning);
260         assertTrue("Check task should run state false", !st1.context.taskShouldRun);
261         assertEquals("Check that task ran exactly twice", 2, ran);
262         assertEquals("Check that task finished exactly twice", 2, finished);
263
264         assertTrue("Check that time passed appropriately: " + (time - start),
265                 (time - start) >= TimeUnit.NANOSECONDS.convert(90, TimeUnit.MILLISECONDS));
266         assertTrue("Check that time passed appropriately: " + (time - start),
267                 (time - start) <= TimeUnit.NANOSECONDS.convert(500, TimeUnit.MILLISECONDS));
268
269         ses.shutdown();
270         ses.awaitTermination(5, TimeUnit.SECONDS);
271     }
272 }