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.junit4;
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    import org.junit.Assert;
045    
046    /**
047     * A bunch of useful testing methods
048     *
049     * @version $Revision: 784509 $
050     */
051    public abstract class TestSupport extends Assert {
052        private static final Log LOG = LogFactory.getLog(TestSupport.class);    
053        protected transient Log log = LogFactory.getLog(getClass());    
054        
055        // Builder methods for expressions used when testing
056        // -------------------------------------------------------------------------
057    
058        /**
059         * Returns a value builder for the given header
060         */
061        public static ValueBuilder header(String name) {
062            return Builder.header(name);
063        }
064    
065        /**
066         * Returns a value builder for the given property
067         */
068        public static ValueBuilder property(String name) {
069            return Builder.property(name);
070        }    
071        
072        /**
073         * Returns a predicate and value builder for the inbound body on an exchange
074         */
075        public static ValueBuilder body() {
076            return Builder.body();
077        }
078    
079        /**
080         * Returns a predicate and value builder for the inbound message body as a
081         * specific type
082         */
083        public static <T> ValueBuilder bodyAs(Class<T> type) {
084            return Builder.bodyAs(type);
085        }
086    
087        /**
088         * Returns a predicate and value builder for the outbound body on an
089         * exchange
090         */
091        public static ValueBuilder outBody() {
092            return Builder.outBody();
093        }
094    
095        /**
096         * Returns a predicate and value builder for the outbound message body as a
097         * specific type
098         */
099        public static <T> ValueBuilder outBodyAs(Class<T> type) {
100            return Builder.outBodyAs(type);
101        }
102    
103        /**
104         * Returns a predicate and value builder for the fault body on an
105         * exchange
106         */
107        public static ValueBuilder faultBody() {
108            return Builder.faultBody();
109        }
110    
111        /**
112         * Returns a predicate and value builder for the fault message body as a
113         * specific type
114         */
115        public static <T> ValueBuilder faultBodyAs(Class<T> type) {
116            return Builder.faultBodyAs(type);
117        }
118    
119        /**
120         * Returns a value builder for the given system property
121         */
122        public static ValueBuilder systemProperty(String name) {
123            return Builder.systemProperty(name);
124        }
125    
126        /**
127         * Returns a value builder for the given system property
128         */
129        public static ValueBuilder systemProperty(String name, String defaultValue) {
130            return Builder.systemProperty(name, defaultValue);
131        }
132    
133        // Assertions
134        // -----------------------------------------------------------------------
135    
136        public static <T> T assertIsInstanceOf(Class<T> expectedType, Object value) {
137            assertNotNull("Expected an instance of type: " + expectedType.getName() + " but was null", value);
138            assertTrue("object should be a " + expectedType.getName() + " but was: " + value + " with type: "
139                       + value.getClass().getName(), expectedType.isInstance(value));
140            return expectedType.cast(value);
141        }
142    
143        public static void assertEndpointUri(Endpoint endpoint, String uri) {
144            assertNotNull("Endpoint is null when expecting endpoint for: " + uri, endpoint);
145            assertEquals("Endoint uri for: " + endpoint, uri, endpoint.getEndpointUri());
146        }
147    
148        /**
149         * Asserts the In message on the exchange contains the expected value
150         */
151        public static Object assertInMessageHeader(Exchange exchange, String name, Object expected) {
152            return assertMessageHeader(exchange.getIn(), name, expected);
153        }
154    
155        /**
156         * Asserts the Out message on the exchange contains the expected value
157         */
158        public static Object assertOutMessageHeader(Exchange exchange, String name, Object expected) {
159            return assertMessageHeader(exchange.getOut(), name, expected);
160        }
161    
162        /**
163         * Asserts that the given exchange has an OUT message of the given body value
164         *
165         * @param exchange the exchange which should have an OUT message
166         * @param expected the expected value of the OUT message
167         * @throws InvalidPayloadException is thrown if the payload is not the expected class type
168         */
169        public static void assertInMessageBodyEquals(Exchange exchange, Object expected) throws InvalidPayloadException {
170            assertNotNull("Should have a response exchange!", exchange);
171    
172            Object actual;
173            if (expected == null) {
174                actual = ExchangeHelper.getMandatoryInBody(exchange);
175                assertEquals("in body of: " + exchange, expected, actual);
176            } else {
177                actual = ExchangeHelper.getMandatoryInBody(exchange, expected.getClass());
178            }
179            assertEquals("in body of: " + exchange, expected, actual);
180    
181            LOG.debug("Received response: " + exchange + " with in: " + exchange.getIn());
182        }
183    
184        /**
185         * Asserts that the given exchange has an OUT message of the given body value
186         *
187         * @param exchange the exchange which should have an OUT message
188         * @param expected the expected value of the OUT message
189         * @throws InvalidPayloadException is thrown if the payload is not the expected class type
190         */
191        public static void assertOutMessageBodyEquals(Exchange exchange, Object expected) throws InvalidPayloadException {
192            assertNotNull("Should have a response exchange!", exchange);
193    
194            Object actual;
195            if (expected == null) {
196                actual = ExchangeHelper.getMandatoryOutBody(exchange);
197                assertEquals("output body of: " + exchange, expected, actual);
198            } else {
199                actual = ExchangeHelper.getMandatoryOutBody(exchange, expected.getClass());
200            }
201            assertEquals("output body of: " + exchange, expected, actual);
202    
203            LOG.debug("Received response: " + exchange + " with out: " + exchange.getOut());
204        }
205    
206        public static Object assertMessageHeader(Message message, String name, Object expected) {
207            Object value = message.getHeader(name);
208            assertEquals("Header: " + name + " on Message: " + message, expected, value);
209            return value;
210        }
211    
212        /**
213         * Asserts that the given expression when evaluated returns the given answer
214         */
215        public static Object assertExpression(Expression expression, Exchange exchange, Object expected) {
216            Object value;
217            if (expected != null) {
218                value = expression.evaluate(exchange, expected.getClass());
219            } else {
220                value = expression.evaluate(exchange, Object.class);
221            }
222    
223            LOG.debug("Evaluated expression: " + expression + " on exchange: " + exchange + " result: " + value);
224    
225            assertEquals("Expression: " + expression + " on Exchange: " + exchange, expected, value);
226            return value;
227        }
228    
229        /**
230         * Asserts that the predicate returns the expected value on the exchange
231         */
232        public static void assertPredicateMatches(Predicate predicate, Exchange exchange) {
233            assertPredicate(predicate, exchange, true);
234        }
235    
236        /**
237         * Asserts that the predicate returns the expected value on the exchange
238         */
239        public static void assertPredicateDoesNotMatch(Predicate predicate, Exchange exchange) {
240            try {
241                PredicateAssertHelper.assertMatches(predicate, "Predicate should match: ", exchange);
242            } catch (AssertionError e) {
243                LOG.debug("Caught expected assertion error: " + e);
244            }
245            assertPredicate(predicate, exchange, false);
246        }
247    
248        /**
249         * Asserts that the predicate returns the expected value on the exchange
250         */
251        public static boolean assertPredicate(final Predicate predicate, Exchange exchange, boolean expected) {
252            if (expected) {
253                PredicateAssertHelper.assertMatches(predicate, "Predicate failed: ", exchange);
254            }
255            boolean value = predicate.matches(exchange);
256    
257            LOG.debug("Evaluated predicate: " + predicate + " on exchange: " + exchange + " result: " + value);
258    
259            assertEquals("Predicate: " + predicate + " on Exchange: " + exchange, expected, value);
260            return value;
261        }
262    
263        /**
264         * Resolves an endpoint and asserts that it is found
265         */
266        public static Endpoint resolveMandatoryEndpoint(CamelContext context, String uri) {
267            Endpoint endpoint = context.getEndpoint(uri);
268    
269            assertNotNull("No endpoint found for URI: " + uri, endpoint);
270    
271            return endpoint;
272        }
273    
274        /**
275         * Resolves an endpoint and asserts that it is found
276         */
277        public static <T extends Endpoint> T resolveMandatoryEndpoint(CamelContext context, String uri,
278                                                                  Class<T> endpointType) {
279            T endpoint = context.getEndpoint(uri, endpointType);
280    
281            assertNotNull("No endpoint found for URI: " + uri, endpoint);
282    
283            return endpoint;
284        }
285    
286        /**
287         * Creates an exchange with the given body
288         */
289        protected Exchange createExchangeWithBody(CamelContext camelContext, Object body) {
290            Exchange exchange = new DefaultExchange(camelContext);
291            Message message = exchange.getIn();        
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    }