1
1
package bwapi ;
2
2
3
- import static org .assertj .core .api .Assertions .assertThat ;
4
- import static org .junit .Assert .assertEquals ;
5
- import static org .junit .Assert .assertNull ;
6
- import static org .junit .Assert .assertThrows ;
7
- import static org .mockito .Mockito .*;
3
+ import org .junit .Test ;
8
4
9
- import java .util .HashMap ;
10
- import java .util .Map ;
11
5
import java .util .stream .IntStream ;
12
6
13
- import org .junit .Rule ;
14
- import org .junit .Test ;
15
- import org .junit .rules . Timeout ;
7
+ import static org .junit .Assert . assertEquals ;
8
+ import static org .junit .Assert . assertThrows ;
9
+ import static org .junit .Assert . assertTrue ;
16
10
17
11
public class SynchronizationTest {
18
12
@@ -24,6 +18,26 @@ private void sleepUnchecked(int milliseconds) {
24
18
}
25
19
}
26
20
21
+ private String describeApproximateExpectation (double expected , double actual , double margin ) {
22
+ return "Expected " + expected + " == " + actual + " +/- " + margin ;
23
+ }
24
+
25
+ private boolean measureApproximateEquality (double expected , double actual , double margin ) {
26
+ return expected + margin >= actual && expected - margin <= actual ;
27
+ }
28
+
29
+ private void assertWithin (double expected , double actual , double margin ) {
30
+ assertTrue (
31
+ describeApproximateExpectation (expected , actual , margin ),
32
+ measureApproximateEquality (expected , actual , margin ));
33
+ }
34
+
35
+ private void assertWithin (String message , double expected , double actual , double margin ) {
36
+ assertTrue (
37
+ message + ": " + describeApproximateExpectation (expected , actual , margin ),
38
+ measureApproximateEquality (expected , actual , margin ));
39
+ }
40
+
27
41
@ Test
28
42
public void sync_IfException_ThrowException () throws InterruptedException {
29
43
SynchronizationEnvironment environment = new SynchronizationEnvironment ();
@@ -48,6 +62,7 @@ public void sync_IfDelay_ThenNoBuffer() throws InterruptedException {
48
62
environment .configuration .async = false ;
49
63
environment .configuration .asyncFrameDurationMs = 1 ;
50
64
environment .configuration .asyncFrameBufferSize = 3 ;
65
+
51
66
IntStream .range (0 , 5 ).forEach (frame -> {
52
67
environment .onFrame (frame , () -> {
53
68
sleepUnchecked (5 );
@@ -61,17 +76,163 @@ public void sync_IfDelay_ThenNoBuffer() throws InterruptedException {
61
76
}
62
77
63
78
@ Test
64
- public void async_IfDelay_ThenBuffer () throws InterruptedException {
79
+ public void async_IfBotDelay_ThenClientBuffers () throws InterruptedException {
65
80
SynchronizationEnvironment environment = new SynchronizationEnvironment ();
66
81
environment .configuration .async = true ;
67
- environment .configuration .asyncFrameDurationMs = 1 ;
82
+ environment .configuration .asyncFrameDurationMs = 10 ;
68
83
environment .configuration .asyncFrameBufferSize = 4 ;
84
+
69
85
environment .onFrame (1 , () -> {
70
- sleepUnchecked (5 );
86
+ sleepUnchecked (40 );
71
87
assertEquals ("Bot should be observing an old frame" , 1 , environment .bwClient .getGame ().getFrameCount ());
72
88
assertEquals ("Client should be as far ahead as the frame buffer allows" , 4 , environment .liveGameData ().getFrameCount ());
73
89
assertEquals ("Bot should be behind the live game" , 3 , environment .bwClient .framesBehind ());
74
90
});
91
+
92
+ environment .onFrame (6 , () -> { // Maybe it should be possible to demand that these assertions pass a frame earlier?
93
+ assertEquals ("Bot should be observing the live frame" , 6 , environment .bwClient .getGame ().getFrameCount ());
94
+ assertEquals ("Client should not be ahead of the bot" , 6 , environment .liveGameData ().getFrameCount ());
95
+ assertEquals ("Bot should not be behind the live game" , 0 , environment .bwClient .framesBehind ());
96
+ });
97
+
98
+ environment .runGame ();
99
+ }
100
+
101
+ @ Test
102
+ public void async_IfBotDelay_ThenClientStalls () throws InterruptedException {
103
+ SynchronizationEnvironment environment = new SynchronizationEnvironment ();
104
+ environment .configuration .async = true ;
105
+ environment .configuration .asyncFrameDurationMs = 50 ;
106
+ environment .configuration .asyncFrameBufferSize = 5 ;
107
+
108
+ environment .onFrame (1 , () -> {
109
+ sleepUnchecked (125 );
110
+ assertEquals ("3: Bot should be observing an old frame" , 1 , environment .bwClient .getGame ().getFrameCount ());
111
+ assertEquals ("3: Client should have progressed as slowly as possible" , 3 , environment .liveGameData ().getFrameCount ());
112
+ assertEquals ("3: Bot should be behind the live game by as little as possible" , 2 , environment .bwClient .framesBehind ());
113
+ sleepUnchecked (50 );
114
+ assertEquals ("4: Bot should be observing an old frame" , 1 , environment .bwClient .getGame ().getFrameCount ());
115
+ assertEquals ("4: Client should have progressed as slowly as possible" , 4 , environment .liveGameData ().getFrameCount ());
116
+ assertEquals ("4: Bot should be behind the live game by as little as possible" , 3 , environment .bwClient .framesBehind ());
117
+ sleepUnchecked (50 );
118
+ assertEquals ("5: Bot should be observing an old frame" , 1 , environment .bwClient .getGame ().getFrameCount ());
119
+ assertEquals ("5: Client should have progressed as slowly as possible" , 5 , environment .liveGameData ().getFrameCount ());
120
+ assertEquals ("5: Bot should be behind the live game by as little as possible" , 4 , environment .bwClient .framesBehind ());
121
+ });
122
+
75
123
environment .runGame ();
76
124
}
125
+
126
+ @ Test
127
+ public void async_IfFrameZeroWaitsEnabled_ThenAllowInfiniteTime () throws InterruptedException {
128
+ SynchronizationEnvironment environment = new SynchronizationEnvironment ();
129
+ environment .configuration .async = true ;
130
+ environment .configuration .unlimitedFrameZero = true ;
131
+ environment .configuration .asyncFrameDurationMs = 5 ;
132
+ environment .configuration .asyncFrameBufferSize = 2 ;
133
+
134
+ environment .onFrame (0 , () -> {
135
+ sleepUnchecked (50 );
136
+ assertEquals ("Bot should still be on frame zero" , 0 , environment .bwClient .getGame ().getFrameCount ());
137
+ assertEquals ("Client should still be on frame zero" , 0 , environment .liveGameData ().getFrameCount ());
138
+ assertEquals ("Bot should not be behind the live game" , 0 , environment .bwClient .framesBehind ());
139
+ });
140
+
141
+ environment .runGame ();
142
+ }
143
+
144
+ @ Test
145
+ public void async_IfFrameZeroWaitsDisabled_ThenClientBuffers () throws InterruptedException {
146
+ SynchronizationEnvironment environment = new SynchronizationEnvironment ();
147
+ environment .configuration .async = true ;
148
+ environment .configuration .unlimitedFrameZero = false ;
149
+ environment .configuration .asyncFrameDurationMs = 5 ;
150
+ environment .configuration .asyncFrameBufferSize = 2 ;
151
+
152
+ environment .onFrame (0 , () -> {
153
+ sleepUnchecked (50 );
154
+ assertEquals ("Bot should still be on frame zero" , 0 , environment .bwClient .getGame ().getFrameCount ());
155
+ assertEquals ("Client should have advanced to the next frame" , 2 , environment .liveGameData ().getFrameCount ());
156
+ assertEquals ("Bot should be behind the live game" , 2 , environment .bwClient .framesBehind ());
157
+ });
158
+
159
+ environment .runGame ();
160
+ }
161
+
162
+ @ Test
163
+ public void async_MeasurePerformance_TotalFrameDuration () {
164
+
165
+ }
166
+
167
+ @ Test
168
+ public void async_MeasurePerformance_CopyingToBuffer () {
169
+
170
+ }
171
+
172
+ @ Test
173
+ public void async_MeasurePerformance_IntentionallyBlocking () {
174
+
175
+ }
176
+
177
+ @ Test
178
+ public void async_MeasurePerformance_FrameBufferSize () {
179
+
180
+ }
181
+
182
+ @ Test
183
+ public void async_MeasurePerformance_FlushSideEffects () {
184
+
185
+ }
186
+
187
+ /**
188
+ * Number of milliseconds of leeway to give in performance metrics.
189
+ * Increase if tests are flaky due to variance in execution speed.
190
+ */
191
+ private final static long MS_MARGIN = 10 ;
192
+
193
+ @ Test
194
+ public void async_MeasurePerformance_BotResponse () {
195
+ SynchronizationEnvironment environment = new SynchronizationEnvironment ();
196
+
197
+ // Frame zero appears to take an extra 60ms, so let's disable timing for it
198
+ // (and also verify that we omit frame zero from performance metrics)
199
+ environment .configuration .unlimitedFrameZero = true ;
200
+
201
+ environment .onFrame (1 , () -> {
202
+ sleepUnchecked (100 );
203
+ });
204
+ environment .onFrame (2 , () -> {
205
+ assertWithin ("2: Bot response average" , 100 , environment .metrics ().botResponse .avgValue , MS_MARGIN );
206
+ assertWithin ("2: Bot response minimum" , 100 , environment .metrics ().botResponse .minValue , MS_MARGIN );
207
+ assertWithin ("2: Bot response maximum" , 100 , environment .metrics ().botResponse .maxValue , MS_MARGIN );
208
+ assertWithin ("2: Bot response previous" , 100 , environment .metrics ().botResponse .lastValue , MS_MARGIN );
209
+ sleepUnchecked (300 );
210
+ });
211
+ environment .onFrame (3 , () -> {
212
+ assertWithin ("3: Bot response average" , 200 , environment .metrics ().botResponse .avgValue , MS_MARGIN );
213
+ assertWithin ("3: Bot response minimum" , 100 , environment .metrics ().botResponse .minValue , MS_MARGIN );
214
+ assertWithin ("3: Bot response maximum" , 300 , environment .metrics ().botResponse .maxValue , MS_MARGIN );
215
+ assertWithin ("3: Bot response previous" , 300 , environment .metrics ().botResponse .lastValue , MS_MARGIN );
216
+ sleepUnchecked (200 );
217
+ });
218
+
219
+ environment .runGame (4 );
220
+
221
+ assertWithin ("Final: Bot response average" , 200 , environment .metrics ().botResponse .avgValue , MS_MARGIN );
222
+ assertWithin ("Final: Bot response minimum" , 100 , environment .metrics ().botResponse .minValue , MS_MARGIN );
223
+ assertWithin ("Final: Bot response maximum" , 300 , environment .metrics ().botResponse .maxValue , MS_MARGIN );
224
+ assertWithin ("Final: Bot response previous" , 200 , environment .metrics ().botResponse .lastValue , MS_MARGIN );
225
+ }
226
+
227
+ @ Test
228
+ public void async_MeasurePerformance_BwapiResponse () {
229
+
230
+ }
231
+
232
+ @ Test
233
+ public void async_MeasurePerformance_BotIdle () {
234
+
235
+ }
236
+
237
+
77
238
}
0 commit comments