#!/usr/bin/perl

# moat - mother of all (driver) tests
# John Jacobsen, NPX Designs, Inc., jacobsen\@npxdesigns.com
# Started: Fri Aug 13 08:38:05 2004

my $Id = "Id"; my $id = "$Id: moat,v 1.13 2004/10/12 16:42:41 jacobsen Exp $x";

package MY_PACKAGE;
use strict;
use Getopt::Long;

sub off_all; sub on_all;
sub check_for_running_processes;

sub usage { return <<EOF;
Usage: $0
           [-h|-help]           Show these options
	   [-n <N>]             Number of times to perform all tests (default=1)
	   [-d|-dorfreq <MHz>]  Specify DOR clock frequency
	   [-c|-cbsecs]         Number of seconds for configboot stagedtests runs
	   [-r|-relsecs]        Number of seconds for "release" stagedtests runs
	   [-t|-savetsecs]      Number of seconds for same, saving tcal data
	                        (default is to skip this step)
EOF
;
	}

my $help;
my $dorfreq;
my $n        = 1;
my $relsecs  = 3000;
my $cbsecs   = 600;
my $savtsecs = 0;

GetOptions("help|h"          => \$help,
           "dorfreq|d=i"     => \$dorfreq,
	   "relsecs|s=i"     => \$relsecs,
	   "cbsecs|c=i"      => \$cbsecs,
	   "savetsecs|t=i"   => \$savtsecs,
	   "n=i"             => \$n) || die usage;
die usage if $help;

print "Welcome to $0 by jacobsen\@npxdesigns.com.\n";

check_for_running_processes;

while(!defined $dorfreq) {
    print "Enter clock frequency (10 or 20) in Mhz: ";
    $dorfreq = <STDIN>; chomp $dorfreq;
    last if $dorfreq == 10 || $dorfreq == 20;
}

my ($sec,$min,$hr,$mday,$mon,$yr,$wday,$yday,$isdst) = localtime;
$yr += 1900;
$mon++;
my $ts = sprintf("$yr-%02d-%02d__%02d:%02d:%02d", $mon, $mday, $hr, $min, $sec);
my $testdir = "MOAT__$ts";
my $logfile = "MOAT.out";

print "Creating $testdir... ";
mkdir $testdir || die "Can't create $testdir: $!\n";
print "OK.\n";
chdir $testdir || die "Can't chdir $testdir: $!\n";

open LOG, ">$logfile" || die "Can't open $logfile: $!\n";
my $ofh = select(LOG); $| = 1; select $ofh;
sub mydie { my $m = shift; print LOG $m; die $m; }
print "\nResults to appear in directory $testdir\n\n";

exit if fork;

print LOG "MOAT: Started at ".(scalar localtime)."\n";
print LOG "      CVS $id\n";

my $have_failure = 0;

for(my $iter=0; $iter<$n; $iter++) {
    print LOG "\n\nMOAT test iteration $iter...\n";
    my $iterd = sprintf("test%03d",$iter);
    mkdir $iterd || mydie "Can't mkdir $iterd: $!\n";
    chdir $iterd || mydie "Can't chdir $iterd: $!\n";

    if($cbsecs > 0) {
	#### stagedtests (echo test) of configboot 
	my $cbet = "configboot_echotest";
	mkdir $cbet || mydie "Can't mkdir $cbet: $!\n";
	chdir $cbet || mydie "Can't chdir $cbet: $!\n";
	unlink "st.out" || mydie "Can't unlink st.out: $!\n";
	my $stcmd = "/usr/local/bin/stagedtests.pl -b -t $cbsecs -x -d $dorfreq -p";
	print LOG "\n\nMOAT: Starting $stcmd\n";
	system "$stcmd 2>&1 > st.out";
	my $stresult = `tail -1 st.out`;
	print LOG $stresult;
	chdir ".." || mydie "Can't chdir ..: $!\n";
	if($stresult !~ /SUCCESS/) {
	    print LOG "\n\nStagedtests/echo test with configboot firmware FAILED".
		" on trial $iter.\n";
	    $have_failure = 1;
	    chdir "..";
	    last;
	}
    }


    if($relsecs > 0) {
	#### stagedtests (echo test + tcaltest) of release firmware
	my $rest = "release_stagedtests";
	mkdir $rest || mydie "Can't mkdir $rest: $!\n";
	chdir $rest || mydie "Can't chdir $rest: $!\n";
	unlink "st.out" || mydie "Can't unlink st.out: $!\n";
	my $stcmd = "/usr/local/bin/stagedtests.pl -t $relsecs -d $dorfreq -p";
	print LOG "\n\nMOAT: Starting $stcmd\n";
	system "$stcmd 2>&1 > st.out";
	my $stresult = `tail -1 st.out`;
	print LOG $stresult;
	chdir ".." || mydie "Can't chdir ..: $!\n";
	if($stresult !~ /SUCCESS/) {
	    print LOG "\n\nStagedtests (echo+tcal) FAILED on iteration $iter.\n";
	    $have_failure = 1;
	    chdir "..";
	    last;
	}
    }

    if($savtsecs > 0) {
	#### stagedtests of release firmware as above, but save tcalib data
	my $rest = "save_tcal_stagedtests";
	mkdir $rest || mydie "Can't mkdir $rest: $!\n";
	chdir $rest || mydie "Can't chdir $rest: $!\n";
	unlink "st.out" || mydie "Can't unlink st.out: $!\n";
	my $stcmd = "/usr/local/bin/stagedtests.pl -t $savtsecs -v -p -d $dorfreq";
	print LOG "\n\nMOAT: Starting $stcmd\n";
	system "$stcmd 2>&1 > st.out";
	my $stresult = `tail -1 st.out`;
	print LOG $stresult;
	chdir ".." || mydie "Can't chdir ..: $!\n";
	if($stresult !~ /SUCCESS/) {
	    print LOG "\n\nStagedtests (echo+tcal) FAILED on iteration $iter.\n";
	    $have_failure = 1;
	    chdir "..";
	    last;
	}
    }

#     #### Do a short newpkttest for a few minutes just to make sure
#     #### softboot and flow control are ok

#     print LOG "\n\nMOAT: Powering DOMs off, then on...\n";
#     off_all;
#     on_all;
#     my $newp = "newpkt_test";
#     mkdir $newp || mydie "Can't mkdir $newp: $!\n";
#     chdir $newp || mydie "Can't chdir $newp: $!\n";
#     my $newpktcmd = "/usr/local/bin/newpkttest.pl -p -n 1";
#     print LOG "\n\nMOAT: Starting $newpktcmd\n";
#     my $npresult = `$newpktcmd 2>&1`;
#     print LOG $npresult;
#     if($npresult !~ /SUCCESS/) {
# 	print LOG "\n\nnewpkttest FAILED on iteration $iter.\n";
# 	$have_failure = 1;
#         last;
#     }
#
#    chdir ".." || mydie "Can't chdir ..: $!\n";

    #### Done with tests this iteration
    chdir ".." || mydie "Can't chdir ..: $!\n";

    print LOG "MOAT: Test iteration $iter succeeded.\n";
}

print LOG "MOAT: Powering off all DOMs.\n";
off_all;

my $now = scalar localtime;
if($have_failure) {
    print LOG "\n\n\nMOAT: Tests ended with FAILURE at $now.\n";
    open FAIL, ">FAIL" || mydie "Can't open status file FAIL: $!\n";
    print FAIL " ";
    close FAIL;
} else {
    print LOG "\n\n\nMOAT: Tests ended SUCCESSFULLY at $now.\n";
    open SUCC, ">SUCCESS" || mydie "Can't open status file SUCCESS: $!\n";
    print SUCC " ";
    close SUCC;
}

exit;

sub off_all {
    system "echo off > /proc/driver/domhub/pwrall";
}

sub on_all {
    system "echo on > /proc/driver/domhub/pwrall";
}

sub check_for_running_processes {
    my @ps = `ps --columns 1000 ax`;
    foreach my $ps(@ps) {
	chomp $ps;
	if($ps =~ m|/usr/local/bin/readwrite| ||
	   $ps =~ m|/usr/local/bin/tcaltest|  ||
	   $ps =~ m|/usr/local/bin/stagedtests.pl|) {
	    die "Process \"$ps\" would interfere; please kill before starting MOAT.\n";
	}
    }
}
	   
__END__

