From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6072 invoked by alias); 27 Nov 2003 02:51:59 -0000 Mailing-List: contact mauve-discuss-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: mauve-discuss-owner@sources.redhat.com Received: (qmail 6055 invoked from network); 27 Nov 2003 02:51:57 -0000 Received: from unknown (HELO mx1.redhat.com) (66.187.233.31) by sources.redhat.com with SMTP; 27 Nov 2003 02:51:57 -0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.11.6/8.11.6) with ESMTP id hAR2pvH03842 for ; Wed, 26 Nov 2003 21:51:57 -0500 Received: from dub.venge.net (sebastian-int.corp.redhat.com [172.16.52.221]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id hAR2puw15896 for ; Wed, 26 Nov 2003 21:51:56 -0500 To: mauve-discuss@sources.redhat.com Subject: JUnit integration From: graydon hoare Date: Thu, 27 Nov 2003 02:51:00 -0000 Message-ID: <874qwqjziy.fsf@dub.venge.net> User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.3 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-SW-Source: 2003-q4/txt/msg00003.txt.bz2 --=-=-= Content-length: 1225 hi, I've recently found myself somewhat unsatisfied with mauve, and have put together a list of changes I'd like to make. of course it's wildly optimistic, but, y'know, best to have unrealistic goals than no goals at all :) I posted it to classpath list the other day: http://mail.gnu.org/archive/html/classpath/2003-11/msg00184.html and have, since there was a generally non-hostile reception there, gone on to write up a couple bits of useful preparatory work: - a bridge class which connects classpath to JUnit ( see http://people.redhat.com/graydon/junit-mauve.png ) - a perl script which does what "choose" claims to do for mauve tests, only with some improvements (much faster, interprets Uses: lines correctly and recursively, etc) these are attached. but the more general question -- the next logical step in my mind -- is whether to start merging mauve into classpath so it configures and builds "naturally" as part of the day-to-day development cycle on classpath (using the classpath build dir, compiler and VM selection, for example, and running as the nominal "make check" for classpath). I'm wondering how taboo an idea that is, whether anyone would mind if I had a go at it. -graydon --=-=-= Content-Type: application/octet-stream Content-Disposition: attachment; filename=TestletSuite.java Content-length: 3536 // Copyright (c) 2003 Red Hat // Written by Graydon Hoare // 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.io.*; /** * * This class adapts older Mauve tests, based on the Testlet / TestHarness * interfaces, to JUnit's TestCase / TestSuite interfaces. The result is * that each Testlet runs as a single TestCase, and the complete collection * of all Testlets-mapped-to-TestCases is run as a TestSuite, itself a type * of TestCase. * * we use explicit package names in the source here because we are bridging * two packages with very similar vocabulary, and it helps clarify * intention. * */ public class TestletSuite extends junit.framework.TestSuite { private gnu.testlet.TestHarness harness; private static class JUnitHarness extends gnu.testlet.SimpleTestHarness { // override parts of gnu.testlet.SimpleTestHarness public void check (boolean result) { junit.framework.Assert.assertTrue (result); } public JUnitHarness() { super(false,false,false); } } // fill junit.framework.TestSuite with wrapped gnu.testlet.Testlets private static class TestletCase extends junit.framework.TestCase { private gnu.testlet.Testlet testlet; private gnu.testlet.TestHarness harness; public TestletCase (gnu.testlet.Testlet t, gnu.testlet.TestHarness h) { super(t.getClass ().getName ()); testlet = t; harness = h; } protected void runTest () { testlet.test (harness); } } public TestletSuite () { harness = new JUnitHarness (); try { BufferedReader r = new BufferedReader (new InputStreamReader (new FileInputStream (gnu.testlet.config.builddir + File.separator + "classes"))); while (true) { String name = null; name = r.readLine (); if (name == null) break; try { gnu.testlet.Testlet tl = (gnu.testlet.Testlet) Class.forName (name).newInstance (); this.addTest (new TestletCase (tl, harness)); } catch (Exception e) { System.err.println("Exception building testlet " + name + ": "); } } } catch (Exception e) { System.err.println("Exception building testlet suite: " + e); } } // this is for JUnit's graphical runners to hook in to the class public static junit.framework.Test suite () { return new TestletSuite (); } // this is for the command-line to hook into the class public static void main (String args[]) { junit.textui.TestRunner.run (suite ()); } } --=-=-= Content-Type: application/octet-stream Content-Disposition: attachment; filename=choose.pl Content-length: 4357 #!/usr/bin/perl -w # Copyright (c) 2003 Red Hat # Written by Graydon Hoare # 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. */ # Choose the tests we want to run. # Usage: choose.pl output-directory [tag] ... # Run in the source directory. # See README for information on tags. use File::Find; use Carp; use strict; my %tests_to_run = (); my %tags_to_find = (); my $basedir = 'gnu/testlet'; my @dirs = qw( java javax BinaryCompatibility ); my @file_patterns = (); sub scan_deps { my $filename = shift(@_); return if (exists($tests_to_run{$filename})); $tests_to_run{$filename} = 1; my @deps = (); open(FILE, $filename); while () { if (m@^// Uses: (.*)$@o) { my $uses = $1; my @uses = split(/\s+/, $uses); for my $used (@uses) { my $target = $File::Find::dir . '/' . $used . '.java'; -e $target || croak("missing 'Uses:' target $target, in $filename"); push @deps, $target; } } } close(FILE); for my $dep (@deps) { scan_deps($dep); } } sub finder { if ($File::Find::name =~ /.java$/o) { my $filename_matches = 0; my $tag_spec_matches = 0; if (not @file_patterns) { # no file patterns -> everything matches $filename_matches = 1; } else { my $simple_name = $File::Find::name; $simple_name =~ s@^$basedir/@@o; for my $pat (@file_patterns) { if (('!' . $simple_name) =~ /^$pat/) { $filename_matches = 0; } elsif ($simple_name =~ /^$pat/) { $filename_matches = 1; } } } if ($filename_matches) { if (not %tags_to_find) { # no tag patterns -> everything matches $tag_spec_matches = 1; } else { open(FILE, $File::Find::name); while () { if (m@^// Tags: (.*)$@o) { my $tags = $1; my @tags = split(/\s+/, $tags); for my $tag (@tags) { if ($tag eq 'not-a-test') { close(FILE); return; } } my $included_by_tag = 0; my $excluded_by_tag = 0; for my $tag (@tags) { if (length($tag) > 2 && substr($tag,0,1) eq '!' && exists($tags_to_find{substr($tag,1)})) { $excluded_by_tag = 1; } elsif (exists($tags_to_find{$tag})) { $included_by_tag = 1; } } if ($included_by_tag && (! $excluded_by_tag)) { $tag_spec_matches = 1; } } } close(FILE); } } # scan dependencies of this file if ($tag_spec_matches) { scan_deps($File::Find::name); } } } # main() croak "usage: choose [KEYS...]" unless @ARGV; my $outdir = shift(@ARGV); for my $arg (@ARGV) { if ($arg =~ /java/) { $arg =~ s@\.@/@; push @file_patterns, $arg; } else { $tags_to_find{$arg} = 1; } } # massage arguments if (not %tags_to_find || exists $tags_to_find{'JDK1.1'} || exists $tags_to_find{'JDK1.2'}) { $tags_to_find{'JDK1.1'} = 1; $tags_to_find{'JDK1.0'} = 1; } # search directories my @qualified_dirs = map { $basedir . '/' . $_; } @dirs; find({ 'no_chdir' => 1, 'wanted' => \&finder }, @qualified_dirs); # output results my $test = ''; open (CLASSES, ">$outdir/classes"); for $test (sort(keys(%tests_to_run))) { $test =~ s/.java$//o; $test =~ s@/@.@go; print CLASSES $test, "\n"; } close (CLASSES); open (CHOICES, ">$outdir/choices"); print CHOICES 'CHOICES='; for $test (sort(keys(%tests_to_run))) { print CHOICES $test, " \\\n"; } print CHOICES "\n"; print CHOICES 'SimpleTestHarness: '; for $test (sort(keys(%tests_to_run))) { $test =~ s/.java$/.o/o; print CHOICES $test, " \\\n"; } print CHOICES "\n"; close (CHOICES); --=-=-=--