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