1
# Copyright (C) 2008-2010 Sun Microsystems, Inc. All rights reserved.
2
# Use is subject to license terms.
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.
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.
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
20
## Repeated runs of runall with variation of seed and mask values.
22
## There will be a message in case some conditions are fulfilled.
23
## ==============================================================
24
## Message about | Fulfilled conditions
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)
34
## The protocol of some RQG run will be not deleted in case of
35
## ===========================================================
36
## runall status code <> 0
38
## desired_status_codes is not defined, expected_outputs is defined and we just reached one of them
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
44
## if expected_outputs is defined we found all patterns.
46
## The various options are explained in bughunt_template.cfg.
59
use GenTest::Constants;
61
use GenTest::Properties;
62
use GenTest::Simplifier::Grammar;
73
'expected_outputs=s@',
74
'desired_status_codes=s@',
80
my $config = GenTest::Properties->new(
82
legal => ['desired_status_codes',
98
required=>['rqg_options',
103
defaults => {search_var_size=>10000,
110
## Calculate mysqld and rqg options
112
my $mysqlopt = $config->genOpt("--mysqld=--",$config->mysqld)
113
if defined $config->mysqld;
115
my $rqgoptions = $config->genOpt('--', 'rqg_options');
117
# Determine some runtime parameter, check parameters, ....
121
say("The ID of this run is $run_id.");
123
if ( ! -d $config->vardir_prefix ) {
124
croak("vardir_prefix '"
125
. $config->vardir_prefix .
126
"' is not an existing directory");
129
my $vardir = $config->vardir_prefix . '/var_' . $run_id;
131
push my @mtr_options, "--vardir=$vardir";
133
if ( ! -d $config->storage_prefix) {
134
croak("storage_prefix '"
135
. $config->storage_prefix .
136
"' is not an existing directory");
138
my $storage = $config->storage_prefix.'/'.$run_id;
139
say "Storage is $storage";
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;
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;
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;
169
my $good_seed = $config->initial_seed;
170
my $mask_level = $config->mask_level;
171
my $good_mask = $config->initial_mask;
175
my $errfile = $vardir . '/log/master.err';
177
foreach my $trial (1..$config->trials) {
178
say("###### run_id = $run_id; trial = $trial ######");
180
$current_seed = $good_seed - 1 + $trial;
181
$current_mask = $good_mask - 1 + $trial;
182
$current_rqg_log = $storage . '/' . $trial . '.log';
185
my $start_time = Time::HiRes::time();
189
" $rqgoptions $mysqlopt ".
190
"--grammar=".$sql_grammar." ".
192
"--mask-level=$mask_level ".
193
"--mask=$current_mask ".
194
"--seed=$current_seed >$current_rqg_log 2>&1";
197
my $runall_status = system($runall);
198
$runall_status = $runall_status >> 8;
200
if ($runall_status == STATUS_UNKNOWN_ERROR) {
201
say("runall_status = $runall_status");
202
say("Maybe the server startup options are wrong.");
204
exit STATUS_UNKNOWN_ERROR;
208
my $end_time = Time::HiRes::time();
209
my $duration = $end_time - $start_time;
211
say("runall_status = $runall_status; duration = $duration");
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();
223
exit STATUS_OK if $config->stop_on_match;
227
} elsif (defined $config->expected_outputs) {
228
checkLogForPattern();
230
# Save storage space by deleting the log of a non important run.
231
if ($preserve_log == 0) {
232
unlink($current_rqg_log)
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
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
247
#############################
249
sub checkLogForPattern {
250
open (my $my_logfile,'<'.$current_rqg_log)
251
or croak "unable to open $current_rqg_log : $!";
253
my @filestats = stat($current_rqg_log);
254
my $filesize = $filestats[7];
255
my $offset = $filesize - $config->search_var_size;
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,
265
foreach my $expected_output (@{$config->expected_outputs}) {
266
if ($rqgtest_output =~ m{$expected_output}sio) {
267
say ("###### Found pattern: $expected_output ######");
270
say ("###### Not found pattern: $expected_output ######");
274
exit STATUS_OK if $config->stop_on_match and $match_on_all;