[harness] Update smolder submission info
[parrot.git] / lib / Parrot / Harness / Smoke.pm
blobc74d92a4f81fa494c4b3b0b2f56bf226ebadce74
1 # Copyright (C) 2006-2008, Parrot Foundation.
2 # $Id$
4 =head1 NAME
6 Parrot::Harness::Smoke - Subroutines used by harness-scripts to generate smoke reports
8 =head1 DESCRIPTION
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.
13 =head1 SUBROUTINES
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:
23 =over 4
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
32 used, if available.
34 =back
36 You may directly affect I<Submitter> data by setting the following environmental
37 variable(s):
39 =over 4
41 =item * All systems. C<$ENV{'SMOLDER_SUBMITTER'}>.
43 =item * Win32 only. C<$ENV{'USERNAME'}> or C<$ENV{'LOGNAME'}>, plus
44 C<$ENV{'USERDOMAIN'}>.
46 =back
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
57 with that command:
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 (
69 tests => \@tests,
70 args => $args,
71 file => 'smoke.html',
74 This subroutine requires CPAN modules F<Test::TAP::HTMLMatrix> and
75 F<Test::TAP::Model::Visual>.
77 =cut
79 package Parrot::Harness::Smoke;
81 use strict;
82 use warnings;
84 use lib qw( . lib ../lib ../../lib );
85 use Parrot::Config qw/%PConfig/;
86 use base qw( Exporter );
87 our @EXPORT_OK = qw(
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',
98 project_id => 1,
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 };
106 if( $@ ) {
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};
114 my $url
115 = $SMOLDER_CONFIG{server}
116 . '/app/projects/process_add_report/'
117 . $project_id;
118 my $ua = LWP::UserAgent->new();
119 $ua->timeout(360);
120 $ua->agent( 'Parrot::Harness::Smoke' );
121 $ua->env_proxy();
123 # create our tags based off the test environment information
124 my $tags = join(',',
125 (map { $test_env_data{$_} } qw(Architecture Compiler Platform Version)),
126 'Perl ' . $test_env_data{'Perl Version'});
127 my $response = $ua->post(
128 $url,
129 Content_Type => 'form-data',
130 Content => [
131 username => $SMOLDER_CONFIG{username},
132 password => $SMOLDER_CONFIG{password},
133 tags => $tags,
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";
142 my $project_url
143 = $SMOLDER_CONFIG{server}
144 . '/app/projects/smoke_reports/'
145 . $project_id;
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";
149 else {
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 {
157 my ($branch, @mods);
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
166 if (-d ".svn") {
167 my $status = `svn status`;
168 @mods = grep /\S/, map { /^M +(.+)$/ and $1 } split(/\n/, $status);
169 if (@mods) {
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;";
179 if (!$@) {
180 $domain = Mail::Util::maildomain();
182 elsif ($^O eq 'MSWin32') {
183 $domain = $ENV{'USERDOMAIN'};
185 else {
186 eval { require Sys::Hostname;
187 $domain = Sys::Hostname::hostname(); }
189 my @data = (
190 'Architecture' => $arch,
191 'Compiler' => _get_compiler_version(),
192 'DEVEL' => $devel,
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;
203 return @data;
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}";
215 # catch cc or ccache
216 elsif ($PConfig{gccversion}) {
217 $compiler .= " (gcc $PConfig{gccversion})";
219 elsif ($PConfig{msvcversion}) {
220 $compiler .= " (msvc $PConfig{msvcversion})";
222 return $compiler;
225 sub generate_html_smoke_report {
226 my $argsref = shift;
227 my $html_fn = $argsref->{file};
229 eval {
230 require Test::TAP::HTMLMatrix;
231 require Test::TAP::Model::Visual;
233 die "You must have Test::TAP::HTMLMatrix installed.\n\n$@"
234 if $@;
236 my @test_env_data = collect_test_environment_data();
239 no warnings qw/redefine once/;
240 *Test::TAP::Model::run_tests = sub {
241 my $self = shift;
243 $self->_init;
244 $self->{meat}{start_time} = time();
246 my %stats;
248 foreach my $file (@_) {
249 my $data;
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",
257 $stats{ok},
258 $stats{tests},
259 $stats{ok} / $stats{tests} * 100;
261 $self->{meat}{end_time} = time();
264 my $start = time();
265 my $model = Test::TAP::Model::Visual->new();
266 $model->run_tests( @{ $argsref->{tests} } );
268 my $end = time();
270 my $duration = $end - $start;
271 my %hash = @test_env_data;
272 my $branch = $hash{Branch} ||= 'trunk';
273 my $v = Test::TAP::HTMLMatrix->new(
274 $model,
275 join("\n",
276 "duration: $duration",
277 "branch: $branch",
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();
286 close $HTML;
288 print "$html_fn has been generated.\n";
294 # Local Variables:
295 # mode: cperl
296 # cperl-indent-level: 4
297 # fill-column: 100
298 # End:
299 # vim: expandtab shiftwidth=4: