Skip to content

Commit d61cee4

Browse files
committed
ci: Add job to run tests with built perl
1 parent cc6a831 commit d61cee4

File tree

2 files changed

+288
-0
lines changed

2 files changed

+288
-0
lines changed

.github/workflows/glpi-agent-ci.yml

+42
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,48 @@ jobs:
104104
run: gmake test
105105
shell: cmd
106106

107+
built-windows-test:
108+
109+
runs-on: windows-latest
110+
111+
steps:
112+
- uses: actions/checkout@v4
113+
- name: Create folders for cached datas
114+
run: |
115+
mkdir C:\Strawberry-perl-for-GLPI-Agent_build\restore
116+
shell: cmd
117+
- name: Restore points cache
118+
uses: actions/cache@v4
119+
id: built-perl-cache
120+
with:
121+
path: |
122+
C:/Strawberry-perl-for-GLPI-Agent_build/restore
123+
key: windows-packaging-cache-x64-${{ hashFiles('contrib\windows\glpi-agent-extlibs-build.pl', 'contrib\windows\glpi-agent-packaging.pl', 'contrib\windows\packaging\*') }}
124+
- name: Update environment
125+
if: steps.built-perl-cache.outputs.cache-hit == 'true'
126+
run: |
127+
echo 'C:\Strawberry\perl\bin' >> $GITHUB_PATH
128+
echo 'C:\Strawberry\perl\site\bin' >> $GITHUB_PATH
129+
echo 'C:\Strawberry\c\bin' >> $GITHUB_PATH
130+
shell: bash
131+
- name: Install Module::Install
132+
if: steps.built-perl-cache.outputs.cache-hit == 'true'
133+
run: cpan -T Module::Install
134+
shell: cmd
135+
- name: Install latest Perl::Dist::Strawberry from github
136+
if: steps.built-perl-cache.outputs.cache-hit == 'true'
137+
run: |
138+
cpanm --notest --verbose https://github.com/StrawberryPerl/Perl-Dist-Strawberry.git
139+
shell: cmd
140+
- name: Run tests script
141+
if: steps.built-perl-cache.outputs.cache-hit == 'true'
142+
run: perl contrib/windows/glpi-agent-built-perl-tests.pl
143+
shell: cmd
144+
- name: Set warning & notice on cache miss
145+
if: steps.built-perl-cache.outputs.cache-hit == 'false'
146+
run: |
147+
echo '::warning title=Built Perl not available in cache::You should be able to restart this job after packaging workflow run.'
148+
107149
macos-test:
108150

109151
runs-on: macos-latest
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
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

Comments
 (0)