Esempio n. 1
0
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()
Esempio n. 2
0
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)
Esempio n. 3
0
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)
Esempio n. 4
0
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()
Esempio n. 5
0
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
Esempio n. 6
0
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
Esempio n. 7
0
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
Esempio n. 8
0
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