~ubuntu-branches/ubuntu/saucy/drizzle/saucy-proposed

« back to all changes in this revision

Viewing changes to tests/kewpie/randgen/lib/GenTest/Validator/ResultsetComparator3Simplify.pm

  • Committer: Package Import Robot
  • Author(s): Clint Byrum
  • Date: 2012-06-19 10:46:49 UTC
  • mfrom: (1.2.11) (2.1.16 sid)
  • Revision ID: package-import@ubuntu.com-20120619104649-9ij634mxm4x8pp4l
Tags: 1:7.1.36-stable-1ubuntu1
* Merge from Debian unstable. (LP: #987575)
  Remaining changes:
  - Added upstart script.
* debian/drizzle.upstart: dropped logger since upstart logs job
  output now.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2008-2009 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
# 2-way and 3-way result set comparartor with minority report in the
 
19
# case of 3-way comparision. Does also the same job as
 
20
# ResultsetComparator and may replace it for 2-ay comparision.
 
21
 
 
22
package GenTest::Validator::ResultsetComparator3Simplify;
 
23
 
 
24
require Exporter;
 
25
@ISA = qw(GenTest GenTest::Validator);
 
26
 
 
27
use strict;
 
28
 
 
29
use GenTest;
 
30
use GenTest::Constants;
 
31
use GenTest::Comparator;
 
32
use GenTest::Result;
 
33
use GenTest::Validator;
 
34
use GenTest::Simplifier::SQL;
 
35
use GenTest::Simplifier::Test;
 
36
 
 
37
 
 
38
sub compareTwo {
 
39
    my ($self, $q, $s1, $s2, $res1, $res2) = @_;
 
40
    
 
41
    my $outcome = GenTest::Comparator::compare($res1, $res2);
 
42
 
 
43
    if ($outcome == STATUS_LENGTH_MISMATCH) {
 
44
        if ($q =~ m{^\s*select}io) {
 
45
            say("-----------");
 
46
            say("Result length mismatch between $s1 and $s2 (".$res1->rows()." vs. ".$res2->rows().")");
 
47
            say("Query1: " . $res1->query());
 
48
            say("Query2: " . $res2->query());
 
49
            say(GenTest::Comparator::dumpDiff($res1,$res2));
 
50
        } else {
 
51
            say("-----------");
 
52
            say("Affected_rows mismatch between $s1 and $s2 (".$res1->affectedRows()." vs. ".$res2->affectedRows().")");
 
53
            say("Query1: " . $res1->query());
 
54
            say("Query2: " . $res2->query());
 
55
        }
 
56
    } elsif ($outcome == STATUS_CONTENT_MISMATCH) {
 
57
        say("-----------");
 
58
        say("Result content mismatch between $s1 and $s2.");
 
59
        say("Query1: " . $res1->query());
 
60
        say("Query2: " . $res2->query());
 
61
        say(GenTest::Comparator::dumpDiff($res1, $res2));
 
62
    }
 
63
 
 
64
    return $outcome;
 
65
    
 
66
}
 
67
 
 
68
sub simplifyTwo {
 
69
    my ($self, $query, $ex1, $ex2, $r1, $r2) = @_;
 
70
 
 
71
    my @executors = ( $ex1, $ex2 );
 
72
 
 
73
    my @results = ($r1, $r2);
 
74
 
 
75
    my $simplifier_sql = GenTest::Simplifier::SQL->new(
 
76
        oracle => sub {
 
77
            my $oracle_query = shift;
 
78
            
 
79
            my @oracle_results;
 
80
            foreach my $executor (@executors) {
 
81
                push @oracle_results, $executor->execute($oracle_query, 1);
 
82
            }
 
83
            my $oracle_compare = GenTest::Comparator::compare($oracle_results[0], $oracle_results[1]);
 
84
            if (
 
85
                ($oracle_compare == STATUS_LENGTH_MISMATCH) ||
 
86
                ($oracle_compare == STATUS_CONTENT_MISMATCH)
 
87
                ) {
 
88
                return ORACLE_ISSUE_STILL_REPEATABLE;
 
89
            } else {
 
90
                return ORACLE_ISSUE_NO_LONGER_REPEATABLE;
 
91
            }
 
92
        }
 
93
        );
 
94
    
 
95
    my $simplified_query = $simplifier_sql->simplify($query);
 
96
        
 
97
    if (defined $simplified_query) {
 
98
        my $simplified_results = [];
 
99
 
 
100
        foreach my $i (0,1) {
 
101
            $simplified_results->[$i] = 
 
102
                $executors[$i]->execute($simplified_query, 1);
 
103
            say("Simplified query".($i+1)." (".
 
104
                $executors[$i]->getName()." ".
 
105
                $executors[$i]->version()."): ".
 
106
                $simplified_results->[$i]->query().";");
 
107
        }
 
108
        
 
109
        say(GenTest::Comparator::dumpDiff($simplified_results->[0], $simplified_results->[1]));
 
110
        
 
111
        my $simplifier_test = GenTest::Simplifier::Test->new(
 
112
            executors   => \@executors ,
 
113
            results     => [ $simplified_results , \@results ]
 
114
            );
 
115
        # show_index is enabled for result difference queries its good to see the index details,
 
116
        # the value 1 is used to define if show_index is enabled, to disable dont assign a value.
 
117
        my $show_index = 1;
 
118
        my $simplified_test = $simplifier_test->simplify($show_index);
 
119
 
 
120
        my $tmpfile = tmpdir().$$.time().".test";
 
121
        say("Dumping .test to $tmpfile");
 
122
        open (TESTFILE, '>'.$tmpfile);
 
123
        print TESTFILE $simplified_test;
 
124
        close TESTFILE;
 
125
    } else {
 
126
        say("Could not simplify failure, appears to be sporadic.");
 
127
    }
 
128
}
 
129
 
 
130
 
 
131
sub validate {
 
132
    my ($self, $executors, $results) = @_;
 
133
 
 
134
    # Skip the whole stuff if only one resultset.
 
135
 
 
136
    return STATUS_OK if $#$results < 1;
 
137
 
 
138
    return STATUS_WONT_HANDLE 
 
139
        if $results->[0]->status() == STATUS_SEMANTIC_ERROR || 
 
140
           $results->[1]->status() == STATUS_SEMANTIC_ERROR;
 
141
    return STATUS_WONT_HANDLE if $results->[0]->query() =~ m{EXPLAIN}sio;
 
142
 
 
143
    ## Compare the two first resultsets
 
144
 
 
145
    my $query = $results->[0]->query();
 
146
 
 
147
    my $server1 = $executors->[0]->getName()." ".$executors->[0]->version();
 
148
    my $server2 = $executors->[1]->getName()." ".$executors->[1]->version();
 
149
    
 
150
    my $compare_1_2 = $self->compareTwo($query, $server1, $server2, $results->[0], $results->[1]);
 
151
    my $compare_result = $compare_1_2;
 
152
 
 
153
    # If 3 of them, do some more comparisions
 
154
 
 
155
    if ($#$results > 1) {
 
156
        my $server3 = $executors->[2]->getName()." ".$executors->[2]->version();
 
157
 
 
158
        return STATUS_WONT_HANDLE if $results->[2]->status() == STATUS_SEMANTIC_ERROR;
 
159
 
 
160
        my $compare_1_3 = $self->compareTwo($query, $server1, $server3, $results->[0], $results->[2]);
 
161
 
 
162
        ## If some of the above were different, we need compare 2 and
 
163
        ## 3 too to see if there exists a minority
 
164
        if ($compare_1_2 > STATUS_OK or $compare_1_3 > STATUS_OK) {
 
165
 
 
166
            return STATUS_WONT_HANDLE if $results->[2]->status() == STATUS_SEMANTIC_ERROR;
 
167
            
 
168
            my $compare_2_3 = $self->compareTwo($query, $server2, $server3, $results->[1], $results->[2]);
 
169
 
 
170
            if ($compare_1_2 > STATUS_OK and $compare_1_3 > STATUS_OK and $compare_2_3 > STATUS_OK) {
 
171
                say("Minority report: no minority");
 
172
                say("-----------");
 
173
            } elsif ($compare_1_2 > STATUS_OK and $compare_1_3 > STATUS_OK and $compare_2_3 == STATUS_OK) {
 
174
                say("Minority report: $server1(dsn1) differs from the two others");
 
175
                say("-----------");
 
176
                ####
 
177
                #### In this first shot, we only do simplification if
 
178
                #### Server 1, which is assumed to be MySQL is the
 
179
                #### minority, and we do the simplification only withe
 
180
                #### excutions on 1 and 2. This should be sufficirnt
 
181
                #### for hunting down MYSQL bugs.
 
182
                #### 
 
183
                if (($query =~ m{^\s*select}sio) && (
 
184
                        ($compare_1_2 == STATUS_LENGTH_MISMATCH) ||
 
185
                        ($compare_1_2 == STATUS_CONTENT_MISMATCH))) {
 
186
                    $self->simplifyTwo($query,$executors->[0],$executors->[1],$results->[0],$results->[1]);
 
187
                }
 
188
            } elsif ($compare_1_2 > STATUS_OK and $compare_1_3 == STATUS_OK and $compare_2_3 > STATUS_OK) {
 
189
                say("Minority report: $server2(dsn2) differs from the two others");
 
190
                say("-----------");
 
191
            } elsif ($compare_1_2 == STATUS_OK and $compare_1_3 > STATUS_OK and $compare_2_3 > STATUS_OK) {
 
192
                say("Minority report: $server3(dsn3) differs from the two others");
 
193
                say("-----------");
 
194
            }
 
195
 
 
196
            $compare_result = $compare_2_3 if $compare_2_3 > $compare_result;
 
197
        }
 
198
        
 
199
        $compare_result = $compare_1_3 if $compare_1_3 > $compare_result;
 
200
    }
 
201
    
 
202
    
 
203
    #
 
204
    # If the discrepancy is found on SELECT, we reduce the severity of
 
205
    # the error so that the test can continue hopefully finding
 
206
    # further errors in the same run or providing an indication as to
 
207
    # how frequent the error is.
 
208
    #
 
209
    # If the discrepancy is on an UPDATE, then the servers have
 
210
    # diverged and the test can not continue safely.
 
211
    # 
 
212
 
 
213
    # CAVEAT: This may cause false positives if one execution
 
214
    # influences the following executions. Failures due to a previous
 
215
    # failure have been seen.
 
216
    
 
217
    if ($query =~ m{^[\s/*!0-9]*(EXPLAIN|SELECT|ALTER|LOAD\s+INDEX|CACHE\s+INDEX)}io) {
 
218
        return $compare_result - STATUS_SELECT_REDUCTION;
 
219
    } else {
 
220
        return $compare_result;
 
221
    }
 
222
}
 
223
 
 
224
1;