App-TestOnTap

 view release on metacpan or  search on metacpan

lib/App/TestOnTap/Harness.pm  view on Meta::CPAN

package App::TestOnTap::Harness;

use strict;
use warnings;

our $VERSION = '1.001';
my $version = $VERSION;
$VERSION = eval $VERSION;

use base qw(TAP::Harness);

use App::TestOnTap::Scheduler;
use App::TestOnTap::Dispenser;
use App::TestOnTap::Util qw(slashify runprocess $IS_PACKED);

use TAP::Formatter::Console;
use TAP::Formatter::File;

use List::Util qw(max);

sub new
{
	my $class = shift;
	my $args = shift;

	my $self = $class->SUPER::new
								(
									{
										formatter => __getFormatter($args),
										jobs => $args->getJobs(),
										merge => $args->getMerge(),
										callbacks => { after_test => $args->getWorkDirManager()->getResultCollector() },
										'exec' => __getExecMapper($args),
										scheduler_class => 'App::TestOnTap::Scheduler'
									}
								);

	$self->{testontap} = { args => $args, pez => App::TestOnTap::Dispenser->new($args) };

	return $self;
}

sub make_scheduler
{
	my $self = shift;
	
	return $self->{scheduler_class}->new($self->{testontap}->{pez}, @_);
}

sub runtests
{
	my $self = shift;
	
	my $args = $self->{testontap}->{args}; 
	my $sr = $args->getSuiteRoot();
	
	my @pairs;
	push(@pairs, [ slashify("$sr/$_"), $_ ]) foreach ($self->{testontap}->{pez}->getAllTests());

	my $failed = 0;
	{
		my $wdmgr = $self->{testontap}->{args}->getWorkDirManager();

		local %ENV = %{$self->{testontap}->{args}->getPreprocess()->getEnv()};
		$ENV{TESTONTAP_SUITE_DIR} = $sr;
		$ENV{TESTONTAP_TMP_DIR} = $wdmgr->getTmp();
		$ENV{TESTONTAP_SAVE_DIR} = $wdmgr->getSaveSuite();
		
		if ($self->{testontap}->{args}->useHarness())
		{
			# the normal case is to run with a 'real' harness that parses
			# TAP, handles parallelization, formatters and all that
			#
			$wdmgr->beginTestRun();
			my $aggregator = $self->SUPER::runtests(@pairs); 
			$wdmgr->endTestRun($self->{testontap}->{args}, $aggregator);
			$failed = $aggregator->failed() || 0;
		}
		else
		{
			# if the user has requested 'no harness', just run the jobs serially
			# in the right context, but make no effort to parse their output
			# in any way - more convenient for debugging (esp. with an execmap
			# that can start a test in debug mode)
			#
			my $scheduler = $self->make_scheduler(@pairs);

			# figure out the longest test file name with some extra to produce some
			# nice delimiters...
			#
			my $longestTestFileName = 0;
			$longestTestFileName = max($longestTestFileName, length($_->[0])) foreach (@pairs);
			$longestTestFileName += 10;
			my $topDelimLine = '#' x $longestTestFileName;
			my $bottomDelimLine = '-' x $longestTestFileName;

			while (my $job = $scheduler->get_job())
			{
				my $desc = $job->description();
				my $filename = $job->filename;
				my $cmdline = $self->exec()->($self, $filename);
				my $dryrun = $self->{testontap}->{args}->doDryRun();
				my $parallelizable = ($self->{testontap}->{args}->getConfig()->parallelizable($desc) ? '' : 'not ') . 'parallelizable'; 
				print "$topDelimLine\n";
				print "Run test '$desc' ($parallelizable) using:\n";
				print "  $_\n" foreach (@$cmdline);
				print "$bottomDelimLine\n";
				if ($dryrun)
				{
					print "(dry run only, actual test not executed)\n";
				}
				else
				{	 
					$failed++ if system(@$cmdline) >> 8;
				}
				$job->finish();
			}	
		}
		
		# run postprocessing
		#
		my $postcmd = $self->{testontap}->{args}->getConfig()->getPostprocessCmd();
		if ($postcmd && @$postcmd)
		{
			my @postproc;
			my $xit = runprocess
						(
							sub
								{
									push(@postproc, $_[0]);
									print STDERR $_[0]
								},
							$sr,
							(
								@$postcmd,



( run in 0.935 second using v1.01-cache-2.11-cpan-ceb78f64989 )