Add support for storing results in an SQL database master
authorChris Butler <chrisb@debian.org>
Fri, 8 Apr 2011 17:45:50 +0000 (18:45 +0100)
committerChris Butler <chrisb@debian.org>
Fri, 8 Apr 2011 17:45:50 +0000 (18:45 +0100)
schema.sql [new file with mode: 0644]
tools/mh-xmltv-do-cvs
tools/mh-xmltv-do-package
tools/mh-xmltv-do-release
tools/mh-xmltv-testlog2sql [new file with mode: 0755]

diff --git a/schema.sql b/schema.sql
new file mode 100644 (file)
index 0000000..6f020fe
--- /dev/null
@@ -0,0 +1,56 @@
+-- 
+-- Database schema for XMLTV tester
+-- Copyright 2011 Chris Butler <chrisb@debian.org>
+-- Released under the terms of the GPL (version 2 or later)
+--
+
+CREATE TYPE dists AS ENUM ('lenny', 'squeeze', 'wheezy', 'sid');
+CREATE TYPE versions AS ENUM ('nightly', 'release', 'package');
+
+CREATE TYPE grabstatus AS ENUM (
+       'ok', 
+       
+       'WARNING', -- meta-status, anything > this but < CRITICAL is a warning
+       'badepisode', 'badiso8859', 'badstart', 'badstop', 'badutf8', 'caterror',
+       'channelnoprogramme', 'duplicatechannel', 'emptydescription', 'emptytitle',
+       'graberror', 'invalidid', 'nobaseline', 'nocapabilities', 'nodescription',
+       'noid', 'nomanualconfig', 'noparamcheck', 'notadditive', 'notquiet',
+       'noversion', 'outputdiffers', 'sorterror', 'unknownid',
+
+       'CRITICAL', -- meta-status, anything > this is a critical error
+       'noconfigurationfile', 'noprogrammes', 'notdtd', 'notwell', 'no exe', 'no test.conf'
+);
+
+CREATE TABLE grabber (
+       grabberid SERIAL PRIMARY KEY,
+       grabbername TEXT NOT NULL
+);
+
+CREATE TABLE result (
+       resultid SERIAL PRIMARY KEY,
+       grabberid INTEGER REFERENCES grabber (grabberid) NOT NULL,
+       dist dists NOT NULL,
+       version versions NOT NULL,
+       resultdatetime TIMESTAMPTZ NOT NULL,
+       status grabstatus[],
+       messages TEXT
+);
+
+CREATE TABLE resultfiles (
+       resultfileid SERIAL PRIMARY KEY,
+       resultid INTEGER REFERENCES result (resultid) NOT NULL,
+       filename TEXT NOT NULL,
+       contents BYTEA
+);
+
+GRANT SELECT,INSERT ON grabber TO "xmltv-tester";
+GRANT SELECT,INSERT ON result TO "xmltv-tester";
+GRANT INSERT ON resultfiles TO "xmltv-tester";
+
+GRANT ALL ON grabber_grabberid_seq TO "xmltv-tester";
+GRANT ALL ON result_resultid_seq TO "xmltv-tester";
+GRANT ALL ON resultfiles_resultfileid_seq TO "xmltv-tester";
+
+GRANT SELECT ON grabber TO testerweb;
+GRANT SELECT ON result TO testerweb;
+GRANT SELECT ON resultfiles TO testerweb;
index 0301223..ddeebb0 100755 (executable)
@@ -29,6 +29,7 @@ $XT/mh-xmltv-test "$BASE/work/nightly/xmltv" \
 
 $XT/mh-xmltv-testlog2html $BASE/result/nightly/latest/test_grabbers.log \
                       "Nightly" $BASE/result/nightly/latest nightly ${DEBIAN_VERS}
+$XT/mh-xmltv-testlog2sql $BASE/result/nightly/latest/test_grabbers.log nightly ${DEBIAN_VERS}
 
 $XT/mh-xmltv-add-result "$BASE/result/nightly/latest" "$BASE/result/nightly"
 $XT/mh-xmltv-generate-summary "Nightly" "$BASE/result/nightly" nightly ${DEBIAN_VERS}
index 5f553fb..9ea2c6d 100755 (executable)
@@ -20,6 +20,7 @@ $XT/mh-xmltv-test "" \
 
 $XT/mh-xmltv-testlog2html $BASE/result/package/latest/test_grabbers.log \
                       "Release $RELEASE" $BASE/result/package/latest package ${DEBIAN_VERS}
+$XT/mh-xmltv-testlog2sql $BASE/result/package/latest/test_grabbers.log package ${DEBIAN_VERS}
 
 $XT/mh-xmltv-add-result "$BASE/result/package/latest" "$BASE/result/package"
 
index 07bc5ea..bb388f7 100755 (executable)
@@ -39,6 +39,7 @@ $XT/mh-xmltv-test "$BASE/work/release/xmltv-$RELEASE" \
 
 $XT/mh-xmltv-testlog2html $BASE/result/release/latest/test_grabbers.log \
                       "Release $RELEASE" $BASE/result/release/latest release ${DEBIAN_VERS}
+$XT/mh-xmltv-testlog2sql $BASE/result/release/latest/test_grabbers.log release ${DEBIAN_VERS}
 
 $XT/mh-xmltv-add-result "$BASE/result/release/latest" "$BASE/result/release"
 $XT/mh-xmltv-generate-summary "Release $RELEASE" "$BASE/result/release" release ${DEBIAN_VERS}
diff --git a/tools/mh-xmltv-testlog2sql b/tools/mh-xmltv-testlog2sql
new file mode 100755 (executable)
index 0000000..8900f95
--- /dev/null
@@ -0,0 +1,173 @@
+#!/usr/bin/perl -w
+
+use strict;
+use Data::Dumper;
+use Template;
+use File::Slurp;
+use File::Basename;
+use FindBin;
+use DBI;
+use DBD::Pg qw(:pg_types);
+
+if( scalar @ARGV != 3 ) {
+    print "mh-xmltv-testlog2sql <logfile> <xmltv vers> <dist>\n";
+    exit 1;
+}
+
+my( $infile, $vers, $dist ) = @ARGV;
+my $resultdir = dirname($infile);
+
+# Memory is cheap...
+my @lines = read_file( $infile );
+
+my $dbh = DBI->connect('dbi:Pg:service=xmltv-tester');
+our $sth_findgrabber = $dbh->prepare('SELECT grabberid FROM grabber WHERE grabbername=?');
+our $sth_addgrabber = $dbh->prepare('INSERT INTO grabber (grabbername) VALUES (?) RETURNING grabberid');
+my $sth_addresult = $dbh->prepare('
+       INSERT INTO result (grabberid, dist, version, resultdatetime, status, messages) 
+       VALUES (?, ' . $dbh->quote($dist) . ', ' . $dbh->quote($vers) . ',NOW(),?,?)
+       RETURNING resultid
+');
+my $sth_addfile = $dbh->prepare('INSERT INTO resultfiles (resultid, filename, contents) VALUES (?, ?, ?)');
+our %grabber_ids;
+my %results;
+$dbh->begin_work or die $dbh->errstr;
+
+my $i = 0;
+do  {
+    $i++;
+} while ($lines[$i] !~ /Tested:/) and ($i<=$#lines);
+
+$i++;
+$i++;
+
+while( $lines[$i] =~ /^(tv_grab_\S+)\s+(.*?)\s*$/ ) {
+    my $grabber = $1;
+    my @codes = split( /,\s*/, $2 );
+       
+       my $grabber_id = find_grabber($1);
+       next unless defined $grabber_id;
+
+    $results{$grabber_id} = { status => [ @codes ] };
+    $i++;
+}
+
+do  {
+    $i++;
+} while( ($lines[$i] !~ /Not tested:/) and ($i<=$#lines) );
+
+# Skip line with ------
+$i++;
+$i++;
+
+while( $lines[$i] =~ /^(tv_grab_\S+)\s+(.*?)\s*$/ ) {
+    my $grabber = $1;
+    my @codes = split( /,\s*/, $2 );
+
+       my $grabber_id = find_grabber($1);
+       next unless defined $grabber_id;
+       
+       $sth_addresult->execute($grabber_id, \@codes, undef);
+    $i++;
+}
+
+$i=0;
+my $grabber_id;
+while( ($lines[$i] !~ /Tested/) and ($i<=$#lines) ) {
+    if( $lines[$i] =~ /^---/ ) {
+    }
+    elsif( $lines[$i] =~ /^Testing (tv_\S+)\s*$/ ) {
+        $grabber_id = find_grabber($1);
+    }
+    else {
+               push @{$results{$grabber_id}->{messages}}, $lines[$i];  
+
+               while ($lines[$i] =~ /\b(t_[-a-z0-9_.]+\.[a-z]{3})\b/g)
+               {
+                       push @{$results{$grabber_id}->{files}}, $1;
+               }
+    }
+    $i++;
+}
+
+# all done, save results to the DB
+for my $grabber_id (keys %results)
+{
+       if ($sth_addresult->execute($grabber_id, $results{$grabber_id}->{status}, join("\n", @{$results{$grabber_id}->{messages}})) && $sth_addresult->rows)
+       {
+               my $result_id = ($sth_addresult->fetchrow_array())[0];
+
+               if (exists($results{$grabber_id}->{files}))
+               {
+                       for my $filename (@{$results{$grabber_id}->{files}})
+                       {
+                               # get file contents and put in resultfiles table
+                               # if file doesn't exist, filecontents will be NULL, which is handy (we can easily show "file didn't exist" in the web interface)
+                               my $filecontents;
+
+                               $filecontents = read_file("$resultdir/$filename") if (-r "$resultdir/$filename");
+                               warn "File $resultdir/$filename missing or not readable" unless $filecontents;
+
+                               $sth_addfile->bind_param(1, $result_id);
+                               $sth_addfile->bind_param(2, $filename);
+                               $sth_addfile->bind_param(3, $filecontents, { pg_type => PG_BYTEA });
+                               $sth_addfile->execute();
+                       }
+               }
+       }
+       else
+       {
+               warn "Unable to add results for grabber $grabber_id: " . $sth_addresult->errstr;
+       }
+}
+
+$dbh->commit or die $dbh->errstr;
+exit 0;
+
+sub find_grabber
+{
+       my $grabber_name = shift;
+       unless (exists $grabber_ids{$grabber_name})
+       {
+               unless ($sth_findgrabber->execute($grabber_name))
+               {
+                       warn "ERROR: unable to find grabber row: " . $sth_findgrabber->errstr;
+                       next;
+               }
+               
+               if ($sth_findgrabber->rows) 
+               {
+                       $grabber_ids{$grabber_name} = ($sth_findgrabber->fetchrow_array())[0];
+               }
+               else
+               {
+                       unless ($sth_addgrabber->execute($grabber_name) && $sth_addgrabber->rows)
+                       {
+                               warn "ERROR: Unable to add grabber row for $grabber_name: " . $sth_addgrabber->errstr . "\n";
+                               return undef;
+                       }
+
+                       $grabber_ids{$grabber_name} = ($sth_addgrabber->fetchrow_array())[0];
+               }
+       }
+
+       return $grabber_ids{$grabber_name};
+}
+### Setup indentation in Emacs
+## Local Variables:
+## perl-indent-level: 4
+## perl-continued-statement-offset: 4
+## perl-continued-brace-offset: 0
+## perl-brace-offset: -4
+## perl-brace-imaginary-offset: 0
+## perl-label-offset: -2
+## cperl-indent-level: 4
+## cperl-brace-offset: 0
+## cperl-continued-brace-offset: 0
+## cperl-label-offset: -2
+## cperl-extra-newline-before-brace: t
+## cperl-merge-trailing-else: nil
+## cperl-continued-statement-offset: 2
+## indent-tabs-mode: t
+## End: