#!/usr/bin/perl
#
# (C) Copyright IBM Corp. 2004
#
# This program is free software;  you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program;  if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# Top-level script for running the EVMS test-suite. Call this script with
# the name of one or more disks to use for testing. Use the "-d" option
# to display debugging output.

use strict;
use warnings;

use Evms::Common;
use Evms::Log;
use Evms::Object;

# check_prerequisites
# The "prerequisites" file contains a list of all command-line tools
# necessary to run the test-suite. Check to make sure each of these
# tools is found in the user's PATH.
sub check_prerequisites($)
{
	my $directory = $_[0];
	my $file = $directory . "/prerequisites";
	my @prereqs;
	my $prereq;
	my $rc;

	log_info("Checking for required tools:\n");

	open(PREREQS, "<" . $file) || return 0;
	@prereqs = <PREREQS>;
	close(PREREQS);
	chomp(@prereqs);

	foreach $prereq (@prereqs) {
		next if ($prereq =~ /(^#)|(^\s*$)/);
		`which $prereq 2>&1`;
		$rc = $? >> 8;
		if ($rc) {
			log_error("     $prereq: Not found\n");
			return $rc;
		} else {
			log_info("     $prereq: OK\n");
		}
	}

	return 0;
}

# verify_disks
# Make sure EVMS can find each of the disks the user specified
# on the command-line.
sub verify_disks(@)
{
	my @disks = @_;
	my $disk;
	my @query_output;

	log_info("Checking existance of disks:\n");

	foreach $disk (@disks) {
		@query_output = query_object($disk);
		if (@query_output == 0) {
			log_error("     $disk: Not found\n");
			return 1;
		} else {
			log_info("     $disk: OK\n");
		}
	}

	return 0;
}

# get_test_directories
# The "Tests/directories" file contains a list of the directories containing
# the test scripts to be run. The directories should be processed in the
# order that they appear in this file.
sub get_test_directories()
{
	my @directories;

	open(TESTDIRS, "< Tests/directories") ||
		die("Cannot open list of test directories\n");
	@directories = <TESTDIRS>;
	close(TESTDIRS);
	chomp(@directories);
	return @directories;
}

MAIN:
{
	my $USAGE = "USAGE: $0 [-d] <disk1> [disk2 ...]";
	my @disks;
	my $directory;
	my @directories;
	my $testfile;
	my $rc;

	if (@ARGV == 0) {
		die("$USAGE\n");
	}

	if ($ARGV[0] eq "-d" ||
	    $ARGV[0] eq "--debug") {
		$ENV{"EVMS_DEBUG"} = 1;
		shift @ARGV;
	}

	$ENV{"PATH"} .= ":..";

	# Get list of disks from the command-line.
	@disks = @ARGV;
	if (@disks == 0) {
		die("$USAGE\n");
	}

	$rc = check_prerequisites(".");
	if ($rc) {
		die("Error: Cannot find all required tools.\n");
	}

	$rc = verify_disks(@disks);
	if ($rc) {
		die("Error: Cannot access all specified disks.\n");
	}

	# Get the list of test subdirectories to run.
	@directories = get_test_directories();

	# In each test subdirectory, run all scripts that start with "test".
	foreach $directory (@directories) {
		next if ($directory =~ /(^#)|(^\s*$)/);

		log_info("\n===============================================\n");
		log_info("Running test scripts in Tests/$directory\n");

		# Check each test directory's list of required tools.
		$rc = check_prerequisites("Tests/$directory");
		next if ($rc);

		opendir(TESTDIR, "Tests/$directory") || next;
		while (defined($testfile = readdir(TESTDIR))) {
			if ($testfile =~ /^test/) {
				$rc = clean_objects(@disks);
				if ($rc) {
					die("Error cleaning disks before running " .
					    "Tests/$directory/$testfile\n");
				}

				log_info("\nRunning Tests/$directory/" .
					 "$testfile @disks\n\n");

				system("Tests/$directory/$testfile @disks");
			}
		}

		closedir(TESTDIR);
	}

	clean_objects(@disks);
}

