line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Test::Smoke::App::RepostFromArchive; |
2
|
1
|
|
|
1
|
|
130486
|
use warnings; |
|
1
|
|
|
|
|
11
|
|
|
1
|
|
|
|
|
34
|
|
3
|
1
|
|
|
1
|
|
5
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
35
|
|
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
our $VERSION = '0.002'; |
6
|
|
|
|
|
|
|
|
7
|
1
|
|
|
1
|
|
5
|
use base 'Test::Smoke::App::Base'; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
486
|
|
8
|
|
|
|
|
|
|
|
9
|
1
|
|
|
1
|
|
471
|
use File::Spec::Functions qw(catfile curdir); |
|
1
|
|
|
|
|
827
|
|
|
1
|
|
|
|
|
60
|
|
10
|
1
|
|
|
1
|
|
437
|
use Test::Smoke::Poster; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
46
|
|
11
|
1
|
|
|
1
|
|
6
|
use POSIX qw(strftime); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
9
|
|
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
=head1 NAME |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
Test::Smoke::App::RepostFromArchive - The tsrepostjsn.pl application. |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
=head1 SYNOPSIS |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
Interactive: |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
$ tsrepostjsn.pl -c smokecurrent |
22
|
|
|
|
|
|
|
Show the last 10 reports: |
23
|
|
|
|
|
|
|
1 jsn7a29e8d2c80588346422b4b6b936e6f8b56a3af4.jsn (2022-09-04 05:16:49 +0200) |
24
|
|
|
|
|
|
|
2 jsn69bc7167fa24b1e8d3f810ce465d84bdddf413f6.jsn (2022-09-03 05:15:11 +0200) |
25
|
|
|
|
|
|
|
3 jsncd55125d69f5f698ef7cbdd650cda7d2e59fc388.jsn (2022-09-02 05:14:42 +0200) |
26
|
|
|
|
|
|
|
4 jsn0c33882a943825845dde164b60900bf224b131cc.jsn (2022-09-01 05:15:05 +0200) |
27
|
|
|
|
|
|
|
5 jsnb885e42dc2078e29df142cfcefaa86725199d15b.jsn (2022-08-31 05:15:16 +0200) |
28
|
|
|
|
|
|
|
6 jsne772cf349a3609ba583f441d10e1e92c5e338377.jsn (2022-08-30 05:15:01 +0200) |
29
|
|
|
|
|
|
|
7 jsnf603e191e0bea582034a16f05909a56bcc05a564.jsn (2022-08-29 05:15:14 +0200) |
30
|
|
|
|
|
|
|
8 jsn51634b463845a03d4f22b9d23f6c5e2fb98af9c8.jsn (2022-08-28 05:15:47 +0200) |
31
|
|
|
|
|
|
|
9 jsn305697f3995f7ddfba2e200c5deb2e274e1136c0.jsn (2022-08-27 05:15:34 +0200) |
32
|
|
|
|
|
|
|
10 jsn18fa8a6f818cbe2838cfe9b1bfa0c5d9c311930c.jsn (2022-08-26 05:15:41 +0200) |
33
|
|
|
|
|
|
|
Type the numbers (with white space inbetween): 1 2 3 |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
Or direct: |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
$ tsrepostjsn.pl -c smokecurrent --sha 7a29e8d2c8058 --sha 69bc7167fa2 --sha cd55125d69f5f698ef7cbdd6 |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
=head1 OPTIONS |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
--max-reports Number of reports to choose from (10) |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
--sha Commit SHA for the smoke (repeat for more reports) |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
--jsonreport The actual json-file to re-post |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
Override the config: |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
--adir Archive directory |
50
|
|
|
|
|
|
|
--smokedb_url Where to POST to for CoreSmokeDB |
51
|
|
|
|
|
|
|
--poster Use another poster |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
=head1 DESCRIPTION |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
=head2 Test::Smoke::App::RepostFromArchive->new() |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
Creates a new attribute C of class L. |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
=cut |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
sub new { |
62
|
3
|
|
|
3
|
1
|
8
|
my $class = shift; |
63
|
3
|
|
|
|
|
18
|
my $self = $class->SUPER::new(@_); |
64
|
|
|
|
|
|
|
|
65
|
3
|
|
|
|
|
11
|
$self->{_poster} = Test::Smoke::Poster->new( |
66
|
|
|
|
|
|
|
$self->option('poster') => $self->options, |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
# We will need to fake 'ddir' in order to get the reports from the |
69
|
|
|
|
|
|
|
# archive |
70
|
|
|
|
|
|
|
ddir => $self->option('adir'), |
71
|
|
|
|
|
|
|
v => $self->option('verbose'), |
72
|
|
|
|
|
|
|
); |
73
|
|
|
|
|
|
|
|
74
|
3
|
|
|
|
|
19
|
return $self; |
75
|
|
|
|
|
|
|
} |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
=head2 $reposter->run() |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
Get a list of C<< jsn.jsn >> filenames from the C archive |
80
|
|
|
|
|
|
|
directory an try to send them to the report server at C again. |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
=cut |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
sub run { |
85
|
3
|
|
|
3
|
1
|
4649
|
my $self = shift; |
86
|
|
|
|
|
|
|
|
87
|
3
|
|
|
|
|
21
|
my @to_post = $self->pick_reports(); |
88
|
3
|
|
|
|
|
32
|
for my $report (@to_post) { |
89
|
13
|
|
|
|
|
35
|
$self->log_info("Reposting '%s' to %s\n", $report, $self->option('smokedb_url')); |
90
|
13
|
|
|
|
|
68
|
$self->poster->jsnfile($report); |
91
|
13
|
|
|
|
|
61
|
my $id = $self->poster->post($report); |
92
|
13
|
|
50
|
|
|
63
|
$self->log_info("Report posted with id: %s", $id || ""); |
93
|
|
|
|
|
|
|
} |
94
|
|
|
|
|
|
|
} |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
=head2 $reposter->pick_reports() |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
First checks for reports passed on the command line with C<< --sha |
99
|
|
|
|
|
|
|
>>. If none were passed it fetches the latest reports C<--max-reports> from the |
100
|
|
|
|
|
|
|
archive directory C and lets you pick 1 or more. |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
=head3 Returns |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
A list of filenames representing the json files from the archive. |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
=cut |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
sub pick_reports { |
109
|
3
|
|
|
3
|
|
1064
|
my $self = shift; |
110
|
|
|
|
|
|
|
|
111
|
3
|
100
|
|
|
|
10
|
if (my $jsonreport = $self->option('jsonreport')) { |
112
|
2
|
50
|
|
|
|
38
|
die("Cannot find '$jsonreport'") unless -f $jsonreport; |
113
|
2
|
50
|
|
|
|
14
|
if ($jsonreport =~ m{^ / }x) { |
114
|
2
|
|
|
|
|
15
|
$self->poster->ddir(''); |
115
|
|
|
|
|
|
|
} |
116
|
|
|
|
|
|
|
else { |
117
|
0
|
|
|
|
|
0
|
$self->poster->ddir(curdir()); |
118
|
|
|
|
|
|
|
} |
119
|
2
|
|
|
|
|
8
|
return ($jsonreport); |
120
|
|
|
|
|
|
|
} |
121
|
|
|
|
|
|
|
|
122
|
1
|
|
|
|
|
10
|
my $entries = $self->fetch_jsn_from_archive; |
123
|
1
|
|
|
|
|
44
|
my $max_entries = scalar(keys %$entries); |
124
|
|
|
|
|
|
|
|
125
|
1
|
|
|
|
|
4
|
my $commits = $self->option('commit_sha'); |
126
|
1
|
50
|
|
|
|
4
|
if (@$commits) { |
127
|
|
|
|
|
|
|
# tranlate (partial) sha into filenames |
128
|
1
|
|
|
|
|
3
|
my @reports; |
129
|
1
|
|
|
|
|
3
|
for my $commit (@$commits) { |
130
|
5
|
|
|
|
|
15
|
my @candidates = grep { $_ =~ m{^ jsn $commit [0-9a-f]* \.jsn $}x } keys %$entries; |
|
55
|
|
|
|
|
218
|
|
131
|
5
|
50
|
|
|
|
20
|
push @reports, $candidates[0] if @candidates; |
132
|
|
|
|
|
|
|
} |
133
|
1
|
|
|
|
|
9
|
return @reports; |
134
|
|
|
|
|
|
|
} |
135
|
|
|
|
|
|
|
|
136
|
0
|
|
|
|
|
|
my $max = $self->option('max_reports'); |
137
|
0
|
0
|
|
|
|
|
$max > $max_entries and $max = $max_entries; |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
my @short_list = ( |
140
|
|
|
|
|
|
|
sort { |
141
|
0
|
|
|
|
|
|
$entries->{$b}{mtime} <=> $entries->{$a}{mtime} |
142
|
0
|
|
|
|
|
|
} keys %$entries |
143
|
|
|
|
|
|
|
)[0..$max - 1]; |
144
|
|
|
|
|
|
|
|
145
|
0
|
|
|
|
|
|
$max = @short_list; |
146
|
0
|
|
|
|
|
|
my @reports; |
147
|
0
|
|
|
|
|
|
printf "Show the last %u reports:\n", $max; |
148
|
0
|
|
|
|
|
|
for my $cnt (1..$max) { |
149
|
|
|
|
|
|
|
printf |
150
|
|
|
|
|
|
|
"%3u %-35s (%s)\n", |
151
|
|
|
|
|
|
|
$cnt, $short_list[$cnt - 1], |
152
|
|
|
|
|
|
|
strftime( |
153
|
|
|
|
|
|
|
"%Y-%m-%d %H:%M:%S %z", |
154
|
|
|
|
|
|
|
localtime($entries->{ $short_list[$cnt - 1] }{mtime}) |
155
|
0
|
|
|
|
|
|
); |
156
|
|
|
|
|
|
|
} |
157
|
0
|
|
|
|
|
|
print "Type the numbers (with white space inbetween): "; |
158
|
0
|
|
|
|
|
|
chomp(my $input = ); |
159
|
0
|
0
|
0
|
|
|
|
my @picks = grep { m{^ [0-9]+ $}x && $_ >= 1 && $_ <= $max } split(" ", $input); |
|
0
|
|
|
|
|
|
|
160
|
0
|
|
|
|
|
|
for my $pick (@picks) { |
161
|
0
|
|
|
|
|
|
push @reports, $short_list[$pick - 1]; |
162
|
|
|
|
|
|
|
} |
163
|
0
|
|
|
|
|
|
return @reports; |
164
|
|
|
|
|
|
|
} |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
sub fetch_jsn_from_archive { |
167
|
0
|
|
|
0
|
|
|
my $self = shift; |
168
|
|
|
|
|
|
|
|
169
|
0
|
|
|
|
|
|
my %entries; |
170
|
0
|
|
|
|
|
|
my $adir = $self->option('adir'); |
171
|
0
|
0
|
|
|
|
|
opendir(my $dh, $adir) or die "Cannot opendir($adir): $!"; |
172
|
0
|
|
|
|
|
|
while (my $entry = readdir($dh)) { |
173
|
0
|
|
|
|
|
|
my $fn = catfile($adir, $entry); |
174
|
0
|
0
|
|
|
|
|
next unless -f $fn; |
175
|
0
|
0
|
|
|
|
|
next unless $entry =~ m{^ jsn [0-9a-f]+ \.jsn $}x; |
176
|
0
|
|
|
|
|
|
$entries{$entry} = { |
177
|
|
|
|
|
|
|
mtime => (stat $fn)[9], |
178
|
|
|
|
|
|
|
fullname => $fn, |
179
|
|
|
|
|
|
|
}; |
180
|
|
|
|
|
|
|
} |
181
|
0
|
|
|
|
|
|
closedir($dh); |
182
|
|
|
|
|
|
|
|
183
|
0
|
|
|
|
|
|
return \%entries; |
184
|
|
|
|
|
|
|
} |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
1; |
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
=head1 COPYRIGHT |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
E 2002-2022, Abe Timmerman All rights reserved. |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
With contributions from Jarkko Hietaniemi, Merijn Brand, Campo |
193
|
|
|
|
|
|
|
Weijerman, Alan Burlison, Allen Smith, Alain Barbet, Dominic Dunlop, |
194
|
|
|
|
|
|
|
Rich Rauenzahn, David Cantrell. |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or modify |
197
|
|
|
|
|
|
|
it under the same terms as Perl itself. |
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
See: |
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
=over 4 |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
=item * L |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
=item * L |
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
=back |
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful, |
210
|
|
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
211
|
|
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
=cut |
214
|
|
|
|
|
|
|
|