#!/usr/bin/perl

# ====================================================================
# The Vovida Software License, Version 1.0 
# 
# Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in
#    the documentation and/or other materials provided with the
#    distribution.
# 
# 3. The names "VOCAL", "Vovida Open Communication Application Library",
#    and "Vovida Open Communication Application Library (VOCAL)" must
#    not be used to endorse or promote products derived from this
#    software without prior written permission. For written
#    permission, please contact vocal\@vovida.org.
# 
# 4. Products derived from this software may not be called "VOCAL", nor
#    may "VOCAL" appear in their name, without prior written
#    permission of Vovida Networks, Inc.
# 
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
# NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
# NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
# IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
# 
# ====================================================================
# 
# This software consists of voluntary contributions made by Vovida
# Networks, Inc. and many individuals on behalf of Vovida Networks,
# Inc.  For more information on Vovida Networks, Inc., please see
# <http://www.vovida.org/>.

# test-analyzer

# this program does test analysis, by doing the following things in
# the following modes:

# in canonical mode (-c), it takes the given log file(s), and prints
# to stdout a file which contains only the most recent runs, in
# canonical (alphabetical by test name) order.

# in diffable mode (-d), it does the same as -c, but does NOT include
# the date.  This produces a file which can be compared via diff.

# in report mode (-r), it takes two files from the command line, runs them
# through the diffable mode, and then diffs the two files.

require "getopts.pl";

&Getopts("cdr");

if($opt_c) {
    foreach(@ARGV) {
        $data = &canonical_mode(0, $_);
	print $data;
    }
}

if($opt_d) {
    foreach(@ARGV) {
        $data = &canonical_mode(1, $_); # 1 means diff mode
	print $data;
    }
}

if($opt_r) {
    $data_0 = &canonical_mode(1, $ARGV[0]);
    $data_1 = &canonical_mode(1, $ARGV[1]);
    # now, do a diff on these two entries
    $filename_1 = "/tmp/test-analyzer.$$.file1";
    $filename_2 = "/tmp/test-analyzer.$$.file2";
    open(F1, ">$filename_1") || die "can't open $filename_1 for writing";
    print F1 $data_0;
    close(F1);
    open(F2, ">$filename_2") || die "can't open $filename_2 for writing";
    print F2 $data_1;
    close(F2);
    print "Report for $ARGV[0] compared to $ARGV[1]\n";
    print "----------------------------------------\n";
    system("diff -c $filename_1 $filename_2");
    unlink $filename_1;
    unlink $filename_2;
}

sub canonical_mode {
    my($diff_mode) = $_[0];
    my($filename) = $_[1];
    my($data);
    $test_data = "";

    open(F, $filename) || die "can't open $filename";
    while(<F>) {
	if(/^>>>> START ([^\(]*) \( ([0-9\-]*) \) \( ([a-zA-Z0-9\.]*) \)$/) {
	    # this is the start of a test
#	    print STDERR "got start $3:$1\n";
	    $test_name = $1;
	    $test_time = $2;
	    $test_bin = $3;

 	    $hashkey = "$test_bin:$test_name";
	    if($test_time gt $test_time_hash{$hashkey}) {
		# test is later, so replace
#		print STDERR "$hashkey: replacing $test_time_hash{$hashkey} with $test_time\n";
		$replace = 1;
		$test_time_hash{$hashkey} = $test_time;
	    } else {
		$replace = 0;
	    }
	    
#	    print "$test_name : $test_time\n";
	} elsif(/^<<<< END ([^\(]*) \( ([0-9\-]*) \) \( ([a-zA-Z0-9\.]*) \)$/) {
	    if($replace) {
#	        print STDERR "got end $3:$1\n";
		$test_name = $1;
		$test_time = $2;
		$test_bin = $3;
		$hashkey = "$test_bin:$test_name";
		$test_data_hash{$hashkey} = $test_data;
		$test_bin_hash{$hashkey} = $test_bin;
		$test_name_hash{$hashkey} = $test_name;
		$test_data = "";
		$replace = 0;
	    }
	} else {
	    if ($replace) {
		$test_data .= $_;
	    }
	}
    }
    close(F);

    if($diff_mode) {
	foreach(sort keys %test_data_hash) {
	    $data .= ">>>> START $test_name_hash{$_} (  ) ( $test_bin_hash{$_} )\n";
	    $data .= $test_data_hash{$_};
	    $data .= "<<<< END $test_name_hash{$_} (  ) ( $test_bin_hash{$_} )\n";
	}
    } else {
	foreach(sort keys %test_data_hash) {
	    $data .= ">>>> START $test_name_hash{$_} ( $test_time_hash{$_} ) ( $test_bin_hash{$_} )\n";
	    $data .= $test_data_hash{$_};
	    $data .= "<<<< END $test_name_hash{$_} ( $test_time_hash{$_} ) ( $test_bin_hash{$_} )\n";
	}
    }
    return $data;
}


syntax highlighted by Code2HTML, v. 0.9.1