2
# -*- mode: python; indent-tabs-mode: nil; -*-
3
# vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
5
# Copyright (C) 2010 Patrick Crews
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.
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.
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
22
""" sysbench_test_execution:
23
code related to the execution of sysbench test cases
25
We are provided access to a testManager with
26
sysbench-specific testCases.
37
import lib.test_mgmt.test_execution as test_execution
39
class testExecutor(test_execution.testExecutor):
40
""" sysbench-specific testExecutor
44
def execute_testCase (self):
45
""" Execute a sysbench testCase
48
test_execution.testExecutor.execute_testCase(self)
51
# prepare the server for sysbench
52
self.prepare_sysbench()
55
self.execute_sysbench()
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)
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
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
self.logging.debug(sysbench_cmd)
73
sysbench_subproc = subprocess.Popen( sysbench_cmd
76
, env=self.working_environment
77
, stdout = sysbench_output
78
, stderr = subprocess.STDOUT
80
sysbench_subproc.wait()
81
retcode = sysbench_subproc.returncode
83
sysbench_output.close()
84
sysbench_file = open(sysbench_outfile,'r')
85
output = ''.join(sysbench_file.readlines())
87
self.logging.debug("sysbench_retcode: %d" %(retcode))
88
self.logging.debug(output)
90
self.logging.error("sysbench_prepare failed with retcode %d:" %(retcode))
91
self.logging.error(output)
97
def execute_sysbench(self):
98
""" Execute the commandline and return the result.
99
We use subprocess as we can pass os.environ dicts and whatnot
103
testcase_name = self.current_testcase.fullname
104
self.time_manager.start(testcase_name,'test')
105
sysbench_outfile = os.path.join(self.logdir,'sysbench.out')
106
sysbench_output = open(sysbench_outfile,'w')
107
sysbench_cmd = ' '.join([self.current_testcase.test_command, 'run'])
108
self.logging.info("Executing sysbench: %s" %(sysbench_cmd))
110
sysbench_subproc = subprocess.Popen( sysbench_cmd
112
#, cwd=self.system_manager.sysbench_path
113
, env=self.working_environment
114
, stdout = sysbench_output
115
, stderr = subprocess.STDOUT
117
sysbench_subproc.wait()
118
retcode = sysbench_subproc.returncode
119
execution_time = int(self.time_manager.stop(testcase_name)*1000) # millisec
121
sysbench_output.close()
122
sysbench_file = open(sysbench_outfile,'r')
123
output = ''.join(sysbench_file.readlines())
124
self.logging.debug(output)
125
sysbench_file.close()
127
self.logging.debug("sysbench_retcode: %d" %(retcode))
128
self.current_test_retcode = retcode
129
self.current_test_output = output
130
self.current_test_exec_time = execution_time
132
def process_sysbench_output(self):
133
""" sysbench has run, we now check out what we have
134
We also output the data from the run
137
# This slice code taken from drizzle-automation's sysbench handling
138
# Slice up the output report into a matrix and insert into the DB.
140
'tps': re.compile(r".*transactions\:\s+\d+\D*(\d+\.\d+).*")
141
, 'deadlocksps': re.compile(r".*deadlocks\:\s+\d+\D*(\d+\.\d+).*")
142
, 'rwreqps': re.compile(r".*read\/write\s+requests\:\s+\d+\D*(\d+\.\d+).*")
143
, 'min_req_lat_ms': re.compile(r".*min\:\s+(\d*\.\d+)ms.*")
144
, 'max_req_lat_ms': re.compile(r".*max\:\s+(\d*\.\d+)ms.*")
145
, 'avg_req_lat_ms': re.compile(r".*avg\:\s+(\d*\.\d+)ms.*")
146
, '95p_req_lat_ms': re.compile(r".*approx.\s+95\s+percentile\:\s+(\d+\.\d+)ms.*")
149
for line in self.current_test_output.split("\n"):
150
for key in regexes.keys():
151
result= regexes[key].match(line)
153
run[key]= float(result.group(1)) # group(0) is entire match...
154
# we set our test output to the regex'd-up data
155
# we also make it a single string, separated by newlines
156
self.current_test_output = str(run)[1:-1].replace(',','\n').replace("'",'')
158
if self.current_test_retcode == 0: