From 5720db2b43491e5aec9265bce9637e00c72fa0aa Mon Sep 17 00:00:00 2001 From: Rasmus Johansson Date: Tue, 7 Apr 2020 07:45:49 +0000 Subject: [PATCH] MDEV-22176 Add JUnit support to MTR to generate XML test result A new parameter has been added called xml-report, with which the filename of the XML file is given to which the XML result is written. There is also xml-package for adding a package value in the XML output. Example usage: ./mysql-test-run.pl main.events_bugs innodb.count_distinct main.explain_json innodb.file_format_defaults json.json_no_table --suite=main,innodb,json --force --xml-report=build123456789.xml --xml-package=simpletestrun --- mysql-test/lib/My/Tee.pm | 2 +- mysql-test/lib/mtr_report.pm | 90 ++++++++++++++++++++++++++++++++++++ mysql-test/mysql-test-run.pl | 8 +++- 3 files changed, 97 insertions(+), 3 deletions(-) diff --git a/mysql-test/lib/My/Tee.pm b/mysql-test/lib/My/Tee.pm index 5985fe33739..8d6b4ddd52f 100644 --- a/mysql-test/lib/My/Tee.pm +++ b/mysql-test/lib/My/Tee.pm @@ -10,7 +10,7 @@ sub PUSHED open($copyfh, '>', "$::opt_vardir/log/stdout.log") or die "open(>$::opt_vardir/log/stdout.log): $!" unless $copyfh; - bless { }, shift; + bless { }, shift; } sub WRITE diff --git a/mysql-test/lib/mtr_report.pm b/mysql-test/lib/mtr_report.pm index 3701ad79b15..a3282704dd2 100644 --- a/mysql-test/lib/mtr_report.pm +++ b/mysql-test/lib/mtr_report.pm @@ -20,7 +20,9 @@ # same name. package mtr_report; + use strict; +use Sys::Hostname; use base qw(Exporter); our @EXPORT= qw(report_option mtr_print_line mtr_print_thick_line @@ -253,6 +255,7 @@ sub mtr_report_stats ($$$$) { # Find out how we where doing # ---------------------------------------------------------------------- + my $tot_disabled = 0; my $tot_skipped= 0; my $tot_skipdetect= 0; my $tot_passed= 0; @@ -273,6 +276,7 @@ sub mtr_report_stats ($$$$) { { # Test was skipped (disabled not counted) $tot_skipped++ unless $tinfo->{'disable'}; + $tot_disabled++ if $tinfo->{'disable'}; $tot_skipdetect++ if $tinfo->{'skip_detected_by_test'}; } elsif ( $tinfo->{'result'} eq 'MTR_RES_PASSED' ) @@ -402,6 +406,92 @@ sub mtr_report_stats ($$$$) { print "All $tot_tests tests were successful.\n\n"; } + if ($::opt_xml_report) { + my $xml_report = ""; + my @sorted_tests = sort {$a->{'name'} cmp $b->{'name'}} @$tests; + my $last_suite = ""; + my $current_suite = ""; + my $timest = isotime(time); + my %suite_totals; + my %suite_time; + my %suite_tests; + my %suite_failed; + my %suite_disabled; + my %suite_skipped; + my $host = hostname; + my $suiteNo = 0; + + # loop through test results to count totals + foreach my $test ( @sorted_tests ) { + $current_suite = $test->{'suite'}->{'name'}; + + if ($test->{'timer'} eq "") { + $test->{'timer'} = 0; + } + + $suite_time{$current_suite} = $suite_time{$current_suite} + $test->{'timer'}; + $suite_tests{$current_suite} = $suite_tests{$current_suite} + 1; + + if ($test->{'result'} eq "MTR_RES_FAILED") { + $suite_failed{$current_suite} = $suite_failed{$current_suite} + 1; + } elsif ($test->{'result'} eq "MTR_RES_SKIPPED" && $test->{'disable'}) { + $suite_disabled{$current_suite} = $suite_disabled{$current_suite} + 1; + } elsif ($test->{'result'} eq "MTR_RES_SKIPPED") { + $suite_skipped{$current_suite} = $suite_skipped{$current_suite} + 1; + } + + $suite_totals{"all_time"} = $suite_totals{"all_time"} + $test->{'timer'}; + } + + my $all_time = sprintf("%.3f", $suite_totals{"all_time"} / 1000); + my $suite_time = 0; + my $test_time = 0; + + # generate xml + $xml_report = "\n"; + $xml_report .= qq(\n); + + foreach my $test ( @sorted_tests ) { + $current_suite = $test->{'suite'}->{'name'}; + + if ($current_suite ne $last_suite) { + if ($last_suite ne "") { + $xml_report .= "\t\n"; + $suiteNo++; + } + + $suite_time = sprintf("%.3f", $suite_time{$current_suite} / 1000); + $xml_report .= qq(\t\n); + $last_suite = $current_suite; + } + + $test_time = sprintf("%.3f", $test->{timer} / 1000); + $xml_report .= qq(\t\t{'comment'}; + $comment =~ s/[\"]//g; + + if ($test->{'result'} eq "MTR_RES_FAILED") { + $xml_report .= qq(>\n\t\t\t\n{'logfile'}]]>\n\t\t\t\n\t\t\n); + } elsif ($test->{'result'} eq "MTR_RES_SKIPPED" && $test->{'disable'}) { + $xml_report .= qq(>\n\t\t\t\n\t\t\n); + } elsif ($test->{'result'} eq "MTR_RES_SKIPPED") { + $xml_report .= qq(>\n\t\t\t\n\t\t\n); + } else { + $xml_report .= " />\n"; + } + } + + $xml_report .= "\t\n\n"; + + # save to file + my $xml_file = $::opt_xml_report; + + open XML_FILE, ">", $xml_file or die "Cannot create file $xml_file: $!"; + print XML_FILE $xml_report; + close XML_FILE; + } + if (@$extra_warnings) { print < \$opt_usage, # list-options is internal, not listed in help 'list-options' => \$opt_list_options, - 'skip-test-list=s' => \@opt_skip_test_list + 'skip-test-list=s' => \@opt_skip_test_list, + 'xml-report=s' => \$opt_xml_report ); # fix options (that take an optional argument and *only* after = sign @@ -6281,6 +6284,7 @@ Misc options phases of test execution. stress=ARGS Run stress test, providing options to mysql-stress-test.pl. Options are separated by comma. + xml-report= Output jUnit xml file of the results. Some options that control enabling a feature for normal test runs, can be turned off by prepending 'no' to the option, e.g. --notimer.