#!/usr/bin/perl -w
######################################################################
#
# $Id: test_harness,v 1.10 2006/05/30 19:44:34 mavrik Exp $
#
######################################################################
#
# Copyright 2005-2006 The WebJob Project, All Rights Reserved.
#
######################################################################
#
# Purpose: A generic test harness.
#
######################################################################
use strict;
use File::Basename;
use File::Path;
use Getopt::Std;
BEGIN
{
my (%hProperties, %hTestNumbers, %hTestDescriptions, %hTestProperties, %hTestTargetValues);
sub GetProperties
{
return \%hProperties;
}
sub GetTestNumbers
{
return \%hTestNumbers;
}
sub GetTestDescriptions
{
return \%hTestDescriptions;
}
sub GetTestProperties
{
return \%hTestProperties;
}
sub GetTestTargetValues
{
return \%hTestTargetValues;
}
}
######################################################################
#
# Main Routine
#
######################################################################
####################################################################
#
# Punch in and go to work.
#
####################################################################
my ($phProperties);
$phProperties = GetProperties();
$$phProperties{'Program'} = basename(__FILE__);
####################################################################
#
# Set platform-specific variables.
#
####################################################################
if ($^O =~ /MSWin32/i)
{
$$phProperties{'OsClass'} = "WINDOWS";
$$phProperties{'Newline'} = "\r\n";
}
else
{
$$phProperties{'OsClass'} = "UNIX";
$$phProperties{'Newline'} = "\n";
}
####################################################################
#
# Get Options.
#
####################################################################
my (%hOptions);
if (!getopts("d:m:p:s:t:w:", \%hOptions))
{
Usage($$phProperties{'Program'});
}
####################################################################
#
# DebugLevel, '-d', is optional.
#
####################################################################
$$phProperties{'DebugLevel'} = (exists($hOptions{'d'})) ? $hOptions{'d'} : 1;
if ($$phProperties{'DebugLevel'} !~ /^\d+$/)
{
print STDERR "$$phProperties{'Program'}: Error='The debug level ($$phProperties{'DebugLevel'}) is not valid.'\n";
exit(2);
}
####################################################################
#
# A RunMode, -m, is required.
#
####################################################################
$$phProperties{'RunMode'} = (exists($hOptions{'m'})) ? $hOptions{'m'} : "unknown";
if ($$phProperties{'RunMode'} !~ /^(?:check|clean|setup)$/)
{
Usage($$phProperties{'Program'});
}
####################################################################
#
# A TargetProgram, -p, is required.
#
####################################################################
my ($sTargetProgram);
$sTargetProgram = $$phProperties{'TargetProgram'} = (exists($hOptions{'p'})) ? $hOptions{'p'} : undef;
if (!defined($$phProperties{'TargetProgram'}))
{
Usage($$phProperties{'Program'});
}
if ($$phProperties{'RunMode'} =~ /^check$/)
{
if ($$phProperties{'OsClass'} =~ /^WINDOWS$/ && $sTargetProgram !~ /\.exe$/)
{
$sTargetProgram .= ".exe"
}
if (!-f $sTargetProgram || !-x _)
{
print STDERR "$$phProperties{'Program'}: Error='The target program ($sTargetProgram) is not a file, does not exist, or is not executable.'\n";
exit(2);
}
}
####################################################################
#
# SrcDir, '-s', is optional.
#
####################################################################
$$phProperties{'SrcDir'} = (exists($hOptions{'s'})) ? $hOptions{'s'} : ".";
####################################################################
#
# HarnessType, '-t', is optional.
#
####################################################################
$$phProperties{'HarnessType'} = (exists($hOptions{'t'})) ? $hOptions{'t'} : "4";
if ($$phProperties{'HarnessType'} !~ /^[34]$/)
{
print STDERR "$$phProperties{'Program'}: Error='Invalid harness type ($$$phProperties{'HarnessType'}). Type must be 3 or 4.'\n";
exit(2);
}
####################################################################
#
# WorkDir, '-w', is optional.
#
####################################################################
$$phProperties{'WorkDir'} = (exists($hOptions{'w'})) ? $hOptions{'w'} : "work";
####################################################################
#
# If there's any arguments left, it's an error.
#
####################################################################
if (scalar(@ARGV) > 0)
{
Usage($$phProperties{'Program'});
}
####################################################################
#
# Conditionally create a work directory.
#
####################################################################
if ($$phProperties{'RunMode'} =~ /^setup$/)
{
CreateWorkArea($$phProperties{'WorkDir'});
}
####################################################################
#
# Pull in local the test harness. Then, walk up the tree looking
# for additional harness files.
#
####################################################################
$$phProperties{'HarnessFile'} = "test_harness.local";
require $$phProperties{'SrcDir'} . "/" . $$phProperties{'HarnessFile'};
my @aDirs = ("..", "../..", "../../..");
push(@aDirs, "../../../..") if ($$phProperties{'HarnessType'} == 4);
foreach my $sDir (@aDirs)
{
my $sHarnessFile = $$phProperties{'SrcDir'} . "/" . $sDir . "/" . $$phProperties{'HarnessFile'};
if (-f $sHarnessFile)
{
require $sHarnessFile;
}
}
####################################################################
#
# Run through the hitching routines.
#
####################################################################
my ($phTestNumbers);
$phTestNumbers = GetTestNumbers();
foreach my $sSubTest (sort(keys(%$phTestNumbers)))
{
my $sRoutine = \&{("Hitch_" . $$phTestNumbers{$sSubTest})};
&$sRoutine();
}
####################################################################
#
# Run through the mode-specific routines.
#
####################################################################
my ($phTestDescriptions, $sErrors);
$phTestDescriptions = GetTestDescriptions();
$sErrors = 0;
foreach my $sSubTest (sort(keys(%$phTestNumbers)))
{
my $sRoutine = \&{(MakeModeName($$phProperties{'RunMode'}) . $$phTestNumbers{$sSubTest})};
my $sResults = &$sRoutine($phProperties);
if ($$phProperties{'DebugLevel'} >= 2)
{
printf("%s %s %s,%s,%s,%d.%d - %s\n",
$sResults,
$$phProperties{'RunMode'},
GetToolName(),
GetPlatformName(),
GetModeName(),
GetTestNumber(),
$sSubTest,
$$phTestDescriptions{$$phTestNumbers{$sSubTest}},
);
}
if ($sResults !~ /^(?:pass|skip)$/)
{
$sErrors++;
}
}
####################################################################
#
# Print out the test results.
#
####################################################################
if ($$phProperties{'DebugLevel'} >= 1)
{
printf("%s %s %s,%s,%s,%d\n",
($sErrors == 0) ? "pass" : "fail",
$$phProperties{'RunMode'},
GetToolName(),
GetPlatformName(),
GetModeName(),
GetTestNumber(),
);
}
####################################################################
#
# Conditionally, create a done file.
#
####################################################################
if ($sErrors == 0)
{
CreateDoneFile($$phProperties{'RunMode'});
}
####################################################################
#
# Cleanup and go home.
#
####################################################################
exit(($sErrors == 0) ? 0 : 3);
######################################################################
#
# CreateDoneFile
#
######################################################################
sub CreateDoneFile
{
my ($sRunMode) = @_;
if ($sRunMode =~ /^(?:clean|check|setup)$/)
{
my $sFile = "_" . $sRunMode . "_done";
if (!open(FH, "> $sFile"))
{
return undef;
}
close(FH);
}
}
######################################################################
#
# CreateWorkArea
#
######################################################################
sub CreateWorkArea
{
my ($sDir) = @_;
if (!-d $sDir)
{
mkdir($sDir, 0755);
}
}
######################################################################
#
# DebugPrint
#
######################################################################
sub DebugPrint
{
my ($sDebugLevel, $sMessage) = @_;
my $phProperties = GetProperties();
if ($$phProperties{'DebugLevel'} >= $sDebugLevel)
{
printf(" %s%s", $sMessage, $$phProperties{'Newline'});
}
}
######################################################################
#
# MakeModeName
#
######################################################################
sub MakeModeName
{
my ($sMode) = @_;
$sMode =~ s/^(.)(.*)$/uc($1).$2."_"/e;
return $sMode;
}
######################################################################
#
# MakeTestName
#
######################################################################
sub MakeTestName
{
my ($phProperties) = @_;
my ($sFile, $sName);
$sName = (caller(1))[3];
$sName =~ s/^.+(?:Check|Clean|Setup)_//;
$sFile = $$phProperties{'WorkDir'} . "/" . $sName;
return ($sFile, $sName);
}
######################################################################
#
# UnlinkDoneFile
#
######################################################################
sub UnlinkDoneFile
{
my ($sRunMode) = @_;
if ($sRunMode =~ /^(?:clean|check|setup)$/)
{
my $sFile = "_" . $sRunMode . "_done";
if (-f $sFile && !unlink($sFile))
{
return undef;
}
}
}
######################################################################
#
# Usage
#
######################################################################
sub Usage
{
my ($sProgram) = @_;
print STDERR "\n";
print STDERR "Usage: $sProgram [-d debug-level] [-s src-dir] [-t {3|4}] [-w work-dir] -m {check|clean|setup} -p target-program\n";
print STDERR "\n";
exit(1);
}
syntax highlighted by Code2HTML, v. 0.9.1