home *** CD-ROM | disk | FTP | other *** search
- use Benchmark;
- use Getopt::Long;
- use File::Basename;
- use XML::XPath;
- use strict;
-
- $|++;
-
- my @default_drivers = qw(
- LibXSLT
- Sablotron
- );
-
- use vars qw(
- $component $iter $ms $kb_in $kb_out $kb_sec $result $ref_size
- );
-
- my @getopt_args = (
- 'c=s', # config file
- 'n=i', # number of benchmark times
- 'd=s@', # drivers
- 't', # only 1 iteration per test
- 'v', # verbose
- 'h', # help
- 'x', # XSLTMark emulation
- );
-
- my %options;
-
- Getopt::Long::config("bundling");
-
- unless (GetOptions(\%options, @getopt_args)) {
- usage();
- }
-
- usage() if $options{h};
-
- $options{c} ||= 'testcases/default.conf';
-
- my $basedir = dirname($options{c});
-
- $options{d} ||= [@default_drivers];
-
- $options{n} ||= 1;
-
- # load drivers
- for my $driver (@{$options{d}}) {
- warn "Loading $driver Driver\n" if $options{v};
- require "Driver/$driver.pm";
- }
-
- # load config
- my @config;
- open(CONFIG, $options{c}) || die "Can't open config file '$options{c}' : $!";
- my $current = {};
- while(my $line = <CONFIG>) {
- if ($line =~ /^\s*$/m && %$current) {
- push @config, $current;
- $current = {};
- }
-
- # ignore comments and full line comments
- $line =~ s/#.*$//;
- next unless $line =~ /\S/;
-
- if ($line =~ /^\s*\[(.*)\]\s*$/) {
- $current->{component} = $1;
- }
- elsif ($line =~ /^(.*?)\s*=\s*(.*)$/) {
- $current->{$1} = $2;
- }
- }
-
- for my $driver (@{$options{d}}) {
- my $pkg = "Driver::${driver}";
-
- $pkg->can('init')->(verbose => $options{v});
-
- $pkg->can('chdir')->($basedir);
-
- print "Testing: $driver\n\n";
-
- print_header();
-
- my %totals;
-
- COMPONENT:
- for my $cmp (@config) {
- warn "Running test: $cmp->{component}\n" if $options{v};
- for (1..$options{n}) {
- $component = $cmp->{component};
- $iter = $ms = $kb_in = $kb_out = $kb_sec = $ref_size = 0;
-
- if ($cmp->{skipdriver} =~ /\b\Q$driver\E\b/) {
- $result = 'SKIPPED';
- print_output() unless $cmp->{written};
- $cmp->{written}++;
- next COMPONENT;
- }
-
- eval {
- $pkg->can('load_stylesheet')->($cmp->{stylesheet});
- $pkg->can('load_input')->($cmp->{input});
-
- $iter = $cmp->{iterations};
- $iter = 1 if $options{t};
-
-
- my $bench = timeit($iter, sub {
- $pkg->can('run_transform')->($cmp->{output});
- });
-
- my $str = timestr($bench, 'all', '5.4f');
-
- if ($str =~ /\((\d+\.\d+)/) {
- $ms = $1;
- $ms *= 1000;
- }
-
- $kb_in = (stat($cmp->{input}))[7];
-
- if ($options{x}) {
- $kb_in /= 1000;
- }
- else {
- $kb_in += (stat($cmp->{stylesheet}))[7];
- $kb_in /= 1024;
- }
-
- $kb_in *= $iter;
-
- $kb_out = (stat($cmp->{output}))[7];
- $kb_out /= 1024;
- $kb_out *= $iter;
-
- die "failed - no output\n" unless $kb_out > 0;
-
- $kb_sec = ($kb_in + $kb_out) /
- ( $ms / 500 );
-
- if ($cmp->{reference}) {
- $ref_size = (stat($cmp->{reference}))[7];
- $ref_size /= 1024;
-
- open(REFERENCE, $cmp->{reference}) || die "Can't open reference '$cmp->{reference}' : $!";
- open(NEW, $cmp->{output}) || die "Can't open transform output '$cmp->{output}' : $!";
- local $/;
- my $ref = <REFERENCE>;
- my $new = <NEW>;
- close REFERENCE;
- close NEW;
- $new =~ s/\A<\?xml.*?\?>\s*//;
- $new =~ s/\A<!DOCTYPE.*?>\s*//;
-
- if (!length($new)) {
- die "output length failed\n";
- }
- if ($new eq $ref) {
- $result = 'OK';
- }
- else {
- $result = 'CHECK OUTPUT';
- eval {
- my $rpp = XML::XPath->new(xml => $ref);
- my $ppp = XML::XPath::XMLParser->new(xml => $new);
- my $npp;
- eval {
- $npp = $ppp->parse;
- };
- if ($@) {
- $npp = $ppp->parse("<norm>$new</norm>");
- }
- my @rnodes = $rpp->findnodes('//*');
- my @nnodes = $npp->findnodes('//*');
- # warn "ref nodes: ", scalar(@rnodes), "\n";
- # warn "new nodes: ", scalar(@nnodes), "\n";
- if (@rnodes == @nnodes) {
- $result = 'COUNT OK';
- }
- };
- if ($@) {
- warn $@ if $options{v};
- }
- }
- }
- else {
- $result = 'NO REFERENCE';
- }
- };
- if ($@) {
- warn "$component failed: $@" if $options{v};
- $result = 'ERROR';
- }
-
- if (($result =~ /OK/) || ($result eq 'NO REFERENCE')) {
- $totals{iter} += $iter;
- $totals{ms} += $ms;
- $totals{kb_in} += $kb_in;
- $totals{kb_out} += $kb_out;
- }
-
- print_output() unless $cmp->{written};
- $cmp->{written}++;
- } # $options{n} loop
-
- delete $cmp->{written};
- } # each component
-
- $pkg->can('shutdown')->();
-
- $component = 'total';
- $iter = $totals{iter};
- $ms = $totals{ms};
- $kb_in = $totals{kb_in};
- $kb_out = $totals{kb_out};
- $kb_sec = ($kb_in + $kb_out) /
- ( $ms / 500 );
- $ref_size = 0;
- $result = '';
- print_output();
- }
-
- sub usage {
- print <<EOT;
- usage: $0 [options]
-
- options:
-
- -c <file> load configuration from <file>
- defaults to testcases/default.conf
-
- -n <num> run each test case <num> times. Default = 1.
-
- -t only one iteration per test case (note this
- is different to -n 1)
-
- -d <Driver> test <Driver>. Use multiple -d options to test
- more than one driver. Defaults are set in this
- script (the \@default_drivers variable).
-
- -x XSLTMark emulation. Infuriatingly XSLTMark thinks
- there are 1000 bytes in a Kilobyte. Someone please
- tell them some basic computer science...
-
- Without this option, this benchmark also includes
- the size of the stylesheet in the KB In figure.
-
- -v be verbose.
-
- Copyright 2001 AxKit.com Ltd. This is free software, you may use it and
- distribute it under either the GNU GPL Version 2, or under the Perl
- Artistic License.
-
- EOT
- exit(0);
- }
-
- sub print_header {
- print STDOUT <<'EOF';
- Test Component Iter ms KB In KB Out KB/s Result
- ==========================================================================
- EOF
- }
-
- sub print_output {
- printf STDOUT "%-15.15s %5.0d %5.0d %7.0f %7.0f %9.2f %-15.15s\n",
- $component, $iter, $ms, $kb_in, $kb_out, $kb_sec, $result;
- }
-