run-test-suites.pl 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. #!/usr/bin/env perl
  2. # run-test-suites.pl
  3. #
  4. # Copyright The Mbed TLS Contributors
  5. # SPDX-License-Identifier: Apache-2.0
  6. #
  7. # Licensed under the Apache License, Version 2.0 (the "License"); you may
  8. # not use this file except in compliance with the License.
  9. # You may obtain a copy of the License at
  10. #
  11. # http://www.apache.org/licenses/LICENSE-2.0
  12. #
  13. # Unless required by applicable law or agreed to in writing, software
  14. # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  15. # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. # See the License for the specific language governing permissions and
  17. # limitations under the License.
  18. =head1 SYNOPSIS
  19. Execute all the test suites and print a summary of the results.
  20. run-test-suites.pl [[-v|--verbose] [VERBOSITY]] [--skip=SUITE[...]]
  21. Options:
  22. -v|--verbose Print detailed failure information.
  23. -v 2|--verbose=2 Print detailed failure information and summary messages.
  24. -v 3|--verbose=3 Print detailed information about every test case.
  25. --skip=SUITE[,SUITE...]
  26. Skip the specified SUITE(s). This option can be used
  27. multiple times.
  28. =cut
  29. use warnings;
  30. use strict;
  31. use utf8;
  32. use open qw(:std utf8);
  33. use Getopt::Long qw(:config auto_help gnu_compat);
  34. use Pod::Usage;
  35. my $verbose = 0;
  36. my @skip_patterns = ();
  37. GetOptions(
  38. 'skip=s' => \@skip_patterns,
  39. 'verbose|v:1' => \$verbose,
  40. ) or die;
  41. # All test suites = executable files with a .datax file.
  42. my @suites = ();
  43. for my $data_file (glob 'test_suite_*.datax') {
  44. (my $base = $data_file) =~ s/\.datax$//;
  45. push @suites, $base if -x $base;
  46. push @suites, "$base.exe" if -e "$base.exe";
  47. }
  48. die "$0: no test suite found\n" unless @suites;
  49. # "foo" as a skip pattern skips "test_suite_foo" and "test_suite_foo.bar"
  50. # but not "test_suite_foobar".
  51. my $skip_re =
  52. ( '\Atest_suite_(' .
  53. join('|', map {
  54. s/[ ,;]/|/g; # allow any of " ,;|" as separators
  55. s/\./\./g; # "." in the input means ".", not "any character"
  56. $_
  57. } @skip_patterns) .
  58. ')(\z|\.)' );
  59. # in case test suites are linked dynamically
  60. $ENV{'LD_LIBRARY_PATH'} = '../library';
  61. $ENV{'DYLD_LIBRARY_PATH'} = '../library';
  62. my $prefix = $^O eq "MSWin32" ? '' : './';
  63. my (@failed_suites, $total_tests_run, $failed, $suite_cases_passed,
  64. $suite_cases_failed, $suite_cases_skipped, $total_cases_passed,
  65. $total_cases_failed, $total_cases_skipped );
  66. my $suites_skipped = 0;
  67. sub pad_print_center {
  68. my( $width, $padchar, $string ) = @_;
  69. my $padlen = ( $width - length( $string ) - 2 ) / 2;
  70. print $padchar x( $padlen ), " $string ", $padchar x( $padlen ), "\n";
  71. }
  72. for my $suite (@suites)
  73. {
  74. print "$suite ", "." x ( 72 - length($suite) - 2 - 4 ), " ";
  75. if( $suite =~ /$skip_re/o ) {
  76. print "SKIP\n";
  77. ++$suites_skipped;
  78. next;
  79. }
  80. my $command = "$prefix$suite";
  81. if( $verbose ) {
  82. $command .= ' -v';
  83. }
  84. my $result = `$command`;
  85. $suite_cases_passed = () = $result =~ /.. PASS/g;
  86. $suite_cases_failed = () = $result =~ /.. FAILED/g;
  87. $suite_cases_skipped = () = $result =~ /.. ----/g;
  88. if( $? == 0 ) {
  89. print "PASS\n";
  90. if( $verbose > 2 ) {
  91. pad_print_center( 72, '-', "Begin $suite" );
  92. print $result;
  93. pad_print_center( 72, '-', "End $suite" );
  94. }
  95. } else {
  96. push @failed_suites, $suite;
  97. print "FAIL\n";
  98. if( $verbose ) {
  99. pad_print_center( 72, '-', "Begin $suite" );
  100. print $result;
  101. pad_print_center( 72, '-', "End $suite" );
  102. }
  103. }
  104. my ($passed, $tests, $skipped) = $result =~ /([0-9]*) \/ ([0-9]*) tests.*?([0-9]*) skipped/;
  105. $total_tests_run += $tests - $skipped;
  106. if( $verbose > 1 ) {
  107. print "(test cases passed:", $suite_cases_passed,
  108. " failed:", $suite_cases_failed,
  109. " skipped:", $suite_cases_skipped,
  110. " of total:", ($suite_cases_passed + $suite_cases_failed +
  111. $suite_cases_skipped),
  112. ")\n"
  113. }
  114. $total_cases_passed += $suite_cases_passed;
  115. $total_cases_failed += $suite_cases_failed;
  116. $total_cases_skipped += $suite_cases_skipped;
  117. }
  118. print "-" x 72, "\n";
  119. print @failed_suites ? "FAILED" : "PASSED";
  120. printf( " (%d suites, %d tests run%s)\n",
  121. scalar(@suites) - $suites_skipped,
  122. $total_tests_run,
  123. $suites_skipped ? ", $suites_skipped suites skipped" : "" );
  124. if( $verbose && @failed_suites ) {
  125. # the output can be very long, so provide a summary of which suites failed
  126. print " failed suites : @failed_suites\n";
  127. }
  128. if( $verbose > 1 ) {
  129. print " test cases passed :", $total_cases_passed, "\n";
  130. print " failed :", $total_cases_failed, "\n";
  131. print " skipped :", $total_cases_skipped, "\n";
  132. print " of tests executed :", ( $total_cases_passed + $total_cases_failed ),
  133. "\n";
  134. print " of available tests :",
  135. ( $total_cases_passed + $total_cases_failed + $total_cases_skipped ),
  136. "\n";
  137. if( $suites_skipped != 0 ) {
  138. print "Note: $suites_skipped suites were skipped.\n";
  139. }
  140. }
  141. exit( @failed_suites ? 1 : 0 );