~ubuntu-branches/ubuntu/vivid/drizzle/vivid-proposed

« back to all changes in this revision

Viewing changes to tests/randgen/lib/GenTest/Mixer.pm

  • Committer: Package Import Robot
  • Author(s): Tobias Frost
  • Date: 2013-08-22 20:18:31 UTC
  • mto: (20.1.1 sid)
  • mto: This revision was merged to the branch mainline in revision 21.
  • Revision ID: package-import@ubuntu.com-20130822201831-gn3ozsh7o7wmc5tk
Tags: upstream-7.2.3
ImportĀ upstreamĀ versionĀ 7.2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (c) 2008,2011 Oracle and/or its affiliates. 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
 
package GenTest::Mixer;
19
 
 
20
 
require Exporter;
21
 
@ISA = qw(GenTest);
22
 
 
23
 
use strict;
24
 
use Data::Dumper;
25
 
use GenTest;
26
 
use GenTest::Constants;
27
 
use GenTest::Result;
28
 
use GenTest::Validator;
29
 
 
30
 
use constant MIXER_GENERATOR    => 0;
31
 
use constant MIXER_EXECUTORS    => 1;
32
 
use constant MIXER_VALIDATORS   => 2;
33
 
use constant MIXER_FILTERS      => 3;
34
 
use constant MIXER_PROPERTIES   => 4;
35
 
 
36
 
my %rule_status;
37
 
 
38
 
1;
39
 
 
40
 
sub new {
41
 
        my $class = shift;
42
 
 
43
 
        my $mixer = $class->SUPER::new({
44
 
                'generator'     => MIXER_GENERATOR,
45
 
                'executors'     => MIXER_EXECUTORS,
46
 
                'validators'    => MIXER_VALIDATORS,
47
 
                'properties'    => MIXER_PROPERTIES,
48
 
                'filters'       => MIXER_FILTERS
49
 
        }, @_);
50
 
 
51
 
        foreach my $executor (@{$mixer->executors()}) {
52
 
                my $init_result = $executor->init();
53
 
                return undef if $init_result > STATUS_OK;
54
 
                $executor->cacheMetaData();
55
 
        }
56
 
 
57
 
        my @validators = @{$mixer->validators()};
58
 
        my %validators;
59
 
 
60
 
        # If a Validator was specified by name, load the class and create an object.
61
 
 
62
 
        foreach my $i (0..$#validators) {
63
 
                my $validator = $validators[$i];
64
 
                if (ref($validator) eq '') {
65
 
                        $validator = "GenTest::Validator::".$validator;
66
 
                        say("Loading Validator $validator.");
67
 
                        eval "use $validator" or print $@;
68
 
                        $validators[$i] = $validator->new();
69
 
            
70
 
            $validators[$i]->configure($mixer->properties);
71
 
                }
72
 
                $validators{ref($validators[$i])}++;
73
 
        }
74
 
 
75
 
        # Query every object for its prerequisies. If one is not loaded, load it and place it
76
 
        # in front of the Validators array.
77
 
 
78
 
        my @prerequisites;
79
 
        foreach my $validator (@validators) {
80
 
                my $prerequisites = $validator->prerequsites();
81
 
                next if not defined $prerequisites;
82
 
                foreach my $prerequisite (@$prerequisites) {
83
 
                        next if exists $validators{$prerequisite};
84
 
                        $prerequisite = "GenTest::Validator::".$prerequisite;
85
 
#                       say("Loading Prerequisite $prerequisite, required by $validator.");
86
 
                        eval "use $prerequisite" or print $@;
87
 
                        push @prerequisites, $prerequisite->new();
88
 
                }
89
 
        }
90
 
 
91
 
        my @validators = (@prerequisites, @validators);
92
 
        $mixer->setValidators(\@validators);
93
 
 
94
 
        foreach my $validator (@validators) {
95
 
                return undef if not defined $validator->init($mixer->executors());
96
 
        }
97
 
 
98
 
        return $mixer;
99
 
}
100
 
 
101
 
sub next {
102
 
        my $mixer = shift;
103
 
 
104
 
        my $executors = $mixer->executors();
105
 
        my $filters = $mixer->filters();
106
 
 
107
 
        my $queries = $mixer->generator()->next($executors);
108
 
        if (not defined $queries) {
109
 
                say("Internal grammar problem. Terminating.");
110
 
                return STATUS_ENVIRONMENT_FAILURE;
111
 
        } elsif ($queries->[0] eq '') {
112
 
#               say("Your grammar generated an empty query.");
113
 
#               return STATUS_ENVIRONMENT_FAILURE;
114
 
        }
115
 
 
116
 
        my $max_status = STATUS_OK;
117
 
 
118
 
        query: foreach my $query (@$queries) {
119
 
                next if $query =~ m{^\s*$}o;
120
 
 
121
 
                if (defined $filters) {
122
 
                        foreach my $filter (@$filters) {
123
 
                                my $explain = Dumper $executors->[0]->execute("EXPLAIN $query") if $query =~ m{^\s*SELECT}sio;
124
 
                                my $filter_result = $filter->filter($query." ".$explain);
125
 
                                next query if $filter_result == STATUS_SKIP;
126
 
                        }
127
 
                }
128
 
 
129
 
                my @execution_results;
130
 
                foreach my $executor (@$executors) {
131
 
                        my $execution_result = $executor->execute($query);
132
 
                        $max_status = $execution_result->status() if $execution_result->status() > $max_status;
133
 
                        push @execution_results, $execution_result;
134
 
                        
135
 
                        # If one server has crashed, do not send the query to the second one in order to preserve consistency
136
 
                        if ($execution_result->status() == STATUS_SERVER_CRASHED) {
137
 
                                say("Server crash reported at dsn ".$executor->dsn());
138
 
                                last;
139
 
                        }
140
 
                }
141
 
                
142
 
                foreach my $validator (@{$mixer->validators()}) {
143
 
                        my $validation_result = $validator->validate($executors, \@execution_results);
144
 
                        $max_status = $validation_result if ($validation_result != STATUS_WONT_HANDLE) && ($validation_result > $max_status);
145
 
                }
146
 
        }
147
 
 
148
 
        #
149
 
        # Record the lowest (best) status achieved for all participating rules. The goal
150
 
        # is for all rules to generate at least some STATUS_OK queries. If not, the offending
151
 
        # rules will be reported on DESTROY.
152
 
        #
153
 
 
154
 
        if ((rqg_debug()) && (ref($mixer->generator()) eq 'GenTest::Generator::FromGrammar')) {
155
 
                my $participating_rules = $mixer->generator()->participatingRules();
156
 
                foreach my $participating_rule (@$participating_rules) {
157
 
                        if (
158
 
                                (not exists $rule_status{$participating_rule}) ||
159
 
                                ($rule_status{$participating_rule} > $max_status)
160
 
                        ) {
161
 
                                $rule_status{$participating_rule} = $max_status
162
 
                        }
163
 
                }
164
 
        }
165
 
 
166
 
        return $max_status;
167
 
}
168
 
 
169
 
sub DESTROY {
170
 
        my @rule_failures;
171
 
 
172
 
        foreach my $rule (keys %rule_status) {
173
 
                push @rule_failures, "$rule (".status2text($rule_status{$rule}).")" if $rule_status{$rule} > STATUS_OK;
174
 
        }
175
 
 
176
 
        if ($#rule_failures > -1) {
177
 
                say("The following rules produced no STATUS_OK queries: ".join(', ', @rule_failures));
178
 
        }
179
 
}
180
 
 
181
 
sub generator {
182
 
        return $_[0]->[MIXER_GENERATOR];
183
 
}
184
 
 
185
 
sub executors {
186
 
        return $_[0]->[MIXER_EXECUTORS];
187
 
}
188
 
 
189
 
sub validators {
190
 
        return $_[0]->[MIXER_VALIDATORS];
191
 
}
192
 
 
193
 
sub properties {
194
 
        return $_[0]->[MIXER_PROPERTIES];
195
 
}
196
 
 
197
 
sub filters {
198
 
        return $_[0]->[MIXER_FILTERS];
199
 
}
200
 
 
201
 
sub setValidators {
202
 
        $_[0]->[MIXER_VALIDATORS] = $_[1];
203
 
}
204
 
 
205
 
1;