19512fe85Sahl#!/usr/perl5/bin/perl 29512fe85Sahl# 39512fe85Sahl# CDDL HEADER START 49512fe85Sahl# 59512fe85Sahl# The contents of this file are subject to the terms of the 69512fe85Sahl# Common Development and Distribution License (the "License"). 79512fe85Sahl# You may not use this file except in compliance with the License. 89512fe85Sahl# 99512fe85Sahl# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 109512fe85Sahl# or http://www.opensolaris.org/os/licensing. 119512fe85Sahl# See the License for the specific language governing permissions 129512fe85Sahl# and limitations under the License. 139512fe85Sahl# 149512fe85Sahl# When distributing Covered Code, include this CDDL HEADER in each 159512fe85Sahl# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 169512fe85Sahl# If applicable, add the following below this CDDL HEADER, with the 179512fe85Sahl# fields enclosed by brackets "[]" replaced with your own identifying 189512fe85Sahl# information: Portions Copyright [yyyy] [name of copyright owner] 199512fe85Sahl# 209512fe85Sahl# CDDL HEADER END 219512fe85Sahl# 229512fe85Sahl 239512fe85Sahl# 24*e77b06d2Stomee# Copyright 2008 Sun Microsystems, Inc. All rights reserved. 259512fe85Sahl# Use is subject to license terms. 269512fe85Sahl# 272b6e762cSahl# ident "%Z%%M% %I% %E% SMI" 289512fe85Sahl 299512fe85Sahlrequire 5.6.1; 309512fe85Sahl 319512fe85Sahluse File::Find; 329512fe85Sahluse File::Basename; 339512fe85Sahluse Getopt::Std; 349512fe85Sahluse Cwd; 3523b5c241Stomeeuse Cwd 'abs_path'; 369512fe85Sahl 379512fe85Sahl$PNAME = $0; 389512fe85Sahl$PNAME =~ s:.*/::; 39*e77b06d2Stomee$OPTSTR = 'abd:fghi:jlnqsx:'; 40*e77b06d2Stomee$USAGE = "Usage: $PNAME [-abfghjlnqs] [-d dir] [-i isa] " 419512fe85Sahl . "[-x opt[=arg]] [file | dir ...]\n"; 429512fe85Sahl($MACH = `uname -p`) =~ s/\W*\n//; 439512fe85Sahl 449512fe85Sahl@dtrace_argv = (); 459512fe85Sahl 469512fe85Sahl$ksh_path = '/usr/bin/ksh'; 479512fe85Sahl 489512fe85Sahl@files = (); 4923b5c241Stomee%exceptions = (); 50*e77b06d2Stomee%results = (); 519512fe85Sahl$errs = 0; 529512fe85Sahl 539512fe85Sahl# 549512fe85Sahl# If no test files are specified on the command-line, execute a find on "." 559512fe85Sahl# and append any tst.*.d, tst.*.ksh, err.*.d or drp.*.d files found within 569512fe85Sahl# the directory tree. 579512fe85Sahl# 589512fe85Sahlsub wanted 599512fe85Sahl{ 609512fe85Sahl push(@files, $File::Find::name) 619512fe85Sahl if ($_ =~ /^(tst|err|drp)\..+\.(d|ksh)$/ && -f "$_"); 629512fe85Sahl} 639512fe85Sahl 649512fe85Sahlsub dirname { 659512fe85Sahl my($s) = @_; 669512fe85Sahl my($i); 679512fe85Sahl 689512fe85Sahl $s = substr($s, 0, $i) if (($i = rindex($s, '/')) != -1); 699512fe85Sahl return $i == -1 ? '.' : $i == 0 ? '/' : $s; 709512fe85Sahl} 719512fe85Sahl 729512fe85Sahlsub usage 739512fe85Sahl{ 749512fe85Sahl print $USAGE; 759512fe85Sahl print "\t -a execute test suite using anonymous enablings\n"; 769512fe85Sahl print "\t -b execute bad ioctl test program\n"; 779512fe85Sahl print "\t -d specify directory for test results files and cores\n"; 789512fe85Sahl print "\t -g enable libumem debugging when running tests\n"; 79*e77b06d2Stomee print "\t -f force bypassed tests to run\n"; 809512fe85Sahl print "\t -h display verbose usage message\n"; 819512fe85Sahl print "\t -i specify ISA to test instead of isaexec(3C) default\n"; 82*e77b06d2Stomee print "\t -j execute test suite using jdtrace (Java API) only\n"; 839512fe85Sahl print "\t -l save log file of results and PIDs used by tests\n"; 84*e77b06d2Stomee print "\t -n execute test suite using dtrace(1m) only\n"; 859512fe85Sahl print "\t -q set quiet mode (only report errors and summary)\n"; 869512fe85Sahl print "\t -s save results files even for tests that pass\n"; 879512fe85Sahl print "\t -x pass corresponding -x argument to dtrace(1M)\n"; 889512fe85Sahl exit(2); 899512fe85Sahl} 909512fe85Sahl 919512fe85Sahlsub errmsg 929512fe85Sahl{ 939512fe85Sahl my($msg) = @_; 949512fe85Sahl 959512fe85Sahl print STDERR $msg; 969512fe85Sahl print LOG $msg if ($opt_l); 979512fe85Sahl $errs++; 989512fe85Sahl} 999512fe85Sahl 1009512fe85Sahlsub fail 1019512fe85Sahl{ 1029512fe85Sahl my(@parms) = @_; 1039512fe85Sahl my($msg) = $parms[0]; 1049512fe85Sahl my($errfile) = $parms[1]; 1059512fe85Sahl my($n) = 0; 1069512fe85Sahl my($dest) = basename($file); 1079512fe85Sahl 1089512fe85Sahl while (-d "$opt_d/failure.$n") { 1099512fe85Sahl $n++; 1109512fe85Sahl } 1119512fe85Sahl 1129512fe85Sahl unless (mkdir "$opt_d/failure.$n") { 1139512fe85Sahl warn "ERROR: failed to make directory $opt_d/failure.$n: $!\n"; 1149512fe85Sahl exit(125); 1159512fe85Sahl } 1169512fe85Sahl 1179512fe85Sahl open(README, ">$opt_d/failure.$n/README"); 1189512fe85Sahl print README "ERROR: " . $file . " " . $msg; 1199512fe85Sahl 1209512fe85Sahl if (scalar @parms > 1) { 1219512fe85Sahl print README "; see $errfile\n"; 1229512fe85Sahl } else { 1239512fe85Sahl if (-f "$opt_d/$pid.core") { 1249512fe85Sahl print README "; see $pid.core\n"; 1259512fe85Sahl } else { 1269512fe85Sahl print README "\n"; 1279512fe85Sahl } 1289512fe85Sahl } 1299512fe85Sahl 1309512fe85Sahl close(README); 1319512fe85Sahl 1329512fe85Sahl if (-f "$opt_d/$pid.out") { 1339512fe85Sahl rename("$opt_d/$pid.out", "$opt_d/failure.$n/$pid.out"); 1349512fe85Sahl link("$file.out", "$opt_d/failure.$n/$dest.out"); 1359512fe85Sahl } 1369512fe85Sahl 1379512fe85Sahl if (-f "$opt_d/$pid.err") { 1389512fe85Sahl rename("$opt_d/$pid.err", "$opt_d/failure.$n/$pid.err"); 1399512fe85Sahl link("$file.err", "$opt_d/failure.$n/$dest.err"); 1409512fe85Sahl } 1419512fe85Sahl 1429512fe85Sahl if (-f "$opt_d/$pid.core") { 1439512fe85Sahl rename("$opt_d/$pid.core", "$opt_d/failure.$n/$pid.core"); 1449512fe85Sahl } 1459512fe85Sahl 1469512fe85Sahl link("$file", "$opt_d/failure.$n/$dest"); 1479512fe85Sahl 1489512fe85Sahl $msg = "ERROR: " . $dest . " " . $msg; 1499512fe85Sahl 1509512fe85Sahl if (scalar @parms > 1) { 1519512fe85Sahl $msg = $msg . "; see $errfile in failure.$n\n"; 1529512fe85Sahl } else { 1539512fe85Sahl $msg = $msg . "; details in failure.$n\n"; 1549512fe85Sahl } 1559512fe85Sahl 1569512fe85Sahl errmsg($msg); 1579512fe85Sahl} 1589512fe85Sahl 1599512fe85Sahlsub logmsg 1609512fe85Sahl{ 1619512fe85Sahl my($msg) = @_; 1629512fe85Sahl 1639512fe85Sahl print STDOUT $msg unless ($opt_q); 1649512fe85Sahl print LOG $msg if ($opt_l); 1659512fe85Sahl} 1669512fe85Sahl 16723b5c241Stomee# Trim leading and trailing whitespace 16823b5c241Stomeesub trim { 16923b5c241Stomee my($s) = @_; 17023b5c241Stomee 17123b5c241Stomee $s =~ s/^\s*//; 17223b5c241Stomee $s =~ s/\s*$//; 17323b5c241Stomee return $s; 17423b5c241Stomee} 17523b5c241Stomee 176*e77b06d2Stomee# Load exception set of skipped tests from the file at the given 177*e77b06d2Stomee# pathname. The test names are assumed to be paths relative to $dt_tst, 178*e77b06d2Stomee# for example: common/aggs/tst.neglquant.d, and specify tests to be 179*e77b06d2Stomee# skipped. 18023b5c241Stomeesub load_exceptions { 18123b5c241Stomee my($listfile) = @_; 18223b5c241Stomee my($line) = ""; 18323b5c241Stomee 184*e77b06d2Stomee %exceptions = (); 185*e77b06d2Stomee if (length($listfile) > 0) { 186*e77b06d2Stomee exit(123) unless open(STDIN, "<$listfile"); 187*e77b06d2Stomee while (<STDIN>) { 188*e77b06d2Stomee chomp; 189*e77b06d2Stomee $line = $_; 190*e77b06d2Stomee # line is non-empty and not a comment 191*e77b06d2Stomee if ((length($line) > 0) && ($line =~ /^\s*[^\s#]/ )) { 192*e77b06d2Stomee $exceptions{trim($line)} = 1; 193*e77b06d2Stomee } 19423b5c241Stomee } 19523b5c241Stomee } 19623b5c241Stomee} 19723b5c241Stomee 198*e77b06d2Stomee# Return 1 if the test is found in the exception set, 0 otherwise. 19923b5c241Stomeesub is_exception { 20023b5c241Stomee my($file) = @_; 20123b5c241Stomee my($i) = -1; 20223b5c241Stomee 203*e77b06d2Stomee if (scalar(keys(%exceptions)) == 0) { 204*e77b06d2Stomee return 0; 205*e77b06d2Stomee } 206*e77b06d2Stomee 20723b5c241Stomee # hash absolute pathname after $dt_tst/ 20823b5c241Stomee $file = abs_path($file); 20923b5c241Stomee $i = index($file, $dt_tst); 21023b5c241Stomee if ($i == 0) { 21123b5c241Stomee $file = substr($file, length($dt_tst) + 1); 21223b5c241Stomee return $exceptions{$file}; 21323b5c241Stomee } 21423b5c241Stomee return 0; 21523b5c241Stomee} 21623b5c241Stomee 217*e77b06d2Stomee# 218*e77b06d2Stomee# Iterate over the set of test files specified on the command-line or by 219*e77b06d2Stomee# a find on "$defdir/common" and "$defdir/$MACH" and execute each one. 220*e77b06d2Stomee# If the test file is executable, we fork and exec it. If the test is a 221*e77b06d2Stomee# .ksh file, we run it with $ksh_path. Otherwise we run dtrace -s on it. 222*e77b06d2Stomee# If the file is named tst.* we assume it should return exit status 0. 223*e77b06d2Stomee# If the file is named err.* we assume it should return exit status 1. 224*e77b06d2Stomee# If the file is named err.D_[A-Z0-9]+[.*].d we use dtrace -xerrtags and 225*e77b06d2Stomee# examine stderr to ensure that a matching error tag was produced. 226*e77b06d2Stomee# If the file is named drp.[A-Z0-9]+[.*].d we use dtrace -xdroptags and 227*e77b06d2Stomee# examine stderr to ensure that a matching drop tag was produced. 228*e77b06d2Stomee# If any *.out or *.err files are found we perform output comparisons. 229*e77b06d2Stomee# 230*e77b06d2Stomee# run_tests takes two arguments: The first is the pathname of the dtrace 231*e77b06d2Stomee# command to invoke when running the tests. The second is the pathname 232*e77b06d2Stomee# of a file (may be the empty string) listing tests that ought to be 233*e77b06d2Stomee# skipped (skipped tests are listed as paths relative to $dt_tst, for 234*e77b06d2Stomee# example: common/aggs/tst.neglquant.d). 235*e77b06d2Stomee# 236*e77b06d2Stomeesub run_tests { 237*e77b06d2Stomee my($dtrace, $exceptions_path) = @_; 238*e77b06d2Stomee my($passed) = 0; 239*e77b06d2Stomee my($bypassed) = 0; 240*e77b06d2Stomee my($failed) = $errs; 241*e77b06d2Stomee my($total) = 0; 242*e77b06d2Stomee 243*e77b06d2Stomee die "$PNAME: $dtrace not found\n" unless (-x "$dtrace"); 244*e77b06d2Stomee logmsg($dtrace . "\n"); 245*e77b06d2Stomee 246*e77b06d2Stomee load_exceptions($exceptions_path); 247*e77b06d2Stomee 248*e77b06d2Stomee foreach $file (sort @files) { 249*e77b06d2Stomee $file =~ m:.*/((.*)\.(\w+)):; 250*e77b06d2Stomee $name = $1; 251*e77b06d2Stomee $base = $2; 252*e77b06d2Stomee $ext = $3; 253*e77b06d2Stomee 254*e77b06d2Stomee $dir = dirname($file); 255*e77b06d2Stomee $isksh = 0; 256*e77b06d2Stomee $tag = 0; 257*e77b06d2Stomee $droptag = 0; 258*e77b06d2Stomee 259*e77b06d2Stomee if ($name =~ /^tst\./) { 260*e77b06d2Stomee $isksh = ($ext eq 'ksh'); 261*e77b06d2Stomee $status = 0; 262*e77b06d2Stomee } elsif ($name =~ /^err\.(D_[A-Z0-9_]+)\./) { 263*e77b06d2Stomee $status = 1; 264*e77b06d2Stomee $tag = $1; 265*e77b06d2Stomee } elsif ($name =~ /^err\./) { 266*e77b06d2Stomee $status = 1; 267*e77b06d2Stomee } elsif ($name =~ /^drp\.([A-Z0-9_]+)\./) { 268*e77b06d2Stomee $status = 0; 269*e77b06d2Stomee $droptag = $1; 270*e77b06d2Stomee } else { 271*e77b06d2Stomee errmsg("ERROR: $file is not a valid test file name\n"); 272*e77b06d2Stomee next; 273*e77b06d2Stomee } 274*e77b06d2Stomee 275*e77b06d2Stomee $fullname = "$dir/$name"; 276*e77b06d2Stomee $exe = "$dir/$base.exe"; 277*e77b06d2Stomee $exe_pid = -1; 278*e77b06d2Stomee 279*e77b06d2Stomee if ($opt_a && ($status != 0 || $tag != 0 || $droptag != 0 || 280*e77b06d2Stomee -x $exe || $isksh || -x $fullname)) { 281*e77b06d2Stomee $bypassed++; 282*e77b06d2Stomee next; 283*e77b06d2Stomee } 284*e77b06d2Stomee 285*e77b06d2Stomee if (!$opt_f && is_exception("$dir/$name")) { 286*e77b06d2Stomee $bypassed++; 287*e77b06d2Stomee next; 288*e77b06d2Stomee } 289*e77b06d2Stomee 290*e77b06d2Stomee if (!$isksh && -x $exe) { 291*e77b06d2Stomee if (($exe_pid = fork()) == -1) { 292*e77b06d2Stomee errmsg( 293*e77b06d2Stomee "ERROR: failed to fork to run $exe: $!\n"); 294*e77b06d2Stomee next; 295*e77b06d2Stomee } 296*e77b06d2Stomee 297*e77b06d2Stomee if ($exe_pid == 0) { 298*e77b06d2Stomee open(STDIN, '</dev/null'); 299*e77b06d2Stomee 300*e77b06d2Stomee exec($exe); 301*e77b06d2Stomee 302*e77b06d2Stomee warn "ERROR: failed to exec $exe: $!\n"; 303*e77b06d2Stomee } 304*e77b06d2Stomee } 305*e77b06d2Stomee 306*e77b06d2Stomee logmsg("testing $file ... "); 307*e77b06d2Stomee 308*e77b06d2Stomee if (($pid = fork()) == -1) { 309*e77b06d2Stomee errmsg("ERROR: failed to fork to run test $file: $!\n"); 310*e77b06d2Stomee next; 311*e77b06d2Stomee } 312*e77b06d2Stomee 313*e77b06d2Stomee if ($pid == 0) { 314*e77b06d2Stomee open(STDIN, '</dev/null'); 315*e77b06d2Stomee exit(125) unless open(STDOUT, ">$opt_d/$$.out"); 316*e77b06d2Stomee exit(125) unless open(STDERR, ">$opt_d/$$.err"); 317*e77b06d2Stomee 318*e77b06d2Stomee unless (chdir($dir)) { 319*e77b06d2Stomee warn "ERROR: failed to chdir for $file: $!\n"; 320*e77b06d2Stomee exit(126); 321*e77b06d2Stomee } 322*e77b06d2Stomee 323*e77b06d2Stomee push(@dtrace_argv, '-xerrtags') if ($tag); 324*e77b06d2Stomee push(@dtrace_argv, '-xdroptags') if ($droptag); 325*e77b06d2Stomee push(@dtrace_argv, $exe_pid) if ($exe_pid != -1); 326*e77b06d2Stomee 327*e77b06d2Stomee if ($isksh) { 328*e77b06d2Stomee exit(123) unless open(STDIN, "<$name"); 329*e77b06d2Stomee exec("$ksh_path /dev/stdin $dtrace"); 330*e77b06d2Stomee } elsif (-x $name) { 331*e77b06d2Stomee warn "ERROR: $name is executable\n"; 332*e77b06d2Stomee exit(1); 333*e77b06d2Stomee } else { 334*e77b06d2Stomee if ($tag == 0 && $status == $0 && $opt_a) { 335*e77b06d2Stomee push(@dtrace_argv, '-A'); 336*e77b06d2Stomee } 337*e77b06d2Stomee 338*e77b06d2Stomee push(@dtrace_argv, '-C'); 339*e77b06d2Stomee push(@dtrace_argv, '-s'); 340*e77b06d2Stomee push(@dtrace_argv, $name); 341*e77b06d2Stomee exec($dtrace, @dtrace_argv); 342*e77b06d2Stomee } 343*e77b06d2Stomee 344*e77b06d2Stomee warn "ERROR: failed to exec for $file: $!\n"; 345*e77b06d2Stomee exit(127); 346*e77b06d2Stomee } 347*e77b06d2Stomee 348*e77b06d2Stomee if (waitpid($pid, 0) == -1) { 349*e77b06d2Stomee errmsg("ERROR: timed out waiting for $file\n"); 350*e77b06d2Stomee kill(9, $exe_pid) if ($exe_pid != -1); 351*e77b06d2Stomee kill(9, $pid); 352*e77b06d2Stomee next; 353*e77b06d2Stomee } 354*e77b06d2Stomee 355*e77b06d2Stomee kill(9, $exe_pid) if ($exe_pid != -1); 356*e77b06d2Stomee 357*e77b06d2Stomee if ($tag == 0 && $status == $0 && $opt_a) { 358*e77b06d2Stomee # 359*e77b06d2Stomee # We can chuck the earler output. 360*e77b06d2Stomee # 361*e77b06d2Stomee unlink($pid . '.out'); 362*e77b06d2Stomee unlink($pid . '.err'); 363*e77b06d2Stomee 364*e77b06d2Stomee # 365*e77b06d2Stomee # This is an anonymous enabling. We need to get 366*e77b06d2Stomee # the module unloaded. 367*e77b06d2Stomee # 368*e77b06d2Stomee system("dtrace -ae 1> /dev/null 2> /dev/null"); 369*e77b06d2Stomee system("svcadm disable -s " . 370*e77b06d2Stomee "svc:/network/nfs/mapid:default"); 371*e77b06d2Stomee system("modunload -i 0 ; modunload -i 0 ; " . 372*e77b06d2Stomee "modunload -i 0"); 373*e77b06d2Stomee if (!system("modinfo | grep dtrace")) { 374*e77b06d2Stomee warn "ERROR: couldn't unload dtrace\n"; 375*e77b06d2Stomee system("svcadm enable " . 376*e77b06d2Stomee "-s svc:/network/nfs/mapid:default"); 377*e77b06d2Stomee exit(124); 378*e77b06d2Stomee } 379*e77b06d2Stomee 380*e77b06d2Stomee # 381*e77b06d2Stomee # DTrace is gone. Now update_drv(1M), and rip 382*e77b06d2Stomee # everything out again. 383*e77b06d2Stomee # 384*e77b06d2Stomee system("update_drv dtrace"); 385*e77b06d2Stomee system("dtrace -ae 1> /dev/null 2> /dev/null"); 386*e77b06d2Stomee system("modunload -i 0 ; modunload -i 0 ; " . 387*e77b06d2Stomee "modunload -i 0"); 388*e77b06d2Stomee if (!system("modinfo | grep dtrace")) { 389*e77b06d2Stomee warn "ERROR: couldn't unload dtrace\n"; 390*e77b06d2Stomee system("svcadm enable " . 391*e77b06d2Stomee "-s svc:/network/nfs/mapid:default"); 392*e77b06d2Stomee exit(124); 393*e77b06d2Stomee } 394*e77b06d2Stomee 395*e77b06d2Stomee # 396*e77b06d2Stomee # Now bring DTrace back in. 397*e77b06d2Stomee # 398*e77b06d2Stomee system("sync ; sync"); 399*e77b06d2Stomee system("dtrace -l -n bogusprobe 1> /dev/null " . 400*e77b06d2Stomee "2> /dev/null"); 401*e77b06d2Stomee system("svcadm enable -s " . 402*e77b06d2Stomee "svc:/network/nfs/mapid:default"); 403*e77b06d2Stomee 404*e77b06d2Stomee # 405*e77b06d2Stomee # That should have caused DTrace to reload with 406*e77b06d2Stomee # the new configuration file. Now we can try to 407*e77b06d2Stomee # snag our anonymous state. 408*e77b06d2Stomee # 409*e77b06d2Stomee if (($pid = fork()) == -1) { 410*e77b06d2Stomee errmsg("ERROR: failed to fork to run " . 411*e77b06d2Stomee "test $file: $!\n"); 412*e77b06d2Stomee next; 413*e77b06d2Stomee } 414*e77b06d2Stomee 415*e77b06d2Stomee if ($pid == 0) { 416*e77b06d2Stomee open(STDIN, '</dev/null'); 417*e77b06d2Stomee exit(125) unless open(STDOUT, ">$opt_d/$$.out"); 418*e77b06d2Stomee exit(125) unless open(STDERR, ">$opt_d/$$.err"); 419*e77b06d2Stomee 420*e77b06d2Stomee push(@dtrace_argv, '-a'); 421*e77b06d2Stomee 422*e77b06d2Stomee unless (chdir($dir)) { 423*e77b06d2Stomee warn "ERROR: failed to chdir " . 424*e77b06d2Stomee "for $file: $!\n"; 425*e77b06d2Stomee exit(126); 426*e77b06d2Stomee } 427*e77b06d2Stomee 428*e77b06d2Stomee exec($dtrace, @dtrace_argv); 429*e77b06d2Stomee warn "ERROR: failed to exec for $file: $!\n"; 430*e77b06d2Stomee exit(127); 431*e77b06d2Stomee } 432*e77b06d2Stomee 433*e77b06d2Stomee if (waitpid($pid, 0) == -1) { 434*e77b06d2Stomee errmsg("ERROR: timed out waiting for $file\n"); 435*e77b06d2Stomee kill(9, $pid); 436*e77b06d2Stomee next; 437*e77b06d2Stomee } 438*e77b06d2Stomee } 439*e77b06d2Stomee 440*e77b06d2Stomee logmsg("[$pid]\n"); 441*e77b06d2Stomee $wstat = $?; 442*e77b06d2Stomee $wifexited = ($wstat & 0xFF) == 0; 443*e77b06d2Stomee $wexitstat = ($wstat >> 8) & 0xFF; 444*e77b06d2Stomee $wtermsig = ($wstat & 0x7F); 445*e77b06d2Stomee 446*e77b06d2Stomee if (!$wifexited) { 447*e77b06d2Stomee fail("died from signal $wtermsig"); 448*e77b06d2Stomee next; 449*e77b06d2Stomee } 450*e77b06d2Stomee 451*e77b06d2Stomee if ($wexitstat == 125) { 452*e77b06d2Stomee die "$PNAME: failed to create output file in $opt_d " . 453*e77b06d2Stomee "(cd elsewhere or use -d)\n"; 454*e77b06d2Stomee } 455*e77b06d2Stomee 456*e77b06d2Stomee if ($wexitstat != $status) { 457*e77b06d2Stomee fail("returned $wexitstat instead of $status"); 458*e77b06d2Stomee next; 459*e77b06d2Stomee } 460*e77b06d2Stomee 461*e77b06d2Stomee if (-f "$file.out" && 462*e77b06d2Stomee system("cmp -s $file.out $opt_d/$pid.out") != 0) { 463*e77b06d2Stomee fail("stdout mismatch", "$pid.out"); 464*e77b06d2Stomee next; 465*e77b06d2Stomee } 466*e77b06d2Stomee 467*e77b06d2Stomee if (-f "$file.err" && 468*e77b06d2Stomee system("cmp -s $file.err $opt_d/$pid.err") != 0) { 469*e77b06d2Stomee fail("stderr mismatch: see $pid.err"); 470*e77b06d2Stomee next; 471*e77b06d2Stomee } 472*e77b06d2Stomee 473*e77b06d2Stomee if ($tag) { 474*e77b06d2Stomee open(TSTERR, "<$opt_d/$pid.err"); 475*e77b06d2Stomee $tsterr = <TSTERR>; 476*e77b06d2Stomee close(TSTERR); 477*e77b06d2Stomee 478*e77b06d2Stomee unless ($tsterr =~ /: \[$tag\] line \d+:/) { 479*e77b06d2Stomee fail("errtag mismatch: see $pid.err"); 480*e77b06d2Stomee next; 481*e77b06d2Stomee } 482*e77b06d2Stomee } 483*e77b06d2Stomee 484*e77b06d2Stomee if ($droptag) { 485*e77b06d2Stomee $found = 0; 486*e77b06d2Stomee open(TSTERR, "<$opt_d/$pid.err"); 487*e77b06d2Stomee 488*e77b06d2Stomee while (<TSTERR>) { 489*e77b06d2Stomee if (/\[$droptag\] /) { 490*e77b06d2Stomee $found = 1; 491*e77b06d2Stomee last; 492*e77b06d2Stomee } 493*e77b06d2Stomee } 494*e77b06d2Stomee 495*e77b06d2Stomee close (TSTERR); 496*e77b06d2Stomee 497*e77b06d2Stomee unless ($found) { 498*e77b06d2Stomee fail("droptag mismatch: see $pid.err"); 499*e77b06d2Stomee next; 500*e77b06d2Stomee } 501*e77b06d2Stomee } 502*e77b06d2Stomee 503*e77b06d2Stomee unless ($opt_s) { 504*e77b06d2Stomee unlink($pid . '.out'); 505*e77b06d2Stomee unlink($pid . '.err'); 506*e77b06d2Stomee } 507*e77b06d2Stomee } 508*e77b06d2Stomee 509*e77b06d2Stomee if ($opt_a) { 510*e77b06d2Stomee # 511*e77b06d2Stomee # If we're running with anonymous enablings, we need to 512*e77b06d2Stomee # restore the .conf file. 513*e77b06d2Stomee # 514*e77b06d2Stomee system("dtrace -A 1> /dev/null 2> /dev/null"); 515*e77b06d2Stomee system("dtrace -ae 1> /dev/null 2> /dev/null"); 516*e77b06d2Stomee system("modunload -i 0 ; modunload -i 0 ; modunload -i 0"); 517*e77b06d2Stomee system("update_drv dtrace"); 518*e77b06d2Stomee } 519*e77b06d2Stomee 520*e77b06d2Stomee $total = scalar(@files); 521*e77b06d2Stomee $failed = $errs - $failed; 522*e77b06d2Stomee $passed = ($total - $failed - $bypassed); 523*e77b06d2Stomee $results{$dtrace} = { 524*e77b06d2Stomee "passed" => $passed, 525*e77b06d2Stomee "bypassed" => $bypassed, 526*e77b06d2Stomee "failed" => $failed, 527*e77b06d2Stomee "total" => $total 528*e77b06d2Stomee }; 529*e77b06d2Stomee} 530*e77b06d2Stomee 53123b5c241Stomeedie $USAGE unless (getopts($OPTSTR)); 5329512fe85Sahlusage() if ($opt_h); 5339512fe85Sahl 5349512fe85Sahlforeach $arg (@ARGV) { 5359512fe85Sahl if (-f $arg) { 5369512fe85Sahl push(@files, $arg); 5379512fe85Sahl } elsif (-d $arg) { 5389512fe85Sahl find(\&wanted, $arg); 5399512fe85Sahl } else { 5409512fe85Sahl die "$PNAME: $arg is not a valid file or directory\n"; 5419512fe85Sahl } 5429512fe85Sahl} 5439512fe85Sahl 54423b5c241Stomee$dt_tst = '/opt/SUNWdtrt/tst'; 54523b5c241Stomee$dt_bin = '/opt/SUNWdtrt/bin'; 54623b5c241Stomee$defdir = -d $dt_tst ? $dt_tst : '.'; 54723b5c241Stomee$bindir = -d $dt_bin ? $dt_bin : '.'; 5489512fe85Sahl 5499512fe85Sahlfind(\&wanted, "$defdir/common") if (scalar(@ARGV) == 0); 5509512fe85Sahlfind(\&wanted, "$defdir/$MACH") if (scalar(@ARGV) == 0); 5519512fe85Sahldie $USAGE if (scalar(@files) == 0); 5529512fe85Sahl 553*e77b06d2Stomee$dtrace_path = '/usr/sbin/dtrace'; 554*e77b06d2Stomee$jdtrace_path = "$bindir/jdtrace"; 555*e77b06d2Stomee 556*e77b06d2Stomee%exception_lists = ("$jdtrace_path" => "$bindir/exception.lst"); 557*e77b06d2Stomee 558*e77b06d2Stomeeif ($opt_j || $opt_n || $opt_i) { 559*e77b06d2Stomee @dtrace_cmds = (); 560*e77b06d2Stomee push(@dtrace_cmds, $dtrace_path) if ($opt_n); 561*e77b06d2Stomee push(@dtrace_cmds, $jdtrace_path) if ($opt_j); 562*e77b06d2Stomee push(@dtrace_cmds, "/usr/sbin/$opt_i/dtrace") if ($opt_i); 563*e77b06d2Stomee} else { 564*e77b06d2Stomee @dtrace_cmds = ($dtrace_path, $jdtrace_path); 565*e77b06d2Stomee} 566*e77b06d2Stomee 5679512fe85Sahlif ($opt_d) { 5689512fe85Sahl die "$PNAME: -d arg must be absolute path\n" unless ($opt_d =~ /^\//); 5699512fe85Sahl die "$PNAME: -d arg $opt_d is not a directory\n" unless (-d "$opt_d"); 5709512fe85Sahl system("coreadm -p $opt_d/%p.core"); 5719512fe85Sahl} else { 5729512fe85Sahl my $dir = getcwd; 5739512fe85Sahl system("coreadm -p $dir/%p.core"); 5749512fe85Sahl $opt_d = '.'; 5759512fe85Sahl} 5769512fe85Sahl 5779512fe85Sahlif ($opt_x) { 5789512fe85Sahl push(@dtrace_argv, '-x'); 5799512fe85Sahl push(@dtrace_argv, $opt_x); 5809512fe85Sahl} 5819512fe85Sahl 5829512fe85Sahldie "$PNAME: failed to open $PNAME.$$.log: $!\n" 5839512fe85Sahl unless (!$opt_l || open(LOG, ">$PNAME.$$.log")); 5849512fe85Sahl 5859512fe85Sahlif ($opt_g) { 5869512fe85Sahl $ENV{'UMEM_DEBUG'} = 'default,verbose'; 5879512fe85Sahl $ENV{'UMEM_LOGGING'} = 'fail,contents'; 5889512fe85Sahl $ENV{'LD_PRELOAD'} = 'libumem.so'; 5899512fe85Sahl} 5909512fe85Sahl 5919512fe85Sahl# 5929512fe85Sahl# Ensure that $PATH contains a cc(1) so that we can execute the 5939512fe85Sahl# test programs that require compilation of C code. 5949512fe85Sahl# 5952b6e762cSahl$ENV{'PATH'} = $ENV{'PATH'} . ':/ws/onnv-tools/SUNWspro/SS11/bin'; 5969512fe85Sahl 5979512fe85Sahlif ($opt_b) { 5989512fe85Sahl logmsg("badioctl'ing ... "); 5999512fe85Sahl 6009512fe85Sahl if (($badioctl = fork()) == -1) { 6019512fe85Sahl errmsg("ERROR: failed to fork to run badioctl: $!\n"); 6029512fe85Sahl next; 6039512fe85Sahl } 6049512fe85Sahl 6059512fe85Sahl if ($badioctl == 0) { 6069512fe85Sahl open(STDIN, '</dev/null'); 6079512fe85Sahl exit(125) unless open(STDOUT, ">$opt_d/$$.out"); 6089512fe85Sahl exit(125) unless open(STDERR, ">$opt_d/$$.err"); 6099512fe85Sahl 6109512fe85Sahl exec($bindir . "/badioctl"); 6119512fe85Sahl warn "ERROR: failed to exec badioctl: $!\n"; 6129512fe85Sahl exit(127); 6139512fe85Sahl } 6149512fe85Sahl 6159512fe85Sahl 6169512fe85Sahl logmsg("[$badioctl]\n"); 6179512fe85Sahl 6189512fe85Sahl # 6199512fe85Sahl # If we're going to be bad, we're just going to iterate over each 6209512fe85Sahl # test file. 6219512fe85Sahl # 6229512fe85Sahl foreach $file (sort @files) { 6239512fe85Sahl ($name = $file) =~ s:.*/::; 6249512fe85Sahl $dir = dirname($file); 6259512fe85Sahl 6269512fe85Sahl if (!($name =~ /^tst\./ && $name =~ /\.d$/)) { 6279512fe85Sahl next; 6289512fe85Sahl } 6299512fe85Sahl 6309512fe85Sahl logmsg("baddof'ing $file ... "); 6319512fe85Sahl 6329512fe85Sahl if (($pid = fork()) == -1) { 6339512fe85Sahl errmsg("ERROR: failed to fork to run baddof: $!\n"); 6349512fe85Sahl next; 6359512fe85Sahl } 6369512fe85Sahl 6379512fe85Sahl if ($pid == 0) { 6389512fe85Sahl open(STDIN, '</dev/null'); 6399512fe85Sahl exit(125) unless open(STDOUT, ">$opt_d/$$.out"); 6409512fe85Sahl exit(125) unless open(STDERR, ">$opt_d/$$.err"); 6419512fe85Sahl 6429512fe85Sahl unless (chdir($dir)) { 6439512fe85Sahl warn "ERROR: failed to chdir for $file: $!\n"; 6449512fe85Sahl exit(126); 6459512fe85Sahl } 6469512fe85Sahl 6479512fe85Sahl exec($bindir . "/baddof", $name); 6489512fe85Sahl 6499512fe85Sahl warn "ERROR: failed to exec for $file: $!\n"; 6509512fe85Sahl exit(127); 6519512fe85Sahl } 6529512fe85Sahl 6539512fe85Sahl sleep 60; 6549512fe85Sahl kill(9, $pid); 6559512fe85Sahl waitpid($pid, 0); 6569512fe85Sahl 6579512fe85Sahl logmsg("[$pid]\n"); 6589512fe85Sahl 6599512fe85Sahl unless ($opt_s) { 6609512fe85Sahl unlink($pid . '.out'); 6619512fe85Sahl unlink($pid . '.err'); 6629512fe85Sahl } 6639512fe85Sahl } 6649512fe85Sahl 6659512fe85Sahl kill(9, $badioctl); 6669512fe85Sahl waitpid($badioctl, 0); 6679512fe85Sahl 6689512fe85Sahl unless ($opt_s) { 6699512fe85Sahl unlink($badioctl . '.out'); 6709512fe85Sahl unlink($badioctl . '.err'); 6719512fe85Sahl } 6729512fe85Sahl 6739512fe85Sahl exit(0); 6749512fe85Sahl} 6759512fe85Sahl 6769512fe85Sahl# 677*e77b06d2Stomee# Run all the tests specified on the command-line (the entire test suite 678*e77b06d2Stomee# by default) once for each dtrace command tested, skipping any tests 679*e77b06d2Stomee# not valid for that command. 6809512fe85Sahl# 681*e77b06d2Stomeeforeach $dtrace_cmd (@dtrace_cmds) { 682*e77b06d2Stomee run_tests($dtrace_cmd, $exception_lists{$dtrace_cmd}); 6839512fe85Sahl} 6849512fe85Sahl 6859512fe85Sahl$opt_q = 0; # force final summary to appear regardless of -q option 6869512fe85Sahl 6879512fe85Sahllogmsg("\n==== TEST RESULTS ====\n"); 688*e77b06d2Stomeeforeach $key (keys %results) { 689*e77b06d2Stomee my $passed = $results{$key}{"passed"}; 690*e77b06d2Stomee my $bypassed = $results{$key}{"bypassed"}; 691*e77b06d2Stomee my $failed = $results{$key}{"failed"}; 692*e77b06d2Stomee my $total = $results{$key}{"total"}; 693*e77b06d2Stomee 694*e77b06d2Stomee logmsg("\n mode: " . $key . "\n"); 695*e77b06d2Stomee logmsg(" passed: " . $passed . "\n"); 696*e77b06d2Stomee if ($bypassed) { 697*e77b06d2Stomee logmsg(" bypassed: " . $bypassed . "\n"); 698*e77b06d2Stomee } 699*e77b06d2Stomee logmsg(" failed: " . $failed . "\n"); 700*e77b06d2Stomee logmsg(" total: " . $total . "\n"); 7019512fe85Sahl} 7029512fe85Sahl 7039512fe85Sahlexit($errs != 0); 704