blob: edb47d9a817e73f2ff52ca6c8273c2ba09ad091a [file] [log] [blame]
Christophe Lyonbff39612015-11-18 16:29:11 +01001#!/usr/bin/env perl
2use strict;
3use warnings;
4
5use File::Glob;
6use Getopt::Long;
7use Term::ANSIColor qw(:constants);
8use File::Basename;
9use Cwd;
10
11my $app = $0;
12
13sub read_sum($);
14sub read_unstable($);
Christophe Lyon8823eeb2025-04-07 15:40:22 +000015sub read_flaky($$);
Christophe Lyonbff39612015-11-18 16:29:11 +010016sub dump_result($);
17sub compare_results($$);
18sub usage();
19sub print_compare_results_summary($$);
20sub nothing($$$$);
Thiago Jung Bauermann99efda82023-02-28 23:03:05 +000021sub merge($$@);
Christophe Lyonbff39612015-11-18 16:29:11 +010022
Christophe Lyondded4d82016-06-28 18:12:38 +020023my $PASS_PASS = "Still passes [PASS => PASS]";
Christophe Lyondded4d82016-06-28 18:12:38 +020024my $PASS_XPASS = "PASS now XPASS [PASS =>XPASS]";
25my $PASS_FAIL = "PASS now FAIL [PASS => FAIL]";
Christophe Lyon71cec962016-06-28 18:27:30 +020026my $PASS_XFAIL = "PASS now XFAIL [PASS =>XFAIL]";
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +000027my $PASS_KFAIL = "PASS now KFAIL [PASS =>KFAIL]";
Christophe Lyon9dde3332016-06-28 23:00:00 +020028my $PASS_UNSUPPORTED = "PASS now UNSUPPORTED [PASS =>UNSUP]";
29my $PASS_UNRESOLVED = "PASS now UNRESOLVED [PASS =>UNRES]";
30my $PASS_UNTESTED = "PASS now UNTESTED [PASS =>UNTES]";
Christophe Lyona140aa82015-12-17 22:53:03 +010031my $PASS_DISAPPEARS = "PASS disappears [PASS => ]";
Christophe Lyon71cec962016-06-28 18:27:30 +020032my $PASS_APPEARS = "New PASS [ => PASS]";
33my $PASSED_NOW_TIMEOUTS = "Timeout [PASS =>T.OUT]";
34
35my $XPASS_PASS = "XPASS now PASS [XPASS=> PASS]";
36my $XPASS_XPASS = "Still xpass [XPASS=>XPASS]";
Christophe Lyondded4d82016-06-28 18:12:38 +020037my $XPASS_FAIL = "XPASS now FAIL [XPASS=> FAIL]";
Christophe Lyon71cec962016-06-28 18:27:30 +020038my $XPASS_XFAIL = "XPASS now XFAIL [XPASS=>XFAIL]";
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +000039my $XPASS_KFAIL = "XPASS now KFAIL [XPASS=>KFAIL]";
Christophe Lyon9dde3332016-06-28 23:00:00 +020040my $XPASS_UNSUPPORTED = "XPASS now UNSUPPORTED [XPASS=>UNSUP]";
41my $XPASS_UNRESOLVED = "XPASS now UNRESOLVED [XPASS=>UNRES]";
42my $XPASS_UNTESTED = "XPASS now UNTESTED [XPASS=>UNTES]";
Christophe Lyon71cec962016-06-28 18:27:30 +020043my $XPASS_DISAPPEARS = "XPASS disappears [XPASS=> ]";
44my $XPASS_APPEARS = "XPASS appears [ =>XPASS]";
45
46my $FAIL_PASS = "FAIL now PASS [FAIL => PASS]";
47my $FAIL_XPASS = "FAIL now XPASS [FAIL =>XPASS]";
48my $FAIL_FAIL = "Still fails [FAIL => FAIL]";
49my $FAIL_XFAIL = "FAIL now XFAIL [FAIL =>XFAIL]";
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +000050my $FAIL_KFAIL = "FAIL now KFAIL [FAIL =>KFAIL]";
Christophe Lyon9dde3332016-06-28 23:00:00 +020051my $FAIL_UNSUPPORTED = "FAIL now UNSUPPORTED [FAIL =>UNSUP]";
52my $FAIL_UNRESOLVED = "FAIL now UNRESOLVED [FAIL =>UNRES]";
53my $FAIL_UNTESTED = "FAIL now UNTESTED [FAIL =>UNTES]";
Christophe Lyon71cec962016-06-28 18:27:30 +020054my $FAIL_DISAPPEARS = "FAIL disappears [FAIL => ]";
55my $FAIL_APPEARS = "FAIL appears [ => FAIL]";
56
57my $XFAIL_PASS = "XFAIL now PASS [XFAIL=> PASS]";
58my $XFAIL_XPASS = "XFAIL now XPASS [XFAIL=>XPASS]";
Christophe Lyondded4d82016-06-28 18:12:38 +020059my $XFAIL_FAIL = "XFAIL now FAIL [XFAIL=> FAIL]";
Christophe Lyon71cec962016-06-28 18:27:30 +020060my $XFAIL_XFAIL = "Still xfail [XFAIL=>XFAIL]";
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +000061my $XFAIL_KFAIL = "XFAIL now KFAIL [XFAIL=>KFAIL]";
Christophe Lyon9dde3332016-06-28 23:00:00 +020062my $XFAIL_UNSUPPORTED = "XFAIL now UNSUPPORTED [XFAIL=>UNSUP]";
63my $XFAIL_UNRESOLVED = "XFAIL now UNRESOLVED [XFAIL=>UNRES]";
64my $XFAIL_UNTESTED = "XFAIL now UNTESTED [XFAIL=>UNTES]";
Christophe Lyona140aa82015-12-17 22:53:03 +010065my $XFAIL_DISAPPEARS = "XFAIL disappears [XFAIL=> ]";
Christophe Lyon71cec962016-06-28 18:27:30 +020066my $XFAIL_APPEARS = "XFAIL appears [ =>XFAIL]";
Christophe Lyona140aa82015-12-17 22:53:03 +010067
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +000068my $KFAIL_PASS = "KFAIL now PASS [KFAIL=> PASS]";
69my $KFAIL_XPASS = "KFAIL now XPASS [KFAIL=>XPASS]";
70my $KFAIL_FAIL = "KFAIL now FAIL [KFAIL=> FAIL]";
71my $KFAIL_XFAIL = "KFAIL now XFAIL [KFAIL=>XFAIL]";
72my $KFAIL_KFAIL = "Still kfail [KFAIL=>KFAIL]";
73my $KFAIL_UNSUPPORTED = "KFAIL now UNSUPPORTED [KFAIL=>UNSUP]";
74my $KFAIL_UNRESOLVED = "KFAIL now UNRESOLVED [KFAIL=>UNRES]";
75my $KFAIL_UNTESTED = "KFAIL now UNTESTED [KFAIL=>UNTES]";
76my $KFAIL_DISAPPEARS = "KFAIL disappears [KFAIL=> ]";
77my $KFAIL_APPEARS = "KFAIL appears [ =>KFAIL]";
78
Christophe Lyona140aa82015-12-17 22:53:03 +010079my $UNSUPPORTED_PASS = "UNSUPPORTED now PASS [UNSUP=> PASS]";
Christophe Lyon71cec962016-06-28 18:27:30 +020080my $UNSUPPORTED_XPASS = "UNSUPPORTED now XPASS [UNSUP=>XPASS]";
Christophe Lyona140aa82015-12-17 22:53:03 +010081my $UNSUPPORTED_FAIL = "UNSUPPORTED now FAIL [UNSUP=> FAIL]";
Christophe Lyon71cec962016-06-28 18:27:30 +020082my $UNSUPPORTED_XFAIL = "UNSUPPORTED now XFAIL [UNSUP=>XFAIL]";
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +000083my $UNSUPPORTED_KFAIL = "UNSUPPORTED now KFAIL [UNSUP=>KFAIL]";
Christophe Lyon9dde3332016-06-28 23:00:00 +020084my $UNSUPPORTED_UNSUPPORTED= "UNSUPP now UNSUPP [UNSUP=>UNSUP]";
85my $UNSUPPORTED_UNRESOLVED= "UNSUPP now UNRESOLVED [UNSUP=>UNRES]";
86my $UNSUPPORTED_UNTESTED = "UNSUPP now UNTESTED [UNSUP=>UNTES]";
Christophe Lyon71cec962016-06-28 18:27:30 +020087my $UNSUPPORTED_DISAPPEARS= "UNSUPPORTED disappears [UNSUP=> ]";
88my $UNSUPPORTED_APPEARS = "UNSUPPORTED appears [ =>UNSUP]";
89
90my $UNTESTED_PASS = "UNTESTED now PASS [UNTES=> PASS]";
Christophe Lyona140aa82015-12-17 22:53:03 +010091my $UNTESTED_XPASS = "UNTESTED now XPASS [UNTES=>XPASS]";
Christophe Lyon71cec962016-06-28 18:27:30 +020092my $UNTESTED_FAIL = "UNTESTED now FAIL [UNTES=> FAIL]";
93my $UNTESTED_XFAIL = "UNTESTED now XFAIL [UNTES=>XFAIL]";
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +000094my $UNTESTED_KFAIL = "UNTESTED now KFAIL [UNTES=>KFAIL]";
Christophe Lyon9dde3332016-06-28 23:00:00 +020095my $UNTESTED_UNSUPPORTED = "UNTESTED now UNSUPP [UNTES=>UNSUP]";
96my $UNTESTED_UNRESOLVED = "UNTESTED now UNRESOLVED [UNTES=>UNRES]";
97my $UNTESTED_UNTESTED = "UNTESTED now UNTESTED [UNTES=>UNTES]";
Christophe Lyon71cec962016-06-28 18:27:30 +020098my $UNTESTED_DISAPPEARS = "UNTESTED disappears [UNTES=> ]";
99my $UNTESTED_APPEARS = "UNTESTED appears [ =>UNTES]";
100
101my $UNRESOLVED_PASS = "UNRESOLVED now PASS [UNRES=> PASS]";
Christophe Lyona140aa82015-12-17 22:53:03 +0100102my $UNRESOLVED_XPASS = "UNRESOLVED now XPASS [UNRES=>XPASS]";
Christophe Lyon71cec962016-06-28 18:27:30 +0200103my $UNRESOLVED_FAIL = "UNRESOLVED now FAIL [UNRES=> FAIL]";
104my $UNRESOLVED_XFAIL = "UNRESOLVED now XFAIL [UNRES=>XFAIL]";
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000105my $UNRESOLVED_KFAIL = "UNRESOLVED now KFAIL [UNRES=>KFAIL]";
Christophe Lyon9dde3332016-06-28 23:00:00 +0200106my $UNRESOLVED_UNSUPPORTED= "UNRESOLVED now UNSUPP [UNRES=>UNSUP]";
107my $UNRESOLVED_UNRESOLVED = "UNRESOLVED now UNRESOLVED [UNRES=>UNRES]";
108my $UNRESOLVED_UNTESTED = "UNRESOLVED now UNTESTED [UNRES=>UNTES]";
Christophe Lyon71cec962016-06-28 18:27:30 +0200109my $UNRESOLVED_DISAPPEARS = "UNRESOLVED disappears [UNRES=> ]";
110my $UNRESOLVED_APPEARS = "UNRESOLVED appears [ =>UNRES]";
111
Christophe Lyonbcbd7482016-09-19 14:54:50 +0200112my $ERROR_DISAPPEARS = "ERROR disappears [ERROR=> ]";
113my $ERROR_APPEARS = "ERROR appears [ =>ERROR]";
114
Christophe Lyon71cec962016-06-28 18:27:30 +0200115my $UNHANDLED_CASES = "Unhandled cases [ ..??.. ]";
Christophe Lyon8823eeb2025-04-07 15:40:22 +0000116my $UNSTABLE_CASES = "Flaky cases, ignored [~RANDOM ]";
Christophe Lyon73ac1d82018-06-12 13:32:47 +0000117my $HWDEP_CASES = "HW dependent cases [HW-DEPENDENT]";
Christophe Lyonbff39612015-11-18 16:29:11 +0100118
Christophe Lyon73ac1d82018-06-12 13:32:47 +0000119# Handle status transitions:
120# 'was' is the reference status
121# 'is' is the current status
122# 'cat' is the short name for the transition type
123# 'handler' is a function handling the transition, if non-trivial
124# report_hwdep is a boolean controlling whether to report the
125# transition even if flagged as hardware-dependent
Christophe Lyonbff39612015-11-18 16:29:11 +0100126my @handler_list = (
Christophe Lyon73ac1d82018-06-12 13:32:47 +0000127 {was=>"PASS", is=>"PASS", cat=>$PASS_PASS, report_hwdep=>"false"},
128 {was=>"PASS", is=>"XPASS", cat=>$PASS_XPASS, report_hwdep=>"true"},
129 {was=>"PASS", is=>"FAIL", handler=>\&handle_pass_fail, report_hwdep=>"true"},
130 {was=>"PASS", is=>"XFAIL", cat=>$PASS_XFAIL, report_hwdep=>"true"},
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000131 {was=>"PASS", is=>"KFAIL", cat=>$PASS_KFAIL, report_hwdep=>"true"},
Christophe Lyon73ac1d82018-06-12 13:32:47 +0000132 {was=>"PASS", is=>"UNSUPPORTED",cat=>$PASS_UNSUPPORTED, report_hwdep=>"false"},
133 {was=>"PASS", is=>"UNTESTED", cat=>$PASS_UNTESTED, report_hwdep=>"true"},
134 {was=>"PASS", is=>"UNRESOLVED",cat=>$PASS_UNRESOLVED, report_hwdep=>"true"},
135 {was=>"PASS", is=>"NO_EXIST", cat=>$PASS_DISAPPEARS, report_hwdep=>"false"},
136 {was=>"NO_EXIST", is=>"PASS", cat=>$PASS_APPEARS, report_hwdep=>"false"},
Christophe Lyonfdfbd172016-06-28 18:38:55 +0200137
Christophe Lyon73ac1d82018-06-12 13:32:47 +0000138 {was=>"XPASS", is=>"PASS", cat=>$XPASS_PASS, report_hwdep=>"true"},
139 {was=>"XPASS", is=>"XPASS", cat=>$XPASS_XPASS, report_hwdep=>"true"},
140 {was=>"XPASS", is=>"FAIL", cat=>$XPASS_FAIL, report_hwdep=>"true"},
141 {was=>"XPASS", is=>"XFAIL", cat=>$XPASS_XFAIL, report_hwdep=>"true"},
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000142 {was=>"XPASS", is=>"KFAIL", cat=>$XPASS_KFAIL, report_hwdep=>"true"},
Christophe Lyon73ac1d82018-06-12 13:32:47 +0000143 {was=>"XPASS", is=>"UNSUPPORTED",cat=>$XPASS_UNSUPPORTED, report_hwdep=>"true"},
144 {was=>"XPASS", is=>"UNTESTED", cat=>$XPASS_UNTESTED, report_hwdep=>"true"},
145 {was=>"XPASS", is=>"UNRESOLVED",cat=>$XPASS_UNRESOLVED, report_hwdep=>"true"},
146 {was=>"XPASS", is=>"NO_EXIST", cat=>$XPASS_DISAPPEARS, report_hwdep=>"true"},
147 {was=>"NO_EXIST", is=>"XPASS", cat=>$XPASS_APPEARS, report_hwdep=>"true"},
Christophe Lyonbff39612015-11-18 16:29:11 +0100148
Christophe Lyon73ac1d82018-06-12 13:32:47 +0000149 {was=>"FAIL", is=>"PASS", cat=>$FAIL_PASS, report_hwdep=>"true"},
150 {was=>"FAIL", is=>"XPASS", cat=>$FAIL_XPASS, report_hwdep=>"true"},
151 {was=>"FAIL", is=>"FAIL", cat=>$FAIL_FAIL, report_hwdep=>"true"},
152 {was=>"FAIL", is=>"XFAIL", cat=>$FAIL_XFAIL, report_hwdep=>"true"},
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000153 {was=>"FAIL", is=>"KFAIL", cat=>$FAIL_KFAIL, report_hwdep=>"true"},
Christophe Lyon73ac1d82018-06-12 13:32:47 +0000154 {was=>"FAIL", is=>"UNSUPPORTED",cat=>$FAIL_UNSUPPORTED, report_hwdep=>"true"},
155 {was=>"FAIL", is=>"UNTESTED", cat=>$FAIL_UNTESTED, report_hwdep=>"true"},
156 {was=>"FAIL", is=>"UNRESOLVED",cat=>$FAIL_UNRESOLVED, report_hwdep=>"true"},
157 {was=>"FAIL", is=>"NO_EXIST", cat=>$FAIL_DISAPPEARS, report_hwdep=>"true"},
158 {was=>"NO_EXIST", is=>"FAIL", cat=>$FAIL_APPEARS, report_hwdep=>"true"},
Christophe Lyonfdfbd172016-06-28 18:38:55 +0200159
Christophe Lyon73ac1d82018-06-12 13:32:47 +0000160 {was=>"XFAIL", is=>"PASS", cat=>$XFAIL_PASS, report_hwdep=>"true"},
161 {was=>"XFAIL", is=>"XPASS", cat=>$XFAIL_XPASS, report_hwdep=>"true"},
162 {was=>"XFAIL", is=>"FAIL", cat=>$XFAIL_FAIL, report_hwdep=>"true"},
163 {was=>"XFAIL", is=>"XFAIL", cat=>$XFAIL_XFAIL, report_hwdep=>"true"},
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000164 {was=>"XFAIL", is=>"KFAIL", cat=>$XFAIL_KFAIL, report_hwdep=>"true"},
Christophe Lyon73ac1d82018-06-12 13:32:47 +0000165 {was=>"XFAIL", is=>"UNSUPPORTED",cat=>$XFAIL_UNSUPPORTED, report_hwdep=>"true"},
166 {was=>"XFAIL", is=>"UNTESTED", cat=>$XFAIL_UNTESTED, report_hwdep=>"true"},
167 {was=>"XFAIL", is=>"UNRESOLVED",cat=>$XFAIL_UNRESOLVED, report_hwdep=>"true"},
168 {was=>"XFAIL", is=>"NO_EXIST", cat=>$XFAIL_DISAPPEARS, report_hwdep=>"true"},
169 {was=>"NO_EXIST", is=>"XFAIL", cat=>$XFAIL_APPEARS, report_hwdep=>"true"},
Christophe Lyonbff39612015-11-18 16:29:11 +0100170
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000171 {was=>"KFAIL", is=>"PASS", cat=>$KFAIL_PASS, report_hwdep=>"true"},
172 {was=>"KFAIL", is=>"XPASS", cat=>$KFAIL_XPASS, report_hwdep=>"true"},
173 {was=>"KFAIL", is=>"FAIL", cat=>$KFAIL_FAIL, report_hwdep=>"true"},
174 {was=>"KFAIL", is=>"XFAIL", cat=>$KFAIL_XFAIL, report_hwdep=>"true"},
175 {was=>"KFAIL", is=>"KFAIL", cat=>$KFAIL_KFAIL, report_hwdep=>"true"},
176 {was=>"KFAIL", is=>"UNSUPPORTED",cat=>$KFAIL_UNSUPPORTED, report_hwdep=>"true"},
177 {was=>"KFAIL", is=>"UNTESTED", cat=>$KFAIL_UNTESTED, report_hwdep=>"true"},
178 {was=>"KFAIL", is=>"UNRESOLVED",cat=>$KFAIL_UNRESOLVED, report_hwdep=>"true"},
179 {was=>"KFAIL", is=>"NO_EXIST", cat=>$KFAIL_DISAPPEARS, report_hwdep=>"true"},
180 {was=>"NO_EXIST", is=>"KFAIL", cat=>$KFAIL_APPEARS, report_hwdep=>"true"},
181
Christophe Lyon73ac1d82018-06-12 13:32:47 +0000182 {was=>"UNSUPPORTED", is=>"PASS", cat=>$UNSUPPORTED_PASS, report_hwdep=>"true"},
183 {was=>"UNSUPPORTED", is=>"XPASS", cat=>$UNSUPPORTED_XPASS, report_hwdep=>"true"},
184 {was=>"UNSUPPORTED", is=>"FAIL", cat=>$UNSUPPORTED_FAIL, report_hwdep=>"true"},
185 {was=>"UNSUPPORTED", is=>"XFAIL", cat=>$UNSUPPORTED_XFAIL, report_hwdep=>"true"},
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000186 {was=>"UNSUPPORTED", is=>"KFAIL", cat=>$UNSUPPORTED_KFAIL, report_hwdep=>"true"},
Christophe Lyon73ac1d82018-06-12 13:32:47 +0000187 {was=>"UNSUPPORTED", is=>"UNSUPPORTED",cat=>$UNSUPPORTED_UNSUPPORTED, report_hwdep=>"true"},
188 {was=>"UNSUPPORTED", is=>"UNTESTED", cat=>$UNSUPPORTED_UNTESTED, report_hwdep=>"true"},
189 {was=>"UNSUPPORTED", is=>"UNRESOLVED",cat=>$UNSUPPORTED_UNRESOLVED, report_hwdep=>"true"},
190 {was=>"UNSUPPORTED", is=>"NO_EXIST", cat=>$UNSUPPORTED_DISAPPEARS, report_hwdep=>"true"},
191 {was=>"NO_EXIST", is=>"UNSUPPORTED", cat=>$UNSUPPORTED_APPEARS, report_hwdep=>"true"},
Christophe Lyona140aa82015-12-17 22:53:03 +0100192
Christophe Lyon73ac1d82018-06-12 13:32:47 +0000193 {was=>"UNTESTED", is=>"PASS", cat=>$UNTESTED_PASS, report_hwdep=>"true"},
194 {was=>"UNTESTED", is=>"XPASS", cat=>$UNTESTED_XPASS, report_hwdep=>"true"},
195 {was=>"UNTESTED", is=>"FAIL", cat=>$UNTESTED_FAIL, report_hwdep=>"true"},
196 {was=>"UNTESTED", is=>"XFAIL", cat=>$UNTESTED_XFAIL, report_hwdep=>"true"},
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000197 {was=>"UNTESTED", is=>"KFAIL", cat=>$UNTESTED_KFAIL, report_hwdep=>"true"},
Christophe Lyon73ac1d82018-06-12 13:32:47 +0000198 {was=>"UNTESTED", is=>"UNSUPPORTED",cat=>$UNTESTED_UNSUPPORTED,report_hwdep=>"true"},
199 {was=>"UNTESTED", is=>"UNTESTED", cat=>$UNTESTED_UNTESTED, report_hwdep=>"true"},
200 {was=>"UNTESTED", is=>"UNRESOLVED",cat=>$UNTESTED_UNRESOLVED, report_hwdep=>"true"},
201 {was=>"UNTESTED", is=>"NO_EXIST", cat=>$UNTESTED_DISAPPEARS, report_hwdep=>"true"},
202 {was=>"NO_EXIST", is=>"UNTESTED", cat=>$UNTESTED_APPEARS, report_hwdep=>"true"},
Christophe Lyona140aa82015-12-17 22:53:03 +0100203
Christophe Lyon73ac1d82018-06-12 13:32:47 +0000204 {was=>"UNRESOLVED", is=>"PASS", cat=>$UNRESOLVED_PASS, report_hwdep=>"true"},
205 {was=>"UNRESOLVED", is=>"XPASS", cat=>$UNRESOLVED_XPASS, report_hwdep=>"true"},
206 {was=>"UNRESOLVED", is=>"FAIL", cat=>$UNRESOLVED_FAIL, report_hwdep=>"true"},
207 {was=>"UNRESOLVED", is=>"XFAIL", cat=>$UNRESOLVED_XFAIL, report_hwdep=>"true"},
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000208 {was=>"UNRESOLVED", is=>"KFAIL", cat=>$UNRESOLVED_KFAIL, report_hwdep=>"true"},
Christophe Lyon73ac1d82018-06-12 13:32:47 +0000209 {was=>"UNRESOLVED", is=>"UNSUPPORTED",cat=>$UNRESOLVED_UNSUPPORTED, report_hwdep=>"true"},
210 {was=>"UNRESOLVED", is=>"UNTESTED", cat=>$UNRESOLVED_UNTESTED, report_hwdep=>"true"},
211 {was=>"UNRESOLVED", is=>"UNRESOLVED",cat=>$UNRESOLVED_UNRESOLVED, report_hwdep=>"true"},
212 {was=>"UNRESOLVED", is=>"NO_EXIST", cat=>$UNRESOLVED_DISAPPEARS, report_hwdep=>"true"},
213 {was=>"NO_EXIST", is=>"UNRESOLVED", cat=>$UNRESOLVED_APPEARS, report_hwdep=>"true"},
Christophe Lyondc66fc52016-04-05 17:38:07 +0200214
Christophe Lyon73ac1d82018-06-12 13:32:47 +0000215 {was=>"ERROR", is=>"NO_EXIST", cat=>$ERROR_DISAPPEARS, report_hwdep=>"true"},
216 {was=>"NO_EXIST", is=>"ERROR", cat=>$ERROR_APPEARS, report_hwdep=>"true"},
Christophe Lyonbcbd7482016-09-19 14:54:50 +0200217
Christophe Lyonbff39612015-11-18 16:29:11 +0100218# {was=>"NO_EXIST", is=>"NO_EXIST", handler=>\&handle_not_yet_supported}
219);
220
221######################################################
222# TREAT ARGUMENTS
223
224my $verbose=0;
225my $quiet=0;
226my $long=0;
227my $short=0;
228my $debug=0;
Thiago Jung Bauermann99efda82023-02-28 23:03:05 +0000229my $merge_mode=0; # Merge result sum files into reference sum file
230my $output_file;
Christophe Lyonbff39612015-11-18 16:29:11 +0100231my ($testroot, $basename);
232my ($ref_file_name, $res_file_name);
233my $nounstable=0;
234my $unstablefile=0;
235my @unstable_markers=();
Christophe Lyon8823eeb2025-04-07 15:40:22 +0000236my $flakyfile=0;
Christophe Lyon73ac1d82018-06-12 13:32:47 +0000237
238my $no_hwdep=0; # Ignore hw-dependent flag (ie. consider all tests as *not* hw-dependent
239my $hwdep_file=0; # File containing the list of hw-dependent tests
240my @hwdep_markers=(); # Optional markers when parsing hwdep_file
241
Christophe Lyonca9d8302017-05-22 12:04:00 +0000242my $ratio_thresh = 0.95; # Warn if pass ratio is below this threshold
Christophe Lyonbff39612015-11-18 16:29:11 +0100243
244GetOptions ("l" => \$long,
Thiago Jung Bauermann99efda82023-02-28 23:03:05 +0000245 "o=s" => \$output_file,
Christophe Lyonbff39612015-11-18 16:29:11 +0100246 "s" => \$short,
247 "q" => \$quiet,
248 "v" => \$verbose,
249 "dbg" => \$debug,
250 "testroot=s" => \$testroot,
251 "basename=s" => \$basename,
Christophe Lyonca9d8302017-05-22 12:04:00 +0000252 "pass-thresh=f" => \$ratio_thresh,
Christophe Lyonbff39612015-11-18 16:29:11 +0100253 "no-unstable" => \$nounstable,
254 "unstable-tests=s" => \$unstablefile,
Christophe Lyon73ac1d82018-06-12 13:32:47 +0000255 "unstable-marker=s" => \@unstable_markers,
256 "no-hwdep" => \$no_hwdep,
257 "hwdep-tests=s" => \$hwdep_file,
Thiago Jung Bauermann99efda82023-02-28 23:03:05 +0000258 "hwdep-marker=s" => \@hwdep_markers,
Christophe Lyon8823eeb2025-04-07 15:40:22 +0000259 "flaky-tests=s" => \$flakyfile,
Thiago Jung Bauermann99efda82023-02-28 23:03:05 +0000260 "merge" => \$merge_mode);
261
262# Merge is a separate operating mode of this script where instead of comparing sum files,
263# it merges them. It could be a separate script, but it's kept here to reuse the sum file
264# parsing code.
265#
266# In this mode, the script will merge the sum files provided as arguments into one
267# synthetic sum file. The reference sum file will be the first one provided as argument.
268# For tests that didn't pass, check the other sum files to see whether that test PASSed or
269# XFAILed in any of them. If so, the status for the test is changed to PASS or XFAIL in
270# the reference file. The result is written to the file given by the '-o' option.
271if ($merge_mode) {
272 $ref_file_name = shift(@ARGV);
273 my $ref = read_sum($ref_file_name);
274 my @res;
275 foreach (@ARGV) {
276 push(@res, read_sum($_));
277 }
278
279 exit merge($output_file, $ref_file_name, @res);
280}
Christophe Lyonbff39612015-11-18 16:29:11 +0100281
282$ref_file_name = $ARGV[0] if ($#ARGV == 1);
283$res_file_name = $ARGV[1] if ($#ARGV == 1);
284
285$ref_file_name = $testroot."/expected_results/".$basename if ($testroot and $basename);
286$res_file_name = $testroot."/testing/run/".$basename if ($testroot and $basename);
287&usage if (not $ref_file_name or not $res_file_name);
288
289my ($col_boldred, $col_red, $col_boldgreen, $col_green, $col_boldpink, $col_pink, $col_reset)
290 = ("\033[31;1m","\033[31;3m","\033[32;1m","\033[32;3m","\033[35;1m","\033[35;2m","\033[0m");
291($col_boldred, $col_red, $col_boldgreen, $col_green, $col_boldpink, $col_pink, $col_reset)
292 = ("","","","","","","") if (not I_am_interactive());
293
294######################################################
295# MAIN PROGRAM
296# print "comparing $ref_file_name $res_file_name\n";
297
298# If none of the 2 .sum exists, nothing to compare: exit early.
299exit 0 if ( (! -e $ref_file_name) && (! -e $res_file_name ));
300
301my $ref = read_sum($ref_file_name) ;
302my $res = read_sum($res_file_name) ;
303my @unstablelist = ();
304
305@unstablelist = read_unstable($unstablefile) if ($unstablefile ne 0);
Christophe Lyon8823eeb2025-04-07 15:40:22 +0000306read_flaky($flakyfile, \@unstablelist) if ($flakyfile ne 0);
Christophe Lyonbff39612015-11-18 16:29:11 +0100307
Christophe Lyon73ac1d82018-06-12 13:32:47 +0000308# Import list of hw-dependent files, if provided
309my @hwdep_list = ();
310
311@hwdep_list = read_unstable($hwdep_file) if ($hwdep_file ne 0);
312
Christophe Lyonbff39612015-11-18 16:29:11 +0100313compare_results($ref, $res);
314
315my $final_result = print_compare_results_summary($ref, $res);
316
317exit $final_result;
318
319######################################################
320# UTILITIES
321
322sub empty_result()
323{
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000324 my %empty_result;# = {PASS=>0, FAIL=>0, XPASS=>0, XFAIL=>0, KFAIL=>0, UNSUPPORTED=>0, UNTESTED=>0, UNRESOLVED=>0, ERROR=>0};
325 $empty_result{PASS}=$empty_result{FAIL}=$empty_result{XPASS}=$empty_result{XFAIL}=$empty_result{KFAIL}=0;
Christophe Lyonbcbd7482016-09-19 14:54:50 +0200326 $empty_result{UNSUPPORTED}=$empty_result{UNTESTED}=$empty_result{UNRESOLVED}=$empty_result{NO_EXIST}=$empty_result{ERROR}=0;
Christophe Lyon9a3ce972021-06-30 23:18:23 +0000327 $empty_result{NB}=0;
Christophe Lyonbff39612015-11-18 16:29:11 +0100328 return \%empty_result;
329}
330sub I_am_interactive {
331 return -t STDIN && -t STDOUT;
332}
333sub usage()
334{
335 print "Usage : $app <ref_file.sum> <result_file.sum>\n";
336 exit 1;
337}
338
339
340######################################################
341# PARSING
342sub read_sum($)
343{
344 my ($sum_file) = @_;
345 my $res = empty_result();
346 my %testcases;
Thiago Jung Bauermann9cbfa082024-02-24 21:31:48 -0300347 my %exp_files;
Christophe Lyonbff39612015-11-18 16:29:11 +0100348 $res->{testcases} = \%testcases;
Thiago Jung Bauermann9cbfa082024-02-24 21:31:48 -0300349 $res->{exp_files} = \%exp_files;
Christophe Lyonbff39612015-11-18 16:29:11 +0100350 my $pending_timeout=0;
Christophe Lyonc63afc92021-07-01 09:52:29 +0000351 my $current_tool="";
Christophe Lyon14d1ec82017-03-23 14:59:58 +0000352 my $current_exp="";
Christophe Lyonbff39612015-11-18 16:29:11 +0100353
Christophe Lyonad8c7242016-02-03 13:04:28 +0100354 $res->{EXEC}->{PASS} = 0;
355 $res->{EXEC}->{FAIL} = 0;
356
Christophe Lyonbff39612015-11-18 16:29:11 +0100357 open SUMFILE, $sum_file or die $!;
358 while (<SUMFILE>)
359 {
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000360 if (m/^(PASS|XPASS|FAIL|XFAIL|KFAIL|UNSUPPORTED|UNTESTED|UNRESOLVED|ERROR): *(.*)/)
Christophe Lyonbff39612015-11-18 16:29:11 +0100361 {
362 my ($diag,$tc) = ($1,$2);
363 my %tcresult;
364 $tc =~ s/==[0-9]+== Shadow memory range interleaves with an existing memory mapping. ASan cannot proceed correctly./==<pid>== Shadow memory range interleaves with an existing memory mapping. ASan cannot proceed correctly./;
Christophe Lyonc63afc92021-07-01 09:52:29 +0000365 # Prefix test name wih .exp filename to help report
366 # regressions/run bisect.
367 $tc = "$current_tool:$current_exp=$tc";
Christophe Lyonbff39612015-11-18 16:29:11 +0100368 $testcases{$tc} = empty_result() if (not exists $testcases{$tc});
369 $testcases{$tc}->{$diag}++;
370 $testcases{$tc}->{HAS_TIMED_OUT} = $pending_timeout;
Christophe Lyonc63afc92021-07-01 09:52:29 +0000371 $testcases{$tc}->{TOOL_EXP} = "$current_tool:$current_exp";
Christophe Lyon9a3ce972021-06-30 23:18:23 +0000372 $testcases{$tc}->{NB}++;
Christophe Lyonbff39612015-11-18 16:29:11 +0100373 $pending_timeout = 0;
374 $res->{$diag}++;
Christophe Lyonad8c7242016-02-03 13:04:28 +0100375 # Count execution tests, for a sanity check
376 if ($tc =~ /execution/)
377 {
378 $res->{EXEC}->{$diag}++;
379 }
Christophe Lyonbff39612015-11-18 16:29:11 +0100380 }
381 elsif (m/WARNING: program timed out/)
382 {
383 $pending_timeout = 1;
384 }
385 elsif (m/^(# of expected passes|# of unexpected failures|# of expected failures|# of known failures|# of unsupported tests|# of untested testcases)\s+(.*)/)
386 {
387 $res->{"summary - "."$1"} = $2;
388 }
389 elsif (m/^\/.*\/([^\/]+)\s+version\s+(.*)/)
390 {
391 $res->{tool} = $1;
392 $res->{version} = $2;
393 $res->{version} =~ s/ [-(].*//;
394 }
Christophe Lyon14d1ec82017-03-23 14:59:58 +0000395 elsif (m/^Running target .*/)
396 {
397 }
398 elsif (m/^Running (.*) \.\.\.*/)
399 {
400 $current_exp=$1;
401 $current_exp =~ s|.*/testsuite/||;
Thiago Jung Bauermann9cbfa082024-02-24 21:31:48 -0300402 # For merging, we want to know whether the exp file is present in the result.
403 $exp_files{"$current_tool:$current_exp"} = 1;
Christophe Lyon14d1ec82017-03-23 14:59:58 +0000404 }
Christophe Lyonc63afc92021-07-01 09:52:29 +0000405 elsif (m/^\t\t=== (.*) tests ===/)
406 {
407 $current_tool=$1;
408 }
409 elsif (m/^\t\t=== (.*) Summary ===/)
410 {
411 $current_tool="";
412 $current_exp="";
413 }
Christophe Lyonbff39612015-11-18 16:29:11 +0100414 }
415 close SUMFILE;
416 return $res;
417}
418
Christophe Lyon73ac1d82018-06-12 13:32:47 +0000419# Parse list of unstable/hw-dependent tests
Christophe Lyonbff39612015-11-18 16:29:11 +0100420sub read_unstable($)
421{
422 my ($unstable_file) = @_;
423 my @unstable_tests = ();
424
425 open UNSTABLEFILE, $unstable_file or die $!;
426 while (<UNSTABLEFILE>)
427 {
428 # Skip lines starting with '#', or with spaces only
429 if ((/^#/) || (/^[ ]*$/))
430 {
431 }
432 else
433 {
434 chomp;
435
436 my $test = $_;
437
438 # Check if line is of type: target:testname
Christophe Lyon5e7241c2015-12-04 12:57:27 +0100439 if (/^(.*?):/)
Christophe Lyonbff39612015-11-18 16:29:11 +0100440 {
441 foreach my $unstable_marker (@unstable_markers)
442 {
443 if ($unstable_marker eq $1) {
444 # If target matches the one supplied as script
445 # argument, add the testname to the list
Christophe Lyon5e7241c2015-12-04 12:57:27 +0100446 $test =~ s/.*?://;
Christophe Lyonbff39612015-11-18 16:29:11 +0100447 push @unstable_tests, $test;
448 }
449 }
450 } else {
451 push @unstable_tests, $test;
452 }
453 }
454 }
455 close UNSTABLEFILE;
456 return @unstable_tests;
457}
458
Christophe Lyon8823eeb2025-04-07 15:40:22 +0000459# Parse list of flaky tests and append to $unstable_tests. This is
460# similar to read_unstable, but reads a file produced by
461# validate_failures.py
462# FIXME: Handle expire attribute
463sub read_flaky($$)
464{
465 my ($flaky_file, $unstable_tests) = @_;
466
467 open FLAKYFILE, $flaky_file or die $!;
468 while (<FLAKYFILE>)
469 {
470 # Only parse lines starting with "flaky[.*] |"
471 if (/^[ ]*flaky.* \| /)
472 {
473 chomp;
474
475 my $test = $_;
476
477 # Check if line is of type: 'flaky,expire=YYYYMMDD | testname'
478 if (/^[ ]*flaky,expire=.* \| (PASS|XPASS|FAIL|XFAIL|KFAIL|UNSUPPORTED|UNTESTED|UNRESOLVED|ERROR): /)
479 {
Christophe Lyon4bd47892025-04-18 12:53:34 +0000480 $test =~ s/.*flaky,expire=.* \| (PASS|XPASS|FAIL|XFAIL|KFAIL|UNSUPPORTED|UNTESTED|UNRESOLVED|ERROR): //;
Christophe Lyon8823eeb2025-04-07 15:40:22 +0000481 } else {
482 $test =~ s/.*flaky \| (PASS|XPASS|FAIL|XFAIL|KFAIL|UNSUPPORTED|UNTESTED|UNRESOLVED|ERROR): //;
483 }
484 push @$unstable_tests, $test;
485 }
486 }
487 close FLAKYFILE;
488}
489
Christophe Lyonbff39612015-11-18 16:29:11 +0100490######################################################
491# DIFFING
492sub handle_pass_fail($$$$)
493{
494 my ($ref, $res, $diag_diag, $tc) = @_;
495 if ($res->{testcases}->{$tc}->{HAS_TIMED_OUT})
496 {
497 push @{$res->{$PASSED_NOW_TIMEOUTS}}, $tc;
498 }
499 else
500 {
Christophe Lyon73ac1d82018-06-12 13:32:47 +0000501 # This transition is flagged as hw-dependent if:
502 # - the name is in the list
503 # - the transition should not be reported (but be flagged as hw-dependent instead)
504 # - --no-hwdep was not provided
505 if ((grep { (index $tc,$_)!=-1} @hwdep_list)
506 && ($diag_diag->{report_hwdep} eq "false")
507 && ($no_hwdep == 0)) {
508 push @{$res->{$HWDEP_CASES}}, $tc;
509 } else {
510 push @{$res->{$PASS_FAIL}}, $tc;
511 }
Christophe Lyonbff39612015-11-18 16:29:11 +0100512 }
513}
514
515sub compare_results($$)
516{
517 my ($ref, $res) = @_;
518
Christophe Lyondded4d82016-06-28 18:12:38 +0200519 @{$res->{$PASS_PASS}} = ();
Christophe Lyondded4d82016-06-28 18:12:38 +0200520 @{$res->{$PASS_XPASS}} = ();
Christophe Lyonfdfbd172016-06-28 18:38:55 +0200521 @{$res->{$PASS_FAIL}} = ();
522 @{$res->{$PASS_XFAIL}} = ();
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000523 @{$res->{$PASS_KFAIL}} = ();
Christophe Lyon9dde3332016-06-28 23:00:00 +0200524 @{$res->{$PASS_UNSUPPORTED}} = ();
525 @{$res->{$PASS_UNTESTED}} = ();
526 @{$res->{$PASS_UNRESOLVED}} = ();
Christophe Lyonfdfbd172016-06-28 18:38:55 +0200527 @{$res->{$PASS_DISAPPEARS}} = ();
528 @{$res->{$PASS_APPEARS}} = ();
529 @{$res->{$PASSED_NOW_TIMEOUTS}} = ();
530
Christophe Lyondded4d82016-06-28 18:12:38 +0200531 @{$res->{$XPASS_PASS}} = ();
Christophe Lyonfdfbd172016-06-28 18:38:55 +0200532 @{$res->{$XPASS_XPASS}} = ();
533 @{$res->{$XPASS_FAIL}} = ();
534 @{$res->{$XPASS_XFAIL}} = ();
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000535 @{$res->{$XPASS_KFAIL}} = ();
Christophe Lyon9dde3332016-06-28 23:00:00 +0200536 @{$res->{$XPASS_UNSUPPORTED}} = ();
537 @{$res->{$XPASS_UNTESTED}} = ();
538 @{$res->{$XPASS_UNRESOLVED}} = ();
Christophe Lyonfdfbd172016-06-28 18:38:55 +0200539 @{$res->{$XPASS_DISAPPEARS}} = ();
540 @{$res->{$XPASS_APPEARS}} = ();
541
542 @{$res->{$FAIL_PASS}} = ();
543 @{$res->{$FAIL_XPASS}} = ();
544 @{$res->{$FAIL_FAIL}} = ();
545 @{$res->{$FAIL_XFAIL}} = ();
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000546 @{$res->{$FAIL_KFAIL}} = ();
Christophe Lyon9dde3332016-06-28 23:00:00 +0200547 @{$res->{$FAIL_UNSUPPORTED}} = ();
548 @{$res->{$FAIL_UNTESTED}} = ();
549 @{$res->{$FAIL_UNRESOLVED}} = ();
Christophe Lyonfdfbd172016-06-28 18:38:55 +0200550 @{$res->{$FAIL_DISAPPEARS}} = ();
551 @{$res->{$FAIL_APPEARS}} = ();
552
Christophe Lyondded4d82016-06-28 18:12:38 +0200553 @{$res->{$XFAIL_PASS}} = ();
554 @{$res->{$XFAIL_XPASS}} = ();
555 @{$res->{$XFAIL_FAIL}} = ();
Christophe Lyonfdfbd172016-06-28 18:38:55 +0200556 @{$res->{$XFAIL_XFAIL}} = ();
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000557 @{$res->{$XFAIL_KFAIL}} = ();
Christophe Lyon9dde3332016-06-28 23:00:00 +0200558 @{$res->{$XFAIL_UNSUPPORTED}} = ();
559 @{$res->{$XFAIL_UNTESTED}} = ();
560 @{$res->{$XFAIL_UNRESOLVED}} = ();
Christophe Lyonfdfbd172016-06-28 18:38:55 +0200561 @{$res->{$XFAIL_DISAPPEARS}} = ();
562 @{$res->{$XFAIL_APPEARS}} = ();
563
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000564 @{$res->{$KFAIL_PASS}} = ();
565 @{$res->{$KFAIL_XPASS}} = ();
566 @{$res->{$KFAIL_FAIL}} = ();
567 @{$res->{$KFAIL_XFAIL}} = ();
568 @{$res->{$KFAIL_KFAIL}} = ();
569 @{$res->{$KFAIL_UNSUPPORTED}} = ();
570 @{$res->{$KFAIL_UNTESTED}} = ();
571 @{$res->{$KFAIL_UNRESOLVED}} = ();
572 @{$res->{$KFAIL_DISAPPEARS}} = ();
573 @{$res->{$KFAIL_APPEARS}} = ();
574
Christophe Lyona140aa82015-12-17 22:53:03 +0100575 @{$res->{$UNSUPPORTED_PASS}} = ();
576 @{$res->{$UNSUPPORTED_XPASS}} = ();
577 @{$res->{$UNSUPPORTED_FAIL}} = ();
578 @{$res->{$UNSUPPORTED_XFAIL}} = ();
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000579 @{$res->{$UNSUPPORTED_KFAIL}} = ();
Christophe Lyon9dde3332016-06-28 23:00:00 +0200580 @{$res->{$UNSUPPORTED_UNSUPPORTED}} = ();
581 @{$res->{$UNSUPPORTED_UNTESTED}} = ();
582 @{$res->{$UNSUPPORTED_UNRESOLVED}} = ();
Christophe Lyona140aa82015-12-17 22:53:03 +0100583 @{$res->{$UNSUPPORTED_DISAPPEARS}} = ();
Christophe Lyondc66fc52016-04-05 17:38:07 +0200584 @{$res->{$UNSUPPORTED_APPEARS}} = ();
Christophe Lyonfdfbd172016-06-28 18:38:55 +0200585
Christophe Lyona140aa82015-12-17 22:53:03 +0100586 @{$res->{$UNTESTED_PASS}} = ();
587 @{$res->{$UNTESTED_XPASS}} = ();
588 @{$res->{$UNTESTED_FAIL}} = ();
589 @{$res->{$UNTESTED_XFAIL}} = ();
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000590 @{$res->{$UNTESTED_KFAIL}} = ();
Christophe Lyon9dde3332016-06-28 23:00:00 +0200591 @{$res->{$UNTESTED_UNSUPPORTED}} = ();
592 @{$res->{$UNTESTED_UNTESTED}} = ();
593 @{$res->{$UNTESTED_UNRESOLVED}} = ();
Christophe Lyona140aa82015-12-17 22:53:03 +0100594 @{$res->{$UNTESTED_DISAPPEARS}} = ();
Christophe Lyondc66fc52016-04-05 17:38:07 +0200595 @{$res->{$UNTESTED_APPEARS}} = ();
Christophe Lyonfdfbd172016-06-28 18:38:55 +0200596
Christophe Lyona140aa82015-12-17 22:53:03 +0100597 @{$res->{$UNRESOLVED_PASS}} = ();
598 @{$res->{$UNRESOLVED_XPASS}} = ();
599 @{$res->{$UNRESOLVED_FAIL}} = ();
600 @{$res->{$UNRESOLVED_XFAIL}} = ();
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000601 @{$res->{$UNRESOLVED_KFAIL}} = ();
Christophe Lyon9dde3332016-06-28 23:00:00 +0200602 @{$res->{$UNRESOLVED_UNSUPPORTED}} = ();
603 @{$res->{$UNRESOLVED_UNTESTED}} = ();
604 @{$res->{$UNRESOLVED_UNRESOLVED}} = ();
Christophe Lyona140aa82015-12-17 22:53:03 +0100605 @{$res->{$UNRESOLVED_DISAPPEARS}} = ();
Christophe Lyondc66fc52016-04-05 17:38:07 +0200606 @{$res->{$UNRESOLVED_APPEARS}} = ();
Christophe Lyonfdfbd172016-06-28 18:38:55 +0200607
Christophe Lyonbcbd7482016-09-19 14:54:50 +0200608 @{$res->{$ERROR_DISAPPEARS}} = ();
609 @{$res->{$ERROR_APPEARS}} = ();
610
Christophe Lyonbff39612015-11-18 16:29:11 +0100611 @{$res->{$UNHANDLED_CASES}} = ();
612 @{$res->{$UNSTABLE_CASES}} = ();
Christophe Lyon73ac1d82018-06-12 13:32:47 +0000613 @{$res->{$HWDEP_CASES}} = ();
Christophe Lyonbff39612015-11-18 16:29:11 +0100614
615 #### MERGE REF AND RES
616 foreach my $key (sort (keys %{$res->{testcases}}))
617 {
618 if (not exists $ref->{testcases}->{$key}) {
619 $ref->{testcases}->{$key} = empty_result();
620 $ref->{testcases}->{$key}->{NO_EXIST} = 1;
Christophe Lyonc63afc92021-07-01 09:52:29 +0000621 $ref->{testcases}->{$key}->{TOOL_EXP} = $res->{testcases}->{$key}->{TOOL_EXP};
Christophe Lyonbff39612015-11-18 16:29:11 +0100622 }
Christophe Lyon9a3ce972021-06-30 23:18:23 +0000623
624 # Consistency check, useful in case of duplicate test names
625 if ($ref->{testcases}->{$key}->{NB} != $res->{testcases}->{$key}->{NB}) {
626 print "Number of occurrences mismatch $key (ref $ref->{testcases}->{$key}->{NB} vs $res->{testcases}->{$key}->{NB})\n" if ($debug);
627 if ($ref->{testcases}->{$key}->{NB} > $res->{testcases}->{$key}->{NB}) {
628 $res->{testcases}->{$key}->{NO_EXIST} = 1;
629 } elsif ($ref->{testcases}->{$key}->{NB} < $res->{testcases}->{$key}->{NB}) {
630 $ref->{testcases}->{$key}->{NO_EXIST} = 1;
631 }
632 }
Christophe Lyonbff39612015-11-18 16:29:11 +0100633 }
634 foreach my $key (keys %{$ref->{testcases}})
635 {
636 if (not exists $res->{testcases}->{$key})
637 {
638 $res->{testcases}->{$key} = empty_result();
639 $res->{testcases}->{$key}->{NO_EXIST} = 1;
Christophe Lyonc63afc92021-07-01 09:52:29 +0000640 $res->{testcases}->{$key}->{TOOL_EXP} = $ref->{testcases}->{$key}->{TOOL_EXP};
Christophe Lyonbff39612015-11-18 16:29:11 +0100641 }
Christophe Lyon9a3ce972021-06-30 23:18:23 +0000642
643 # No need for similar consistency check: since we are
644 # checking for tests whose number of occurrences are
645 # different, they are present in both ref and res, so
646 # no need to check again here.
Christophe Lyonbff39612015-11-18 16:29:11 +0100647 }
648
649 #### ACTIONS FOR EACH CASES
650 my %unstable_found;
651
652 foreach my $key (sort (keys %{$ref->{testcases}}))
653 {
654 foreach my $diag_diag (@handler_list)
655 {
656 if ($ref->{testcases}->{$key}->{$diag_diag->{was}} != $res->{testcases}->{$key}->{$diag_diag->{was}}
Christophe Lyon9a3ce972021-06-30 23:18:23 +0000657 and $ref->{testcases}->{$key}->{$diag_diag->{was}}
Christophe Lyonbff39612015-11-18 16:29:11 +0100658 and $res->{testcases}->{$key}->{$diag_diag->{is}})
659 {
Christophe Lyon1ed93102021-06-30 23:04:43 +0000660 print "$key ref $diag_diag->{was}:$ref->{testcases}->{$key}->{$diag_diag->{was}}, res $diag_diag->{was}:$res->{testcases}->{$key}->{$diag_diag->{was}}, res $diag_diag->{is}:$res->{testcases}->{$key}->{$diag_diag->{is}} \n" if ($debug);
Christophe Lyon28a92782017-09-13 09:00:39 +0000661 # If testcase is listed as 'unstable' mark it as such
662 # and skip other processing to avoid listing it twice.
Christophe Lyonbff39612015-11-18 16:29:11 +0100663 {
664 if (grep { (index $key,$_)!=-1} @unstablelist)
665 {
666 print "[unstable] $key\n" if ($debug);
667 $unstable_found{$key}=1;
668 }
669 else {
670 print "[$diag_diag->{was} => $diag_diag->{is}] $key\n" if ($debug);
671 if ($diag_diag->{handler})
672 {
673 $diag_diag->{handler} ($ref, $res, $diag_diag, $key);
674 }
675 else
676 {
Christophe Lyon73ac1d82018-06-12 13:32:47 +0000677 # This transition is flagged as hw-dependent if:
678 # - the name is in the list
679 # - the transition should not be reported (but be flagged as hw-dependent instead)
680 # - --no-hwdep was not provided
681 if ((grep { (index $key,$_)!=-1} @hwdep_list)
682 && ($diag_diag->{report_hwdep} eq "false")
683 && ($no_hwdep == 0)) {
684 push @{$res->{$HWDEP_CASES}}, $key;
685 } else {
686 push @{$res->{$diag_diag->{cat}}}, $key;
687 }
Christophe Lyonbff39612015-11-18 16:29:11 +0100688 }
689 }
690 }
691 }
692 }
693 }
694 push @{$res->{$UNSTABLE_CASES}}, (sort (keys (%unstable_found))) if ($nounstable == 0);
695
696}
697
698######################################################
699# PRINTING
700sub print_tclist($@)
701{
Christophe Lyon14d1ec82017-03-23 14:59:58 +0000702 # The 1st parameter is used to find the name of the .exp file
Christophe Lyon28a92782017-09-13 09:00:39 +0000703 # associated with the testcase.
Christophe Lyon14d1ec82017-03-23 14:59:58 +0000704 my ($this_res, $cat, @tclist) = @_;
Christophe Lyonc63afc92021-07-01 09:52:29 +0000705 my $this_tool_exp = "";
Christophe Lyon14d1ec82017-03-23 14:59:58 +0000706 if (scalar(@tclist))
707 {
708 print " - ".$cat.":\n\n";
709 foreach my $case (@tclist)
710 {
Christophe Lyonc63afc92021-07-01 09:52:29 +0000711 if ($this_tool_exp ne $this_res->{testcases}->{$case}->{TOOL_EXP}) {
712 $this_tool_exp = $this_res->{testcases}->{$case}->{TOOL_EXP};
713 print " Executed from: $this_tool_exp\n";
Christophe Lyon14d1ec82017-03-23 14:59:58 +0000714 }
715 print " $case\n";
716 }
717 print "\n\n";
718 }
Christophe Lyonbff39612015-11-18 16:29:11 +0100719}
720
721sub print_compare_results_summary($$)
722{
723 my ($ref, $res) = @_;
724 my $return_value=0;
Christophe Lyonf5aeb342015-12-08 14:47:16 +0100725 my $total_better = 0;
Christophe Lyonbff39612015-11-18 16:29:11 +0100726 my $rtotal = 0;
727 my $quiet_reg = $quiet;
Christophe Lyond618f662016-02-02 19:07:58 +0100728 my $ref_ratio = 0;
Christophe Lyon0ab7d352016-04-06 10:39:58 +0200729 my $ref_total = 0;
Christophe Lyond618f662016-02-02 19:07:58 +0100730 my $res_ratio = 0;
Christophe Lyon0ab7d352016-04-06 10:39:58 +0200731 my $res_total = 0;
Christophe Lyonad8c7242016-02-03 13:04:28 +0100732 my $ignore_exec = 0;
733 my $ref_has_exec_tests = 0;
734 my $res_has_exec_tests = 0;
Christophe Lyond618f662016-02-02 19:07:58 +0100735
736 # Compute the pass ratio as a sanity check
Christophe Lyon0ab7d352016-04-06 10:39:58 +0200737 $ref_total = $ref->{PASS} +
738 $ref->{XFAIL} +
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000739 $ref->{KFAIL} +
Christophe Lyon0ab7d352016-04-06 10:39:58 +0200740 $ref->{XPASS} +
741 $ref->{FAIL} +
742 $ref->{UNRESOLVED} +
743 $ref->{UNSUPPORTED} +
744 $ref->{UNTESTED};
745
746 # It is possible that no test is executed at all (for instance if
747 # RUNTESTFLAGS was too restrictive). Avoid division by 0.
748 if ($ref_total > 0) {
749 $ref_ratio = ($ref->{PASS} + $ref->{XFAIL}) /
750 $ref_total;
751 }
752
753 $res_total = $res->{PASS} +
754 $res->{XFAIL} +
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000755 $res->{KFAIL} +
Christophe Lyon0ab7d352016-04-06 10:39:58 +0200756 $res->{XPASS} +
757 $res->{FAIL} +
758 $res->{UNRESOLVED} +
759 $res->{UNSUPPORTED} +
760 $res->{UNTESTED};
761
762 if ($res_total > 0) {
763 $res_ratio = ($res->{PASS} + $res->{XFAIL}) /
764 $res_total;
765 }
Christophe Lyonbff39612015-11-18 16:29:11 +0100766
767 if (not $quiet)
768 {
769 printf "Comparing:\n";
770 printf "REFERENCE:$ref_file_name\n";
771 printf "CURRENT: $res_file_name\n\n";
772 }
773
774 #### TESTS STATUS
775 if (not $quiet and not $short)
776 {
Thiago Jung Bauermann66d0ccb2023-03-01 05:15:40 +0000777 printf " +---------+---------+\n";
Christophe Lyona140aa82015-12-17 22:53:03 +0100778 printf "o RUN STATUS: | REF | RES |\n";
Christophe Lyonbff39612015-11-18 16:29:11 +0100779 printf " +------------------------------------------+---------+---------+\n";
Christophe Lyona140aa82015-12-17 22:53:03 +0100780 printf " | %-40s | %7d | %7d |\n", "Passes [PASS]", $ref->{PASS}, $res->{PASS};
Christophe Lyonbff39612015-11-18 16:29:11 +0100781 printf " | %-40s | %7d | %7d |\n", "Unexpected fails [FAIL]", $ref->{FAIL}, $res->{FAIL};
Christophe Lyonbcbd7482016-09-19 14:54:50 +0200782 printf " | %-40s | %7d | %7d |\n", "Errors [ERROR]", $ref->{ERROR}, $res->{ERROR};
Christophe Lyona140aa82015-12-17 22:53:03 +0100783 printf " | %-40s | %7d | %7d |\n", "Unexpected passes [XPASS]", $ref->{XPASS}, $res->{XPASS};
Christophe Lyonbff39612015-11-18 16:29:11 +0100784 printf " | %-40s | %7d | %7d |\n", "Expected fails [XFAIL]", $ref->{XFAIL}, $res->{XFAIL};
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000785 printf " | %-40s | %7d | %7d |\n", "Known fails [KFAIL]", $ref->{KFAIL}, $res->{KFAIL};
Christophe Lyonbff39612015-11-18 16:29:11 +0100786 printf " | %-40s | %7d | %7d |\n", "Unresolved [UNRESOLVED]", $ref->{UNRESOLVED}, $res->{UNRESOLVED};
Christophe Lyona140aa82015-12-17 22:53:03 +0100787 printf " | %-40s | %7d | %7d |\n", "Unsupported [UNSUPPORTED]", $ref->{UNSUPPORTED}, $res->{UNSUPPORTED};
788 printf " | %-40s | %7d | %7d |\n", "Untested [UNTESTED]", $ref->{UNTESTED}, $res->{UNTESTED};
Christophe Lyonbff39612015-11-18 16:29:11 +0100789 printf " +------------------------------------------+---------+---------+\n";
790 printf "\n";
Christophe Lyond618f662016-02-02 19:07:58 +0100791
Christophe Lyon3d195c22016-04-06 16:00:25 +0200792 printf " REF PASS ratio: %f\n", $ref_ratio;
793 printf " RES PASS ratio: %f\n", $res_ratio;
Christophe Lyond618f662016-02-02 19:07:58 +0100794 if ($ref_ratio < $ratio_thresh)
795 {
Christophe Lyon1176f962016-03-03 18:01:10 +0100796 printf " ***** ERROR: REF PASS ratio is abnormally low *****\n";
Christophe Lyond618f662016-02-02 19:07:58 +0100797 }
798 if ($res_ratio < $ratio_thresh)
799 {
Christophe Lyon1176f962016-03-03 18:01:10 +0100800 printf " ***** ERROR: RES PASS ratio is abnormally low *****\n";
Christophe Lyond618f662016-02-02 19:07:58 +0100801 }
802
Christophe Lyonad8c7242016-02-03 13:04:28 +0100803 # If both PASS and FAIL EXEC tests are zero, assume there is no
804 # execution test for this tool, and do not warn.
805 $ref_has_exec_tests = ($ref->{EXEC}->{PASS} + $ref->{EXEC}->{FAIL}) != 0;
806 if ($ref_has_exec_tests)
807 {
808 printf " ***** ERROR: No REF execution test PASSed. Check execution engine configuration. *****\n" if ($ref->{EXEC}->{PASS} == 0);
809 printf " ***** WARNING: No REF execution test FAILed. Check execution engine configuration. *****\n" if ($ref->{EXEC}->{FAIL} == 0);
810 }
811
812 $res_has_exec_tests = ($res->{EXEC}->{PASS} + $res->{EXEC}->{FAIL}) != 0;
813 if ($res_has_exec_tests)
814 {
815 printf " ***** ERROR: No RES execution test PASSed. Check execution engine configuration. *****\n" if ($res->{EXEC}->{PASS} == 0);
816 printf " ***** WARNING: No RES execution test FAILed. Check execution engine configuration. *****\n" if ($res->{EXEC}->{FAIL} == 0);
817 }
818
819 # Ignore number of execution tests when computing the return
820 # value, if both REF and RES have no execution test.
821 $ignore_exec = !$ref_has_exec_tests && !$res_has_exec_tests;
Christophe Lyonbff39612015-11-18 16:29:11 +0100822 }
823
824 #### REGRESSIONS ?
Christophe Lyon9dde3332016-06-28 23:00:00 +0200825 $rtotal = scalar(@{$res->{$PASS_XPASS}})
826 +scalar(@{$res->{$PASS_FAIL}})
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000827 +scalar(@{$res->{$PASS_KFAIL}})
Christophe Lyon9dde3332016-06-28 23:00:00 +0200828 +scalar(@{$res->{$PASS_UNRESOLVED}})
829 +scalar(@{$res->{$PASSED_NOW_TIMEOUTS}})
Christophe Lyon30037832018-11-30 15:33:20 +0000830 +scalar(@{$res->{$ERROR_APPEARS}})
Christophe Lyon9dde3332016-06-28 23:00:00 +0200831 +scalar(@{$res->{$XPASS_FAIL}})
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000832 +scalar(@{$res->{$XPASS_KFAIL}})
Christophe Lyona140aa82015-12-17 22:53:03 +0100833 +scalar(@{$res->{$XPASS_APPEARS}})
Christophe Lyon9dde3332016-06-28 23:00:00 +0200834 +scalar(@{$res->{$XPASS_UNRESOLVED}})
835 +scalar(@{$res->{$FAIL_APPEARS}})
836 +scalar(@{$res->{$FAIL_UNRESOLVED}})
Christophe Lyondded4d82016-06-28 18:12:38 +0200837 +scalar(@{$res->{$XFAIL_FAIL}})
Christophe Lyon9dde3332016-06-28 23:00:00 +0200838 +scalar(@{$res->{$XFAIL_UNRESOLVED}})
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000839 +scalar(@{$res->{$KFAIL_APPEARS}})
840 +scalar(@{$res->{$KFAIL_UNRESOLVED}})
Christophe Lyona140aa82015-12-17 22:53:03 +0100841 +scalar(@{$res->{$UNSUPPORTED_FAIL}})
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000842 +scalar(@{$res->{$UNSUPPORTED_KFAIL}})
Christophe Lyona140aa82015-12-17 22:53:03 +0100843 +scalar(@{$res->{$UNSUPPORTED_XPASS}})
Christophe Lyon9dde3332016-06-28 23:00:00 +0200844 +scalar(@{$res->{$UNSUPPORTED_UNRESOLVED}})
Christophe Lyona140aa82015-12-17 22:53:03 +0100845 +scalar(@{$res->{$UNTESTED_FAIL}})
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000846 +scalar(@{$res->{$UNTESTED_KFAIL}})
Christophe Lyona140aa82015-12-17 22:53:03 +0100847 +scalar(@{$res->{$UNTESTED_XPASS}})
Christophe Lyon9dde3332016-06-28 23:00:00 +0200848 +scalar(@{$res->{$UNTESTED_UNRESOLVED}})
Christophe Lyona140aa82015-12-17 22:53:03 +0100849 +scalar(@{$res->{$UNRESOLVED_FAIL}})
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000850 +scalar(@{$res->{$UNRESOLVED_KFAIL}})
Christophe Lyona140aa82015-12-17 22:53:03 +0100851 +scalar(@{$res->{$UNRESOLVED_XPASS}})
Christophe Lyon30037832018-11-30 15:33:20 +0000852 +scalar(@{$res->{$UNRESOLVED_APPEARS}});
Christophe Lyona140aa82015-12-17 22:53:03 +0100853
854 $quiet_reg=1 if ($short and not $rtotal);
Christophe Lyonbff39612015-11-18 16:29:11 +0100855
856 if (not $quiet_reg)
857 {
Christophe Lyona140aa82015-12-17 22:53:03 +0100858 printf "\n$col_red"."o REGRESSIONS:\n";
Christophe Lyonbff39612015-11-18 16:29:11 +0100859 printf " +------------------------------------------+---------+\n";
Christophe Lyondded4d82016-06-28 18:12:38 +0200860 printf " | %-40s | %7d |\n", $PASS_XPASS, scalar(@{$res->{$PASS_XPASS}}) if (scalar(@{$res->{$PASS_XPASS}}));
Christophe Lyon9dde3332016-06-28 23:00:00 +0200861 printf " | %-40s | %7d |\n", $PASS_FAIL, scalar(@{$res->{$PASS_FAIL}}) if (scalar(@{$res->{$PASS_FAIL}}));
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000862 printf " | %-40s | %7d |\n", $PASS_KFAIL, scalar(@{$res->{$PASS_KFAIL}}) if (scalar(@{$res->{$PASS_KFAIL}}));
Christophe Lyon9dde3332016-06-28 23:00:00 +0200863 printf " | %-40s | %7d |\n", $PASS_UNRESOLVED, scalar(@{$res->{$PASS_UNRESOLVED}}) if (scalar(@{$res->{$PASS_UNRESOLVED}}));
864 printf " | %-40s | %7d |\n", $PASSED_NOW_TIMEOUTS, scalar(@{$res->{$PASSED_NOW_TIMEOUTS}}) if (scalar(@{$res->{$PASSED_NOW_TIMEOUTS}}));
Christophe Lyonbcbd7482016-09-19 14:54:50 +0200865 printf " | %-40s | %7d |\n", $ERROR_APPEARS, scalar(@{$res->{$ERROR_APPEARS}}) if (scalar(@{$res->{$ERROR_APPEARS}}));
Christophe Lyon9dde3332016-06-28 23:00:00 +0200866 printf " | %-40s | %7d |\n", $XPASS_FAIL, scalar(@{$res->{$XPASS_FAIL}}) if (scalar(@{$res->{$XPASS_FAIL}}));
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000867 printf " | %-40s | %7d |\n", $XPASS_KFAIL, scalar(@{$res->{$XPASS_KFAIL}}) if (scalar(@{$res->{$XPASS_KFAIL}}));
Christophe Lyon9dde3332016-06-28 23:00:00 +0200868 printf " | %-40s | %7d |\n", $XPASS_APPEARS, scalar(@{$res->{$XPASS_APPEARS}}) if (scalar(@{$res->{$XPASS_APPEARS}}));
869 printf " | %-40s | %7d |\n", $XPASS_UNRESOLVED, scalar(@{$res->{$XPASS_UNRESOLVED}}) if (scalar(@{$res->{$XPASS_UNRESOLVED}}));
870 printf " | %-40s | %7d |\n", $FAIL_APPEARS, scalar(@{$res->{$FAIL_APPEARS}}) if (scalar(@{$res->{$FAIL_APPEARS}}));
871 printf " | %-40s | %7d |\n", $FAIL_UNRESOLVED, scalar(@{$res->{$FAIL_UNRESOLVED}}) if (scalar(@{$res->{$FAIL_UNRESOLVED}}));
Christophe Lyondded4d82016-06-28 18:12:38 +0200872 printf " | %-40s | %7d |\n", $XFAIL_FAIL, scalar(@{$res->{$XFAIL_FAIL}}) if (scalar(@{$res->{$XFAIL_FAIL}}));
Christophe Lyon9dde3332016-06-28 23:00:00 +0200873 printf " | %-40s | %7d |\n", $XFAIL_UNRESOLVED, scalar(@{$res->{$XFAIL_UNRESOLVED}}) if (scalar(@{$res->{$XFAIL_UNRESOLVED}}));
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000874 printf " | %-40s | %7d |\n", $KFAIL_APPEARS, scalar(@{$res->{$KFAIL_APPEARS}}) if (scalar(@{$res->{$KFAIL_APPEARS}}));
875 printf " | %-40s | %7d |\n", $KFAIL_UNRESOLVED, scalar(@{$res->{$KFAIL_UNRESOLVED}}) if (scalar(@{$res->{$KFAIL_UNRESOLVED}}));
Christophe Lyona140aa82015-12-17 22:53:03 +0100876 printf " | %-40s | %7d |\n", $UNSUPPORTED_FAIL, scalar(@{$res->{$UNSUPPORTED_FAIL}}) if (scalar(@{$res->{$UNSUPPORTED_FAIL}}));
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000877 printf " | %-40s | %7d |\n", $UNSUPPORTED_KFAIL, scalar(@{$res->{$UNSUPPORTED_KFAIL}}) if (scalar(@{$res->{$UNSUPPORTED_KFAIL}}));
Christophe Lyona140aa82015-12-17 22:53:03 +0100878 printf " | %-40s | %7d |\n", $UNSUPPORTED_XPASS, scalar(@{$res->{$UNSUPPORTED_XPASS}}) if (scalar(@{$res->{$UNSUPPORTED_XPASS}}));
Christophe Lyon9dde3332016-06-28 23:00:00 +0200879 printf " | %-40s | %7d |\n", $UNSUPPORTED_UNRESOLVED, scalar(@{$res->{$UNSUPPORTED_UNRESOLVED}}) if (scalar(@{$res->{$UNSUPPORTED_UNRESOLVED}}));
Christophe Lyona140aa82015-12-17 22:53:03 +0100880 printf " | %-40s | %7d |\n", $UNTESTED_FAIL, scalar(@{$res->{$UNTESTED_FAIL}}) if (scalar(@{$res->{$UNTESTED_FAIL}}));
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000881 printf " | %-40s | %7d |\n", $UNTESTED_KFAIL, scalar(@{$res->{$UNTESTED_KFAIL}}) if (scalar(@{$res->{$UNTESTED_KFAIL}}));
Christophe Lyona140aa82015-12-17 22:53:03 +0100882 printf " | %-40s | %7d |\n", $UNTESTED_XPASS, scalar(@{$res->{$UNTESTED_XPASS}}) if (scalar(@{$res->{$UNTESTED_XPASS}}));
Christophe Lyon9dde3332016-06-28 23:00:00 +0200883 printf " | %-40s | %7d |\n", $UNTESTED_UNRESOLVED, scalar(@{$res->{$UNTESTED_UNRESOLVED}}) if (scalar(@{$res->{$UNTESTED_UNRESOLVED}}));
Christophe Lyona140aa82015-12-17 22:53:03 +0100884 printf " | %-40s | %7d |\n", $UNRESOLVED_FAIL, scalar(@{$res->{$UNRESOLVED_FAIL}}) if (scalar(@{$res->{$UNRESOLVED_FAIL}}));
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000885 printf " | %-40s | %7d |\n", $UNRESOLVED_KFAIL, scalar(@{$res->{$UNRESOLVED_KFAIL}}) if (scalar(@{$res->{$UNRESOLVED_KFAIL}}));
Christophe Lyona140aa82015-12-17 22:53:03 +0100886 printf " | %-40s | %7d |\n", $UNRESOLVED_XPASS, scalar(@{$res->{$UNRESOLVED_XPASS}}) if (scalar(@{$res->{$UNRESOLVED_XPASS}}));
Christophe Lyondc66fc52016-04-05 17:38:07 +0200887 printf " | %-40s | %7d |\n", $UNRESOLVED_APPEARS, scalar(@{$res->{$UNRESOLVED_APPEARS}}) if (scalar(@{$res->{$UNRESOLVED_APPEARS}}));
Christophe Lyonbff39612015-11-18 16:29:11 +0100888 printf " +------------------------------------------+---------+\n";
889 printf " | %-40s | %7d |\n", "TOTAL_REGRESSIONS", $rtotal;
890 printf " +------------------------------------------+---------+\n";
891 printf "\n";
892
893 if ($long)
894 {
Christophe Lyon14d1ec82017-03-23 14:59:58 +0000895 print_tclist($res, $PASS_XPASS, @{$res->{$PASS_XPASS}});
896 print_tclist($res, $PASS_FAIL, @{$res->{$PASS_FAIL}});
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000897 print_tclist($res, $PASS_KFAIL, @{$res->{$PASS_KFAIL}});
Christophe Lyon14d1ec82017-03-23 14:59:58 +0000898 print_tclist($res, $PASS_UNRESOLVED, @{$res->{$PASS_UNRESOLVED}});
899 print_tclist($res, $PASSED_NOW_TIMEOUTS, @{$res->{$PASSED_NOW_TIMEOUTS}});
900 print_tclist($res, $ERROR_APPEARS, @{$res->{$ERROR_APPEARS}});
901 print_tclist($res, $XPASS_FAIL, @{$res->{$XPASS_FAIL}});
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000902 print_tclist($res, $XPASS_KFAIL, @{$res->{$XPASS_KFAIL}});
Christophe Lyon14d1ec82017-03-23 14:59:58 +0000903 print_tclist($res, $XPASS_APPEARS, @{$res->{$XPASS_APPEARS}});
904 print_tclist($res, $XPASS_UNRESOLVED, @{$res->{$XPASS_UNRESOLVED}});
905 print_tclist($res, $FAIL_APPEARS, @{$res->{$FAIL_APPEARS}});
906 print_tclist($res, $FAIL_UNRESOLVED, @{$res->{$FAIL_UNRESOLVED}});
907 print_tclist($res, $XFAIL_FAIL, @{$res->{$XFAIL_FAIL}});
Christophe Lyon14d1ec82017-03-23 14:59:58 +0000908 print_tclist($res, $XFAIL_UNRESOLVED, @{$res->{$XFAIL_UNRESOLVED}});
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000909 print_tclist($res, $KFAIL_APPEARS, @{$res->{$KFAIL_APPEARS}});
910 print_tclist($res, $KFAIL_UNRESOLVED, @{$res->{$KFAIL_UNRESOLVED}});
Christophe Lyon14d1ec82017-03-23 14:59:58 +0000911 print_tclist($res, $UNSUPPORTED_FAIL, @{$res->{$UNSUPPORTED_FAIL}});
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000912 print_tclist($res, $UNSUPPORTED_KFAIL, @{$res->{$UNSUPPORTED_KFAIL}});
Christophe Lyon14d1ec82017-03-23 14:59:58 +0000913 print_tclist($res, $UNSUPPORTED_XPASS, @{$res->{$UNSUPPORTED_XPASS}});
914 print_tclist($res, $UNSUPPORTED_UNRESOLVED, @{$res->{$UNSUPPORTED_UNRESOLVED}});
915 print_tclist($res, $UNTESTED_FAIL, @{$res->{$UNTESTED_FAIL}});
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000916 print_tclist($res, $UNTESTED_KFAIL, @{$res->{$UNTESTED_KFAIL}});
Christophe Lyon14d1ec82017-03-23 14:59:58 +0000917 print_tclist($res, $UNTESTED_XPASS, @{$res->{$UNTESTED_XPASS}});
918 print_tclist($res, $UNTESTED_UNRESOLVED, @{$res->{$UNTESTED_UNRESOLVED}});
919 print_tclist($res, $UNRESOLVED_FAIL, @{$res->{$UNRESOLVED_FAIL}});
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000920 print_tclist($res, $UNRESOLVED_KFAIL, @{$res->{$UNRESOLVED_KFAIL}});
Christophe Lyon14d1ec82017-03-23 14:59:58 +0000921 print_tclist($res, $UNRESOLVED_XPASS, @{$res->{$UNRESOLVED_XPASS}});
922 print_tclist($res, $UNRESOLVED_APPEARS, @{$res->{$UNRESOLVED_APPEARS}});
Christophe Lyonbff39612015-11-18 16:29:11 +0100923 }
924 printf "$col_reset\n";
925 }
926
Christophe Lyon924cce42018-11-30 15:38:19 +0000927 #### IMPROVEMENTS TO BE CHECKED ?
Christophe Lyonbff39612015-11-18 16:29:11 +0100928 if (not $quiet and not $short)
929 {
Christophe Lyon9dde3332016-06-28 23:00:00 +0200930 $total_better =
Christophe Lyon31279df2016-07-04 17:02:12 +0200931 scalar(@{$res->{$PASS_DISAPPEARS}})+
Christophe Lyon9dde3332016-06-28 23:00:00 +0200932 scalar(@{$res->{$PASS_XFAIL}})+
933 scalar(@{$res->{$PASS_APPEARS}})+
934 scalar(@{$res->{$PASS_UNSUPPORTED}})+
935 scalar(@{$res->{$PASS_UNTESTED}})+
936 scalar(@{$res->{$XPASS_PASS}})+
937 scalar(@{$res->{$XPASS_XFAIL}})+
938 scalar(@{$res->{$XPASS_UNSUPPORTED}})+
939 scalar(@{$res->{$XPASS_UNTESTED}})+
940 scalar(@{$res->{$XPASS_DISAPPEARS}})+
Christophe Lyondded4d82016-06-28 18:12:38 +0200941 scalar(@{$res->{$FAIL_PASS}})+
942 scalar(@{$res->{$FAIL_XPASS}})+
Christophe Lyondded4d82016-06-28 18:12:38 +0200943 scalar(@{$res->{$FAIL_XFAIL}})+
Christophe Lyon9dde3332016-06-28 23:00:00 +0200944 scalar(@{$res->{$FAIL_UNSUPPORTED}})+
945 scalar(@{$res->{$FAIL_UNTESTED}})+
946 scalar(@{$res->{$FAIL_DISAPPEARS}})+
Christophe Lyon3b675e82018-11-30 15:24:32 +0000947 scalar(@{$res->{$XFAIL_DISAPPEARS}})+
Christophe Lyon9dde3332016-06-28 23:00:00 +0200948 scalar(@{$res->{$XFAIL_PASS}})+
949 scalar(@{$res->{$XFAIL_XPASS}})+
950 scalar(@{$res->{$XFAIL_UNSUPPORTED}})+
951 scalar(@{$res->{$XFAIL_UNTESTED}})+
952 scalar(@{$res->{$XFAIL_APPEARS}})+
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +0000953 scalar(@{$res->{$KFAIL_PASS}})+
954 scalar(@{$res->{$KFAIL_XPASS}})+
955 scalar(@{$res->{$KFAIL_XFAIL}})+
956 scalar(@{$res->{$KFAIL_UNSUPPORTED}})+
957 scalar(@{$res->{$KFAIL_UNTESTED}})+
958 scalar(@{$res->{$KFAIL_DISAPPEARS}})+
Christophe Lyona140aa82015-12-17 22:53:03 +0100959 scalar(@{$res->{$UNSUPPORTED_PASS}})+
960 scalar(@{$res->{$UNSUPPORTED_XFAIL}})+
Christophe Lyon9dde3332016-06-28 23:00:00 +0200961 scalar(@{$res->{$UNSUPPORTED_UNTESTED}})+
Christophe Lyona140aa82015-12-17 22:53:03 +0100962 scalar(@{$res->{$UNSUPPORTED_DISAPPEARS}})+
Christophe Lyondc66fc52016-04-05 17:38:07 +0200963 scalar(@{$res->{$UNSUPPORTED_APPEARS}})+
Christophe Lyona140aa82015-12-17 22:53:03 +0100964 scalar(@{$res->{$UNTESTED_PASS}})+
965 scalar(@{$res->{$UNTESTED_XFAIL}})+
Christophe Lyon9dde3332016-06-28 23:00:00 +0200966 scalar(@{$res->{$UNTESTED_UNSUPPORTED}})+
Christophe Lyona140aa82015-12-17 22:53:03 +0100967 scalar(@{$res->{$UNTESTED_DISAPPEARS}})+
Christophe Lyondc66fc52016-04-05 17:38:07 +0200968 scalar(@{$res->{$UNTESTED_APPEARS}})+
Christophe Lyona140aa82015-12-17 22:53:03 +0100969 scalar(@{$res->{$UNRESOLVED_PASS}})+
970 scalar(@{$res->{$UNRESOLVED_XFAIL}})+
Christophe Lyon9dde3332016-06-28 23:00:00 +0200971 scalar(@{$res->{$UNRESOLVED_UNSUPPORTED}})+
972 scalar(@{$res->{$UNRESOLVED_UNTESTED}})+
Christophe Lyona140aa82015-12-17 22:53:03 +0100973 scalar(@{$res->{$UNRESOLVED_DISAPPEARS}})+
Christophe Lyonbcbd7482016-09-19 14:54:50 +0200974 scalar(@{$res->{$ERROR_DISAPPEARS}})+
Christophe Lyonf5aeb342015-12-08 14:47:16 +0100975 scalar(@{$res->{$UNHANDLED_CASES}});
Christophe Lyonbff39612015-11-18 16:29:11 +0100976
Christophe Lyon924cce42018-11-30 15:38:19 +0000977 printf "$col_pink"."o IMPROVEMENTS TO BE CHECKED:\n";
Christophe Lyonbff39612015-11-18 16:29:11 +0100978 printf " +------------------------------------------+---------+\n";
Christophe Lyon31279df2016-07-04 17:02:12 +0200979 printf " | %-40s | %7d |\n", $PASS_DISAPPEARS, scalar(@{$res->{$PASS_DISAPPEARS}}) if (scalar(@{$res->{$PASS_DISAPPEARS}}));
Christophe Lyondded4d82016-06-28 18:12:38 +0200980 printf " | %-40s | %7d |\n", $PASS_XFAIL, scalar(@{$res->{$PASS_XFAIL}}) if (scalar(@{$res->{$PASS_XFAIL}}));
Christophe Lyon9dde3332016-06-28 23:00:00 +0200981 printf " | %-40s | %7d |\n", $PASS_APPEARS, scalar(@{$res->{$PASS_APPEARS}}) if (scalar(@{$res->{$PASS_APPEARS}}));
982 printf " | %-40s | %7d |\n", $PASS_UNSUPPORTED, scalar(@{$res->{$PASS_UNSUPPORTED}}) if (scalar(@{$res->{$PASS_UNSUPPORTED}}));
983 printf " | %-40s | %7d |\n", $PASS_UNTESTED, scalar(@{$res->{$PASS_UNTESTED}}) if (scalar(@{$res->{$PASS_UNTESTED}}));
Christophe Lyondded4d82016-06-28 18:12:38 +0200984 printf " | %-40s | %7d |\n", $XPASS_PASS, scalar(@{$res->{$XPASS_PASS}}) if (scalar(@{$res->{$XPASS_PASS}}));
Christophe Lyon9dde3332016-06-28 23:00:00 +0200985 printf " | %-40s | %7d |\n", $XPASS_XFAIL, scalar(@{$res->{$XPASS_XFAIL}}) if (scalar(@{$res->{$XPASS_XFAIL}}));
986 printf " | %-40s | %7d |\n", $XPASS_UNSUPPORTED, scalar(@{$res->{$XPASS_UNSUPPORTED}}) if (scalar(@{$res->{$XPASS_UNSUPPORTED}}));
987 printf " | %-40s | %7d |\n", $XPASS_UNTESTED, scalar(@{$res->{$XPASS_UNTESTED}}) if (scalar(@{$res->{$XPASS_UNTESTED}}));
988 printf " | %-40s | %7d |\n", $XPASS_DISAPPEARS, scalar(@{$res->{$XPASS_DISAPPEARS}}) if (scalar(@{$res->{$XPASS_DISAPPEARS}}));
Christophe Lyondded4d82016-06-28 18:12:38 +0200989 printf " | %-40s | %7d |\n", $FAIL_PASS, scalar(@{$res->{$FAIL_PASS}}) if (scalar(@{$res->{$FAIL_PASS}}));
990 printf " | %-40s | %7d |\n", $FAIL_XPASS, scalar(@{$res->{$FAIL_XPASS}}) if (scalar(@{$res->{$FAIL_XPASS}}));
Christophe Lyon9dde3332016-06-28 23:00:00 +0200991 printf " | %-40s | %7d |\n", $FAIL_XFAIL, scalar(@{$res->{$FAIL_XFAIL}}) if (scalar(@{$res->{$FAIL_XFAIL}}));
992 printf " | %-40s | %7d |\n", $FAIL_UNSUPPORTED, scalar(@{$res->{$FAIL_UNSUPPORTED}}) if (scalar(@{$res->{$FAIL_UNSUPPORTED}}));
993 printf " | %-40s | %7d |\n", $FAIL_UNTESTED, scalar(@{$res->{$FAIL_UNTESTED}}) if (scalar(@{$res->{$FAIL_UNTESTED}}));
994 printf " | %-40s | %7d |\n", $FAIL_DISAPPEARS, scalar(@{$res->{$FAIL_DISAPPEARS}}) if (scalar(@{$res->{$FAIL_DISAPPEARS}}));
Christophe Lyon3b675e82018-11-30 15:24:32 +0000995 printf " | %-40s | %7d |\n", $XFAIL_DISAPPEARS, scalar(@{$res->{$XFAIL_DISAPPEARS}}) if (scalar(@{$res->{$XFAIL_DISAPPEARS}}));
Christophe Lyon9dde3332016-06-28 23:00:00 +0200996 printf " | %-40s | %7d |\n", $XFAIL_PASS, scalar(@{$res->{$XFAIL_PASS}}) if (scalar(@{$res->{$XFAIL_PASS}}));
997 printf " | %-40s | %7d |\n", $XFAIL_XPASS, scalar(@{$res->{$XFAIL_XPASS}}) if (scalar(@{$res->{$XFAIL_XPASS}}));
998 printf " | %-40s | %7d |\n", $XFAIL_UNSUPPORTED, scalar(@{$res->{$XFAIL_UNSUPPORTED}}) if (scalar(@{$res->{$XFAIL_UNSUPPORTED}}));
999 printf " | %-40s | %7d |\n", $XFAIL_UNTESTED, scalar(@{$res->{$XFAIL_UNTESTED}}) if (scalar(@{$res->{$XFAIL_UNTESTED}}));
1000 printf " | %-40s | %7d |\n", $XFAIL_APPEARS, scalar(@{$res->{$XFAIL_APPEARS}}) if (scalar(@{$res->{$XFAIL_APPEARS}}));
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +00001001 printf " | %-40s | %7d |\n", $KFAIL_PASS, scalar(@{$res->{$KFAIL_PASS}}) if (scalar(@{$res->{$KFAIL_PASS}}));
1002 printf " | %-40s | %7d |\n", $KFAIL_XPASS, scalar(@{$res->{$KFAIL_XPASS}}) if (scalar(@{$res->{$KFAIL_XPASS}}));
1003 printf " | %-40s | %7d |\n", $KFAIL_XFAIL, scalar(@{$res->{$KFAIL_XFAIL}}) if (scalar(@{$res->{$KFAIL_XFAIL}}));
1004 printf " | %-40s | %7d |\n", $KFAIL_UNSUPPORTED, scalar(@{$res->{$KFAIL_UNSUPPORTED}}) if (scalar(@{$res->{$KFAIL_UNSUPPORTED}}));
1005 printf " | %-40s | %7d |\n", $KFAIL_UNTESTED, scalar(@{$res->{$KFAIL_UNTESTED}}) if (scalar(@{$res->{$KFAIL_UNTESTED}}));
1006 printf " | %-40s | %7d |\n", $KFAIL_DISAPPEARS, scalar(@{$res->{$KFAIL_DISAPPEARS}}) if (scalar(@{$res->{$KFAIL_DISAPPEARS}}));
Christophe Lyona140aa82015-12-17 22:53:03 +01001007 printf " | %-40s | %7d |\n", $UNSUPPORTED_PASS, scalar(@{$res->{$UNSUPPORTED_PASS}}) if (scalar(@{$res->{$UNSUPPORTED_PASS}}));
1008 printf " | %-40s | %7d |\n", $UNSUPPORTED_XFAIL, scalar(@{$res->{$UNSUPPORTED_XFAIL}}) if (scalar(@{$res->{$UNSUPPORTED_XFAIL}}));
Christophe Lyon9dde3332016-06-28 23:00:00 +02001009 printf " | %-40s | %7d |\n", $UNSUPPORTED_UNTESTED, scalar(@{$res->{$UNSUPPORTED_UNTESTED}}) if (scalar(@{$res->{$UNSUPPORTED_UNTESTED}}));
Christophe Lyona140aa82015-12-17 22:53:03 +01001010 printf " | %-40s | %7d |\n", $UNSUPPORTED_DISAPPEARS, scalar(@{$res->{$UNSUPPORTED_DISAPPEARS}}) if (scalar(@{$res->{$UNSUPPORTED_DISAPPEARS}}));
Christophe Lyondc66fc52016-04-05 17:38:07 +02001011 printf " | %-40s | %7d |\n", $UNSUPPORTED_APPEARS, scalar(@{$res->{$UNSUPPORTED_APPEARS}}) if (scalar(@{$res->{$UNSUPPORTED_APPEARS}}));
Christophe Lyona140aa82015-12-17 22:53:03 +01001012 printf " | %-40s | %7d |\n", $UNTESTED_PASS, scalar(@{$res->{$UNTESTED_PASS}}) if (scalar(@{$res->{$UNTESTED_PASS}}));
1013 printf " | %-40s | %7d |\n", $UNTESTED_XFAIL, scalar(@{$res->{$UNTESTED_XFAIL}}) if (scalar(@{$res->{$UNTESTED_XFAIL}}));
Christophe Lyon9dde3332016-06-28 23:00:00 +02001014 printf " | %-40s | %7d |\n", $UNTESTED_UNSUPPORTED, scalar(@{$res->{$UNTESTED_UNSUPPORTED}}) if (scalar(@{$res->{$UNTESTED_UNSUPPORTED}}));
Christophe Lyona140aa82015-12-17 22:53:03 +01001015 printf " | %-40s | %7d |\n", $UNTESTED_DISAPPEARS, scalar(@{$res->{$UNTESTED_DISAPPEARS}}) if (scalar(@{$res->{$UNTESTED_DISAPPEARS}}));
Christophe Lyondc66fc52016-04-05 17:38:07 +02001016 printf " | %-40s | %7d |\n", $UNTESTED_APPEARS, scalar(@{$res->{$UNTESTED_APPEARS}}) if (scalar(@{$res->{$UNTESTED_APPEARS}}));
Christophe Lyona140aa82015-12-17 22:53:03 +01001017 printf " | %-40s | %7d |\n", $UNRESOLVED_PASS, scalar(@{$res->{$UNRESOLVED_PASS}}) if (scalar(@{$res->{$UNRESOLVED_PASS}}));
1018 printf " | %-40s | %7d |\n", $UNRESOLVED_XFAIL, scalar(@{$res->{$UNRESOLVED_XFAIL}}) if (scalar(@{$res->{$UNRESOLVED_XFAIL}}));
Christophe Lyon9dde3332016-06-28 23:00:00 +02001019 printf " | %-40s | %7d |\n", $UNRESOLVED_UNSUPPORTED, scalar(@{$res->{$UNRESOLVED_UNSUPPORTED}}) if (scalar(@{$res->{$UNRESOLVED_UNSUPPORTED}}));
1020 printf " | %-40s | %7d |\n", $UNRESOLVED_UNTESTED, scalar(@{$res->{$UNRESOLVED_UNTESTED}}) if (scalar(@{$res->{$UNRESOLVED_UNTESTED}}));
Christophe Lyona140aa82015-12-17 22:53:03 +01001021 printf " | %-40s | %7d |\n", $UNRESOLVED_DISAPPEARS, scalar(@{$res->{$UNRESOLVED_DISAPPEARS}}) if (scalar(@{$res->{$UNRESOLVED_DISAPPEARS}}));
Christophe Lyonbcbd7482016-09-19 14:54:50 +02001022 printf " | %-40s | %7d |\n", $ERROR_DISAPPEARS, scalar(@{$res->{$ERROR_DISAPPEARS}}) if (scalar(@{$res->{$ERROR_DISAPPEARS}}));
Christophe Lyonbff39612015-11-18 16:29:11 +01001023 printf " | %-40s | %7d |\n", $UNHANDLED_CASES, scalar(@{$res->{$UNHANDLED_CASES}}) if (scalar(@{$res->{$UNHANDLED_CASES}}));
1024 printf " | %-40s | %7d |\n", $UNSTABLE_CASES, scalar(@{$res->{$UNSTABLE_CASES}}) if (scalar(@{$res->{$UNSTABLE_CASES}}));
Christophe Lyon73ac1d82018-06-12 13:32:47 +00001025 printf " | %-40s | %7d |\n", $HWDEP_CASES, scalar(@{$res->{$HWDEP_CASES}}) if (scalar(@{$res->{$HWDEP_CASES}}));
Christophe Lyonbff39612015-11-18 16:29:11 +01001026 printf " +------------------------------------------+---------+\n";
Christophe Lyon924cce42018-11-30 15:38:19 +00001027 printf " | %-40s | %7d |\n", "TOTAL_IMPROVEMENTS_TO_BE_CHECKED", $total_better + scalar(@{$res->{$UNSTABLE_CASES}});;
Christophe Lyonbff39612015-11-18 16:29:11 +01001028 printf " +------------------------------------------+---------+\n";
1029 printf "\n";
1030
1031 if ($long)
1032 {
Christophe Lyon28a92782017-09-13 09:00:39 +00001033 print_tclist($res, $PASS_DISAPPEARS, @{$res->{$PASS_DISAPPEARS}});
Christophe Lyon14d1ec82017-03-23 14:59:58 +00001034 print_tclist($res, $PASS_XFAIL, @{$res->{$PASS_XFAIL}});
1035 print_tclist($res, $PASS_APPEARS, @{$res->{$PASS_APPEARS}});
1036 print_tclist($res, $PASS_UNSUPPORTED, @{$res->{$PASS_UNSUPPORTED}});
1037 print_tclist($res, $PASS_UNTESTED, @{$res->{$PASS_UNTESTED}});
1038 print_tclist($res, $XPASS_PASS, @{$res->{$XPASS_PASS}});
1039 print_tclist($res, $XPASS_XFAIL, @{$res->{$XPASS_XFAIL}});
1040 print_tclist($res, $XPASS_UNSUPPORTED, @{$res->{$XPASS_UNSUPPORTED}});
1041 print_tclist($res, $XPASS_UNTESTED, @{$res->{$XPASS_UNTESTED}});
Christophe Lyon28a92782017-09-13 09:00:39 +00001042 print_tclist($res, $XPASS_DISAPPEARS, @{$res->{$XPASS_DISAPPEARS}});
Christophe Lyon14d1ec82017-03-23 14:59:58 +00001043 print_tclist($res, $FAIL_PASS, @{$res->{$FAIL_PASS}});
1044 print_tclist($res, $FAIL_XPASS, @{$res->{$FAIL_XPASS}});
1045 print_tclist($res, $FAIL_XFAIL, @{$res->{$FAIL_XFAIL}});
1046 print_tclist($res, $FAIL_UNSUPPORTED, @{$res->{$FAIL_UNSUPPORTED}});
1047 print_tclist($res, $FAIL_UNTESTED, @{$res->{$FAIL_UNTESTED}});
Christophe Lyon28a92782017-09-13 09:00:39 +00001048 print_tclist($res, $FAIL_DISAPPEARS, @{$res->{$FAIL_DISAPPEARS}});
Christophe Lyon3b675e82018-11-30 15:24:32 +00001049 print_tclist($res, $XFAIL_DISAPPEARS, @{$res->{$XFAIL_DISAPPEARS}});
Christophe Lyon14d1ec82017-03-23 14:59:58 +00001050 print_tclist($res, $XFAIL_PASS, @{$res->{$XFAIL_PASS}});
1051 print_tclist($res, $XFAIL_XPASS, @{$res->{$XFAIL_XPASS}});
1052 print_tclist($res, $XFAIL_UNSUPPORTED, @{$res->{$XFAIL_UNSUPPORTED}});
1053 print_tclist($res, $XFAIL_UNTESTED, @{$res->{$XFAIL_UNTESTED}});
1054 print_tclist($res, $XFAIL_APPEARS, @{$res->{$XFAIL_APPEARS}});
Thiago Jung Bauermann3be267a2023-02-28 23:30:09 +00001055 print_tclist($res, $KFAIL_PASS, @{$res->{$KFAIL_PASS}});
1056 print_tclist($res, $KFAIL_XPASS, @{$res->{$KFAIL_XPASS}});
1057 print_tclist($res, $KFAIL_XFAIL, @{$res->{$KFAIL_XFAIL}});
1058 print_tclist($res, $KFAIL_UNSUPPORTED, @{$res->{$KFAIL_UNSUPPORTED}});
1059 print_tclist($res, $KFAIL_UNTESTED, @{$res->{$KFAIL_UNTESTED}});
1060 print_tclist($res, $KFAIL_DISAPPEARS, @{$res->{$KFAIL_DISAPPEARS}});
Christophe Lyon14d1ec82017-03-23 14:59:58 +00001061 print_tclist($res, $UNSUPPORTED_PASS, @{$res->{$UNSUPPORTED_PASS}});
1062 print_tclist($res, $UNSUPPORTED_XFAIL, @{$res->{$UNSUPPORTED_XFAIL}});
1063 print_tclist($res, $UNSUPPORTED_UNTESTED, @{$res->{$UNSUPPORTED_UNTESTED}});
Christophe Lyon28a92782017-09-13 09:00:39 +00001064 print_tclist($res, $UNSUPPORTED_DISAPPEARS, @{$res->{$UNSUPPORTED_DISAPPEARS}});
Christophe Lyon14d1ec82017-03-23 14:59:58 +00001065 print_tclist($res, $UNSUPPORTED_APPEARS, @{$res->{$UNSUPPORTED_APPEARS}});
1066 print_tclist($res, $UNTESTED_PASS, @{$res->{$UNTESTED_PASS}});
1067 print_tclist($res, $UNTESTED_XFAIL, @{$res->{$UNTESTED_XFAIL}});
1068 print_tclist($res, $UNTESTED_UNSUPPORTED, @{$res->{$UNTESTED_UNSUPPORTED}});
Christophe Lyon28a92782017-09-13 09:00:39 +00001069 print_tclist($res, $UNTESTED_DISAPPEARS, @{$res->{$UNTESTED_DISAPPEARS}});
Christophe Lyon14d1ec82017-03-23 14:59:58 +00001070 print_tclist($res, $UNTESTED_APPEARS, @{$res->{$UNTESTED_APPEARS}});
1071 print_tclist($res, $UNRESOLVED_PASS, @{$res->{$UNRESOLVED_PASS}});
1072 print_tclist($res, $UNRESOLVED_XFAIL, @{$res->{$UNRESOLVED_XFAIL}});
1073 print_tclist($res, $UNRESOLVED_UNSUPPORTED, @{$res->{$UNRESOLVED_UNSUPPORTED}});
1074 print_tclist($res, $UNRESOLVED_UNTESTED, @{$res->{$UNRESOLVED_UNTESTED}});
Christophe Lyon28a92782017-09-13 09:00:39 +00001075 print_tclist($res, $UNRESOLVED_DISAPPEARS, @{$res->{$UNRESOLVED_DISAPPEARS}});
1076 print_tclist($res, $ERROR_DISAPPEARS, @{$res->{$ERROR_DISAPPEARS}});
Christophe Lyon14d1ec82017-03-23 14:59:58 +00001077 print_tclist($res, $UNHANDLED_CASES, @{$res->{$UNHANDLED_CASES}});
1078 print_tclist($res, $UNSTABLE_CASES, @{$res->{$UNSTABLE_CASES}});
Christophe Lyon73ac1d82018-06-12 13:32:47 +00001079 print_tclist($res, $HWDEP_CASES, @{$res->{$HWDEP_CASES}});
Christophe Lyonbff39612015-11-18 16:29:11 +01001080 }
1081 printf "$col_reset\n";
1082 }
1083
Christophe Lyonf5aeb342015-12-08 14:47:16 +01001084 $return_value = 1 if ($total_better);
Christophe Lyonbff39612015-11-18 16:29:11 +01001085
1086 $return_value = 2 if ($rtotal);
1087
Christophe Lyond618f662016-02-02 19:07:58 +01001088 # Error if there was no PASS (eg when sth went wrong and no .sum was generated)
1089 $return_value = 2 if (($res->{PASS} + $res->{XFAIL}) == 0);
1090
1091 # Error if every test passed, or the ratio was too low. This
1092 # generally means the simulator is not configured well.
1093 $return_value = 2 if (($ref_ratio == 100) || ($ref_ratio < $ratio_thresh));
1094 $return_value = 2 if (($res_ratio == 100) || ($res_ratio < $ratio_thresh));
Christophe Lyonbff39612015-11-18 16:29:11 +01001095
Christophe Lyonad8c7242016-02-03 13:04:28 +01001096 # Error if no execution test passed.
1097 # It is possible that no execution test fails, though.
1098 $return_value = 2 if (($ignore_exec == 0)
1099 && (($ref->{EXEC}->{PASS} == 0)
1100 || ($res->{EXEC}->{PASS} == 0)));
1101
Christophe Lyonbff39612015-11-18 16:29:11 +01001102 return $return_value;
1103}
Thiago Jung Bauermann99efda82023-02-28 23:03:05 +00001104
1105######################################################
1106# MERGING
1107sub merge($$@)
1108{
1109 my ($output_file, $ref_file, @results) = @_;
1110 my $res = empty_result();
1111 my $current_tool="";
1112 my $current_exp="";
1113
1114 open(REF, '<', $ref_file) or die $!;
1115 open(OUTPUT, '>', $output_file) or die $!;
1116
1117 print OUTPUT "Note: This is a synthetic sum file generated by merging the sum files of\n";
1118 print OUTPUT " several testsuite runs. To investigate test results, refer to the\n";
1119 print OUTPUT " original sum and log files.\n\n";
1120
1121 while (<REF>) {
1122 my $printed = 0;
1123 if (m/^(PASS|XPASS|FAIL|XFAIL|KFAIL|UNSUPPORTED|UNTESTED|UNRESOLVED): *(.*)/) {
1124 my ($diag,$tc) = ($1,$2);
1125 # Prefix test name wih .exp filename to help report
1126 # regressions/run bisect.
1127 $tc = "$current_tool:$current_exp=$tc";
1128
1129 if ($diag ne "PASS") {
1130 my $xfail_seen = 0;
Thiago Jung Bauermann4578bcf2023-03-22 15:44:00 +00001131 my $test_in_all_results = 1;
Thiago Jung Bauermann99efda82023-02-28 23:03:05 +00001132
1133 # Did this test pass or xfail in any of the other results?
1134 foreach my $result (@results) {
Thiago Jung Bauermann4578bcf2023-03-22 15:44:00 +00001135 if (not exists $result->{testcases}->{$tc}) {
1136 # Check whether the exp file is present in this result.
Thiago Jung Bauermann9cbfa082024-02-24 21:31:48 -03001137 if (exists $result->{exp_files}->{"$current_tool:$current_exp"}) {
1138 # The exp file is present but this test isn't.
1139 $test_in_all_results = 0;
Thiago Jung Bauermann4578bcf2023-03-22 15:44:00 +00001140 }
1141 } elsif ($result->{testcases}->{$tc}->{PASS}) {
Thiago Jung Bauermann99efda82023-02-28 23:03:05 +00001142 print OUTPUT "PASS: $2\n";
1143 $printed = 1;
1144
1145 # Adjust the summary statistics.
1146 $res->{$diag}--;
1147 $res->{PASS}++;
1148 last;
1149 } elsif ($result->{testcases}->{$tc}->{XFAIL}) {
1150 $xfail_seen = 1;
1151 }
1152 }
1153
1154 if (not $printed and $xfail_seen) {
1155 print OUTPUT "XFAIL: $2\n";
1156 $printed = 1;
1157
1158 # Adjust the summary statistics.
1159 $res->{$diag}--;
1160 $res->{XFAIL}++;
Thiago Jung Bauermann4578bcf2023-03-22 15:44:00 +00001161 } elsif (not $test_in_all_results) {
1162 # If this test isn't present in all the sum files then consider its
1163 # absence from at least one of them to mean that it didn't fail, and
1164 # therefore leave it out of the merged sum file. This addresses a
1165 # situation that can happen in GDB tests where if a test succeeds it
1166 # doesn't produce a PASS but if it fails it produces a FAIL.
1167 $printed = 1;
1168
1169 # Adjust the summary statistics.
1170 $res->{$diag}--;
Thiago Jung Bauermann99efda82023-02-28 23:03:05 +00001171 }
1172 }
1173 } elsif (m/^(# of expected passes|# of unexpected failures|# of expected failures|# of known failures|# of unsupported tests|# of untested testcases|# of unresolved testcases)(\s+)(\d+)$/) {
1174 my $total;
1175 my $adjustment = 0;
1176
1177 $adjustment = $res->{PASS} if ($1 eq "# of expected passes");
1178 $adjustment = $res->{FAIL} if ($1 eq "# of unexpected failures");
1179 $adjustment = $res->{XFAIL} if ($1 eq "# of expected failures");
1180 $adjustment = $res->{KFAIL} if ($1 eq "# of known failures");
1181 $adjustment = $res->{UNSUPPORTED} if ($1 eq "# of unsupported tests");
1182 $adjustment = $res->{UNTESTED} if ($1 eq "# of untested testcases");
1183 $adjustment = $res->{UNRESOLVED} if ($1 eq "# of unresolved testcases");
1184
1185 $total = $3 + $adjustment;
1186 print OUTPUT "$1$2$total\n";
1187 $printed = 1;
1188 } elsif (m/^Running (.*) \.\.\.*/) {
1189 $current_exp=$1;
1190 $current_exp =~ s|.*/testsuite/||;
1191 } elsif (m/^\t\t=== (.*) tests ===/) {
1192 $current_tool=$1;
1193 } elsif (m/^\t\t=== (.*) Summary ===/) {
1194 $current_tool="";
1195 $current_exp="";
1196 } elsif (m/^Note: This is a synthetic sum file.*/) {
1197 # If the reference file is itself a synthetic sum file, we should skip the
1198 # note at the top because we already printed it.
1199
1200 # Skip next 3 lines.
1201 foreach my $i (0..2) {
1202 my $skipped_line = <REF>;
1203 }
1204
1205 $printed = 1;
1206 }
1207
1208 # Pass-through lines that weren't modified.
1209 print OUTPUT $_ if (not $printed);
1210 }
1211 close(REF);
1212 close(OUTPUT);
1213
1214 return 0;
1215}