~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to tests/lib/sysbench/sysbench_test_execution.py

  • Committer: patrick crews
  • Date: 2011-06-01 23:31:52 UTC
  • mto: This revision was merged to the branch mainline in revision 2322.
  • Revision ID: gleebix@gmail.com-20110601233152-7kwbqhr4xujq9hsu
Updates to dbqp to add a sysbench mode.  Created test suites to duplicate readonly / readwrite drizzle-automation tests.  Still needs some work, but tests execute

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) 2010 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
""" sysbench_test_execution:
 
23
    code related to the execution of sysbench test cases 
 
24
    
 
25
    We are provided access to a testManager with 
 
26
    sysbench-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
class sysbenchTestExecutor(test_execution.testExecutor):
 
40
    """ sysbench-specific testExecutor 
 
41
        
 
42
    """
 
43
  
 
44
    def execute_testCase (self):
 
45
        """ Execute a sysbench testCase
 
46
 
 
47
        """
 
48
        test_execution.testExecutor.execute_testCase(self)
 
49
        self.status = 0
 
50
 
 
51
        # prepare the server for sysbench
 
52
        self.prepare_sysbench()
 
53
 
 
54
        # execute sysbench
 
55
        self.execute_sysbench()
 
56
 
 
57
        # analyze results
 
58
        self.current_test_status = self.process_sysbench_output()
 
59
        self.set_server_status(self.current_test_status)
 
60
        self.server_manager.reset_servers(self.name)
 
61
 
 
62
    def prepare_sysbench(self):
 
63
        """ Prepare the server for a sysbench run
 
64
            We use subprocess as we can pass os.environ dicts and whatnot 
 
65
 
 
66
        """
 
67
      
 
68
        sysbench_outfile = os.path.join(self.logdir,'sysbench.out')
 
69
        sysbench_output = open(sysbench_outfile,'w')
 
70
        sysbench_cmd = ' '.join([self.current_testcase.test_command,'prepare'])      
 
71
        self.logging.info("Preparing database for sysbench run...")
 
72
        if self.debug:
 
73
            self.logging.debug(sysbench_cmd)
 
74
        sysbench_subproc = subprocess.Popen( sysbench_cmd
 
75
                                         , shell=True
 
76
                                         #, cwd=os.getcwd()
 
77
                                         , env=self.working_environment
 
78
                                         , stdout = sysbench_output
 
79
                                         , stderr = subprocess.STDOUT
 
80
                                         )
 
81
        sysbench_subproc.wait()
 
82
        retcode = sysbench_subproc.returncode
 
83
 
 
84
        sysbench_output.close()
 
85
        sysbench_file = open(sysbench_outfile,'r')
 
86
        output = ''.join(sysbench_file.readlines())
 
87
        sysbench_file.close()
 
88
        if self.debug:
 
89
            self.logging.debug("sysbench_retcode: %d" %(retcode))
 
90
            self.logging.debug(output)
 
91
        if retcode:
 
92
            self.logging.error("sysbench_prepare failed with retcode %d:" %(retcode))
 
93
            self.logging.error(output)   
 
94
            sys.exit(1)
 
95
            
 
96
 
 
97
    
 
98
 
 
99
    def execute_sysbench(self):
 
100
        """ Execute the commandline and return the result.
 
101
            We use subprocess as we can pass os.environ dicts and whatnot 
 
102
 
 
103
        """
 
104
      
 
105
        testcase_name = self.current_testcase.fullname
 
106
        self.time_manager.start(testcase_name,'test')
 
107
        sysbench_outfile = os.path.join(self.logdir,'sysbench.out')
 
108
        sysbench_output = open(sysbench_outfile,'w')
 
109
        sysbench_cmd = ' '.join([self.current_testcase.test_command, 'run'])
 
110
        self.logging.info("Executing sysbench:  %s" %(sysbench_cmd))
 
111
        
 
112
        sysbench_subproc = subprocess.Popen( sysbench_cmd
 
113
                                         , shell=True
 
114
                                         #, cwd=self.system_manager.sysbench_path
 
115
                                         , env=self.working_environment
 
116
                                         , stdout = sysbench_output
 
117
                                         , stderr = subprocess.STDOUT
 
118
                                         )
 
119
        sysbench_subproc.wait()
 
120
        retcode = sysbench_subproc.returncode     
 
121
        execution_time = int(self.time_manager.stop(testcase_name)*1000) # millisec
 
122
 
 
123
        sysbench_output.close()
 
124
        sysbench_file = open(sysbench_outfile,'r')
 
125
        output = ''.join(sysbench_file.readlines())
 
126
        if self.debug:
 
127
            self.logging.debug(output)
 
128
        sysbench_file.close()
 
129
 
 
130
        if self.debug:
 
131
            self.logging.debug("sysbench_retcode: %d" %(retcode))
 
132
        self.current_test_retcode = retcode
 
133
        self.current_test_output = output
 
134
        self.current_test_exec_time = execution_time
 
135
 
 
136
    def process_sysbench_output(self):
 
137
        """ sysbench has run, we now check out what we have 
 
138
            We also output the data from the run
 
139
        
 
140
        """
 
141
        # This slice code taken from drizzle-automation's sysbench handling
 
142
        # Slice up the output report into a matrix and insert into the DB.
 
143
        regexes= {
 
144
          'tps': re.compile(r".*transactions\:\s+\d+\D*(\d+\.\d+).*")
 
145
        , 'deadlocksps': re.compile(r".*deadlocks\:\s+\d+\D*(\d+\.\d+).*")
 
146
        , 'rwreqps': re.compile(r".*read\/write\s+requests\:\s+\d+\D*(\d+\.\d+).*")
 
147
        , 'min_req_lat_ms': re.compile(r".*min\:\s+(\d*\.\d+)ms.*")
 
148
        , 'max_req_lat_ms': re.compile(r".*max\:\s+(\d*\.\d+)ms.*")
 
149
        , 'avg_req_lat_ms': re.compile(r".*avg\:\s+(\d*\.\d+)ms.*")
 
150
        , '95p_req_lat_ms': re.compile(r".*approx.\s+95\s+percentile\:\s+(\d+\.\d+)ms.*")
 
151
        }
 
152
        run= {}
 
153
        for line in self.current_test_output.split("\n"):
 
154
            for key in regexes.keys():
 
155
                result= regexes[key].match(line)
 
156
                if result:
 
157
                    run[key]= float(result.group(1)) # group(0) is entire match...
 
158
        # we set our test output to the regex'd-up data
 
159
        # we also make it a single string, separated by newlines
 
160
        self.current_test_output = str(run)[1:-1].replace(',','\n').replace("'",'')
 
161
                    
 
162
        if self.current_test_retcode == 0:
 
163
            return 'pass'
 
164
        else:
 
165
            return 'fail'
 
166
 
 
167
    def handle_system_reqs(self):
 
168
        """ We check our test case and see what we need to do
 
169
            system-wise to get ready.  This is likely to be 
 
170
            mode-dependent and this is just a placeholder
 
171
            method
 
172
 
 
173
        """
 
174
 
 
175
        self.process_environment_reqs()
 
176
        self.process_symlink_reqs()
 
177
        self.process_master_sh()  
 
178
        return
 
179
 
 
180
    def process_master_sh(self):
 
181
        """ We do what we need to if we have a master.sh file """
 
182
        if self.current_testcase.master_sh:
 
183
            retcode, output = self.system_manager.execute_cmd("/bin/sh %s" %(self.current_testcase.master_sh))
 
184
            if self.debug:
 
185
                self.logging.info("retcode: %retcode")
 
186
                self.logging.info("%output")
 
187
 
 
188
    def process_environment_reqs(self):
 
189
        """ We generate the ENV vars we need set
 
190
            and then ask systemManager to do so
 
191
 
 
192
        """
 
193
        env_reqs = {  'DRIZZLETEST_VARDIR': self.master_server.vardir
 
194
                   ,  'DRIZZLE_TMP_DIR': self.master_server.tmpdir
 
195
                   ,  'MASTER_MYSOCK': self.master_server.socket_file
 
196
                   ,  'MASTER_MYPORT': str(self.master_server.master_port)
 
197
                   ,  'MC_PORT': str(self.master_server.mc_port)
 
198
                   ,  'PBMS_PORT': str(self.master_server.pbms_port)
 
199
                   ,  'RABBITMQ_NODE_PORT': str(self.master_server.rabbitmq_node_port)
 
200
                   ,  'DRIZZLE_TCP_PORT': str(self.master_server.drizzle_tcp_port)
 
201
                   ,  'EXE_DRIZZLE': self.master_server.drizzle_client
 
202
                   ,  'MASTER_SERVER_SLAVE_CONFIG' : self.master_server.slave_config_file
 
203
                   ,  'DRIZZLE_DUMP': "%s --no-defaults -uroot -p%d" %( self.master_server.drizzledump
 
204
                                                        , self.master_server.master_port)
 
205
                   ,  'DRIZZLE_SLAP': "%s -uroot -p%d" %( self.master_server.drizzleslap
 
206
                                                        , self.master_server.master_port)
 
207
                   ,  'DRIZZLE_IMPORT': "%s -uroot -p%d" %( self.master_server.drizzleimport
 
208
                                                          , self.master_server.master_port)
 
209
                   ,  'DRIZZLE': "%s -uroot -p%d" %( self.master_server.drizzle_client
 
210
                                                   , self.master_server.master_port)
 
211
                   ,  'DRIZZLE_ADMIN' : "%s -uroot -p%d" %( self.master_server.drizzleadmin
 
212
                                                         , self.master_server.master_port)
 
213
                   ,  'DRIZZLE_BASEDIR' : self.system_manager.code_tree.basedir
 
214
                   ,  'DRIZZLE_TRX_READER' : self.system_manager.code_tree.drizzle_trx_reader
 
215
                   }     
 
216
 
 
217
 
 
218
        self.working_environment = self.system_manager.create_working_environment(env_reqs)
 
219
 
 
220
 
 
221
    def process_symlink_reqs(self):
 
222
        """ Create any symlinks we may need """
 
223
        needed_symlinks = []
 
224
 
 
225
        self.system_manager.create_symlinks(needed_symlinks)
 
226
 
 
227
    
 
228
   
 
229
 
 
230