2 # -----------------------------------------------------------------------
3 # Copyright (C) 2007-2008 King County Library System
4 # Bill Erickson <erickson@esilibrary.com>
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; either version 3
9 # of the License, or (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
15 # -----------------------------------------------------------------------
17 import sys, getopt, os, errno, shutil
18 from constrictor.properties import Properties
19 from constrictor.controller import DroneController
20 from constrictor.script import ScriptThread, ScriptManager
21 from constrictor.log import *
22 from constrictor.utils import load_props, save_props, init_dirs, init_db, open_script, PROPS_FILENAME
23 import constrictor.data
26 props_filename = PROPS_FILENAME
27 drone_controller = None
35 By default, all options are read from the properties file constrictor.properties.
36 Arguments passed via the command line will override any properties
37 loaded from the properties file
40 -h show this help message
41 -s test script to run (property constrictor.script)
42 -t number of threads to launch (property constrictor.numThreads)
43 -i number of test iterations per thread (property constrictor.numIterations)
44 -d database file (property constrictor.dbFile)
45 -p port to listen for controller connections on
46 -l listen address for incoming controller connections
47 -x clear the local cache file cache
48 -n do not store the results in the database
49 -m optional task set name
55 def read_args_and_props():
61 # see if we have any command-line args that override the properties file
62 ops, args = getopt.getopt(sys.argv[1:], 's:t:i:d:p:l:f:m:hxn')
63 options = dict( (k,v) for k,v in ops )
65 if options.has_key('-f'):
66 props_filename = options['-f']
68 load_props(props_filename)
69 props = Properties.get_properties()
71 if options.has_key('-h'):
73 if options.has_key('-s'):
74 props.set_property('constrictor.script', options['-s'])
75 if options.has_key('-t'):
76 props.set_property('constrictor.numThreads', options['-t'])
77 if options.has_key('-i'):
78 props.set_property('constrictor.numIterations', options['-i'])
79 if options.has_key('-d'):
80 props.set_property('constrictor.dbFile', options['-d'])
81 if options.has_key('-p'):
82 props.set_property('constrictor.port', options['-p'])
83 if options.has_key('-l'):
84 props.set_property('constrictor.listenAddress', options['-l'])
85 if options.has_key('-m'):
86 task_set_name = options['-m']
87 if options.has_key('-n'):
90 if options.has_key('-x'):
91 # delete the cache directory
92 cacheDir = props.get_property('constrictor.cacheDir')
93 shutil.rmtree(os.path.join(os.getcwd(), cacheDir))
97 def onThreadsComplete(scriptManager):
98 global drone_controller
99 #summary = ScriptThread.current_script_thread().dbConnection.createTaskSummary()
100 #drone_controller.sendResult(type='task_summary', **summary)
102 read_args_and_props()
105 scriptDirs = props.get_property('constrictor.scriptDirs').split(',')
109 if props.get_property('constrictor.listen') == 'true':
111 ''' This is the main controller listen loop. Here, we
112 accept commands from the controller module, perform
113 the action, then go back to listening '''
115 drone_controller = DroneController(
116 props.get_property('constrictor.address'),
117 int(props.get_property('constrictor.port')))
119 ScriptManager.set_on_threads_complete(onThreadsComplete)
123 command = drone_controller.recv()['command']
125 if command['action'] == 'setprop':
126 prop = str(command['prop'])
127 val = str(command['val'])
128 log_info('setting property %s %s' % (prop, val))
129 props.set_property(prop, val)
132 if command['action'] == 'saveprops':
133 log_info("saving properties back to file")
137 if command['action'] == 'run':
138 ScriptThread.reset_thread_seed()
139 script = props.get_property('constrictor.script')
140 log_info('running ' + script)
141 f = open_script(scriptDirs, script)
143 init_db(task_set_name, store_data)
147 log_error("script execution failed: %s" % str(e))
148 drone_controller.sendError(text=str(e))
152 except KeyboardInterrupt:
153 drone_controller.shutdown()
156 init_db(task_set_name, store_data)
157 script = props.get_property('constrictor.script') # execute the requested script
158 ScriptThread.reset_thread_seed()
159 f = open_script(scriptDirs, script)