class StartHandler(tornado.web.RequestHandler): def post(self): global active_test cfg, cfg_data = None, None try: cfg_data = self.get_body_argument("config") cfg = yaml.load(cfg_data) except Exception: self.set_status(400) self.write('Error parsing config: %s. \nTraceback: %s' % (cfg_data, traceback.format_exc())) return logger.debug('Received config: %s. Starting test', cfg) try: self.core = Core(cfg) self.core.configure() self.perform_test() active_test = self.core self.write(json.dumps(self.core.get_current_test_info())) except Exception: logger.warning('Failed to start the test', exc_info=True) self.set_status(500) self.write('Failed to start the test: %s' % traceback.format_exc()) @gen.coroutine def perform_test(self): logger.info( 'Starting test... You can interrupt via API /stop/ handler') self.core.start_test()
def perform_test(configs, log): core = Core(configs) try: core.configure() logger.info( 'Starting test... You can interrupt test w/ Ctrl+C or SIGTERM signal' ) core.start_test() while True: time.sleep(1) # infinite loop until SIGTERM except KeyboardInterrupt: logger.info( 'Keyboard interrupt, trying graceful shutdown. Do not press interrupt again, ' 'otherwise test might be broken') core.end_test() except Exception: logger.error('Uncaught exception in core\n', exc_info=True) core.end_test() finally: core.post_process() try: shutil.move(log, os.path.join(core.data_session.artifacts_dir, log)) except Exception: logger.warning('Failed to move logfile %s to artifacts dir', log) logger.debug('Failed to move logfile %s to artifacts dir', log, exc_info=True)
def main(): import argparse parser = argparse.ArgumentParser(description='volta console worker') parser.add_argument('-d', '--debug', '-v', '--verbose', dest='verbose', action='store_true', default=False) parser.add_argument('-q', '--quiet', dest='quiet', action='store_true', default=False) parser.add_argument('-l', '--log', dest='log', default='volta.log') parser.add_argument('-c', '--config', dest='config') args = parser.parse_args() if not args.config: raise RuntimeError('Empty config') init_logging(args.log, args.verbose, args.quiet) cfg_dict = {} with open(args.config, 'r') as cfg_stream: try: cfg_dict = yaml.safe_load(cfg_stream) except: logger.debug('Config file format not yaml or json...', exc_info=True) raise RuntimeError('Unknown config file format. Malformed?') core = Core(cfg_dict) try: core.configure() logger.info( 'Starting test... You can interrupt test w/ Ctrl+C or SIGTERM signal' ) core.start_test() while True: time.sleep(1) # infinite loop until SIGTERM except KeyboardInterrupt: logger.info( 'Keyboard interrupt, trying graceful shutdown. Do not press interrupt again...' ) core.end_test() except: logger.error('Uncaught exception in core\n', exc_info=True) finally: core.post_process() core.collect_file(args.log)
def main(): import argparse parser = argparse.ArgumentParser(description='volta console worker') parser.add_argument('--debug', dest='debug', action='store_true', default=False) parser.add_argument('-c', '--config', dest='config') args = parser.parse_args() logging.basicConfig( level="DEBUG" if args.debug else "INFO", format= '%(asctime)s [%(levelname)s] [Volta Core] %(filename)s:%(lineno)d %(message)s' ) if not args.config: raise RuntimeError('Empty config') cfg_dict = {} with open(args.config, 'r') as cfg_stream: try: cfg_dict = yaml.safe_load(cfg_stream) except: logger.debug('Config file format not yaml or json...', exc_info=True) raise RuntimeError('Unknown config file format. Malformed?') core = Core(cfg_dict) try: core.configure() logger.info( 'Starting test... You can interrupt test w/ Ctrl+C or SIGTERM signal' ) core.start_test() while True: time.sleep(1) # infinite loop until SIGTERM except KeyboardInterrupt: logger.info( 'Keyboard interrupt, trying graceful shutdown. Do not press interrupt again...' ) core.end_test() except: logger.error('Uncaught exception in core\n', exc_info=True) finally: core.post_process()
class Plugin(AbstractPlugin): SECTION = "android" SECTION_META = "meta" def __init__(self, core, cfg): self.stats_reader = None self.reader = None super(Plugin, self).__init__(core, cfg) self.device = None try: self.cfg = cfg['volta_options'] for key, value in self.cfg.iteritems(): if not isinstance(value, dict): logger.debug('Malformed VoltaConfig key: %s value %s', key, value) raise RuntimeError( 'Malformed VoltaConfig passed, key: %s. Should by dict' % key) except AttributeError: logger.error('Failed to read Volta config', exc_info=True) self.volta_core = VoltaCore(self.cfg) @staticmethod def get_key(): return __file__ def get_available_options(self): opts = ["volta_options"] return opts def configure(self): self.volta_core.configure() def get_reader(self): if self.reader is None: self.reader = AndroidReader() return self.reader def get_stats_reader(self): if self.stats_reader is None: self.stats_reader = AndroidStatsReader() return self.stats_reader def prepare_test(self): self.core.add_artifact_file(self.volta_core.currents_fname) [ self.core.add_artifact_file(fname) for fname in self.volta_core.event_fnames.values() ] def start_test(self): try: self.volta_core.start_test() # FIXME raise/catch appropriate exception here except: # noqa: E722 logger.info('Failed to start test of Android plugin', exc_info=True) return 1 def is_test_finished(self): try: if hasattr(self.volta_core, 'phone'): if hasattr(self.volta_core.phone, 'test_performer'): if not self.volta_core.phone.test_performer: logger.warning( 'There is no test performer process on the phone, interrupting test' ) return 1 if not self.volta_core.phone.test_performer.is_finished(): logger.debug('Waiting for phone test to finish...') return -1 else: return self.volta_core.phone.test_performer.retcode # FIXME raise/catch appropriate exception here except: # noqa: E722 logger.error( 'Unknown exception of Android plugin. Interrupting test', exc_info=True) return 1 def end_test(self, retcode): try: self.volta_core.end_test() uploaders = self.core.get_plugins_of_type(DataUploaderPlugin) for uploader in uploaders: response = uploader.lp_job.api_client.link_mobile_job( lp_key=uploader.lp_job.number, mobile_key=self.volta_core.uploader.jobno) logger.info( 'Linked mobile job %s to %s for plugin: %s. Response: %s', self.volta_core.uploader.jobno, uploader.lp_job.number, uploader.backend_type, response) # FIXME raise/catch appropriate exception here except: # noqa: E722 logger.error('Failed to complete end_test of Android plugin', exc_info=True) retcode = 1 return retcode def get_info(self): return AndroidInfo() def post_process(self, retcode): try: self.volta_core.post_process() # FIXME raise/catch appropriate exception here except: # noqa: E722 logger.error('Failed to complete post_process of Android plugin', exc_info=True) retcode = 1 return retcode
class Plugin(AbstractPlugin): SECTION = "android" SECTION_META = "meta" def __init__(self, core, cfg, name): self.stats_reader = None self.reader = None super(Plugin, self).__init__(core, cfg, name) self.device = None try: self.cfg = cfg['volta_options'] for key, value in self.cfg.iteritems(): if not isinstance(value, dict): logger.debug('Malformed VoltaConfig key: %s value %s', key, value) raise RuntimeError('Malformed VoltaConfig passed, key: %s. Should by dict' % key) except AttributeError: logger.error('Failed to read Volta config', exc_info=True) self.volta_core = VoltaCore(self.cfg) @staticmethod def get_key(): return __file__ def get_available_options(self): opts = ["volta_options"] return opts def configure(self): self.volta_core.configure() def get_reader(self): if self.reader is None: self.reader = AndroidReader() return self.reader def get_stats_reader(self): if self.stats_reader is None: self.stats_reader = AndroidStatsReader() return self.stats_reader def prepare_test(self): self.core.add_artifact_file(self.volta_core.currents_fname) [self.core.add_artifact_file(fname) for fname in self.volta_core.event_fnames.values()] def start_test(self): try: self.volta_core.start_test() # FIXME raise/catch appropriate exception here except: # noqa: E722 logger.info('Failed to start test of Android plugin', exc_info=True) return 1 def is_test_finished(self): try: if hasattr(self.volta_core, 'phone'): if hasattr(self.volta_core.phone, 'test_performer'): if not self.volta_core.phone.test_performer: logger.warning('There is no test performer process on the phone, interrupting test') return 1 if not self.volta_core.phone.test_performer.is_finished(): logger.debug('Waiting for phone test to finish...') return -1 else: return self.volta_core.phone.test_performer.retcode # FIXME raise/catch appropriate exception here except: # noqa: E722 logger.error('Unknown exception of Android plugin. Interrupting test', exc_info=True) return 1 def end_test(self, retcode): try: self.volta_core.end_test() uploaders = self.core.get_plugins_of_type(DataUploaderPlugin) for uploader in uploaders: response = uploader.lp_job.api_client.link_mobile_job( lp_key=uploader.lp_job.number, mobile_key=self.volta_core.uploader.jobno ) logger.info( 'Linked mobile job %s to %s for plugin: %s. Response: %s', self.volta_core.uploader.jobno, uploader.lp_job.number, uploader.backend_type, response ) # FIXME raise/catch appropriate exception here except: # noqa: E722 logger.error('Failed to complete end_test of Android plugin', exc_info=True) retcode = 1 return retcode def get_info(self): return AndroidInfo() def post_process(self, retcode): try: self.volta_core.post_process() # FIXME raise/catch appropriate exception here except: # noqa: E722 logger.error('Failed to complete post_process of Android plugin', exc_info=True) retcode = 1 return retcode
class Plugin(AbstractPlugin, GeneratorPlugin): SECTION = "android" SECTION_META = "meta" def __init__(self, core, cfg, cfg_updater): try: super(Plugin, self).__init__(core, cfg, cfg_updater) self.device = None self.cfg = cfg['volta_options'] for key, value in self.cfg.iteritems(): if not isinstance(value, dict): logger.debug('Malformed VoltaConfig key: %s value %s', key, value) raise RuntimeError( 'Malformed VoltaConfig passed, key: %s. Should by dict' % key) except AttributeError: logger.error('Failed to read Volta config', exc_info=True) self.volta_core = VoltaCore(self.cfg) @staticmethod def get_key(): return __file__ def get_available_options(self): opts = ["volta_options"] return opts def configure(self): self.volta_core.configure() def prepare_test(self): aggregator = self.core.job.aggregator_plugin if aggregator: aggregator.reader = AndroidReader() aggregator.stats_reader = AndroidStatsReader() self.core.add_artifact_file(self.volta_core.currents_fname) [ self.core.add_artifact_file(fname) for fname in self.volta_core.event_fnames.values() ] def start_test(self): self.volta_core.start_test() def is_test_finished(self): if hasattr(self.volta_core, 'phone'): if hasattr(self.volta_core.phone, 'test_performer'): if not self.volta_core.phone.test_performer._finished: logger.debug('Waiting for phone test for finish...') return -1 else: return self.volta_core.phone.test_performer.retcode def end_test(self, retcode): self.volta_core.end_test() return retcode def get_info(self): return AndroidInfo() def post_process(self, retcode): self.volta_core.post_process() return retcode
class Plugin(AbstractPlugin, GeneratorPlugin): SECTION = "android" SECTION_META = "meta" def __init__(self, core, cfg, cfg_updater): self.stats_reader = None self.reader = None try: super(Plugin, self).__init__(core, cfg, cfg_updater) self.device = None self.cfg = cfg['volta_options'] for key, value in self.cfg.iteritems(): if not isinstance(value, dict): logger.debug('Malformed VoltaConfig key: %s value %s', key, value) raise RuntimeError('Malformed VoltaConfig passed, key: %s. Should by dict' % key) except AttributeError: logger.error('Failed to read Volta config', exc_info=True) self.volta_core = VoltaCore(self.cfg) @staticmethod def get_key(): return __file__ def get_available_options(self): opts = ["volta_options"] return opts def configure(self): self.volta_core.configure() def get_reader(self): if self.reader is None: self.reader = AndroidReader() return self.reader def get_stats_reader(self): if self.stats_reader is None: self.stats_reader = AndroidStatsReader() return self.stats_reader def prepare_test(self): self.core.add_artifact_file(self.volta_core.currents_fname) [self.core.add_artifact_file(fname) for fname in self.volta_core.event_fnames.values()] def start_test(self): self.volta_core.start_test() def is_test_finished(self): if hasattr(self.volta_core, 'phone'): if hasattr(self.volta_core.phone, 'test_performer'): if not self.volta_core.phone.test_performer._finished: logger.debug('Waiting for phone test for finish...') return -1 else: return self.volta_core.phone.test_performer.retcode def end_test(self, retcode): self.volta_core.end_test() mobile_key = self.volta_core.uploader.jobno logger.info("Mobile jobno: %s", mobile_key) jobno = self.core.status['uploader']['job_no'] logger.info("Simple jobno: %s", jobno) web_link = self.core.status['uploader']['web_link'] url = web_link.replace(str(jobno), '') logger.info("Url: %s", url) self.link_jobs(url, jobno, mobile_key) return retcode def link_jobs(self, url, jobno, mobile_key): api_client = OverloadClient() api_client.set_api_address(url) api_client.session.verify = False addr = "/api/job/{jobno}/edit.json".format(jobno=jobno) data = { 'mobile_key': mobile_key } logger.info("Jobs link request: url = %s, data = %s", url + addr, data) while True: try: response = api_client.post(addr, data) return response except requests.exceptions.HTTPError as ex: logger.debug("Got error for jobs link request: %s", ex) if ex.response.status_code == 423: logger.warn( "Overload is under maintenance, will retry in 5s...") time.sleep(5) else: raise ex def get_info(self): return AndroidInfo() def post_process(self, retcode): self.volta_core.post_process() return retcode