#!/usr/bin/perl

# $Id: debian-test,v 1.4 2000/04/13 09:53:32 phil Exp $
# Copyright (c) 1998 Philip Hands <phil@hands.com>
#
# This program is distributable under the terms of the GPL

#---
#  Usage: debian-test [options] <package-name> ...
#         debian-test -a [options]
# Options:
#    -q   produces no output
#    -v   asks tests to be verbose, by passing on the -v option
#    -i   allows tests to be interactive
#    -a   runs all tests
#    -s   prints success/failure summary

$DT_DIR = "/usr/lib/debian-test" ;
$ENV{'DEBIANTEST_LIB'} = $DT_DIR . "/lib" ;

use Getopt::Std ;

getopts('aimsqv');

# print the usage message 
sub usage {
  printf "Usage: debian-test [options] [<package-name> ...]
    -q   quiet (produces no output)
    -v   asks tests to be verbose, by passing on the -v option
    -i   allows tests to be interactive (by passing on the -i option)
    -a   runs all tests.
    -s   prints success/failure summary for each test
    -m   mail report (currently disabled)

Either the -a option, or the name(s) of the package(s) to be tested
must be specified, but not both.\n"
}


# Given a package name, find the associated test
sub pkg_tests($) {
  my ($pkg) = @_ ;
  my $try ;
  
  for $try ( "tests/$pkg", "default-tests/$pkg" ) {
    if (-f "$DT_DIR/$try") { return ($try) }
    if (-d "$DT_DIR/$try") {
      opendir(TRY, "$DT_DIR/$try" ) || next ;
      my @tests = grep { s#^(test-.*)$#$try/\1# } readdir(TRY) ;
      closedir(TRY) ;
      return(@tests) if (@tests) ;
    }
  }
}


# run the test(s) for a package
sub run_tests($) {
  my($pkg) = @_ ;
  my $test ;
  my $test_cnt=0, $test_fail_cnt=0;

  for $test (pkg_tests($pkg)) {
    chdir($DT_DIR) || die ;
    open(TEST, "$test |") || die ;
    while(<TEST>) {
      $test_cnt++ if (/debian-test RESULT:/) ;
      $test_fail_cnt++  if (/debian-test RESULT: .*: FAILED/) ;
      
      next if $opt_q ;
      if ($opt_v) {
	if (/debian-test (.*)$/) {
	  print "$test: $1\n" ;
	} else {
	  chomp;
	  printf "$test: [%s]\n", $_ ;
	}
      } else {
	if (/debian-test RESULT: (.*): FAILED/) {
	  print "$test: $1: failed\n" ;
	} elsif  (/debian-test MESSAGE: (.*)$/) {
	  print "$test: $1\n" ;
	}
      } 
    }
    close(TEST) ;
  }

  printf ("%-20s Tests Run: %2d, Tests Failed: %2d\n",
	  $pkg . ":", $test_cnt, $test_fail_cnt)
      if ($opt_s) ;

  return($test_fail_cnt == 0) ;
}

sub all_tests() {
  my (%testflag) ;

  for $dir ("tests", "default-tests") {
    $fulldir = $DT_DIR . '/' . $dir ;
    opendir(DIR, $fulldir) || die "opening $fulldir" ;
    while ($_=readdir(DIR)) {
      my($name) = $_ ;

      next if ($name eq "." || $name eq ".." || /~$/ || /.bak$/) ;
      $fullname = $fulldir . '/' . $name ;
      if (-f $fullname && -x $fullname) {
	$testflag{$name} = 1 ;
      }
      if (-d $fullname && (@subtests = glob($fullname . '/test-*'))) {
	foreach (@subtests) {
	  if (-f && -x) {
	    $testflag{$name} = 1 ;
	    last ;
	  }
	}
      }
    }
    closedir(DIR) ;
  }
  return (keys(%testflag)) ;
}


# --- Main program starts here ---

# check that -a or some args, but not both have been specified
unless ($opt_a xor @ARGV) {
  usage() ;
  exit 2 ;
}

# run the tests
my $return_val = 0;

foreach ($opt_a ? all_tests() : @ARGV) {
  $return_val = 1 unless run_tests( $_ ) ;
}

exit($return_val) ;

# Local variables:
# perl-indent-level: 2
# End:
__END__
