1 18 19 package org.apache.jmeter.assertions; 20 21 import java.io.ByteArrayInputStream ; 22 import java.io.ByteArrayOutputStream ; 23 import java.io.FileWriter ; 24 import java.io.IOException ; 25 import java.io.PrintWriter ; 26 import java.io.Serializable ; 27 import java.io.StringWriter ; 28 import java.text.MessageFormat ; 29 30 import org.apache.jmeter.samplers.SampleResult; 31 import org.apache.jmeter.testelement.AbstractTestElement; 32 import org.apache.jmeter.testelement.property.BooleanProperty; 33 import org.apache.jmeter.testelement.property.LongProperty; 34 import org.apache.jmeter.testelement.property.StringProperty; 35 import org.apache.jmeter.util.JMeterUtils; 36 import org.apache.jorphan.logging.LoggingManager; 37 import org.apache.log.Logger; 38 import org.w3c.tidy.Node; 39 import org.w3c.tidy.Tidy; 40 41 44 public class HTMLAssertion extends AbstractTestElement implements Serializable , Assertion { 45 46 public static final String DEFAULT_DOCTYPE = "omit"; 48 public static final String DOCTYPE_KEY = "html_assertion_doctype"; 49 public static final String ERRORS_ONLY_KEY = "html_assertion_errorsonly"; 50 public static final String ERROR_THRESHOLD_KEY = "html_assertion_error_threshold"; 51 public static final String WARNING_THRESHOLD_KEY = "html_assertion_warning_threshold"; 52 public static final String FORMAT_KEY = "html_assertion_format"; 53 public static final String FILENAME_KEY = "html_assertion_filename"; 54 55 transient private static Logger log = LoggingManager.getLoggerForClass(); 57 58 61 public HTMLAssertion() { 62 log.debug("HTMLAssertion(): called"); 63 } 64 65 70 public AssertionResult getResult(SampleResult inResponse) { 71 log.debug("HTMLAssertions.getResult() called"); 72 73 AssertionResult result = new AssertionResult(); 75 76 if (inResponse.getResponseData() == null) { 77 return setResultForNull(result); 78 } 79 80 result.setFailure(false); 81 82 Tidy tidy = null; 84 try { 85 log.debug("HTMLAssertions.getResult(): Setup tidy ..."); 86 log.debug("doctype: " + getDoctype()); 87 log.debug("errors only: " + isErrorsOnly()); 88 log.debug("error threshold: " + getErrorThreshold()); 89 log.debug("warning threshold: " + getWarningThreshold()); 90 log.debug("html mode: " + isHTML()); 91 log.debug("xhtml mode: " + isXHTML()); 92 log.debug("xml mode: " + isXML()); 93 tidy = new Tidy(); 94 tidy.setCharEncoding(org.w3c.tidy.Configuration.UTF8); 95 tidy.setQuiet(false); 96 tidy.setShowWarnings(true); 97 tidy.setOnlyErrors(isErrorsOnly()); 98 tidy.setDocType(getDoctype()); 99 if (isXHTML()) { 100 tidy.setXHTML(true); 101 } else if (isXML()) { 102 tidy.setXmlTags(true); 103 } 104 log.debug("err file: " + getFilename()); 105 tidy.setErrfile(getFilename()); 106 107 if (log.isDebugEnabled()) { 108 log.debug("getParser : tidy parser created - " + tidy); 109 } 110 log.debug("HTMLAssertions.getResult(): Tidy instance created!"); 111 112 } catch (Exception e) { 113 log.error("Unable to instantiate tidy parser", e); 114 result.setFailure(true); 115 result.setFailureMessage("Unable to instantiate tidy parser"); 116 return result; 118 } 119 120 122 try { 123 log.debug("HTMLAssertions.getResult(): start parsing with tidy ..."); 124 125 StringWriter errbuf = new StringWriter (); 126 tidy.setErrout(new PrintWriter (errbuf)); 127 ByteArrayOutputStream os = new ByteArrayOutputStream (); 129 log.debug("Start : parse"); 130 Node node = tidy.parse(new ByteArrayInputStream (inResponse.getResponseData()), os); 131 if (log.isDebugEnabled()) { 132 log.debug("node : " + node); 133 } 134 log.debug("End : parse"); 135 log.debug("HTMLAssertions.getResult(): parsing with tidy done!"); 136 log.debug("Output: " + os.toString()); 137 138 writeOutput(errbuf.toString()); 140 141 if ((tidy.getParseErrors() > getErrorThreshold()) || (!isErrorsOnly() && (tidy.getParseWarnings() > getWarningThreshold()))) { 143 log.debug("HTMLAssertions.getResult(): errors/warnings detected:"); 144 log.debug(errbuf.toString()); 145 result.setFailure(true); 146 result.setFailureMessage(MessageFormat.format("Tidy Parser errors: " + tidy.getParseErrors() + " (allowed " + getErrorThreshold() + ") " + "Tidy Parser warnings: " + tidy.getParseWarnings() + " (allowed " + getWarningThreshold() + ")", new Object [0])); 147 149 } else if ((tidy.getParseErrors() > 0) || (tidy.getParseWarnings() > 0)) { 150 log.debug("HTMLAssertions.getResult(): there were errors/warnings but threshold to high"); 152 result.setFailure(false); 153 } else { 154 log.debug("HTMLAssertions.getResult(): no errors/warnings detected:"); 156 result.setFailure(false); 157 } 158 159 } catch (Exception e) { 160 log.warn("Cannot parse result content", e); 162 result.setFailure(true); 163 result.setFailureMessage(e.getMessage()); 164 } 165 return result; 166 } 167 168 172 private void writeOutput(String inOutput) { 173 String lFilename = getFilename(); 174 175 if ((lFilename != null) && (!"".equals(lFilename.trim()))) { 177 FileWriter lOutputWriter = null; 178 try { 179 180 lOutputWriter = new FileWriter (lFilename, false); 182 183 lOutputWriter.write(inOutput); 185 186 lOutputWriter.flush(); 188 189 log.debug("writeOutput() -> output successfully written to file " + lFilename); 190 191 } catch (IOException ex) { 192 log.warn("writeOutput() -> could not write output to file " + lFilename, ex); 193 } finally { 194 if (lOutputWriter != null) { 196 try { 197 lOutputWriter.close(); 198 } catch (Exception e) { 199 } 200 } 201 } 202 } 203 } 204 205 209 protected AssertionResult setResultForNull(AssertionResult inResult) { 210 inResult.setError(false); 211 inResult.setFailure(true); 212 inResult.setFailureMessage("Response was null"); 213 return inResult; 214 } 215 216 220 public String getDoctype() { 221 return getPropertyAsString(DOCTYPE_KEY); 222 } 223 224 228 public boolean isErrorsOnly() { 229 return getPropertyAsBoolean(ERRORS_ONLY_KEY); 230 } 231 232 236 public long getErrorThreshold() { 237 return getPropertyAsLong(ERROR_THRESHOLD_KEY); 238 } 239 240 244 public long getWarningThreshold() { 245 return getPropertyAsLong(WARNING_THRESHOLD_KEY); 246 } 247 248 252 public void setDoctype(String inDoctype) { 253 if ((inDoctype == null) || (inDoctype.trim().equals(""))) { 254 setProperty(new StringProperty(DOCTYPE_KEY, DEFAULT_DOCTYPE)); 255 } else { 256 setProperty(new StringProperty(DOCTYPE_KEY, inDoctype)); 257 } 258 } 259 260 264 public void setErrorsOnly(boolean inErrorsOnly) { 265 setProperty(new BooleanProperty(ERRORS_ONLY_KEY, inErrorsOnly)); 266 } 267 268 272 public void setErrorThreshold(long inErrorThreshold) { 273 if (inErrorThreshold < 0L) { 274 throw new IllegalArgumentException (JMeterUtils.getResString("argument_must_not_be_negative")); 275 } 276 if (inErrorThreshold == Long.MAX_VALUE) { 277 setProperty(new LongProperty(ERROR_THRESHOLD_KEY, 0)); 278 } else { 279 setProperty(new LongProperty(ERROR_THRESHOLD_KEY, inErrorThreshold)); 280 } 281 } 282 283 287 public void setWarningThreshold(long inWarningThreshold) { 288 if (inWarningThreshold < 0L) { 289 throw new IllegalArgumentException (JMeterUtils.getResString("argument_must_not_be_negative")); 290 } 291 if (inWarningThreshold == Long.MAX_VALUE) { 292 setProperty(new LongProperty(WARNING_THRESHOLD_KEY, 0)); 293 } else { 294 setProperty(new LongProperty(WARNING_THRESHOLD_KEY, inWarningThreshold)); 295 } 296 } 297 298 301 public void setHTML() { 302 setProperty(new LongProperty(FORMAT_KEY, 0)); 303 } 304 305 309 public boolean isHTML() { 310 return getPropertyAsLong(FORMAT_KEY) == 0; 311 } 312 313 316 public void setXHTML() { 317 setProperty(new LongProperty(FORMAT_KEY, 1)); 318 } 319 320 324 public boolean isXHTML() { 325 return getPropertyAsLong(FORMAT_KEY) == 1; 326 } 327 328 331 public void setXML() { 332 setProperty(new LongProperty(FORMAT_KEY, 2)); 333 } 334 335 339 public boolean isXML() { 340 return getPropertyAsLong(FORMAT_KEY) == 2; 341 } 342 343 347 public String getFilename() { 348 return getPropertyAsString(FILENAME_KEY); 349 } 350 351 355 public void setFilename(String inName) { 356 setProperty(FILENAME_KEY, inName); 357 } 358 } 359 | Popular Tags |