View Javadoc

1   // Copyright (C) 2011 - 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;
23  
24  import static net.grinder.testutility.AssertUtilities.assertContains;
25  import static net.grinder.testutility.AssertUtilities.assertContainsPattern;
26  import static net.grinder.testutility.MockingUtilities.containsRegex;
27  import static net.grinder.testutility.SocketUtilities.findFreePort;
28  import static org.junit.Assert.assertEquals;
29  import static org.junit.Assert.assertNotNull;
30  import static org.junit.Assert.assertNull;
31  import static org.junit.Assert.fail;
32  import static org.mockito.Matchers.contains;
33  import static org.mockito.Mockito.times;
34  import static org.mockito.Mockito.verify;
35  
36  import java.io.File;
37  import java.io.FileWriter;
38  import java.io.Writer;
39  import java.util.Properties;
40  
41  import net.grinder.common.GrinderException;
42  import net.grinder.plugin.http.tcpproxyfilter.HTTPRequestFilter;
43  import net.grinder.plugin.http.tcpproxyfilter.HTTPResponseFilter;
44  import net.grinder.testutility.TemporaryDirectory;
45  import net.grinder.tools.tcpproxy.EchoFilter;
46  import net.grinder.tools.tcpproxy.NullFilter;
47  import net.grinder.tools.tcpproxy.UpdatableCommentSource;
48  
49  import org.junit.Before;
50  import org.junit.Test;
51  import org.mockito.ArgumentCaptor;
52  import org.mockito.Captor;
53  import org.mockito.Mock;
54  import org.mockito.MockitoAnnotations;
55  import org.picocontainer.PicoContainer;
56  import org.slf4j.Logger;
57  
58  
59  
60  /**
61   * Unit tests for {@link TestTCPProxy}.
62   *
63   * @author Philip Aston
64   */
65  public class TestTCPProxy {
66  
67    @Mock private Logger m_logger;
68    @Captor private ArgumentCaptor<String> m_stringCaptor;
69  
70    @Before public void setUp() {
71      MockitoAnnotations.initMocks(this);
72    }
73  
74    @Test public void testDefaultOptions() throws Exception {
75  
76      final TCPProxy tcpProxy = new TCPProxy(new String[0], m_logger);
77  
78      verify(m_logger, times(2)).info(m_stringCaptor.capture());
79      final String message = m_stringCaptor.getAllValues().get(0);
80  
81      assertContains(message, "HTTP/HTTPS proxy");
82      assertContainsPattern(message, "Request filters:\\s+EchoFilter\\s*\n");
83      assertContainsPattern(message, "Response filters:\\s+EchoFilter\\s*\n");
84  
85      assertContains(m_stringCaptor.getValue(), "listening on port 8001");
86  
87      final PicoContainer filterContainer = tcpProxy.getFilterContainer();
88  
89      assertNotNull(filterContainer.getComponent(UpdatableCommentSource.class));
90      assertNotNull(filterContainer.getComponent(Logger.class));
91      assertEquals(2, filterContainer.getComponents(EchoFilter.class).size());
92      assertEquals(5, filterContainer.getComponents().size());
93    }
94  
95    @Test public void testHTTP() throws Exception {
96  
97      final int port = findFreePort();
98  
99      final String[] arguments = { "-http",
100                                  "-localPort",
101                                  Integer.toString(port) };
102 
103     final TCPProxy tcpProxy = new TCPProxy(arguments, m_logger);
104 
105     verify(m_logger, times(2)).info(m_stringCaptor.capture());
106     final String message = m_stringCaptor.getAllValues().get(0);
107 
108     assertContains(message, "HTTP/HTTPS proxy");
109     assertContainsPattern(message,
110                           "Request filters:\\s+HTTPRequestFilter\\s*\n");
111     assertContainsPattern(message,
112                           "Response filters:\\s+HTTPResponseFilter\\s*\n");
113 
114     assertContains(m_stringCaptor.getValue(), "listening on port " + port);
115 
116     final PicoContainer filterContainer = tcpProxy.getFilterContainer();
117 
118     assertNotNull(filterContainer.getComponent(UpdatableCommentSource.class));
119     assertNotNull(filterContainer.getComponent(Logger.class));
120     assertNotNull(filterContainer.getComponent(HTTPRequestFilter.class));
121     assertNotNull(filterContainer.getComponent(HTTPResponseFilter.class));
122   }
123 
124   @Test public void testInvalidFilter() throws Exception {
125     final String[] arguments = { "-responsefilter", "XXX" };
126 
127     try {
128       new TCPProxy(arguments, m_logger);
129       fail("Expected exception");
130     }
131     catch (Exception e) {
132     }
133 
134     verify(m_logger).error(contains("'XXX' not found"));
135   }
136 
137   @Test public void testInvalidFilter2() throws Exception {
138     final String[] arguments = { "-requestfilter", "java.lang.Object" };
139 
140     try {
141       new TCPProxy(arguments, m_logger);
142       fail("Expected exception");
143     }
144     catch (Exception e) {
145     }
146 
147     verify(m_logger).error(contains("does not implement"));
148   }
149 
150   public static class TestFilter extends NullFilter {}
151 
152   @Test public void testCustomFilter() throws Exception {
153     final String[] arguments = { "-localPort",
154                                  Integer.toString(findFreePort()),
155                                  "-requestFilter",
156                                  TestFilter.class.getName() };
157 
158     final TCPProxy tcpProxy = new TCPProxy(arguments, m_logger);
159     assertNotNull(tcpProxy.getFilterContainer().getComponent(TestFilter.class));
160 
161     verify(m_logger).info(containsRegex("Request filters:\\s+TestFilter\\s*\n"));
162   }
163 
164   @Test public void testNoneFilter() throws Exception {
165 
166     final String[] arguments = { "-localPort",
167                                  Integer.toString(findFreePort()),
168                                  "-responseFilter",
169                                  "NONE" };
170 
171     final TCPProxy tcpProxy = new TCPProxy(arguments, m_logger);
172     assertNotNull(tcpProxy.getFilterContainer().getComponent(NullFilter.class));
173 
174     verify(m_logger)
175       .info(containsRegex("Response filters:\\s+NullFilter\\s*\n"));
176   }
177 
178   @Test public void testEchoFilter() throws Exception {
179 
180     final String[] arguments = { "-localPort",
181                                  Integer.toString(findFreePort()),
182                                  "-requestFilter",
183                                  "ECHO" };
184 
185     final TCPProxy tcpProxy = new TCPProxy(arguments, m_logger);
186     final PicoContainer filterContainer = tcpProxy.getFilterContainer();
187     assertEquals(2, filterContainer.getComponents(EchoFilter.class).size());
188 
189     verify(m_logger)
190       .info(containsRegex("Request filters:\\s+EchoFilter\\s*\n"));
191   }
192 
193   @Test public void testChainedFilter() throws Exception {
194     final String[] arguments = { "-localPort",
195                                  Integer.toString(findFreePort()),
196                                  "-requestFilter",
197                                  TestFilter.class.getName(),
198                                  "-requestFilter",
199                                  "ECHO" };
200 
201     final TCPProxy tcpProxy = new TCPProxy(arguments, m_logger);
202     assertNotNull(tcpProxy.getFilterContainer().getComponent(TestFilter.class));
203 
204     verify(m_logger)
205       .info(containsRegex("Request filters:\\s+TestFilter" +
206                           "\\s*,\\s*EchoFilter" +
207                           "\\s*\n"));
208   }
209 
210   @Test public void testProperties() throws Exception {
211     final TemporaryDirectory directory = new TemporaryDirectory();
212 
213     Writer out = null;
214 
215     try {
216       assertNull(System.getProperty("myproperty"));
217 
218       final Properties properties = new Properties();
219       properties.setProperty("myproperty", "myvalue");
220 
221       final File propertiesFile = directory.newFile("properties");
222       out = new FileWriter(propertiesFile);
223       properties.store(out, "");
224 
225       final String[] arguments = { "-localPort",
226                                    Integer.toString(findFreePort()),
227                                    "-properties",
228                                    propertiesFile.getAbsolutePath() };
229 
230       new TCPProxy(arguments, m_logger);
231 
232       assertEquals("myvalue", System.getProperty("myproperty"));
233     }
234     finally {
235       if (out != null) {
236         out.close();
237       }
238 
239       directory.delete();
240       System.getProperties().remove("myproperty");
241     }
242   }
243 
244   @Test public void testBadOption() throws Exception {
245 
246     final String[] arguments = { "-http",
247                                  "-foobar" };
248 
249     try {
250       new TCPProxy(arguments, m_logger);
251       fail("Expected exception");
252     }
253     catch (GrinderException e) {
254     }
255 
256     verify(m_logger).error(contains("Usage"));
257   }
258 
259   @Test public void testBadOption2() throws Exception {
260 
261     final String[] arguments = { "-storetype" };
262 
263     try {
264       new TCPProxy(arguments, m_logger);
265       fail("Expected exception");
266     }
267     catch (GrinderException e) {
268     }
269 
270     verify(m_logger).error(contains("Usage"));
271   }
272 
273   @Test public void testBadOption3() throws Exception {
274 
275     final String[] arguments = { "-properties", "nonexistent" };
276 
277     try {
278       new TCPProxy(arguments, m_logger);
279       fail("Expected exception");
280     }
281     catch (GrinderException e) {
282     }
283 
284     verify(m_logger).error(contains("No such file or directory"));
285   }
286 
287   @Test public void testBadOption4() throws Exception {
288 
289     final String[] arguments = { "-timeout", "blah" };
290 
291     try {
292       new TCPProxy(arguments, m_logger);
293       fail("Expected exception");
294     }
295     catch (GrinderException e) {
296     }
297 
298     verify(m_logger).error(contains("Usage"));
299   }
300 
301   @Test public void testBadOption5() throws Exception {
302 
303     final String[] arguments = { "-timeout", "-10" };
304 
305     try {
306       new TCPProxy(arguments, m_logger);
307       fail("Expected exception");
308     }
309     catch (GrinderException e) {
310     }
311 
312     verify(m_logger).error(contains("must be non-negative"));
313   }
314 
315   @Test public void testPortForwardingArguments() throws Exception {
316 
317     final int port = findFreePort();
318 
319     final String[] arguments = { "-localHost", "localhost",
320                                  "-localPort", "" + port,
321                                  "-remoteHost", "r",
322                                  "-remotePort", "1234" };
323 
324     new TCPProxy(arguments, m_logger);
325 
326     verify(m_logger).info(containsRegex("Remote address:\\s+r:1234"));
327 
328     verify(m_logger).info(contains("listening on port " + port));
329   }
330 
331   @Test public void testBadComponent() throws Exception {
332 
333     final String[] arguments = { "-component",
334                                  "***abc" };
335 
336     try {
337       new TCPProxy(arguments, m_logger);
338       fail("Expected exception");
339     }
340     catch (GrinderException e) {
341     }
342 
343     verify(m_logger).error(contains("Class '***abc' not found"));
344   }
345 
346   public static class TestClass { }
347 
348   @Test public void testGoodComponent() throws Exception {
349 
350     final String[] arguments = { "-component",
351                                  TestClass.class.getName(),
352                                  "-localPort",
353                                  Integer.toString(findFreePort()),};
354 
355     final TCPProxy tcpProxy = new TCPProxy(arguments, m_logger);
356     assertNotNull(tcpProxy.getFilterContainer().getComponent(TestClass.class));
357   }
358 }