-# $Id: IRSpy.pm,v 1.75 2007-03-09 08:56:37 mike Exp $
+# $Id: IRSpy.pm,v 1.84 2007-04-30 11:28:37 mike Exp $
package ZOOM::IRSpy;
use ZOOM::IRSpy::Node;
use ZOOM::IRSpy::Connection;
use ZOOM::IRSpy::Stats;
-use ZOOM::IRSpy::Utils qw(cql_target render_record);
+use ZOOM::IRSpy::Utils qw(cql_target render_record
+ irspy_xpath_context irspy_make_identifier
+ irspy_record2identifier);
our @ISA = qw();
our $VERSION = '0.02';
use ZOOM::IRSpy;
$spy = new ZOOM::IRSpy("target/string/for/irspy/database");
$spy->targets(@targets);
- $spy->initialise();
- $res = $spy->check("Main");
+ $spy->initialise("Main");
+ $res = $spy->check();
=head1 DESCRIPTION
queue => undef, # Filled in by initialise()
libxml => $libxml,
irspy_to_zeerex_style => $irspy_to_zeerex_style,
+ test => undef, # Filled in by initialise()
tests => undef, # Tree of tests to be executed
activeSetSize => defined $activeSetSize ? $activeSetSize : 10,
}, $class;
join(", ", map { "'$_'" } @targets));
my @qlist;
foreach my $target (@targets) {
- my($host, $port, $db, $newtarget) = _parse_target_string($target);
+ my($protocol, $host, $port, $db, $newtarget) =
+ _parse_target_string($target);
if ($newtarget ne $target) {
$this->log("irspy_debug", "rewriting '$target' to '$newtarget'");
$target = $newtarget; # This is written through the ref
}
- push @qlist, cql_target($host, $port, $db);
+ push @qlist, cql_target($protocol, $host, $port, $db);
}
$this->{targets} = \@targets;
sub _parse_target_string {
my($target) = @_;
- my($host, $port, $db) = ($target =~ /(.*?):(.*?)\/(.*)/);
+ my($protocol, $host, $port, $db) = ($target =~ /(.*?):(.*?):(.*?)\/(.*)/);
if (!defined $host) {
$port = 210;
- ($host, $db) = ($target =~ /(.*?)\/(.*)/);
- $target = "$host:$port/$db";
+ ($protocol, $host, $db) = ($target =~ /(.*?):(.*?)\/(.*)/);
+ $target = irspy_make_identifier($protocol, $host, $port, $db);
}
die "$0: invalid target string '$target'"
if !defined $host;
- return ($host, $port, $db, $target);
+ return ($protocol, $host, $port, $db, $target);
}
#
sub initialise {
my $this = shift();
+ my($tname) = @_;
+
+ $tname = "Main" if !defined $tname;
+ $this->{test} = $tname;
+ $this->{tree} = $this->_gather_tests($tname)
+ or die "No tests defined for '$tname'";
+ $this->{tree}->resolve();
+ #$this->{tree}->print(0);
+
+ my $timeout = "ZOOM::IRSpy::Test::$tname"->timeout();
my @targets;
my $targets = $this->{targets};
foreach my $i (1..$n) {
push @connections, create ZOOM::IRSpy::Connection($this,
shift @targets,
- async => 1);
+ async => 1,
+ timeout => $timeout);
}
$this->{connections} = \@connections;
# Since IRSpy can run for a long time between writes back to the
# database, it's quite possible for the server to have closed the
# connection as idle. So re-establish it if necessary.
- $conn->connect($conn->option("host"));
+ $this->{conn}->connect($conn->option("host"));
_really_rewrite_record($this->{conn}, $rec);
$conn->log("irspy", "rewrote XML record");
sub _really_rewrite_record {
- my($conn, $rec) = @_;
+ my($conn, $rec, $oldid) = @_;
my $p = $conn->package();
$p->option(action => "specialUpdate");
$p->send("update");
$p->destroy();
+ # This is the expression in the ID-making stylesheet
+ # ../../zebra/zeerex2id.xsl
+ my $xc = irspy_xpath_context($rec);
+ my $id = irspy_record2identifier($xc);
+ if (defined $oldid && $id ne $oldid) {
+ warn "IDs differ (old='$oldid' new='$id')";
+ # Delete old record;
+ ### Should use same mechanism as delete.mc
+ my $p = $conn->package();
+ $p->option(action => "recordDelete");
+ $p->option(recordIdOpaque => $oldid);
+ $p->option(record => "<dummy/>"); # Work around Zebra bug
+ $p->send("update");
+ $p->destroy();
+ }
+
$p = $conn->package();
$p->send("commit");
$p->destroy();
#
sub check {
my $this = shift();
- my($tname) = @_;
- $tname = "Main" if !defined $tname;
- $this->{tree} = $this->_gather_tests($tname)
- or die "No tests defined for '$tname'";
- $this->{tree}->resolve();
- #$this->{tree}->print(0);
- my $nskipped = 0;
+ my $topname = $this->{tree}->name();
+ my $timeout = "ZOOM::IRSpy::Test::$topname"->timeout();
+ $this->log("irspy", "beginnning with test '$topname' (timeout $timeout)");
+ my $nskipped = 0;
my @conn = @{ $this->{connections} };
my $nruns = 0;
$conn->log("irspy", "has no more tests: removing");
$this->_rewrite_record($conn);
$conn->option(rewrote_record => 1);
- $conn->destroy();
if (@{ $this->{queue} } == 0) {
+ # Do not destroy: we need this for later sanity checks
splice @conn, $i0, 1;
} else {
+ $conn->destroy();
$conn[$i0] = create
ZOOM::IRSpy::Connection($this,
- shift @{ $this->{queue} }, async => 1);
+ shift @{ $this->{queue} }, async => 1,
+ timeout => $timeout);
$conn[$i0]->option(current_test_address => "");
$conn[$i0]->log("irspy", "entering active pool - ",
scalar(@{ $this->{queue} }),
}
$this->log("irspy", "exiting main loop");
+
# Sanity checks: none of the following should ever happen
my $finished = 1;
- @conn = @{ $this->{connections} };
+ $this->log("irspy", "performing end-of-run sanity-checks");
foreach my $conn (@conn) {
my $test = $conn->option("current_test_address");
my $next = $this->_next_test($test);
eval {
require $fullName;
- $this->log("irspy", "successfully required '$fullName'");
}; if ($@) {
$this->log("irspy", "couldn't require '$fullName': $@");
$this->log("warn", "can't load test '$tname': skipping",