Made smoke testing even easier
[sdlgit/SDL_perl.git] / tools / smolder_smoke_signal
CommitLineData
6c315353 1#!/usr/bin/perl
2
3eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
4 if 0; # not running under some shell
5use strict;
6use warnings;
7use Getopt::Long;
8use Pod::Usage;
9
10BEGIN {
11 eval { require WWW::Mechanize };
12 if ($@) {
13 warn "\nCannot load WWW::Mechanize. "
14 . "\nPlease install it before using smolder_smoke_signal.\n";
15 exit(1);
16 }
17}
18
19=pod
20
21=head1 NAME
22
23smolder_smoke_signal
24
25=head1 SYNOPSIS
26
27 ./bin/smolder_smoke_signal --server smolder.foo.com \
28 --username myself --password s3cr3t --file test_report.xml \
29 --project MyProject
30
31=head1 DESCRIPTION
32
33Script used to upload a Smoke test report to a running smolder server.
34This is extremely useful for scripted/automatic test runs but also
35helpful when using a CLI makes things faster.
36
37=head1 OPTIONS
38
39=head2 REQUIRED
40
41=over
42
43=item server
44
45This is the hostname (and port if not 80) of the running Smolder server.
46
47=item project
48
49The name of the Smolder project to use for the upload.
50
51=item username
52
53The name of the Smolder user to use for the upload.
54
55=item password
56
57The password for the Smolder user given by C<username>.
58
59=item file
60
61The name of the file to upload. Please see F<docs/upload_file_format.pod>
62for more details about the format that Smolder expects this file to
63take.
64
65=back
66
67=head2 OPTIONAL
68
69=over
70
71=item port
72
73If your Smolder server is running on a port other than 80, then you
74can specify it here.
75
76=item architecture
77
78The architecture for the given smoke test run. If none is given
79it will use the default architecture for the project.
80
81=item platform
82
83The platform for the given smoke test run. If none is given
84it will use the default platform for the project.
85
86=item revision
87
88The revision control number for this test run. Only applies to
89projects that use revision control (shouldn't they all) and only
90applies to tests run against a checkout from revision control.
91
92This is just a free form text option so it will work with any
93revision number that your preferred revision control system uses.
94
95=item tags
96
97A comma separated list of tags that are given for this smoke report run.
98
99 ./bin/smolder_smoke_signal --server smolder.foo.com \
100 --username myself --password s3cr3t --file test_report.xml \
101 --project MyProject --tags "Foo, My Bar"
102
103=item comments
104
105Any comments that you want to associate with the smoke test run.
106
107=item verbose
108
109Print verbose output of our actions to STDOUT.
110
111=cut
112
113# default options
114my ($server, $project, $user, $pw, $file, $arch, $platform, $tags, $comments, $verbose, $rev,
115 $port);
116my ($help, $man);
117
118GetOptions(
119 'server=s' => \$server,
120 'port=s' => \$port,
121 'project=s' => \$project,
122 'username=s' => \$user,
123 'password=s' => \$pw,
124 'file=s' => \$file,
125 'architecture=s' => \$arch,
126 'platform=s' => \$platform,
127 'tags=s' => \$tags,
128 'comments=s' => \$comments,
129 'revision=s' => \$rev,
130 'verbose!' => \$verbose,
131 'help' => \$help,
132 'man' => \$man,
133) || pod2usage();
134
135if ($help) {
136 pod2usage(
137 -exitval => 0,
138 -verbose => 1,
139 );
140} elsif ($man) {
141 pod2usage(
142 -exitval => 0,
143 -verbose => 2,
144 );
145}
146
147# make sure all the required fields are there
148_missing_required('server') unless $server;
149_missing_required('project') unless $project;
150_missing_required('username') unless $user;
151_missing_required('password') unless $pw;
152_missing_required('file') unless $file;
153
154# make sure our file is there and is of the right type
155if (-r $file) {
156 unless ($file =~ /\.tar(\.gz)?$/) {
157 warn "File '$file' is not of the correct type!\n";
158 exit(1);
159 }
160} else {
161 warn "File '$file' does not exist, or is not readable!\n";
162 exit(1);
163}
164
165# try and reach the smolder server
166print "Trying to reach Smolder server at $server.\n" if ($verbose);
167$port ||= 80;
168my $mech = WWW::Mechanize->new();
169my $base_url = "http://$server:$port/app";
170eval { $mech->get($base_url) };
171unless ($mech->status eq '200') {
172 warn "Could not reach $server:$port successfully. Received status " . $mech->status . "\n";
173 exit(1);
174}
175
176# now login
177print "Trying to login with username '$user'.\n" if ($verbose);
178$mech->get($base_url . '/public_auth/login');
179my $form = $mech->form_name('login');
180if ($mech->status ne '200' || !$form) {
181 warn "Could not reach Smolder login form. Are you sure $server:$port is a Smolder server?\n";
182 exit(1);
183}
184$mech->set_fields(
185 username => $user,
186 password => $pw,
187);
188$mech->submit();
189my $content = $mech->content;
190if ($mech->status ne '200' || $content !~ /Welcome \Q$user\E/) {
191 warn "Could not login with username '$user' and password '$pw'!\n";
192 exit(1);
193}
194
195# now go to this project's page
196print "Retrieving project listing for user '$user'.\n" if ($verbose);
197$mech->get($base_url . '/developer_projects');
198$content = $mech->content;
199$content =~ />\Q$project\E<!--ID:(\d+)-->/;
200my $project_id = $1;
201if ($mech->status ne '200' || !$project_id) {
202 warn "Could not get your project listing, or you are not a member of the '$project' project!\n";
203 exit(1);
204}
205
206# now go to the add-smoke-report page for this project
207print "Adding smoke report to project '$project'.\n" if ($verbose);
208$mech->get($base_url . "/developer_projects/add_report/$project_id");
209$content = $mech->content;
210if ($mech->status ne '200' || $content !~ /New Smoke Report/) {
211 warn "Could not reach the Add Smoke Report form!\n";
212 exit(1);
213}
214$mech->form_name('add_report');
215my %fields = (report_file => $file);
216$fields{platform} = $platform if $platform;
217$fields{architecture} = $arch if $arch;
218$fields{tags} = $tags if $tags;
219$fields{comments} = $comments if $comments;
220$fields{revision} = $rev if $rev;
221$mech->set_fields(%fields);
222$mech->submit();
223
224$content = $mech->content;
225if ($mech->status ne '200' || $content !~ /Recent Smoke Reports/) {
226 warn "Could not upload smoke report with the given information!\n";
227 exit(1);
228}
229$content =~ /#(\d+) Added/;
230my $report_id = $1;
231
232print "\nReport successfully uploaded as #$report_id.\n";
233
234##########################################################
235# helper methods
236##########################################################
237sub _missing_required {
238 my $field = shift;
239 warn "Missing required field '$field'!\n";
240 pod2usage();
241}