All of lore.kernel.org
 help / color / mirror / Atom feed
* [OSSTEST PATCH 00/25] Reporting improvements
@ 2015-06-17 16:44 Ian Jackson
  2015-06-17 16:44 ` [OSSTEST PATCH 01/25] Osstest.pm: Provide new db_prepare helper with built-in debugging Ian Jackson
                   ` (25 more replies)
  0 siblings, 26 replies; 37+ messages in thread
From: Ian Jackson @ 2015-06-17 16:44 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

Most of the early part of this series is straightforward (and acked)
and could go in whenever.

Patches 15-24 introduce sg-report-host-history.  It's probably easiest
to simply review the final version of the script, which can be found
below.  The history is preserved mostly for archeological purposes.

Ian.

#!/usr/bin/perl -w

# This is part of "osstest", an automated testing framework for Xen.
# Copyright (C) 2009-2013 Citrix Inc.
# 
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
# 
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.


use strict qw(vars);

use DBI;
use Osstest;
use IO::Handle;
use HTML::Entities;
use POSIX;

use Osstest::Executive qw(:DEFAULT :colours);

our $limit= 200;
our $flightlimit;
our $htmlout = ".";
our @blessings;

open DEBUG, ">/dev/null";

my $namecond= "(name = 'host' or name like '%_host')";
csreadconfig();

while (@ARGV && $ARGV[0] =~ m/^-/) {
    $_= shift @ARGV;
    last if m/^--?$/;
    if (m/^--(limit)\=([1-9]\d*)$/) {
        $$1= $2;
    } elsif (m/^--flight-limit\=([1-9]\d*)$/) {
	$flightlimit= $1;
    } elsif (m/^--blessings?=(.*)$/) {
        push @blessings, split ',', $1;
    } elsif (m/^--html-dir=(.*)$/) {
        $htmlout= $1;
    } elsif (m/^--debug/) {
        open DEBUG, ">&2" or die $!;
        DEBUG->autoflush(1);
    } else {
        die "$_ ?";
    }
}
@blessings= qw(real) if !@blessings;

@ARGV or die $!;

our $flightcond;

sub computeflightsrange () {
    if (!$flightlimit) {
	my $flagscond =
	    '('.join(' OR ', map { "f.hostflag = 'blessed-$_'" } @blessings).')';
	my $nhostsq = db_prepare(<<END);
	    SELECT count(*)
	      FROM resources r
	     WHERE restype='host'
	       AND EXISTS (SELECT 1
			     FROM hostflags f
			    WHERE f.hostname=r.resname
			      AND $flagscond)
END
        $nhostsq->execute();
	my ($nhosts) = $nhostsq->fetchrow_array();
	print DEBUG "COUNTED $nhosts hosts\n";
	$flightlimit = $nhosts * $limit * 2;
    }

    my $minflightsq = db_prepare(<<END);
	SELECT flight
	  FROM (
	    SELECT flight
	      FROM flights
	     ORDER BY flight DESC
	     LIMIT $flightlimit
	  ) f
	  ORDER BY flight ASC
	  LIMIT 1
END
    $minflightsq->execute();
    my ($minflight) = $minflightsq->fetchrow_array();
    $minflight //= 0;

    $flightcond = "(flight > $minflight)";
}

sub jobquery ($$) {
    my ($q, $jr) = @_;
    $q->execute($jr->{flight}, $jr->{job});
    return $q->fetchrow_hashref();
}

our %hosts;

sub mainquery () {
    our $valcond = join " OR ", map { "val = ?" } keys %hosts;
    our @params = keys %hosts;

    our $runvarq //= db_prepare(<<END);
	SELECT flight, job, name, val
	  FROM runvars
	 WHERE $namecond
	   AND ($valcond)
	   AND $flightcond
	 ORDER BY flight DESC
	 LIMIT ($limit * 3 + 100) * ?
END

    push @params, scalar keys %hosts;

    $runvarq->execute(@params);

    print DEBUG "FIRST PASS\n";
    while (my $jr= $runvarq->fetchrow_hashref()) {
	print DEBUG "JOB $jr->{flight}.$jr->{job} ";
	push @{ $hosts{$jr->{val}} }, $jr;
    }
}

sub reporthost ($) {
    my ($hostname) = @_;

    die if $hostname =~ m/[^-_.+0-9a-z]/;

    my $html_file= "$htmlout/$hostname.html";
    open H, "> $html_file.new" or die "$html_file $!";

    my $title= "host history $hostname\n";
    $title= encode_entities($title);
    print H "<html><head><title>$title</title></head><body>\n";
    print H "<h1>$title</h1>\n";
    print H "<table rules=all><tr>\n";

    print H "<th>alloc testid</th><th>alloc completed</th>\n";
    print H "<th>job finished</th>\n";
    print H "<th>role</th>\n";

    print H "<th>flight</th>\n";
    print H "<th>branch</th><th>intended</th><th>blessing</th>\n";

    print H "<th>job</th><th>failure</th>\n";

    print H "</tr>\n";

    our $endedq //= db_prepare(<<END);
	SELECT finished, testid, status AS laststepstatus
	  FROM steps
	 WHERE flight=? AND job=? AND finished IS NOT NULL
	 ORDER BY finished DESC
	 LIMIT 1
END

    our $infoq //= db_prepare(<<END);
	SELECT blessing, branch, intended, status
	  FROM flights
	  JOIN jobs USING (flight)
	 WHERE flight=? AND job=?
END

    our $allocdq //= db_prepare(<<END);
	SELECT testid, finished, status
	  FROM steps
	 WHERE flight=? AND job=?
	   AND (testid='hosts-allocate' OR step='ts-hosts-allocate')
	 ORDER BY finished ASC
	 LIMIT 1
END

    my $inrows = $hosts{$hostname};
    print DEBUG "FOUND ", (scalar @$inrows), " ROWS for $hostname\n";

    my @rows;
    foreach my $jr (@$inrows) {
	print DEBUG "JOB $jr->{flight}.$jr->{job}\n";

	my $endedrow = jobquery($endedq, $jr);
	if (!$endedrow) {
	    print DEBUG "no-finished\n";
	    next;
	}
	print DEBUG join " ", map { $endedrow->{$_} } sort keys %$endedrow;
	print DEBUG ".\n";

	push @rows, { %$jr, %$endedrow };
    }

    @rows = sort { $b->{finished} <=> $a->{finished} } @rows;
    $#rows = $limit-1 if @rows > $limit;

    my $alternate = 0;
    foreach my $jr (@rows) {
	my $ir = jobquery($infoq, $jr);
	my $ar = jobquery($allocdq, $jr);

	my $altcolour = report_altcolour($alternate);
	print H "<tr $altcolour>";

	if (!defined $ar->{testid}) {
	    print H "<td bgcolor=\"$red\"></td>";
	    print H "<td>?</td>";
	} else {
	    if ($ar->{status} eq 'pass') {
		print H "<td>$ar->{testid}</td>";
		print H "<td>", (show_abs_time $ar->{finished}), "</td>";
	    } elsif ($ar->{status} eq 'running') {
		print H "<td bgcolor=\"$blue\">$ar->{testid}</td>";
		print H "<td>(incomplete)</td>";
	    } else {
		print H "<td bgcolor=\"$red\">$ar->{testid}</td>";
		print H "<td>$ar->{status}</td>";
	    }
	}
	print H "\n";

	print H "<td>", (show_abs_time $jr->{finished}), "</td>\n";
	print H "<td>", $jr->{name}, "</td>\n";

	my $url= "$c{ReportHtmlPubBaseUrl}/$jr->{flight}";
	print H "<td><a href=\"$url\">$jr->{flight}</a></td>\n";
	$url= "$c{ReportHtmlPubBaseUrl}/$jr->{flight}/".
	    encode_entities($jr->{job})."/";
	print H "<td>$ir->{branch}</td>";
	print H "<td>$ir->{intended}</td>";
	print H "<td>";
	print H $ir->{blessing} unless $ir->{blessing} eq 'running';
	print H "</td>";

	print H "<td><a href=\"$url\">$jr->{job}</td>\n";

	my $ri = report_run_getinfo({ %$jr, %$ir });
	print H "<td bgcolor=\"$ri->{Colour}\">$ri->{Summary}</td>\n";

	print H "</tr>\n\n";
	$alternate ^= 1;
    }

    print H "</table></body></html>\n";

    close H or die $!;
    rename "$html_file.new", "$html_file" or die "$html_file $!";
}

db_retry($dbh_tests, [qw(flights resources)], sub {
    computeflightsrange();
});

$dbh_tests->do("SET LOCAL enable_seqscan=false");
# Otherwise the PostgreSQL query planner likes to do a complete scan
# of the runvars table, rather than walking backwards through the
# flights until it has what we've told it is enough.

foreach my $host (@ARGV) {
    if ($host =~ m/^flight:/) {
	my $flight=$'; #';
	db_retry($dbh_tests, [qw(flights)], sub {
	    our $hostsinflightq //= db_prepare(<<END);
	        SELECT DISTINCT val
		  FROM runvars
		 WHERE flight=?
		   AND (name = 'host' or name like '%_host')
END
            $hostsinflightq->execute($flight);
	    while (my $row = $hostsinflightq->fetchrow_hashref()) {
		$hosts{$row->{val}} = [ ];
	    }
	});
    } elsif ($host !~ m/:/) {
	$hosts{$host} = [ ];
    } else {
	die "$host ?";
    }
}

exit 0 unless %hosts;

db_retry($dbh_tests, [qw(flights)], sub {
    mainquery();
});

foreach my $host (sort keys %hosts) {
    db_retry($dbh_tests, [qw(flights)], sub {
	reporthost $host;
    });
}

^ permalink raw reply	[flat|nested] 37+ messages in thread

end of thread, other threads:[~2015-06-18 16:24 UTC | newest]

Thread overview: 37+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-06-17 16:44 [OSSTEST PATCH 00/25] Reporting improvements Ian Jackson
2015-06-17 16:44 ` [OSSTEST PATCH 01/25] Osstest.pm: Provide new db_prepare helper with built-in debugging Ian Jackson
2015-06-18 15:33   ` Ian Jackson
2015-06-18 15:46     ` Ian Campbell
2015-06-17 16:44 ` [OSSTEST PATCH 02/25] sg-report-job-history: Use db_prepare Ian Jackson
2015-06-17 16:44 ` [OSSTEST PATCH 03/25] cs-bisection-step: " Ian Jackson
2015-06-17 16:45 ` [OSSTEST PATCH 04/25] sg-report-flight: " Ian Jackson
2015-06-17 16:45 ` [OSSTEST PATCH 05/25] sg-report-job-history: Add a debugging statement Ian Jackson
2015-06-17 16:45 ` [OSSTEST PATCH 06/25] sg-report-job-history: Slightly prettify sql Ian Jackson
2015-06-17 16:45 ` [OSSTEST PATCH 07/25] sg-report-job-history: Cope if history too short Ian Jackson
2015-06-17 16:45 ` [OSSTEST PATCH 08/25] sg-report-job-history: Show start time Ian Jackson
2015-06-17 16:45 ` [OSSTEST PATCH 09/25] reporting: Move report_run_getinfo and some colours into Executive.pm Ian Jackson
2015-06-17 16:45 ` [OSSTEST PATCH 10/25] reporting: Add colours as optional export tag, and provide $blue Ian Jackson
2015-06-17 16:45 ` [OSSTEST PATCH 11/25] reporting: Show slightly better info for broken jobs Ian Jackson
2015-06-18  8:44   ` Ian Campbell
2015-06-17 16:45 ` [OSSTEST PATCH 12/25] reporting: Move job histories into history/ Ian Jackson
2015-06-18  8:45   ` Ian Campbell
2015-06-17 16:45 ` [OSSTEST PATCH 13/25] reporting: Move bisection report outputs Ian Jackson
2015-06-18  8:45   ` Ian Campbell
2015-06-17 16:45 ` [OSSTEST PATCH 14/25] reporting: sg-report-flight should ignore missing jobs Ian Jackson
2015-06-18  8:46   ` Ian Campbell
2015-06-17 16:45 ` [OSSTEST PATCH 15/25] sg-report-host-history: Introduce new script Ian Jackson
2015-06-17 16:45 ` [OSSTEST PATCH 16/25] sg-report-host-history: Break out computeflightsrange Ian Jackson
2015-06-17 16:45 ` [OSSTEST PATCH 17/25] sg-report-host-history: Move query preparation into jobquery Ian Jackson
2015-06-17 16:45 ` [OSSTEST PATCH 18/25] sg-report-host-history: Move database manipulations Ian Jackson
2015-06-17 16:45 ` [OSSTEST PATCH 19/25] sg-report-host-history: Use a hash for hosts Ian Jackson
2015-06-17 16:45 ` [OSSTEST PATCH 20/25] sg-report-host-history: Support flight:FLIGHT Ian Jackson
2015-06-17 16:45 ` [OSSTEST PATCH 21/25] sg-report-host-history: Aggregate runvars query for all hosts Ian Jackson
2015-06-17 16:45 ` [OSSTEST PATCH 22/25] sg-report-host-history: Move per-row endedq query into per-host transaction Ian Jackson
2015-06-17 16:45 ` [OSSTEST PATCH 23/25] sg-report-host-history: Show "running" jobs as "incomplete" Ian Jackson
2015-06-17 16:45 ` [OSSTEST PATCH 24/25] sg-report-host-history: Make --html-dir have to be host/ Ian Jackson
2015-06-17 16:45 ` [OSSTEST PATCH 25/25] cri-args-hostlists: Run sg-report-host-history Ian Jackson
2015-06-18  8:47   ` Ian Campbell
2015-06-18  9:06 ` [OSSTEST PATCH 00/25] Reporting improvements Ian Campbell
2015-06-18 11:21   ` Ian Jackson
2015-06-18 14:21     ` Ian Campbell
2015-06-18 14:36       ` Ian Jackson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.