001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.camel.test;
018    
019    import java.io.File;
020    import java.util.Collection;
021    import java.util.List;
022    
023    import junit.framework.TestCase;
024    import org.apache.camel.CamelContext;
025    import org.apache.camel.Channel;
026    import org.apache.camel.Endpoint;
027    import org.apache.camel.Exchange;
028    import org.apache.camel.Expression;
029    import org.apache.camel.InvalidPayloadException;
030    import org.apache.camel.Message;
031    import org.apache.camel.Predicate;
032    import org.apache.camel.Processor;
033    import org.apache.camel.Route;
034    import org.apache.camel.builder.Builder;
035    import org.apache.camel.builder.RouteBuilder;
036    import org.apache.camel.builder.ValueBuilder;
037    import org.apache.camel.impl.DefaultCamelContext;
038    import org.apache.camel.impl.DefaultExchange;
039    import org.apache.camel.processor.DelegateProcessor;
040    import org.apache.camel.util.ExchangeHelper;
041    import org.apache.camel.util.PredicateAssertHelper;
042    import org.apache.commons.logging.Log;
043    import org.apache.commons.logging.LogFactory;
044    
045    /**
046     * A bunch of useful testing methods
047     *
048     * @version $Revision: 773199 $
049     */
050    public abstract class TestSupport extends TestCase {
051        private static final Log LOG = LogFactory.getLog(TestSupport.class);    
052        protected transient Log log = LogFactory.getLog(getClass());    
053        
054        // Builder methods for expressions used when testing
055        // -------------------------------------------------------------------------
056    
057        /**
058         * Returns a value builder for the given header
059         */
060        public static ValueBuilder header(String name) {
061            return Builder.header(name);
062        }
063    
064        /**
065         * Returns a value builder for the given property
066         */
067        public static ValueBuilder property(String name) {
068            return Builder.property(name);
069        }    
070        
071        /**
072         * Returns a predicate and value builder for the inbound body on an exchange
073         */
074        public static ValueBuilder body() {
075            return Builder.body();
076        }
077    
078        /**
079         * Returns a predicate and value builder for the inbound message body as a
080         * specific type
081         */
082        public static <T> ValueBuilder bodyAs(Class<T> type) {
083            return Builder.bodyAs(type);
084        }
085    
086        /**
087         * Returns a predicate and value builder for the outbound body on an
088         * exchange
089         */
090        public static ValueBuilder outBody() {
091            return Builder.outBody();
092        }
093    
094        /**
095         * Returns a predicate and value builder for the outbound message body as a
096         * specific type
097         */
098        public static <T> ValueBuilder outBodyAs(Class<T> type) {
099            return Builder.outBodyAs(type);
100        }
101    
102        /**
103         * Returns a predicate and value builder for the fault body on an
104         * exchange
105         */
106        public static ValueBuilder faultBody() {
107            return Builder.faultBody();
108        }
109    
110        /**
111         * Returns a predicate and value builder for the fault message body as a
112         * specific type
113         */
114        public static <T> ValueBuilder faultBodyAs(Class<T> type) {
115            return Builder.faultBodyAs(type);
116        }
117    
118        /**
119         * Returns a value builder for the given system property
120         */
121        public static ValueBuilder systemProperty(String name) {
122            return Builder.systemProperty(name);
123        }
124    
125        /**
126         * Returns a value builder for the given system property
127         */
128        public static ValueBuilder systemProperty(String name, String defaultValue) {
129            return Builder.systemProperty(name, defaultValue);
130        }
131    
132        // Assertions
133        // -----------------------------------------------------------------------
134    
135        public static <T> T assertIsInstanceOf(Class<T> expectedType, Object value) {
136            assertNotNull("Expected an instance of type: " + expectedType.getName() + " but was null", value);
137            assertTrue("object should be a " + expectedType.getName() + " but was: " + value + " with type: "
138                       + value.getClass().getName(), expectedType.isInstance(value));
139            return expectedType.cast(value);
140        }
141    
142        public static void assertEndpointUri(Endpoint endpoint, String uri) {
143            assertNotNull("Endpoint is null when expecting endpoint for: " + uri, endpoint);
144            assertEquals("Endoint uri for: " + endpoint, uri, endpoint.getEndpointUri());
145        }
146    
147        /**
148         * Asserts the In message on the exchange contains the expected value
149         */
150        public static Object assertInMessageHeader(Exchange exchange, String name, Object expected) {
151            return assertMessageHeader(exchange.getIn(), name, expected);
152        }
153    
154        /**
155         * Asserts the Out message on the exchange contains the expected value
156         */
157        public static Object assertOutMessageHeader(Exchange exchange, String name, Object expected) {
158            return assertMessageHeader(exchange.getOut(), name, expected);
159        }
160    
161        /**
162         * Asserts that the given exchange has an OUT message of the given body value
163         *
164         * @param exchange the exchange which should have an OUT message
165         * @param expected the expected value of the OUT message
166         * @throws InvalidPayloadException is thrown if the payload is not the expected class type
167         */
168        public static void assertInMessageBodyEquals(Exchange exchange, Object expected) throws InvalidPayloadException {
169            assertNotNull("Should have a response exchange!", exchange);
170    
171            Object actual;
172            if (expected == null) {
173                actual = ExchangeHelper.getMandatoryInBody(exchange);
174                assertEquals("in body of: " + exchange, expected, actual);
175            } else {
176                actual = ExchangeHelper.getMandatoryInBody(exchange, expected.getClass());
177            }
178            assertEquals("in body of: " + exchange, expected, actual);
179    
180            LOG.debug("Received response: " + exchange + " with in: " + exchange.getIn());
181        }
182    
183        /**
184         * Asserts that the given exchange has an OUT message of the given body value
185         *
186         * @param exchange the exchange which should have an OUT message
187         * @param expected the expected value of the OUT message
188         * @throws InvalidPayloadException is thrown if the payload is not the expected class type
189         */
190        public static void assertOutMessageBodyEquals(Exchange exchange, Object expected) throws InvalidPayloadException {
191            assertNotNull("Should have a response exchange!", exchange);
192    
193            Object actual;
194            if (expected == null) {
195                actual = ExchangeHelper.getMandatoryOutBody(exchange);
196                assertEquals("output body of: " + exchange, expected, actual);
197            } else {
198                actual = ExchangeHelper.getMandatoryOutBody(exchange, expected.getClass());
199            }
200            assertEquals("output body of: " + exchange, expected, actual);
201    
202            LOG.debug("Received response: " + exchange + " with out: " + exchange.getOut());
203        }
204    
205        public static Object assertMessageHeader(Message message, String name, Object expected) {
206            Object value = message.getHeader(name);
207            assertEquals("Header: " + name + " on Message: " + message, expected, value);
208            return value;
209        }
210    
211        /**
212         * Asserts that the given expression when evaluated returns the given answer
213         */
214        public static Object assertExpression(Expression expression, Exchange exchange, Object expected) {
215            Object value;
216            if (expected != null) {
217                value = expression.evaluate(exchange, expected.getClass());
218            } else {
219                value = expression.evaluate(exchange, Object.class);
220            }
221    
222            LOG.debug("Evaluated expression: " + expression + " on exchange: " + exchange + " result: " + value);
223    
224            assertEquals("Expression: " + expression + " on Exchange: " + exchange, expected, value);
225            return value;
226        }
227    
228        /**
229         * Asserts that the predicate returns the expected value on the exchange
230         */
231        public static void assertPredicateMatches(Predicate predicate, Exchange exchange) {
232            assertPredicate(predicate, exchange, true);
233        }
234    
235        /**
236         * Asserts that the predicate returns the expected value on the exchange
237         */
238        public static void assertPredicateDoesNotMatch(Predicate predicate, Exchange exchange) {
239            try {
240                PredicateAssertHelper.assertMatches(predicate, "Predicate should match: ", exchange);
241            } catch (AssertionError e) {
242                LOG.debug("Caught expected assertion error: " + e);
243            }
244            assertPredicate(predicate, exchange, false);
245        }
246    
247        /**
248         * Asserts that the predicate returns the expected value on the exchange
249         */
250        public static boolean assertPredicate(final Predicate predicate, Exchange exchange, boolean expected) {
251            if (expected) {
252                PredicateAssertHelper.assertMatches(predicate, "Predicate failed: ", exchange);
253            }
254            boolean value = predicate.matches(exchange);
255    
256            LOG.debug("Evaluated predicate: " + predicate + " on exchange: " + exchange + " result: " + value);
257    
258            assertEquals("Predicate: " + predicate + " on Exchange: " + exchange, expected, value);
259            return value;
260        }
261    
262        /**
263         * Resolves an endpoint and asserts that it is found
264         */
265        public static Endpoint resolveMandatoryEndpoint(CamelContext context, String uri) {
266            Endpoint endpoint = context.getEndpoint(uri);
267    
268            assertNotNull("No endpoint found for URI: " + uri, endpoint);
269    
270            return endpoint;
271        }
272    
273        /**
274         * Resolves an endpoint and asserts that it is found
275         */
276        public static <T extends Endpoint> T resolveMandatoryEndpoint(CamelContext context, String uri,
277                                                                  Class<T> endpointType) {
278            T endpoint = context.getEndpoint(uri, endpointType);
279    
280            assertNotNull("No endpoint found for URI: " + uri, endpoint);
281    
282            return endpoint;
283        }
284    
285        /**
286         * Creates an exchange with the given body
287         */
288        protected Exchange createExchangeWithBody(CamelContext camelContext, Object body) {
289            Exchange exchange = new DefaultExchange(camelContext);
290            Message message = exchange.getIn();
291            message.setHeader("testName", getName());
292            message.setHeader("testClass", getClass().getName());
293            message.setBody(body);
294            return exchange;
295        }
296    
297        public static <T> T assertOneElement(List<T> list) {
298            assertEquals("Size of list should be 1: " + list, 1, list.size());
299            return list.get(0);
300        }
301    
302        /**
303         * Asserts that a list is of the given size
304         */
305        public static <T> List<T> assertListSize(List<T> list, int size) {
306            return assertListSize("List", list, size);
307        }
308    
309        /**
310         * Asserts that a list is of the given size
311         */
312        public static <T> List<T> assertListSize(String message, List<T> list, int size) {
313            assertEquals(message + " should be of size: "
314                    + size + " but is: " + list, size, list.size());
315            return list;
316        }
317    
318        /**
319         * Asserts that a list is of the given size
320         */
321        public static <T> Collection<T> assertCollectionSize(Collection<T> list, int size) {
322            return assertCollectionSize("List", list, size);
323        }
324    
325        /**
326         * Asserts that a list is of the given size
327         */
328        public static <T> Collection<T> assertCollectionSize(String message, Collection<T> list, int size) {
329            assertEquals(message + " should be of size: "
330                    + size + " but is: " + list, size, list.size());
331            return list;
332        }
333    
334        /**
335         * A helper method to create a list of Route objects for a given route builder
336         */
337        public static List<Route> getRouteList(RouteBuilder builder) throws Exception {
338            CamelContext context = new DefaultCamelContext();
339            context.addRoutes(builder);
340            context.start();
341            List<Route> answer = context.getRoutes();
342            context.stop();
343            return answer;
344        }
345    
346        /**
347         * Asserts that the text contains the given string
348         *
349         * @param text the text to compare
350         * @param containedText the text which must be contained inside the other text parameter
351         */
352        public static void assertStringContains(String text, String containedText) {
353            assertNotNull("Text should not be null!", text);
354            assertTrue("Text: " + text + " does not contain: " + containedText, text.contains(containedText));
355        }
356    
357        /**
358         * If a processor is wrapped with a bunch of DelegateProcessor or DelegateAsyncProcessor objects
359         * this call will drill through them and return the wrapped Processor.
360         */
361        public static Processor unwrap(Processor processor) {
362            while (true) {
363                if (processor instanceof DelegateProcessor) {
364                    processor = ((DelegateProcessor)processor).getProcessor();
365                } else {
366                    return processor;
367                }
368            }
369        }
370    
371        /**
372         * If a processor is wrapped with a bunch of DelegateProcessor or DelegateAsyncProcessor objects
373         * this call will drill through them and return the Channel.
374         * <p/>
375         * Returns null if no channel is found.
376         */
377        public static Channel unwrapChannel(Processor processor) {
378            while (true) {
379                if (processor instanceof Channel) {
380                    return (Channel) processor;
381                } else if (processor instanceof DelegateProcessor) {
382                    processor = ((DelegateProcessor)processor).getProcessor();
383                } else {
384                    return null;
385                }
386            }
387        }
388    
389        /**
390         * Recursively delete a directory, useful to zapping test data
391         *
392         * @param file the directory to be deleted
393         */
394        public static void deleteDirectory(String file) {
395            deleteDirectory(new File(file));
396        }
397    
398        /**
399         * Recursively delete a directory, useful to zapping test data
400         *
401         * @param file the directory to be deleted
402         */
403        public static void deleteDirectory(File file) {
404            if (file.isDirectory()) {
405                File[] files = file.listFiles();
406                for (int i = 0; i < files.length; i++) {
407                    deleteDirectory(files[i]);
408                }
409            }
410            file.delete();
411        }
412    
413        /**
414         * create the directory
415         *
416         * @param file the directory to be created
417         */
418        public static void createDirectory(String file) {
419            File dir = new File(file);
420            dir.mkdirs();
421        }
422    
423        /**
424         * To be used for folder/directory comparison that works across different platforms such
425         * as Window, Mac and Linux.
426         */
427        public static void assertDirectoryEquals(String expected, String actual) {
428            assertDirectoryEquals(null, expected, actual);
429        }
430    
431        /**
432         * To be used for folder/directory comparison that works across different platforms such
433         * as Window, Mac and Linux.
434         */
435        public static void assertDirectoryEquals(String message, String expected, String actual) {
436            // must use single / as path separators
437            String expectedPath = expected.replace('\\', '/');
438            String actualPath = actual.replace('\\', '/');
439    
440            if (message != null) {
441                assertEquals(message, expectedPath, actualPath);
442            } else {
443                assertEquals(expectedPath, actualPath);
444            }
445        }
446    
447    }