public inbox for mauve-discuss@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] xml output from mauve
@ 2004-09-17 21:20 Noa Resare
  2004-09-18 20:47 ` [PATCH] xml output from mauve (updated) Noa Resare
  0 siblings, 1 reply; 4+ messages in thread
From: Noa Resare @ 2004-09-17 21:20 UTC (permalink / raw)
  To: mauve-discuss

[-- Attachment #1: Type: text/plain, Size: 985 bytes --]

Hello friends

I started hacking on kaffe a few days ago, and this lead me to looking
at mauve. While thinking about writing some scripts that do fun stuff
with the output from mauve test runs and had a look at the perl script
that lives in kaffe cvs I came to the conclusion that the mauve output
wasn't as easy to parse as I wanted it to be.

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.

Note that since this patch touches Makefile.am autoreconf should be re-
run also and the generated changes should go into cvs.

Where should I add documentation about this?

cheers/noa

-- 
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

[-- Attachment #2: mauve-xmlout.patch --]
[-- Type: text/x-patch, Size: 14105 bytes --]

diff -urN mauve.vanilla/ChangeLog mauve/ChangeLog
--- mauve.vanilla/ChangeLog	2004-09-17 21:39:53.000000000 +0200
+++ mauve/ChangeLog	2004-09-17 23:04:50.477983188 +0200
@@ -1,3 +1,10 @@
+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
+
 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.509889216 +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-17 22:43:52.508012163 +0200
@@ -0,0 +1,106 @@
+// 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>" + failures[i] + "</failure>\n");
+
+	if (tr.getException() != null)
+	  {
+	    Throwable t = tr.getException();
+	    out.write("    <exception class='" + t.getClass().getName() +
+		    "'>\n      <reason>" + tr.getExceptionMessage() +
+		    "</reason>\n      <message>" + t.getMessage() +
+		    "</message>\n    </exception>\n");
+	  }
+	if (failures.length > 0 || tr.getException() != null) 
+	  out.write("  </testresult>\n");
+      }
+    out.write("</testreport>\n");
+    out.close();
+  }
+}
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.529576676 +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.836605670 +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

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] xml output from mauve (updated)
  2004-09-17 21:20 [PATCH] xml output from mauve Noa Resare
@ 2004-09-18 20:47 ` Noa Resare
  2004-09-19 21:51   ` Mark Wielaard
  0 siblings, 1 reply; 4+ messages in thread
From: Noa Resare @ 2004-09-18 20:47 UTC (permalink / raw)
  To: mauve-discuss

[-- Attachment #1: Type: text/plain, Size: 774 bytes --]

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

[-- Attachment #2: mauve-xmlout2.patch --]
[-- Type: text/x-patch, Size: 14599 bytes --]

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 &lt; &gt; and &amp; 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("&", "&amp;");
+    str = str.replaceAll("<", "&lt;");
+    str = str.replaceAll(">", "&gt;");
+    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

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] xml output from mauve (updated)
  2004-09-18 20:47 ` [PATCH] xml output from mauve (updated) Noa Resare
@ 2004-09-19 21:51   ` Mark Wielaard
  2004-09-20  6:48     ` Noa Resare
  0 siblings, 1 reply; 4+ messages in thread
From: Mark Wielaard @ 2004-09-19 21:51 UTC (permalink / raw)
  To: Noa Resare; +Cc: mauve-discuss

[-- Attachment #1: Type: text/plain, Size: 1174 bytes --]

Hi,

On Sat, 2004-09-18 at 22:47, Noa Resare wrote:
> 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.
>
> ps. a test result diff program (that looks for regressions) in very
> rough form is available from http://resare.com/noa/testdiff

Very nice!

Maybe this should be written as a new XMLTestHarness class?
Although I don't really see a problem with just tagging it on the
SimpleTestHarness. Opinions anybody?

Are you sure the XML escaping is always correct?
Maybe it doesn't really matter in this case, but you might want to look
whether GNU Kawa (http://www.gnu.org/software/kawa/) has something
appropriate in the gnu.xml package.

Thanks for doing this. Having easy to compare mauve results is very
valuable.

Cheers,

Mark

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] xml output from mauve (updated)
  2004-09-19 21:51   ` Mark Wielaard
@ 2004-09-20  6:48     ` Noa Resare
  0 siblings, 0 replies; 4+ messages in thread
From: Noa Resare @ 2004-09-20  6:48 UTC (permalink / raw)
  To: mauve-discuss

[-- Attachment #1: Type: text/plain, Size: 1785 bytes --]

On sön, 2004-09-19 at 23:51 +0200, Mark Wielaard wrote:
> Hi,
> 
> On Sat, 2004-09-18 at 22:47, Noa Resare wrote:
> > 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.
> >
> > ps. a test result diff program (that looks for regressions) in very
> > rough form is available from http://resare.com/noa/testdiff
> 
> Very nice!
> 
> Maybe this should be written as a new XMLTestHarness class?
> Although I don't really see a problem with just tagging it on the
> SimpleTestHarness. Opinions anybody?

Maybe that would be better. However, I don't think the current solution
is horribly ugly and I'd rather use that time trying to contribute to
fixing jvm bugs. I'm open to suggestions though :)

> Are you sure the XML escaping is always correct?
> Maybe it doesn't really matter in this case, but you might want to look
> whether GNU Kawa (http://www.gnu.org/software/kawa/) has something
> appropriate in the gnu.xml package.

I'm think escaping is correct except for the case when any of the
properties used to identify a jvm in the output header or a class name
contains a single quote ('). The attached patch fixes this and applies
on top of my previous patch. 

/noa

-- 
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

[-- Attachment #2: mauve-xmlout-escape.patch --]
[-- Type: text/x-patch, Size: 2258 bytes --]

--- mauve/gnu/testlet/TestReport.java.vanilla	2004-09-20 08:20:22.653300790 +0200
+++ mauve/gnu/testlet/TestReport.java	2004-09-20 08:43:54.765740326 +0200
@@ -68,18 +68,19 @@
     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");
+	    escAttrib(systemProperties.get("java.vm.vendor")) +
+	    "'\n    version='" +
+	    escAttrib(systemProperties.get("java.vm.version")) + "' \n" +
+	    "    os='" + escAttrib(systemProperties.get("os.name")) + " " +
+	    escAttrib(systemProperties.get("os.version")) + " " +
+	    escAttrib(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() +
+	out.write("  <testresult testlet='" + escAttrib(tr.getTestletName()) +
 		 "' passcount='" + tr.getPassCount());
 	if (failures.length > 0 || tr.getException() != null)
 	  out.write("'>\n");
@@ -92,7 +93,8 @@
 	if (tr.getException() != null)
 	  {
 	    Throwable t = tr.getException();
-	    out.write("    <exception class='" + t.getClass().getName() +
+	    out.write("    <exception class='" +
+                    escAttrib(t.getClass().getName()) +
 		    "'>\n      <reason>" + esc(tr.getExceptionMessage()) +
 		    "</reason>\n      <message>" + esc(t.getMessage()) +
 		    "</message>\n    </exception>\n");
@@ -117,4 +119,16 @@
     str = str.replaceAll(">", "&gt;");
     return str;
   }
+
+  /**
+   * Escapes single quotes in string by prepending a backslash.
+   */
+  private String escAttrib(Object obj)
+  {
+    if (obj == null)
+      return null;
+    String str = (String)obj;
+    str = str.replaceAll("'", "\\'");
+    return str;
+  }
 }

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2004-09-20  6:48 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-09-17 21:20 [PATCH] xml output from mauve Noa Resare
2004-09-18 20:47 ` [PATCH] xml output from mauve (updated) Noa Resare
2004-09-19 21:51   ` Mark Wielaard
2004-09-20  6:48     ` Noa Resare

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).