Fixed the pod path in archive
[sdlgit/SDL_perl.git] / tools / smolder_smoke_signal
1 #!/usr/bin/perl 
2
3 eval 'exec /usr/bin/perl  -S $0 ${1+"$@"}'
4     if 0; # not running under some shell
5 use strict;
6 use warnings;
7 use Getopt::Long;
8 use Pod::Usage;
9
10 BEGIN {
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
23 smolder_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
33 Script used to upload a Smoke test report to a running smolder server.
34 This is extremely useful for scripted/automatic test runs but also
35 helpful when using a CLI makes things faster.
36
37 =head1 OPTIONS
38
39 =head2 REQUIRED
40
41 =over
42
43 =item server
44
45 This is the hostname (and port if not 80) of the running Smolder server.
46
47 =item project
48
49 The name of the Smolder project to use for the upload.
50
51 =item username
52
53 The name of the Smolder user to use for the upload.
54
55 =item password
56
57 The password for the Smolder user given by C<username>.
58
59 =item file
60
61 The name of the file to upload. Please see F<docs/upload_file_format.pod>
62 for more details about the format that Smolder expects this file to
63 take.
64
65 =back
66
67 =head2 OPTIONAL
68
69 =over
70
71 =item port
72
73 If your Smolder server is running on a port other than 80, then you
74 can specify it here.
75
76 =item architecture
77
78 The architecture for the given smoke test run. If none is given
79 it will use the default architecture for the project.
80
81 =item platform
82
83 The platform for the given smoke test run. If none is given
84 it will use the default platform for the project.
85
86 =item revision
87
88 The revision control number for this test run. Only applies to
89 projects that use revision control (shouldn't they all) and only
90 applies to tests run against a checkout from revision control.
91
92 This is just a free form text option so it will work with any
93 revision number that your preferred revision control system uses.
94
95 =item tags
96
97 A 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
105 Any comments that you want to associate with the smoke test run.
106
107 =item verbose
108
109 Print verbose output of our actions to STDOUT.
110
111 =cut
112
113 # default options
114 my ($server, $project, $user, $pw, $file, $arch, $platform, $tags, $comments, $verbose, $rev,
115     $port);
116 my ($help, $man);
117
118 GetOptions(
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
135 if ($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
155 if (-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
166 print "Trying to reach Smolder server at $server.\n" if ($verbose);
167 $port ||= 80;
168 my $mech     = WWW::Mechanize->new();
169 my $base_url = "http://$server:$port/app";
170 eval { $mech->get($base_url) };
171 unless ($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
177 print "Trying to login with username '$user'.\n" if ($verbose);
178 $mech->get($base_url . '/public_auth/login');
179 my $form = $mech->form_name('login');
180 if ($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();
189 my $content = $mech->content;
190 if ($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
196 print "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+)-->/;
200 my $project_id = $1;
201 if ($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
207 print "Adding smoke report to project '$project'.\n" if ($verbose);
208 $mech->get($base_url . "/developer_projects/add_report/$project_id");
209 $content = $mech->content;
210 if ($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');
215 my %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;
225 if ($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/;
230 my $report_id = $1;
231
232 print "\nReport successfully uploaded as #$report_id.\n";
233
234 ##########################################################
235 # helper methods
236 ##########################################################
237 sub _missing_required {
238     my $field = shift;
239     warn "Missing required field '$field'!\n";
240     pod2usage();
241 }