1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 /* 19 * $Id$ 20 */ 21 22 package org.apache.qetest.xsl; 23 24 import java.io.File; 25 import java.util.Hashtable; 26 27 import org.apache.qetest.Datalet; 28 import org.apache.qetest.Logger; 29 30 /** 31 * Testlet for conformance testing of xsl stylesheet files using 32 * the MSXSL command line instead of a TransformWrapper. 33 * 34 * @author Shane_Curcuru@lotus.com 35 * @version $Id$ 36 */ 37 public class MSXSLTestlet extends CmdlineTestlet 38 { 39 // Initialize our classname for TestletImpl's main() method 40 static { thisClassName = "org.apache.qetest.xsl.MSXSLTestlet"; } 41 42 // Initialize our defaultDatalet 43 { defaultDatalet = (Datalet)new StylesheetDatalet(); } 44 45 /** 46 * Accesor method for a brief description of this test. 47 * 48 * @return String describing what this MSXSLTestlet does. 49 */ getDescription()50 public String getDescription() 51 { 52 return "MSXSLTestlet"; 53 } 54 55 56 /** 57 * Default Actual name of external program to call. 58 * @return msxsl, the MSXSL 4.0 command line. 59 */ getDefaultProgName()60 public String getDefaultProgName() 61 { 62 return "msxsl"; 63 } 64 65 66 /** 67 * Worker method to get list of arguments specific to this program. 68 * 69 * <p>Must be overridden for different processors, obviously. 70 * This implementation returns the args for Xalan-C TestXSLT</p> 71 * 72 * @param program path\name of program to Runtime.exec() 73 * @param defaultArgs any additional arguments to pass 74 * @return String array of arguments suitable to pass to 75 * Runtime.exec() 76 */ getProgramArguments(StylesheetDatalet datalet, String[] defaultArgs)77 public String[] getProgramArguments(StylesheetDatalet datalet, String[] defaultArgs) 78 { 79 final int NUMARGS = 6; 80 String[] args = new String[defaultArgs.length + NUMARGS]; 81 String progName = datalet.options.getProperty(OPT_PROGNAME, getDefaultProgName()); 82 String progPath = datalet.options.getProperty(OPT_PROGPATH); 83 if ((null != progPath) && (progPath.length() > 0)) 84 { 85 args[0] = progPath + File.separator + progName; 86 } 87 else 88 { 89 // Pesume the program is on the PATH already... 90 args[0] = progName; 91 } 92 93 // Default args for MSXSL 4.0 94 args[1] = datalet.xmlName; 95 args[2] = datalet.inputName; 96 args[3] = "-o"; // Write output to named file 97 args[4] = datalet.outputName; 98 args[5] = "-t"; // Show load and transformation timings 99 100 if (defaultArgs.length > 0) 101 System.arraycopy(defaultArgs, 0, args, NUMARGS, defaultArgs.length); 102 103 return args; 104 } 105 106 107 /** 108 * Worker method to evaluate the System.out/.err streams of 109 * a particular processor. 110 * 111 * Overridden to parse out -t timings from msxsl output. 112 * 113 * @param cmdline that was used for execProcess 114 * @param outBuf buffer from execProcess' System.out 115 * @param errBuf buffer from execProcess' System.err 116 * @param processReturnVal from execProcess 117 */ checkOutputStreams(String[] cmdline, StringBuffer outBuf, StringBuffer errBuf, int processReturnVal)118 protected void checkOutputStreams(String[] cmdline, StringBuffer outBuf, 119 StringBuffer errBuf, int processReturnVal) 120 { 121 Hashtable attrs = new Hashtable(); 122 attrs.put("program", cmdline[0]); 123 attrs.put("returnVal", String.valueOf(processReturnVal)); 124 125 StringBuffer buf = new StringBuffer(); 126 if ((null != errBuf) && (errBuf.length() > 0)) 127 { 128 buf.append("<system-err>"); 129 buf.append(errBuf); 130 buf.append("</system-err>\n"); 131 } 132 if ((null != outBuf) && (outBuf.length() > 0)) 133 { 134 buf.append("<system-out>"); 135 buf.append(outBuf); 136 buf.append("</system-out>\n"); 137 } 138 logger.logElement(Logger.INFOMSG, "checkOutputStreams", attrs, buf.toString()); 139 attrs = null; 140 buf = null; 141 142 try 143 { 144 final String SOURCE_LOAD = "Source document load time:"; 145 final String STYLESHEET_LOAD = "Stylesheet document load time:"; 146 final String STYLESHEET_COMPILE = "Stylesheet compile time:"; 147 final String STYLESHEET_EXECUTE = "Stylesheet execution time:"; 148 final String MILLISECONDS = "milliseconds"; 149 double sourceLoad; 150 double stylesheetLoad; 151 double stylesheetCompile; 152 double stylesheetExecute; 153 // Now actually parse the system-err stream for performance 154 // This is embarassingly messy, but I'm not investing 155 // more time here until I'm sure it'll be worth it 156 String tmp = errBuf.toString(); 157 String ms = null; 158 int tmpIdx = 0; 159 // Advance to source loading time 160 tmp = tmp.substring(tmp.indexOf(SOURCE_LOAD) + SOURCE_LOAD.length()); 161 // Time is spaces & numbers up to the 'milliseconds' marker 162 ms = tmp.substring(0, tmp.indexOf(MILLISECONDS)).trim(); 163 sourceLoad = Double.parseDouble(ms); 164 165 // Advance to stylesheet loading time 166 tmp = tmp.substring(tmp.indexOf(STYLESHEET_LOAD) + STYLESHEET_LOAD.length()); 167 // Time is spaces & numbers up to the 'milliseconds' marker 168 ms = tmp.substring(0, tmp.indexOf(MILLISECONDS)).trim(); 169 stylesheetLoad = Double.parseDouble(ms); 170 171 // Advance to stylesheet compile time 172 tmp = tmp.substring(tmp.indexOf(STYLESHEET_COMPILE) + STYLESHEET_COMPILE.length()); 173 // Time is spaces & numbers up to the 'milliseconds' marker 174 ms = tmp.substring(0, tmp.indexOf(MILLISECONDS)).trim(); 175 stylesheetCompile = Double.parseDouble(ms); 176 177 // Advance to stylesheet execute time 178 tmp = tmp.substring(tmp.indexOf(STYLESHEET_EXECUTE) + STYLESHEET_EXECUTE.length()); 179 // Time is spaces & numbers up to the 'milliseconds' marker 180 ms = tmp.substring(0, tmp.indexOf(MILLISECONDS)).trim(); 181 stylesheetExecute = Double.parseDouble(ms); 182 183 // Log out approximate timing data 184 // Log special performance element with our timing 185 attrs = new Hashtable(); 186 // UniqRunid is an Id that our TestDriver normally sets 187 // with some unique code, so that results analysis 188 // stylesheets can compare different test runs 189 attrs.put("UniqRunid", "runId;notImplemented-MSXSLTestlet"); 190 // processor is the 'flavor' of processor we're testing 191 attrs.put("processor", getDescription()); 192 // idref is the individual filename 193 attrs.put("idref", (new File(cmdline[2])).getName()); 194 // inputName is the actual name we gave to the processor 195 attrs.put("inputName", cmdline[2]); 196 attrs.put("iterations", new Integer(1)); 197 attrs.put("sourceLoad", new Double(sourceLoad)); 198 attrs.put("stylesheetLoad", new Double(stylesheetLoad)); 199 attrs.put("stylesheetCompile", new Double(stylesheetCompile)); 200 attrs.put("stylesheetExecute", new Double(stylesheetExecute)); 201 202 logger.logElement(Logger.STATUSMSG, "perf", attrs, "PItr;"); 203 } 204 catch (Exception e) 205 { 206 logger.logThrowable(Logger.WARNINGMSG, e, "checkOutputStreams threw"); 207 } 208 } 209 } // end of class MSXSLTestlet 210 211