You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by cu...@apache.org on 2002/03/05 22:25:32 UTC

cvs commit: xml-xalan/test/java/src/org/apache/qetest FileDatalet.java FileTestlet.java

curcuru     02/03/05 13:25:32

  Added:       test/java/src/org/apache/qetest FileDatalet.java
                        FileTestlet.java
  Log:
  Simple generic file-based testlet implementations
  
  Revision  Changes    Path
  1.1                  xml-xalan/test/java/src/org/apache/qetest/FileDatalet.java
  
  Index: FileDatalet.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001-2002 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:  
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xalan" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 2000, Lotus
   * Development Corporation., http://www.lotus.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package org.apache.qetest;
  
  import java.io.File;
  import java.util.Hashtable;
  import java.util.Properties;
  import java.util.StringTokenizer;
  
  /**
   * Datalet representing set of paths to files: input, output, gold.
   * 
   * This is a fairly simplistic Datalet implementation that's 
   * useful for the many programs where the test requires reading 
   * an input file, performing an operation with the program, and 
   * then verifying an output file.
   *
   * We normally operate on local path/filenames, since the Java 
   * SDK's implementation of URLs and File objects is so poor at 
   * handling proper URI/URL's according to the RFCs.
   * 
   * @author Shane_Curcuru@us.ibm.com
   * @version $Id: FileDatalet.java,v 1.1 2002/03/05 21:25:32 curcuru Exp $
   */
  public class FileDatalet implements Datalet
  {
      /** Path of the location to get input resources from.  */
      protected String input = "tests/defaultInput";
  
      /** Accessor method for input.  */
      public String getInput() { return input; }
  
      /** Path to put actual output resources into.  */
      protected String output = "output/defaultOutput";
  
      /** Accessor method for output.  */
      public String getOutput() { return output; }
  
      /** Path of the location to get gold or reference resources from.  */
      protected String gold = "gold/defaultGold";
  
      /** Accessor method for gold.  */
      public String getGold() { return gold; }
  
  
      /** 
       * Generic placeholder for any additional options.  
       * 
       * This allows FileDatalets to support additional kinds 
       * of tests, like performance tests, without having to change 
       * this data model.  These options can serve as a catch-all 
       * for any new properties or options or what-not that new 
       * tests need, without having to change how the most basic 
       * member variables here work.
       * Note that while this needs to be a Properties object to 
       * take advantage of the parent/default behavior in 
       * getProperty(), this doesn't necessarily mean they can only 
       * store Strings; however only String-valued items can make 
       * use of the default properties mechanisim.
       *
       * Default is a null object.
       */
      protected Properties options = null;
  
      /** Accessor method for optional properties.  */
      public Properties getOptions() { return options; }
  
      /** Accessor method for optional properties; settable.  */
      public void setOptions(Properties p) { options = p; }
  
  
      /** Description of what this Datalet tests.  */
      protected String description = "FileDatalet: default description";
  
      /**
       * Accesor method for a brief description of this Datalet.  
       *
       * @return String describing the specific set of data 
       * this Datalet contains (can often be used as the description
       * of any check() calls made from the Testlet).
       */
      public String getDescription()
      {
          return description;
      }
  
  
      /**
       * Accesor method for a brief description of this Datalet.  
       *
       * @param s description to use for this Datalet.
       */
      public void setDescription(String s)
      {
          description = s;
      }
  
  
      /**
       * Worker method to auto-set the description of this Datalet.  
       */
      protected void setDescription()
      {
          setDescription("input=" + input 
                         + " output=" + output 
                         + " gold=" + gold); 
      }
  
  
      /**
       * No argument constructor is a no-op; not very useful.  
       */
      public FileDatalet() { /* no-op */ }
  
  
      /**
       * Initialize this datalet from another FileDatalet which 
       * serves as a 'base' location, and a filename.  
       * 
       * We set each of our input, output, gold to be concatenations 
       * of the base + File.separator + fileName.
       *
       * @param base FileDatalet object to serve as base directories
       * @param fileName to concatenate for each of input/output/gold
       */
      public FileDatalet(FileDatalet base, String fileName)
      {
          if ((null == base) || (null == fileName))
              throw new IllegalArgumentException("FileDatalet(base, fileName) called with null base!");
  
          StringBuffer buf = new StringBuffer(File.separator + fileName);
          input = base.getInput() + buf;
          output = base.getOutput() + buf;
          gold = base.getGold() + buf;
          
          setDescription(); 
      }
  
  
      /**
       * Initialize this datalet from a list of paths.  
       * 
       * @param i path for input
       * @param o path for output
       * @param g path for gold
       */
      public FileDatalet(String i, String o, String g)
      {
          input = i;
          output = o;
          gold = g;
          
          setDescription(); 
      }
  
  
      /**
       * Load fields of this Datalet from a Hashtable.  
       * Caller must provide data for all of our fields.
       * 
       * @param Hashtable to load
       */
      public void load(Hashtable h)
      {
          if (null == h)
              return; //@todo should this have a return val or exception?
  
          input = (String)h.get("input");
          output = (String)h.get("output");
          gold = (String)h.get("gold");
      }
  
  
      /**
       * Load fields of this Datalet from an array.  
       * Order: input, output, gold
       * If too few args, then fields at end of list are left at default value.
       * @param args array of Strings
       */
      public void load(String[] args)
      {
          if (null == args)
              return; //@todo should this have a return val or exception?
  
          try
          {
              input = args[0];
              output = args[2];
              gold = args[3];
          }
          catch (ArrayIndexOutOfBoundsException  aioobe)
          {
              // No-op, leave remaining items as default
          }
      }
  
  }  // end of class FileDatalet
  
  
  
  
  1.1                  xml-xalan/test/java/src/org/apache/qetest/FileTestlet.java
  
  Index: FileTestlet.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001-2002 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:  
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xalan" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 2000, Lotus
   * Development Corporation., http://www.lotus.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package org.apache.qetest;
  
  import java.io.File;
  import java.util.Hashtable;
  
  /**
   * Testlet superclass for testing URI or file based resources.
   *
   * This class is broken up into common worker methods to make 
   * subclassing easier for alternate testing algoritims.  
   * Individual subclasses may be implemented to test various 
   * programs that somehow can be tested by taking an input file 
   * and processing it, creating an output file, and then comparing 
   * the output to a known good gold file.
   *
   * @author Shane_Curcuru@us.ibm.com
   * @version $Id: FileTestlet.java,v 1.1 2002/03/05 21:25:32 curcuru Exp $
   */
  public class FileTestlet extends TestletImpl
  {
      // Initialize our classname for TestletImpl's main() method
      static { thisClassName = "org.apache.qetest.FileTestlet"; }
  
      // Initialize our defaultDatalet
      { defaultDatalet = (Datalet)new FileDatalet(); }
  
      /**
       * Accesor method for a brief description of this test.  
       *
       * @return String describing what this FileTestlet does.
       */
      public String getDescription()
      {
          return "FileTestlet";
      }
  
  
      /**
       * Run this FileTestlet: execute it's test and return.
       *
       * Calls various worker methods to perform the basic steps of:
       * initDatalet, testDatalet, checkDatalet;  
       * catch... {handleException}
       *
       * @param Datalet to use as data point for the test.
       */
      public void execute(Datalet d)
  	{
          // Ensure we have the correct kind of datalet
          FileDatalet datalet = null;
          try
          {
              datalet = (FileDatalet)d;
          }
          catch (ClassCastException e)
          {
              logger.checkErr("Datalet provided is not a FileDatalet; cannot continue with " + d);
              return;
          }
  
          // Perform any general setup needed...
          if (!initDatalet(datalet))
              return;
              
          try
          {
              // Perform the operation on the product under test..
              testDatalet(datalet);
  
              // ...and compare with gold data
              checkDatalet(datalet);
          }
          // Handle any exceptions from the testing
          catch (Throwable t)
          {
              handleException(datalet, t);
              return;
          }
  	}
  
  
      /** 
       * Worker method to perform any initialization needed.  
       *
       * Subclasses might pre-verify the existence of the input and 
       * gold files or delete any pre-existing outputs in the 
       * datalet before testing.
       *
       * @param datalet to test with
       * @return true if OK, false if test should be aborted; if 
       * false, this method must log a fail or error
       */
      protected boolean initDatalet(FileDatalet datalet)
      {
          //@todo validate our Datalet - ensure it has valid 
          //  and/or existing files available.
  
          // Cleanup outName only if asked to - delete the file on disk
          // Optimization: this takes extra time and often is not 
          //  needed, so only do this if the option is set
          if ("true".equalsIgnoreCase(datalet.getOptions().getProperty("deleteOutFile")))
          {
              String output = datalet.getOutput();
              try
              {
                  boolean btmp = (new File(output)).delete();
                  logger.logMsg(Logger.TRACEMSG, "Deleting OutFile of::" + output
                                       + " status: " + btmp);
              }
              catch (SecurityException se)
              {
                  logger.logMsg(Logger.WARNINGMSG, "Deleting OutFile of::" + output
                                         + " threw: " + se.toString());
              }
          }
          return true;
      }
  
  
      /** 
       * Worker method to actually perform the test operation.  
       *
       * Subclasses must (obviously) override this.  They should 
       * perform whatever actions are needed to process the input 
       * into an output, logging any status along the way.  
       * Note that validation of the output file is handled later 
       * in checkDatalet.
       *
       * @param datalet to test with
       * @throws allows any underlying exception to be thrown
       */
      protected void testDatalet(FileDatalet datalet)
              throws Exception
      {
          logger.logMsg(Logger.TRACEMSG, getCheckDescription(datalet));
  
          // Perform the test operation here - you must subclass this!
      }
  
  
      /** 
       * Worker method to validate output resource with gold.  
       *
       * Logs out applicable info while validating output file.  
       * Attempts to use datalet.getOptions.get("fileCheckerImpl")
       * or datalet.getOptions.getProperty("fileChecker") to get 
       * a CheckService for the output; if that fails, it uses a 
       * default QetestFactory.newCheckService().
       *
       * @param datalet to test with
       * @throws allows any underlying exception to be thrown
       */
      protected void checkDatalet(FileDatalet datalet)
              throws Exception
      {
          // See if the datalet already has a fileChecker to use...
          CheckService fileChecker = (CheckService)datalet.getOptions().get("fileCheckerImpl");
          // ...if not, look for a default classname to use...
          if (null == fileChecker)
          {
              String clazzName = datalet.getOptions().getProperty("fileChecker");
              if (!(null == clazzName))
              {
                  // ...find and create a class of the default classname given
                  Class fClazz = QetestUtils.testClassForName(clazzName, QetestUtils.defaultPackages, null);
                  fileChecker = (CheckService)fClazz.newInstance();
              }
              else
              {
                  //...If all else failed, simply get a default one from the factory
                  fileChecker = QetestFactory.newCheckService(logger, QetestFactory.TYPE_FILES);
              }
              // Apply any testing options to the fileChecker
              fileChecker.applyAttributes(datalet.getOptions());    
          }
  
          int result = fileChecker.check(logger,
                                   new File(datalet.getOutput()), 
                                   new File(datalet.getGold()), 
                                   getCheckDescription(datalet));
  
          //@todo if needed, we can put additional processing here 
          //  to output special logging in case of results that are fail                                 
      }
  
  
      /** 
       * Worker method to validate or log exceptions thrown by testDatalet.  
       *
       * Provided so subclassing is simpler; our implementation merely 
       * calls checkErr and logs the exception.
       *
       * @param datalet to test with
       * @param e Throwable that was thrown
       */
      protected void handleException(FileDatalet datalet, Throwable t)
      {
          // Put the logThrowable first, so it appears before 
          //  the Fail record, and gets color-coded
          logger.logThrowable(Logger.ERRORMSG, t, getCheckDescription(datalet) + " threw");
          logger.checkErr(getCheckDescription(datalet) 
                           + " threw: " + t.toString());
      }
  
  
      /** 
       * Worker method to construct a description.  
       *
       * Simply concatenates useful info to override getDescription().
       *
       * @param datalet to test with
       * @return simple concatenation of our desc and datalet's desc
       */
      protected String getCheckDescription(FileDatalet datalet)
      {
          return getDescription() 
                  + ": "
                  + datalet.getDescription();
      }
  }  // end of class FileTestlet
  
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: xalan-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xalan-cvs-help@xml.apache.org