~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

Viewing changes to mysql-test/lib/mtr_report.pm

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- cperl -*-
 
2
# Copyright 2004-2008 MySQL AB, 2008 Sun Microsystems, Inc.
 
3
 
4
# This program is free software; you can redistribute it and/or modify
 
5
# it under the terms of the GNU General Public License as published by
 
6
# the Free Software Foundation; version 2 of the License.
 
7
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
16
 
 
17
# This is a library file used by the Perl version of mysql-test-run,
 
18
# and is part of the translation of the Bourne shell script with the
 
19
# same name.
 
20
 
 
21
package mtr_report;
 
22
use strict;
 
23
 
 
24
use base qw(Exporter);
 
25
our @EXPORT= qw(report_option mtr_print_line mtr_print_thick_line
 
26
                mtr_print_header mtr_report mtr_report_stats
 
27
                mtr_warning mtr_error mtr_debug mtr_verbose
 
28
                mtr_verbose_restart mtr_report_test_passed
 
29
                mtr_report_test_skipped mtr_print
 
30
                mtr_report_test);
 
31
 
 
32
use mtr_match;
 
33
use My::Platform;
 
34
use POSIX qw[ _exit ];
 
35
require "mtr_io.pl";
 
36
 
 
37
my $tot_real_time= 0;
 
38
 
 
39
our $timestamp= 0;
 
40
our $timediff= 0;
 
41
our $name;
 
42
our $verbose;
 
43
our $verbose_restart= 0;
 
44
our $timer= 1;
 
45
 
 
46
sub report_option {
 
47
  my ($opt, $value)= @_;
 
48
 
 
49
  # Evaluate $opt as string to use "Getopt::Long::Callback legacy API"
 
50
  my $opt_name = "$opt";
 
51
 
 
52
  # Convert - to _ in option name
 
53
  $opt_name =~ s/-/_/g;
 
54
  no strict 'refs';
 
55
  ${$opt_name}= $value;
 
56
}
 
57
 
 
58
sub _name {
 
59
  return $name ? $name." " : undef;
 
60
}
 
61
 
 
62
sub _mtr_report_test_name ($) {
 
63
  my $tinfo= shift;
 
64
  my $tname= $tinfo->{name};
 
65
 
 
66
  return unless defined $verbose;
 
67
 
 
68
  # Add combination name if any
 
69
  $tname.= " '$tinfo->{combination}'"
 
70
    if defined $tinfo->{combination};
 
71
 
 
72
  print _name(). _timestamp();
 
73
  printf "%-40s ", $tname;
 
74
  my $worker = $tinfo->{worker};
 
75
  printf "w$worker " if $worker;
 
76
 
 
77
  return $tname;
 
78
}
 
79
 
 
80
 
 
81
sub mtr_report_test_skipped ($) {
 
82
  my ($tinfo)= @_;
 
83
  $tinfo->{'result'}= 'MTR_RES_SKIPPED';
 
84
 
 
85
  mtr_report_test($tinfo);
 
86
}
 
87
 
 
88
 
 
89
sub mtr_report_test_passed ($) {
 
90
  my ($tinfo)= @_;
 
91
 
 
92
  # Save the timer value
 
93
  my $timer_str=  "";
 
94
  if ( $timer and -f "$::opt_vardir/log/timer" )
 
95
  {
 
96
    $timer_str= mtr_fromfile("$::opt_vardir/log/timer");
 
97
    $tinfo->{timer}= $timer_str;
 
98
  }
 
99
 
 
100
  # Big warning if status already set
 
101
  if ( $tinfo->{'result'} ){
 
102
    mtr_warning("mtr_report_test_passed: Test result",
 
103
                "already set to '", $tinfo->{'result'}, ",");
 
104
  }
 
105
 
 
106
  $tinfo->{'result'}= 'MTR_RES_PASSED';
 
107
 
 
108
  mtr_report_test($tinfo);
 
109
}
 
110
 
 
111
 
 
112
sub mtr_report_test ($) {
 
113
  my ($tinfo)= @_;
 
114
  my $test_name = _mtr_report_test_name($tinfo);
 
115
 
 
116
  my $comment=  $tinfo->{'comment'};
 
117
  my $logfile=  $tinfo->{'logfile'};
 
118
  my $warnings= $tinfo->{'warnings'};
 
119
  my $result=   $tinfo->{'result'};
 
120
  my $retry=    $tinfo->{'retries'} ? "retry-" : "";
 
121
 
 
122
  if ($result eq 'MTR_RES_FAILED'){
 
123
 
 
124
    my $timest = format_time();
 
125
    my $fail = "fail";
 
126
 
 
127
    if ( $::opt_experimental )
 
128
    {
 
129
      # Find out if this test case is an experimental one, so we can treat
 
130
      # the failure as an expected failure instead of a regression.
 
131
      for my $exp ( @$::experimental_test_cases ) {
 
132
        if ( $exp ne $test_name ) {
 
133
          # if the expression is not the name of this test case, but has
 
134
          # an asterisk at the end, determine if the characters up to
 
135
          # but excluding the asterisk are the same
 
136
          if ( $exp ne "" && substr($exp, -1, 1) eq "*" ) {
 
137
            my $nexp = substr($exp, 0, length($exp) - 1);
 
138
            if ( substr($test_name, 0, length($nexp)) ne $nexp ) {
 
139
              # no match, try next entry
 
140
              next;
 
141
            }
 
142
            # if yes, fall through to set the exp-fail status
 
143
          } else {
 
144
            # no match, try next entry
 
145
            next;
 
146
          }
 
147
        }
 
148
        $fail = "exp-fail";
 
149
        $tinfo->{exp_fail}= 1;
 
150
        last;
 
151
      }
 
152
    }
 
153
 
 
154
    if ( $warnings )
 
155
    {
 
156
      mtr_report("[ $retry$fail ]  Found warnings/errors in server log file!");
 
157
      mtr_report("        Test ended at $timest");
 
158
      mtr_report($warnings);
 
159
      return;
 
160
    }
 
161
    my $timeout= $tinfo->{'timeout'};
 
162
    if ( $timeout )
 
163
    {
 
164
      mtr_report("[ $retry$fail ]  timeout after $timeout seconds");
 
165
      mtr_report("        Test ended at $timest");
 
166
      mtr_report("\n$tinfo->{'comment'}");
 
167
      return;
 
168
    }
 
169
    else
 
170
    {
 
171
      mtr_report("[ $retry$fail ]\n        Test ended at $timest");
 
172
    }
 
173
 
 
174
    if ( $logfile )
 
175
    {
 
176
      # Test failure was detected by test tool and its report
 
177
      # about what failed has been saved to file. Display the report.
 
178
      mtr_report("\n$logfile\n");
 
179
    }
 
180
    if ( $comment )
 
181
    {
 
182
      # The test failure has been detected by mysql-test-run.pl
 
183
      # when starting the servers or due to other error, the reason for
 
184
      # failing the test is saved in "comment"
 
185
      mtr_report("\n$comment\n");
 
186
    }
 
187
 
 
188
    if ( !$logfile and !$comment )
 
189
    {
 
190
      # Neither this script or the test tool has recorded info
 
191
      # about why the test has failed. Should be debugged.
 
192
      mtr_report("\nUnknown result, neither 'comment' or 'logfile' set");
 
193
    }
 
194
  }
 
195
  elsif ($result eq 'MTR_RES_SKIPPED')
 
196
  {
 
197
    if ( $tinfo->{'disable'} )
 
198
    {
 
199
      mtr_report("[ disabled ]  $comment");
 
200
    }
 
201
    elsif ( $comment )
 
202
    {
 
203
      mtr_report("[ skipped ]  $comment");
 
204
    }
 
205
    else
 
206
    {
 
207
      mtr_report("[ skipped ]");
 
208
    }
 
209
  }
 
210
  elsif ($result eq 'MTR_RES_PASSED')
 
211
  {
 
212
    my $timer_str= $tinfo->{timer} || "";
 
213
    $tot_real_time += ($timer_str/1000);
 
214
    mtr_report("[ ${retry}pass ] ", sprintf("%5s", $timer_str));
 
215
 
 
216
    # Show any problems check-testcase found
 
217
    if ( defined $tinfo->{'check'} )
 
218
    {
 
219
      mtr_report($tinfo->{'check'});
 
220
    }
 
221
  }
 
222
}
 
223
 
 
224
 
 
225
sub mtr_report_stats ($$;$) {
 
226
  my ($prefix, $tests, $dont_error)= @_;
 
227
 
 
228
  # ----------------------------------------------------------------------
 
229
  # Find out how we where doing
 
230
  # ----------------------------------------------------------------------
 
231
 
 
232
  my $tot_skiped= 0;
 
233
  my $tot_passed= 0;
 
234
  my $tot_failed= 0;
 
235
  my $tot_tests=  0;
 
236
  my $tot_restarts= 0;
 
237
  my $found_problems= 0;
 
238
 
 
239
  foreach my $tinfo (@$tests)
 
240
  {
 
241
    if ( $tinfo->{failures} )
 
242
    {
 
243
      # Test has failed at least one time
 
244
      $tot_tests++;
 
245
      $tot_failed++;
 
246
    }
 
247
    elsif ( $tinfo->{'result'} eq 'MTR_RES_SKIPPED' )
 
248
    {
 
249
      # Test was skipped
 
250
      $tot_skiped++;
 
251
    }
 
252
    elsif ( $tinfo->{'result'} eq 'MTR_RES_PASSED' )
 
253
    {
 
254
      # Test passed
 
255
      $tot_tests++;
 
256
      $tot_passed++;
 
257
    }
 
258
 
 
259
    if ( $tinfo->{'restarted'} )
 
260
    {
 
261
      # Servers was restarted
 
262
      $tot_restarts++;
 
263
    }
 
264
 
 
265
    # Add counts for repeated runs, if any.
 
266
    # Note that the last run has already been counted above.
 
267
    my $num_repeat = $tinfo->{'repeat'} - 1;
 
268
    if ( $num_repeat > 0 )
 
269
    {
 
270
      $tot_tests += $num_repeat;
 
271
      my $rep_failed = $tinfo->{'rep_failures'} || 0;
 
272
      $tot_failed += $rep_failed;
 
273
      $tot_passed += $num_repeat - $rep_failed;
 
274
    }
 
275
 
 
276
    # Look for warnings produced by mysqltest
 
277
    my $base_file= mtr_match_extension($tinfo->{'result_file'},
 
278
                                       "result"); # Trim extension
 
279
    my $warning_file= "$base_file.warnings";
 
280
    if ( -f $warning_file )
 
281
    {
 
282
      $found_problems= 1;
 
283
      mtr_warning("Check myqltest warnings in '$warning_file'");
 
284
    }
 
285
  }
 
286
 
 
287
  # ----------------------------------------------------------------------
 
288
  # Print out a summary report to screen
 
289
  # ----------------------------------------------------------------------
 
290
  print "The servers were restarted $tot_restarts times\n";
 
291
 
 
292
  if ( $timer )
 
293
  {
 
294
    use English;
 
295
 
 
296
    mtr_report("Spent", sprintf("%.3f", $tot_real_time),"of",
 
297
               time - $BASETIME, "seconds executing testcases");
 
298
  }
 
299
 
 
300
 
 
301
  my $warnlog= "$::opt_vardir/log/warnings";
 
302
  if ( -f $warnlog )
 
303
  {
 
304
    mtr_warning("Got errors/warnings while running tests, please examine",
 
305
                "'$warnlog' for details.");
 
306
 }
 
307
 
 
308
  print "\n";
 
309
 
 
310
  # Print a list of check_testcases that failed(if any)
 
311
  if ( $::opt_check_testcases )
 
312
  {
 
313
    my %check_testcases;
 
314
 
 
315
    foreach my $tinfo (@$tests)
 
316
    {
 
317
      if ( defined $tinfo->{'check_testcase_failed'} )
 
318
      {
 
319
        $check_testcases{$tinfo->{'name'}}= 1;
 
320
      }
 
321
    }
 
322
 
 
323
    if ( keys %check_testcases )
 
324
    {
 
325
      print "Check of testcase failed for: ";
 
326
      print join(" ", keys %check_testcases);
 
327
      print "\n\n";
 
328
    }
 
329
  }
 
330
 
 
331
  # Print summary line prefix
 
332
  print "$prefix: ";
 
333
 
 
334
  # Print a list of testcases that failed
 
335
  if ( $tot_failed != 0 )
 
336
  {
 
337
 
 
338
    # Print each failed test, again
 
339
    #foreach my $test ( @$tests ){
 
340
    #  if ( $test->{failures} ) {
 
341
    #    mtr_report_test($test);
 
342
    #  }
 
343
    #}
 
344
 
 
345
    my $ratio=  $tot_passed * 100 / $tot_tests;
 
346
    print "Failed $tot_failed/$tot_tests tests, ";
 
347
    printf("%.2f", $ratio);
 
348
    print "\% were successful.\n\n";
 
349
 
 
350
    # Print the list of test that failed in a format
 
351
    # that can be copy pasted to rerun only failing tests
 
352
    print "Failing test(s):";
 
353
 
 
354
    my %seen= ();
 
355
    foreach my $tinfo (@$tests)
 
356
    {
 
357
      my $tname= $tinfo->{'name'};
 
358
      if ( ($tinfo->{failures} || $tinfo->{rep_failures}) and ! $seen{$tname})
 
359
      {
 
360
        print " $tname";
 
361
        $seen{$tname}= 1;
 
362
      }
 
363
    }
 
364
    print "\n\n";
 
365
 
 
366
    # Print info about reporting the error
 
367
    print
 
368
      "The log files in var/log may give you some hint of what went wrong.\n\n",
 
369
      "If you want to report this error, please read first ",
 
370
      "the documentation\n",
 
371
      "at http://dev.mysql.com/doc/mysql/en/mysql-test-suite.html\n\n";
 
372
 
 
373
   }
 
374
  else
 
375
  {
 
376
    print "All $tot_tests tests were successful.\n\n";
 
377
  }
 
378
 
 
379
  if ( $tot_failed != 0 || $found_problems)
 
380
  {
 
381
    mtr_error("there were failing test cases") unless $dont_error;
 
382
  }
 
383
}
 
384
 
 
385
 
 
386
##############################################################################
 
387
#
 
388
#  Text formatting
 
389
#
 
390
##############################################################################
 
391
 
 
392
sub mtr_print_line () {
 
393
  print '-' x 60 . "\n";
 
394
}
 
395
 
 
396
 
 
397
sub mtr_print_thick_line {
 
398
  my $char= shift || '=';
 
399
  print $char x 78 . "\n";
 
400
}
 
401
 
 
402
 
 
403
sub mtr_print_header () {
 
404
  print "\n";
 
405
  printf "TEST";
 
406
  print " " x 38;
 
407
  print "RESULT   ";
 
408
  print "TIME (ms)" if $timer;
 
409
  print "\n";
 
410
  mtr_print_line();
 
411
  print "\n";
 
412
}
 
413
 
 
414
 
 
415
##############################################################################
 
416
#
 
417
#  Log and reporting functions
 
418
#
 
419
##############################################################################
 
420
 
 
421
use Time::localtime;
 
422
 
 
423
use Time::HiRes qw(gettimeofday);
 
424
 
 
425
sub format_time {
 
426
  my $tm= localtime();
 
427
  return sprintf("%4d-%02d-%02d %02d:%02d:%02d",
 
428
                 $tm->year + 1900, $tm->mon+1, $tm->mday,
 
429
                 $tm->hour, $tm->min, $tm->sec);
 
430
}
 
431
 
 
432
my $t0= gettimeofday();
 
433
 
 
434
sub _timestamp {
 
435
  return "" unless $timestamp;
 
436
 
 
437
  my $diff;
 
438
  if ($timediff){
 
439
    my $t1= gettimeofday();
 
440
    my $elapsed= $t1 - $t0;
 
441
 
 
442
    $diff= sprintf(" +%02.3f", $elapsed);
 
443
 
 
444
    # Save current time for next lap
 
445
    $t0= $t1;
 
446
 
 
447
  }
 
448
 
 
449
  my $tm= localtime();
 
450
  return sprintf("%02d%02d%02d %2d:%02d:%02d%s ",
 
451
                 $tm->year % 100, $tm->mon+1, $tm->mday,
 
452
                 $tm->hour, $tm->min, $tm->sec, $diff);
 
453
}
 
454
 
 
455
# Always print message to screen
 
456
sub mtr_print (@) {
 
457
  print _name(). join(" ", @_). "\n";
 
458
}
 
459
 
 
460
 
 
461
# Print message to screen if verbose is defined
 
462
sub mtr_report (@) {
 
463
  if (defined $verbose)
 
464
  {
 
465
    print _name(). join(" ", @_). "\n";
 
466
  }
 
467
}
 
468
 
 
469
 
 
470
# Print warning to screen
 
471
sub mtr_warning (@) {
 
472
  print STDERR _name(). _timestamp().
 
473
    "mysql-test-run: WARNING: ". join(" ", @_). "\n";
 
474
}
 
475
 
 
476
 
 
477
# Print error to screen and then exit
 
478
sub mtr_error (@) {
 
479
  print STDERR _name(). _timestamp().
 
480
    "mysql-test-run: *** ERROR: ". join(" ", @_). "\n";
 
481
  if (IS_WINDOWS)
 
482
  {
 
483
    POSIX::_exit(1);
 
484
  }
 
485
  else
 
486
  {
 
487
    exit(1);
 
488
  }
 
489
}
 
490
 
 
491
 
 
492
sub mtr_debug (@) {
 
493
  if ( $verbose > 2 )
 
494
  {
 
495
    print STDERR _name().
 
496
      _timestamp(). "####: ". join(" ", @_). "\n";
 
497
  }
 
498
}
 
499
 
 
500
 
 
501
sub mtr_verbose (@) {
 
502
  if ( $verbose )
 
503
  {
 
504
    print STDERR _name(). _timestamp().
 
505
      "> ".join(" ", @_)."\n";
 
506
  }
 
507
}
 
508
 
 
509
 
 
510
sub mtr_verbose_restart (@) {
 
511
  my ($server, @args)= @_;
 
512
  my $proc= $server->{proc};
 
513
  if ( $verbose_restart )
 
514
  {
 
515
    print STDERR _name()._timestamp().
 
516
      "> Restart $proc - ".join(" ", @args)."\n";
 
517
  }
 
518
}
 
519
 
 
520
 
 
521
1;