1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package net.grinder.console.communication;
23
24 import java.util.Arrays;
25 import java.util.Comparator;
26 import java.util.HashMap;
27 import java.util.Map;
28 import java.util.Timer;
29 import java.util.TimerTask;
30
31 import junit.framework.TestCase;
32 import net.grinder.common.processidentity.ProcessIdentity;
33 import net.grinder.common.processidentity.ProcessReport;
34 import net.grinder.common.processidentity.WorkerIdentity;
35 import net.grinder.common.processidentity.WorkerProcessReport;
36 import net.grinder.console.common.processidentity.StubAgentProcessReport;
37 import net.grinder.console.common.processidentity.StubWorkerProcessReport;
38 import net.grinder.console.communication.ProcessControl.ProcessReports;
39 import net.grinder.console.communication.ProcessStatusImplementation.AgentAndWorkers;
40 import net.grinder.engine.agent.StubAgentIdentity;
41 import net.grinder.messages.console.AgentAndCacheReport;
42 import net.grinder.testutility.AssertUtilities;
43 import net.grinder.testutility.CallData;
44 import net.grinder.testutility.RandomStubFactory;
45 import net.grinder.util.AllocateLowestNumber;
46
47
48
49
50
51
52
53 public class TestProcessStatusImplementation extends TestCase {
54 private final ProcessReportComparator m_processReportComparator =
55 new ProcessReportComparator();
56
57 private final Comparator<ProcessReports> m_processReportsComparator =
58 new ProcessReportsComparator();
59
60 private final MyTimer m_timer = new MyTimer();
61
62 private final RandomStubFactory<AllocateLowestNumber>
63 m_allocateLowestNumberStubFactory =
64 RandomStubFactory.create(AllocateLowestNumber.class);
65 private final AllocateLowestNumber m_allocateLowestNumber =
66 m_allocateLowestNumberStubFactory.getStub();
67
68 protected void tearDown() {
69 m_timer.cancel();
70 }
71
72 public void testConstruction() throws Exception {
73 new ProcessStatusImplementation(m_timer, m_allocateLowestNumber);
74
75 assertEquals(2, m_timer.getNumberOfScheduledTasks());
76
77 m_allocateLowestNumberStubFactory.assertNoMoreCalls();
78 }
79
80 public void testUpdate() throws Exception {
81
82 final RandomStubFactory<ProcessControl.Listener> listenerStubFactory =
83 RandomStubFactory.create(ProcessControl.Listener.class);
84
85 final ProcessStatusImplementation processStatusSet =
86 new ProcessStatusImplementation(m_timer, m_allocateLowestNumber);
87
88 final TimerTask updateTask = m_timer.getTaskByPeriod(500L);
89
90 processStatusSet.addListener(listenerStubFactory.getStub());
91
92 updateTask.run();
93 listenerStubFactory.assertNoMoreCalls();
94 m_allocateLowestNumberStubFactory.assertNoMoreCalls();
95
96 updateTask.run();
97 listenerStubFactory.assertNoMoreCalls();
98 m_allocateLowestNumberStubFactory.assertNoMoreCalls();
99
100 final StubAgentIdentity agentIdentity = new StubAgentIdentity("agent");
101 final WorkerIdentity workerIdentity =
102 agentIdentity.createWorkerIdentity();
103
104 final WorkerProcessReport workerProcessReport =
105 new StubWorkerProcessReport(workerIdentity,
106 ProcessReport.State.RUNNING,
107 3,
108 5);
109
110 processStatusSet.addWorkerStatusReport(workerProcessReport);
111 m_allocateLowestNumberStubFactory.assertSuccess("add", Object.class);
112 m_allocateLowestNumberStubFactory.assertNoMoreCalls();
113
114 updateTask.run();
115 final CallData callData =
116 listenerStubFactory.assertSuccess(
117 "update",
118 new ProcessControl.ProcessReports[0].getClass());
119
120 final ProcessControl.ProcessReports[] processReportsArray =
121 (ProcessControl.ProcessReports[])callData.getParameters()[0];
122
123 assertEquals(1, processReportsArray.length);
124 final WorkerProcessReport[] workerProcessReports =
125 processReportsArray[0].getWorkerProcessReports();
126 assertEquals(1, workerProcessReports.length);
127 assertEquals(workerProcessReport, workerProcessReports[0]);
128
129 updateTask.run();
130 listenerStubFactory.assertNoMoreCalls();
131 m_allocateLowestNumberStubFactory.assertNoMoreCalls();
132 }
133
134 public void testUpdateWithManyProcessStatusesAndFlush() throws Exception {
135 final RandomStubFactory<ProcessControl.Listener> listenerStubFactory =
136 RandomStubFactory.create(ProcessControl.Listener.class);
137
138 final ProcessStatusImplementation processStatus =
139 new ProcessStatusImplementation(m_timer, m_allocateLowestNumber);
140
141 final TimerTask updateTask = m_timer.getTaskByPeriod(500L);
142 final TimerTask flushTask = m_timer.getTaskByPeriod(2000L);
143
144 processStatus.addListener(listenerStubFactory.getStub());
145
146 updateTask.run();
147 listenerStubFactory.assertNoMoreCalls();
148 m_allocateLowestNumberStubFactory.assertNoMoreCalls();
149
150 final StubAgentIdentity agentIdentityA =
151 new StubAgentIdentity("Agent A");
152 final WorkerIdentity workerIdentityA1 =
153 agentIdentityA.createWorkerIdentity();
154 final WorkerIdentity workerIdentityA2 =
155 agentIdentityA.createWorkerIdentity();
156 final WorkerIdentity workerIdentityA3 =
157 agentIdentityA.createWorkerIdentity();
158 final WorkerIdentity workerIdentityA4 =
159 agentIdentityA.createWorkerIdentity();
160 assertEquals(3, workerIdentityA4.getNumber());
161
162 final StubAgentIdentity agentIdentityB =
163 new StubAgentIdentity("Agent B");
164 final WorkerIdentity workerIdentityB1 =
165 agentIdentityB.createWorkerIdentity();
166 assertEquals(0, workerIdentityB1.getNumber());
167
168 final WorkerProcessReport[] workerProcessReportArray = {
169 new StubWorkerProcessReport(
170 workerIdentityA3, ProcessReport.State.STARTED, 1, 1),
171 new StubWorkerProcessReport(
172 workerIdentityA4, ProcessReport.State.STARTED, 1, 1),
173 new StubWorkerProcessReport(
174 workerIdentityA3, ProcessReport.State.RUNNING, 5, 10),
175 new StubWorkerProcessReport(
176 workerIdentityB1, ProcessReport.State.RUNNING, 1, 1),
177 new StubWorkerProcessReport(
178 workerIdentityA2, ProcessReport.State.FINISHED, 1, 1),
179 new StubWorkerProcessReport(
180 workerIdentityA1, ProcessReport.State.FINISHED, 3, 10),
181 };
182
183 for (int i = 0; i < workerProcessReportArray.length; ++i) {
184 processStatus.addWorkerStatusReport(workerProcessReportArray[i]);
185 }
186
187 assertEquals(2, processStatus.getNumberOfLiveAgents());
188 m_allocateLowestNumberStubFactory.assertSuccess("add", Object.class);
189 m_allocateLowestNumberStubFactory.assertSuccess("add", Object.class);
190 m_allocateLowestNumberStubFactory.assertNoMoreCalls();
191
192 updateTask.run();
193
194 final CallData callData =
195 listenerStubFactory.assertSuccess(
196 "update",
197 new ProcessControl.ProcessReports[0].getClass());
198
199 final ProcessControl.ProcessReports[] processReports =
200 (ProcessControl.ProcessReports[])callData.getParameters()[0];
201 Arrays.sort(processReports, m_processReportsComparator);
202
203 assertEquals(2, processReports.length);
204
205 final WorkerProcessReport[] agent1WorkerReports =
206 processReports[0].getWorkerProcessReports();
207 Arrays.sort(agent1WorkerReports, m_processReportComparator);
208
209 final WorkerProcessReport[] expectedAgent1WorkerProcessReports = {
210 new StubWorkerProcessReport(
211 workerIdentityA4, ProcessReport.State.STARTED, 1, 1),
212 new StubWorkerProcessReport(
213 workerIdentityA3, ProcessReport.State.RUNNING, 5, 10),
214 new StubWorkerProcessReport(
215 workerIdentityA1, ProcessReport.State.FINISHED, 3, 10),
216 new StubWorkerProcessReport(
217 workerIdentityA2, ProcessReport.State.FINISHED, 1, 1),
218 };
219
220 AssertUtilities.assertArraysEqual(expectedAgent1WorkerProcessReports,
221 agent1WorkerReports);
222
223 final WorkerProcessReport[] agent2WorkerReports =
224 processReports[1].getWorkerProcessReports();
225 Arrays.sort(agent2WorkerReports, m_processReportComparator);
226
227 final WorkerProcessReport[] expectedAgent2WorkerProcessReports = {
228 new StubWorkerProcessReport(
229 workerIdentityB1, ProcessReport.State.RUNNING, 1, 1),
230 };
231
232 AssertUtilities.assertArraysEqual(expectedAgent2WorkerProcessReports,
233 agent2WorkerReports);
234
235 updateTask.run();
236 listenerStubFactory.assertNoMoreCalls();
237
238
239 flushTask.run();
240 updateTask.run();
241 listenerStubFactory.assertNoMoreCalls();
242 m_allocateLowestNumberStubFactory.assertNoMoreCalls();
243
244 final StubAgentIdentity agentIdentityC =
245 new StubAgentIdentity("Agent C");
246 final WorkerIdentity workerIdentityC1 =
247 agentIdentityC.createWorkerIdentity();
248
249 final WorkerProcessReport[] processStatusArray2 = {
250 new StubWorkerProcessReport(
251 workerIdentityB1, ProcessReport.State.RUNNING, 1, 1),
252 new StubWorkerProcessReport(
253 workerIdentityA1, ProcessReport.State.RUNNING, 5, 10),
254 new StubWorkerProcessReport(
255 workerIdentityC1, ProcessReport.State.FINISHED, 1, 1),
256 };
257
258 for (int i = 0; i < processStatusArray2.length; ++i) {
259 processStatus.addWorkerStatusReport(processStatusArray2[i]);
260 }
261
262 assertEquals(3, processStatus.getNumberOfLiveAgents());
263 m_allocateLowestNumberStubFactory.assertSuccess("add", Object.class);
264 m_allocateLowestNumberStubFactory.assertNoMoreCalls();
265
266 processStatus.addAgentStatusReport(
267 new StubAgentProcessReport(agentIdentityA,
268 ProcessReport.State.RUNNING));
269 processStatus.addAgentStatusReport(
270 new StubAgentProcessReport(agentIdentityB,
271 ProcessReport.State.RUNNING));
272
273 assertEquals(3, processStatus.getNumberOfLiveAgents());
274 m_allocateLowestNumberStubFactory.assertNoMoreCalls();
275
276
277
278
279 flushTask.run();
280 updateTask.run();
281
282 final CallData callData2 =
283 listenerStubFactory.assertSuccess(
284 "update",
285 new ProcessControl.ProcessReports[0].getClass());
286
287 final ProcessControl.ProcessReports[] processReports2 =
288 (ProcessControl.ProcessReports[])callData2.getParameters()[0];
289 Arrays.sort(processReports2, m_processReportsComparator);
290
291 assertEquals(3, processReports2.length);
292 m_allocateLowestNumberStubFactory.assertNoMoreCalls();
293
294 final WorkerProcessReport[] expectedAgent1WorkerProcessReports2 = {
295 new StubWorkerProcessReport(
296 workerIdentityA1, ProcessReport.State.RUNNING, 5, 10),
297 };
298
299 AssertUtilities.assertArraysEqual(
300 expectedAgent1WorkerProcessReports2,
301 processReports2[0].getWorkerProcessReports());
302
303 final WorkerProcessReport[] expectedAgent2WorkerProcessReports2 = {
304 new StubWorkerProcessReport(
305 workerIdentityB1, ProcessReport.State.RUNNING, 1, 1),
306 };
307
308 AssertUtilities.assertArraysEqual(
309 expectedAgent2WorkerProcessReports2,
310 processReports2[1].getWorkerProcessReports());
311
312 final WorkerProcessReport[] expectedAgent3WorkerProcessReports2 = {
313 new StubWorkerProcessReport(
314 workerIdentityC1, ProcessReport.State.FINISHED, 1, 1),
315 };
316
317 AssertUtilities.assertArraysEqual(
318 expectedAgent3WorkerProcessReports2,
319 processReports2[2].getWorkerProcessReports());
320
321 updateTask.run();
322 listenerStubFactory.assertNoMoreCalls();
323
324
325 flushTask.run();
326
327 assertEquals(0, processStatus.getNumberOfLiveAgents());
328 m_allocateLowestNumberStubFactory.assertSuccess("remove", Object.class);
329 m_allocateLowestNumberStubFactory.assertSuccess("remove", Object.class);
330 m_allocateLowestNumberStubFactory.assertSuccess("remove", Object.class);
331 m_allocateLowestNumberStubFactory.assertNoMoreCalls();
332 }
333
334 public void testAgentAndWorkers() throws Exception {
335 final ProcessStatusImplementation processStatusSet =
336 new ProcessStatusImplementation(m_timer, m_allocateLowestNumber);
337
338 final StubAgentIdentity agentIdentity =
339 new StubAgentIdentity("agent");
340
341 final AgentAndWorkers agentAndWorkers =
342 processStatusSet.new AgentAndWorkers(agentIdentity);
343
344 final AgentAndCacheReport initialReport =
345 agentAndWorkers.getAgentProcessReport();
346
347 assertEquals(agentIdentity, initialReport.getAgentIdentity());
348
349 assertNull(initialReport.getCacheHighWaterMark());
350 }
351
352 private static final class MyTimer extends Timer {
353 private final Map<Long, TimerTask> m_taskByPeriod =
354 new HashMap<Long, TimerTask>();
355
356 private int m_numberOfScheduledTasks;
357
358 MyTimer() {
359 super(true);
360 }
361
362 public void schedule(TimerTask timerTask, long delay, long period) {
363 assertEquals(0, delay);
364
365 m_taskByPeriod.put(new Long(period), timerTask);
366 ++m_numberOfScheduledTasks;
367 }
368
369 public TimerTask getTaskByPeriod(long period) {
370 return m_taskByPeriod.get(new Long(period));
371 }
372
373 public int getNumberOfScheduledTasks() {
374 return m_numberOfScheduledTasks;
375 }
376 }
377
378
379 private static final class ProcessReportComparator
380 implements Comparator<ProcessReport> {
381
382 public int compare(ProcessReport processReport1,
383 ProcessReport processReport2) {
384 final int compareState =
385 processReport1.getState().compareTo(processReport2.getState());
386
387 if (compareState == 0) {
388 final ProcessIdentity identity1 =
389 processReport1.getProcessAddress().getIdentity();
390 final ProcessIdentity identity2 =
391 processReport2.getProcessAddress().getIdentity();
392
393 return identity1.getName().compareTo(identity2.getName());
394 }
395 else {
396 return compareState;
397 }
398 }
399 }
400
401 private final class ProcessReportsComparator
402 implements Comparator<ProcessReports> {
403
404 public int compare(ProcessReports o1, ProcessReports o2) {
405 return m_processReportComparator.compare(o1.getAgentProcessReport(),
406 o2.getAgentProcessReport());
407 }
408 }
409 }