-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathActiveObjectTest.java
146 lines (114 loc) · 5.63 KB
/
ActiveObjectTest.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
//@formatter:off
/*
* Active Object Test - demonstrates ACTIVE OBJECT pattern.
* Code-Beispiel zum Buch Patterns Kompakt, Verlag Springer Vieweg
* Copyright 2014 Karl Eilebrecht
*
* Licensed under the Apache License, Version 2.0 (the "License"):
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//@formatter:on
package de.calamanari.pk.activeobject;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.awaitility.Awaitility;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import de.calamanari.pk.util.TimeUtils;
/**
* Active Object Test - demonstrates ACTIVE OBJECT pattern.
*
* @author <a href="mailto:Karl.Eilebrecht(a/t)calamanari.de">Karl Eilebrecht</a>
*/
public class ActiveObjectTest {
private static final Logger LOGGER = LoggerFactory.getLogger(ActiveObjectTest.class);
/**
* some test data
*/
private static final List<String[]> MOCK_HISTORY_DATA;
static {
MOCK_HISTORY_DATA = new ArrayList<>();
MOCK_HISTORY_DATA.add(new String[] { "Jack", "Miller", "1976-08-08", "The quick brown fox jumped over the lazy dog." });
MOCK_HISTORY_DATA.add(new String[] { "Lisa", "Miller", "1978-10-17", "Bad bananas punished by old trees." });
MOCK_HISTORY_DATA.add(new String[] { "Mary", "Gin-Tonic", "1978-10-17", "Blue apes on skyscrapers." });
}
/**
* test duration for mock calls
*/
private static final long CALL_DURATION = 5000;
/**
* number of worker threads for test
*/
private static final int NUMBER_OF_WORKERS = 2; // Runtime.getRuntime().availableProcessors()
@Test
public void testActiveObject() {
// HINTS:
// * Adjust the log-level in logback.xml to DEBUG to see the ACTIVE OBJECT working
// * Play with the settings for CALL_DURATION / NUMBER_OF_WORKERS and watch execution time
LOGGER.info("Test Active Object ...");
long startTimeNanos = System.nanoTime();
AbstractHistoryQueryEngine engine = new HistoryQueryEngineMock(MOCK_HISTORY_DATA, CALL_DURATION);
HistoryQueryScheduler scheduler = new HistoryQueryScheduler(NUMBER_OF_WORKERS);
// component configured to execute queries on the engine using the scheduler
HistoryQueryComponent queryComponent = new HistoryQueryComponent(engine, scheduler);
// now let's query
QueryRequestFuture future1 = queryComponent.queryHistoryData("Jack", "Miller", "1976-08-08");
QueryRequestFuture future2 = queryComponent.queryHistoryData(null, "Miller", "1978-10-17");
QueryRequestFuture future3 = queryComponent.queryHistoryData(null, null, "1978-10-17");
Awaitility.await().atMost(20, TimeUnit.SECONDS).pollInterval(2, TimeUnit.SECONDS)
.until(() -> future1.isQueryDone() && future2.isQueryDone() && future3.isQueryDone());
List<String[]> result1 = future1.getResult();
List<String[]> result2 = future2.getResult();
List<String[]> result3 = future3.getResult();
assertNotSame(QueryRequestFuture.NO_RESULT, result1);
assertNotSame(QueryRequestFuture.NO_RESULT, result2);
assertNotSame(QueryRequestFuture.NO_RESULT, result3);
assertEquals(1, result1.size());
assertEquals(1, result2.size());
assertEquals(2, result3.size());
assertEquals("The quick brown fox jumped over the lazy dog.", result1.get(0)[3]);
assertEquals("Bad bananas punished by old trees.", result2.get(0)[3]);
assertEquals("Blue apes on skyscrapers.", result3.get(1)[3]);
String elapsedSeconds = TimeUtils.formatNanosAsSeconds(System.nanoTime() - startTimeNanos);
LOGGER.info("Test Active Object successful! Elapsed time: {} s", elapsedSeconds);
}
@Test
public void testActiveObjectCancel() throws RuntimeException {
LOGGER.info("Test Active Object cancel ...");
long startTimeNanos = System.nanoTime();
AbstractHistoryQueryEngine engine = new HistoryQueryEngineMock(MOCK_HISTORY_DATA, 10000); // 10 seconds
HistoryQueryScheduler scheduler = new HistoryQueryScheduler(1); // one call in parallel
// component configured to execute queries on the engine using the scheduler
HistoryQueryComponent queryComponent = new HistoryQueryComponent(engine, scheduler);
// now let's query
QueryRequestFuture future1 = queryComponent.queryHistoryData("Jack", "Miller", "1976-08-08");
int waitCount = 0;
while (!future1.isQueryDone()) {
if (waitCount >= 3) {
future1.cancelQuery();
break;
}
Awaitility.await().pollDelay(2, TimeUnit.SECONDS).until(() -> true);
waitCount++;
}
assertTrue(future1.isQueryCancelled());
assertSame(QueryRequestFuture.NO_RESULT, future1.getResult());
String elapsedSeconds = TimeUtils.formatNanosAsSeconds(System.nanoTime() - startTimeNanos);
LOGGER.info("Test Active Object cancel successful! Elapsed time: {} s", elapsedSeconds);
}
}