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 byte arrays have the same length and content
139     * @param array1 - the first array
140     * @param array2 - the second array
141     */
142    protected void assertEquals(String message, byte[] array1, byte[] array2) {
143        assertTrue("Arrays not equal: " + message, Arrays.equals(array1, array2));
144    }
145
146    /**
147     * Assert that the two Object 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, Object[] array1, Object[] array2) {
152        assertTrue("Arrays not equal: " + message, Arrays.equals(array1, array2));
153    }
154
155    /**
156     * Create and return a one-element Object[] containing the specified Object
157     * @param o - the object
158     * @return the Object array, of length 1, containing o
159     */
160    protected static Object[] objArray(Object o) {
161        return new Object[] { o };
162    }
163
164    /**
165     * Create and return a one-element String[] containing the specified String
166     * @param s - the String
167     * @return the String array, of length 1, containing s
168     */
169    protected static String[] array(String s) {
170        return new String[] { s };
171    }
172
173    /**
174     * Create and return a two-element String[] containing the specified Strings
175     * @param s1 - the first String
176     * @param s2 - the second String
177     * @return the String array, of length 2, containing s1 and s2
178     */
179    protected static String[] array(String s1, String s2) {
180        return new String[] { s1, s2 };
181    }
182
183    /**
184     * Create a new InetAddress from the specified host String, using the
185     * {@link InetAddress#getByName(String)} method, wrapping any checked
186     * exception within a unchecked MockFtpServerException.
187     * @param host
188     * @return an InetAddress for the specified host
189     *
190     * @throws MockFtpServerException - if an UnknownHostException is thrown
191     */
192    protected static InetAddress inetAddress(String host) {
193        try {
194            return InetAddress.getByName(host);
195        }
196        catch (UnknownHostException e) {
197            throw new MockFtpServerException(e);
198        }
199    }
200
201    /**
202     * Create and return a List containing the Objects passed as arguments to this method
203     * @param e1- the first element to add
204     * @param e1- the second element to add
205     * @return the List containing the specified elements
206     */
207    protected static List list(Object e1, Object e2) {
208        List list = new ArrayList();
209        list.add(e1);
210        list.add(e2);
211        return list;
212    }
213
214    /**
215     * Create and return a Set containing the Objects passed as arguments to this method
216     * @param e1- the first element to add
217     * @param e1- the second element to add
218     * @return the Set containing the specified elements
219     */
220    protected static Set set(Object e1, Object e2) {
221        Set set = new HashSet();
222        set.add(e1);
223        set.add(e2);
224        return set;
225    }
226
227    /**
228     * Override the default test run behavior to write out the current test name
229     * and handle Errors and Exceptions in a standard way.
230     *
231     * @see junit.framework.TestCase#runBare()
232     */
233    public void runBare() throws Throwable {
234
235        LoggingUtil loggingUtil = null;
236        try {
237            loggingUtil = LoggingUtil.getTestCaseLogger(this);
238            loggingUtil.logStartOfTest();
239            super.runBare();
240        }
241        catch (Exception e) {
242            handleException(e);
243        }
244        catch (Error e) {
245            handleError(e);
246        }
247        finally {
248            if (loggingUtil != null) {
249                loggingUtil.logEndOfTest();
250            }
251        }
252    }
253
254    /**
255     * Setup before each test.
256     */
257    protected void setUp() throws Exception {
258        super.setUp();
259    }
260
261    /**
262     * Cleanup after each test.
263     */
264    protected void tearDown() throws Exception {
265        super.tearDown();
266    }
267
268    //-----------------------------------------------------------
269    // Private Internal Methods
270    //-----------------------------------------------------------
271
272    /**
273     * Handle an exception
274     * @param e the Exception
275     * @throws Exception
276     */
277    private void handleException(Exception e) throws Exception {
278
279        LOG.error("EXCEPTION: ", e);
280        throw e;
281    }
282
283    /**
284     * Handle an Error
285     * @param e the Error
286     * @throws Exception
287     */
288    private void handleError(Error e) throws Exception {
289        LOG.error("ERROR: ", e);
290        throw e;
291    }
292
293    //-------------------------------------------------------------------------
294    // Helper methods
295    //-------------------------------------------------------------------------
296
297    /**
298     * Delete the named file if it exists
299     *
300     * @param filename - the full pathname of the file
301     */
302    protected void deleteFile(String filename) {
303        File keyFile = new File(filename);
304        boolean deleted = keyFile.delete();
305        LOG.info("Deleted [" + filename + "]: " + deleted);
306    }
307
308
309
310    //-------------------------------------------------------------------------
311    // Common validation helper methods
312    //-------------------------------------------------------------------------
313
314    /**
315     * Verify that the named file exists
316     *
317     * @param filename - the full pathname of the file
318     */
319    protected void verifyFileExists(String filename) {
320        File keyFile = new File(filename);
321        assertTrue("File does not exist [" + filename + "]", keyFile.exists());
322    }
323
324}
325