1 #!/usr/perl5/bin/perl
   2 #
   3 # Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
   4 #
   5 
   6 #
   7 # This script is a stress test for ::Exacct and libexacct.
   8 # See README for details.
   9 #
  10 
  11 use strict;
  12 use warnings;
  13 use blib;
  14 use POSIX qw(:sys_wait_h);
  15 
  16 use Sun::Solaris::Exacct qw(:ALL);
  17 use Sun::Solaris::Exacct::Catalog qw(:ALL);
  18 use Sun::Solaris::Exacct::Object qw(:ALL);
  19 use Sun::Solaris::Exacct::File qw(:ALL);
  20 use Fcntl;
  21 
  22 our $exit = 0;
  23 our $ono  = 1;
  24 our $maxono = 1000;     # max = 16777216 (2^24)
  25 
  26 #
  27 # Dump an object.
  28 #
  29 sub dump_object
  30 {
  31         my ($obj, $fh, $indent) = @_;
  32         $fh ||= \*STDOUT;
  33         $indent ||= 0;
  34         my @cat = $obj->catalog()->value();
  35         my $istr = '  ' x $indent;
  36 
  37         if ($obj->type() == &EO_ITEM) {
  38                 printf $fh ("%sITEM\n%s  Catalog = %s|%s|%d\n", 
  39                    $istr, $istr, @cat);
  40                 $indent++;
  41                 my $val = $obj->value();
  42                 if (ref($val)) {
  43                         dump_object($val, $fh, $indent);
  44                 } else {
  45                         printf $fh ("%s  Value = %s\n", $istr, $val);
  46                 }
  47         } else {
  48                 printf $fh ("%sGROUP\n%s  Catalog = %s|%s|%d\n",
  49                     $istr, $istr, @cat);
  50                 $indent++;
  51                 foreach my $val ($obj->value()) {
  52                         dump_object($val, $fh, $indent);
  53                 }
  54                 printf $fh ("%sENDGROUP\n", $istr);
  55         }
  56 }
  57 
  58 #
  59 # Dump a list of objects.
  60 #
  61 sub dump_objects
  62 {
  63         my ($fh, $objs) = @_;
  64         foreach my $o (@$objs) {
  65                 dump_object($o, $fh);
  66         }
  67 }
  68 
  69 #
  70 # Build up a set of random objects.
  71 #
  72 sub gen_objs
  73 {
  74         my ($nobjs, $embed) = @_;
  75         $nobjs += $ono;
  76         $embed ||= 0;
  77         my @objs;
  78         while ($ono < $nobjs) {
  79                 my $rt = int(rand(9)) + 1;
  80                 $rt = 15 if ($rt >= 9);      # Group.
  81                 $rt <<= 28;
  82                 if ($rt == &EXT_UINT8) {
  83                         push(@objs, ea_new_item($rt | $ono++, 8));
  84                 } elsif ($rt == &EXT_UINT16) {
  85                         push(@objs, ea_new_item($rt | $ono++, 16));
  86                 } elsif ($rt == &EXT_UINT32) {
  87                         push(@objs, ea_new_item($rt | $ono++, 32));
  88                 } elsif ($rt == &EXT_UINT64) {
  89                         push(@objs, ea_new_item($rt | $ono++, 64));
  90                 } elsif ($rt == &EXT_DOUBLE) {
  91                         push(@objs, ea_new_item($rt | $ono++,
  92                             123456789.123456789));
  93                 } elsif ($rt == &EXT_STRING) {
  94                         push(@objs, ea_new_item($rt | $ono++, "string"));
  95                 } elsif ($rt == &EXT_EXACCT_OBJECT) {
  96                         my $o = $ono++;
  97                         my $i = int(rand($nobjs - $ono)) + 1;
  98                         push(@objs, ea_new_item($rt | $o, gen_objs($i, 1)));
  99                 } elsif ($rt == &EXT_RAW) {
 100                         push(@objs, ea_new_item($rt | $ono++, "RAWrawRAW"));
 101                 } elsif ($rt == &EXT_GROUP) {
 102                         my $o = $ono++;
 103                         my $i = int(rand($nobjs - $ono + 1));
 104                         push(@objs, ea_new_group($rt | $o, gen_objs($i)));
 105                 }
 106 
 107                 # If for an embedded object, just return 1 object.
 108                 last if ($embed);
 109         }
 110         return(@objs);
 111 }
 112 
 113 #
 114 # Main routine.
 115 #
 116 $| = 1;
 117 $SIG{INT} = $SIG{TERM} = $SIG{HUP} = sub { $exit = 1; };
 118 my $iters = 0;
 119 while (! $exit) {
 120         print(".");
 121 
 122         # Generate and output some random records.
 123         my $f = ea_new_file("/tmp/wr.$$", &O_RDWR | &O_CREAT | &O_TRUNC)
 124             || die("\ncreate /tmp/wr.$$ failed: ", ea_error_str(), "\n");
 125         my @outobjs = gen_objs($maxono);
 126         $f->write(@outobjs);
 127         $f = undef;
 128         open($f, ">/tmp/wr1.$$") || die("\nopen /tmp/wr1.$$ failed: $!\n");
 129         dump_objects($f, \@outobjs);
 130         close($f);
 131         @outobjs = ();
 132 
 133         # Scan the file forwards with next.
 134         $f = ea_new_file("/tmp/wr.$$", &O_RDONLY)
 135             || die("\nopen /tmp/wr.$$ failed: ", ea_error_str(), "\n");
 136         while ($f->next()) {
 137                 ;
 138         }
 139         die("\nnext /tmp/wr.$$ failed: ", ea_error_str(), "\n")
 140             unless (ea_error() == EXR_EOF);
 141         $f = undef;
 142 
 143         # Scan the file backwards with previous.
 144         $f = ea_new_file("/tmp/wr.$$", &O_RDONLY, aflags => &EO_TAIL)
 145             || die("\nopen /tmp/wr.$$ failed: ", ea_error_str(), "\n");
 146         while ($f->previous()) {
 147                 ;
 148         }
 149         die("\nprevious /tmp/wr.$$ failed: ", ea_error_str(), "\n")
 150             unless (ea_error() == EXR_EOF);
 151         $f = undef;
 152 
 153         # Read the file forwards with get.
 154         my @inobjs = ();
 155         $f = ea_new_file("/tmp/wr.$$", &O_RDONLY)
 156             || die("\nopen /tmp/wr.$$ failed: ", ea_error_str(), "\n");
 157         while (my $obj = $f->get()) {
 158                 push(@inobjs, $obj);
 159         }
 160         die("\nget /tmp/wr.$$ failed: ", ea_error_str(), "\n")
 161             unless (ea_error() == EXR_EOF);
 162         $f = undef;
 163 
 164         # Dump the objects and compare with original.
 165         open($f, ">/tmp/wr2.$$") || die("\nopen /tmp/wr2.$$ failed: $!\n");
 166         dump_objects($f, \@inobjs);
 167         close($f);
 168         if (system("cmp -s /tmp/wr1.$$ /tmp/wr2.$$") != 0) {
 169                 die("\nget cmp failed /tmp/wr2.$$\n");
 170         }
 171 
 172         # Read the file forwards with next and get.
 173         @inobjs = ();
 174         $f = ea_new_file("/tmp/wr.$$", &O_RDONLY)
 175             || die("\nopen /tmp/wr.$$ failed: ", ea_error_str(), "\n");
 176         while ($f->next()) {
 177                 my $obj = $f->get();
 178                 push(@inobjs, $obj);
 179         }
 180         die("\nnext/get /tmp/wr.$$ failed: ", ea_error_str(), "\n")
 181             unless (ea_error() == EXR_EOF);
 182         $f = undef;
 183 
 184         # Dump the objects and compare with original.
 185         open($f, ">/tmp/wr2.$$") || die("\nopen /tmp/wr2.$$ failed: $!\n");
 186         dump_objects($f, \@inobjs);
 187         close($f);
 188         if (system("cmp -s /tmp/wr1.$$ /tmp/wr2.$$") != 0) {
 189                 die("\nnext/get cmp failed /tmp/wr2.$$\n");
 190         }
 191 
 192         # Read the file backwards with previous and get.
 193         @inobjs = ();
 194         $f = ea_new_file("/tmp/wr.$$", &O_RDONLY, aflags => &EO_TAIL)
 195             || die("\nopen /tmp/wr.$$ failed: ", ea_error_str(), "\n");
 196         while ($f->previous()) {
 197                 my $obj = $f->get();
 198                 $f->previous();
 199                 unshift(@inobjs, $obj);
 200         }
 201         die("\nprevious/get /tmp/wr.$$ failed: ", ea_error_str(), "\n")
 202             unless (ea_error() == EXR_EOF);
 203         $f = undef;
 204 
 205         # Dump the objects and compare with original.
 206         open($f, ">/tmp/wr2.$$") || die("\nopen /tmp/wr2.$$ failed: $!\n");
 207         dump_objects($f, \@inobjs);
 208         close($f);
 209         if (system("cmp -s /tmp/wr1.$$ /tmp/wr2.$$") != 0) {
 210                 die("\nprevious/get cmp failed /tmp/wr2.$$\n");
 211         }
 212 
 213         # Run randtest on the file.
 214         foreach my $sz (qw(5 10 50 100)) {
 215                 my $s = system ("./randtest 1000 $sz /tmp/wr.$$") >> 8;
 216                 if ($s == 2) {
 217                         $exit = 1;
 218                 } elsif ($s != 0) {
 219                         die("randtest 1000 $sz /tmp/wr.$$ failed $s\n");
 220                 }
 221         }
 222 
 223         $iters++;
 224 }
 225 unlink("/tmp/wr.$$", "/tmp/wr1.$$", "/tmp/wr2.$$") ||
 226     die("\nCan't cleanup: $!\n");
 227 print("\n$iters iterations completed\n");