Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Bug 797371 - Update phone info and restart worker if reg msg changes.…

… r=bc
  • Loading branch information...
commit 9860a54b267cffac7e18736c3479080bd4e48540 1 parent d7e45f9
@markrcote markrcote authored
View
79 autophone.py
@@ -136,6 +136,7 @@ def __init__(self, clear_cache, reboot_phones, test_path, cachefile,
self.pulsemonitor = None
self.enable_unittests = enable_unittests
+ self.restart_workers = {}
@property
def next_worker_num(self):
@@ -152,12 +153,18 @@ def run(self):
self.worker_msg_loop()
def check_for_dead_workers(self):
- phoneids = self.phone_workers.keys()
- for phoneid in phoneids:
- if not self.phone_workers[phoneid].is_alive():
+ for phoneid, worker in self.phone_workers.iteritems():
+ if not worker.is_alive():
+ if phoneid in self.restart_workers:
+ logging.info('Worker %s exited; restarting with new '
+ 'values.' % phoneid)
+ self.create_worker(self.restart_workers[phoneid],
+ worker.user_cfg)
+ del self.restart_workers[phoneid]
+ continue
+
print 'Worker %s died!' % phoneid
logging.error('Worker %s died!' % phoneid)
- worker = self.phone_workers[phoneid]
worker.stop()
worker.crashes.add_crash()
msg_subj = 'Worker for phone %s died' % \
@@ -239,7 +246,7 @@ def route_cmd(self, data):
now = datetime.datetime.now().replace(microsecond=0)
for i, w in self.phone_workers.iteritems():
response += 'phone %s (%s):\n' % (i, w.phone_cfg['ip'])
- response += ' debug level %d\n' % w.phone_cfg.get('debug', 3)
+ response += ' debug level %d\n' % w.user_cfg.get('debug', 3)
if not w.last_status_msg:
response += ' no updates\n'
else:
@@ -280,18 +287,17 @@ def route_cmd(self, data):
self.cmd_lock.release()
return response
- def register_phone(self, phone_cfg):
- tests = [x[0](phone_cfg=phone_cfg, config_file=x[1]) for
- x in self._tests]
-
+ def create_worker(self, phone_cfg, user_cfg):
+ logging.info('Creating worker for %s.' % phone_cfg['phoneid'])
+ tests = [x[0](phone_cfg=phone_cfg, user_cfg=user_cfg, config_file=x[1])
+ for x in self._tests]
logfile_prefix = os.path.splitext(self.logfile)[0]
worker = PhoneWorker(self.next_worker_num, self.ipaddr,
- tests, phone_cfg, self.worker_msg_queue,
+ tests, phone_cfg, user_cfg, self.worker_msg_queue,
'%s-%s' % (logfile_prefix, phone_cfg['phoneid']),
self.loglevel, self.mailer)
self.phone_workers[phone_cfg['phoneid']] = worker
worker.start()
- logging.info('Registered phone %s.' % phone_cfg['phoneid'])
def register_cmd(self, data):
# Un-url encode it
@@ -302,22 +308,36 @@ def register_cmd(self, data):
# The configparser does odd things with the :'s so remove them.
macaddr = data['name'][0].replace(':', '_')
phoneid = '%s_%s' % (macaddr, data['hardware'][0])
-
- if phoneid not in self.phone_workers:
- phone_cfg = dict(
- phoneid=phoneid,
- serial=data['pool'][0].upper(),
- ip=data['ipaddr'][0],
- sutcmdport=int(data['cmdport'][0]),
- machinetype=data['hardware'][0],
- osver=data['os'][0],
- debug=3,
- ipaddr=self.ipaddr)
- self.register_phone(phone_cfg)
- self.update_phone_cache()
+ phone_cfg = dict(
+ phoneid=phoneid,
+ serial=data['pool'][0].upper(),
+ ip=data['ipaddr'][0],
+ sutcmdport=int(data['cmdport'][0]),
+ machinetype=data['hardware'][0],
+ osver=data['os'][0],
+ ipaddr=self.ipaddr)
+ if phoneid in self.phone_workers:
+ logging.debug('Received registration message for known phone '
+ '%s.' % phoneid)
+ worker = self.phone_workers[phoneid]
+ if worker.phone_cfg != phone_cfg:
+ # This won't update the subprocess, but it will allow
+ # us to write out the updated values right away.
+ worker.phone_cfg = phone_cfg
+ self.update_phone_cache()
+ logging.info('Registration info has changed; restarting '
+ 'worker.')
+ if phoneid in self.restart_workers:
+ logging.info('Phone worker is already scheduled to be '
+ 'restarted!')
+ else:
+ self.restart_workers[phoneid] = phone_cfg
+ worker.stop()
else:
- logging.debug('Registering known phone: %s' %
- self.phone_workers[phoneid].phone_cfg['phoneid'])
+ user_cfg = {'debug': 3}
+ self.create_worker(phone_cfg, user_cfg)
+ logging.info('Registered phone %s.' % phone_cfg['phoneid'])
+ self.update_phone_cache()
except:
print 'ERROR: could not write cache file, exiting'
traceback.print_exception(*sys.exc_info())
@@ -332,15 +352,16 @@ def read_cache(self):
except ValueError:
cache = {}
- for phone_cfg in cache.get('phones', []):
- self.register_phone(phone_cfg)
+ for cfg in cache.get('phones', []):
+ self.create_worker(cfg['phone_cfg'], cfg['user_cfg'])
except IOError, err:
if err.errno != errno.ENOENT:
raise err
def update_phone_cache(self):
cache = {}
- cache['phones'] = [x.phone_cfg for x in self.phone_workers.values()]
+ cache['phones'] = [{'phone_cfg': x.phone_cfg, 'user_cfg': x.user_cfg}
+ for x in self.phone_workers.values()]
with open(self._cache, 'w') as f:
f.write(json.dumps(cache))
View
5 phonetest.py
@@ -64,10 +64,11 @@ class PhoneTest(object):
TODO: Add in connection data here for programmable power so we can add a
powercycle method to this class.
"""
- def __init__(self, phone_cfg, config_file=None, status_cb=None):
+ def __init__(self, phone_cfg, user_cfg, config_file=None, status_cb=None):
self.config_file = config_file
self.status_cb = status_cb
self.phone_cfg = phone_cfg
+ self.user_cfg = user_cfg
self.status = None
self.logger = logging.getLogger('phonetest')
self._base_device_path = ''
@@ -97,7 +98,7 @@ def runjob(self, job):
raise NotImplementedError
def set_dm_debug(self, level):
- self.phone_cfg['debug'] = level
+ self.user_cfg['debug'] = level
if self._dm:
self._dm.debug = level
View
3  tests/runtestsremote.py
@@ -26,9 +26,6 @@
class UnitTest(PhoneTest):
- def __init__(self, phone_cfg, config_file=None, status_cb=None):
- PhoneTest.__init__(self, phone_cfg, config_file, status_cb)
-
def runjob(self, job):
self.logger.debug('runtestsremote.py runjob start')
View
3  tests/s1s2test.py
@@ -17,9 +17,6 @@
class S1S2Test(PhoneTest):
- def __init__(self, phone_cfg, config_file=None, status_cb=None):
- PhoneTest.__init__(self, phone_cfg, config_file, status_cb)
-
def runjob(self, job):
# Read our config file which gives us our number of
# iterations and urls that we will be testing
View
3  tests/smoketest.py
@@ -13,9 +13,6 @@
class SmokeTest(PhoneTest):
- def __init__(self, phone_cfg, config_file=None, status_cb=None):
- PhoneTest.__init__(self, phone_cfg, config_file, status_cb)
-
def runjob(self, job):
try:
os.unlink('smoketest_pass')
View
24 worker.py
@@ -44,9 +44,10 @@ class PhoneWorker(object):
This is the interface to the subprocess, accessible by the main
process."""
- def __init__(self, worker_num, ipaddr, tests, phone_cfg, autophone_queue,
- logfile_prefix, loglevel, mailer):
+ def __init__(self, worker_num, ipaddr, tests, phone_cfg, user_cfg,
+ autophone_queue, logfile_prefix, loglevel, mailer):
self.phone_cfg = phone_cfg
+ self.user_cfg = user_cfg
self.worker_num = worker_num
self.ipaddr = ipaddr
self.last_status_msg = None
@@ -56,7 +57,7 @@ def __init__(self, worker_num, ipaddr, tests, phone_cfg, autophone_queue,
self.job_queue = multiprocessing.Queue()
self.lock = multiprocessing.Lock()
self.subprocess = PhoneWorkerSubProcess(self.worker_num, self.ipaddr,
- tests, phone_cfg,
+ tests, phone_cfg, user_cfg,
autophone_queue,
self.job_queue, logfile_prefix,
loglevel, mailer)
@@ -88,7 +89,7 @@ def debug(self, level):
except ValueError:
logging.error('Invalid argument for debug: %s' % level)
else:
- self.phone_cfg['debug'] = level
+ self.user_cfg['debug'] = level
self.job_queue.put_nowait(('debug', level))
def ping(self):
@@ -120,12 +121,13 @@ class PhoneWorkerSubProcess(object):
PING_SECONDS = 60*15
JOB_QUEUE_TIMEOUT_SECONDS = 10
- def __init__(self, worker_num, ipaddr, tests, phone_cfg, autophone_queue,
- job_queue, logfile_prefix, loglevel, mailer):
+ def __init__(self, worker_num, ipaddr, tests, phone_cfg, user_cfg,
+ autophone_queue, job_queue, logfile_prefix, loglevel, mailer):
self.worker_num = worker_num
self.ipaddr = ipaddr
self.tests = tests
self.phone_cfg = phone_cfg
+ self.user_cfg = user_cfg
self.autophone_queue = autophone_queue
self.job_queue = job_queue
self.logfile = logfile_prefix + '.log'
@@ -402,7 +404,7 @@ def loop(self):
logging.info('Worker for phone %s starting up.' %
self.phone_cfg['phoneid'])
- DeviceManagerSUT.debug = self.phone_cfg.get('debug', 3)
+ DeviceManagerSUT.debug = self.user_cfg.get('debug', 3)
for t in self.tests:
t.status_cb = self.status_update
@@ -481,12 +483,12 @@ def loop(self):
for j in self.skipped_job_queue:
self.job_queue.put(('job', j))
elif request[0] == 'debug':
- self.phone_cfg['debug'] = request[1]
- DeviceManagerSUT.debug = self.phone_cfg['debug']
+ self.user_cfg['debug'] = request[1]
+ DeviceManagerSUT.debug = self.user_cfg['debug']
# update any existing DeviceManagerSUT objects
if self._dm:
- self._dm.debug = self.phone_cfg['debug']
+ self._dm.debug = self.user_cfg['debug']
for t in self.tests:
- t.set_dm_debug(self.phone_cfg['debug'])
+ t.set_dm_debug(self.user_cfg['debug'])
elif request[0] == 'ping':
self.ping()
Please sign in to comment.
Something went wrong with that request. Please try again.