|
|||||||||||||||||||
| Source file | Conditionals | Statements | Methods | TOTAL | |||||||||||||||
| XMLRoot.java | 0% | 0% | 0% | 0% |
|
||||||||||||||
| 1 |
package junit.extensions.jfcunit.tools;
|
|
| 2 |
|
|
| 3 |
import junit.extensions.jfcunit.xml.XMLRecorder;
|
|
| 4 |
|
|
| 5 |
import junit.extensions.xml.XMLTestSuite;
|
|
| 6 |
import junit.extensions.xml.XMLUtil;
|
|
| 7 |
|
|
| 8 |
import junit.framework.Test;
|
|
| 9 |
|
|
| 10 |
import junit.textui.TestRunner;
|
|
| 11 |
|
|
| 12 |
import java.io.File;
|
|
| 13 |
import java.io.FileInputStream;
|
|
| 14 |
import java.io.FileNotFoundException;
|
|
| 15 |
import java.io.FileOutputStream;
|
|
| 16 |
import java.io.IOException;
|
|
| 17 |
import java.io.InputStream;
|
|
| 18 |
import java.io.PrintWriter;
|
|
| 19 |
|
|
| 20 |
import java.lang.reflect.InvocationTargetException;
|
|
| 21 |
import java.lang.reflect.Method;
|
|
| 22 |
|
|
| 23 |
import java.util.StringTokenizer;
|
|
| 24 |
|
|
| 25 |
|
|
| 26 |
/**
|
|
| 27 |
* <p>Title: JFCUnit</p>
|
|
| 28 |
* <p>Description: This class is a tool class which interfaces
|
|
| 29 |
* a JUnit test environment to the JFCUnits XML test environment.
|
|
| 30 |
* The application can be passed through system properties, the constructor,
|
|
| 31 |
* the static call to get the test suite, or through the main methods arguments.
|
|
| 32 |
*
|
|
| 33 |
* When XMLRoot is instanciated with no arguments then the
|
|
| 34 |
* following system properties are queried.
|
|
| 35 |
*
|
|
| 36 |
* jfcunit.xmlroot.classname required main classname.
|
|
| 37 |
* jfcunit.xmlroot.args optional parameters to the main method.
|
|
| 38 |
* jfcunit.xmlroot.testsuite XML test suite to be run.
|
|
| 39 |
* jfcunit.xmlroot.record If not specified the record tags will be ignored.
|
|
| 40 |
* jfcunit.xmlroot.create Create a new xml file if it does not exist.
|
|
| 41 |
* </p>
|
|
| 42 |
* @author kevin wilson
|
|
| 43 |
* @version 1.0
|
|
| 44 |
*/
|
|
| 45 |
public class XMLRoot extends XMLTestSuite { |
|
| 46 |
/** Document factory to be used as default. */
|
|
| 47 |
public static final String DOCUMENT_FACTORY = "javax.xml.parsers.DocumentBuilderFactory"; |
|
| 48 |
|
|
| 49 |
/** System property for classname. */
|
|
| 50 |
public static final String XMLROOT_CLASSNAME = "jfcunit.xmlroot.classname"; |
|
| 51 |
|
|
| 52 |
/** System property for args. */
|
|
| 53 |
public static final String XMLROOT_ARGS = "jfcunit.xmlroot.args"; |
|
| 54 |
|
|
| 55 |
/** System property for recording. */
|
|
| 56 |
public static final String XMLROOT_RECORD = "jfcunit.xmlroot.record"; |
|
| 57 |
|
|
| 58 |
/** System property for XML file. */
|
|
| 59 |
public static final String XMLROOT_TESTSUITE = "jfcunit.xmlroot.testsuite"; |
|
| 60 |
|
|
| 61 |
/** System property for create the xml root. */
|
|
| 62 |
public static final String XMLROOT_CREATE = "jfcunit.xmlroot.create"; |
|
| 63 |
|
|
| 64 |
/**
|
|
| 65 |
* Default constructor. Uses system properties to get the classname and
|
|
| 66 |
* testsuite filename.
|
|
| 67 |
* @throws Exception may be thrown.
|
|
| 68 |
*/
|
|
| 69 | 0 |
public XMLRoot() throws Exception { |
| 70 | 0 |
this(
|
| 71 |
getClassName(), |
|
| 72 |
getArgs(), |
|
| 73 |
getTestSuite()); |
|
| 74 |
} |
|
| 75 |
|
|
| 76 |
/**
|
|
| 77 |
* Default constructor.
|
|
| 78 |
* @param classname Class name of the main application class
|
|
| 79 |
* @param args Arguments to be passed to the main method.
|
|
| 80 |
* @param filename The filename of the XML test suite specification
|
|
| 81 |
* @throws Exception may be thrown.
|
|
| 82 |
*/
|
|
| 83 | 0 |
public XMLRoot(final String classname, final String[] args,
|
| 84 |
final String filename) throws Exception {
|
|
| 85 | 0 |
super(filename,
|
| 86 |
getInputStream( |
|
| 87 |
classname.trim(), |
|
| 88 |
args, |
|
| 89 |
filename)); |
|
| 90 |
|
|
| 91 | 0 |
Class applClass = getClass().getClassLoader().loadClass( |
| 92 |
classname.trim()); |
|
| 93 | 0 |
Class[] parameterSpec = {String[].class};
|
| 94 | 0 |
final Method mainMethod = applClass.getMethod("main", parameterSpec);
|
| 95 | 0 |
XMLRecorder.setReplay(!getRecord()); |
| 96 |
|
|
| 97 | 0 |
final String[] appArgs; |
| 98 |
|
|
| 99 | 0 |
if (args == null) { |
| 100 | 0 |
appArgs = new String[0];
|
| 101 |
} else {
|
|
| 102 | 0 |
appArgs = args; |
| 103 |
} |
|
| 104 |
|
|
| 105 | 0 |
final Object[] parameters = {appArgs};
|
| 106 |
|
|
| 107 |
// Start the main from another thread so this does not block the test case
|
|
| 108 |
// in cases where the main method does not return.
|
|
| 109 | 0 |
new Thread(
|
| 110 |
new Runnable() {
|
|
| 111 | 0 |
public void run() { |
| 112 | 0 |
try {
|
| 113 | 0 |
mainMethod.invoke(null, parameters);
|
| 114 |
} catch (IllegalAccessException ex) {
|
|
| 115 | 0 |
System.err.println( |
| 116 |
"Exception occured while invoking application:"
|
|
| 117 |
+ classname); |
|
| 118 | 0 |
ex.printStackTrace(); |
| 119 |
} catch (IllegalArgumentException ex) {
|
|
| 120 | 0 |
System.err.println( |
| 121 |
"Exception occured while invoking application:"
|
|
| 122 |
+ classname); |
|
| 123 | 0 |
ex.printStackTrace(); |
| 124 |
} catch (InvocationTargetException ex) {
|
|
| 125 | 0 |
System.err.println( |
| 126 |
"Exception occured while invoking application:"
|
|
| 127 |
+ classname); |
|
| 128 | 0 |
ex.printStackTrace(); |
| 129 |
} |
|
| 130 |
} |
|
| 131 |
}).start(); |
|
| 132 |
} |
|
| 133 |
|
|
| 134 |
/**
|
|
| 135 |
* Application start method. The application takes two arguments:
|
|
| 136 |
* >main class< The Main class of the application to test
|
|
| 137 |
* >test suite specification< The XML file containing the test suite
|
|
| 138 |
* @param args classname [args...] xmlfile
|
|
| 139 |
* @throws Exception may be thrown.
|
|
| 140 |
*/
|
|
| 141 | 0 |
public static void main(final String[] args) throws Exception { |
| 142 | 0 |
updateDocFactory(); |
| 143 |
|
|
| 144 | 0 |
if (args.length < 2) {
|
| 145 | 0 |
TestRunner.run((Test) XMLRoot.suite()); |
| 146 | 0 |
} else if (args.length >= 2) { |
| 147 | 0 |
System.out.println("Application Class = " + args[0]);
|
| 148 |
|
|
| 149 | 0 |
String[] progArgs = new String[args.length - 2];
|
| 150 |
|
|
| 151 | 0 |
for (int i = 1; i < (args.length - 1); i++) { |
| 152 | 0 |
progArgs[i - 1] = args[i]; |
| 153 |
} |
|
| 154 |
|
|
| 155 | 0 |
System.out.println("Test Suite = " + args[args.length - 1]);
|
| 156 |
|
|
| 157 | 0 |
TestRunner.run((Test) XMLRoot.suite(args[0], progArgs, |
| 158 |
args[args.length - 1])); |
|
| 159 |
} else {
|
|
| 160 | 0 |
System.out.println( |
| 161 |
"Usage: junit.extensions.jfcunit.tools.XMLRoot mainclass [class arguments...] [xml file]");
|
|
| 162 | 0 |
System.exit(1); |
| 163 |
} |
|
| 164 |
} |
|
| 165 |
|
|
| 166 |
/**
|
|
| 167 |
* Creates a new test suite based on the system properties.
|
|
| 168 |
* @return Test generated from the System properties.
|
|
| 169 |
* @throws Exception may be thrown.
|
|
| 170 |
*/
|
|
| 171 | 0 |
public static Test suite() throws Exception { |
| 172 | 0 |
updateDocFactory(); |
| 173 |
|
|
| 174 | 0 |
return new XMLRoot(); |
| 175 |
} |
|
| 176 |
|
|
| 177 |
/**
|
|
| 178 |
* Creates a new test suite based on the main class and filename provided.
|
|
| 179 |
* @param classname Class name of the main application class
|
|
| 180 |
* @param args Arguments to be passed to the application.
|
|
| 181 |
* @param filename Name of XML file containing test suite
|
|
| 182 |
* @return Test created with the given arguments.
|
|
| 183 |
* @throws Exception may be thrown.
|
|
| 184 |
*/
|
|
| 185 | 0 |
public static Test suite(final String classname, final String[] args, |
| 186 |
final String filename) throws Exception {
|
|
| 187 | 0 |
updateDocFactory(); |
| 188 |
|
|
| 189 | 0 |
return new XMLRoot(classname, args, filename); |
| 190 |
} |
|
| 191 |
|
|
| 192 |
/**
|
|
| 193 |
* Get the jfcunit.xmlroot.args system property.
|
|
| 194 |
* @return Arguments to be run with the command.
|
|
| 195 |
* Assumes space separated list. May not work for
|
|
| 196 |
* all cases of program arguments.
|
|
| 197 |
*/
|
|
| 198 | 0 |
protected static final String[] getArgs() { |
| 199 | 0 |
String args = System.getProperty(XMLROOT_ARGS); |
| 200 |
|
|
| 201 | 0 |
if (args == null) { |
| 202 | 0 |
return null; |
| 203 |
} |
|
| 204 |
|
|
| 205 | 0 |
StringTokenizer st = new StringTokenizer(args, " "); |
| 206 | 0 |
String[] tokens = new String[st.countTokens()];
|
| 207 | 0 |
int i = 0;
|
| 208 |
|
|
| 209 | 0 |
while (st.hasMoreTokens()) {
|
| 210 | 0 |
tokens[i++] = st.nextToken(); |
| 211 |
} |
|
| 212 |
|
|
| 213 | 0 |
return tokens;
|
| 214 |
} |
|
| 215 |
|
|
| 216 |
/**
|
|
| 217 |
* Get the jfcunit.xmlroot.classname system property.
|
|
| 218 |
* @return class name to be executed.
|
|
| 219 |
*/
|
|
| 220 | 0 |
protected static final String getClassName() { |
| 221 | 0 |
String classname = System.getProperty(XMLROOT_CLASSNAME); |
| 222 |
|
|
| 223 | 0 |
if (classname == null) { |
| 224 | 0 |
throw new RuntimeException("Could not find system property:" |
| 225 |
+ XMLROOT_CLASSNAME); |
|
| 226 |
} |
|
| 227 |
|
|
| 228 | 0 |
return classname;
|
| 229 |
} |
|
| 230 |
|
|
| 231 |
/**
|
|
| 232 |
* Assembles the classname and args into one string.
|
|
| 233 |
* @param classname program name.
|
|
| 234 |
* @param args Arguments used.
|
|
| 235 |
* @return Program and arguments.
|
|
| 236 |
*/
|
|
| 237 | 0 |
protected static final String getCommand(final String classname, |
| 238 |
final String[] args) {
|
|
| 239 | 0 |
StringBuffer buf = new StringBuffer(1000);
|
| 240 | 0 |
buf.append(classname); |
| 241 | 0 |
buf.append(" ");
|
| 242 |
|
|
| 243 | 0 |
if (args != null) { |
| 244 | 0 |
for (int i = 0; i < args.length; i++) { |
| 245 | 0 |
buf.append(args[i]); |
| 246 | 0 |
buf.append(" ");
|
| 247 |
} |
|
| 248 |
} |
|
| 249 |
|
|
| 250 | 0 |
return buf.toString();
|
| 251 |
} |
|
| 252 |
|
|
| 253 |
/**
|
|
| 254 |
* Get the XML file name from the jfcunit.xmlroot.create system property.
|
|
| 255 |
* @return true if the xml file should be created.
|
|
| 256 |
*/
|
|
| 257 | 0 |
protected static final boolean getCreate() { |
| 258 | 0 |
if (getRecord()) {
|
| 259 | 0 |
return Boolean.getBoolean(XMLROOT_CREATE);
|
| 260 |
} |
|
| 261 |
|
|
| 262 | 0 |
return false; |
| 263 |
} |
|
| 264 |
|
|
| 265 |
/**
|
|
| 266 |
* Get the input stream for the XML file. If a XML file
|
|
| 267 |
* cannot be found then a template will be generated
|
|
| 268 |
* for recording.
|
|
| 269 |
*
|
|
| 270 |
* @param classname Classname added to template.
|
|
| 271 |
* @param args Arguments to be added to the template.
|
|
| 272 |
* @param fileName XML file name to be opened or created.
|
|
| 273 |
* @return Input stream of the file opened.
|
|
| 274 |
*/
|
|
| 275 | 0 |
protected static InputStream getInputStream(final String classname, |
| 276 |
final String[] args, final String fileName) {
|
|
| 277 | 0 |
InputStream is = null;
|
| 278 |
|
|
| 279 | 0 |
try {
|
| 280 | 0 |
is = XMLUtil.readFileFromClasspath(fileName); |
| 281 |
} catch (Exception e) {
|
|
| 282 |
; // Ignore exception
|
|
| 283 |
} |
|
| 284 |
|
|
| 285 | 0 |
if (is != null) { |
| 286 |
// If record is turned on then save the file to the
|
|
| 287 |
// current directory. Then it may be recorded to.
|
|
| 288 | 0 |
return is;
|
| 289 |
} else {
|
|
| 290 |
// Look in the local directory.
|
|
| 291 | 0 |
File file = new File(fileName);
|
| 292 |
|
|
| 293 | 0 |
if (file.exists()) {
|
| 294 | 0 |
try {
|
| 295 |
// Found the file so we will open the file.
|
|
| 296 | 0 |
is = new FileInputStream(file);
|
| 297 |
} catch (FileNotFoundException ex) {
|
|
| 298 | 0 |
System.err.println("Error opening local file." + fileName);
|
| 299 | 0 |
is = null;
|
| 300 |
} |
|
| 301 |
|
|
| 302 | 0 |
return is;
|
| 303 |
} else {
|
|
| 304 | 0 |
if (!getCreate()) {
|
| 305 | 0 |
System.err.println("File not found:" + fileName);
|
| 306 |
} else {
|
|
| 307 | 0 |
try {
|
| 308 |
// File was not found so we will create a new file.
|
|
| 309 | 0 |
file.createNewFile(); |
| 310 |
|
|
| 311 | 0 |
FileOutputStream os = new FileOutputStream(file);
|
| 312 | 0 |
PrintWriter pw = new PrintWriter(os);
|
| 313 | 0 |
pw.println("<?xml version=\"1.0\" ?>");
|
| 314 | 0 |
pw.println( |
| 315 |
"<!-- An example test suite template -->");
|
|
| 316 | 0 |
pw.println( |
| 317 |
"<!-- The first step in creating the test case is -->");
|
|
| 318 | 0 |
pw.println( |
| 319 |
"<!-- to document what is going to be tested. -->");
|
|
| 320 | 0 |
pw.println( |
| 321 |
"<!-- To do this, create the test suites and -->");
|
|
| 322 | 0 |
pw.println( |
| 323 |
"<!-- test cases which are to be recorded. -->");
|
|
| 324 | 0 |
pw.println( |
| 325 |
"<!-- 2. Setup the JFCXMLTestCase extension, -->");
|
|
| 326 | 0 |
pw.println( |
| 327 |
"<!-- to startup your application. -->");
|
|
| 328 | 0 |
pw.println( |
| 329 |
"<!-- 3. Run the JFCXMLTestCase defined above. -->");
|
|
| 330 | 0 |
pw.println( |
| 331 |
"<!-- 4. While the test case is running each -->");
|
|
| 332 | 0 |
pw.println( |
| 333 |
"<!-- \"record\" element will add to the XML. -->");
|
|
| 334 | 0 |
pw.print("<suite name=\"");
|
| 335 | 0 |
pw.print(getCommand(classname, args)); |
| 336 | 0 |
pw.println("\">");
|
| 337 | 0 |
pw.println(" <!-- definition of a local suite -->");
|
| 338 | 0 |
pw.println(" <suite name=\"Recording test suite\">");
|
| 339 | 0 |
pw.println( |
| 340 |
" <test name=\"Recording test\" robot=\"true\">");
|
|
| 341 | 0 |
pw.print( |
| 342 |
" <record encoding=\"UTF-8\" file=\"");
|
|
| 343 | 0 |
pw.print(fileName); |
| 344 | 0 |
pw.println("\"/>");
|
| 345 | 0 |
pw.println(" </test>");
|
| 346 | 0 |
pw.println(" </suite>");
|
| 347 | 0 |
pw.println("</suite>");
|
| 348 |
|
|
| 349 | 0 |
pw.close(); |
| 350 | 0 |
os.close(); |
| 351 |
|
|
| 352 | 0 |
return new FileInputStream(file); |
| 353 |
} catch (IOException ex1) {
|
|
| 354 | 0 |
System.err.println("Error creating new XML file."
|
| 355 |
+ fileName); |
|
| 356 | 0 |
ex1.printStackTrace(); |
| 357 |
} |
|
| 358 |
} |
|
| 359 |
} |
|
| 360 |
} |
|
| 361 |
|
|
| 362 | 0 |
return null; |
| 363 |
} |
|
| 364 |
|
|
| 365 |
/**
|
|
| 366 |
* Get the state of the jfcunit.xmlroot.record system property.
|
|
| 367 |
* @return true if the record element is present and set to true.
|
|
| 368 |
*/
|
|
| 369 | 0 |
protected static final boolean getRecord() { |
| 370 | 0 |
return Boolean.getBoolean(XMLROOT_RECORD);
|
| 371 |
} |
|
| 372 |
|
|
| 373 |
/**
|
|
| 374 |
* Get the XML file name from the jfcunit.xmlroot.testsuite system property.
|
|
| 375 |
* @return XML file name.
|
|
| 376 |
*/
|
|
| 377 | 0 |
protected static final String getTestSuite() { |
| 378 | 0 |
String testsuite = System.getProperty(XMLROOT_TESTSUITE); |
| 379 |
|
|
| 380 | 0 |
if (testsuite == null) { |
| 381 | 0 |
throw new RuntimeException("Could not find system property: " |
| 382 |
+ XMLROOT_TESTSUITE); |
|
| 383 |
} |
|
| 384 |
|
|
| 385 | 0 |
return testsuite;
|
| 386 |
} |
|
| 387 |
|
|
| 388 |
/**
|
|
| 389 |
* Set the document factory if it is not set for java
|
|
| 390 |
* versions less than 1.4.
|
|
| 391 |
*/
|
|
| 392 | 0 |
private static void updateDocFactory() { |
| 393 | 0 |
String version = System.getProperty("java.version");
|
| 394 |
|
|
| 395 | 0 |
if (version.startsWith("1.2") || version.startsWith("1.3")) { |
| 396 | 0 |
if (System.getProperty(DOCUMENT_FACTORY) == null) { |
| 397 | 0 |
System.setProperty(DOCUMENT_FACTORY, |
| 398 |
"org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
|
|
| 399 |
} |
|
| 400 |
} |
|
| 401 |
} |
|
| 402 |
} |
|
| 403 |
|
|
||||||||||