|
| 1 | +#!perl |
| 2 | + |
| 3 | +use strict; |
| 4 | +use warnings; |
| 5 | + |
| 6 | +use File::Spec; |
| 7 | +use Cwd qw(abs_path); |
| 8 | +use File::Spec::Functions qw(catfile); |
| 9 | + |
| 10 | +use lib abs_path(File::Spec->rel2abs('../packaging', __FILE__)); |
| 11 | +use PerlBuildJob; |
| 12 | + |
| 13 | +use lib 'lib'; |
| 14 | +use GLPI::Agent::Version; |
| 15 | + |
| 16 | +# HACK: make "use Perl::Dist::GLPI::Agent::Step::XXX" works as included plugin |
| 17 | +map { $INC{"Perl/Dist/GLPI/Agent/Step/$_.pm"} = __FILE__ } qw(Test); |
| 18 | + |
| 19 | +my $provider = $GLPI::Agent::Version::PROVIDER; |
| 20 | + |
| 21 | +sub build_app { |
| 22 | + my ($arch) = @_; |
| 23 | + |
| 24 | + my $app = Perl::Dist::GLPI::Agent->new( |
| 25 | + arch => $arch, |
| 26 | + _restore_step => PERL_BUILD_STEPS, |
| 27 | + ); |
| 28 | + |
| 29 | + $app->parse_options( |
| 30 | + -job => "glpi-agent built perl test", |
| 31 | + -image_dir => "C:\\Strawberry-perl-for-$provider-Agent", |
| 32 | + -working_dir => "C:\\Strawberry-perl-for-$provider-Agent_build", |
| 33 | + -nointeractive, |
| 34 | + -restorepoints, |
| 35 | + ); |
| 36 | + |
| 37 | + return $app; |
| 38 | +} |
| 39 | + |
| 40 | +my %do = (); |
| 41 | +while ( @ARGV ) { |
| 42 | + my $arg = shift @ARGV; |
| 43 | + if ($arg eq "--arch") { |
| 44 | + my $arch = shift @ARGV; |
| 45 | + next unless $arch =~ /^x(86|64)$/; |
| 46 | + $do{$arch} = 1; |
| 47 | + } elsif ($arg eq "--all") { |
| 48 | + %do = ( |
| 49 | + #~ x86 => 32, |
| 50 | + x64 => 64 |
| 51 | + ); |
| 52 | + } |
| 53 | +} |
| 54 | + |
| 55 | +foreach my $arch (keys(%do) || ("x64")) { |
| 56 | + print "Running $arch built perl tests...\n"; |
| 57 | + my $app = build_app($arch); |
| 58 | + $app->do_job(); |
| 59 | + # global_dump_FINAL.txt must exist in debug_dir if all steps have been passed |
| 60 | + exit(1) unless -e catfile($app->global->{debug_dir}, 'global_dump_FINAL.txt'); |
| 61 | +} |
| 62 | + |
| 63 | +print "Tests processing passed\n"; |
| 64 | + |
| 65 | +exit(0); |
| 66 | + |
| 67 | +package |
| 68 | + Perl::Dist::GLPI::Agent::Step::Test; |
| 69 | + |
| 70 | +use parent 'Perl::Dist::Strawberry::Step'; |
| 71 | + |
| 72 | +use File::Spec::Functions qw(catfile catdir); |
| 73 | +use File::Glob qw(:glob); |
| 74 | + |
| 75 | +sub run { |
| 76 | + my $self = shift; |
| 77 | + |
| 78 | + # Update PATH to include perl/bin for DLLs loading |
| 79 | + my $binpath = catfile($self->global->{image_dir}, 'perl/bin'); |
| 80 | + $ENV{PATH} .= ":$binpath"; |
| 81 | + |
| 82 | + # Without defined modules, run the tests |
| 83 | + my $perlbin = catfile($binpath, 'perl.exe'); |
| 84 | + |
| 85 | + my $makefile_pl_cmd = [ $perlbin, "Makefile.PL"]; |
| 86 | + $self->boss->message(2, "Test: gonna run perl Makefile.PL"); |
| 87 | + my $rv = $self->execute_standard($makefile_pl_cmd); |
| 88 | + die "ERROR: TEST, perl Makefile.PL\n" unless (defined $rv && $rv == 0); |
| 89 | +} |
| 90 | + |
| 91 | +sub test { |
| 92 | + my $self = shift; |
| 93 | + |
| 94 | + # Update PATH to include perl/bin for DLLs loading |
| 95 | + my $binpath = catfile($self->global->{image_dir}, 'perl/bin'); |
| 96 | + $ENV{PATH} .= ":$binpath"; |
| 97 | + |
| 98 | + # Without defined modules, run the tests |
| 99 | + my $makebin = catfile($binpath, 'gmake.exe'); |
| 100 | + |
| 101 | + my @test_files = (); |
| 102 | + @test_files = map { bsd_glob($_) } @{$self->{config}->{test_files}} |
| 103 | + if ref($self->{config}->{test_files}) && @{$self->{config}->{test_files}}; |
| 104 | + if (@test_files && ref($self->{config}->{skip_tests}) && @{$self->{config}->{skip_tests}}) { |
| 105 | + my %skip_tests = map { $_ => 1 } @{$self->{config}->{skip_tests}}; |
| 106 | + @test_files = grep { not $skip_tests{$_} } @test_files; |
| 107 | + } |
| 108 | + |
| 109 | + # Only test files compilation |
| 110 | + my $make_test_cmd = [ $makebin, "test" ]; |
| 111 | + push @{$make_test_cmd}, "TEST_FILES=@test_files" if @test_files; |
| 112 | + $self->boss->message(2, "Test: gonna run gmake test"); |
| 113 | + my $rv = $self->execute_standard($make_test_cmd); |
| 114 | + die "ERROR: TEST, make test\n" unless (defined $rv && $rv == 0); |
| 115 | +} |
| 116 | + |
| 117 | +package |
| 118 | + Perl::Dist::GLPI::Agent; |
| 119 | + |
| 120 | +use parent qw(Perl::Dist::Strawberry); |
| 121 | + |
| 122 | +use File::Path qw(remove_tree); |
| 123 | +use File::Spec::Functions qw(canonpath); |
| 124 | +use File::Glob qw(:glob); |
| 125 | +use Time::HiRes qw(usleep); |
| 126 | +use PerlBuildJob; |
| 127 | + |
| 128 | +sub message { |
| 129 | + my ($self, $level, @msg) = @_; |
| 130 | + # Filter out wrong message |
| 131 | + return if $level == 0 && $msg[0] =~ /restorepoint saved$/; |
| 132 | + $self->SUPER::message($level, @msg); |
| 133 | +} |
| 134 | + |
| 135 | +sub make_restorepoint { |
| 136 | + my ($self, $text) = @_; |
| 137 | + |
| 138 | + my $step = $self->global->{_restore_step}; |
| 139 | + |
| 140 | + return $self->message(3, "skipping restorepoint '$text'\n"); |
| 141 | +} |
| 142 | + |
| 143 | +sub create_dirs { |
| 144 | + my $self = shift; |
| 145 | + |
| 146 | + # Make a first pass on removing expected dirs as this may fail for unknown reason |
| 147 | + foreach my $global (qw(image_dir build_dir debug_dir env_dir)) { |
| 148 | + my $dir = $self->global->{$global} |
| 149 | + or next; |
| 150 | + remove_tree($dir) if -d $dir; |
| 151 | + |
| 152 | + # We may have some issue with fs synchro, be ready to wait a little |
| 153 | + my $timeout = time + 10; |
| 154 | + while (-d $dir && time < $timeout) { |
| 155 | + usleep(100000); |
| 156 | + } |
| 157 | + } |
| 158 | + |
| 159 | + $self->SUPER::create_dirs(); |
| 160 | +} |
| 161 | + |
| 162 | +sub ask_about_restorepoint { |
| 163 | + my ($self, $image_dir, $bits) = @_; |
| 164 | + my @points; |
| 165 | + for my $pp (sort(bsd_glob($self->global->{restore_dir}."/*.pp"))) { |
| 166 | + my $d = eval { do($pp) }; |
| 167 | + warn "SKIPPING/1 $pp\n" and next unless defined $d && ref($d) eq 'HASH'; |
| 168 | + warn "SKIPPING/2 $pp\n" and next unless defined $d->{build_job_steps}; |
| 169 | + warn "SKIPPING/3 $pp\n" and next unless defined $d->{restorepoint_info}; |
| 170 | + warn "SKIPPING/4 $pp\n" and next unless $d->{restorepoint_zip_image_dir} && -f $d->{restorepoint_zip_image_dir}; |
| 171 | + warn "SKIPPING/5 $pp\n" and next unless $d->{restorepoint_zip_debug_dir} && -f $d->{restorepoint_zip_debug_dir}; |
| 172 | + warn "SKIPPING/6 $pp\n" and next unless canonpath($d->{image_dir}) eq canonpath($image_dir); |
| 173 | + warn "SKIPPING/7 $pp\n" and next unless $d->{bits} == $bits; |
| 174 | + push @points, $d; |
| 175 | + } |
| 176 | + |
| 177 | + # Select the restore point at expected step |
| 178 | + my $step = $self->global->{_restore_step}; |
| 179 | + my ($restorepoint) = grep { $_->{build_job_steps}->[$step]->{done} && ! $_->{build_job_steps}->[$step+1]->{done} } @points; |
| 180 | + die "ERROR: restorepoint from built perl is required\n" unless $restorepoint; |
| 181 | + |
| 182 | + return $restorepoint; |
| 183 | +} |
| 184 | + |
| 185 | +sub create_buildmachine { |
| 186 | + my ($self, $job, $restorepoint) = @_; |
| 187 | + my $h; |
| 188 | + my $counter = 0; |
| 189 | + |
| 190 | + $h = delete $job->{build_job_steps}; |
| 191 | + for my $s (@$h) { |
| 192 | + my $p = delete $s->{plugin}; |
| 193 | + my $n = eval "use $p; $p->new()"; |
| 194 | + die "ERROR: invalid plugin '$p'\n$@" unless $n; |
| 195 | + $n->{boss} = $self; |
| 196 | + $n->{config} = $s; |
| 197 | + $n->{data} = { done=>0, plugin=>$p, output=>undef }; |
| 198 | + push @{$self->{build_job_steps}}, $n; |
| 199 | + } |
| 200 | + $counter += scalar(@$h); |
| 201 | + |
| 202 | + # store remaining job data into global-hash |
| 203 | + while (my ($k, $v) = each %$job) { |
| 204 | + if (my $vv = $self->global->{$k}) { |
| 205 | + $self->message(2, "parameter '$k=$vv' overridden from commandline"); |
| 206 | + $job->{$k} = $vv; |
| 207 | + } else { |
| 208 | + $self->global->{$k} = $v; |
| 209 | + } |
| 210 | + } |
| 211 | + |
| 212 | + if ($restorepoint) { |
| 213 | + my $i; |
| 214 | + my $start_time = time; |
| 215 | + $self->message(0, "loading RESTOREPOINT=$restorepoint->{restorepoint_info}\n"); |
| 216 | + |
| 217 | + $self->unzip_dir($restorepoint->{restorepoint_zip_debug_dir}, $self->global->{debug_dir}); |
| 218 | + $self->unzip_dir($restorepoint->{restorepoint_zip_image_dir}, $self->global->{image_dir}); |
| 219 | + |
| 220 | + $self->message(0, sprintf("RESTOREPOINT loaded in %.2f minutes\n", (time-$start_time)/60)); |
| 221 | + } else { |
| 222 | + $self->message(0, "new build machine created, total steps=$counter"); |
| 223 | + } |
| 224 | +} |
| 225 | + |
| 226 | +sub load_jobfile { |
| 227 | + my ($self, $arch) = @_; |
| 228 | + |
| 229 | + return { |
| 230 | + bits => $self->global->{arch} eq 'x64' ? 64 : 32, |
| 231 | + build_job_steps => [ |
| 232 | + ### STEP 0 Run GLPI Agent test suite ############################## |
| 233 | + { |
| 234 | + plugin => 'Perl::Dist::GLPI::Agent::Step::Test', |
| 235 | + # By default all possible test will be run |
| 236 | + test_files => [ |
| 237 | + #~ qw(t/*.t t/*/*.t t/*/*/*.t t/*/*/*/*.t t/*/*/*/*/*.t t/*/*/*/*/*/*.t) |
| 238 | + ], |
| 239 | + skip_tests => [ |
| 240 | + # Fails if not run as administrator |
| 241 | + #~ qw(t/agent/config.t) |
| 242 | + ], |
| 243 | + }, |
| 244 | + ], |
| 245 | + }; |
| 246 | +} |
0 commit comments