~ubuntu-branches/ubuntu/trusty/drizzle/trusty

« back to all changes in this revision

Viewing changes to tests/randgen/util/bughunt.pl

  • Committer: Package Import Robot
  • Author(s): Clint Byrum
  • Date: 2012-06-19 10:46:49 UTC
  • mfrom: (1.1.6)
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20120619104649-e2l0ggd4oz3um0f4
Tags: upstream-7.1.36-stable
ImportĀ upstreamĀ versionĀ 7.1.36-stable

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2008-2010 Sun Microsystems, Inc. All rights reserved.
 
2
# Use is subject to license terms.
 
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, but
 
9
# WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 
11
# 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
 
16
# USA
 
17
 
 
18
## Hunting for bugs.
 
19
##
 
20
## Repeated runs of runall with variation of seed and mask values.
 
21
##
 
22
## There will be a message in case some conditions are fulfilled.
 
23
## ==============================================================
 
24
## Message about           | Fulfilled conditions
 
25
##                         |
 
26
## --------------------------------------------------------------------------------------------------
 
27
## runall status code      | desired_status_codes is defined and we just reached one of them
 
28
## --------------------------------------------------------------------------------------------------
 
29
## matching output pattern | (expected_outputs is defined and one of the patterns matched)
 
30
##                         | and (desired_status_codes is not defined
 
31
##                         |      or desired_status_codes is defined and we just reached one of them)
 
32
##
 
33
##
 
34
## The protocol of some RQG run will be not deleted in case of
 
35
## ===========================================================
 
36
## runall status code <> 0
 
37
## or
 
38
## desired_status_codes is not defined, expected_outputs is defined and we just reached one of them
 
39
##
 
40
## If "--stop_on_match" is set a bughunt terminates in case of
 
41
## ===========================================================
 
42
## if desired_status_codes is defined and we just reached one of them
 
43
## and
 
44
## if expected_outputs is defined we found all patterns.
 
45
##
 
46
## The various options are explained in bughunt_template.cfg.
 
47
##
 
48
 
 
49
use strict;
 
50
use lib 'lib';
 
51
use lib '../lib';
 
52
use DBI;
 
53
use Carp;
 
54
use Getopt::Long;
 
55
use Data::Dumper;
 
56
use File::Copy;
 
57
 
 
58
use GenTest;
 
59
use GenTest::Constants;
 
60
use GenTest::Grammar;
 
61
use GenTest::Properties;
 
62
use GenTest::Simplifier::Grammar;
 
63
use Time::HiRes;
 
64
 
 
65
my $options = {};
 
66
GetOptions($options,
 
67
           'config=s',
 
68
           'grammar=s',
 
69
           'redefine=s',
 
70
           'trials=i',
 
71
           'initial_seed=i',
 
72
           'storage_prefix=s',
 
73
           'expected_outputs=s@',
 
74
           'desired_status_codes=s@',
 
75
           'rqg_options=s%',
 
76
           'basedir=s',
 
77
           'vardir_prefix=s',
 
78
           'mysqld=s%',
 
79
           'stop_on_match!');
 
80
my $config = GenTest::Properties->new(
 
81
    options => $options,
 
82
    legal => ['desired_status_codes',
 
83
              'expected_outputs',
 
84
              'grammar',
 
85
              'gendata',
 
86
              'redefine',
 
87
              'trials',
 
88
              'initial_seed',
 
89
              'mask_level',
 
90
              'initial_mask',
 
91
              'search_var_size',
 
92
              'rqg_options',
 
93
              'basedir',
 
94
              'vardir_prefix',
 
95
              'storage_prefix',
 
96
              'stop_on_match',
 
97
              'mysqld'],
 
98
    required=>['rqg_options',
 
99
               'grammar',
 
100
               'basedir',
 
101
               'vardir_prefix',
 
102
               'storage_prefix'],
 
103
    defaults => {search_var_size=>10000,
 
104
                 trials=>1}
 
105
    );
 
106
 
 
107
# Dump settings
 
108
$config->printProps;
 
109
 
 
110
## Calculate mysqld and rqg options
 
111
 
 
112
my $mysqlopt = $config->genOpt("--mysqld=--",$config->mysqld)
 
113
    if defined $config->mysqld;
 
114
 
 
115
my $rqgoptions = $config->genOpt('--', 'rqg_options');
 
116
 
 
117
# Determine some runtime parameter, check parameters, ....
 
118
 
 
119
my $run_id = time();
 
120
 
 
121
say("The ID of this run is $run_id.");
 
122
 
 
123
if ( ! -d $config->vardir_prefix ) {
 
124
    croak("vardir_prefix '"
 
125
          . $config->vardir_prefix .
 
126
          "' is not an existing directory");
 
127
}
 
128
 
 
129
my $vardir = $config->vardir_prefix . '/var_' . $run_id;
 
130
mkdir ($vardir);
 
131
push my @mtr_options, "--vardir=$vardir";
 
132
 
 
133
if ( ! -d $config->storage_prefix) {
 
134
    croak("storage_prefix '"
 
135
          . $config->storage_prefix .
 
136
          "' is not an existing directory");
 
137
}
 
138
my $storage = $config->storage_prefix.'/'.$run_id;
 
139
say "Storage is $storage";
 
140
mkdir ($storage);
 
141
 
 
142
# We must work on a copy of our test grammars because the original grammars could
 
143
# be modified during the bughunt or before inspection of the bughunt results.
 
144
my $sql_grammar = $storage."/bughunt_sql.yy";
 
145
copy($config->grammar, $sql_grammar)
 
146
    or croak("File " . $config->grammar . " cannot be copied to " . $sql_grammar );
 
147
my $data_grammar = "";
 
148
if ( defined $config->gendata ) {
 
149
   $data_grammar = $storage."/bughunt_data.zz";
 
150
   copy($config->gendata, $data_grammar)
 
151
       or croak("File " . $config->gendata . " cannot be copied to " . $data_grammar );
 
152
   $rqgoptions = $rqgoptions . " --gendata=" . $data_grammar;
 
153
}
 
154
my $redefine_grammar = "";
 
155
if ( defined $config->redefine ) {
 
156
   $redefine_grammar = $storage."/bughunt_sql_redefine.yy";
 
157
   copy($config->redefine, $redefine_grammar)
 
158
       or croak("File " . $config->redefine . " cannot be copied to " . $redefine_grammar );
 
159
   $rqgoptions = $rqgoptions . " --redefine=" . $redefine_grammar;
 
160
}
 
161
 
 
162
# Some bugs can be investigating using the core file and the server binary.
 
163
# Make a copy of the server binary.
 
164
# Attention: In the moment we do not use the copy during testing like the grammars.
 
165
# FIXME: There is at least one more location where the "mysqld" binary might be stored.
 
166
copy($config->basedir.'/sql/mysqld', $storage.'/mysqld');
 
167
$rqgoptions = $rqgoptions . " --basedir=" . $config->basedir;
 
168
 
 
169
my $good_seed = $config->initial_seed;
 
170
my $mask_level = $config->mask_level;
 
171
my $good_mask = $config->initial_mask;
 
172
my $current_seed;
 
173
my $current_mask;
 
174
my $current_rqg_log;
 
175
my $errfile = $vardir . '/log/master.err';
 
176
my $preserve_log;
 
177
foreach my $trial (1..$config->trials) {
 
178
    say("###### run_id = $run_id; trial = $trial ######");
 
179
 
 
180
    $current_seed = $good_seed - 1 + $trial;
 
181
    $current_mask = $good_mask - 1 + $trial;
 
182
    $current_rqg_log = $storage . '/' . $trial . '.log';
 
183
    $preserve_log = 0;
 
184
 
 
185
    my $start_time = Time::HiRes::time();
 
186
 
 
187
    my $runall =
 
188
        "perl runall.pl ".
 
189
        " $rqgoptions $mysqlopt ".
 
190
        "--grammar=".$sql_grammar." ".
 
191
        "--vardir=$vardir ".
 
192
        "--mask-level=$mask_level ".
 
193
        "--mask=$current_mask ".
 
194
        "--seed=$current_seed >$current_rqg_log 2>&1";
 
195
 
 
196
    say($runall);
 
197
    my $runall_status = system($runall);
 
198
    $runall_status = $runall_status >> 8;
 
199
 
 
200
    if ($runall_status == STATUS_UNKNOWN_ERROR) {
 
201
       say("runall_status = $runall_status");
 
202
       say("Maybe the server startup options are wrong.");
 
203
       say("Abort");
 
204
       exit STATUS_UNKNOWN_ERROR;
 
205
    }
 
206
 
 
207
 
 
208
    my $end_time = Time::HiRes::time();
 
209
    my $duration = $end_time - $start_time;
 
210
 
 
211
    say("runall_status = $runall_status; duration = $duration");
 
212
 
 
213
    if ($runall_status != 0) {$preserve_log = 1};
 
214
    if (defined $config->desired_status_codes) {
 
215
        foreach my $desired_status_code (@{$config->desired_status_codes}) {
 
216
            if (($runall_status == $desired_status_code) ||
 
217
                (($runall_status != 0) &&
 
218
                 ($desired_status_code == STATUS_ANY_ERROR))) {
 
219
                say ("###### Found status $runall_status ######");
 
220
                if (defined $config->expected_outputs) {
 
221
                    checkLogForPattern();
 
222
                } else {
 
223
                    exit STATUS_OK if $config->stop_on_match;
 
224
                }
 
225
            }
 
226
        }
 
227
    } elsif (defined $config->expected_outputs) {
 
228
        checkLogForPattern();
 
229
    }
 
230
    # Save storage space by deleting the log of a non important run.
 
231
    if ($preserve_log == 0) {
 
232
       unlink($current_rqg_log)
 
233
    } else {
 
234
      # Backup vardir, the grammars and the mysqld binary 
 
235
      # Attention: There might be warnings about missing grammar files
 
236
      # Sleep a bit with the intention to avoid that the archiver comes up with a
 
237
      # warning like "<vardir>/master-data/ib_logfile1: File changed during reading
 
238
      sleep 10;
 
239
      my $save_cmd = 'tar czf ' . $storage . '/' . $trial . '.tgz ' . $vardir . ' ' . $current_rqg_log . ' ' . $sql_grammar . ' ' . $data_grammar . ' ' . $redefine_grammar . ' ' . $storage.'/mysqld' ;
 
240
      say("save_cmd: ->$save_cmd<-");
 
241
      my $save_vardir = system($save_cmd);
 
242
      # FIXME: Abort in case the call to tar fails
 
243
    }
 
244
 
 
245
}
 
246
 
 
247
#############################
 
248
 
 
249
sub checkLogForPattern {
 
250
    open (my $my_logfile,'<'.$current_rqg_log)
 
251
        or croak "unable to open $current_rqg_log : $!";
 
252
 
 
253
    my @filestats = stat($current_rqg_log);
 
254
    my $filesize = $filestats[7];
 
255
    my $offset = $filesize - $config->search_var_size;
 
256
 
 
257
    ## Ensure the offset is not negative
 
258
    $offset = 0 if $offset < 0;
 
259
    read($my_logfile, my $rqgtest_output,
 
260
         $config->search_var_size,
 
261
         $offset );
 
262
    close ($my_logfile);
 
263
 
 
264
    my $match_on_all=1;
 
265
    foreach my $expected_output (@{$config->expected_outputs}) {
 
266
        if ($rqgtest_output =~ m{$expected_output}sio) {
 
267
            say ("###### Found pattern: $expected_output ######");
 
268
            $preserve_log = 1;
 
269
        } else {
 
270
            say ("###### Not found pattern: $expected_output ######");
 
271
            $match_on_all = 0;
 
272
        }
 
273
    }
 
274
    exit STATUS_OK if $config->stop_on_match and $match_on_all;
 
275
}