#!/usr/bin/perl -w =head1 Attribute Time Test This simple script tests the performance on the attribute server in multiple-PEG queries. Each test takes a PEG set and computes the mean time required to run the attribute request by running multiple trials. The user can specify a single test, multiple tests with different sizes, or multiple tests with a single size. The currently-supported command-line options are as follows. =over 4 =item user Name suffix to be used for log files. If omitted, the PID is used. =item trace Numeric trace level. A higher trace level causes more messages to appear. The default trace level is 2. Tracing will be directly to the standard output as well as to a CIC<.log> file in the FIG temporary directory, where I is the value of the B option above. =item sql If specified, turns on tracing of SQL activity. =item background Save the standard and error output to files. The files will be created in the FIG temporary directory and will be named CIC<.log> and CIC<.log>, respectively, where I is the value of the B option above. =item h Display this command's parameters and options. =item phone Phone number to message when the script is complete. =item count Number of pegs to test. The default is 100. =item trials Number of trials. The default is 50. =item tests Number of separate PEG sets to test. =item increment Number of PEGs to add for each test. If this is 0, every test will be for the same number of PEGs. =back =cut use strict; use Tracer; use DocUtils; use TestUtils; use Cwd; use File::Copy; use File::Path; use FIG; use Time::HiRes qw(time); # Get the command-line options and parameters. my ($options, @parameters) = StandardSetup([qw(FIG) ], { trace => [2, "tracing level"], count => [100, "number of PEGs per trial"], trials => [50, "number of trials"], tests => [1, "number of PEG sets to test"], increment => [100, "number of PEGs to add between tests"], phone => ["", "phone number (international format) to call when load finishes"], }, "", @ARGV); # Set a variable to contain return type information. my $rtype; # Insure we catch errors. eval { # Get a FIG object. my $fig = FIG->new(); # Do one test at a time. for (my $test = 1; $test <= $options->{tests}; $test++) { # Compute the number of PEGs for this test. my $pegCount = $options->{count} + $options->{increment}*($test - 1); Trace("Preparing test $test for $pegCount PEGs.") if T(3); # Now get the genomes. my %genomes = map { $_ => 1 } $fig->genomes(); # This gives us the genomes in a mixed-up order. my @genomeList = keys %genomes; # Compute the number of PEGs per genome. We allow for the possibility of some genomes # not having enough, so it's not a straight division. my $pegsPerGenome = int(4 * $pegCount / scalar(@genomeList)); $pegsPerGenome = 10 if $pegsPerGenome < 10; # Now we accumulate the PEGs in a hash. my %pegs = (); Trace("Accumulating PEGs at a rate of $pegsPerGenome per genome.") if T(2); # Loop until we have enough PEGs. while (scalar(keys %pegs) < $pegCount && scalar(@genomeList)) { # Get a genome. my $genome = pop @genomeList; Trace("Pulling PEGs from $genome.") if T(3); # Get some of its pegs in subsystems. my @newPegs = $fig->assigned_pegs_in_subsystems($genome); for (my $i = 0; $i <= $#newPegs && $i <= $pegsPerGenome; $i++) { $pegs{$newPegs[$i]} = 1; } } # Get the PEGs into a list and reduce it to the correct size. my @keyList = keys %pegs; while (scalar(@keyList) > $pegCount) { pop @keyList; } my $count = scalar(@keyList); Trace("$count PEGs accumulated.") if T(2); # Now we have our pegs. Try the retrieval and time it. my $seconds = 0; for (my $i = 0; $i < $options->{trials}; $i++) { my @attrs; my $now = time(); @attrs = $fig->get_attributes(\@keyList, "evidence_code"); $seconds += time() - $now; } my $actualTime = $seconds / $options->{trials}; Trace("$count pegs processed in $actualTime seconds.") if T(2); } Trace("Tests complete.") if T(2); }; if ($@) { Trace("Script failed with error: $@") if T(0); $rtype = "error"; } else { Trace("Script complete.") if T(2); $rtype = "no error"; } if ($options->{phone}) { my $msgID = Tracer::SendSMS($options->{phone}, "Attribute Time Test terminated with $rtype."); if ($msgID) { Trace("Phone message sent with ID $msgID.") if T(2); } else { Trace("Phone message not sent.") if T(2); } } 1;