~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to util/simplify-grammar.pl

merge from internal tree

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
 
6
6
use GenTest;
7
7
use GenTest::Constants;
 
8
use GenTest::Grammar;
8
9
use GenTest::Simplifier::Grammar;
9
10
use Time::HiRes;
10
11
 
11
12
12
 
# This script is used to simplify grammar files to the smallest form that will still reproduce the problem
 
13
# This script is used to simplify grammar files to the smallest form that will still reproduce the desired outcome
13
14
# For the purpose, the GenTest::Simplifier::Grammar module provides progressively simple grammars, and we
14
15
# define an oracle() function that runs those grammars with the RQG and reports if the RQG returns the desired
15
16
# status code (usually something like STATUS_SERVER_CRASHED
24
25
#
25
26
 
26
27
my @rqg_options =( 
27
 
        '--mem',
28
 
        '--threads=1',
29
 
        '--basedir=/path/to/mysql/basedir',
30
 
        '--mysqld=--innodb-lock-wait-timeout=1',
31
 
        '--mysqld=--table-lock-wait-timeout=1',
32
 
        '--reporters=Deadlock,ErrorLog',
33
 
        '--validators=',
34
 
        '--queries=10000',
35
 
        '--duration=90'
 
28
        '--basedir=/build/bzr/mysql-next-bugfixing',
 
29
        '--gendata=conf/WL5004_data.zz --threads=40 --rpl_mode=row --queries=10K --duration=40 --reporter=Deadlock,Shutdown'
36
30
);
37
31
 
38
 
my $initial_grammar_file = 'conf/example.yy';
 
32
my $initial_grammar_file = 'conf/WL5004_sql.yy';
39
33
 
40
34
# Status codes are described in lib/GenTest/Constants.pm
 
35
# STATUS_ANY_ERROR means that any RQG error would cause the simplification to continue,
 
36
# e.g. both deadlocks and crashes will be considered together
41
37
 
42
 
my $expected_status_code = STATUS_SERVER_CRASHED;
 
38
my @desired_status_codes = (STATUS_REPLICATION_FAILURE);
43
39
 
44
40
# This is the number of times the oracle() will run the RQG in order to get to the
45
41
# desired error code. If the error is sporadic, several runs may be required to know
47
43
 
48
44
my $trials = 1;
49
45
 
 
46
# Set $grammar_flags to GRAMMAR_FLAG_COMPACT_RULES so that rules such as rule: a | a | a | a | a | a | b
 
47
# are compressed to rule: a | b before simplification. This will speed up the process as each instance of
 
48
# "a" will not be removed separately until they are all gone.
 
49
 
 
50
my $grammar_flags = GRAMMAR_FLAG_COMPACT_RULES;
 
51
 
50
52
# End of user-modifiable settings
51
53
 
52
54
my $run_id = time();
53
55
 
54
56
say("The ID of this run is $run_id.");
55
57
 
56
 
open(INITIAL_GRAMMAR, $initial_grammar_file);
 
58
open(INITIAL_GRAMMAR, $initial_grammar_file) or die "Umable to open '$initial_grammar_file': $!";;
57
59
read(INITIAL_GRAMMAR, my $initial_grammar , -s $initial_grammar_file);
58
60
close(INITIAL_GRAMMAR);
59
61
 
60
62
my $iteration;
61
63
 
62
64
my $simplifier = GenTest::Simplifier::Grammar->new(
 
65
        grammar_flags => $grammar_flags,
63
66
        oracle => sub {
64
67
 
65
68
                my $oracle_grammar = shift;
70
73
 
71
74
                        my $tmpfile = tmpdir().$run_id.'-'.$iteration.'-'.$trial.'.yy';
72
75
                        my $logfile = tmpdir().$run_id.'-'.$iteration.'-'.$trial.'.log';
 
76
                        my $vardir = tmpdir().$run_id.'-'.$iteration.'-'.$trial.'-var';
73
77
                        open (GRAMMAR, ">$tmpfile") or die "unable to create $tmpfile: $!";
74
78
                        print GRAMMAR $oracle_grammar;
75
79
                        close (GRAMMAR);
76
80
 
77
81
                        my $start_time = Time::HiRes::time();
78
82
 
79
 
                        my $rqg_status = system("perl runall.pl ".join(' ', @rqg_options)." --grammar=$tmpfile 2>&1 >$logfile");
 
83
                        mkdir ($vardir);
 
84
                        my $rqg_status = system("perl runall.pl ".join(' ', @rqg_options)." --grammar=$tmpfile --vardir=$vardir 2>&1 >$logfile");
80
85
                        $rqg_status = $rqg_status >> 8;
81
86
 
82
87
                        my $end_time = Time::HiRes::time();
84
89
 
85
90
                        say("rqg_status = $rqg_status; duration = $duration");
86
91
 
87
 
                        return 0 if $rqg_status == STATUS_ENVIRONMENT_FAILURE;
88
 
 
89
 
                        if ($rqg_status == $expected_status_code) {
90
 
                                return 1;
91
 
                        } 
 
92
                        return ORACLE_ISSUE_NO_LONGER_REPEATABLE if $rqg_status == STATUS_ENVIRONMENT_FAILURE;
 
93
                        
 
94
                        foreach my $desired_status_code (@desired_status_codes) {
 
95
                                if (
 
96
                                        ($rqg_status == $desired_status_code) ||
 
97
                                        (($rqg_status != 0) && ($desired_status_code == STATUS_ANY_ERROR))
 
98
                                ) {
 
99
                                        return ORACLE_ISSUE_STILL_REPEATABLE;
 
100
                                }
 
101
                        }
92
102
                }
93
 
                return 0;
 
103
                return ORACLE_ISSUE_NO_LONGER_REPEATABLE;
94
104
        }
95
105
);
96
106
 
97
107
my $simplified_grammar = $simplifier->simplify($initial_grammar);
98
108
 
99
 
print "Simplified grammar:\n\n$simplified_grammar;\n\n";
 
109
print "Simplified grammar:\n\n$simplified_grammar;\n\n" if defined $simplified_grammar;