1 /*
2 * Redistribution and use of this software and associated documentation
3 * ("Software"), with or without modification, are permitted provided
4 * that the following conditions are met:
5 *
6 * 1. Redistributions of source code must retain copyright
7 * statements and notices. Redistributions must also contain a
8 * copy of this document.
9 *
10 * 2. Redistributions in binary form must reproduce the
11 * above copyright notice, this list of conditions and the
12 * following disclaimer in the documentation and/or other
13 * materials provided with the distribution.
14 *
15 * 3. The name "Exolab" must not be used to endorse or promote
16 * products derived from this Software without prior written
17 * permission of Intalio, Inc. For written permission,
18 * please contact info@exolab.org.
19 *
20 * 4. Products derived from this Software may not be called "Exolab"
21 * nor may "Exolab" appear in their names without prior written
22 * permission of Intalio, Inc. Exolab is a registered
23 * trademark of Intalio, Inc.
24 *
25 * 5. Due credit should be given to the Exolab Project
26 * (http://www.exolab.org/).
27 *
28 * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS
29 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
30 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
32 * INTALIO, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39 * OF THE POSSIBILITY OF SUCH DAMAGE.
40 *
41 * Copyright 2001-2002 (C) Intalio, Inc. All Rights Reserved.
42 *
43 * $Id: TestCaseAggregator.java 6787 2007-01-29 06:00:49Z ekuns $
44 */
45 package org.castor.xmlctf;
46
47 import java.io.File;
48
49 import org.castor.xmlctf.util.FileServices;
50
51
52 import junit.framework.Test;
53 import junit.framework.TestCase;
54 import junit.framework.TestSuite;
55
56 /**
57 * This class is used to inspect recursively a hierarchy of directories that
58 * contain CTF tests (jars or directories). A JUnit TestSuite is created for
59 * each directory.
60 *
61 * @author <a href="mailto:gignoux@kernelcenter.org">Sebastien Gignoux</a>
62 * @author <a href="mailto:blandin@intalio.com">Arnaud Blandin</a>
63 * @version $Revision: 6787 $ $Date: 2006-04-26 15:14:53 -0600 (Wed, 26 Apr 2006) $
64 */
65 public class TestCaseAggregator extends TestCase {
66
67 /** File separator for this system. */
68 private static final String FILE_SEPARATOR = System.getProperty("file.separator");
69 /** Name of the system property to set up the verbose mode. */
70 public static final String VERBOSE_PROPERTY = "org.exolab.castor.tests.Verbose";
71 /** Name of the system property to set up the printStackTrace mode. */
72 public static final String PRINT_STACK_TRACE = "org.exolab.castor.tests.printStack";
73 /** True if we desire a lot of info on what happen. */
74 private static boolean _verbose;
75
76 static {
77 String v = System.getProperty(VERBOSE_PROPERTY);
78 _verbose = (v != null && v.equals("true"));
79 }
80
81 /** The directory that contains CTF test cases. */
82 private final File _directory;
83 /** Location of the temporary files when the tests are run. */
84 private final String _testOutputRoot;
85 /** String containing the directory path from the test root to here. */
86 private final String _directoryToHere;
87
88 /**
89 * Creates a new TestCaseAggregator with the given name.
90 *
91 * @param name the name of this TestCaseAggregator
92 */
93 public TestCaseAggregator(final String name) {
94 super(name);
95 _directory = null;
96 _directoryToHere = null;
97 _testOutputRoot = null;
98 }
99
100 /**
101 * Create a new TestCaseAggregator which will inspect the directory given in
102 * parameter.
103 *
104 * @param directory the directory to inspect for test case and subdirectory
105 * @param testOutputRoot the path to the directory where the test in this
106 * directory can put there temporary files.
107 */
108 public TestCaseAggregator(final File directory, final String testOutputRoot) {
109 super(directory.getName());
110 _directory = directory;
111 _directoryToHere = "";
112 _testOutputRoot = testOutputRoot;
113 }
114
115 /**
116 * Create a new TestCaseAggregator which will inspect the directory given in
117 * parameter.
118 *
119 * @param directory the directory to inspect for test case and subdirectory
120 * @param directoryToHere the directory path above "directory"
121 * @param testOutputRoot the path to the directory where the test in this
122 * directory can put there temporary files.
123 */
124 protected TestCaseAggregator(final File directory, final String directoryToHere,
125 final String testOutputRoot) {
126 super(directory.getName());
127 _directory = directory;
128 _directoryToHere = directoryToHere + "/";
129 _testOutputRoot = testOutputRoot;
130 }
131
132 /**
133 * Assembles and returns a test suite containing all known tests.
134 *
135 * @return A non-null test suite.
136 */
137 public Test suite() {
138 final TestSuite suite = new TestSuite();
139 final String suiteName = (_directoryToHere.length() == 0) ? _directory.getName()
140 : _directoryToHere;
141 suite.setName(suiteName);
142
143 if (!_directory.isDirectory()) {
144 // Maybe it is a jar file, it happens if we run the
145 // CastorTestSuiteRunner with just one jar in param
146 if (_directory.getName().endsWith(".jar")) {
147 CastorTestCase tc = new CastorTestCase(_directory, _directoryToHere, _testOutputRoot);
148 return tc.suite();
149 }
150 // If not a jar file, just return the empty TestSuite
151 return suite;
152 }
153
154 String outputRoot = _testOutputRoot;
155 if (outputRoot.endsWith("/") || outputRoot.endsWith(FILE_SEPARATOR)) {
156 outputRoot = outputRoot + _directory.getName();
157 } else {
158 outputRoot = outputRoot + FILE_SEPARATOR + _directory.getName();
159 }
160
161 verbose("\n==================================================================");
162 verbose("Processing directory:\n" + _directory.getAbsolutePath());
163 verbose("==================================================================\n");
164
165 final File[] list = _directory.listFiles();
166 for (int i = 0; i < list.length; ++i) {
167 processOneFileOrDirectory(suite, outputRoot, list[i]);
168 }
169
170 return suite;
171 }
172
173 /**
174 * Processes a single file or directory, recurses into directories and for
175 * files, if a JAR file or a test descriptor XML file, create a new test
176 * case and add it to our test suite.
177 *
178 * @param suite the test suite to add new tests to
179 * @param outputRoot output directory for temporary files in our tests
180 * @param file the file or directory to process
181 */
182 private void processOneFileOrDirectory(final TestSuite suite, final String outputRoot,
183 final File file) {
184 String name = file.getName();
185
186 // If a directory (and not a source control directory), recurse
187 if (file.isDirectory()) {
188 // Directories that contain TestDescriptor.xml do not get recursed any deeper
189 if (!FileServices.isScmDirectory(name) && !((new File(file.getParentFile(), "TestDescriptor.xml")).exists())) {
190 //look for jars or testDescriptor files inside the directory
191 Test test = new TestCaseAggregator(file, _directoryToHere + file.getName(), outputRoot).suite();
192 if (test != null) {
193 suite.addTest(test);
194 }
195 }
196 return;
197 }
198
199 // Otherwise make a test case if a JAR file or test descriptor
200
201 Test test = null;
202 if (name.endsWith(".jar")) {
203 test = (new CastorTestCase(file, _directoryToHere, outputRoot)).suite();
204 } else if (name.endsWith(CastorTestCase.TEST_DESCRIPTOR)) {
205 test = (new CastorTestCase(_directory, _directoryToHere, outputRoot)).suite();
206 }
207
208 if (test != null) {
209 suite.addTest(test);
210 }
211 }
212
213 /**
214 * Prints the provided message if verbose is true.
215 * @param message the message to print
216 */
217 private void verbose(final String message) {
218 if (_verbose) {
219 System.out.println(message);
220 }
221 }
222
223 }