App-Ikaros
view release on metacpan or search on metacpan
lib/App/Ikaros/Planner.pm view on Meta::CPAN
package App::Ikaros::Planner;
use strict;
use warnings;
use parent qw/Class::Accessor::Fast/;
use List::Util qw/shuffle/;
use List::MoreUtils qw/part/;
use App::Ikaros::PathMaker;
use App::Ikaros::Helper qw/load_from_yaml/;
use Data::Dumper;
use constant {
PROVE_STATE_FILE => '.prove',
};
__PACKAGE__->mk_accessors(qw/
prove_tests
forkprove_tests
saved_tests
sorted_tests
/);
sub new {
my ($class, $hosts, $args) = @_;
unless ($args->{prove_tests} || $args->{forkprove_tests}) {
die "must be set 'prove_tests' and 'forkprove_tests(optional)'";
}
my $self = $class->SUPER::new({ %$args });
$self->__load_prove_state([ @{$args->{prove_tests}}, @{$args->{forkprove_tests}} ])
if (-f PROVE_STATE_FILE);
$self->__setup_testing_cluster($hosts);
return $self;
}
sub planning {
my ($self, $host, $args) = @_;
my $commands = $self->__make_command($args, $host);
$host->plan($commands);
}
sub __load_prove_state {
my ($self, $tests) = @_;
my %tests_map;
$tests_map{$_}++ foreach @$tests;
my $saved_tests = (load_from_yaml PROVE_STATE_FILE)->{tests};
my %elapsed_times;
foreach my $saved_test (keys %$saved_tests) {
next unless exists $tests_map{$saved_test};
my $elapsed_time = $saved_tests->{$saved_test}->{elapsed};
$elapsed_times{$saved_test} = $elapsed_time + 0;
}
my @elapsed_times = reverse sort {
$elapsed_times{$a} <=> $elapsed_times{$b}
} keys %elapsed_times;
$self->saved_tests(\%elapsed_times);
$self->sorted_tests(\@elapsed_times);
}
sub __setup_testing_cluster {
my ($self, $hosts) = @_;
my ($prove_host_num, $forkprove_host_num);
foreach my $host (@$hosts) {
if ($host->runner eq 'prove') {
$prove_host_num++;
} elsif ($host->runner eq 'forkprove') {
$forkprove_host_num++;
} else {
die "unknown keyword at runner [$host->{runner}]";
}
}
my $prove_test_clusters = $self->__make_test_cluster($self->prove_tests, $prove_host_num);
my $forkprove_test_clusters = $self->__make_test_cluster($self->forkprove_tests, $forkprove_host_num);
foreach my $host (@$hosts) {
if ($host->runner eq 'prove') {
$host->tests(shift @$prove_test_clusters);
} else {
$host->tests(shift @$forkprove_test_clusters);
}
}
}
sub __make_test_cluster {
my ($self, $tests, $host_num) = @_;
( run in 4.134 seconds using v1.01-cache-2.11-cpan-2e0ccfb7a10 )