~ubuntu-branches/ubuntu/trusty/drizzle/trusty

« back to all changes in this revision

Viewing changes to tests/lib/dbqp_opts/test_run_options.py

  • Committer: Package Import Robot
  • Author(s): Clint Byrum
  • Date: 2012-06-19 10:46:49 UTC
  • mfrom: (1.1.6)
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20120619104649-e2l0ggd4oz3um0f4
Tags: upstream-7.1.36-stable
ImportĀ upstreamĀ versionĀ 7.1.36-stable

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, 2011 Patrick Crews
 
6
#
 
7
# This program is free software; you can redistribute it and/or modify
 
8
# it under the terms of the GNU General Public License as published by
 
9
# the Free Software Foundation; either version 2 of the License, or
 
10
# (at your option) any later version.
 
11
#
 
12
# This program is distributed in the hope that it will be useful,
 
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
# GNU General Public License for more details.
 
16
#
 
17
# You should have received a copy of the GNU General Public License
 
18
# along with this program; if not, write to the Free Software
 
19
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
20
 
 
21
 
 
22
 
 
23
"""Processes command line options for Drizzle test-runner"""
 
24
 
 
25
import os
 
26
import sys
 
27
import copy
 
28
import exceptions
 
29
import optparse
 
30
 
 
31
# functions
 
32
def comma_list_split(option, opt, value, parser):
 
33
    """Callback for splitting input expected in list form"""
 
34
    cur_list = getattr(parser.values, option.dest,[])
 
35
    input_list = value.split(',')
 
36
    # this is a hack to work with make target - we
 
37
    # don't deal with a dangling ',' in our list
 
38
    if '' in input_list:
 
39
        input_list.remove('')
 
40
    if cur_list:
 
41
        value_list = cur_list + input_list 
 
42
    else:
 
43
        value_list = input_list 
 
44
    setattr(parser.values, option.dest, value_list)
 
45
 
 
46
def get_abspath(option, opt, value, parser):
 
47
    """ Utility function to make sure we have absolute paths
 
48
        if the user supplies values
 
49
 
 
50
    """
 
51
    the_path = os.path.abspath(value)
 
52
    setattr(parser.values, option.dest, the_path)
 
53
 
 
54
def organize_options(args, test_cases):
 
55
    """Put our arguments in a nice dictionary
 
56
       We use option.dest as dictionary key
 
57
       item = supplied input
 
58
 ['
 
59
    """
 
60
    variables = {}
 
61
    # we make a copy as the python manual on vars
 
62
    # says we shouldn't alter the dictionary returned
 
63
    # by vars() - could affect symbol table?
 
64
    variables = copy.copy(vars(args))
 
65
    variables['test_cases']= test_cases
 
66
    # This code should become a function once
 
67
    # enough thought has been given to it
 
68
    if variables['manualgdb']:
 
69
        variables['gdb']=True
 
70
    if variables['repeat'] <= 0:
 
71
        print "Setting --repeat=1.  You chose a silly value that I will ignore :P"
 
72
        variables['repeat'] = 1
 
73
    if variables['mode'] == 'randgen' or variables['gendatafile']:
 
74
        print "Setting --no-secure-file-priv=True for randgen usage..."
 
75
        variables['nosecurefilepriv']=True
 
76
    if variables['mode'] == 'cleanup':
 
77
        print "Setting --start-dirty=True for cleanup mode..."
 
78
        variables['startdirty']=True
 
79
    if variables['libeatmydata'] and os.path.exists(variables['libeatmydatapath']):
 
80
        # We are using libeatmydata vs. shared mem for server speedup
 
81
        print "Using libeatmydata at %s.  Setting --no-shm / not using shared memory for testing..." %(variables['libeatmydatapath'])
 
82
        variables['noshm']=True
 
83
    return variables
 
84
 
 
85
def populate_defaults(variables, basedir_default):
 
86
    """ We fill in any default values that need
 
87
        to be put in post-parsing
 
88
 
 
89
    """
 
90
    if not variables['basedir']:
 
91
        # We populate this value with the default now
 
92
        # it allows us to have a default and have user
 
93
        # supplied opts to override them
 
94
        variables['basedir'].append(basedir_default)
 
95
    return variables
 
96
 
 
97
def handle_user_opts(variables, basedir_default, testdir_default, suitepaths_default):
 
98
    """ Some variables are dependent upon default values
 
99
        We do the probably hacky thing of going through
 
100
        and updating them accordingly
 
101
 
 
102
        We make the assumption / decision that only
 
103
        the first basedir value supplied should
 
104
        be applicable when searching for tests
 
105
 
 
106
    """
 
107
    master_basedir = os.path.abspath(variables['basedir'][0])
 
108
    if master_basedir != basedir_default:
 
109
        new_path = os.path.join(master_basedir, 'plugin')
 
110
        search_path = os.path.join(basedir_default,'plugin')
 
111
        tmp = variables['suitepaths']
 
112
        tmp[tmp.index(search_path)] = new_path
 
113
        variables['suitepaths'] = tmp
 
114
    if variables['testdir'] != testdir_default:
 
115
        new_path = os.path.join(variables['testdir'],'suite')
 
116
        search_path = os.path.join(testdir_default,'suite')
 
117
        tmp = variables['suitepaths']
 
118
        tmp[tmp.index(search_path)] = new_path
 
119
        variables['suitepaths'] = tmp
 
120
    return variables
 
121
 
 
122
 
 
123
# Create the CLI option parser
 
124
parser= optparse.OptionParser(version='%prog (database quality platform aka project steve austin) version 0.1.1')
 
125
 
 
126
# set some default values
 
127
testdir_default = os.path.abspath(os.getcwd())
 
128
workdir_default = os.path.join(testdir_default,'workdir')
 
129
clientbindir_default = os.path.abspath(os.path.join(testdir_default,'../client'))
 
130
basedir_default = os.path.split(testdir_default)[0]
 
131
server_type_default = 'drizzle'
 
132
valgrind_suppression_default = os.path.join(testdir_default,'valgrind.supp')
 
133
suitepaths_default = [ os.path.join(basedir_default,'plugin')
 
134
                     , os.path.join(testdir_default,'suite')
 
135
                     ]
 
136
randgen_path_default = os.path.join(testdir_default,'randgen')
 
137
 
 
138
 
 
139
config_control_group = optparse.OptionGroup(parser, 
 
140
                     "Configuration controls - allows you to specify a file with a number of options already specified")
 
141
config_control_group.add_option(
 
142
   "--sys_config_file"
 
143
    , dest="sysconfigfilepath"
 
144
    , action='store'
 
145
    , default=None # We want to have a file that will be our default defaults file...
 
146
    , help="The file that specifies system configuration specs for dbqp to execute tests (not yet implemented)"
 
147
    )
 
148
parser.add_option_group(config_control_group)
 
149
 
 
150
 
 
151
system_control_group = optparse.OptionGroup(parser, 
 
152
                         "Options for the test-runner itself - defining the system under test and how to execute tests")
 
153
 
 
154
system_control_group.add_option(
 
155
      "--force"
 
156
    , dest="force"
 
157
    , action="store_true"
 
158
    , default=False
 
159
    , help="Set this to continue test execution beyond the first failed test"
 
160
    )
 
161
 
 
162
system_control_group.add_option(
 
163
       "--start-and-exit"
 
164
     , dest="startandexit"
 
165
     , action="store_true"
 
166
     , default=False
 
167
     , help="Spin up the server(s) for the first specified test then exit (will leave servers running)"
 
168
     )
 
169
 
 
170
system_control_group.add_option(
 
171
       "--verbose"
 
172
     , dest="verbose"
 
173
     , action="store_true"
 
174
     , default = False
 
175
     , help="Produces extensive output about test-runner state.  Distinct from --debug"
 
176
     )
 
177
   
 
178
system_control_group.add_option(
 
179
       "--debug"
 
180
     , dest="debug"
 
181
     , action="store_true"
 
182
     , default = False
 
183
     , help="Provide internal-level debugging output.  Distinct from --verbose"
 
184
     )
 
185
 
 
186
system_control_group.add_option(
 
187
       "--mode"
 
188
     , dest="mode"
 
189
     , default="dtr"
 
190
     , help="Testing mode.  We currently support dtr, randgen, sysbench, sqlbench, crashme and cleanup modes.  See docs for further details about individual modes [%default]"
 
191
     )
 
192
 
 
193
system_control_group.add_option(
 
194
       "--record"
 
195
     , dest="record"
 
196
     , action="store_true"
 
197
     , default=False
 
198
     , help="Record a testcase result (if the testing mode supports it) [%default]"
 
199
     )
 
200
 
 
201
system_control_group.add_option(
 
202
       "--fast"
 
203
     , dest="fast"
 
204
     , action="store_true"
 
205
     , default=False
 
206
     , help="Don't try to cleanup from earlier runs (currently just a placeholder) [%default]"
 
207
     )
 
208
   
 
209
parser.add_option_group(system_control_group)
 
210
 
 
211
test_control_group = optparse.OptionGroup(parser, 
 
212
                         "Options for controlling which tests are executed")
 
213
 
 
214
test_control_group.add_option(
 
215
    "--suite"
 
216
  , dest="suitelist"
 
217
  , type='string'
 
218
  , action="callback"
 
219
  , callback=comma_list_split
 
220
  , 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]"
 
221
  )
 
222
 
 
223
test_control_group.add_option(
 
224
    "--suitepath"
 
225
  , dest="suitepaths"
 
226
  , type='string'
 
227
  , action="append"
 
228
  , default = suitepaths_default
 
229
  , help="The path containing the suite(s) you wish to execute.  Use one --suitepath for each suite you want to use. [%default]"
 
230
  )
 
231
 
 
232
test_control_group.add_option(
 
233
    "--do-test"
 
234
  , dest="dotest"
 
235
  , type='string'
 
236
  , default = None
 
237
  , help="input can either be a prefix or a regex. Will only execute tests that match the provided pattern"
 
238
  )
 
239
 
 
240
test_control_group.add_option(
 
241
    "--skip-test"
 
242
  , dest="skiptest"
 
243
  , type='string'
 
244
  , default = None
 
245
  , help = "input can either be a prefix or a regex.  Will exclude tests that match the provided pattern"
 
246
  )
 
247
 
 
248
test_control_group.add_option(
 
249
    "--reorder"
 
250
  , dest="reorder"
 
251
  , action="store_true"
 
252
  , default=False
 
253
  , help = "sort the testcases so that they are executed optimally for the given mode [%default]"
 
254
  )
 
255
 
 
256
test_control_group.add_option(
 
257
    "--repeat"
 
258
  , dest="repeat"
 
259
  , type='int'
 
260
  , action="store"
 
261
  , default=1
 
262
  , 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]"
 
263
  )
 
264
 
 
265
parser.add_option_group(test_control_group)
 
266
 
 
267
# test subject control group
 
268
# terrible name for options tht define the server / code
 
269
# that is under test
 
270
 
 
271
# find some default values
 
272
# assume we are in-tree testing in general and operating from root/test(?)
 
273
testdir_default = os.path.abspath(os.getcwd())
 
274
 
 
275
basedir_default = os.path.split(testdir_default)[0]
 
276
 
 
277
test_subject_control_group = optparse.OptionGroup(parser,
 
278
                                 "Options for defining the code that will be under test")
 
279
 
 
280
test_subject_control_group.add_option(
 
281
    "--basedir"
 
282
  , dest="basedir"
 
283
  , type='string'
 
284
  , default = []
 
285
  , action="append"
 
286
  , 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]"
 
287
  )
 
288
 
 
289
test_subject_control_group.add_option(
 
290
    "--default_server_type"
 
291
  , dest="defaultservertype"
 
292
  , type='string'
 
293
  , default = server_type_default
 
294
  , action='store'
 
295
  , help = "Defines what we consider to be the default server type.  We assume a server is default type unless specified otherwise. [%default]"
 
296
  )
 
297
 
 
298
test_subject_control_group.add_option(
 
299
    "--serverdir"
 
300
  , dest="serverpath"
 
301
  , type='string'
 
302
  , action="callback"
 
303
  , callback=get_abspath
 
304
  , help = "Path to the server executable.  [%default]"
 
305
  )
 
306
 
 
307
test_subject_control_group.add_option(
 
308
    "--client-bindir"
 
309
  , dest="clientbindir"
 
310
  , type = 'string'
 
311
  , action="callback"
 
312
  , callback=get_abspath
 
313
  , help = "Path to the directory containing client program binaries for use in testing [%default]"
 
314
  )
 
315
 
 
316
 
 
317
test_subject_control_group.add_option(
 
318
    "--default-storage-engine"
 
319
   , dest="defaultengine"
 
320
   , default = 'innodb'
 
321
   , help="Start drizzled using the specified engine [%default]"
 
322
   )    
 
323
 
 
324
 
 
325
parser.add_option_group(test_subject_control_group)
 
326
# end test subject control group
 
327
 
 
328
# environment options
 
329
 
 
330
environment_control_group = optparse.OptionGroup(parser, 
 
331
                            "Options for defining the testing environment")
 
332
 
 
333
environment_control_group.add_option(
 
334
    "--testdir"
 
335
  , dest="testdir"
 
336
  , type = 'string'
 
337
  , default = testdir_default
 
338
  , action="callback"
 
339
  , callback=get_abspath
 
340
  , help = "Path to the test dir, containing additional files for test execution. [%default]"
 
341
  )
 
342
 
 
343
environment_control_group.add_option(
 
344
    "--workdir"
 
345
  , dest="workdir"
 
346
  , type='string'
 
347
  , default = workdir_default
 
348
  , action="callback"
 
349
  , callback=get_abspath
 
350
  , help = "Path to the directory test-run will use to store generated files and directories. [%default]"
 
351
  )
 
352
 
 
353
environment_control_group.add_option(
 
354
    "--top-srcdir"
 
355
  , dest="topsrcdir"
 
356
  , type='string'
 
357
  , default = basedir_default
 
358
  , help = "build option [%default]"
 
359
  )
 
360
 
 
361
environment_control_group.add_option(
 
362
    "--top-builddir"
 
363
  , dest="topbuilddir"
 
364
  , type='string'
 
365
  , default = basedir_default
 
366
  , help = "build option [%default]"
 
367
  )
 
368
 
 
369
environment_control_group.add_option(
 
370
    "--no-shm"
 
371
  , dest="noshm"
 
372
  , action='store_true'
 
373
  , default=False
 
374
  , help = "By default, we symlink workdir to a location in shm.  Use this flag to not symlink [%default]"
 
375
  )
 
376
 
 
377
environment_control_group.add_option(
 
378
    "--libeatmydata"
 
379
  , dest="libeatmydata"
 
380
  , action='store_true'
 
381
  , default=False
 
382
  , help = "We use libeatmydata (if available) to disable fsyncs and speed up test execution.  Implies --no-shm"
 
383
  )
 
384
 
 
385
environment_control_group.add_option(
 
386
    "--libeatmydata-path"
 
387
  , dest="libeatmydatapath"
 
388
  , action='store'
 
389
  , default='/usr/local/lib/libeatmydata.so'
 
390
  , help = "Path to the libeatmydata install you want to use [%default]"
 
391
  )
 
392
 
 
393
environment_control_group.add_option(
 
394
    "--start-dirty"
 
395
  , dest="startdirty"
 
396
  , action='store_true'
 
397
  , default=False
 
398
  , help = "Don't try to clean up working directories before test execution [%default]"
 
399
  )
 
400
 
 
401
environment_control_group.add_option(
 
402
    "--no-secure-file-priv"
 
403
  , dest = "nosecurefilepriv"
 
404
  , action='store_true'
 
405
  , default=False
 
406
  , help = "Turn off the use of --secure-file-priv=vardir for started servers"
 
407
  )
 
408
 
 
409
environment_control_group.add_option(
 
410
       "--randgen-path"
 
411
     , dest="randgenpath"
 
412
     , action='store'
 
413
     , default=randgen_path_default
 
414
     , help = "The path to a randgen installation that can be used to execute randgen-based tests"
 
415
     )
 
416
 
 
417
parser.add_option_group(environment_control_group)
 
418
# end environment control group
 
419
 
 
420
option_passing_group = optparse.OptionGroup(parser,
 
421
                      "Options to pass options on to the server")
 
422
 
 
423
option_passing_group.add_option(
 
424
"--drizzled"
 
425
  , dest="drizzledoptions"
 
426
  , type='string'
 
427
  , action='append' 
 
428
  , default = []
 
429
  , help = "Pass additional options to the server.  Will be passed to all servers for all tests (mostly for --start-and-exit)"
 
430
  )
 
431
 
 
432
parser.add_option_group(option_passing_group)
 
433
# end option passing group
 
434
 
 
435
analysis_control_group = optparse.OptionGroup(parser, 
 
436
                            "Options for defining the tools we use for code analysis (valgrind, gprof, gcov, etc)")
 
437
 
 
438
analysis_control_group.add_option(
 
439
    "--valgrind"
 
440
  , dest="valgrind"
 
441
  , action='store_true'
 
442
  , default = False
 
443
  , help = "Run drizzletest and drizzled executables using valgrind with default options [%default]"
 
444
  )
 
445
 
 
446
analysis_control_group.add_option(
 
447
    "--valgrind-option"
 
448
  , dest="valgrindarglist"
 
449
  , type='string'
 
450
  , action="append"
 
451
  , help = "Pass an option to valgrind (overrides/removes default valgrind options)"
 
452
  )
 
453
 
 
454
analysis_control_group.add_option(
 
455
    "--valgrind-suppressions"
 
456
  , dest="valgrindsuppressions"
 
457
  , type='string'
 
458
  , action='store'
 
459
  , default = valgrind_suppression_default
 
460
  , help = "Point at a valgrind suppression file [%default]"
 
461
  )
 
462
 
 
463
parser.add_option_group(analysis_control_group)
 
464
 
 
465
debugger_control_group = optparse.OptionGroup(parser,
 
466
                           "Options for controlling the use of debuggers with test execution")
 
467
 
 
468
debugger_control_group.add_option(
 
469
    "--gdb"
 
470
  , dest="gdb"
 
471
  , action='store_true'
 
472
  , default=False
 
473
  , help="Start the drizzled server(s) in gdb"
 
474
  )
 
475
 
 
476
debugger_control_group.add_option(
 
477
    "--manual-gdb"
 
478
  , dest="manualgdb"
 
479
  , action='store_true'
 
480
  , default=False
 
481
  , help="Allows you to start the drizzled server(s) in gdb manually (in another window, etc)"
 
482
  )
 
483
 
 
484
parser.add_option_group(debugger_control_group)
 
485
 
 
486
utility_group = optparse.OptionGroup(parser,
 
487
                  "Options to call additional utilities such as datagen")
 
488
 
 
489
utility_group.add_option(
 
490
    "--gendata"
 
491
  , dest="gendatafile"
 
492
  , action='store'
 
493
  , type='string'
 
494
  , default=None
 
495
  , help="Call the randgen's gendata utility to use the specified configuration file.  This will populate the server prior to any test execution")
 
496
 
 
497
parser.add_option_group(utility_group)
 
498
 
 
499
# supplied will be those arguments matching an option, 
 
500
# and test_cases will be everything else
 
501
(args, test_cases)= parser.parse_args()
 
502
 
 
503
variables = {}
 
504
variables = organize_options(args, test_cases)
 
505
variables = populate_defaults(variables, basedir_default)
 
506
variables = handle_user_opts(variables, basedir_default, testdir_default, suitepaths_default)
 
507