10Sstevel@tonic-gate#!/usr/perl5/bin/perl 20Sstevel@tonic-gate# 3*12388SJohn.Sonnenschein@Sun.COM# Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. 40Sstevel@tonic-gate# 5*12388SJohn.Sonnenschein@Sun.COM 60Sstevel@tonic-gate# 70Sstevel@tonic-gate# This script is a stress test for ::Exacct and libexacct. 80Sstevel@tonic-gate# See README for details. 90Sstevel@tonic-gate# 100Sstevel@tonic-gate 110Sstevel@tonic-gateuse strict; 120Sstevel@tonic-gateuse warnings; 130Sstevel@tonic-gateuse blib; 140Sstevel@tonic-gateuse POSIX qw(:sys_wait_h); 150Sstevel@tonic-gate 160Sstevel@tonic-gateuse Sun::Solaris::Exacct qw(:ALL); 170Sstevel@tonic-gateuse Sun::Solaris::Exacct::Catalog qw(:ALL); 180Sstevel@tonic-gateuse Sun::Solaris::Exacct::Object qw(:ALL); 190Sstevel@tonic-gateuse Sun::Solaris::Exacct::File qw(:ALL); 200Sstevel@tonic-gateuse Fcntl; 210Sstevel@tonic-gate 220Sstevel@tonic-gateour $exit = 0; 230Sstevel@tonic-gateour $ono = 1; 240Sstevel@tonic-gateour $maxono = 1000; # max = 16777216 (2^24) 250Sstevel@tonic-gate 260Sstevel@tonic-gate# 270Sstevel@tonic-gate# Dump an object. 280Sstevel@tonic-gate# 290Sstevel@tonic-gatesub dump_object 300Sstevel@tonic-gate{ 310Sstevel@tonic-gate my ($obj, $fh, $indent) = @_; 320Sstevel@tonic-gate $fh ||= \*STDOUT; 330Sstevel@tonic-gate $indent ||= 0; 340Sstevel@tonic-gate my @cat = $obj->catalog()->value(); 350Sstevel@tonic-gate my $istr = ' ' x $indent; 360Sstevel@tonic-gate 370Sstevel@tonic-gate if ($obj->type() == &EO_ITEM) { 380Sstevel@tonic-gate printf $fh ("%sITEM\n%s Catalog = %s|%s|%d\n", 390Sstevel@tonic-gate $istr, $istr, @cat); 400Sstevel@tonic-gate $indent++; 410Sstevel@tonic-gate my $val = $obj->value(); 420Sstevel@tonic-gate if (ref($val)) { 430Sstevel@tonic-gate dump_object($val, $fh, $indent); 440Sstevel@tonic-gate } else { 450Sstevel@tonic-gate printf $fh ("%s Value = %s\n", $istr, $val); 460Sstevel@tonic-gate } 470Sstevel@tonic-gate } else { 480Sstevel@tonic-gate printf $fh ("%sGROUP\n%s Catalog = %s|%s|%d\n", 490Sstevel@tonic-gate $istr, $istr, @cat); 500Sstevel@tonic-gate $indent++; 510Sstevel@tonic-gate foreach my $val ($obj->value()) { 520Sstevel@tonic-gate dump_object($val, $fh, $indent); 530Sstevel@tonic-gate } 540Sstevel@tonic-gate printf $fh ("%sENDGROUP\n", $istr); 550Sstevel@tonic-gate } 560Sstevel@tonic-gate} 570Sstevel@tonic-gate 580Sstevel@tonic-gate# 590Sstevel@tonic-gate# Dump a list of objects. 600Sstevel@tonic-gate# 610Sstevel@tonic-gatesub dump_objects 620Sstevel@tonic-gate{ 630Sstevel@tonic-gate my ($fh, $objs) = @_; 640Sstevel@tonic-gate foreach my $o (@$objs) { 650Sstevel@tonic-gate dump_object($o, $fh); 660Sstevel@tonic-gate } 670Sstevel@tonic-gate} 680Sstevel@tonic-gate 690Sstevel@tonic-gate# 700Sstevel@tonic-gate# Build up a set of random objects. 710Sstevel@tonic-gate# 720Sstevel@tonic-gatesub gen_objs 730Sstevel@tonic-gate{ 740Sstevel@tonic-gate my ($nobjs, $embed) = @_; 750Sstevel@tonic-gate $nobjs += $ono; 760Sstevel@tonic-gate $embed ||= 0; 770Sstevel@tonic-gate my @objs; 780Sstevel@tonic-gate while ($ono < $nobjs) { 790Sstevel@tonic-gate my $rt = int(rand(9)) + 1; 800Sstevel@tonic-gate $rt = 15 if ($rt >= 9); # Group. 810Sstevel@tonic-gate $rt <<= 28; 820Sstevel@tonic-gate if ($rt == &EXT_UINT8) { 830Sstevel@tonic-gate push(@objs, ea_new_item($rt | $ono++, 8)); 840Sstevel@tonic-gate } elsif ($rt == &EXT_UINT16) { 850Sstevel@tonic-gate push(@objs, ea_new_item($rt | $ono++, 16)); 860Sstevel@tonic-gate } elsif ($rt == &EXT_UINT32) { 870Sstevel@tonic-gate push(@objs, ea_new_item($rt | $ono++, 32)); 880Sstevel@tonic-gate } elsif ($rt == &EXT_UINT64) { 890Sstevel@tonic-gate push(@objs, ea_new_item($rt | $ono++, 64)); 900Sstevel@tonic-gate } elsif ($rt == &EXT_DOUBLE) { 910Sstevel@tonic-gate push(@objs, ea_new_item($rt | $ono++, 920Sstevel@tonic-gate 123456789.123456789)); 930Sstevel@tonic-gate } elsif ($rt == &EXT_STRING) { 940Sstevel@tonic-gate push(@objs, ea_new_item($rt | $ono++, "string")); 950Sstevel@tonic-gate } elsif ($rt == &EXT_EXACCT_OBJECT) { 960Sstevel@tonic-gate my $o = $ono++; 970Sstevel@tonic-gate my $i = int(rand($nobjs - $ono)) + 1; 980Sstevel@tonic-gate push(@objs, ea_new_item($rt | $o, gen_objs($i, 1))); 990Sstevel@tonic-gate } elsif ($rt == &EXT_RAW) { 1000Sstevel@tonic-gate push(@objs, ea_new_item($rt | $ono++, "RAWrawRAW")); 1010Sstevel@tonic-gate } elsif ($rt == &EXT_GROUP) { 1020Sstevel@tonic-gate my $o = $ono++; 1030Sstevel@tonic-gate my $i = int(rand($nobjs - $ono + 1)); 1040Sstevel@tonic-gate push(@objs, ea_new_group($rt | $o, gen_objs($i))); 1050Sstevel@tonic-gate } 1060Sstevel@tonic-gate 1070Sstevel@tonic-gate # If for an embedded object, just return 1 object. 1080Sstevel@tonic-gate last if ($embed); 1090Sstevel@tonic-gate } 1100Sstevel@tonic-gate return(@objs); 1110Sstevel@tonic-gate} 1120Sstevel@tonic-gate 1130Sstevel@tonic-gate# 1140Sstevel@tonic-gate# Main routine. 1150Sstevel@tonic-gate# 1160Sstevel@tonic-gate$| = 1; 1170Sstevel@tonic-gate$SIG{INT} = $SIG{TERM} = $SIG{HUP} = sub { $exit = 1; }; 1180Sstevel@tonic-gatemy $iters = 0; 1190Sstevel@tonic-gatewhile (! $exit) { 1200Sstevel@tonic-gate print("."); 1210Sstevel@tonic-gate 1220Sstevel@tonic-gate # Generate and output some random records. 1230Sstevel@tonic-gate my $f = ea_new_file("/tmp/wr.$$", &O_RDWR | &O_CREAT | &O_TRUNC) 1240Sstevel@tonic-gate || die("\ncreate /tmp/wr.$$ failed: ", ea_error_str(), "\n"); 1250Sstevel@tonic-gate my @outobjs = gen_objs($maxono); 1260Sstevel@tonic-gate $f->write(@outobjs); 1270Sstevel@tonic-gate $f = undef; 1280Sstevel@tonic-gate open($f, ">/tmp/wr1.$$") || die("\nopen /tmp/wr1.$$ failed: $!\n"); 1290Sstevel@tonic-gate dump_objects($f, \@outobjs); 1300Sstevel@tonic-gate close($f); 1310Sstevel@tonic-gate @outobjs = (); 1320Sstevel@tonic-gate 1330Sstevel@tonic-gate # Scan the file forwards with next. 1340Sstevel@tonic-gate $f = ea_new_file("/tmp/wr.$$", &O_RDONLY) 1350Sstevel@tonic-gate || die("\nopen /tmp/wr.$$ failed: ", ea_error_str(), "\n"); 1360Sstevel@tonic-gate while ($f->next()) { 1370Sstevel@tonic-gate ; 1380Sstevel@tonic-gate } 1390Sstevel@tonic-gate die("\nnext /tmp/wr.$$ failed: ", ea_error_str(), "\n") 1400Sstevel@tonic-gate unless (ea_error() == EXR_EOF); 1410Sstevel@tonic-gate $f = undef; 1420Sstevel@tonic-gate 1430Sstevel@tonic-gate # Scan the file backwards with previous. 1440Sstevel@tonic-gate $f = ea_new_file("/tmp/wr.$$", &O_RDONLY, aflags => &EO_TAIL) 1450Sstevel@tonic-gate || die("\nopen /tmp/wr.$$ failed: ", ea_error_str(), "\n"); 1460Sstevel@tonic-gate while ($f->previous()) { 1470Sstevel@tonic-gate ; 1480Sstevel@tonic-gate } 1490Sstevel@tonic-gate die("\nprevious /tmp/wr.$$ failed: ", ea_error_str(), "\n") 1500Sstevel@tonic-gate unless (ea_error() == EXR_EOF); 1510Sstevel@tonic-gate $f = undef; 1520Sstevel@tonic-gate 1530Sstevel@tonic-gate # Read the file forwards with get. 1540Sstevel@tonic-gate my @inobjs = (); 1550Sstevel@tonic-gate $f = ea_new_file("/tmp/wr.$$", &O_RDONLY) 1560Sstevel@tonic-gate || die("\nopen /tmp/wr.$$ failed: ", ea_error_str(), "\n"); 1570Sstevel@tonic-gate while (my $obj = $f->get()) { 1580Sstevel@tonic-gate push(@inobjs, $obj); 1590Sstevel@tonic-gate } 1600Sstevel@tonic-gate die("\nget /tmp/wr.$$ failed: ", ea_error_str(), "\n") 1610Sstevel@tonic-gate unless (ea_error() == EXR_EOF); 1620Sstevel@tonic-gate $f = undef; 1630Sstevel@tonic-gate 1640Sstevel@tonic-gate # Dump the objects and compare with original. 1650Sstevel@tonic-gate open($f, ">/tmp/wr2.$$") || die("\nopen /tmp/wr2.$$ failed: $!\n"); 1660Sstevel@tonic-gate dump_objects($f, \@inobjs); 1670Sstevel@tonic-gate close($f); 1680Sstevel@tonic-gate if (system("cmp -s /tmp/wr1.$$ /tmp/wr2.$$") != 0) { 1690Sstevel@tonic-gate die("\nget cmp failed /tmp/wr2.$$\n"); 1700Sstevel@tonic-gate } 1710Sstevel@tonic-gate 1720Sstevel@tonic-gate # Read the file forwards with next and get. 1730Sstevel@tonic-gate @inobjs = (); 1740Sstevel@tonic-gate $f = ea_new_file("/tmp/wr.$$", &O_RDONLY) 1750Sstevel@tonic-gate || die("\nopen /tmp/wr.$$ failed: ", ea_error_str(), "\n"); 1760Sstevel@tonic-gate while ($f->next()) { 1770Sstevel@tonic-gate my $obj = $f->get(); 1780Sstevel@tonic-gate push(@inobjs, $obj); 1790Sstevel@tonic-gate } 1800Sstevel@tonic-gate die("\nnext/get /tmp/wr.$$ failed: ", ea_error_str(), "\n") 1810Sstevel@tonic-gate unless (ea_error() == EXR_EOF); 1820Sstevel@tonic-gate $f = undef; 1830Sstevel@tonic-gate 1840Sstevel@tonic-gate # Dump the objects and compare with original. 1850Sstevel@tonic-gate open($f, ">/tmp/wr2.$$") || die("\nopen /tmp/wr2.$$ failed: $!\n"); 1860Sstevel@tonic-gate dump_objects($f, \@inobjs); 1870Sstevel@tonic-gate close($f); 1880Sstevel@tonic-gate if (system("cmp -s /tmp/wr1.$$ /tmp/wr2.$$") != 0) { 1890Sstevel@tonic-gate die("\nnext/get cmp failed /tmp/wr2.$$\n"); 1900Sstevel@tonic-gate } 1910Sstevel@tonic-gate 1920Sstevel@tonic-gate # Read the file backwards with previous and get. 1930Sstevel@tonic-gate @inobjs = (); 1940Sstevel@tonic-gate $f = ea_new_file("/tmp/wr.$$", &O_RDONLY, aflags => &EO_TAIL) 1950Sstevel@tonic-gate || die("\nopen /tmp/wr.$$ failed: ", ea_error_str(), "\n"); 1960Sstevel@tonic-gate while ($f->previous()) { 1970Sstevel@tonic-gate my $obj = $f->get(); 1980Sstevel@tonic-gate $f->previous(); 1990Sstevel@tonic-gate unshift(@inobjs, $obj); 2000Sstevel@tonic-gate } 2010Sstevel@tonic-gate die("\nprevious/get /tmp/wr.$$ failed: ", ea_error_str(), "\n") 2020Sstevel@tonic-gate unless (ea_error() == EXR_EOF); 2030Sstevel@tonic-gate $f = undef; 2040Sstevel@tonic-gate 2050Sstevel@tonic-gate # Dump the objects and compare with original. 2060Sstevel@tonic-gate open($f, ">/tmp/wr2.$$") || die("\nopen /tmp/wr2.$$ failed: $!\n"); 2070Sstevel@tonic-gate dump_objects($f, \@inobjs); 2080Sstevel@tonic-gate close($f); 2090Sstevel@tonic-gate if (system("cmp -s /tmp/wr1.$$ /tmp/wr2.$$") != 0) { 2100Sstevel@tonic-gate die("\nprevious/get cmp failed /tmp/wr2.$$\n"); 2110Sstevel@tonic-gate } 2120Sstevel@tonic-gate 2130Sstevel@tonic-gate # Run randtest on the file. 2140Sstevel@tonic-gate foreach my $sz (qw(5 10 50 100)) { 2150Sstevel@tonic-gate my $s = system ("./randtest 1000 $sz /tmp/wr.$$") >> 8; 2160Sstevel@tonic-gate if ($s == 2) { 2170Sstevel@tonic-gate $exit = 1; 2180Sstevel@tonic-gate } elsif ($s != 0) { 2190Sstevel@tonic-gate die("randtest 1000 $sz /tmp/wr.$$ failed $s\n"); 2200Sstevel@tonic-gate } 2210Sstevel@tonic-gate } 2220Sstevel@tonic-gate 2230Sstevel@tonic-gate $iters++; 2240Sstevel@tonic-gate} 2250Sstevel@tonic-gateunlink("/tmp/wr.$$", "/tmp/wr1.$$", "/tmp/wr2.$$") || 2260Sstevel@tonic-gate die("\nCan't cleanup: $!\n"); 2270Sstevel@tonic-gateprint("\n$iters iterations completed\n"); 228