Merge lp:~patrick-crews/percona-server/51-qp-updates into lp:percona-server/5.1

Proposed by Patrick Crews
Status: Merged
Approved by: Stewart Smith
Approved revision: no longer in the source branch.
Merged at revision: 413
Proposed branch: lp:~patrick-crews/percona-server/51-qp-updates
Merge into: lp:percona-server/5.1
Diff against target: 2092 lines (+1327/-472)
20 files modified
Makefile (+10/-8)
kewpie/kewpie.py (+24/-5)
kewpie/lib/modes/native/native_test_management.py (+23/-8)
kewpie/lib/opts/test_run_options.py (+445/-432)
kewpie/lib/server_mgmt/drizzled.py (+9/-1)
kewpie/lib/server_mgmt/galera.py (+9/-0)
kewpie/lib/server_mgmt/mysqld.py (+134/-14)
kewpie/lib/server_mgmt/percona.py (+8/-0)
kewpie/lib/sys_mgmt/system_management.py (+10/-3)
kewpie/percona_tests/crashme/crashme_test.py (+1/-1)
kewpie/percona_tests/innodbCrash/crashCommitAfterLog_test.py (+60/-0)
kewpie/percona_tests/innodbCrash/crashCommitAfterPrepare_test.py (+62/-0)
kewpie/percona_tests/innodbCrash/crashCommitAfter_test.py (+59/-0)
kewpie/percona_tests/innodbCrash/crashCommitBeforeUnlog_test.py (+59/-0)
kewpie/percona_tests/innodbCrash/crashCommitBefore_test.py (+59/-0)
kewpie/percona_tests/innodbCrash/halfBinloggedTrx_test.py (+59/-0)
kewpie/percona_tests/innodbCrash/innodbCrash2_test.py (+140/-0)
kewpie/percona_tests/innodbCrash/innodbCrash3_test.py (+58/-0)
kewpie/percona_tests/innodbCrash/innodbCrashTestCase.py (+69/-0)
kewpie/percona_tests/innodbCrash/suite_config.py (+29/-0)
To merge this branch: bzr merge lp:~patrick-crews/percona-server/51-qp-updates
Reviewer Review Type Date Requested Status
Stewart Smith (community) Approve
Review via email: mp+85589@code.launchpad.net

Description of the change

Updates kewpie to fix issues with crash-me: https://bugs.launchpad.net/kewpie/+bug/901182
We now use --batch-mode so the crash-me run will die / fail on the first problem. I made attempts to interact with the subprocess input / output, but it was problematic...this is a quick, immediate fix : )

Also merges in innodbCrash suite (needs debug build as that is how we control a number of crashes) and various other updates like --test-debug and --randgen-seed options.

To post a comment you must log in.
Revision history for this message
Stewart Smith (stewart) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Makefile'
2--- Makefile 2011-12-05 23:11:20 +0000
3+++ Makefile 2011-12-23 00:55:24 +0000
4@@ -48,30 +48,32 @@
5 clean:
6 rm -rf $(PERCONA_SERVER) $(PERCONA_SERVER_SHORT_1)
7
8-test-qp-crashme:
9+test-crashme:
10 cd $(KEWPIE) && ./kewpie.py --suite=crashme --basedir=$(BASEDIR)/$(PERCONA_SERVER_SHORT_2)
11
12-test-qp-sqlbench:
13+test-sqlbench:
14 cd $(KEWPIE) && ./kewpie.py --suite=sqlbench --basedir=$(BASEDIR)/$(PERCONA_SERVER_SHORT_2)
15
16-test-qp-randgen:
17+test-randgen:
18 cd $(KEWPIE) && ./kewpie.py --suite=randgen_basic --basedir=$(BASEDIR)/$(PERCONA_SERVER_SHORT_2)
19
20-test-qp-randgen-bugs:
21+test-randgen-bugs:
22 cd $(KEWPIE) && ./kewpie.py --suite=randgen_bugs --basedir=$(BASEDIR)/$(PERCONA_SERVER_SHORT_2)
23
24-test-qp-cluster:
25+test-cluster:
26 cd $(KEWPIE) && ./kewpie.py --suite=cluster_basic,cluster_randgen --basedir=$(BASEDIR)/$(PERCONA_SERVER_SHORT_2)
27
28-test-qp-cluster-basic:
29+test-cluster-basic:
30 cd $(KEWPIE) && ./kewpie.py --suite=cluster_basic --basedir=$(BASEDIR)/$(PERCONA_SERVER_SHORT_2)
31
32-test-qp-cluster-randgen:
33+test-cluster-randgen:
34 cd $(KEWPIE) && ./kewpie.py --suite=cluster_randgen --basedir=$(BASEDIR)/$(PERCONA_SERVER_SHORT_2)
35
36-test-qp-cluster-bugs:
37+test-cluster-bugs:
38 cd $(KEWPIE) && ./kewpie.py --suite=cluster_bugs --basedir=$(BASEDIR)/$(PERCONA_SERVER_SHORT_2)
39
40+test-innodb-crash:
41+ cd $(KEWPIE) && ./kewpie.py --suite=innodbCrash --basedir=$(BASEDIR)/$(PERCONA_SERVER_SHORT_2)
42
43
44
45
46=== modified file 'kewpie/kewpie.py'
47--- kewpie/kewpie.py 2011-12-05 18:56:39 +0000
48+++ kewpie/kewpie.py 2011-12-23 00:55:24 +0000
49@@ -19,16 +19,17 @@
50 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
51
52
53-""" dbqp.py
54+""" kewpie.py
55
56-DataBase Quality Platform - system for executing various
57+(DataBase) Quality Platform - system for executing various
58 testing systems and the helper code
59
60 Designed to be a modular test-runner. Different testing tools
61 and databases may be plugged into the system via hacking the
62 appropriate modules
63
64-Currently geared towards Drizzle / will expand to MySQL
65+Currently geared towards Drizzle and MySQL systems
66+Runs: Drizzle, MySQL, Percona Server, Galera dbms's
67 """
68
69 # imports
70@@ -43,9 +44,27 @@
71
72 # functions
73
74-
75 # main
76-variables = test_run_options.variables
77+# We base / look for a lot of things based on the location of
78+# the kewpie.py file
79+qp_rootdir = os.path.dirname(os.path.abspath(sys.argv[0]))
80+basedir_default = os.path.dirname(qp_rootdir)
81+testdir_default = qp_rootdir
82+defaults = { 'qp_root':qp_rootdir
83+ , 'testdir': qp_rootdir
84+ , 'workdir': os.path.join(qp_rootdir,'workdir')
85+ , 'clientbindir': os.path.join(os.path.dirname(qp_rootdir),'client')
86+ , 'basedir':os.path.dirname(qp_rootdir)
87+ , 'server_type':'mysql'
88+ , 'valgrind_suppression':os.path.join(qp_rootdir,'valgrind.supp')
89+ , 'suitepaths': [ os.path.join(basedir_default,'plugin')
90+ , os.path.join(testdir_default,'suite')
91+ ]
92+ , 'randgen_path': os.path.join(qp_rootdir,'randgen')
93+ , 'subunit_file': os.path.join(qp_rootdir,'workdir/test_results.subunit')
94+ }
95+variables = test_run_options.parse_qp_options(defaults)
96+variables['qp_root'] = qp_rootdir
97 system_manager = None
98 server_manager = None
99 test_manager = None
100
101=== modified file 'kewpie/lib/modes/native/native_test_management.py'
102--- kewpie/lib/modes/native/native_test_management.py 2011-11-12 00:50:21 +0000
103+++ kewpie/lib/modes/native/native_test_management.py 2011-12-23 00:55:24 +0000
104@@ -118,7 +118,27 @@
105 tests_to_use.append(test)
106 testlist = tests_to_use
107 for test_case in testlist:
108- self.add_test(self.process_test_file(suite_name, test_case))
109+ self.add_test(self.process_test_file( suite_name
110+ , test_case
111+ ))
112+
113+ def get_server_reqs(self, module_file):
114+ """ Code to handle extraction of server_requests & requirements
115+ from unittest test modules
116+
117+ """
118+
119+ module_name = os.path.basename(module_file).replace('.py','')
120+ my_module = imp.load_source(module_name, module_file)
121+ server_requirements = None
122+ server_requests = None
123+ try:
124+ server_requirements = my_module.server_requirements
125+ except AttributeError, NameError: pass
126+ try:
127+ server_requests = my_module.server_requests
128+ except AttributeError, NameError: pass
129+ return server_requirements, server_requests
130
131
132 def process_test_file(self, suite_name, testfile):
133@@ -127,12 +147,8 @@
134 # test_name = filename - .py...simpler
135 test_name = os.path.basename(testfile).replace('.py','')
136 test_comment = None
137- test_module = imp.load_source(test_name, testfile)
138- server_requirements = test_module.server_requirements
139- try:
140- server_requests = test_module.server_requests
141- except AttributeError, NameError:
142- server_requests = None
143+ server_requirements, server_requests = self.get_server_reqs(testfile)
144+
145 return testCase( self.system_manager
146 , name = test_name
147 , fullname = "%s.%s" %(suite_name, test_name)
148@@ -143,7 +159,6 @@
149 , debug = self.debug )
150
151
152-
153 def record_test_result(self, test_case, test_status, output, exec_time):
154 """ Accept the results of an executed testCase for further
155 processing.
156
157=== modified file 'kewpie/lib/opts/test_run_options.py'
158--- kewpie/lib/opts/test_run_options.py 2011-12-05 23:11:20 +0000
159+++ kewpie/lib/opts/test_run_options.py 2011-12-23 00:55:24 +0000
160@@ -70,7 +70,9 @@
161 if variables['repeat'] <= 0:
162 print "Setting --repeat=1. You chose a silly value that I will ignore :P"
163 variables['repeat'] = 1
164- if variables['mode'] == 'randgen' or variables['gendatafile']:
165+ # we disable the secure-file-priv option if not using dtr / mtr
166+ # this might need to be changed in the future...
167+ if variables['mode'] not in ['dtr','mtr']:
168 print "Setting --no-secure-file-priv=True for randgen usage..."
169 variables['nosecurefilepriv']=True
170 if variables['mode'] == 'cleanup':
171@@ -94,7 +96,7 @@
172 variables['basedir'].append(basedir_default)
173 return variables
174
175-def handle_user_opts(variables, basedir_default, testdir_default, suitepaths_default):
176+def handle_user_opts(variables, defaults):
177 """ Some variables are dependent upon default values
178 We do the probably hacky thing of going through
179 and updating them accordingly
180@@ -105,444 +107,455 @@
181
182 """
183 master_basedir = os.path.abspath(variables['basedir'][0].split(':type:')[0])
184- if master_basedir != basedir_default:
185+ if master_basedir != defaults['basedir']:
186 new_path = os.path.join(master_basedir, 'plugin')
187- search_path = os.path.join(basedir_default,'plugin')
188+ search_path = os.path.join(defaults['basedir'],'plugin')
189 tmp = variables['suitepaths']
190 tmp[tmp.index(search_path)] = new_path
191 variables['suitepaths'] = tmp
192- if variables['testdir'] != testdir_default:
193+ if variables['testdir'] != defaults['testdir']:
194 new_path = os.path.join(variables['testdir'],'suite')
195- search_path = os.path.join(testdir_default,'suite')
196+ search_path = os.path.join(defaults['testdir'],'suite')
197 tmp = variables['suitepaths']
198 tmp[tmp.index(search_path)] = new_path
199 variables['suitepaths'] = tmp
200 return variables
201
202
203-# Create the CLI option parser
204-parser= optparse.OptionParser(version='%prog (database quality platform aka project steve austin) version 0.1.1')
205-
206-# set some default values
207-testdir_default = os.path.abspath(os.getcwd())
208-workdir_default = os.path.join(testdir_default,'workdir')
209-clientbindir_default = os.path.abspath(os.path.join(testdir_default,'../client'))
210-basedir_default = os.path.split(testdir_default)[0]
211-server_type_default = 'mysql'
212-valgrind_suppression_default = os.path.join(testdir_default,'valgrind.supp')
213-suitepaths_default = [ os.path.join(basedir_default,'plugin')
214- , os.path.join(testdir_default,'suite')
215- ]
216-randgen_path_default = os.path.join(testdir_default,'randgen')
217-subunit_file_default = os.path.join(workdir_default,'test_results.subunit')
218-
219-
220-config_control_group = optparse.OptionGroup(parser,
221- "Configuration controls - kewpie can read config files with certain options pre-set")
222-config_control_group.add_option(
223- "--sys_config_file"
224- , dest="sysconfigfilepath"
225- , action='store'
226- , default=None # We want to have a file that will be our default defaults file...
227- , help="The file that specifies system configuration specs for dbqp to execute tests (not yet implemented)"
228- )
229-parser.add_option_group(config_control_group)
230-
231-
232-system_control_group = optparse.OptionGroup(parser,
233- "Options for the test-runner itself - defining the system under test and how to execute tests")
234-
235-system_control_group.add_option(
236- "--force"
237- , dest="force"
238- , action="store_true"
239- , default=False
240- , help="Set this to continue test execution beyond the first failed test"
241- )
242-
243-system_control_group.add_option(
244- "--start-and-exit"
245- , dest="startandexit"
246- , action="store_true"
247- , default=False
248- , help="Spin up the server(s) for the first specified test then exit (will leave servers running)"
249- )
250-
251-system_control_group.add_option(
252- "--verbose"
253- , dest="verbose"
254- , action="store_true"
255- , default = False
256- , help="Produces extensive output about test-runner state. Distinct from --debug"
257- )
258-
259-system_control_group.add_option(
260- "--debug"
261- , dest="debug"
262- , action="store_true"
263- , default = False
264- , help="Provide internal-level debugging output. Distinct from --verbose"
265- )
266-
267-system_control_group.add_option(
268- "--mode"
269- , dest="mode"
270- , default="native"
271- , help="Testing mode. We currently support dtr, randgen, sysbench, sqlbench, crashme and cleanup modes. See docs for further details about individual modes [%default]"
272- )
273-
274-system_control_group.add_option(
275- "--record"
276- , dest="record"
277- , action="store_true"
278- , default=False
279- , help="Record a testcase result (if the testing mode supports it) [%default]"
280- )
281-
282-system_control_group.add_option(
283- "--fast"
284- , dest="fast"
285- , action="store_true"
286- , default=False
287- , help="Don't try to cleanup from earlier runs (currently just a placeholder) [%default]"
288- )
289-
290-parser.add_option_group(system_control_group)
291-
292-test_control_group = optparse.OptionGroup(parser,
293- "Options for controlling which tests are executed")
294-
295-test_control_group.add_option(
296- "--suite"
297- , dest="suitelist"
298- , type='string'
299- , action="callback"
300- , callback=comma_list_split
301- , help="The name of the suite containing tests we want. Can accept comma-separated list (with no spaces). Additional --suite args are appended to existing list [autosearch]"
302- )
303-
304-test_control_group.add_option(
305- "--suitepath"
306- , dest="suitepaths"
307- , type='string'
308- , action="append"
309- , default = suitepaths_default
310- , help="The path containing the suite(s) you wish to execute. Use one --suitepath for each suite you want to use. [%default]"
311- )
312-
313-test_control_group.add_option(
314- "--do-test"
315- , dest="dotest"
316- , type='string'
317- , default = None
318- , help="input can either be a prefix or a regex. Will only execute tests that match the provided pattern"
319- )
320-
321-test_control_group.add_option(
322- "--skip-test"
323- , dest="skiptest"
324- , type='string'
325- , default = None
326- , help = "input can either be a prefix or a regex. Will exclude tests that match the provided pattern"
327- )
328-
329-test_control_group.add_option(
330- "--reorder"
331- , dest="reorder"
332- , action="store_true"
333- , default=False
334- , help = "sort the testcases so that they are executed optimally for the given mode [%default]"
335- )
336-
337-test_control_group.add_option(
338- "--repeat"
339- , dest="repeat"
340- , type='int'
341- , action="store"
342- , default=1
343- , help = "Run each test case the specified number of times. For a given sequence, the first test will be run n times, then the second, etc [%default]"
344- )
345-
346-parser.add_option_group(test_control_group)
347-
348-# test subject control group
349-# terrible name for options tht define the server / code
350-# that is under test
351-
352-# find some default values
353-# assume we are in-tree testing in general and operating from root/test(?)
354-testdir_default = os.path.abspath(os.getcwd())
355-
356-basedir_default = os.path.split(testdir_default)[0]
357-
358-test_subject_control_group = optparse.OptionGroup(parser,
359- "Options for defining the code that will be under test")
360-
361-test_subject_control_group.add_option(
362- "--basedir"
363- , dest="basedir"
364- , type='string'
365- , default = []
366- , action="append"
367- , help = "Pass this argument to signal to the test-runner that this is an in-tree test. We automatically set a number of variables relative to the argument (client-bindir, serverdir, testdir) [%basedir_default]"
368- )
369-
370-test_subject_control_group.add_option(
371- "--default-server-type"
372- , dest="defaultservertype"
373- , type='string'
374- , default = server_type_default
375- , action='store'
376- , help = "Defines what we consider to be the default server type. We assume a server is default type unless specified otherwise. [%default]"
377- )
378-
379-test_subject_control_group.add_option(
380- "--serverdir"
381- , dest="serverpath"
382- , type='string'
383- , action="callback"
384- , callback=get_abspath
385- , help = "Path to the server executable. [%default]"
386- )
387-
388-test_subject_control_group.add_option(
389- "--client-bindir"
390- , dest="clientbindir"
391- , type = 'string'
392- , action="callback"
393- , callback=get_abspath
394- , help = "Path to the directory containing client program binaries for use in testing [%default]"
395- )
396-
397-
398-test_subject_control_group.add_option(
399- "--default-storage-engine"
400- , dest="defaultengine"
401- , default = 'innodb'
402- , help="Start drizzled using the specified engine [%default]"
403- )
404-
405-
406-parser.add_option_group(test_subject_control_group)
407-# end test subject control group
408-
409-# environment options
410-
411-environment_control_group = optparse.OptionGroup(parser,
412- "Options for defining the testing environment")
413-
414-environment_control_group.add_option(
415- "--testdir"
416- , dest="testdir"
417- , type = 'string'
418- , default = testdir_default
419- , action="callback"
420- , callback=get_abspath
421- , help = "Path to the test dir, containing additional files for test execution. [%default]"
422- )
423-
424-environment_control_group.add_option(
425- "--workdir"
426- , dest="workdir"
427- , type='string'
428- , default = workdir_default
429- , action="callback"
430- , callback=get_abspath
431- , help = "Path to the directory test-run will use to store generated files and directories. [%default]"
432- )
433-
434-environment_control_group.add_option(
435- "--top-srcdir"
436- , dest="topsrcdir"
437- , type='string'
438- , default = basedir_default
439- , help = "build option [%default]"
440- )
441-
442-environment_control_group.add_option(
443- "--top-builddir"
444- , dest="topbuilddir"
445- , type='string'
446- , default = basedir_default
447- , help = "build option [%default]"
448- )
449-
450-environment_control_group.add_option(
451- "--no-shm"
452- , dest="noshm"
453- , action='store_true'
454- , default=False
455- , help = "By default, we symlink workdir to a location in shm. Use this flag to not symlink [%default]"
456- )
457-
458-environment_control_group.add_option(
459- "--libeatmydata"
460- , dest="libeatmydata"
461- , action='store_true'
462- , default=False
463- , help = "We use libeatmydata (if available) to disable fsyncs and speed up test execution. Implies --no-shm"
464- )
465-
466-environment_control_group.add_option(
467- "--libeatmydata-path"
468- , dest="libeatmydatapath"
469- , action='store'
470- , default='/usr/local/lib/libeatmydata.so'
471- , help = "Path to the libeatmydata install you want to use [%default]"
472- )
473-
474-environment_control_group.add_option(
475- "--start-dirty"
476- , dest="startdirty"
477- , action='store_true'
478- , default=False
479- , help = "Don't try to clean up working directories before test execution [%default]"
480- )
481-
482-environment_control_group.add_option(
483- "--no-secure-file-priv"
484- , dest = "nosecurefilepriv"
485- , action='store_true'
486- , default=False
487- , help = "Turn off the use of --secure-file-priv=vardir for started servers"
488- )
489-
490-environment_control_group.add_option(
491- "--randgen-path"
492- , dest="randgenpath"
493- , action='store'
494- , default=randgen_path_default
495- , help = "The path to a randgen installation that can be used to execute randgen-based tests [%default]"
496- )
497-
498-environment_control_group.add_option(
499- "--innobackupex-path"
500- , dest="innobackupexpath"
501- , action='store'
502- , default=None
503- , help = "The path to the innobackupex script that facilitates the use of Xtrabackup"
504- )
505-
506-environment_control_group.add_option(
507- "--xtrabackup-path"
508- , dest="xtrabackuppath"
509- , action='store'
510- , default=None
511- , help = "The path the xtrabackup binary to be tested"
512- )
513-
514-environment_control_group.add_option(
515- "--wsrep-provider-path"
516- , dest="wsrepprovider"
517- , action='store'
518- , default=None
519- , help = "The path to a wsrep provider library for use with mysql"
520- )
521-
522-environment_control_group.add_option(
523- "--subunit-outfile"
524- , dest="subunitoutfile"
525- , action='store'
526- , default=subunit_file_default
527- , help = "File path where subunit output will be logged [%default]"
528- )
529-
530-parser.add_option_group(environment_control_group)
531-# end environment control group
532-
533-option_passing_group = optparse.OptionGroup(parser,
534- "Options to pass options on to the server")
535-
536-option_passing_group.add_option(
537-"--drizzled"
538- , dest="drizzledoptions"
539- , type='string'
540- , action='append'
541- , default = []
542- , help = "Pass additional options to the server. Will be passed to all servers for all tests (mostly for --start-and-exit)"
543- )
544-
545-parser.add_option_group(option_passing_group)
546-# end option passing group
547-
548-analysis_control_group = optparse.OptionGroup(parser,
549- "Options for defining the tools we use for code analysis (valgrind, gprof, gcov, etc)")
550-
551-analysis_control_group.add_option(
552- "--valgrind"
553- , dest="valgrind"
554- , action='store_true'
555- , default = False
556- , help = "Run drizzletest and drizzled executables using valgrind with default options [%default]"
557- )
558-
559-analysis_control_group.add_option(
560- "--valgrind-option"
561- , dest="valgrindarglist"
562- , type='string'
563- , action="append"
564- , help = "Pass an option to valgrind (overrides/removes default valgrind options)"
565- )
566-
567-analysis_control_group.add_option(
568- "--valgrind-suppressions"
569- , dest="valgrindsuppressions"
570- , type='string'
571- , action='store'
572- , default = valgrind_suppression_default
573- , help = "Point at a valgrind suppression file [%default]"
574- )
575-
576-analysis_control_group.add_option(
577- "--helgrind"
578- , dest="helgrind"
579- , action='store_true'
580- , default=False
581- , help="Use the helgrind tool for valgrind. Implies / will auto-use --valgrind"
582- )
583-
584-parser.add_option_group(analysis_control_group)
585-
586-debugger_control_group = optparse.OptionGroup(parser,
587- "Options for controlling the use of debuggers with test execution")
588-
589-debugger_control_group.add_option(
590- "--gdb"
591- , dest="gdb"
592- , action='store_true'
593- , default=False
594- , help="Start the drizzled server(s) in gdb"
595- )
596-
597-debugger_control_group.add_option(
598- "--manual-gdb"
599- , dest="manualgdb"
600- , action='store_true'
601- , default=False
602- , help="Allows you to start the drizzled server(s) in gdb manually (in another window, etc)"
603- )
604-
605-parser.add_option_group(debugger_control_group)
606-
607-utility_group = optparse.OptionGroup(parser,
608- "Options to call additional utilities such as datagen")
609-
610-utility_group.add_option(
611- "--gendata"
612- , dest="gendatafile"
613- , action='store'
614- , type='string'
615- , default=None
616- , help="Call the randgen's gendata utility to use the specified configuration file. This will populate the server prior to any test execution")
617-
618-parser.add_option_group(utility_group)
619-
620-# supplied will be those arguments matching an option,
621-# and test_cases will be everything else
622-(args, test_cases)= parser.parse_args()
623-
624-variables = {}
625-variables = organize_options(args, test_cases)
626-variables = populate_defaults(variables, basedir_default)
627-variables = handle_user_opts(variables, basedir_default, testdir_default, suitepaths_default)
628-
629+
630+def parse_qp_options(defaults):
631+ """ We parse our options and do our magic based on some default values """
632+ # Create the CLI option parser
633+ parser= optparse.OptionParser(version='%prog (database quality platform aka project steve austin) version 0.1.1')
634+ config_control_group = optparse.OptionGroup(parser,
635+ "Configuration controls - allows you to specify a file with a number of options already specified")
636+ config_control_group.add_option(
637+ "--sys_config_file"
638+ , dest="sysconfigfilepath"
639+ , action='store'
640+ , default=None # We want to have a file that will be our default defaults file...
641+ , help="The file that specifies system configuration specs for dbqp to execute tests (not yet implemented)"
642+ )
643+ parser.add_option_group(config_control_group)
644+
645+
646+ system_control_group = optparse.OptionGroup(parser,
647+ "Options for the test-runner itself - defining the system under test and how to execute tests")
648+
649+ system_control_group.add_option(
650+ "--force"
651+ , dest="force"
652+ , action="store_true"
653+ , default=False
654+ , help="Set this to continue test execution beyond the first failed test"
655+ )
656+
657+ system_control_group.add_option(
658+ "--start-and-exit"
659+ , dest="startandexit"
660+ , action="store_true"
661+ , default=False
662+ , help="Spin up the server(s) for the first specified test then exit (will leave servers running)"
663+ )
664+
665+ system_control_group.add_option(
666+ "--verbose"
667+ , dest="verbose"
668+ , action="store_true"
669+ , default = False
670+ , help="Produces extensive output about test-runner state. Distinct from --debug"
671+ )
672+
673+ system_control_group.add_option(
674+ "--debug"
675+ , dest="debug"
676+ , action="store_true"
677+ , default = False
678+ , help="Provide internal-level debugging output. Distinct from --verbose"
679+ )
680+
681+ system_control_group.add_option(
682+ "--mode"
683+ , dest="mode"
684+ , default="native"
685+ , help="Testing mode. We currently support dtr, randgen, sysbench, sqlbench, crashme and cleanup modes. See docs for further details about individual modes [%default]"
686+ )
687+
688+ system_control_group.add_option(
689+ "--record"
690+ , dest="record"
691+ , action="store_true"
692+ , default=False
693+ , help="Record a testcase result (if the testing mode supports it) [%default]"
694+ )
695+
696+ system_control_group.add_option(
697+ "--fast"
698+ , dest="fast"
699+ , action="store_true"
700+ , default=False
701+ , help="Don't try to cleanup from earlier runs (currently just a placeholder) [%default]"
702+ )
703+
704+ parser.add_option_group(system_control_group)
705+
706+ test_exec_control_group = optparse.OptionGroup(parser,
707+ "Options for controlling how tests are executed")
708+
709+ test_exec_control_group.add_option(
710+ "--test-debug"
711+ , dest="testdebug"
712+ , action="store_true"
713+ , default=False
714+ , help="Toggle to control any debugging / helper output with unittest test cases [%default]"
715+ )
716+
717+ test_exec_control_group.add_option(
718+ "--randgen-seed"
719+ , dest="randgenseed"
720+ , type='string'
721+ , action="store"
722+ , default='1'
723+ , help="Alter the seed value provided to the random query generator to vary test runs. (string) [%default]"
724+ )
725+
726+ parser.add_option_group(test_exec_control_group)
727+
728+ test_control_group = optparse.OptionGroup(parser,
729+ "Options for controlling which tests are executed")
730+
731+ test_control_group.add_option(
732+ "--suite"
733+ , dest="suitelist"
734+ , type='string'
735+ , action="callback"
736+ , callback=comma_list_split
737+ , help="The name of the suite containing tests we want. Can accept comma-separated list (with no spaces). Additional --suite args are appended to existing list [autosearch]"
738+ )
739+
740+ test_control_group.add_option(
741+ "--suitepath"
742+ , dest="suitepaths"
743+ , type='string'
744+ , action="append"
745+ , default = defaults['suitepaths']
746+ , help="The path containing the suite(s) you wish to execute. Use one --suitepath for each suite you want to use. [%default]"
747+ )
748+
749+ test_control_group.add_option(
750+ "--do-test"
751+ , dest="dotest"
752+ , type='string'
753+ , default = None
754+ , help="input can either be a prefix or a regex. Will only execute tests that match the provided pattern"
755+ )
756+
757+ test_control_group.add_option(
758+ "--skip-test"
759+ , dest="skiptest"
760+ , type='string'
761+ , default = None
762+ , help = "input can either be a prefix or a regex. Will exclude tests that match the provided pattern"
763+ )
764+
765+ test_control_group.add_option(
766+ "--reorder"
767+ , dest="reorder"
768+ , action="store_true"
769+ , default=False
770+ , help = "sort the testcases so that they are executed optimally for the given mode [%default]"
771+ )
772+
773+ test_control_group.add_option(
774+ "--repeat"
775+ , dest="repeat"
776+ , type='int'
777+ , action="store"
778+ , default=1
779+ , help = "Run each test case the specified number of times. For a given sequence, the first test will be run n times, then the second, etc [%default]"
780+ )
781+
782+ parser.add_option_group(test_control_group)
783+
784+ # test subject control group
785+ # terrible name for options tht define the server / code
786+ # that is under test
787+ test_subject_control_group = optparse.OptionGroup(parser,
788+ "Options for defining the code that will be under test")
789+
790+ test_subject_control_group.add_option(
791+ "--basedir"
792+ , dest="basedir"
793+ , type='string'
794+ , default = []
795+ , action="append"
796+ , help = "Pass this argument to signal to the test-runner that this is an in-tree test. We automatically set a number of variables relative to the argument (client-bindir, serverdir, testdir) [%defaults['basedir']]"
797+ )
798+
799+ test_subject_control_group.add_option(
800+ "--default-server-type"
801+ , dest="defaultservertype"
802+ , type='string'
803+ , default = defaults['server_type']
804+ , action='store'
805+ , help = "Defines what we consider to be the default server type. We assume a server is default type unless specified otherwise. [%default]"
806+ )
807+
808+ test_subject_control_group.add_option(
809+ "--serverdir"
810+ , dest="serverpath"
811+ , type='string'
812+ , action="callback"
813+ , callback=get_abspath
814+ , help = "Path to the server executable. [%default]"
815+ )
816+
817+ test_subject_control_group.add_option(
818+ "--client-bindir"
819+ , dest="clientbindir"
820+ , type = 'string'
821+ , action="callback"
822+ , callback=get_abspath
823+ , help = "Path to the directory containing client program binaries for use in testing [%default]"
824+ )
825+
826+
827+ test_subject_control_group.add_option(
828+ "--default-storage-engine"
829+ , dest="defaultengine"
830+ , default = 'innodb'
831+ , help="Start drizzled using the specified engine [%default]"
832+ )
833+
834+
835+ parser.add_option_group(test_subject_control_group)
836+ # end test subject control group
837+
838+ # environment options
839+
840+ environment_control_group = optparse.OptionGroup(parser,
841+ "Options for defining the testing environment")
842+
843+ environment_control_group.add_option(
844+ "--testdir"
845+ , dest="testdir"
846+ , type = 'string'
847+ , default = defaults['testdir']
848+ , action="callback"
849+ , callback=get_abspath
850+ , help = "Path to the test dir, containing additional files for test execution. [%default]"
851+ )
852+
853+ environment_control_group.add_option(
854+ "--workdir"
855+ , dest="workdir"
856+ , type='string'
857+ , default = defaults['workdir']
858+ , action="callback"
859+ , callback=get_abspath
860+ , help = "Path to the directory test-run will use to store generated files and directories. [%default]"
861+ )
862+
863+ environment_control_group.add_option(
864+ "--top-srcdir"
865+ , dest="topsrcdir"
866+ , type='string'
867+ , default = defaults['basedir']
868+ , help = "build option [%default]"
869+ )
870+
871+ environment_control_group.add_option(
872+ "--top-builddir"
873+ , dest="topbuilddir"
874+ , type='string'
875+ , default = defaults['basedir']
876+ , help = "build option [%default]"
877+ )
878+
879+ environment_control_group.add_option(
880+ "--no-shm"
881+ , dest="noshm"
882+ , action='store_true'
883+ , default=False
884+ , help = "By default, we symlink workdir to a location in shm. Use this flag to not symlink [%default]"
885+ )
886+
887+ environment_control_group.add_option(
888+ "--libeatmydata"
889+ , dest="libeatmydata"
890+ , action='store_true'
891+ , default=False
892+ , help = "We use libeatmydata (if available) to disable fsyncs and speed up test execution. Implies --no-shm"
893+ )
894+
895+ environment_control_group.add_option(
896+ "--libeatmydata-path"
897+ , dest="libeatmydatapath"
898+ , action='store'
899+ , default='/usr/local/lib/libeatmydata.so'
900+ , help = "Path to the libeatmydata install you want to use [%default]"
901+ )
902+
903+ environment_control_group.add_option(
904+ "--start-dirty"
905+ , dest="startdirty"
906+ , action='store_true'
907+ , default=False
908+ , help = "Don't try to clean up working directories before test execution [%default]"
909+ )
910+
911+ environment_control_group.add_option(
912+ "--no-secure-file-priv"
913+ , dest = "nosecurefilepriv"
914+ , action='store_true'
915+ , default=False
916+ , help = "Turn off the use of --secure-file-priv=vardir for started servers"
917+ )
918+
919+ environment_control_group.add_option(
920+ "--randgen-path"
921+ , dest="randgenpath"
922+ , action='store'
923+ , default=defaults['randgen_path']
924+ , help = "The path to a randgen installation that can be used to execute randgen-based tests"
925+ )
926+
927+ environment_control_group.add_option(
928+ "--innobackupex-path"
929+ , dest="innobackupexpath"
930+ , action='store'
931+ , default=None
932+ , help = "The path to the innobackupex script that facilitates the use of Xtrabackup"
933+ )
934+
935+ environment_control_group.add_option(
936+ "--xtrabackup-path"
937+ , dest="xtrabackuppath"
938+ , action='store'
939+ , default=None
940+ , help = "The path the xtrabackup binary to be tested"
941+ )
942+
943+ environment_control_group.add_option(
944+ "--wsrep-provider-path"
945+ , dest="wsrepprovider"
946+ , action='store'
947+ , default=None
948+ , help = "The path to a wsrep provider library for use with mysql"
949+ )
950+
951+ environment_control_group.add_option(
952+ "--cluster-cnf"
953+ , dest="clustercnf"
954+ , action='store'
955+ , default=None
956+ , help = "The path to a config file defining a running cluster (node info)"
957+ )
958+
959+ environment_control_group.add_option(
960+ "--subunit-outfile"
961+ , dest="subunitoutfile"
962+ , action='store'
963+ , default=defaults['subunit_file']
964+ , help = "File path where subunit output will be logged [%default]"
965+ )
966+
967+ parser.add_option_group(environment_control_group)
968+ # end environment control group
969+
970+ option_passing_group = optparse.OptionGroup(parser,
971+ "Options to pass options on to the server")
972+
973+ option_passing_group.add_option(
974+ "--drizzled"
975+ , dest="drizzledoptions"
976+ , type='string'
977+ , action='append'
978+ , default = []
979+ , help = "Pass additional options to the server. Will be passed to all servers for all tests (mostly for --start-and-exit)"
980+ )
981+
982+ parser.add_option_group(option_passing_group)
983+ # end option passing group
984+
985+ analysis_control_group = optparse.OptionGroup(parser,
986+ "Options for defining the tools we use for code analysis (valgrind, gprof, gcov, etc)")
987+
988+ analysis_control_group.add_option(
989+ "--valgrind"
990+ , dest="valgrind"
991+ , action='store_true'
992+ , default = False
993+ , help = "Run drizzletest and drizzled executables using valgrind with default options [%default]"
994+ )
995+
996+ analysis_control_group.add_option(
997+ "--valgrind-option"
998+ , dest="valgrindarglist"
999+ , type='string'
1000+ , action="append"
1001+ , help = "Pass an option to valgrind (overrides/removes default valgrind options)"
1002+ )
1003+
1004+ analysis_control_group.add_option(
1005+ "--valgrind-suppressions"
1006+ , dest="valgrindsuppressions"
1007+ , type='string'
1008+ , action='store'
1009+ , default = defaults['valgrind_suppression']
1010+ , help = "Point at a valgrind suppression file [%default]"
1011+ )
1012+
1013+ analysis_control_group.add_option(
1014+ "--helgrind"
1015+ , dest="helgrind"
1016+ , action='store_true'
1017+ , default=False
1018+ , help="Use the helgrind tool for valgrind. Implies / will auto-use --valgrind"
1019+ )
1020+
1021+ parser.add_option_group(analysis_control_group)
1022+
1023+ debugger_control_group = optparse.OptionGroup(parser,
1024+ "Options for controlling the use of debuggers with test execution")
1025+
1026+ debugger_control_group.add_option(
1027+ "--gdb"
1028+ , dest="gdb"
1029+ , action='store_true'
1030+ , default=False
1031+ , help="Start the drizzled server(s) in gdb"
1032+ )
1033+
1034+ debugger_control_group.add_option(
1035+ "--manual-gdb"
1036+ , dest="manualgdb"
1037+ , action='store_true'
1038+ , default=False
1039+ , help="Allows you to start the drizzled server(s) in gdb manually (in another window, etc)"
1040+ )
1041+
1042+ parser.add_option_group(debugger_control_group)
1043+
1044+ utility_group = optparse.OptionGroup(parser,
1045+ "Options to call additional utilities such as datagen")
1046+
1047+ utility_group.add_option(
1048+ "--gendata"
1049+ , dest="gendatafile"
1050+ , action='store'
1051+ , type='string'
1052+ , default=None
1053+ , help="Call the randgen's gendata utility to use the specified configuration file. This will populate the server prior to any test execution")
1054+
1055+ parser.add_option_group(utility_group)
1056+
1057+ # supplied will be those arguments matching an option,
1058+ # and test_cases will be everything else
1059+ (args, test_cases)= parser.parse_args()
1060+
1061+ variables = {}
1062+ variables = organize_options(args, test_cases)
1063+ variables = populate_defaults(variables, defaults['basedir'])
1064+ variables = handle_user_opts(variables, defaults)
1065+ return variables
1066
1067=== modified file 'kewpie/lib/server_mgmt/drizzled.py'
1068--- kewpie/lib/server_mgmt/drizzled.py 2011-12-01 00:14:08 +0000
1069+++ kewpie/lib/server_mgmt/drizzled.py 2011-12-23 00:55:24 +0000
1070@@ -93,9 +93,17 @@
1071 self.logdir = os.path.join(self.vardir,'log')
1072 self.datadir = os.path.join(self.vardir,'master-data')
1073
1074- self.error_log = os.path.join(self.logdir,('%s.err' %(self.name)))
1075+ self.error_log = os.path.join(self.logdir,'error.log')
1076 self.pid_file = os.path.join(self.rundir,('%s.pid' %(self.name)))
1077 self.socket_file = os.path.join(self.vardir, ('%s.sock' %(self.name)))
1078+ if len(self.socket_file) > 107:
1079+ # MySQL has a limitation of 107 characters for socket file path
1080+ # we copy the mtr workaround of creating one in /tmp
1081+ self.logging.verbose("Default socket file path: %s" %(self.socket_file))
1082+ self.socket_file = "/tmp/%s_%s.%s.sock" %(self.system_manager.uuid
1083+ ,self.owner
1084+ ,self.name)
1085+ self.logging.verbose("Changing to alternate: %s" %(self.socket_file))
1086 self.timer_file = os.path.join(self.logdir,('timer'))
1087
1088 # Do magic to create a config file for use with the slave
1089
1090=== modified file 'kewpie/lib/server_mgmt/galera.py'
1091--- kewpie/lib/server_mgmt/galera.py 2011-12-01 01:59:54 +0000
1092+++ kewpie/lib/server_mgmt/galera.py 2011-12-23 00:55:24 +0000
1093@@ -109,6 +109,15 @@
1094 self.bootstrap_log = os.path.join(self.logdir,('bootstrap.log'))
1095 self.pid_file = os.path.join(self.rundir,('my.pid'))
1096 self.socket_file = os.path.join(self.vardir, ('my.sock'))
1097+ if len(self.socket_file) > 107:
1098+ # MySQL has a limitation of 107 characters for socket file path
1099+ # we copy the mtr workaround of creating one in /tmp
1100+ self.logging.verbose("Default socket file path: %s" %(self.socket_file))
1101+ self.socket_file = "/tmp/%s_%s.%s.sock" %(self.system_manager.uuid
1102+ ,self.owner
1103+ ,self.name)
1104+ self.logging.verbose("Changing to alternate: %s" %(self.socket_file))
1105+
1106 self.timer_file = os.path.join(self.logdir,('timer'))
1107 self.general_log_file = os.path.join(self.logdir,'mysqld.log')
1108 self.slow_query_log_file = os.path.join(self.logdir,'mysqld-slow.log')
1109
1110=== modified file 'kewpie/lib/server_mgmt/mysqld.py'
1111--- kewpie/lib/server_mgmt/mysqld.py 2011-12-05 23:11:20 +0000
1112+++ kewpie/lib/server_mgmt/mysqld.py 2011-12-23 00:55:24 +0000
1113@@ -78,10 +78,10 @@
1114 self.bootstrap_file = self.code_tree.bootstrap_path
1115 self.bootstrap_cmd = None
1116
1117- # MySQL 5.1 servers use --language argument vs. lc-message-dir
1118+ # MySQL 5.0 and 5.1 servers use --language argument vs. lc-message-dir
1119 # We check and set things appropriately for such cases
1120 self.langstring = "--lc-messages-dir=%s" %(self.langdir)
1121- if self.version.startswith('5.1'):
1122+ if self.version.startswith('5.1') or self.version.startswith('5.0'):
1123 self.langstring = "--language=%s" %(os.path.join(self.langdir
1124 ,'english')
1125 )
1126@@ -115,6 +115,14 @@
1127 self.bootstrap_log = os.path.join(self.logdir,('bootstrap.log'))
1128 self.pid_file = os.path.join(self.rundir,('%s.pid' %(self.name)))
1129 self.socket_file = os.path.join(self.vardir, ('%s.sock' %(self.name)))
1130+ if len(self.socket_file) > 107:
1131+ # MySQL has a limitation of 107 characters for socket file path
1132+ # we copy the mtr workaround of creating one in /tmp
1133+ self.logging.verbose("Default socket file path: %s" %(self.socket_file))
1134+ self.socket_file = "/tmp/%s_%s.%s.sock" %(self.system_manager.uuid
1135+ ,self.owner
1136+ ,self.name)
1137+ self.logging.verbose("Changing to alternate: %s" %(self.socket_file))
1138 self.timer_file = os.path.join(self.logdir,('timer'))
1139 self.general_log_file = os.path.join(self.logdir,'mysqld.log')
1140 self.slow_query_log_file = os.path.join(self.logdir,'mysqld-slow.log')
1141@@ -225,12 +233,7 @@
1142 , "--loose-performance-schema-max-rwlock-instances=10000"
1143 , "--loose-performance-schema-max-table-instances=500"
1144 , "--loose-performance-schema-max-table-handles=1000"
1145- , "--binlog-direct-non-transactional-updates"
1146 , "--loose-enable-performance-schema"
1147- , "--general_log=1"
1148- , "--general_log_file=%s" %(self.general_log_file)
1149- , "--slow_query_log=1"
1150- , "--slow_query_log_file=%s" %(self.slow_query_log_file)
1151 , "--basedir=%s" %(self.code_tree.basedir)
1152 , "--datadir=%s" %(self.datadir)
1153 , "--tmpdir=%s" %(self.tmpdir)
1154@@ -249,6 +252,14 @@
1155 , self.secure_file_string
1156 , self.user_string
1157 ]
1158+
1159+ if not self.version.startswith('5.0'):
1160+ server_args += [ "--binlog-direct-non-transactional-updates"
1161+ , "--general_log=1"
1162+ , "--general_log_file=%s" %(self.general_log_file)
1163+ , "--slow_query_log=1"
1164+ , "--slow_query_log_file=%s" %(self.slow_query_log_file)
1165+ ]
1166 self.gen_cnf_file(server_args)
1167
1168 if self.gdb:
1169@@ -314,9 +325,12 @@
1170 msg = None
1171 if self.status: # we are running and can do things!
1172 # Get master binlog info
1173- master_binlog_file, master_binlog_pos = master_server.get_binlog_info()
1174- if not get_cur_log_pos:
1175- master_binlog_pos = 0
1176+ retcode, master_binlog_file, master_binlog_pos = master_server.get_binlog_info()
1177+ if not retcode:
1178+ if not get_cur_log_pos:
1179+ master_binlog_pos = 0
1180+ else:
1181+ return retcode, master_binlog_file #contains error msg on failure
1182
1183 # update our slave's master info
1184 query = ("CHANGE MASTER TO "
1185@@ -356,11 +370,117 @@
1186 self.master = master_server
1187 return 0,msg
1188
1189+ def get_slave_status(self):
1190+ query = "SHOW SLAVE STATUS"
1191+ retcode, result_set = execute_query(query, self)
1192+ result_set = result_set[0]
1193+ if not retcode:
1194+ slave_data = { 'slave_io_state':result_set[0]
1195+ , 'master_host':result_set[1]
1196+ , 'master_user':result_set[2]
1197+ , 'master_port':result_set[3]
1198+ , 'connect_retry':result_set[4]
1199+ , 'master_log_file':result_set[5]
1200+ , 'read_master_log_pos':result_set[6]
1201+ , 'relay_log_file':result_set[7]
1202+ , 'relay_log_pos':result_set[8]
1203+ , 'relay_master_log_file':result_set[9]
1204+ , 'slave_io_running':result_set[10]
1205+ , 'slave_sql_running':result_set[11]
1206+ , 'replicate_do_db':result_set[12]
1207+ , 'replicate_ignore_db':result_set[13]
1208+ , 'replicate_do_table':result_set[14]
1209+ , 'replicate_ignore_table':result_set[15]
1210+ , 'replicate_wild_do_table':result_set[16]
1211+ , 'replicate_wild_ignore_table':result_set[17]
1212+ , 'last_errno':result_set[18]
1213+ , 'last_error':result_set[19]
1214+ , 'skip_counter':result_set[20]
1215+ , 'exec_master_log_pos':result_set[21]
1216+ , 'relay_log_space':result_set[22]
1217+ , 'until_condition':result_set[23]
1218+ , 'until_log_file':result_set[24]
1219+ , 'until_log_pos':result_set[25]
1220+ , 'master_ssl_allowed':result_set[26]
1221+ , 'master_ssl_ca_file':result_set[27]
1222+ , 'master_ssl_ca_path':result_set[28]
1223+ , 'master_ssl_cert':result_set[29]
1224+ , 'master_ssl_cipher':result_set[30]
1225+ , 'master_ssl_key':result_set[31]
1226+ , 'seconds_behind_master':result_set[32]
1227+ , 'master_ssl_verify_server_cert':result_set[33]
1228+ , 'last_io_errno':result_set[34]
1229+ , 'last_io_error':result_set[35]
1230+ , 'last_sql_errno':result_set[36]
1231+ , 'last_sql_error':result_set[37]
1232+ , 'replicate_ignore_server_ids':result_set[38]
1233+ }
1234+ return slave_data
1235+ else:
1236+ print result_set
1237+ return None
1238+
1239+
1240 def get_binlog_info(self):
1241 """ We try to get binlog information for the server """
1242 query = "SHOW MASTER STATUS"
1243 retcode, result_set = execute_query(query, self)
1244- binlog_file = result_set[0][0]
1245- binlog_pos = result_set[0][1]
1246- return binlog_file, binlog_pos
1247-
1248+ if not retcode:
1249+ binlog_file = result_set[0][0]
1250+ binlog_pos = result_set[0][1]
1251+ else:
1252+ binlog_file = result_set
1253+ binlog_pos = result_set
1254+ return retcode, binlog_file, binlog_pos
1255+
1256+ def slave_stop(self):
1257+ """ We issue STOP SLAVE and wait for IO and SQL threads to stop """
1258+
1259+ query = "STOP SLAVE"
1260+ retcode, result = execute_query(query, self)
1261+ slave_status = self.get_slave_status()
1262+ while slave_status['slave_io_running'] == 'Yes' or slave_status['slave_sql_running'] == 'Yes':
1263+ slave_status = self.get_slave_status()
1264+
1265+ def slave_start(self):
1266+ """ We issue START SLAVE and wait for IO and SQL threads to start """
1267+ query = "START SLAVE"
1268+ retcode, result = execute_query(query, self)
1269+ slave_status = self.get_slave_status()
1270+ while slave_status['slave_io_running'] == 'No' or slave_status['slave_sql_running'] == 'No':
1271+ slave_status = self.get_slave_status()
1272+
1273+
1274+ def wait_sync_with_slaves(self, slave_list, timeout=60):
1275+ """ We scan through our slave list and make sure we are synched up
1276+ before moving on with the test
1277+
1278+ """
1279+
1280+ retcode, master_binlog_file, master_binlog_pos = self.get_binlog_info()
1281+ while slave_list:
1282+ for idx, slave_server in enumerate(slave_list):
1283+ slave_status_data = slave_server.get_slave_status()
1284+ read_master_log_pos = slave_status_data['read_master_log_pos']
1285+ exec_master_log_pos = slave_status_data['exec_master_log_pos']
1286+ seconds_behind_master = slave_status_data['seconds_behind_master']
1287+ slave_io_state = slave_status_data['slave_io_state']
1288+ # This test subject to change as I learn more ; )
1289+ #if master_binlog_pos == exec_master_log_pos:
1290+ if exec_master_log_pos == read_master_log_pos and slave_io_state == 'Waiting for master to send event':
1291+ #print 'Server: %s.%s' %(self.owner, self.name)
1292+ #print 'Master_binlog_file: %s' %master_binlog_file
1293+ #print 'Master_binlog_pos: %s' %master_binlog_pos
1294+ #print 'Exec_master_log_pos: %s' %exec_master_log_pos
1295+ #print 'Read_master_log_pos: %s' %read_master_log_pos
1296+ #if read_master_log_pos > master_binlog_pos:
1297+ #for key, item in slave_status_data.items():
1298+ # print "%s:%s" %(key, item)
1299+ #print '#'*80
1300+ # It is normally a no-no to remove items from a list
1301+ # mid-iteration, but this is a chance to break that rule
1302+ # >: )
1303+ slave_list.pop(idx)
1304+
1305+
1306+
1307
1308=== modified file 'kewpie/lib/server_mgmt/percona.py'
1309--- kewpie/lib/server_mgmt/percona.py 2011-12-01 00:14:08 +0000
1310+++ kewpie/lib/server_mgmt/percona.py 2011-12-23 00:55:24 +0000
1311@@ -103,6 +103,14 @@
1312 self.bootstrap_log = os.path.join(self.logdir,('bootstrap.log'))
1313 self.pid_file = os.path.join(self.rundir,('%s.pid' %(self.name)))
1314 self.socket_file = os.path.join(self.vardir, ('%s.sock' %(self.name)))
1315+ if len(self.socket_file) > 107:
1316+ # MySQL has a limitation of 107 characters for socket file path
1317+ # we copy the mtr workaround of creating one in /tmp
1318+ self.logging.verbose("Default socket file path: %s" %(self.socket_file))
1319+ self.socket_file = "/tmp/%s_%s.%s.sock" %(self.system_manager.uuid
1320+ ,self.owner
1321+ ,self.name)
1322+ self.logging.verbose("Changing to alternate: %s" %(self.socket_file))
1323 self.timer_file = os.path.join(self.logdir,('timer'))
1324 self.general_log_file = os.path.join(self.logdir,'mysqld.log')
1325 self.slow_query_log_file = os.path.join(self.logdir,'mysqld-slow.log')
1326
1327=== modified file 'kewpie/lib/sys_mgmt/system_management.py'
1328--- kewpie/lib/sys_mgmt/system_management.py 2011-12-05 21:23:04 +0000
1329+++ kewpie/lib/sys_mgmt/system_management.py 2011-12-23 00:55:24 +0000
1330@@ -58,7 +58,7 @@
1331 self.logging.verbose("Initializing system manager...")
1332
1333 self.skip_keys = [ 'port_manager'
1334- , 'logging_manager'
1335+ , 'logging'
1336 , 'code_manager'
1337 , 'env_manager'
1338 , 'environment_reqs'
1339@@ -69,9 +69,10 @@
1340 self.shm_path = self.find_path(["/dev/shm", "/tmp"], required=0)
1341 self.cur_os = os.uname()[0]
1342 self.cur_user = getpass.getuser()
1343+ self.rootdir = variables['qp_root']
1344 self.workdir = os.path.abspath(variables['workdir'])
1345 self.testdir = os.path.abspath(variables['testdir'])
1346- self.datadir = os.path.abspath(os.path.join(variables['testdir'],'qp_data'))
1347+ self.datadir = os.path.join(self.rootdir,'qp_data')
1348 self.top_srcdir = os.path.abspath(variables['topsrcdir'])
1349 self.top_builddir = os.path.abspath(variables['topbuilddir'])
1350 self.start_dirty = variables['startdirty']
1351@@ -84,6 +85,7 @@
1352 self.gdb = variables['gdb']
1353 self.manual_gdb = variables['manualgdb']
1354 self.randgen_path = variables['randgenpath']
1355+ self.randgen_seed = variables['randgenseed']
1356 # there may be a better place to put this...
1357 self.innobackupex_path = variables['innobackupexpath']
1358 self.xtrabackup_path = variables['xtrabackuppath']
1359@@ -239,7 +241,12 @@
1360 else:
1361 shutil.rmtree(full_path)
1362 self.logging.debug("Creating directory: %s" %(dirname))
1363- os.makedirs(full_path)
1364+ try:
1365+ os.makedirs(full_path)
1366+ except IOError, e:
1367+ self.logging.error("Problem creating directory: %s" %(full_path))
1368+ self.logging.error(e)
1369+ sys.exit(1)
1370 return full_path
1371
1372 def remove_dir(self, dirname, require_empty=0 ):
1373
1374=== added file 'kewpie/percona_tests/__init__.py'
1375=== modified file 'kewpie/percona_tests/crashme/crashme_test.py'
1376--- kewpie/percona_tests/crashme/crashme_test.py 2011-11-23 01:07:32 +0000
1377+++ kewpie/percona_tests/crashme/crashme_test.py 2011-12-23 00:55:24 +0000
1378@@ -34,7 +34,7 @@
1379
1380 def test_runCrashme(self):
1381 self.servers = servers
1382- test_cmd = "$SQLBENCH_DIR/crash-me --server=mysqld --host=127.0.0.1 --force --dir=$MYSQL_TEST_WORKDIR --connect-options=port=$MASTER_MYPORT --verbose --debug --user=root"
1383+ test_cmd = "$SQLBENCH_DIR/crash-me --server=mysqld --host=127.0.0.1 --force --dir=$MYSQL_TEST_WORKDIR --connect-options=port=$MASTER_MYPORT --verbose --debug --user=root --batch-mode"
1384 test_status, retcode, output = execute_crashme(test_cmd, test_executor, servers)
1385 self.assertTrue(retcode==0, output)
1386 self.assertTrue(test_status=='pass', output)
1387
1388=== added directory 'kewpie/percona_tests/innodbCrash'
1389=== added file 'kewpie/percona_tests/innodbCrash/__init__.py'
1390=== added file 'kewpie/percona_tests/innodbCrash/crashCommitAfterLog_test.py'
1391--- kewpie/percona_tests/innodbCrash/crashCommitAfterLog_test.py 1970-01-01 00:00:00 +0000
1392+++ kewpie/percona_tests/innodbCrash/crashCommitAfterLog_test.py 2011-12-23 00:55:24 +0000
1393@@ -0,0 +1,60 @@
1394+#! /usr/bin/env python
1395+# -*- mode: python; indent-tabs-mode: nil; -*-
1396+# vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
1397+#
1398+# Copyright (C) 2011 Patrick Crews
1399+#
1400+#
1401+# This program is free software; you can redistribute it and/or modify
1402+# it under the terms of the GNU General Public License as published by
1403+# the Free Software Foundation; either version 2 of the License, or
1404+# (at your option) any later version.
1405+#
1406+# This program is distributed in the hope that it will be useful,
1407+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1408+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1409+# GNU General Public License for more details.
1410+#
1411+# You should have received a copy of the GNU General Public License
1412+# along with this program; if not, write to the Free Software
1413+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1414+
1415+from percona_tests.innodbCrash.innodbCrashTestCase import innodbCrashTestCase
1416+from percona_tests.innodbCrash import suite_config
1417+
1418+server_requirements = suite_config.server_requirements
1419+server_requests = suite_config.server_requests
1420+servers = suite_config.servers
1421+test_executor = suite_config.test_executor
1422+
1423+class basicTest(innodbCrashTestCase):
1424+
1425+ def test_crash(self):
1426+ """
1427+ self.logging = test_executor.logging
1428+ self.servers = servers
1429+ self.master_server = servers[0]
1430+ self.slave_server = servers[1]
1431+ self.randgen_threads = suite_config.randgen_threads
1432+ self.randgen_queries_per_thread = suite_config.randgen_queries_per_thread
1433+ self.crashes = suite_config.crashes
1434+ """
1435+ self.initialize(test_executor, servers, suite_config)
1436+
1437+ # create our table
1438+ self.test_bed_cmd = "./gendata.pl --spec=conf/percona/percona_no_blob.zz "
1439+ self.create_test_bed()
1440+
1441+ # Our randgen load-generation command (transactional grammar)
1442+ self.test_seq = [ "./gentest.pl"
1443+ , "--grammar=conf/percona/trx_crash_commit_after_log.yy"
1444+ , "--queries=%d" %(self.randgen_queries_per_thread)
1445+ , "--threads=%d" %(self.randgen_threads)
1446+ , "--sqltrace"
1447+ , "--debug"
1448+ , "--seed=%s" %(self.randgen_seed)
1449+ ]
1450+ self.test_seq = " ".join(self.test_seq)
1451+ self.execute_crash_test()
1452+
1453+
1454
1455=== added file 'kewpie/percona_tests/innodbCrash/crashCommitAfterPrepare_test.py'
1456--- kewpie/percona_tests/innodbCrash/crashCommitAfterPrepare_test.py 1970-01-01 00:00:00 +0000
1457+++ kewpie/percona_tests/innodbCrash/crashCommitAfterPrepare_test.py 2011-12-23 00:55:24 +0000
1458@@ -0,0 +1,62 @@
1459+#! /usr/bin/env python
1460+# -*- mode: python; indent-tabs-mode: nil; -*-
1461+# vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
1462+#
1463+# Copyright (C) 2011 Patrick Crews
1464+#
1465+#
1466+# This program is free software; you can redistribute it and/or modify
1467+# it under the terms of the GNU General Public License as published by
1468+# the Free Software Foundation; either version 2 of the License, or
1469+# (at your option) any later version.
1470+#
1471+# This program is distributed in the hope that it will be useful,
1472+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1473+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1474+# GNU General Public License for more details.
1475+#
1476+# You should have received a copy of the GNU General Public License
1477+# along with this program; if not, write to the Free Software
1478+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1479+
1480+
1481+from percona_tests.innodbCrash.innodbCrashTestCase import innodbCrashTestCase
1482+from percona_tests.innodbCrash import suite_config
1483+
1484+server_requirements = suite_config.server_requirements
1485+server_requests = suite_config.server_requests
1486+servers = suite_config.servers
1487+test_executor = suite_config.test_executor
1488+
1489+class basicTest(innodbCrashTestCase):
1490+
1491+ def test_crash(self):
1492+ """
1493+ self.logging = test_executor.logging
1494+ self.servers = servers
1495+ self.master_server = servers[0]
1496+ self.slave_server = servers[1]
1497+ self.randgen_threads = suite_config.randgen_threads
1498+ self.randgen_queries_per_thread = suite_config.randgen_queries_per_thread
1499+ self.crashes = suite_config.crashes
1500+ """
1501+ self.initialize(test_executor, servers, suite_config)
1502+
1503+ # create our table
1504+ self.test_bed_cmd = "./gendata.pl --spec=conf/percona/percona_no_blob.zz "
1505+ self.create_test_bed()
1506+
1507+ # Our randgen load-generation command (transactional grammar)
1508+ self.test_seq = [ "./gentest.pl"
1509+ , "--grammar=conf/percona/trx_crash_commit_after_prepare.yy"
1510+ , "--queries=%d" %(self.randgen_queries_per_thread)
1511+ , "--threads=%d" %(self.randgen_threads)
1512+ , "--sqltrace"
1513+ , "--debug"
1514+ , "--seed=%s" %(self.randgen_seed)
1515+ ]
1516+ self.test_seq = " ".join(self.test_seq)
1517+ self.execute_crash_test()
1518+
1519+
1520+
1521
1522=== added file 'kewpie/percona_tests/innodbCrash/crashCommitAfter_test.py'
1523--- kewpie/percona_tests/innodbCrash/crashCommitAfter_test.py 1970-01-01 00:00:00 +0000
1524+++ kewpie/percona_tests/innodbCrash/crashCommitAfter_test.py 2011-12-23 00:55:24 +0000
1525@@ -0,0 +1,59 @@
1526+#! /usr/bin/env python
1527+# -*- mode: python; indent-tabs-mode: nil; -*-
1528+# vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
1529+#
1530+# Copyright (C) 2011 Patrick Crews
1531+#
1532+#
1533+# This program is free software; you can redistribute it and/or modify
1534+# it under the terms of the GNU General Public License as published by
1535+# the Free Software Foundation; either version 2 of the License, or
1536+# (at your option) any later version.
1537+#
1538+# This program is distributed in the hope that it will be useful,
1539+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1540+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1541+# GNU General Public License for more details.
1542+#
1543+# You should have received a copy of the GNU General Public License
1544+# along with this program; if not, write to the Free Software
1545+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1546+
1547+from percona_tests.innodbCrash.innodbCrashTestCase import innodbCrashTestCase
1548+from percona_tests.innodbCrash import suite_config
1549+
1550+server_requirements = suite_config.server_requirements
1551+server_requests = suite_config.server_requests
1552+servers = suite_config.servers
1553+test_executor = suite_config.test_executor
1554+
1555+class basicTest(innodbCrashTestCase):
1556+
1557+ def test_crash(self):
1558+ """
1559+ self.logging = test_executor.logging
1560+ self.servers = servers
1561+ self.master_server = servers[0]
1562+ self.slave_server = servers[1]
1563+ self.randgen_threads = suite_config.randgen_threads
1564+ self.randgen_queries_per_thread = suite_config.randgen_queries_per_thread
1565+ self.crashes = suite_config.crashes
1566+ """
1567+ self.initialize(test_executor, servers, suite_config)
1568+
1569+ # create our table
1570+ self.test_bed_cmd = "./gendata.pl --spec=conf/percona/percona_no_blob.zz "
1571+ self.create_test_bed()
1572+
1573+ # Our randgen load-generation command (transactional grammar)
1574+ self.test_seq = [ "./gentest.pl"
1575+ , "--grammar=conf/percona/trx_crash_commit_after.yy"
1576+ , "--queries=%d" %(self.randgen_queries_per_thread)
1577+ , "--threads=%d" %(self.randgen_threads)
1578+ , "--sqltrace"
1579+ , "--debug"
1580+ , "--seed=%s" %(self.randgen_seed)
1581+ ]
1582+ self.test_seq = " ".join(self.test_seq)
1583+ self.execute_crash_test()
1584+
1585
1586=== added file 'kewpie/percona_tests/innodbCrash/crashCommitBeforeUnlog_test.py'
1587--- kewpie/percona_tests/innodbCrash/crashCommitBeforeUnlog_test.py 1970-01-01 00:00:00 +0000
1588+++ kewpie/percona_tests/innodbCrash/crashCommitBeforeUnlog_test.py 2011-12-23 00:55:24 +0000
1589@@ -0,0 +1,59 @@
1590+#! /usr/bin/env python
1591+# -*- mode: python; indent-tabs-mode: nil; -*-
1592+# vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
1593+#
1594+# Copyright (C) 2011 Patrick Crews
1595+#
1596+#
1597+# This program is free software; you can redistribute it and/or modify
1598+# it under the terms of the GNU General Public License as published by
1599+# the Free Software Foundation; either version 2 of the License, or
1600+# (at your option) any later version.
1601+#
1602+# This program is distributed in the hope that it will be useful,
1603+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1604+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1605+# GNU General Public License for more details.
1606+#
1607+# You should have received a copy of the GNU General Public License
1608+# along with this program; if not, write to the Free Software
1609+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1610+
1611+from percona_tests.innodbCrash.innodbCrashTestCase import innodbCrashTestCase
1612+from percona_tests.innodbCrash import suite_config
1613+
1614+server_requirements = suite_config.server_requirements
1615+server_requests = suite_config.server_requests
1616+servers = suite_config.servers
1617+test_executor = suite_config.test_executor
1618+
1619+class basicTest(innodbCrashTestCase):
1620+
1621+ def test_crash(self):
1622+ """
1623+ self.logging = test_executor.logging
1624+ self.servers = servers
1625+ self.master_server = servers[0]
1626+ self.slave_server = servers[1]
1627+ self.randgen_threads = suite_config.randgen_threads
1628+ self.randgen_queries_per_thread = suite_config.randgen_queries_per_thread
1629+ self.crashes = suite_config.crashes
1630+ """
1631+ self.initialize(test_executor, servers, suite_config)
1632+
1633+ # create our table
1634+ self.test_bed_cmd = "./gendata.pl --spec=conf/percona/percona_no_blob.zz "
1635+ self.create_test_bed()
1636+
1637+ # Our randgen load-generation command (transactional grammar)
1638+ self.test_seq = [ "./gentest.pl"
1639+ , "--grammar=conf/percona/trx_crash_commit_before_unlog.yy"
1640+ , "--queries=%d" %(self.randgen_queries_per_thread)
1641+ , "--threads=%d" %(self.randgen_threads)
1642+ , "--sqltrace"
1643+ , "--debug"
1644+ , "--seed=%s" %(self.randgen_seed)
1645+ ]
1646+ self.test_seq = " ".join(self.test_seq)
1647+ self.execute_crash_test()
1648+
1649
1650=== added file 'kewpie/percona_tests/innodbCrash/crashCommitBefore_test.py'
1651--- kewpie/percona_tests/innodbCrash/crashCommitBefore_test.py 1970-01-01 00:00:00 +0000
1652+++ kewpie/percona_tests/innodbCrash/crashCommitBefore_test.py 2011-12-23 00:55:24 +0000
1653@@ -0,0 +1,59 @@
1654+#! /usr/bin/env python
1655+# -*- mode: python; indent-tabs-mode: nil; -*-
1656+# vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
1657+#
1658+# Copyright (C) 2011 Patrick Crews
1659+#
1660+#
1661+# This program is free software; you can redistribute it and/or modify
1662+# it under the terms of the GNU General Public License as published by
1663+# the Free Software Foundation; either version 2 of the License, or
1664+# (at your option) any later version.
1665+#
1666+# This program is distributed in the hope that it will be useful,
1667+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1668+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1669+# GNU General Public License for more details.
1670+#
1671+# You should have received a copy of the GNU General Public License
1672+# along with this program; if not, write to the Free Software
1673+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1674+
1675+from percona_tests.innodbCrash.innodbCrashTestCase import innodbCrashTestCase
1676+from percona_tests.innodbCrash import suite_config
1677+
1678+server_requirements = suite_config.server_requirements
1679+server_requests = suite_config.server_requests
1680+servers = suite_config.servers
1681+test_executor = suite_config.test_executor
1682+
1683+class basicTest(innodbCrashTestCase):
1684+
1685+ def test_crash(self):
1686+ """
1687+ self.logging = test_executor.logging
1688+ self.servers = servers
1689+ self.master_server = servers[0]
1690+ self.slave_server = servers[1]
1691+ self.randgen_threads = suite_config.randgen_threads
1692+ self.randgen_queries_per_thread = suite_config.randgen_queries_per_thread
1693+ self.crashes = suite_config.crashes
1694+ """
1695+ self.initialize(test_executor, servers, suite_config)
1696+
1697+ # create our table
1698+ self.test_bed_cmd = "./gendata.pl --spec=conf/percona/percona_no_blob.zz "
1699+ self.create_test_bed()
1700+
1701+ # Our randgen load-generation command (transactional grammar)
1702+ self.test_seq = [ "./gentest.pl"
1703+ , "--grammar=conf/percona/trx_crash_commit_before.yy"
1704+ , "--queries=%d" %(self.randgen_queries_per_thread)
1705+ , "--threads=%d" %(self.randgen_threads)
1706+ , "--sqltrace"
1707+ , "--debug"
1708+ , "--seed=%s" %(self.randgen_seed)
1709+ ]
1710+ self.test_seq = " ".join(self.test_seq)
1711+ self.execute_crash_test()
1712+
1713
1714=== added file 'kewpie/percona_tests/innodbCrash/halfBinloggedTrx_test.py'
1715--- kewpie/percona_tests/innodbCrash/halfBinloggedTrx_test.py 1970-01-01 00:00:00 +0000
1716+++ kewpie/percona_tests/innodbCrash/halfBinloggedTrx_test.py 2011-12-23 00:55:24 +0000
1717@@ -0,0 +1,59 @@
1718+#! /usr/bin/env python
1719+# -*- mode: python; indent-tabs-mode: nil; -*-
1720+# vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
1721+#
1722+# Copyright (C) 2011 Patrick Crews
1723+#
1724+#
1725+# This program is free software; you can redistribute it and/or modify
1726+# it under the terms of the GNU General Public License as published by
1727+# the Free Software Foundation; either version 2 of the License, or
1728+# (at your option) any later version.
1729+#
1730+# This program is distributed in the hope that it will be useful,
1731+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1732+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1733+# GNU General Public License for more details.
1734+#
1735+# You should have received a copy of the GNU General Public License
1736+# along with this program; if not, write to the Free Software
1737+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1738+
1739+from percona_tests.innodbCrash.innodbCrashTestCase import innodbCrashTestCase
1740+from percona_tests.innodbCrash import suite_config
1741+
1742+server_requirements = suite_config.server_requirements
1743+server_requests = suite_config.server_requests
1744+servers = suite_config.servers
1745+test_executor = suite_config.test_executor
1746+
1747+class basicTest(innodbCrashTestCase):
1748+
1749+ def test_crash(self):
1750+ """
1751+ self.logging = test_executor.logging
1752+ self.servers = servers
1753+ self.master_server = servers[0]
1754+ self.slave_server = servers[1]
1755+ self.randgen_threads = suite_config.randgen_threads
1756+ self.randgen_queries_per_thread = suite_config.randgen_queries_per_thread
1757+ self.crashes = suite_config.crashes
1758+ """
1759+ self.initialize(test_executor, servers, suite_config)
1760+
1761+ # create our table
1762+ self.test_bed_cmd = "./gendata.pl --spec=conf/percona/percona_no_blob.zz "
1763+ self.create_test_bed()
1764+
1765+ # Our randgen load-generation command (transactional grammar)
1766+ self.test_seq = [ "./gentest.pl"
1767+ , "--grammar=conf/percona/trx_half_binlogged_transaction.yy"
1768+ , "--queries=%d" %(self.randgen_queries_per_thread)
1769+ , "--threads=%d" %(self.randgen_threads)
1770+ , "--sqltrace"
1771+ , "--debug"
1772+ , "--seed=%s" %(self.randgen_seed)
1773+ ]
1774+ self.test_seq = " ".join(self.test_seq)
1775+ self.execute_crash_test()
1776+
1777
1778=== added file 'kewpie/percona_tests/innodbCrash/innodbCrash2_test.py'
1779--- kewpie/percona_tests/innodbCrash/innodbCrash2_test.py 1970-01-01 00:00:00 +0000
1780+++ kewpie/percona_tests/innodbCrash/innodbCrash2_test.py 2011-12-23 00:55:24 +0000
1781@@ -0,0 +1,140 @@
1782+#! /usr/bin/env python
1783+# -*- mode: python; indent-tabs-mode: nil; -*-
1784+# vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
1785+#
1786+# Copyright (C) 2011 Patrick Crews
1787+#
1788+#
1789+# This program is free software; you can redistribute it and/or modify
1790+# it under the terms of the GNU General Public License as published by
1791+# the Free Software Foundation; either version 2 of the License, or
1792+# (at your option) any later version.
1793+#
1794+# This program is distributed in the hope that it will be useful,
1795+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1796+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1797+# GNU General Public License for more details.
1798+#
1799+# You should have received a copy of the GNU General Public License
1800+# along with this program; if not, write to the Free Software
1801+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1802+
1803+import os
1804+import signal
1805+import threading
1806+import time
1807+
1808+from percona_tests.innodbCrash.innodbCrashTestCase import innodbCrashTestCase
1809+from percona_tests.innodbCrash import suite_config
1810+
1811+server_requirements = suite_config.server_requirements
1812+server_requests = suite_config.server_requests
1813+servers = suite_config.servers
1814+test_executor = suite_config.test_executor
1815+
1816+class Worker(threading.Thread):
1817+ def __init__( self
1818+ , xid
1819+ , thread_desc
1820+ , time_delay
1821+ , test_executor
1822+ , server
1823+ , logging):
1824+ threading.Thread.__init__(self)
1825+ self.server = server
1826+ self.xid = xid
1827+ self.desc = thread_desc
1828+ self.time_delay = time_delay
1829+ self.test_executor = test_executor
1830+ self.logging = logging
1831+ self.start()
1832+
1833+ def finish(self):
1834+ return
1835+
1836+ def run(self):
1837+ try:
1838+ self.logging.test_debug( "Will crash after:%d seconds" %(self.time_delay))
1839+ time.sleep(self.time_delay)
1840+ pid = None
1841+ timeout = self.time_delay*6
1842+ decrement = .25
1843+ while not pid and timeout:
1844+ pid = self.server.get_pid()
1845+ time.sleep(decrement)
1846+ timeout -= decrement
1847+ self.logging.test_debug( "Crashing server: port: %s, pid: %s" %(self.server.master_port, pid))
1848+ try:
1849+ os.kill(int(self.server.pid), signal.SIGKILL)
1850+ self.logging.test_debug( "Killed server pid: %s" %pid)
1851+ except OSError, e:
1852+ self.logging.test_debug( "Didn't kill server pid: %s" %pid)
1853+ self.logging.test_debug( e)
1854+ except Exception, e:
1855+ print "caught (%s)" % e
1856+ finally:
1857+ self.finish()
1858+
1859+class basicTest(innodbCrashTestCase):
1860+ """ This test case creates a master-slave pair
1861+ then generates a randgen load against the master
1862+ The master server is killed after %kill_db_after seconds
1863+ and restarted. We restart the slave, then ensure
1864+ the master and slave have matching table checksums once
1865+ they are synced and the test load is stopped
1866+
1867+ """
1868+
1869+ def test_crash(self):
1870+ self.initialize(test_executor, servers, suite_config)
1871+ workers = []
1872+
1873+ # create our table
1874+ self.test_bed_cmd = "./gendata.pl --spec=conf/percona/percona_no_blob.zz "
1875+ self.create_test_bed()
1876+
1877+ # generate our workload via randgen
1878+ test_seq = [ "./gentest.pl"
1879+ , "--grammar=conf/percona/translog_concurrent1.yy"
1880+ , "--queries=%d" %(self.randgen_queries_per_thread)
1881+ , "--threads=%d" %(self.randgen_threads)
1882+ , "--sqltrace"
1883+ , "--debug"
1884+ , "--seed=%s" %(self.randgen_seed)
1885+ ]
1886+
1887+ while self.crashes:
1888+ self.logging.test_debug( "Crashes remaining: %d" %(self.crashes))
1889+ self.crashes -= 1
1890+ worker = Worker( 1
1891+ , 'time_delay_kill_thread'
1892+ , self.kill_db_after
1893+ , self.test_executor
1894+ , self.master_server
1895+ , self.logging
1896+ )
1897+ workers.append(worker)
1898+
1899+ randgen_process = self.get_randgen_process(test_seq, self.test_executor, self.master_server)
1900+ #if not self.master_server.ping(quiet=True) and (randgen_process.poll() is None):
1901+ # Our server is dead, but randgen is running, we kill it to speed up testing
1902+ #randgen_process.send_signal(signal.SIGINT)
1903+
1904+ for w in workers:
1905+ w.join()
1906+ time.sleep(2)
1907+ while not randgen_process.poll():
1908+ randgen_process.send_signal(signal.SIGINT)
1909+
1910+ retcode = self.master_server.start()
1911+ timeout = 300
1912+ decrement = 1
1913+ while timeout and not self.master_server.ping(quiet=True):
1914+ time.sleep(decrement)
1915+ timeout -= decrement
1916+ self.slave_server.slave_stop()
1917+ self.slave_server.slave_start()
1918+ self.master_server.wait_sync_with_slaves([self.slave_server],timeout=60)
1919+ result = self.check_slaves_by_checksum(self.master_server,[self.slave_server])
1920+ self.assertEqual(result,None,msg=result)
1921+
1922
1923=== added file 'kewpie/percona_tests/innodbCrash/innodbCrash3_test.py'
1924--- kewpie/percona_tests/innodbCrash/innodbCrash3_test.py 1970-01-01 00:00:00 +0000
1925+++ kewpie/percona_tests/innodbCrash/innodbCrash3_test.py 2011-12-23 00:55:24 +0000
1926@@ -0,0 +1,58 @@
1927+#! /usr/bin/env python
1928+# -*- mode: python; indent-tabs-mode: nil; -*-
1929+# vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
1930+#
1931+# Copyright (C) 2011 Patrick Crews
1932+#
1933+#
1934+# This program is free software; you can redistribute it and/or modify
1935+# it under the terms of the GNU General Public License as published by
1936+# the Free Software Foundation; either version 2 of the License, or
1937+# (at your option) any later version.
1938+#
1939+# This program is distributed in the hope that it will be useful,
1940+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1941+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1942+# GNU General Public License for more details.
1943+#
1944+# You should have received a copy of the GNU General Public License
1945+# along with this program; if not, write to the Free Software
1946+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1947+
1948+from percona_tests.innodbCrash.innodbCrashTestCase import innodbCrashTestCase
1949+from percona_tests.innodbCrash import suite_config
1950+
1951+server_requirements = suite_config.server_requirements
1952+server_requests = suite_config.server_requests
1953+servers = suite_config.servers
1954+test_executor = suite_config.test_executor
1955+
1956+class basicTest(innodbCrashTestCase):
1957+
1958+ def test_crash(self):
1959+ """
1960+ self.logging = test_executor.logging
1961+ self.servers = servers
1962+ self.master_server = servers[0]
1963+ self.slave_server = servers[1]
1964+ self.randgen_threads = suite_config.randgen_threads
1965+ self.randgen_queries_per_thread = suite_config.randgen_queries_per_thread
1966+ self.crashes = suite_config.crashes
1967+ """
1968+ self.initialize(test_executor, servers, suite_config)
1969+
1970+ # create our table
1971+ self.test_bed_cmd = "./gendata.pl --spec=conf/percona/percona_no_blob.zz "
1972+ self.create_test_bed()
1973+
1974+ # Our randgen load-generation command (transactional grammar)
1975+ self.test_seq = [ "./gentest.pl"
1976+ , "--grammar=conf/percona/trx_randDebugCrash.yy"
1977+ , "--queries=%d" %(self.randgen_queries_per_thread)
1978+ , "--threads=%d" %(self.randgen_threads)
1979+ , "--sqltrace"
1980+ , "--debug"
1981+ , "--seed=%s" %(self.randgen_seed)
1982+ ]
1983+ self.test_seq = " ".join(self.test_seq)
1984+ self.execute_crash_test()
1985
1986=== added file 'kewpie/percona_tests/innodbCrash/innodbCrashTestCase.py'
1987--- kewpie/percona_tests/innodbCrash/innodbCrashTestCase.py 1970-01-01 00:00:00 +0000
1988+++ kewpie/percona_tests/innodbCrash/innodbCrashTestCase.py 2011-12-23 00:55:24 +0000
1989@@ -0,0 +1,69 @@
1990+#! /usr/bin/env python
1991+# -*- mode: python; indent-tabs-mode: nil; -*-
1992+# vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
1993+#
1994+# Copyright (C) 2011 Patrick Crews
1995+#
1996+#
1997+# This program is free software; you can redistribute it and/or modify
1998+# it under the terms of the GNU General Public License as published by
1999+# the Free Software Foundation; either version 2 of the License, or
2000+# (at your option) any later version.
2001+#
2002+# This program is distributed in the hope that it will be useful,
2003+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2004+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2005+# GNU General Public License for more details.
2006+#
2007+# You should have received a copy of the GNU General Public License
2008+# along with this program; if not, write to the Free Software
2009+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2010+
2011+import signal
2012+import time
2013+
2014+from lib.util.mysqlBaseTestCase import mysqlBaseTestCase
2015+
2016+class innodbCrashTestCase(mysqlBaseTestCase):
2017+ def initialize(self,test_executor, servers, suite_config):
2018+ self.logging = test_executor.logging
2019+ self.test_executor = test_executor
2020+ self.servers = servers
2021+ self.master_server = servers[0]
2022+ self.slave_server = servers[1]
2023+ self.randgen_threads = suite_config.randgen_threads
2024+ self.randgen_queries_per_thread = suite_config.randgen_queries_per_thread
2025+ self.randgen_seed = test_executor.system_manager.randgen_seed
2026+ self.crashes = suite_config.crashes
2027+ self.kill_db_after = suite_config.kill_db_after
2028+
2029+ def create_test_bed(self):
2030+ retcode, output = self.execute_randgen(self.test_bed_cmd, self.test_executor, self.master_server)
2031+ self.assertEqual(retcode,0, output)
2032+
2033+
2034+ def execute_crash_test(self):
2035+ while self.crashes:
2036+ self.logging.test_debug ("Crashes remaining: %d" %(self.crashes))
2037+ self.crashes -= 1
2038+
2039+ # generate our workload via randgen
2040+ randgen_process = self.execute_randgen(self.test_seq, self.test_executor, self.master_server)
2041+
2042+ if self.master_server.ping(quiet=True):
2043+ # randgen didn't kill the master : (
2044+ self.logging.test_debug ("Killing master manually...")
2045+ self.master_server.die()
2046+
2047+ retcode = self.master_server.start()
2048+ timeout = 300
2049+ decrement = 1
2050+ while timeout and not self.master_server.ping(quiet=True):
2051+ time.sleep(decrement)
2052+ timeout -= decrement
2053+ self.slave_server.slave_stop()
2054+ self.slave_server.slave_start()
2055+ self.master_server.wait_sync_with_slaves([self.slave_server],timeout=60)
2056+ result = self.check_slaves_by_checksum(self.master_server,[self.slave_server])
2057+ self.assertEqual(result,None,msg=result)
2058+
2059
2060=== added file 'kewpie/percona_tests/innodbCrash/suite_config.py'
2061--- kewpie/percona_tests/innodbCrash/suite_config.py 1970-01-01 00:00:00 +0000
2062+++ kewpie/percona_tests/innodbCrash/suite_config.py 2011-12-23 00:55:24 +0000
2063@@ -0,0 +1,29 @@
2064+# suite_config.py
2065+# module containing suite-wide standard variables
2066+# provides single place to tweak how all related tests run
2067+
2068+server_requirements = [ [ ("--binlog-do-db=test "
2069+ "--innodb-file-per-table "
2070+ "--innodb_file_format='Barracuda' "
2071+ #"--innodb_log_compressed_pages=0 "
2072+ #"--innodb_background_checkpoint=0 "
2073+ "--sync_binlog=100 "
2074+ "--innodb_flush_log_at_trx_commit=2 "
2075+ )]
2076+ ,[ ("--innodb_file_format='Barracuda' "
2077+ #"--innodb_log_compressed_pages=1 "
2078+ "--innodb_flush_log_at_trx_commit=2"
2079+ )]
2080+ ]
2081+server_requests = {'join_cluster':[(0,1)]}
2082+servers = []
2083+server_manager = None
2084+test_executor = None
2085+randgen_threads = 5
2086+randgen_queries_per_thread = 10000
2087+crashes = 10
2088+# This only applies to innodbCrash2 test
2089+# as a time delay for when the kill thread
2090+# will stop the master-server
2091+kill_db_after = 20
2092+

Subscribers

People subscribed via source and target branches