View Javadoc

1   // Copyright (C) 2008 - 2012 Philip Aston
2   // All rights reserved.
3   //
4   // This file is part of The Grinder software distribution. Refer to
5   // the file LICENSE which is part of The Grinder distribution for
6   // licensing details. The Grinder distribution is available on the
7   // Internet at http://grinder.sourceforge.net/
8   //
9   // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
10  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
11  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
12  // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
13  // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
14  // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
15  // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
16  // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
17  // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
18  // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
19  // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
20  // OF THE POSSIBILITY OF SUCH DAMAGE.
21  
22  package net.grinder.console.textui;
23  
24  import static org.junit.Assert.assertTrue;
25  import static org.mockito.Matchers.contains;
26  import static org.mockito.Matchers.matches;
27  import static org.mockito.Mockito.verify;
28  import static org.mockito.Mockito.verifyNoMoreInteractions;
29  
30  import java.util.HashMap;
31  
32  import net.grinder.common.processidentity.ProcessReport;
33  import net.grinder.common.processidentity.WorkerProcessReport;
34  import net.grinder.console.common.ErrorHandler;
35  import net.grinder.console.common.Resources;
36  import net.grinder.console.common.StubResources;
37  import net.grinder.console.common.processidentity.StubAgentProcessReport;
38  import net.grinder.console.common.processidentity.StubWorkerProcessReport;
39  import net.grinder.console.communication.ProcessControl;
40  import net.grinder.console.communication.ProcessControl.ProcessReports;
41  import net.grinder.console.communication.StubProcessReports;
42  import net.grinder.console.model.SampleModel;
43  import net.grinder.engine.agent.StubAgentIdentity;
44  import net.grinder.testutility.CallData;
45  import net.grinder.testutility.RandomStubFactory;
46  
47  import org.junit.Before;
48  import org.junit.Test;
49  import org.mockito.Mock;
50  import org.mockito.MockitoAnnotations;
51  import org.slf4j.Logger;
52  
53  
54  /**
55   * Unit tests for {@link TextUI}.
56   *
57   * @author Philip Aston
58   */
59  public class TestTextUI {
60  
61    private final Resources m_resources = new StubResources<String>(
62      new HashMap<String, String>() {{
63        put("finished.text", "done");
64        put("noConnectedAgents.text", "no agents!");
65        put("processTable.threads.label", "strings");
66        put("processTable.agentProcess.label", "AG");
67        put("processTable.workerProcess.label", "WK");
68        put("processState.started.label", "hot to trot");
69        put("processState.running.label", "rolling");
70        put("processState.connected.label", "plugged in");
71        put("processState.finished.label", "fini");
72        put("processState.disconnected.label", "that's all folks");
73        put("processState.unknown.label", "huh");
74      }}
75    );
76  
77    @Mock private Logger m_logger;
78  
79    private final RandomStubFactory<ProcessControl> m_processControlStubFactory =
80      RandomStubFactory.create(ProcessControl.class);
81    private final ProcessControl m_processControl =
82      m_processControlStubFactory.getStub();
83  
84    private final RandomStubFactory<SampleModel> m_sampleModelStubFactory =
85      RandomStubFactory.create(SampleModel.class);
86    private final SampleModel m_sampleModel =
87      m_sampleModelStubFactory.getStub();
88  
89    @Before public void setUp() {
90      MockitoAnnotations.initMocks(this);
91    }
92  
93    @Test public void testErrorHandler() throws Exception {
94      final TextUI textUI =
95        new TextUI(m_resources, m_processControl, m_sampleModel, m_logger);
96      verify(m_logger).info(contains("The Grinder"));
97  
98      final ErrorHandler errorHandler = textUI.getErrorHandler();
99  
100     errorHandler.handleErrorMessage("I let down their tyres");
101     verify(m_logger).error("I let down their tyres");
102 
103     errorHandler.handleErrorMessage("with matches", "seeyamate");
104     verify(m_logger).error(matches(".*seeyamate.*with matches.*"));
105 
106     final RuntimeException exception = new RuntimeException("wild dogs");
107     errorHandler.handleException(exception);
108     verify(m_logger).error("wild dogs", exception);
109 
110     errorHandler.handleException(exception, "the residents");
111     verify(m_logger).error("the residents", exception);
112 
113     errorHandler.handleInformationMessage("austin maxi");
114     verify(m_logger).info("austin maxi");
115 
116     Runtime.getRuntime().removeShutdownHook(textUI.getShutdownHook());
117     verifyNoMoreInteractions(m_logger);
118 
119     m_sampleModelStubFactory.assertSuccess(
120       "addModelListener", SampleModel.Listener.class);
121   }
122 
123   @Test public void testProcessStatusListener() throws Exception {
124     final TextUI textUI =
125       new TextUI(m_resources, m_processControl, m_sampleModel, m_logger);
126     verify(m_logger).info(contains("The Grinder"));
127 
128     final CallData processsControlCall =
129       m_processControlStubFactory.assertSuccess(
130         "addProcessStatusListener", ProcessControl.Listener.class);
131     final ProcessControl.Listener processListener =
132       (ProcessControl.Listener)processsControlCall.getParameters()[0];
133 
134     Runtime.getRuntime().removeShutdownHook(textUI.getShutdownHook());
135 
136     final ProcessReports[] reports1 = new ProcessReports[0];
137     processListener.update(reports1);
138     verify(m_logger).info("no agents!");
139 
140     processListener.update(reports1);
141 
142     processListener.update(reports1);
143 
144     final StubAgentIdentity agentIdentity1 = new StubAgentIdentity("agent1");
145     final StubAgentProcessReport agentReport1 =
146       new StubAgentProcessReport(agentIdentity1, ProcessReport.State.RUNNING);
147 
148     final WorkerProcessReport workerProcessReport1 =
149       new StubWorkerProcessReport(agentIdentity1.createWorkerIdentity(),
150                                   ProcessReport.State.RUNNING, 3, 6);
151 
152     final WorkerProcessReport workerProcessReport2 =
153       new StubWorkerProcessReport(agentIdentity1.createWorkerIdentity(),
154                                   ProcessReport.State.FINISHED, 0, 6);
155 
156     processListener.update(
157       new ProcessReports[] {
158         new StubProcessReports(agentReport1,
159                                new WorkerProcessReport[] {
160                                  workerProcessReport1,
161                                  workerProcessReport2,
162                                }),
163       });
164 
165     verify(m_logger).info(
166       "AG agent1 [plugged in] " +
167       "{ WK agent1-0 [rolling (3/6 strings)], WK agent1-1 [fini] }");
168 
169     processListener.update(
170       new ProcessReports[] {
171         new StubProcessReports(agentReport1,
172                                new WorkerProcessReport[] {
173                                  workerProcessReport2,
174                                  workerProcessReport1,
175                                }),
176       });
177 
178     final StubAgentIdentity agentIdentity2 = new StubAgentIdentity("agent2");
179     final StubAgentProcessReport agentReport2 =
180       new StubAgentProcessReport(agentIdentity2, ProcessReport.State.FINISHED);
181 
182     processListener.update(
183       new ProcessReports[] {
184           new StubProcessReports(agentReport2,
185             new WorkerProcessReport[] { }),
186         new StubProcessReports(agentReport1,
187                                new WorkerProcessReport[] {
188                                  workerProcessReport2,
189                                  workerProcessReport1,
190                                }),
191       });
192 
193     verify(m_logger).info(
194       "AG agent1 [plugged in] " +
195       "{ WK agent1-0 [rolling (3/6 strings)], WK agent1-1 [fini] }, " +
196       "AG agent2 [that's all folks]");
197 
198     verifyNoMoreInteractions(m_logger);
199   }
200 
201   @Test public void testSampleModelListener() throws Exception {
202     new TextUI(m_resources, m_processControl, m_sampleModel, m_logger);
203     verify(m_logger).info(contains("The Grinder"));
204 
205     final Object[] addListenerParameters =
206       m_sampleModelStubFactory.assertSuccess(
207         "addModelListener", SampleModel.Listener.class).getParameters();
208 
209     final SampleModel.Listener listener =
210       (SampleModel.Listener)addListenerParameters[0];
211 
212     m_sampleModelStubFactory.setResult(
213       "getState",
214       new SampleModel.State() {
215           public String getDescription() {
216             return "no pressure son";
217           }
218 
219           @Override
220           public Value getValue() {
221             return Value.Stopped;
222           }
223 
224           @Override
225           public long getSampleCount() {
226             return -1;
227           }
228         } );
229 
230 
231     listener.newSample();
232     listener.newTests(null, null);
233     listener.resetTests();
234 
235 
236     listener.stateChanged();
237     verify(m_logger).info("no pressure son");
238 
239     verifyNoMoreInteractions(m_logger);
240   }
241 
242   @Test public void testShutdownHook() throws Exception {
243     final TextUI textUI =
244       new TextUI(m_resources, m_processControl, m_sampleModel, m_logger);
245 
246     verify(m_logger).info(contains("The Grinder"));
247 
248     final Thread shutdownHook = textUI.getShutdownHook();
249     assertTrue(Runtime.getRuntime().removeShutdownHook(shutdownHook));
250 
251     shutdownHook.run();
252     verify(m_logger).info("done");
253 
254     shutdownHook.run();
255     verifyNoMoreInteractions(m_logger);
256   }
257 }