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
18 from constrictor.properties import Properties
19 from constrictor.db import DBConnection
20 from constrictor.controller import DroneController
21 from constrictor.script import ScriptThread, ScriptManager
22 from constrictor.log import *
23 from constrictor.utils import loadProps, saveProps, initDirs, initDB, openScript, PROPS_FILENAME
26 droneController = None
32 By default, all options are read from the properties file constrictor.properties.
33 Arguments passed via the command line will override any properties
34 loaded from the properties file
37 -h show this help message
38 -s test script to run (property constrictor.script)
39 -t number of threads to launch (property constrictor.numThreads)
40 -i number of test iterations per thread (property constrictor.numIterations)
41 -d database file (property constrictor.dbFile)
42 -p port to listen for controller connections on
43 -l listen address for incoming controller connections
49 def onThreadsComplete(scriptManager):
50 global droneController
51 summary = ScriptThread.currentScriptThread().dbConnection.createTaskSummary()
52 droneController.sendResult(type='task_summary', **summary)
56 # see if we have any command-line args that override the properties file
57 ops, args = getopt.getopt(sys.argv[1:], 's:t:i:d:p:l:h')
58 options = dict( (k,v) for k,v in ops )
60 if options.has_key('-h'):
62 if options.has_key('-s'):
63 props.setProperty('constrictor.script', options['-s'])
64 if options.has_key('-t'):
65 props.setProperty('constrictor.numThreads', options['-t'])
66 if options.has_key('-i'):
67 props.setProperty('constrictor.numIterations', options['-i'])
68 if options.has_key('-d'):
69 props.setProperty('constrictor.dbFile', options['-d'])
70 if options.has_key('-p'):
71 props.setProperty('constrictor.port', options['-p'])
72 if options.has_key('-l'):
73 props.setProperty('constrictor.listenAddress', options['-l'])
77 def onThreadsComplete(scriptManager):
78 global droneController
79 summary = ScriptThread.currentScriptThread().dbConnection.createTaskSummary()
80 droneController.sendResult(type='task_summary', **summary)
82 loadProps(PROPS_FILENAME)
83 props = Properties.getProperties()
87 scriptDirs = props.getProperty('constrictor.scriptDirs').split(',')
91 if props.getProperty('constrictor.listen') == 'true':
93 ''' This is the main controller listen loop. Here, we
94 accept commands from the controller module, perform
95 the action, then go back to listening '''
97 droneController = DroneController(
98 props.getProperty('constrictor.address'),
99 int(props.getProperty('constrictor.port')))
101 ScriptManager.setOnThreadsComplete(onThreadsComplete)
105 command = droneController.recv()['command']
107 if command['action'] == 'setprop':
108 prop = str(command['prop'])
109 val = str(command['val'])
110 logInfo('setting property %s %s' % (prop, val))
111 props.setProperty(prop, val)
114 if command['action'] == 'saveprops':
115 logInfo("saving properties back to file")
119 if command['action'] == 'run':
120 ScriptThread.resetThreadSeed()
121 script = props.getProperty('constrictor.script')
122 logInfo('running ' + script)
123 f = openScript(scriptDirs, script)
129 logError("script execution failed: %s" % str(e))
130 droneController.sendError(text=str(e))
134 except KeyboardInterrupt:
135 droneController.shutdown()
139 script = props.getProperty('constrictor.script') # execute the requested script
140 ScriptThread.resetThreadSeed()
141 f = openScript(scriptDirs, script)