1/*
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.test;
17
18import java.io.File;
19import java.net.InetAddress;
20import java.net.UnknownHostException;
21import java.util.ArrayList;
22import java.util.Arrays;
23import java.util.Collections;
24import java.util.HashMap;
25import java.util.HashSet;
26import java.util.Iterator;
27import java.util.List;
28import java.util.Map;
29import java.util.Set;
30
31import junit.framework.TestCase;
32
33import org.apache.log4j.Logger;
34import org.easymock.MockControl;
35import org.mockftpserver.core.MockFtpServerException;
36import org.mockftpserver.core.util.Assert;
37import org.mockftpserver.core.util.AssertFailedException;
38
39/**
40 * Abstract superclass for all project test classes
41 *
42 * @version $Revision$ - $Date$
43 *
44 * @author Chris Mair
45 */
46public abstract class AbstractTest extends TestCase {
47
48    private static final Logger LOG = Logger.getLogger(AbstractTest.class);
49    protected static final List EMPTY_LIST = Collections.EMPTY_LIST;
50    protected static final String[] EMPTY = new String[0];
51    protected static final InetAddress DEFAULT_HOST = inetAddress(null);
52
53    /**
54     * Constructor
55     */
56    public AbstractTest() {
57        super();
58    }
59
60    //-------------------------------------------------------------------------
61    // Manage EasyMock Control objects under the covers, and provide a syntax
62    // somewhat similar to EasyMock 2.2 for createMock, verify and replay.
63    //-------------------------------------------------------------------------
64
65    private Map mocks = new HashMap();
66
67    /**
68     * Create a new mock for the specified interface. Keep track of the associated control object
69     * under the covers to support the associated  method.
70     * @param interfaceToMock - the Class of the interface to be mocked
71     * @return the new mock
72     */
73    protected Object createMock(Class interfaceToMock) {
74        MockControl control = MockControl.createControl(interfaceToMock);
75        Object mock = control.getMock();
76        mocks.put(mock, control);
77        return mock;
78    }
79
80    /**
81     * Put the mock object into replay mode
82     * @param mock - the mock to set in replay mode
83     * @throws AssertFailedException - if mock is null
84     * @throws AssertFailedException - if mock is not a mock object created using {@link #createMock(Class)}
85     */
86    protected void replay(Object mock) {
87        control(mock).replay();
88    }
89
90    /**
91     * Put all mocks created with createMock() into replay mode.
92     */
93    protected void replayAll() {
94        for (Iterator iter = mocks.keySet().iterator(); iter.hasNext();) {
95            Object mock = iter.next();
96            replay(mock);
97        }
98    }
99    /**
100     * Verify the mock object
101     * @param mock - the mock to verify
102     * @throws AssertFailedException - if mock is null
103     * @throws AssertFailedException - if mock is not a mock object created using {@link #createMock(Class)}
104     */
105    protected void verify(Object mock) {
106        control(mock).verify();
107    }
108
109    /**
110     * Verify all mocks created with createMock() into replay mode.
111     */
112    protected void verifyAll() {
113        for (Iterator iter = mocks.keySet().iterator(); iter.hasNext();) {
114            Object mock = iter.next();
115            verify(mock);
116        }
117    }
118
119    /**
120     * Return the mock control associated with the mock
121     * @param mock - the mock
122     * @return the associated MockControl
123     * @throws AssertFailedException - if mock is null
124     * @throws AssertFailedException - if mock is not a mock object created using {@link #createMock(Class)}
125     */
126    protected MockControl control(Object mock) {
127        Assert.notNull(mock, "mock");
128        MockControl control = (MockControl) mocks.get(mock);
129        Assert.notNull(control, "control");
130        return control;
131    }
132
133    //-------------------------------------------------------------------------
134    // Other Helper Methods
135    //-------------------------------------------------------------------------
136
137    /**
138     * Assert that the two objects are not equal
139     * @param object1 - the first object
140     * @param object2 - the second object
141     */
142    protected void assertNotEquals(String message, Object object1, Object object2) {
143        assertFalse(message, object1.equals(object2));
144    }
145
146    /**
147     * Assert that the two byte arrays have the same length and content
148     * @param array1 - the first array
149     * @param array2 - the second array
150     */
151    protected void assertEquals(String message, byte[] array1, byte[] array2) {
152        assertTrue("Arrays not equal: " + message, Arrays.equals(array1, array2));
153    }
154
155    /**
156     * Assert that the two Object arrays have the same length and content
157     * @param array1 - the first array
158     * @param array2 - the second array
159     */
160    protected void assertEquals(String message, Object[] array1, Object[] array2) {
161        assertTrue("Arrays not equal: " + message, Arrays.equals(array1, array2));
162    }
163
164    /**
165     * Create and return a one-element Object[] containing the specified Object
166     * @param o - the object
167     * @return the Object array, of length 1, containing o
168     */
169    protected static Object[] objArray(Object o) {
170        return new Object[] { o };
171    }
172
173    /**
174     * Create and return a one-element String[] containing the specified String
175     * @param s - the String
176     * @return the String array, of length 1, containing s
177     */
178    protected static String[] array(String s) {
179        return new String[] { s };
180    }
181
182    /**
183     * Create and return a two-element String[] containing the specified Strings
184     * @param s1 - the first String
185     * @param s2 - the second String
186     * @return the String array, of length 2, containing s1 and s2
187     */
188    protected static String[] array(String s1, String s2) {
189        return new String[] { s1, s2 };
190    }
191
192    /**
193     * Create a new InetAddress from the specified host String, using the
194     * {@link InetAddress#getByName(String)} method, wrapping any checked
195     * exception within a unchecked MockFtpServerException.
196     * @param host
197     * @return an InetAddress for the specified host
198     *
199     * @throws MockFtpServerException - if an UnknownHostException is thrown
200     */
201    protected static InetAddress inetAddress(String host) {
202        try {
203            return InetAddress.getByName(host);
204        }
205        catch (UnknownHostException e) {
206            throw new MockFtpServerException(e);
207        }
208    }
209
210    /**
211     * Create and return a List containing the Objects passed as arguments to this method
212     * @param e1- the first element to add
213     * @param e2- the second element to add
214     * @return the List containing the specified elements
215     */
216    protected static List list(Object e1, Object e2) {
217        List list = new ArrayList();
218        list.add(e1);
219        list.add(e2);
220        return list;
221    }
222
223    /**
224     * Create and return a List containing the single Object passed as an argument to this method
225     * @param element- the element to add
226     * @return the List containing the specified element
227     */
228    protected static List list(Object element) {
229        return Collections.singletonList(element);
230    }
231
232    /**
233     * Create and return a Set containing the Objects passed as arguments to this method
234     * @param e1 - the first element to add
235     * @param e2 - the second element to add
236     * @return the Set containing the specified elements
237     */
238    protected static Set set(Object e1, Object e2) {
239        Set set = new HashSet();
240        set.add(e1);
241        set.add(e2);
242        return set;
243    }
244
245    /**
246     * Create and return a Set containing the Objects passed as arguments to this method
247     * @param e1 - the first element to add
248     * @param e2 - the second element to add
249     * @param e3 - the third element to add
250     * @return the Set containing the specified elements
251     */
252    protected static Set set(Object e1, Object e2, Object e3) {
253        Set set = set(e1, e2);
254        set.add(e3);
255        return set;
256    }
257
258    /**
259     * Override the default test run behavior to write out the current test name
260     * and handle Errors and Exceptions in a standard way.
261     *
262     * @see junit.framework.TestCase#runBare()
263     */
264    public void runBare() throws Throwable {
265
266        LoggingUtil loggingUtil = null;
267        try {
268            loggingUtil = LoggingUtil.getTestCaseLogger(this);
269            loggingUtil.logStartOfTest();
270            super.runBare();
271        }
272        catch (Exception e) {
273            handleException(e);
274        }
275        catch (Error e) {
276            handleError(e);
277        }
278        finally {
279            if (loggingUtil != null) {
280                loggingUtil.logEndOfTest();
281            }
282        }
283    }
284
285    /**
286     * Setup before each test.
287     */
288    protected void setUp() throws Exception {
289        super.setUp();
290    }
291
292    /**
293     * Cleanup after each test.
294     */
295    protected void tearDown() throws Exception {
296        super.tearDown();
297    }
298
299    //-----------------------------------------------------------
300    // Private Internal Methods
301    //-----------------------------------------------------------
302
303    /**
304     * Handle an exception
305     * @param e the Exception
306     * @throws Exception
307     */
308    private void handleException(Exception e) throws Exception {
309
310        LOG.error("EXCEPTION: ", e);
311        throw e;
312    }
313
314    /**
315     * Handle an Error
316     * @param e the Error
317     * @throws Exception
318     */
319    private void handleError(Error e) throws Exception {
320        LOG.error("ERROR: ", e);
321        throw e;
322    }
323
324    //-------------------------------------------------------------------------
325    // Helper methods
326    //-------------------------------------------------------------------------
327
328    /**
329     * Delete the named file if it exists
330     *
331     * @param filename - the full pathname of the file
332     */
333    protected void deleteFile(String filename) {
334        File keyFile = new File(filename);
335        boolean deleted = keyFile.delete();
336        LOG.info("Deleted [" + filename + "]: " + deleted);
337    }
338
339
340
341    //-------------------------------------------------------------------------
342    // Common validation helper methods
343    //-------------------------------------------------------------------------
344
345    /**
346     * Verify that the named file exists
347     *
348     * @param filename - the full pathname of the file
349     */
350    protected void verifyFileExists(String filename) {
351        File keyFile = new File(filename);
352        assertTrue("File does not exist [" + filename + "]", keyFile.exists());
353    }
354
355}
356