Coverage Report - org.apache.commons.latka.Latka
 
Classes in this File Line Coverage Branch Coverage Complexity
Latka
0%
0/105
0%
0/28
4.375
 
 1  
 /*
 2  
  * Copyright 1999-2002,2004 The Apache Software Foundation.
 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  
  */
 16  
 
 17  
 package org.apache.commons.latka;
 18  
 
 19  
 import java.io.File;
 20  
 import java.io.FileInputStream;
 21  
 import java.io.FileWriter;
 22  
 import java.io.IOException;
 23  
 import java.io.StringReader;
 24  
 import java.io.StringWriter;
 25  
 import java.net.URL;
 26  
 import java.text.SimpleDateFormat;
 27  
 import java.util.Date;
 28  
 import java.util.Iterator;
 29  
 import java.util.Properties;
 30  
 
 31  
 import javax.xml.transform.Source;
 32  
 import javax.xml.transform.Transformer;
 33  
 import javax.xml.transform.TransformerException;
 34  
 import javax.xml.transform.TransformerFactory;
 35  
 import javax.xml.transform.stream.StreamResult;
 36  
 import javax.xml.transform.stream.StreamSource;
 37  
 
 38  
 import org.apache.commons.jelly.Jelly;
 39  
 import org.apache.commons.jelly.JellyContext;
 40  
 import org.apache.commons.jelly.XMLOutput;
 41  
 
 42  
 import org.apache.commons.latka.event.LatkaEventInfo;
 43  
 import org.apache.commons.latka.event.LatkaEventListener;
 44  
 import org.apache.commons.latka.jelly.JellyUtils;
 45  
 
 46  
 import org.apache.log4j.Category;
 47  
 
 48  
 /**
 49  
  * This is the primary class for executing Latka functional
 50  
  * tests.  The main(String aargs[]) class provides a convenient
 51  
  * command-line interface for executing single tests.  See the
 52  
  * Latka documentation for details on command-line usage.
 53  
  * There is also a webapp-based Latka interface.
 54  
  *
 55  
  * @see Suite
 56  
  * @see LatkaProperties
 57  
  *
 58  
  * @author Morgan Delagrange
 59  
  * @author <a href="mailto:dion@apache.org">dIon Gillard</a>
 60  
  *
 61  
  * @version $Revision: 155424 $
 62  
  */
 63  0
 public class Latka {
 64  
 
 65  
     /** whether xml parsing is validating or not */
 66  0
     protected boolean _isValidating = true;
 67  
     /** XSL stylesheet url to use when generating XML */
 68  0
     protected URL _reportStylesheetUrl = null;
 69  
 
 70  
     /** log4j category for logged output */
 71  0
     protected static final Category _log = 
 72  0
                              Category.getInstance(Latka.class.getName());
 73  
 
 74  
     /** Latka configuration variables */
 75  0
     protected Properties _props = LatkaProperties.getProperties();
 76  
 
 77  
     /** Message displayed to user when incorrect args provided */
 78  
     private static final String LATKA_USAGE = 
 79  
             "\n######################\n"
 80  
         +   "Latka usage:\n"
 81  
         +   "  java org.apache.commons.latka.Latka \"XML_suite_URL\" "
 82  
         +   "[\"propfile:file_name\"] [\"prop:prop_name=prop_value\"]\n\n"
 83  
         +   "The quotes around properties are REQUIRED.\n"
 84  
         +   "######################\n";
 85  
     
 86  
     /**
 87  
      * Execute a single Latka test suite.  The Latka event listner
 88  
      * will receive all the events generated during the test.
 89  
      * The Latka packages contain an implmentation of LatkaEventInfo
 90  
      * which can generate an XML report according to a standard
 91  
      * DTD (see documentation).
 92  
      * 
 93  
      * @param suite    test suite to execute
 94  
      * @param listener target for test events
 95  
      * @exception LatkaException
 96  
      *                   when any internal error occurs
 97  
      * @see XMLReporter XML-based implementation of LatkaEventListener
 98  
      */
 99  
     public void runTests(Suite suite, LatkaEventListener listener)
 100  
                 throws LatkaException {
 101  
     
 102  
         try {
 103  
 
 104  0
             Jelly jelly = new Jelly();
 105  0
             URL url = suite.getURL();
 106  0
             jelly.setUrl(url);
 107  0
             jelly.setValidateXML(_isValidating);
 108  0
             jelly.setDefaultNamespaceURI("jelly:org.apache.commons.latka.jelly.LatkaTagLibrary");
 109  
 
 110  0
             JellyContext context = buildJellyContext();
 111  0
             JellyUtils.getInstance().setLatkaEventListener(context,listener);
 112  
 
 113  0
             String exturl = url.toExternalForm();
 114  0
             int lastSlash = exturl.lastIndexOf("/");
 115  0
             String extBase = exturl.substring(0,lastSlash+1);
 116  0
             URL baseurl = new URL(extBase);
 117  0
             context.setCurrentURL(baseurl);
 118  
 
 119  
             // add listener
 120  0
             jelly.compileScript().run(context,XMLOutput.createDummyXMLOutput());
 121  
 
 122  0
         } catch (Exception e) {
 123  0
             throw new LatkaException(e);
 124  0
         }
 125  0
     }
 126  
 
 127  
     protected JellyContext buildJellyContext() {
 128  0
         JellyContext context = new JellyContext();
 129  0
         Iterator keys = _props.keySet().iterator();
 130  0
         while (keys.hasNext()) {
 131  0
             String key = (String) keys.next();
 132  0
             String value = _props.getProperty(key);
 133  0
             context.setVariable(key,value);
 134  0
         }
 135  
 
 136  0
         return context;
 137  
     }
 138  
 
 139  
     /**
 140  
      * Set whether or not Latka will validate the XML in
 141  
      * each test.
 142  
      *
 143  
      * @param isValidating whether or not to validate XML
 144  
      */
 145  
     public void setValidating(boolean isValidating) {
 146  0
         _isValidating = isValidating;
 147  0
     }
 148  
 
 149  
     /**
 150  
      * Set the URL to be used when transforming XML generated by the XMLReporter
 151  
      * @param url a valid URL referencing a stylesheet 
 152  
      */
 153  
     public void setReportStylesheet(URL url) {
 154  0
         _reportStylesheetUrl = url;
 155  0
     }
 156  
 
 157  
     /**
 158  
      * Use this method to log XML generated by the
 159  
      * XMLReporter class.
 160  
      *
 161  
      * @param xml XML to be logged
 162  
      * @throws IOException if the XML could not be written to the filesystem
 163  
      */
 164  
     protected void logXML(String xml) throws IOException {
 165  
 
 166  0
         String logProp = _props.getProperty("latka.writeLog");
 167  0
         if ((logProp != null) && (logProp.equals("false"))) {
 168  0
             return;
 169  
         }
 170  
 
 171  0
         File dir = new File("logs");
 172  
         // try to create logs directory. if it fails, then check to
 173  
         // make sure it is there (may have existed before) and is writeable
 174  0
         if (!dir.mkdirs()) {
 175  0
             if (!dir.exists ()) {
 176  0
                 throw new IOException("Unable to create logs directory");
 177  0
             } else if (!dir.canWrite ()) {
 178  0
                 throw new IOException("Unable to write to logs directory");
 179  
             }
 180  
         }
 181  0
         SimpleDateFormat formatter = new SimpleDateFormat ("yyyyMMdd'-'HHmm");
 182  0
         String dateString = formatter.format(new Date());
 183  0
         File file = new File(dir, dateString + ".xml");
 184  0
         FileWriter fileWriter = new FileWriter(file);
 185  0
         fileWriter.write(xml);
 186  0
         fileWriter.close();
 187  0
     }
 188  
 
 189  
     /**
 190  
      * Transform the XML generated by the XMLReporter using
 191  
      * the default stylesheet.
 192  
      *
 193  
      * @param xml XML generated by XMLReporter
 194  
      * @return transformed report
 195  
      * @throws LatkaException if the XML could not be transformed
 196  
      */
 197  
     public String transformXML(String xml) throws LatkaException {
 198  
     
 199  
         try {
 200  0
             StringWriter output = new StringWriter();
 201  
 
 202  0
             Source xslSource = null;
 203  
 
 204  0
             if (_reportStylesheetUrl == null) {
 205  0
             ClassLoader loader = Thread.currentThread().getContextClassLoader();
 206  0
                    if (loader == null) {
 207  
                 // there may not be a context class loader
 208  0
                 loader = getClass().getClassLoader();
 209  
                 }
 210  
 
 211  0
             xslSource = new StreamSource(
 212  
                             loader.getResourceAsStream(
 213  
                             "org.apache.commons.latka.report.xsl")
 214  
                         );
 215  0
             } else {
 216  0
                 xslSource = new StreamSource(_reportStylesheetUrl.toString());
 217  
             }
 218  
 
 219  
 
 220  0
             Transformer transformer = 
 221  
             TransformerFactory.newInstance().newTransformer(xslSource);
 222  0
             StreamSource xmlSource = new StreamSource(new StringReader(xml));
 223  0
             StreamResult result = new StreamResult(output);
 224  0
             transformer.transform(xmlSource, result);
 225  0
             return output.toString();
 226  0
         } catch (TransformerException e) {
 227  0
             throw new LatkaException(e);
 228  
         }
 229  
     }
 230  
 
 231  
     /**
 232  
      * Processes the command line arguments, executes a single test.
 233  
      * and processes the resulting report.  Command line usage is
 234  
      * described in the LATKA_USAGE constant.
 235  
      *
 236  
      * @param args arguments passed into the main(String[]) method
 237  
      *
 238  
      * @throws LatkaException if any problems are encountered during
 239  
      * the execution of the tests
 240  
      */
 241  
     protected void runCommandLine(String args[]) throws LatkaException {
 242  
 
 243  0
         if (args.length < 1) {
 244  0
             System.out.println(LATKA_USAGE);
 245  
         }
 246  
 
 247  0
         String urlString = args[0];
 248  
 
 249  0
         if (args.length > 1) {
 250  
 
 251  0
             for (int i = 1; i < args.length; ++i) {
 252  0
                 String arg = args[i];
 253  0
                 if (arg.startsWith("prop:")) {
 254  0
                     String propName = arg.substring(5, arg.indexOf("="));
 255  0
                     String propValue = arg.substring(arg.indexOf("=") + 1);
 256  0
                     _props.setProperty(propName, propValue);
 257  0
                 } else if (arg.startsWith("propfile:")) { 
 258  
                     try {
 259  0
                         _props.load(new FileInputStream(arg.substring(9)));
 260  0
                     } catch (IOException e) {
 261  0
                         System.out.println("Could not load user prop file, uri="
 262  
                                             + arg.substring(9));
 263  0
                     }                                            
 264  
                 } else {
 265  0
                     throw new IllegalArgumentException(LATKA_USAGE);
 266  
                 }
 267  
             } // for
 268  
         } // if
 269  
 
 270  0
         String xml = null;
 271  0
         XMLReporter listener = new XMLReporter();
 272  
 
 273  
         // overkill, all we need is success/failure
 274  0
         LatkaEventInfo info = new DefaultLatkaEventInfo(listener); 
 275  
 
 276  
         try {
 277  
 
 278  0
             URL url = new URL(urlString);
 279  0
             Suite suite = new Suite(url);
 280  
 
 281  
 
 282  0
             runTests(suite, info);
 283  
 
 284  0
             xml = listener.getDocumentAsString();
 285  0
             logXML(xml);
 286  0
         } catch (IOException e) {
 287  0
             throw new LatkaException(e);
 288  0
         }
 289  
 
 290  0
         System.out.println(transformXML(xml));
 291  
 
 292  0
         if (info.didSuiteSucceed() == false) {
 293  
             // throw an exception, so the process will
 294  
             // return as a failure
 295  0
             throw new LatkaException("SUITE FAILED");
 296  
         }
 297  0
     }
 298  
 
 299  
     /**
 300  
      * Execute a single test suite via the command line
 301  
      * interface.  See the Latka documentation for detailed
 302  
      * usage instructions.  The Java process will return
 303  
      * a 0 if all tests succeed and a 1 if any fail
 304  
      * or there is an unrecoverable error in the test
 305  
      * execution.
 306  
      *
 307  
      * @param args arguments containing the test suite location
 308  
      *        and any properties or property file references
 309  
      */
 310  
     public static void main (String args[]) {
 311  
 
 312  0
         Latka latka = new Latka();
 313  
         try {
 314  0
             latka.runCommandLine(args);
 315  0
         } catch (LatkaException e) {
 316  0
             e.printStackTrace();
 317  0
             System.exit(1);
 318  0
         }
 319  
     
 320  0
     }
 321  
 }