From owner-p4-projects@FreeBSD.ORG Wed Mar 19 18:42:43 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id A1830106566B; Wed, 19 Mar 2008 18:42:43 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 60DBE1065675 for ; Wed, 19 Mar 2008 18:42:43 +0000 (UTC) (envelope-from jb@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 5380B8FC1E for ; Wed, 19 Mar 2008 18:42:43 +0000 (UTC) (envelope-from jb@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id m2JIghlg029493 for ; Wed, 19 Mar 2008 18:42:43 GMT (envelope-from jb@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id m2JIghBl029491 for perforce@freebsd.org; Wed, 19 Mar 2008 18:42:43 GMT (envelope-from jb@freebsd.org) Date: Wed, 19 Mar 2008 18:42:43 GMT Message-Id: <200803191842.m2JIghBl029491@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to jb@freebsd.org using -f From: John Birrell To: Perforce Change Reviews Cc: Subject: PERFORCE change 138121 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 19 Mar 2008 18:42:44 -0000 http://perforce.freebsd.org/chv.cgi?CH=138121 Change 138121 by jb@jb_freebsd8 on 2008/03/19 18:42:01 IFopensolaris. There will probably be compile errors here. Affected files ... .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/cmd/chkargs/Makefile#4 branch .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/cmd/chkargs/Makefile.com#5 branch .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/cmd/chkargs/amd64/Makefile#1 branch .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/cmd/chkargs/i386/Makefile#1 branch .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/cmd/chkargs/sparc/Makefile#1 branch .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/cmd/chkargs/sparcv9/Makefile#1 branch .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/cmd/jdtrace/JDTrace.java#4 integrate .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/cmd/jdtrace/Makefile#5 branch .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/cmd/jdtrace/exception.lst#5 integrate .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/cmd/scripts/dtest.pl#9 integrate .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/tst/common/Makefile#9 integrate .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.avg_neg.d#1 branch .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.avg_neg.d.out#1 branch .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.max_neg.d#1 branch .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.max_neg.d.out#1 branch .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.min_neg.d#1 branch .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.min_neg.d.out#1 branch .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.stddev.d#1 branch .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.stddev.d.out#1 branch .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/Makefile#4 branch .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestBean.java#6 integrate .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.Bean.ksh.out#5 integrate .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/tst/common/nfs/tst.call3.c#1 branch .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/tst/common/nfs/tst.call3.d#1 branch .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex1.ksh#1 branch .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex2.ksh#1 branch .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex2.ksh.out#1 branch .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex3.ksh#1 branch .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex3.ksh.out#1 branch .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex4.ksh#1 branch .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex4.ksh.out#1 branch .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.stddev.d#1 branch .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/tst/i386/Makefile#5 branch .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/sgs/include/_string_table.h#4 integrate .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/sgs/include/alist.h#9 integrate .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/sgs/include/debug.h#12 integrate .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/sgs/include/string_table.h#6 integrate .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/sgs/tools/common/sgsmsg.c#10 integrate .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/sgs/tools/common/string_table.c#9 integrate .. //depot/projects/dtrace/src/contrib/opensolaris/lib/libdtrace/common/dt_aggregate.c#16 integrate .. //depot/projects/dtrace/src/contrib/opensolaris/lib/libdtrace/common/dt_consume.c#17 integrate .. //depot/projects/dtrace/src/contrib/opensolaris/lib/libdtrace/common/dt_impl.h#21 integrate .. //depot/projects/dtrace/src/contrib/opensolaris/lib/libdtrace/common/dt_open.c#27 integrate .. //depot/projects/dtrace/src/contrib/opensolaris/lib/libdtrace/common/dt_pid.c#13 integrate .. //depot/projects/dtrace/src/sys/contrib/opensolaris/uts/common/dtrace/dtrace.c#41 integrate .. //depot/projects/dtrace/src/sys/contrib/opensolaris/uts/common/dtrace/lockstat.c#4 integrate .. //depot/projects/dtrace/src/sys/contrib/opensolaris/uts/common/dtrace/sdt_subr.c#5 integrate Differences ... ==== //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/cmd/jdtrace/JDTrace.java#4 (text+ko) ==== @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * * ident "%Z%%M% %I% %E% SMI" @@ -443,153 +443,10 @@ } } - static int - compareTuples(Tuple t1, Tuple t2, int pos) - { - int cmp = 0; - int len1 = t1.size(); - int len2 = t2.size(); - int index; - - for (int i = 0; (cmp == 0) && (i < len1 && i < len2); ++i) { - index = i + pos; - if (index >= len1) { - index = index - len1; - } - cmp = Tuple.compare(t1, t2, index); - } - - if (cmp == 0) { - cmp = (len1 < len2 ? -1 : (len1 > len2 ? 1 : 0)); - } - - return cmp; - } - - static int - compareValues(AggregationValue v1, AggregationValue v2) - { - int cmp; - - if ((v1 instanceof LinearDistribution) && - (v2 instanceof LinearDistribution)) { - LinearDistribution l1 = (LinearDistribution)v1; - LinearDistribution l2 = (LinearDistribution)v2; - cmp = l1.compareTo(l2); - } else if ((v1 instanceof LogDistribution) && - (v2 instanceof LogDistribution)) { - LogDistribution l1 = (LogDistribution)v1; - LogDistribution l2 = (LogDistribution)v2; - cmp = l1.compareTo(l2); - } else { - double n1 = v1.getValue().doubleValue(); - double n2 = v2.getValue().doubleValue(); - cmp = (n1 < n2 ? -1 : (n1 > n2 ? 1 : 0)); - } - - return cmp; - } - - static Comparator - getAggValCmp(final int keypos) - { - Comparator CMP = new Comparator () { - public int - compare(Object[] pair1, Object[] pair2) - { - int cmp; - long id1 = (Long)pair1[1]; - long id2 = (Long)pair2[1]; - cmp = (id1 < id2 ? -1 : (id1 > id2 ? 1 : 0)); - if (cmp != 0) { - return cmp; - } - - AggregationRecord r1 = (AggregationRecord)pair1[0]; - AggregationRecord r2 = (AggregationRecord)pair2[0]; - AggregationValue v1 = r1.getValue(); - AggregationValue v2 = r2.getValue(); - cmp = compareValues(v1, v2); - if (cmp != 0) { - return cmp; - } - - cmp = compareTuples(r1.getTuple(), r2.getTuple(), keypos); - return cmp; - } - }; - return CMP; - }; - - static Comparator - getAggKeyCmp(final int keypos) - { - Comparator CMP = new Comparator () { - public int - compare(Object[] pair1, Object[] pair2) - { - int cmp; - long id1 = (Long)pair1[1]; - long id2 = (Long)pair2[1]; - cmp = (id1 < id2 ? -1 : (id1 > id2 ? 1 : 0)); - if (cmp != 0) { - return cmp; - } - - AggregationRecord r1 = (AggregationRecord)pair1[0]; - AggregationRecord r2 = (AggregationRecord)pair2[0]; - cmp = compareTuples(r1.getTuple(), r2.getTuple(), keypos); - - return cmp; - } - }; - return CMP; - } - - // Consumer getAggregate() static void printAggregate(Aggregate aggregate) { - List list = - new ArrayList (); - List sortList = new ArrayList (); - for (Aggregation a : aggregate.getAggregations()) { - for (AggregationRecord rec : a.asMap().values()) { - sortList.add(new Object[] {rec, new Long(a.getID())}); - } - } - - try { - // aggsortkeypos - long optval = dtrace.getOption(Option.aggsortkeypos); - int keypos; - if (optval == Option.UNSET) { - keypos = 0; - } else { - keypos = (int)optval; - } - - // aggsortkey - if (dtrace.getOption(Option.aggsortkey) == Option.UNSET) { - Collections.sort(sortList, getAggValCmp(keypos)); - } else { - Collections.sort(sortList, getAggKeyCmp(keypos)); - } - - for (Object[] pair : sortList) { - list.add((AggregationRecord)pair[0]); - } - - // aggsortrev - if (dtrace.getOption(Option.aggsortrev) != Option.UNSET) { - Collections.reverse(list); - } - } catch (DTraceException e) { - e.printStackTrace(); - return; - } - - printAggregationRecords(list); + printAggregationRecords(aggregate.getOrderedRecords()); } static void @@ -830,7 +687,7 @@ } Consumer.OpenFlag[] oflags = new Consumer.OpenFlag[openFlags.size()]; - oflags = (Consumer.OpenFlag[])openFlags.toArray(oflags); + oflags = openFlags.toArray(oflags); dtrace = new LocalConsumer() { protected Thread createThread() { @@ -1001,13 +858,8 @@ } String[] compileArgs = new String[argList.size()]; - compileArgs = (String[])argList.toArray(compileArgs); + compileArgs = argList.toArray(compileArgs); - if (compileRequests.isEmpty()) { - System.err.println("dtrace: no probes specified"); - exit(1); - } - Program program; for (CompileRequest req : compileRequests) { switch (req.type) { @@ -1091,7 +943,7 @@ dtrace.getProgramInfo(p); } info = p.getInfo(); - if (!quiet) { + if ((mode == Mode.EXEC) && !quiet) { System.err.printf("dtrace: %s '%s' matched %d probe%s\n", programType, programDescription, info.getMatchingProbeCount(), ==== //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/cmd/jdtrace/exception.lst#5 (text+ko) ==== @@ -20,20 +20,20 @@ # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" -# Exception list: names tests that are bypassed when running -# 'dtest -i java' (relative to /opt/SUNWdtrt/tst) +# Exception list: names tests that are bypassed when running in Java +# mode (relative to /opt/SUNWdtrt/tst) # double precision (64-bit floating point) not same in java common/aggs/tst.neglquant.d common/aggs/tst.negquant.d # freopen() (to suppress output) not supported by Java DTrace API -common/printa/tst.walltimestamp.d +common/printa/tst.walltimestamp.ksh # -G option not supported by jdtrace common/dtraceUtil/tst.ELFGenerationOut.d.ksh @@ -46,6 +46,8 @@ common/usdt/tst.badguess.ksh common/usdt/tst.dlclose1.ksh common/usdt/tst.dlclose2.ksh +common/usdt/tst.dlclose3.ksh +common/usdt/tst.eliminate.ksh common/usdt/tst.enabled.ksh common/usdt/tst.entryreturn.ksh common/usdt/tst.fork.ksh @@ -61,8 +63,14 @@ common/usdt/tst.static.ksh common/usdt/tst.static2.ksh common/usdt/tst.user.ksh +sparc/usdt/tst.tailcall.ksh +common/pid/tst.provregex3.ksh +common/pid/tst.provregex4.ksh # freopen() and ftruncate() not supported by Java DTrace API common/funcs/tst.badfreopen.ksh common/funcs/tst.freopen.ksh common/funcs/tst.ftruncate.ksh + +# jdtrace doesn't pull in library files? +common/pragma/tst.libdepfullyconnected.ksh ==== //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/cmd/scripts/dtest.pl#9 (text+kox) ==== @@ -21,7 +21,7 @@ # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -36,20 +36,19 @@ $PNAME = $0; $PNAME =~ s:.*/::; -$OPTSTR = 'abd:ghi:lqsux:'; -$USAGE = "Usage: $PNAME [-abghlqsu] [-d dir] [-i isa] " +$OPTSTR = 'abd:fghi:jlnqsx:'; +$USAGE = "Usage: $PNAME [-abfghjlnqs] [-d dir] [-i isa] " . "[-x opt[=arg]] [file | dir ...]\n"; ($MACH = `uname -p`) =~ s/\W*\n//; -$dtrace_path = '/usr/sbin/dtrace'; @dtrace_argv = (); $ksh_path = '/bin/sh'; @files = (); %exceptions = (); +%results = (); $errs = 0; -$bypassed = 0; # # If no test files are specified on the command-line, execute a find on "." @@ -77,14 +76,15 @@ print "\t -b execute bad ioctl test program\n"; print "\t -d specify directory for test results files and cores\n"; print "\t -g enable libumem debugging when running tests\n"; + print "\t -f force bypassed tests to run\n"; print "\t -h display verbose usage message\n"; print "\t -i specify ISA to test instead of isaexec(3C) default\n"; + print "\t -j execute test suite using jdtrace (Java API) only\n"; print "\t -l save log file of results and PIDs used by tests\n"; + print "\t -n execute test suite using dtrace(1m) only\n"; print "\t -q set quiet mode (only report errors and summary)\n"; print "\t -s save results files even for tests that pass\n"; print "\t -x pass corresponding -x argument to dtrace(1M)\n"; - print "\n\tUse \"-i java\" to run tests using the "; - print "Java DTrace API.\n"; exit(2); } @@ -173,28 +173,37 @@ return $s; } -# Loads exception set of skipped tests +# Load exception set of skipped tests from the file at the given +# pathname. The test names are assumed to be paths relative to $dt_tst, +# for example: common/aggs/tst.neglquant.d, and specify tests to be +# skipped. sub load_exceptions { my($listfile) = @_; my($line) = ""; - exit(123) unless open(STDIN, "<$listfile"); - while () { - chomp; - $line = $_; - # line is non-empty and not a comment - if ((length($line) > 0) && ($line =~ /^\s*[^\s#]/ )) { - $exceptions{trim($line)} = 1; + %exceptions = (); + if (length($listfile) > 0) { + exit(123) unless open(STDIN, "<$listfile"); + while () { + chomp; + $line = $_; + # line is non-empty and not a comment + if ((length($line) > 0) && ($line =~ /^\s*[^\s#]/ )) { + $exceptions{trim($line)} = 1; + } } } - return 0; } -# Return 1 if file name found in exception set, 0 otherwise +# Return 1 if the test is found in the exception set, 0 otherwise. sub is_exception { my($file) = @_; my($i) = -1; + if (scalar(keys(%exceptions)) == 0) { + return 0; + } + # hash absolute pathname after $dt_tst/ $file = abs_path($file); $i = index($file, $dt_tst); @@ -205,6 +214,320 @@ return 0; } +# +# Iterate over the set of test files specified on the command-line or by +# a find on "$defdir/common" and "$defdir/$MACH" and execute each one. +# If the test file is executable, we fork and exec it. If the test is a +# .ksh file, we run it with $ksh_path. Otherwise we run dtrace -s on it. +# If the file is named tst.* we assume it should return exit status 0. +# If the file is named err.* we assume it should return exit status 1. +# If the file is named err.D_[A-Z0-9]+[.*].d we use dtrace -xerrtags and +# examine stderr to ensure that a matching error tag was produced. +# If the file is named drp.[A-Z0-9]+[.*].d we use dtrace -xdroptags and +# examine stderr to ensure that a matching drop tag was produced. +# If any *.out or *.err files are found we perform output comparisons. +# +# run_tests takes two arguments: The first is the pathname of the dtrace +# command to invoke when running the tests. The second is the pathname +# of a file (may be the empty string) listing tests that ought to be +# skipped (skipped tests are listed as paths relative to $dt_tst, for +# example: common/aggs/tst.neglquant.d). +# +sub run_tests { + my($dtrace, $exceptions_path) = @_; + my($passed) = 0; + my($bypassed) = 0; + my($failed) = $errs; + my($total) = 0; + + die "$PNAME: $dtrace not found\n" unless (-x "$dtrace"); + logmsg($dtrace . "\n"); + + load_exceptions($exceptions_path); + + foreach $file (sort @files) { + $file =~ m:.*/((.*)\.(\w+)):; + $name = $1; + $base = $2; + $ext = $3; + + $dir = dirname($file); + $isksh = 0; + $tag = 0; + $droptag = 0; + + if ($name =~ /^tst\./) { + $isksh = ($ext eq 'ksh'); + $status = 0; + } elsif ($name =~ /^err\.(D_[A-Z0-9_]+)\./) { + $status = 1; + $tag = $1; + } elsif ($name =~ /^err\./) { + $status = 1; + } elsif ($name =~ /^drp\.([A-Z0-9_]+)\./) { + $status = 0; + $droptag = $1; + } else { + errmsg("ERROR: $file is not a valid test file name\n"); + next; + } + + $fullname = "$dir/$name"; + $exe = "$dir/$base.exe"; + $exe_pid = -1; + + if ($opt_a && ($status != 0 || $tag != 0 || $droptag != 0 || + -x $exe || $isksh || -x $fullname)) { + $bypassed++; + next; + } + + if (!$opt_f && is_exception("$dir/$name")) { + $bypassed++; + next; + } + + if (!$isksh && -x $exe) { + if (($exe_pid = fork()) == -1) { + errmsg( + "ERROR: failed to fork to run $exe: $!\n"); + next; + } + + if ($exe_pid == 0) { + open(STDIN, '$opt_d/$$.out"); + exit(125) unless open(STDERR, ">$opt_d/$$.err"); + + unless (chdir($dir)) { + warn "ERROR: failed to chdir for $file: $!\n"; + exit(126); + } + + push(@dtrace_argv, '-xerrtags') if ($tag); + push(@dtrace_argv, '-xdroptags') if ($droptag); + push(@dtrace_argv, $exe_pid) if ($exe_pid != -1); + + if ($isksh) { + exit(123) unless open(STDIN, "<$name"); + exec("$ksh_path /dev/stdin $dtrace"); + } elsif (-x $name) { + warn "ERROR: $name is executable\n"; + exit(1); + } else { + if ($tag == 0 && $status == $0 && $opt_a) { + push(@dtrace_argv, '-A'); + } + + push(@dtrace_argv, '-C'); + push(@dtrace_argv, '-s'); + push(@dtrace_argv, $name); + exec($dtrace, @dtrace_argv); + } + + warn "ERROR: failed to exec for $file: $!\n"; + exit(127); + } + + if (waitpid($pid, 0) == -1) { + errmsg("ERROR: timed out waiting for $file\n"); + kill(9, $exe_pid) if ($exe_pid != -1); + kill(9, $pid); + next; + } + + kill(9, $exe_pid) if ($exe_pid != -1); + + if ($tag == 0 && $status == $0 && $opt_a) { + # + # We can chuck the earler output. + # + unlink($pid . '.out'); + unlink($pid . '.err'); + + # + # This is an anonymous enabling. We need to get + # the module unloaded. + # + system("dtrace -ae 1> /dev/null 2> /dev/null"); + system("svcadm disable -s " . + "svc:/network/nfs/mapid:default"); + system("modunload -i 0 ; modunload -i 0 ; " . + "modunload -i 0"); + if (!system("modinfo | grep dtrace")) { + warn "ERROR: couldn't unload dtrace\n"; + system("svcadm enable " . + "-s svc:/network/nfs/mapid:default"); + exit(124); + } + + # + # DTrace is gone. Now update_drv(1M), and rip + # everything out again. + # + system("update_drv dtrace"); + system("dtrace -ae 1> /dev/null 2> /dev/null"); + system("modunload -i 0 ; modunload -i 0 ; " . + "modunload -i 0"); + if (!system("modinfo | grep dtrace")) { + warn "ERROR: couldn't unload dtrace\n"; + system("svcadm enable " . + "-s svc:/network/nfs/mapid:default"); + exit(124); + } + + # + # Now bring DTrace back in. + # + system("sync ; sync"); + system("dtrace -l -n bogusprobe 1> /dev/null " . + "2> /dev/null"); + system("svcadm enable -s " . + "svc:/network/nfs/mapid:default"); + + # + # That should have caused DTrace to reload with + # the new configuration file. Now we can try to + # snag our anonymous state. + # + if (($pid = fork()) == -1) { + errmsg("ERROR: failed to fork to run " . + "test $file: $!\n"); + next; + } + + if ($pid == 0) { + open(STDIN, '$opt_d/$$.out"); + exit(125) unless open(STDERR, ">$opt_d/$$.err"); + + push(@dtrace_argv, '-a'); + + unless (chdir($dir)) { + warn "ERROR: failed to chdir " . + "for $file: $!\n"; + exit(126); + } + + exec($dtrace, @dtrace_argv); + warn "ERROR: failed to exec for $file: $!\n"; + exit(127); + } + + if (waitpid($pid, 0) == -1) { + errmsg("ERROR: timed out waiting for $file\n"); + kill(9, $pid); + next; + } + } + + logmsg("[$pid]\n"); + $wstat = $?; + $wifexited = ($wstat & 0xFF) == 0; + $wexitstat = ($wstat >> 8) & 0xFF; + $wtermsig = ($wstat & 0x7F); + + if (!$wifexited) { + fail("died from signal $wtermsig"); + next; + } + + if ($wexitstat == 125) { + die "$PNAME: failed to create output file in $opt_d " . + "(cd elsewhere or use -d)\n"; + } + + if ($wexitstat != $status) { + fail("returned $wexitstat instead of $status"); + next; + } + + if (-f "$file.out" && + system("cmp -s $file.out $opt_d/$pid.out") != 0) { + fail("stdout mismatch", "$pid.out"); + next; + } + + if (-f "$file.err" && + system("cmp -s $file.err $opt_d/$pid.err") != 0) { + fail("stderr mismatch: see $pid.err"); + next; + } + + if ($tag) { + open(TSTERR, "<$opt_d/$pid.err"); + $tsterr = ; + close(TSTERR); + + unless ($tsterr =~ /: \[$tag\] line \d+:/) { + fail("errtag mismatch: see $pid.err"); + next; + } + } + + if ($droptag) { + $found = 0; + open(TSTERR, "<$opt_d/$pid.err"); + + while () { + if (/\[$droptag\] /) { + $found = 1; + last; + } + } + + close (TSTERR); + + unless ($found) { + fail("droptag mismatch: see $pid.err"); + next; + } + } + + unless ($opt_s) { + unlink($pid . '.out'); + unlink($pid . '.err'); + } + } + + if ($opt_a) { + # + # If we're running with anonymous enablings, we need to + # restore the .conf file. + # + system("dtrace -A 1> /dev/null 2> /dev/null"); + system("dtrace -ae 1> /dev/null 2> /dev/null"); + system("modunload -i 0 ; modunload -i 0 ; modunload -i 0"); + system("update_drv dtrace"); + } + + $total = scalar(@files); + $failed = $errs - $failed; + $passed = ($total - $failed - $bypassed); + $results{$dtrace} = { + "passed" => $passed, + "bypassed" => $bypassed, + "failed" => $failed, + "total" => $total + }; +} + die $USAGE unless (getopts($OPTSTR)); usage() if ($opt_h); @@ -227,6 +550,20 @@ find(\&wanted, "$defdir/$MACH") if (scalar(@ARGV) == 0); die $USAGE if (scalar(@files) == 0); +$dtrace_path = '/usr/sbin/dtrace'; +$jdtrace_path = "$bindir/jdtrace"; + +%exception_lists = ("$jdtrace_path" => "$bindir/exception.lst"); + +if ($opt_j || $opt_n || $opt_i) { + @dtrace_cmds = (); + push(@dtrace_cmds, $dtrace_path) if ($opt_n); + push(@dtrace_cmds, $jdtrace_path) if ($opt_j); + push(@dtrace_cmds, "/usr/sbin/$opt_i/dtrace") if ($opt_i); +} else { + @dtrace_cmds = ($dtrace_path, $jdtrace_path); +} + if ($opt_d) { die "$PNAME: -d arg must be absolute path\n" unless ($opt_d =~ /^\//); die "$PNAME: -d arg $opt_d is not a directory\n" unless (-d "$opt_d"); @@ -237,19 +574,6 @@ $opt_d = '.'; } -if ($opt_i) { - if ($opt_i eq "java") { - $dtrace_path = $bindir . "/jdtrace"; - die "$PNAME: jdtrace not found\n" - unless (-x "$dtrace_path"); - load_exceptions($bindir . "/exception.lst"); - } else { - $dtrace_path = "/usr/sbin/$opt_i/dtrace"; - die "$PNAME: dtrace(1M) for ISA $opt_i not found\n" - unless (-x "$dtrace_path"); - } -} - if ($opt_x) { push(@dtrace_argv, '-x'); push(@dtrace_argv, $opt_x); @@ -349,326 +673,31 @@ exit(0); } -if ($opt_u) { - logmsg "spawning module unloading process... "; - - $unloader = fork; - - if ($unloader != 0 && !defined $unloader) { - # - # Couldn't fork for some reason. - # - die "couldn't fork: $!\n"; - } - - if ($unloader == 0) { - # - # We're in the child. Go modunload krazy. - # - for (;;) { - system("modunload -i 0"); - } - } else { - logmsg "[$unloader]\n"; - - $SIG{INT} = sub { - kill 9, $unloader; - exit($errs != 0); - }; - } -} - # -# Iterate over the set of test files specified on the command-line or located -# by a find on "." and execute each one. If the test file is executable, we -# assume it is a #! script and run it. Otherwise we run dtrace -s on it. -# If the file is named tst.* we assume it should return exit status 0. -# If the file is named err.* we assume it should return exit status 1. -# If the file is named err.D_[A-Z0-9]+[.*].d we use dtrace -xerrtags and -# examine stderr to ensure that a matching error tag was produced. -# If the file is named drp.[A-Z0-9]+[.*].d we use dtrace -xdroptags and -# examine stderr to ensure that a matching drop tag was produced. -# If any *.out or *.err files are found we perform output comparisons. +# Run all the tests specified on the command-line (the entire test suite +# by default) once for each dtrace command tested, skipping any tests +# not valid for that command. # -foreach $file (sort @files) { - $file =~ m:.*/((.*)\.(\w+)):; - $name = $1; - $base = $2; - $ext = $3; - - $dir = dirname($file); - $isksh = 0; - $tag = 0; - $droptag = 0; - - if ($name =~ /^tst\./) { - $isksh = ($ext eq 'ksh'); - $status = 0; - } elsif ($name =~ /^err\.(D_[A-Z0-9_]+)\./) { - $status = 1; - $tag = $1; - } elsif ($name =~ /^err\./) { - $status = 1; - } elsif ($name =~ /^drp\.([A-Z0-9_]+)\./) { - $status = 0; - $droptag = $1; - } else { - errmsg("ERROR: $file is not a valid test file name\n"); - next; - } - - $fullname = "$dir/$name"; - $exe = "./$base.exe"; - $exe_pid = -1; - - if ($opt_a && ($status != 0 || $tag != 0 || $droptag != 0 || - -x $exe || $isksh || -x $fullname)) { - $bypassed++; - next; - } - - if ($opt_i eq "java") { - if (is_exception("$dir/$name")) { - $bypassed++; - next; - } - } - - if (!$isksh && -x $exe) { - if (($exe_pid = fork()) == -1) { - errmsg("ERROR: failed to fork to run $exe: $!\n"); - next; - } - - if ($exe_pid == 0) { - open(STDIN, '$opt_d/$$.out"); - exit(125) unless open(STDERR, ">$opt_d/$$.err"); - - unless (chdir($dir)) { - warn "ERROR: failed to chdir for $file: $!\n"; - exit(126); - } - - push(@dtrace_argv, '-xerrtags') if ($tag); - push(@dtrace_argv, '-xdroptags') if ($droptag); - push(@dtrace_argv, $exe_pid) if ($exe_pid != -1); - - if ($isksh) { - exit(123) unless open(STDIN, "<$name"); - exec("$ksh_path /dev/stdin $dtrace_path"); - } elsif (-x $name) { - warn "ERROR: $name is executable\n"; - exit(1); - } else { - if ($tag == 0 && $status == $0 && $opt_a) { - push(@dtrace_argv, '-A'); - } - - push(@dtrace_argv, '-C'); - push(@dtrace_argv, '-s'); - push(@dtrace_argv, $name); - exec($dtrace_path, @dtrace_argv); - } - - warn "ERROR: failed to exec for $file: $!\n"; - exit(127); - } - - if (waitpid($pid, 0) == -1) { - errmsg("ERROR: timed out waiting for $file\n"); - kill(9, $exe_pid) if ($exe_pid != -1); - kill(9, $pid); - next; - } - - kill(9, $exe_pid) if ($exe_pid != -1); - - if ($tag == 0 && $status == $0 && $opt_a) { - # - # We can chuck the earler output. - # - unlink($pid . '.out'); - unlink($pid . '.err'); - - # - # This is an anonymous enabling. We need to get the module - # unloaded. - # - system("dtrace -ae 1> /dev/null 2> /dev/null"); - system("svcadm disable -s svc:/network/nfs/mapid:default"); - system("modunload -i 0 ; modunload -i 0 ; modunload -i 0"); - if (!system("modinfo | grep dtrace")) { - warn "ERROR: couldn't unload dtrace\n"; - system("svcadm enable " . - "-s svc:/network/nfs/mapid:default"); - exit(124); - } - - # - # DTrace is gone. Now update_drv(1M), and rip everything out - # again. - # - system("update_drv dtrace"); - system("dtrace -ae 1> /dev/null 2> /dev/null"); - system("modunload -i 0 ; modunload -i 0 ; modunload -i 0"); - if (!system("modinfo | grep dtrace")) { - warn "ERROR: couldn't unload dtrace\n"; - system("svcadm enable " . - "-s svc:/network/nfs/mapid:default"); - exit(124); - } - - # - # Now bring DTrace back in. - # - system("sync ; sync"); - system("dtrace -l -n bogusprobe 1> /dev/null 2> /dev/null"); - system("svcadm enable -s svc:/network/nfs/mapid:default"); - - # - # That should have caused DTrace to reload with the new - # configuration file. Now we can try to snag our anonymous - # state. - # - if (($pid = fork()) == -1) { - errmsg("ERROR: failed to fork to run test $file: $!\n"); - next; - } - - if ($pid == 0) { - open(STDIN, '$opt_d/$$.out"); - exit(125) unless open(STDERR, ">$opt_d/$$.err"); - - push(@dtrace_argv, '-a'); - - unless (chdir($dir)) { - warn "ERROR: failed to chdir for $file: $!\n"; - exit(126); - } - - exec($dtrace_path, @dtrace_argv); - warn "ERROR: failed to exec for $file: $!\n"; - exit(127); - } - >>> TRUNCATED FOR MAIL (1000 lines) <<<