blob: 5763e5eebdb644ac1137fa39fcaa25d08a0515ef [file] [log] [blame]
chrismair00dc7bd2014-05-11 21:21:28 +00001/*
2 * Copyright 2007 the original author or authors.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.mockftpserver.core.session;
17
18import org.slf4j.Logger;
19import org.slf4j.LoggerFactory;
20import org.mockftpserver.core.MockFtpServerException;
21import org.mockftpserver.core.command.Command;
22import org.mockftpserver.core.socket.StubServerSocket;
23import org.mockftpserver.core.socket.StubServerSocketFactory;
24import org.mockftpserver.core.socket.StubSocket;
25import org.mockftpserver.core.socket.StubSocketFactory;
26import org.mockftpserver.core.util.AssertFailedException;
27import org.mockftpserver.test.AbstractTestCase;
28
29import java.io.ByteArrayInputStream;
30import java.io.ByteArrayOutputStream;
31import java.io.IOException;
32import java.io.InputStream;
33import java.net.InetAddress;
34import java.net.SocketTimeoutException;
35import java.util.Collections;
36import java.util.HashMap;
37import java.util.Map;
38
39/**
40 * Tests for the DefaultSession class
41 *
42 * @version $Revision$ - $Date$
43 *
44 * @author Chris Mair
45 */
46public final class DefaultSessionTest extends AbstractTestCase {
47
48 private static final Logger LOG = LoggerFactory.getLogger(DefaultSessionTest.class);
49 private static final String DATA = "sample data 123";
50 private static final int PORT = 197;
51 private static final String NAME1 = "name1";
52 private static final String NAME2 = "name2";
53 private static final Object VALUE = "value";
54
55 private DefaultSession session;
56 private ByteArrayOutputStream outputStream;
57 private Map commandHandlerMap;
58 private StubSocket stubSocket;
59 private InetAddress clientHost;
60
61 /**
62 * Perform initialization before each test
63 *
64 * @see org.mockftpserver.test.AbstractTestCase#setUp()
65 */
66 protected void setUp() throws Exception {
67 super.setUp();
68
69 commandHandlerMap = new HashMap();
70 outputStream = new ByteArrayOutputStream();
71 session = createDefaultSession("");
72 clientHost = InetAddress.getLocalHost();
73 }
74
75 /**
76 * @see org.mockftpserver.test.AbstractTestCase#tearDown()
77 */
78 protected void tearDown() throws Exception {
79 super.tearDown();
80 }
81
82 /**
83 * Test the Constructor when the control socket is null
84 */
85 public void testConstructor_NullControlSocket() {
86 try {
87 new DefaultSession(null, commandHandlerMap);
88 fail("Expected AssertFailedException");
89 }
90 catch (AssertFailedException expected) {
91 LOG.info("Expected: " + expected);
92 }
93 }
94
95 /**
96 * Test the Constructor when the command handler Map is null
97 */
98 public void testConstructor_NullCommandHandlerMap() {
99 try {
100 new DefaultSession(stubSocket, null);
101 fail("Expected AssertFailedException");
102 }
103 catch (AssertFailedException expected) {
104 LOG.info("Expected: " + expected);
105 }
106 }
107
108 /**
109 * Test the setClientDataPort() method
110 */
111 public void testSetClientDataPort() {
112 StubSocket stubSocket = createTestSocket("");
113 StubSocketFactory stubSocketFactory = new StubSocketFactory(stubSocket);
114 session.socketFactory = stubSocketFactory;
115 session.setClientDataPort(PORT);
116 session.setClientDataHost(clientHost);
117 session.openDataConnection();
118 assertEquals("data port", PORT, stubSocketFactory.requestedDataPort);
119 }
120
121 /**
122 * Test the setClientDataPort() method after the session was in passive data mode
123 */
124 public void testSetClientDataPort_AfterPassiveConnectionMode() throws IOException {
125 StubServerSocket stubServerSocket = new StubServerSocket(PORT);
126 StubServerSocketFactory stubServerSocketFactory = new StubServerSocketFactory(stubServerSocket);
127 session.serverSocketFactory = stubServerSocketFactory;
128
129 session.switchToPassiveMode();
130 assertFalse("server socket closed", stubServerSocket.isClosed());
131 assertNotNull("passiveModeDataSocket", session.passiveModeDataSocket);
132 session.setClientDataPort(PORT);
133
134 // Make sure that any passive mode connection info is cleared out
135 assertTrue("server socket closed", stubServerSocket.isClosed());
136 assertNull("passiveModeDataSocket should be null", session.passiveModeDataSocket);
137 }
138
139 /**
140 * Test the setClientHost() method
141 */
142 public void testSetClientHost() throws Exception {
143 StubSocket stubSocket = createTestSocket("");
144 StubSocketFactory stubSocketFactory = new StubSocketFactory(stubSocket);
145 session.socketFactory = stubSocketFactory;
146 session.setClientDataHost(clientHost);
147 session.openDataConnection();
148 assertEquals("client host", clientHost, stubSocketFactory.requestedHost);
149 }
150
151 /**
152 * Test the openDataConnection(), setClientDataPort() and setClientDataHost() methods
153 */
154 public void testOpenDataConnection() {
155 StubSocket stubSocket = createTestSocket("");
156 StubSocketFactory stubSocketFactory = new StubSocketFactory(stubSocket);
157 session.socketFactory = stubSocketFactory;
158
159 // Use default client data port
160 session.setClientDataHost(clientHost);
161 session.openDataConnection();
162 assertEquals("data port", DefaultSession.DEFAULT_CLIENT_DATA_PORT, stubSocketFactory.requestedDataPort);
163 assertEquals("client host", clientHost, stubSocketFactory.requestedHost);
164
165 // Set client data port explicitly
166 session.setClientDataPort(PORT);
167 session.setClientDataHost(clientHost);
168 session.openDataConnection();
169 assertEquals("data port", PORT, stubSocketFactory.requestedDataPort);
170 assertEquals("client host", clientHost, stubSocketFactory.requestedHost);
171 }
172
173 /**
174 * Test the OpenDataConnection method, when in passive mode and no incoming connection is
175 * initiated
176 */
177 public void testOpenDataConnection_PassiveMode_NoConnection() throws IOException {
178
179 StubServerSocket stubServerSocket = new StubServerSocket(PORT);
180 StubServerSocketFactory stubServerSocketFactory = new StubServerSocketFactory(stubServerSocket);
181 session.serverSocketFactory = stubServerSocketFactory;
182
183 session.switchToPassiveMode();
184
185 try {
186 session.openDataConnection();
187 fail("Expected MockFtpServerException");
188 }
189 catch (MockFtpServerException expected) {
190 LOG.info("Expected: " + expected);
191 assertSame("cause", SocketTimeoutException.class, expected.getCause().getClass());
192 }
193 }
194
195 /**
196 * Test the OpenDataConnection method, when the clientHost has not been set
197 */
198 public void testOpenDataConnection_NullClientHost() {
199 try {
200 session.openDataConnection();
201 fail("Expected AssertFailedException");
202 }
203 catch (AssertFailedException expected) {
204 LOG.info("Expected: " + expected);
205 }
206 }
207
208 /**
209 * Test the readData() method
210 */
211 public void testReadData() {
212 StubSocket stubSocket = createTestSocket(DATA);
213 session.socketFactory = new StubSocketFactory(stubSocket);
214 session.setClientDataHost(clientHost);
215
216 session.openDataConnection();
217 byte[] data = session.readData();
218 LOG.info("data=[" + new String(data) + "]");
219 assertEquals("data", DATA.getBytes(), data);
220 }
221
222 /**
223 * Test the readData() method after switching to passive mode
224 */
225 public void testReadData_PassiveMode() throws IOException {
226 StubSocket stubSocket = createTestSocket(DATA);
227 StubServerSocket stubServerSocket = new StubServerSocket(PORT, stubSocket);
228 StubServerSocketFactory stubServerSocketFactory = new StubServerSocketFactory(stubServerSocket);
229 session.serverSocketFactory = stubServerSocketFactory;
230
231 session.switchToPassiveMode();
232 session.openDataConnection();
233 byte[] data = session.readData();
234 LOG.info("data=[" + new String(data) + "]");
235 assertEquals("data", DATA.getBytes(), data);
236 }
237
238 /**
239 * Test the readData(int) method
240 */
241 public void testReadData_NumBytes() {
242 final int NUM_BYTES = 5;
243 final String EXPECTED_DATA = DATA.substring(0, NUM_BYTES);
244 StubSocket stubSocket = createTestSocket(DATA);
245 session.socketFactory = new StubSocketFactory(stubSocket);
246 session.setClientDataHost(clientHost);
247
248 session.openDataConnection();
249 byte[] data = session.readData(NUM_BYTES);
250 LOG.info("data=[" + new String(data) + "]");
251 assertEquals("data", EXPECTED_DATA.getBytes(), data);
252 }
253
254 public void testReadData_NumBytes_AskForMoreBytesThanThereAre() {
255 StubSocket stubSocket = createTestSocket(DATA);
256 session.socketFactory = new StubSocketFactory(stubSocket);
257 session.setClientDataHost(clientHost);
258
259 session.openDataConnection();
260 byte[] data = session.readData(10000);
261 LOG.info("data=[" + new String(data) + "]");
262 assertEquals("data", DATA.getBytes(), data);
263 }
264
265 /**
266 * Test the closeDataConnection() method
267 */
268 public void testCloseDataConnection() {
269 StubSocket stubSocket = createTestSocket(DATA);
270 session.socketFactory = new StubSocketFactory(stubSocket);
271
272 session.setClientDataHost(clientHost);
273 session.openDataConnection();
274 session.closeDataConnection();
275 assertTrue("client data socket should be closed", stubSocket.isClosed());
276 }
277
278 /**
279 * Test the switchToPassiveMode() method
280 */
281 public void testSwitchToPassiveMode() throws IOException {
282 StubServerSocket stubServerSocket = new StubServerSocket(PORT);
283 StubServerSocketFactory stubServerSocketFactory = new StubServerSocketFactory(stubServerSocket);
284 session.serverSocketFactory = stubServerSocketFactory;
285
286 assertNull("passiveModeDataSocket starts out null", session.passiveModeDataSocket);
287 int port = session.switchToPassiveMode();
288 assertSame("passiveModeDataSocket", stubServerSocket, session.passiveModeDataSocket);
289 assertEquals("port", PORT, port);
290 }
291
292 /**
293 * Test the getServerHost() method
294 */
295 public void testGetServerHost() {
296 assertEquals("host", DEFAULT_HOST, session.getServerHost());
297 }
298
299 /**
300 * Test the getClientHost() method when the session is not yet started
301 */
302 public void testGetClientHost_NotRunning() {
303 assertNull("null", session.getClientHost());
304 }
305
306 /**
307 * Test the parseCommand() method
308 */
309 public void testParseCommand() {
310 Command command = session.parseCommand("LIST");
311 assertEquals("command name", "LIST", command.getName());
312 assertEquals("command parameters", EMPTY, command.getParameters());
313
314 command = session.parseCommand("USER user123");
315 assertEquals("command name", "USER", command.getName());
316 assertEquals("command parameters", array("user123"), command.getParameters());
317
318 command = session.parseCommand("PORT 127,0,0,1,17,37");
319 assertEquals("command name", "PORT", command.getName());
320 assertEquals("command parameters", new String[] { "127", "0", "0", "1", "17", "37" }, command
321 .getParameters());
322 }
323
324 /**
325 * Test the parseCommand() method, passing in an empty command String
326 */
327 public void testParseCommand_EmptyCommandString() {
328 try {
329 session.parseCommand("");
330 fail("Expected AssertFailedException");
331 }
332 catch (AssertFailedException expected) {
333 LOG.info("Expected: " + expected);
334 }
335 }
336
337 /**
338 * Test the sendData() method, as well as the openDataConnection() and closeDataConnection()
339 */
340 public void testSendData() {
341 StubSocket stubSocket = createTestSocket("1234567890 abcdef");
342 session.socketFactory = new StubSocketFactory(stubSocket);
343
344 session.setClientDataHost(clientHost);
345 session.openDataConnection();
346 session.sendData(DATA.getBytes(), DATA.length());
347 LOG.info("output=[" + outputStream.toString() + "]");
348 assertEquals("output", DATA, outputStream.toString());
349 }
350
351 /**
352 * Test the SendData() method, passing in a null byte[]
353 */
354 public void testSendData_Null() {
355
356 try {
357 session.sendData(null, 1);
358 fail("Expected AssertFailedException");
359 }
360 catch (AssertFailedException expected) {
361 LOG.info("Expected: " + expected);
362 }
363 }
364
365 /**
366 * Test the SendReply(int,String) method, passing in an invalid reply code
367 */
368 public void testSendReply_InvalidReplyCode() {
369
370 try {
371 session.sendReply(-66, "text");
372 fail("Expected AssertFailedException");
373 }
374 catch (AssertFailedException expected) {
375 LOG.info("Expected: " + expected);
376 }
377 }
378
379 /**
380 * Test the getAttribute() and setAttribute() methods
381 */
382 public void testGetAndSetAttribute() {
383 assertNull("name does not exist yet", session.getAttribute(NAME1));
384 session.setAttribute(NAME1, VALUE);
385 session.setAttribute(NAME2, null);
386 assertEquals("NAME1", VALUE, session.getAttribute(NAME1));
387 assertNull("NAME2", session.getAttribute(NAME2));
388 assertNull("no such name", session.getAttribute("noSuchName"));
389 }
390
391 /**
392 * Test the getAttribute() method, passing in a null name
393 */
394 public void testGetAttribute_Null() {
395 try {
396 session.getAttribute(null);
397 fail("Expected AssertFailedException");
398 }
399 catch (AssertFailedException expected) {
400 LOG.info("Expected: " + expected);
401 }
402 }
403
404 /**
405 * Test the setAttribute() method, passing in a null name
406 */
407 public void testSetAttribute_NullName() {
408 try {
409 session.setAttribute(null, VALUE);
410 fail("Expected AssertFailedException");
411 }
412 catch (AssertFailedException expected) {
413 LOG.info("Expected: " + expected);
414 }
415 }
416
417 /**
418 * Test the removeAttribute()
419 */
420 public void testRemoveAttribute() {
421 session.removeAttribute("noSuchName"); // do nothing
422 session.setAttribute(NAME1, VALUE);
423 session.removeAttribute(NAME1);
424 assertNull("NAME1", session.getAttribute(NAME1));
425 }
426
427 /**
428 * Test the removeAttribute() method, passing in a null name
429 */
430 public void testRemoveAttribute_Null() {
431 try {
432 session.removeAttribute(null);
433 fail("Expected AssertFailedException");
434 }
435 catch (AssertFailedException expected) {
436 LOG.info("Expected: " + expected);
437 }
438 }
439
440 /**
441 * Test the getAttributeNames()
442 */
443 public void testGetAttributeNames() {
444 assertEquals("No names yet", Collections.EMPTY_SET, session.getAttributeNames());
445 session.setAttribute(NAME1, VALUE);
446 assertEquals("1", Collections.singleton(NAME1), session.getAttributeNames());
447 session.setAttribute(NAME2, VALUE);
448 assertEquals("2", set(NAME1, NAME2), session.getAttributeNames());
449 }
450
451 // -------------------------------------------------------------------------
452 // Internal Helper Methods
453 // -------------------------------------------------------------------------
454
455 /**
456 * Create and return a DefaultSession object that reads from an InputStream with the specified
457 * contents and writes to the predefined outputStrean ByteArrayOutputStream. Also, save the
458 * StubSocket being used in the stubSocket attribute.
459 *
460 * @param inputStreamContents - the contents of the input stream
461 * @return the DefaultSession
462 */
463 private DefaultSession createDefaultSession(String inputStreamContents) {
464 stubSocket = createTestSocket(inputStreamContents);
465 return new DefaultSession(stubSocket, commandHandlerMap);
466 }
467
468 /**
469 * Create and return a StubSocket that reads from an InputStream with the specified contents and
470 * writes to the predefined outputStrean ByteArrayOutputStream.
471 *
472 * @param inputStreamContents - the contents of the input stream
473 * @return the StubSocket
474 */
475 private StubSocket createTestSocket(String inputStreamContents) {
476 InputStream inputStream = new ByteArrayInputStream(inputStreamContents.getBytes());
477 StubSocket stubSocket = new StubSocket(inputStream, outputStream);
478 stubSocket._setLocalAddress(DEFAULT_HOST);
479 return stubSocket;
480 }
481
482}