1 # Copyright (C) 2006-2008, Parrot Foundation.
6 Parrot::Harness::Smoke - Subroutines used by harness-scripts to generate smoke reports
10 This package exports on request subroutines used by the root F<t/harness>
11 and by language implementation F<t/harness> to generate smoke reports.
15 The module currently exports three subroutines on demand.
17 =head2 C<collect_test_environment_data()>
19 %env_data = collect_test_environment_data();
21 Subroutine collects environmental data via:
25 =item * Analysis of the results of Parrot configuration (C<%PConfig>).
27 =item * Environmental variables
29 =item * Analysis of C<.svn> metadata
31 =item * Application of CPAN modules. F<Mail::Util> and F<Sys::Hostname> are
36 You may directly affect I<Submitter> data by setting the following environmental
41 =item * All systems. C<$ENV{'SMOLDER_SUBMITTER'}>.
43 =item * Win32 only. C<$ENV{'USERNAME'}> or C<$ENV{'LOGNAME'}>, plus
44 C<$ENV{'USERDOMAIN'}>.
48 =head2 C<send_archive_to_smolder()>
50 send_archive_to_smolder( %env_data );
52 At the current time, automated smoke reports are collected and displayed via
53 the Smolder system at L<http://smolder.parrot.org>. Such reports require
54 the Perl 5 F<LWP::UserAgent> module, available from CPAN.
56 On network problem or for offline use you may send tar reports later
59 perl -Ilib -MParrot::Harness::Smoke \
60 -e'Parrot::Harness::Smoke::send_archive_to_smolder(Parrot::Harness::Smoke::collect_test_environment_data())'
62 =head2 C<generate_html_smoke_report()>
64 This subroutine generates a type of HTML-smoke report formerly collected and
65 displayed on Parrot's smoke server. It has been superseded by Smolder
66 reporting but is still available for other uses.
68 generate_html_smoke_report (
74 This subroutine requires CPAN modules F<Test::TAP::HTMLMatrix> and
75 F<Test::TAP::Model::Visual>.
79 package Parrot
::Harness
::Smoke
;
84 use lib
qw( . lib ../lib ../../lib );
85 use Parrot
::Config qw
/%PConfig/;
86 use base
qw( Exporter );
88 generate_html_smoke_report
89 collect_test_environment_data
90 send_archive_to_smolder
93 # language implementations have a different project id
94 my %SMOLDER_CONFIG = (
95 server
=> 'http://smolder.parrot.org',
96 username
=> 'parrot-autobot',
97 password
=> 'qa_rocks',
99 report_file
=> ['parrot_test_run.tar.gz'],
102 # language implementations must pass their respective project id
103 sub send_archive_to_smolder
{
104 my %test_env_data = @_;
105 eval { require LWP
::UserAgent
};
107 die "\n" . ('-' x
55) . "\nCould not load LWP::UserAgent."
108 . "\nPlease install it if you want to send TAP archives to Smolder.\n"
109 . ('-' x
55) . "\n\n$@\n";
112 my $project_id = delete $test_env_data{project_id
} || $SMOLDER_CONFIG{project_id
};
113 my $report_file = delete $test_env_data{report_file
} || $SMOLDER_CONFIG{report_file
};
115 = $SMOLDER_CONFIG{server
}
116 . '/app/projects/process_add_report/'
118 my $ua = LWP
::UserAgent
->new();
120 $ua->agent( 'Parrot::Harness::Smoke' );
123 # create our tags based off the test environment information
125 (map { $test_env_data{$_} } qw(Architecture Compiler Platform Version)),
126 'Perl ' . $test_env_data{'Perl Version'});
127 my $response = $ua->post(
129 Content_Type
=> 'form-data',
131 username
=> $SMOLDER_CONFIG{username
},
132 password
=> $SMOLDER_CONFIG{password
},
134 report_file
=> $report_file,
135 revision
=> $PConfig{revision
},
139 if ($response->code == 302) {
140 my ($report_id) = $response->content =~ /Reported #(\d+) added/i;
141 my $report_url = "$SMOLDER_CONFIG{server}/app/projects/report_details/$report_id";
143 = $SMOLDER_CONFIG{server
}
144 . '/app/projects/smoke_reports/'
146 print "Test report successfully sent to Smolder at\n$report_url"
147 . "\nYou can see other recent reports at\n$project_url .\n\n";
150 die "Could not upload report to Smolder at $SMOLDER_CONFIG{server}"
151 . "\nHTTP CODE: " . $response->code . " ("
152 . $response->message . ")\n";
156 sub collect_test_environment_data
{
158 # rename sun4 to sparc
159 my $arch = $PConfig{cpuarch
} eq 'sun4' ?
'sparc' : $PConfig{cpuarch
};
160 # add the 32/64 bit suffix to the cpuarch
161 if ($arch !~ /\d$/) {
162 $arch .= 8 * $PConfig{opcode_t_size
};
164 my $devel = $PConfig{DEVEL
};
165 # check for local-modifications if -d .svn and query to continue
167 my $status = `svn status`;
168 @mods = grep /\S/, map { /^M +(.+)$/ and $1 } split(/\n/, $status);
170 $devel .= (" ".@mods." mods");
172 my $info = `svn info .`;
173 ($branch) = $info =~ m{URL: .+/parrot/(?:branches/)?(\w+)$}m;
175 my $me = $^O
eq 'MSWin32' ?
$ENV{'USERNAME'}
176 : $ENV{'LOGNAME'} || eval { getpwuid($<) };
177 my $domain = 'unknown';
178 eval "use Mail::Util;";
180 $domain = Mail
::Util
::maildomain
();
182 elsif ($^O
eq 'MSWin32') {
183 $domain = $ENV{'USERDOMAIN'};
186 eval { require Sys
::Hostname
;
187 $domain = Sys
::Hostname
::hostname
(); }
190 'Architecture' => $arch,
191 'Compiler' => _get_compiler_version
(),
193 'Optimize' => ($PConfig{optimize
} || 'none'),
194 'Perl Version' => (sprintf('%vd', $^V
) . " $PConfig{archname}"),
195 'Platform' => $PConfig{osname
},
196 'Version' => $PConfig{VERSION
},
197 'Submitter' => $ENV{"SMOLDER_SUBMITTER"} || "$me\@$domain"
199 push @data, ( 'Branch' => $branch ) if $branch;
200 push @data, ( 'Configure args' => $PConfig{configure_args
} )
201 if $PConfig{configure_args
};
202 push @data, ( 'Modifications' => join(" ", @mods) ) if @mods;
206 # this can be expanded to more than just GCC
207 sub _get_compiler_version
{
208 my $compiler = $PConfig{cc
};
209 if ($compiler =~ /gcc/ and $PConfig{gccversion
}) {
210 $compiler .= " $PConfig{gccversion}";
212 elsif ($compiler =~ /cl/ and $PConfig{msvcversion
}) {
213 $compiler .= " $PConfig{msvcversion}";
216 elsif ($PConfig{gccversion
}) {
217 $compiler .= " (gcc $PConfig{gccversion})";
219 elsif ($PConfig{msvcversion
}) {
220 $compiler .= " (msvc $PConfig{msvcversion})";
225 sub generate_html_smoke_report
{
227 my $html_fn = $argsref->{file
};
230 require Test
::TAP
::HTMLMatrix
;
231 require Test
::TAP
::Model
::Visual
;
233 die "You must have Test::TAP::HTMLMatrix installed.\n\n$@"
236 my @test_env_data = collect_test_environment_data
();
239 no warnings qw
/redefine once/;
240 *Test
::TAP
::Model
::run_tests
= sub {
244 $self->{meat
}{start_time
} = time();
248 foreach my $file (@_) {
250 print STDERR
"- $file\n";
251 $data = $self->run_test($file);
252 $stats{tests
} += $data->{results
}{max
} || 0;
253 $stats{ok
} += $data->{results
}{ok
} || 0;
256 printf STDERR
"%s OK from %s tests (%.2f%% ok)\n\n",
259 $stats{ok
} / $stats{tests
} * 100;
261 $self->{meat
}{end_time
} = time();
265 my $model = Test
::TAP
::Model
::Visual
->new();
266 $model->run_tests( @
{ $argsref->{tests
} } );
270 my $duration = $end - $start;
271 my %hash = @test_env_data;
272 my $branch = $hash{Branch
} ||= 'trunk';
273 my $v = Test
::TAP
::HTMLMatrix
->new(
276 "duration: $duration",
278 "harness_args: " . (($argsref->{args
}) ?
$argsref->{args
} : "N/A"),
279 map { "$_: $hash{$_}" } keys %hash),
282 $v->has_inline_css(1); # no separate css file
284 open my $HTML, '>', $html_fn;
285 print {$HTML} $v->html();
288 print "$html_fn has been generated.\n";
296 # cperl-indent-level: 4
299 # vim: expandtab shiftwidth=4: