~linuxjedi/drizzle/trunk-bug-743902

« back to all changes in this revision

Viewing changes to tests/lib/sqlbench/sqlbench_test_execution.py

  • Committer: Andrew Hutchings
  • Date: 2011-06-13 17:29:43 UTC
  • mfrom: (2281.3.50 drizzle)
  • Revision ID: andrew@linuxjedi.co.uk-20110613172943-y3gig2cyg4p2a0tq
Merge with trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#! /usr/bin/env python
 
2
# -*- mode: python; indent-tabs-mode: nil; -*-
 
3
# vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
 
4
#
 
5
# Copyright (C) 2011 Patrick Crews
 
6
#
 
7
#
 
8
# This program is free software; you can redistribute it and/or modify
 
9
# it under the terms of the GNU General Public License as published by
 
10
# the Free Software Foundation; either version 2 of the License, or
 
11
# (at your option) any later version.
 
12
#
 
13
# This program is distributed in the hope that it will be useful,
 
14
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
# GNU General Public License for more details.
 
17
#
 
18
# You should have received a copy of the GNU General Public License
 
19
# along with this program; if not, write to the Free Software
 
20
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
21
 
 
22
""" sqlbench_test_execution:
 
23
    code related to the execution of sqlbench test cases 
 
24
    
 
25
    We are provided access to a testManager with 
 
26
    sqlbench-specific testCases.  
 
27
 
 
28
"""
 
29
 
 
30
# imports
 
31
import os
 
32
import re
 
33
import sys
 
34
import subprocess
 
35
import commands
 
36
 
 
37
import lib.test_mgmt.test_execution as test_execution
 
38
 
 
39
 
 
40
 
 
41
class sqlbenchTestExecutor(test_execution.testExecutor):
 
42
    """ sqlbench-specific testExecutor 
 
43
        
 
44
    """
 
45
  
 
46
    def execute_testCase (self):
 
47
        """ Execute a sqlbench testCase
 
48
 
 
49
        """
 
50
        test_execution.testExecutor.execute_testCase(self)
 
51
        self.status = 0
 
52
 
 
53
        # execute sqlbench
 
54
        self.execute_sqlbench()
 
55
 
 
56
        # analyze results
 
57
        self.current_test_status = self.process_sqlbench_output()
 
58
        self.set_server_status(self.current_test_status)
 
59
        self.server_manager.reset_servers(self.name)
 
60
 
 
61
    def execute_sqlbench(self):
 
62
        """ Execute the commandline and return the result.
 
63
            We use subprocess as we can pass os.environ dicts and whatnot 
 
64
 
 
65
        """
 
66
      
 
67
        testcase_name = self.current_testcase.fullname
 
68
        self.time_manager.start(testcase_name,'test')
 
69
        sqlbench_outfile = os.path.join(self.logdir,'sqlbench.out')
 
70
        sqlbench_output = open(sqlbench_outfile,'w')
 
71
        sqlbench_cmd = self.current_testcase.test_command
 
72
        self.logging.info("Executing sqlbench:  %s" %(sqlbench_cmd))
 
73
        
 
74
        sqlbench_subproc = subprocess.Popen( sqlbench_cmd
 
75
                                         , shell=True
 
76
                                         , cwd=os.path.join(self.system_manager.testdir, 'sql-bench')
 
77
                                         , env=self.working_environment
 
78
                                         , stdout = sqlbench_output
 
79
                                         , stderr = subprocess.STDOUT
 
80
                                         )
 
81
        sqlbench_subproc.wait()
 
82
        retcode = sqlbench_subproc.returncode     
 
83
        execution_time = int(self.time_manager.stop(testcase_name)*1000) # millisec
 
84
 
 
85
        sqlbench_output.close()
 
86
        sqlbench_file = open(sqlbench_outfile,'r')
 
87
        output = ''.join(sqlbench_file.readlines())
 
88
        if self.debug:
 
89
            self.logging.debug(output)
 
90
        sqlbench_file.close()
 
91
 
 
92
        if self.debug:
 
93
            self.logging.debug("sqlbench_retcode: %d" %(retcode))
 
94
        self.current_test_retcode = retcode
 
95
        self.current_test_output = output
 
96
        self.current_test_exec_time = execution_time
 
97
 
 
98
    def process_sqlbench_output(self):
 
99
        
 
100
        # Check for 'Failed' in sql-bench output
 
101
        # The tests don't die on a failed test and
 
102
        # require some checking of the output file
 
103
        infile_name = self.current_test_output.split('\n')[1].strip()
 
104
        inf= open(infile_name, "r")
 
105
        inlines= inf.readlines()
 
106
        error_flag= False
 
107
        for inline in inlines:
 
108
            if 'Failed' in inline:
 
109
                error_flag= True
 
110
                logging.info(inline.strip())
 
111
        inf.close()                    
 
112
        self.current_test_output += ''.join(inlines)
 
113
        if self.current_test_retcode == 0 and not error_flag:
 
114
            return 'pass'
 
115
        else:
 
116
            return 'fail'
 
117
 
 
118
    def handle_system_reqs(self):
 
119
        """ We check our test case and see what we need to do
 
120
            system-wise to get ready.  This is likely to be 
 
121
            mode-dependent and this is just a placeholder
 
122
            method
 
123
 
 
124
        """
 
125
 
 
126
        self.process_environment_reqs()
 
127
        self.process_symlink_reqs()
 
128
        self.process_master_sh()  
 
129
        return
 
130
 
 
131
    def process_master_sh(self):
 
132
        """ We do what we need to if we have a master.sh file """
 
133
        if self.current_testcase.master_sh:
 
134
            retcode, output = self.system_manager.execute_cmd("/bin/sh %s" %(self.current_testcase.master_sh))
 
135
            if self.debug:
 
136
                self.logging.info("retcode: %retcode")
 
137
                self.logging.info("%output")
 
138
 
 
139
    def process_environment_reqs(self):
 
140
        """ We generate the ENV vars we need set
 
141
            and then ask systemManager to do so
 
142
 
 
143
        """
 
144
        env_reqs = {  'DRIZZLETEST_VARDIR': self.master_server.vardir
 
145
                   ,  'DRIZZLE_TMP_DIR': self.master_server.tmpdir
 
146
                   ,  'MASTER_MYSOCK': self.master_server.socket_file
 
147
                   ,  'MASTER_MYPORT': str(self.master_server.master_port)
 
148
                   ,  'MC_PORT': str(self.master_server.mc_port)
 
149
                   ,  'PBMS_PORT': str(self.master_server.pbms_port)
 
150
                   ,  'RABBITMQ_NODE_PORT': str(self.master_server.rabbitmq_node_port)
 
151
                   ,  'DRIZZLE_TCP_PORT': str(self.master_server.drizzle_tcp_port)
 
152
                   ,  'EXE_DRIZZLE': self.master_server.drizzle_client
 
153
                   ,  'MASTER_SERVER_SLAVE_CONFIG' : self.master_server.slave_config_file
 
154
                   ,  'DRIZZLE_DUMP': "%s --no-defaults -uroot -p%d" %( self.master_server.drizzledump
 
155
                                                        , self.master_server.master_port)
 
156
                   ,  'DRIZZLE_SLAP': "%s -uroot -p%d" %( self.master_server.drizzleslap
 
157
                                                        , self.master_server.master_port)
 
158
                   ,  'DRIZZLE_IMPORT': "%s -uroot -p%d" %( self.master_server.drizzleimport
 
159
                                                          , self.master_server.master_port)
 
160
                   ,  'DRIZZLE': "%s -uroot -p%d" %( self.master_server.drizzle_client
 
161
                                                   , self.master_server.master_port)
 
162
                   ,  'DRIZZLE_BASEDIR' : self.system_manager.code_tree.basedir
 
163
                   ,  'DRIZZLE_TRX_READER' : self.system_manager.code_tree.drizzle_trx_reader
 
164
                   ,  'DRIZZLE_TEST_WORKDIR' : self.system_manager.workdir
 
165
                   }     
 
166
 
 
167
 
 
168
        self.working_environment = self.system_manager.create_working_environment(env_reqs)
 
169
 
 
170
 
 
171
    def process_symlink_reqs(self):
 
172
        """ Create any symlinks we may need """
 
173
        needed_symlinks = []
 
174
 
 
175
        self.system_manager.create_symlinks(needed_symlinks)
 
176
 
 
177
    
 
178
class crashmeTestExecutor(sqlbenchTestExecutor):
 
179
    """ crashme-specific variant of sqlbench executor """
 
180
 
 
181
    def execute_testCase (self):
 
182
        """ Execute a crashme testCase
 
183
 
 
184
        """
 
185
        test_execution.testExecutor.execute_testCase(self)
 
186
        self.status = 0
 
187
 
 
188
        self.prepare_config()
 
189
 
 
190
        # execute sqlbench
 
191
        self.execute_crashme()
 
192
 
 
193
        # analyze results
 
194
        self.current_test_status = self.process_crashme_output()
 
195
        self.set_server_status(self.current_test_status)
 
196
        self.server_manager.reset_servers(self.name)
 
197
 
 
198
    def prepare_config(self):
 
199
        """ Create the config file crash-me needs to execute """
 
200
 
 
201
        output_filename= "%s/drizzle.cfg" % (self.system_manager.workdir)
 
202
 
 
203
        # remove the existing configuration file to start fresh
 
204
        if os.path.exists(output_filename):
 
205
            logging.info("Removing %s" % output_filename)
 
206
            os.remove(output_filename)
 
207
  
 
208
        output_file= open(output_filename,"w")
 
209
        # don't support '+' for concatenation
 
210
        output_file.writelines("func_extra_concat_as_+=no\n")
 
211
        # new boost libraries are causing us to put these limits in, needs investigation
 
212
        output_file.writelines("max_text_size=1048576\n")
 
213
        output_file.writelines("where_string_size=1048576\n")
 
214
        output_file.writelines("select_string_size=1048576\n")
 
215
        output_file.flush()
 
216
        output_file.close()
 
217
 
 
218
    def execute_crashme(self):
 
219
        """ Execute the commandline and return the result.
 
220
            We use subprocess as we can pass os.environ dicts and whatnot 
 
221
 
 
222
        """
 
223
 
 
224
        output_filename= "%s/drizzle.cfg" % (self.system_manager.workdir)      
 
225
        testcase_name = self.current_testcase.fullname
 
226
        self.time_manager.start(testcase_name,'test')
 
227
        crashme_outfile = os.path.join(self.logdir,'crashme.out')
 
228
        crashme_output = open(crashme_outfile,'w')
 
229
        crashme_cmd = self.current_testcase.test_command + " --config-file=%s" %(output_filename)
 
230
        self.logging.info("Executing crash-me:  %s" %(crashme_cmd))
 
231
        
 
232
        crashme_subproc = subprocess.Popen( crashme_cmd
 
233
                                         , shell=True
 
234
                                         , cwd=os.path.join(self.system_manager.testdir, 'sql-bench')
 
235
                                         , env=self.working_environment
 
236
                                         , stdout = crashme_output
 
237
                                         , stderr = subprocess.STDOUT
 
238
                                         )
 
239
        crashme_subproc.wait()
 
240
        retcode = crashme_subproc.returncode     
 
241
        execution_time = int(self.time_manager.stop(testcase_name)*1000) # millisec
 
242
 
 
243
        crashme_output.close()
 
244
        crashme_file = open(crashme_outfile,'r')
 
245
        output = ''.join(crashme_file.readlines())
 
246
        if self.debug:
 
247
            self.logging.debug(output)
 
248
        crashme_file.close()
 
249
 
 
250
        if self.debug:
 
251
            self.logging.debug("crashme_retcode: %d" %(retcode))
 
252
        self.current_test_retcode = retcode
 
253
        self.current_test_output = output
 
254
        self.current_test_exec_time = execution_time
 
255
 
 
256
    def process_crashme_output(self):
 
257
        infile_name = self.current_test_output.split('\n')[3].split(':')[1].strip()
 
258
        inf= open(infile_name, "r")
 
259
        inlines= inf.readlines()
 
260
        error_flag= False
 
261
        in_error_section = False
 
262
        # crash-me is quite chatty and we don't normally want to sift
 
263
        # through ALL of that stuff.  We do allow seeing it via --verbose
 
264
        if not self.verbose:
 
265
            self.current_test_output = ''
 
266
        for inline in inlines:
 
267
            if in_error_section and not inline.strip().startswith('#'):
 
268
                in_error_section = False
 
269
            if '=error' in inline:
 
270
                error_flag= True
 
271
                in_error_section= True
 
272
            if in_error_section:
 
273
                self.current_test_output += inline
 
274
        inf.close()                
 
275
        if self.current_test_retcode == 0 and not error_flag:
 
276
            return 'pass'
 
277
        else:
 
278
            return 'fail'
 
279
 
 
280