This is the mail archive of the
mauve-discuss@sources.redhat.com
mailing list for the Mauve project.
Re: [PATCH] xml output from mauve (updated)
- From: Noa Resare <noa at resare dot com>
- To: mauve-discuss at sources dot redhat dot com
- Date: Sat, 18 Sep 2004 22:47:25 +0200
- Subject: Re: [PATCH] xml output from mauve (updated)
- References: <1095456018.2660.33.camel@marit.resare.com>
On fre, 2004-09-17 at 23:20 +0200, Noa Resare wrote:
> So, I did some afternoon hacking and came up with this patch to mauve
> that outputs the results from a mauve run into an xml file for easy
> parsing. I haven't written anything that does anything with the output
> yet but I thought I could share this with you anyway.
>
This updated patch handles mauve output containing & < and > properly.
It also adds Makefile.am to the changelog entry.
/noa
ps. a test result diff program (that looks for regressions) in very
rough form is available from http://resare.com/noa/testdiff
--
And the lions ate the christians and the christians burned the witches,
and even I am out of explanations -- Ola Salo
gpg fingerprint: F3C4 AC90 B885 FE15 344B 4D05 220B 7662 A190 6F09
diff -urN mauve.vanilla/ChangeLog mauve/ChangeLog
--- mauve.vanilla/ChangeLog 2004-09-17 21:39:53.000000000 +0200
+++ mauve/ChangeLog 2004-09-18 11:08:11.215563917 +0200
@@ -1,3 +1,11 @@
+2004-09-17 Noa Resare <noa@resare.com>
+
+ * gnu/testlet/TestResult.java: New file.
+ * gnu/testlet/TestReport.java: New file.
+ * gnu/testlet/SimpleTestHarness.java:
+ support for writing test results to an xml file
+ * Makefile.in: add new files to harness_file
+
2004-09-01 Tom Tromey <tromey@redhat.com>
* gnu/testlet/java/lang/reflect/sub/InvokeHelper.java: New file.
diff -urN mauve.vanilla/gnu/testlet/SimpleTestHarness.java mauve/gnu/testlet/SimpleTestHarness.java
--- mauve.vanilla/gnu/testlet/SimpleTestHarness.java 2004-09-17 21:39:54.000000000 +0200
+++ mauve/gnu/testlet/SimpleTestHarness.java 2004-09-17 23:16:26.000000000 +0200
@@ -42,6 +42,8 @@
private boolean results_only=false;
private String description;
private String last_check;
+ private TestReport report = null;
+ private TestResult currentResult = null;
private final String getDescription (String pf)
{
@@ -60,6 +62,8 @@
if (!result)
{
String desc;
+ currentResult.addFail((last_check == null ? "" : last_check) +
+ " (number " + (count + 1) + ")");
if (!expected_xfails.contains(desc = getDescription("FAIL")))
{
System.out.println(desc);
@@ -71,17 +75,21 @@
++xfailures;
}
}
- else if (verbose || results_only)
+ else
{
- if (expected_xfails.contains(getDescription("FAIL")))
+ currentResult.addPass();
+ if (verbose || results_only)
{
- System.out.println(getDescription("XPASS"));
- ++xpasses;
- }
- else
- {
- System.out.println(getDescription("PASS"));
- }
+ if (expected_xfails.contains(getDescription("FAIL")))
+ {
+ System.out.println(getDescription("XPASS"));
+ ++xpasses;
+ }
+ else
+ {
+ System.out.println(getDescription("PASS"));
+ }
+ }
}
++count;
++total;
@@ -221,6 +229,8 @@
// Try to ensure we start off with a reasonably clean slate.
System.gc();
System.runFinalization();
+
+ currentResult = new TestResult(name);
checkPoint(null);
@@ -238,6 +248,7 @@
catch (Throwable ex)
{
String d = "FAIL: uncaught exception loading " + name;
+ currentResult.addException(ex, "failed loading class " + name);
if (verbose)
d += ": " + ex.toString();
System.out.println(d);
@@ -261,10 +272,11 @@
catch (Throwable ex)
{
removeSecurityManager();
+ String s = (last_check == null ? "" : "\"" + last_check +
+ "\" number " + (count + 1));
String d = ("FAIL: " + description + ": uncaught exception at " +
- ((last_check == null) ? "" :
- ("\"" + last_check + "\"")) +
- " number " + (count + 1));
+ s);
+ currentResult.addException(ex, "uncaught exception at " + s);
if (verbose)
d += ": " + ex.toString();
System.out.println(d);
@@ -273,6 +285,8 @@
++total;
}
}
+ if (report != null)
+ report.addTestResult(currentResult);
}
protected int done ()
@@ -293,15 +307,16 @@
protected SimpleTestHarness (boolean verbose, boolean debug)
{
- this(verbose, debug, false);
+ this(verbose, debug, false, null);
}
protected SimpleTestHarness (boolean verbose, boolean debug,
- boolean results_only)
+ boolean results_only, TestReport report)
{
this.verbose = verbose;
this.debug = debug;
this.results_only = results_only;
+ this.report = report;
try
{
@@ -327,6 +342,8 @@
boolean debug = false;
boolean results_only = false;
String file = null;
+ String xmlfile = null;
+ TestReport report = null;
int i;
for (i = 0; i < args.length; i++)
@@ -346,12 +363,21 @@
throw new RuntimeException("No file path after '-file'. Exit");
file = args[i];
}
+ else if (args[i].equals("-xmlout"))
+ {
+ if (++i >= args.length)
+ throw new RuntimeException("No file path after '-xmlout'.");
+ xmlfile = args[i];
+ }
else
break;
}
+ if (xmlfile != null) {
+ report = new TestReport(System.getProperties());
+ }
SimpleTestHarness harness =
- new SimpleTestHarness(verbose, debug, results_only);
+ new SimpleTestHarness(verbose, debug, results_only, report);
BufferedReader r = null;
if (file != null)
@@ -385,9 +411,22 @@
System.out.println("----");
harness.runtest(cname);
}
+
+ int retval = harness.done();
- System.exit(harness.done());
+ if (report != null)
+ {
+ File f = new File(xmlfile);
+ try
+ {
+ report.writeXml(f);
+ }
+ catch (IOException e)
+ {
+ throw new Error("Failed to write data to xml file: " +
+ e.getMessage());
+ }
+ }
+ System.exit(retval);
}
}
-
-
diff -urN mauve.vanilla/gnu/testlet/TestReport.java mauve/gnu/testlet/TestReport.java
--- mauve.vanilla/gnu/testlet/TestReport.java 1970-01-01 01:00:00.000000000 +0100
+++ mauve/gnu/testlet/TestReport.java 2004-09-18 11:21:34.134118692 +0200
@@ -0,0 +1,120 @@
+// Copyright (c) 2004 Noa Resare.
+// Written by Noa Resre <noa@resare.com>
+
+// This file is part of Mauve.
+
+// Mauve is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// Mauve is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Mauve; see the file COPYING. If not, write to
+// the Free Software Foundation, 59 Temple Place - Suite 330,
+// Boston, MA 02111-1307, USA.
+
+package gnu.testlet;
+
+import java.util.*;
+import java.io.*;
+
+/**
+ * A TestReport represents all the results of a test run. The TestReport
+ * can be serialized to xml with the writeXml method.
+ */
+public class TestReport
+{
+ private Properties systemProperties;
+ private List testResults;
+
+ private static final String ENCODING = "UTF-8";
+
+
+ /**
+ * Creates a new TestReport object with jvmName and jvmVersion set.
+ *
+ * @param systemProperties the Properties object returned from
+ * System.getProperties() of the jvm that is tested.
+ */
+ public TestReport(Properties systemProperties)
+ {
+ this.systemProperties = systemProperties;
+ this.testResults = new ArrayList();
+ }
+
+ /**
+ * Adds a TestResult object to this TestReport.
+ *
+ * @param result the TestResult object to be added
+ */
+ public void addTestResult(TestResult result)
+ {
+ this.testResults.add(result);
+ }
+
+ /**
+ * Writes a representation of this TestReport object in xml format.
+ *
+ * @param f the file where the xml stream gets written
+ */
+ public void writeXml(File f)
+ throws IOException
+ {
+ Writer out = new OutputStreamWriter(new FileOutputStream(f), ENCODING);
+ out.write("<?xml version='1.0' encoding='" + ENCODING + "'?>\n");
+ out.write("<testreport version='0.1'>\n <jvm name='" +
+ systemProperties.get("java.vm.vendor") + "'\n version='" +
+ systemProperties.get("java.vm.version") + "' \n" +
+ " os='" + systemProperties.get("os.name") + " " +
+ systemProperties.get("os.version") + " " +
+ systemProperties.get("os.arch") + "' />\n");
+ Collections.sort(testResults);
+ Iterator results = testResults.iterator();
+ while (results.hasNext())
+ {
+ TestResult tr = (TestResult) results.next();
+ String[] failures = tr.getFailMessags();
+ out.write(" <testresult testlet='" + tr.getTestletName() +
+ "' passcount='" + tr.getPassCount());
+ if (failures.length > 0 || tr.getException() != null)
+ out.write("'>\n");
+ else
+ out.write("'/>\n");
+
+ for (int i = 0; i < failures.length; i++)
+ out.write(" <failure>" + esc(failures[i]) + "</failure>\n");
+
+ if (tr.getException() != null)
+ {
+ Throwable t = tr.getException();
+ out.write(" <exception class='" + t.getClass().getName() +
+ "'>\n <reason>" + esc(tr.getExceptionMessage()) +
+ "</reason>\n <message>" + esc(t.getMessage()) +
+ "</message>\n </exception>\n");
+ }
+ if (failures.length > 0 || tr.getException() != null)
+ out.write(" </testresult>\n");
+ }
+ out.write("</testreport>\n");
+ out.close();
+ }
+
+ /**
+ * Escapes chars < > and & in str so that the result is
+ * suitable for inclusion in an xml stream.
+ */
+ private String esc(String str)
+ {
+ if (str == null)
+ return null;
+ str = str.replaceAll("&", "&");
+ str = str.replaceAll("<", "<");
+ str = str.replaceAll(">", ">");
+ return str;
+ }
+}
diff -urN mauve.vanilla/gnu/testlet/TestResult.java mauve/gnu/testlet/TestResult.java
--- mauve.vanilla/gnu/testlet/TestResult.java 1970-01-01 01:00:00.000000000 +0100
+++ mauve/gnu/testlet/TestResult.java 2004-09-17 22:44:10.000000000 +0200
@@ -0,0 +1,144 @@
+// Copyright (c) 2004 Noa Resare.
+// Written by Noa Resre <noa@resare.com>
+
+// This file is part of Mauve.
+
+// Mauve is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// Mauve is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Mauve; see the file COPYING. If not, write to
+// the Free Software Foundation, 59 Temple Place - Suite 330,
+// Boston, MA 02111-1307, USA.
+
+package gnu.testlet;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * A TestResult object represents the results a run of one Testlet. TestResult
+ * objects are normally agregated in a TestReport. The natural ordering of
+ * TestResult is defined to be the same as the natural order of their
+ * respective testletName field.
+ */
+public class TestResult
+ implements Comparable
+{
+ private String testletName = null;
+ private int passCount = 0;
+ private List failMessages = new ArrayList();
+ private Throwable exception = null;
+ private String exceptionMessage = null;
+
+ /**
+ * Constructs a TestResult instance with testletName set to the given name.
+ *
+ * @param testletName the name of the testlet that produced this TestResult
+ */
+ public TestResult(String testletName)
+ {
+ if (testletName == null)
+ throw new IllegalArgumentException("testletName can not be null");
+ this.testletName = testletName;
+ }
+
+ /**
+ * Adds one to the counter of the number of tests that has passed. Should
+ * be called when a test passses.
+ */
+ public void addPass()
+ {
+ passCount++;
+ }
+
+ /**
+ * Adds a failure message identifying a failing test. Should be called when
+ * a test fails.
+ *
+ * @param message a String that identifies the test that failed inside
+ * this servlet
+ */
+ public void addFail(String message)
+ {
+ failMessages.add(message);
+ }
+
+ /**
+ * Adds an Exception and optional identification message to this TestResult
+ * object. Should be called when the instantiation or execution of a Testlet
+ * results in an exception.
+ *
+ * @param exception The exception that was thrown
+ * @param message A message that identifies the test that caused the
+ * exception to be thrown
+ */
+ public void addException(Throwable exception, String message)
+ {
+ if (this.exception != null)
+ throw new IllegalArgumentException("trying to add more than one " +
+ "exception to TestResult");
+ this.exception = exception;
+ this.exceptionMessage = message;
+ }
+
+ /**
+ * The number of tests that have preformed without failure or exceptions.
+ */
+ public int getPassCount()
+ {
+ return passCount;
+ }
+
+ /**
+ * An array of Strings that holds the identifying messages for all failed
+ * tests.
+ */
+ public String[] getFailMessags()
+ {
+ return (String[]) failMessages.toArray(new String[0]);
+ }
+
+ /**
+ * The name of the Testlet that this TestResult holds information about.
+ */
+ public String getTestletName()
+ {
+ return testletName;
+ }
+
+ /**
+ * If an Exception was thrown when the Testlet was instantiated or run it
+ * is returned, else null is returned.
+ */
+ public Throwable getException()
+ {
+ return exception;
+ }
+
+ /**
+ * If an Exception was thrown when the Testlet was instantiated or run,
+ * this String identifies what test (or other contition) caused the test.
+ */
+ public String getExceptionMessage()
+ {
+ return exceptionMessage;
+ }
+
+ /**
+ * Compares one TestResult object to another. TestResult objects compare
+ * the same as their testletName fields.
+ */
+ public int compareTo(Object o)
+ {
+ TestResult other = (TestResult)o;
+ return testletName.compareTo(other.testletName);
+ }
+}
diff -urN mauve.vanilla/Makefile.am mauve/Makefile.am
--- mauve.vanilla/Makefile.am 2004-09-17 21:39:54.000000000 +0200
+++ mauve/Makefile.am 2004-09-17 23:06:36.000000000 +0200
@@ -13,7 +13,9 @@
gnu/testlet/TestHarness.java gnu/testlet/Testlet.java \
gnu/testlet/TestSecurityManager.java \
gnu/testlet/TestSecurityManager2.java \
- gnu/testlet/ResourceNotFoundException.java
+ gnu/testlet/ResourceNotFoundException.java \
+ gnu/testlet/TestReport.java \
+ gnu/testlet/TestResult.java
## FIXME: leading space makes automake ignore this. Bleah.
include choices
BinÃrfilerna mauve.vanilla/.Makefile.am.swp och mauve/.Makefile.am.swp skiljer