2 # SPDX-License-Identifier: GPL-2.0
4 # Copyright 2020, 2022 Sony Corporation
8 # This program is meant to be an aid to reading the verbose output of
9 # on the console log that results from executing the Linux kernel
10 # devicetree unittest (drivers/of/unitest.c).
20 # strip off everything before final "/"
21 (undef, $script_name) = split(/^.*\//, $0);
23 # following /usr/include/sysexits.h
28 #______________________________________________________________________________
30 my ($expect, $got) = @_;
38 ($expect_next, $type) = split(/<</, $expect);
39 ($type) = split(/>>/, $type);
40 $expect =~ s/^.*?>>//; # '?' is non-greedy, minimal match
42 # literal, ignore all metacharacters when used in a regex
43 $expect_next_lit = quotemeta($expect_next);
46 $got_next =~ s/^($expect_next_lit).*/\1/;
47 $got =~ s/^$expect_next_lit//;
49 if ($expect_next ne $got_next) {
54 if ($got =~ /^[+-]*[0-9]+/) {
55 $got =~ s/^[+-]*[0-9]+//;
59 } elsif ($type eq "hex") {
60 if ($got =~ /^(0x)*[0-9a-f]+/) {
61 $got =~ s/^(0x)*[0-9a-f]+//;
65 } elsif ($type eq "") {
66 if ($expect_next ne $got_next) {
73 print "** ERROR: special pattern not recognized: <<$type>>, CONSOLE_LOG line: $.\n";
81 print "** ERROR: $script_name internal error, at end of compare(), CONSOLE_LOG line: $.\n";
87 #______________________________________________________________________________
90 # ***** when editing, be careful to not put tabs in the string printed:
96 $script_name CONSOLE_LOG
98 -h print program usage
99 --help print program usage
100 --hide-expect suppress output of EXPECTed lines
101 --line-num report line number of CONSOLE_LOG
102 --no-expect-stats do not report EXPECT statistics
103 --no-strip-ts do not strip leading console timestamps
104 --verbose do not suppress EXPECT begin and end lines
105 --version print program version and exit
108 Process a console log for EXPECTed test related messages to either
109 highlight expected devicetree unittest related messages or suppress
110 the messages. Leading console timestamps will be stripped.
112 Various unittests may trigger kernel messages from outside the
113 unittest code. The unittest annotates that it expects the message
114 to occur with an 'EXPECT \\ : text' (begin) before triggering the
115 message, and an 'EXPECT / : text' (end) after triggering the message.
117 If an expected message does not occur, that will be reported.
119 For each expected message, the 'EXPECT \\ : text' (begin) and
120 'EXPECT / : text' (end), 'text' will contain the message text.
122 If 'EXPECT \\' (begin) and 'EXPECT /' (end) lines do not contain
123 matching 'text', that will be reported.
125 If EXPECT lines are nested, 'EXPECT /' (end) lines must be in the
126 reverse order of the corresponding 'EXPECT \\' (begin) lines.
128 'EXPECT \\ : text' (begin) and 'EXPECT / : text' (end) lines can
129 contain special patterns in 'text':
131 <<int>> matches: [+-]*[0-9]+
132 <<hex>> matches: (0x)*[0-9a-f]+
134 'EXPECT \\' (begin) and 'EXPECT /' (end) lines are suppressed.
136 A prefix is added to every line of output:
138 'ok ' Line matches an enclosing EXPECT begin/end pair
140 '** ' Line reports $script_name warning or error
142 '-> ' Line reports start or end of the unittests
144 '>> ' Line reports a unittest test FAIL
146 ' ' Lines that are not otherwise prefixed
148 Issues detected in CONSOLE_LOG are reported to STDOUT, not to STDERR.
152 --line-num causes the CONSOLE_LOG line number to be printed in 4 columns.
153 If CONSOLE_LOG contains more than 9999 lines then more columns will be
154 used to report the line number for lines greater than 9999 (eg for
155 lines 10000 - 99999, 5 columns will be used).
161 #______________________________________________________________________________
162 #______________________________________________________________________________
167 "hide-expect" => \$hide_expect,
168 "line-num" => \$print_line_num,
169 "no-expect-stats" => \$no_expect_stats,
170 "no-strip-ts" => \$no_strip_ts,
171 "verbose" => \$verbose,
172 "version" => \$version,
175 print STDERR "ERROR processing command line options\n";
177 print STDERR "For help, type '$script_name --help'\n";
193 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
202 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
205 print STDERR "\n$script_name $VUFX\n\n";
212 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
215 # Limit input files to exactly one.
217 # 'while ($line = <ARGV>) {' in the code below supports multiple file
218 # names on the command line, but the EXPECT statistics are reported
219 # once for all input - it is not an expected use case to generate one
220 # set of statistics for multiple input files.
223 print STDERR "Required arguments: CONSOLE_LOG\n";
230 #______________________________________________________________________________
232 # Patterns to match 'EXPECT \ : ' (begin) and 'EXPECT / : ' (end)
234 # $exp_* are used as regex match patterns,
235 # so '\\\\' in $exp_begin matches a single '\'
236 # quotemeta() does not do the right thing in this case
238 # $pr_fmt is the prefix that unittest prints for every message
240 $pr_fmt = "### dt-test ### ";
241 $exp_begin = "${pr_fmt}EXPECT \\\\ : ";
242 $exp_end = "${pr_fmt}EXPECT / : ";
249 while ($line = <ARGV>) {
253 $prefix = " "; ## 2 characters
260 if ($timestamp =~ /^\[\s*[0-9]+\.[0-9]*\] /) {
261 ($timestamp, $null) = split(/]/, $line);
262 $timestamp = $timestamp . "] ";
269 $line =~ s/^\[\s*[0-9]+\.[0-9]*\] //;
272 # ----- find EXPECT begin
274 if ($line =~ /^\s*$exp_begin/) {
276 $data =~ s/^\s*$exp_begin//;
280 if ($print_line_num) {
281 $line_num = sprintf("%4s ", $.);
283 printf "%s %s%s%s\n", $prefix, $line_num, $timestamp, $line;
290 # ----- find EXPECT end
292 if ($line =~ /^\s*$exp_end/) {
294 $data =~ s/^\s*$exp_end//;
297 if ($print_line_num) {
298 $line_num = sprintf("%4s ", $.);
300 printf "%s %s%s%s\n", $prefix, $line_num, $timestamp, $line;
305 if (@found_or_begin > 0) {
306 $begin = pop @found_or_begin;
307 if (compare($data, $begin)) {
310 } elsif (@begin > 0) {
318 $expect_missing_begin++;
319 print "** ERROR: EXPECT end without any EXPECT begin:\n";
320 print " end ---> $line\n";
324 if ($print_line_num) {
325 $line_num = sprintf("%4s ", $.);
329 printf "** %s%s$script_name WARNING - not found ---> %s\n",
330 $line_num, $timestamp, $data;
332 } elsif (! compare($data, $begin)) {
334 $expect_missing_end++;
335 print "** ERROR: EXPECT end does not match EXPECT begin:\n";
336 print " begin -> $begin\n";
337 print " end ---> $line\n";
349 # ----- not an EXPECT line
351 if (($line =~ /^${pr_fmt}start of unittest - you will see error messages$/) ||
352 ($line =~ /^${pr_fmt}end of unittest - [0-9]+ passed, [0-9]+ failed$/ ) ) {
353 $prefix = "->"; # 2 characters
354 } elsif ($line =~ /^${pr_fmt}FAIL /) {
356 $prefix = ">>"; # 2 characters
360 foreach $begin (@begin) {
361 if (compare($begin, $line)) {
368 $begin = shift @begin;
369 while (! compare($begin, $line)) {
370 push @found_or_begin, $begin;
371 $begin = shift @begin;
373 push @found_or_begin, $line;
379 $prefix = "ok"; # 2 characters
383 if ($print_line_num) {
384 $line_num = sprintf("%4s ", $.);
387 printf "%s %s%s%s\n", $prefix, $line_num, $timestamp, $line;
390 if (! $no_expect_stats) {
392 print "** EXPECT statistics:\n";
394 printf "** EXPECT found : %4i\n", $expect_found;
395 printf "** EXPECT not found : %4i\n", $expect_not_found;
396 printf "** missing EXPECT begin : %4i\n", $expect_missing_begin;
397 printf "** missing EXPECT end : %4i\n", $expect_missing_end;
398 printf "** unittest FAIL : %4i\n", $unittest_fail;
399 printf "** internal error : %4i\n", $internal_err;
403 print "** ERROR: EXPECT begin without any EXPECT end:\n";
404 print " This list may be misleading.\n";
405 foreach $begin (@begin) {
406 print " begin ---> $begin\n";