示例#1
0
class Program(object):
    def __init__(self):
        self.bus_client = None
        self.case_name = ""

    def _start_bus(self, local=True):
        '''
        _start_bus : start bus server with default config
        :param local: bool, default is True
        :return: None
        '''
        if local:
            return
        elif self.args.bus_server_port:
            self.bus_server = BusServer(self.args.bus_server_port)
        else:
            self.bus_server = BusServer()
        self.bus_server.start()
        time.sleep(0.5)

    def _start_loader(self, count: int, bus_client: BusClient):
        '''
        _start_loader : start loader (count)
        :param count: loader count
        :param bus_client: bus client -> BusClient (connect to bus server)
        :return: None
        '''
        for x in range(count):
            loader = Loader(bus_client, self.loader_recorder_lock, self.args)
            loader.start()

    def _start_runner(self, count: int, log_dir: str, bus_client: BusClient):
        '''
        _start_runner : start runner (count)
        :param count: runner count
        :param log_dir: log
        :return:
        '''
        for x in range(count):
            runner = Runner(log_dir, bus_client, self.multi_process_locks, self.args)
            runner.start()

    def _start_recorder(self, bus_client: BusClient, count: int = 1, log_dir: str = "", time_str: str = ""):
        '''
        start recorder
        :param bus_client:
        :param count:
        :param log_dir:
        :param time_str:
        :return:
        '''
        recorder = Recorder(bus_client, count, self.case_name, time_str, log_dir, self.args.report_template,
                            self.loader_recorder_lock, self.args)
        recorder.start()

    def _init_logging_module(self, args):
        '''
        init logging module
        :param args:
        :return:
        '''
        logging.basicConfig(level=logging.DEBUG if not args.debug else logging.DEBUG,
                            format='%(asctime)s %(levelname)s %(message)s')
        pass

    def _init_system_logger(self, log_dir: str, bus_client: BusClient):
        '''
        init system logger
        :param log_dir:
        :param bus_client:
        :return:
        '''
        log = Logger(self.case_name, self.time_str, log_dir, bus_client, self.args)
        log.start()

    def _init_system_lock(self, args):
        '''
        generate some locker
        :param args:
        :return:
        '''
        self.loader_recorder_lock = m_lock()
        self.multi_process_locks = [m_lock() for x in range(4)]
        if self.bus_client.get_case_count().empty():
            self.bus_client.get_case_count().put(0)

    def _bus_client(self, args):
        '''
        init bus client
        :param args:
        :return:
        '''
        if isinstance(args.bus_server, list):
            self.bus_client = BusClient(args.bus_server[1], args.bus_server[2], args.bus_server[0])
        elif args.bus_server_port:
            self.bus_client = BusClient(None, args.bus_server_port, None)
        else:
            self.bus_client = BusClient()
        self.params_loader = self.bus_client.get_param()

    def start_main(self):
        self.params_loader.put(Signal("main", SIGNAL_START))

    def stop_main(self):
        self.params_loader.put(Signal("main", SIGNAL_STOP))

    def put_loader_msg(self, args):
        if args.case:
            for arg in args.case:
                self.params_loader.put({"file_name": arg})

    def _start_web_server(self, args):
        plugin_manager.start_web_server(args, self.bus_client)

    def run(self, args):
        try:
            self.args = args
            self._init_logging_module(args)
            self.case_name = self.args.name
            self.time_str = Utils.get_time_str()
            self.case_log_dir = f"{args.log_dir}/{self.case_name}/{self.time_str}"
            self.runner_count = args.runner_count if args.runner_count else 1

            self.only_bus(args)

            self._start_bus(local=args.bus_server if args.bus_server else False)
            self._bus_client(args)
            self._init_system_lock(args)
            # this only in server bus
            if not args.bus_server:
                self._init_system_logger(args.log_dir, self.bus_client)

            # only : module
            if args.only_loader:
                self._start_loader(1, self.bus_client)
            elif args.only_runner:
                self._start_runner(self.runner_count, self.case_log_dir, self.bus_client)
            elif args.only_recorder:
                self._start_recorder(self.bus_client, self.runner_count, self.case_log_dir, self.time_str)
            else:
                self._start_loader(1, self.bus_client)
                self._start_runner(self.runner_count, self.case_log_dir, self.bus_client)
                self._start_recorder(self.bus_client, self.runner_count, self.case_log_dir, self.time_str)
            self.start_main()
            self.put_loader_msg(args)
            self.stop_main()
            self._start_web_server(args)

            self.wait_end_signal(args)
        except KeyboardInterrupt as key_inter:
            logger.error(key_inter)
        except FailLoaderException as loader_inter:
            logger.error(loader_inter)
        except FailRecorderException as recorder_inter:
            logger.error(recorder_inter)
        except FailRunnerException as runner_inter:
            logger.error(runner_inter)
        except FailFrameworkException as frame_inter:
            logger.error(frame_inter)

    def only_bus(self, args):
        if args.only_bus:
            self._start_bus(local=args.bus_server if args.bus_server else False)
            self._bus_client(args)
            self._init_system_lock(args)
            self._init_system_logger(args.log_dir, self.bus_client)
            self._start_recorder(self.bus_client, self.runner_count, self.case_log_dir, self.time_str)
            self.wait_end_signal(args)
            sys.exit(0)
        else:
            logger.debug("not only bus mode")

    def only_loader(self, args):
        if args.only_loader:
            pass

    def wait_end_signal(self, args):
        try:
            time.sleep(2)
            system_signal = self.bus_client.get_system()
            while True:
                if not args.console:
                    if not system_signal.empty():
                        self.signal = system_signal.get()
                        signal = self.signal.signal if isinstance(self.signal, Signal) else None
                        logger.info(f"program signal {SIGNAL_GROUP.get(signal) if signal in [x for x in range(20, 30)] else None}")
                        # check the end signal from recorder to main
                        if signal == SIGNAL_RECORD_END or signal == SIGNAL_STOP:
                            if not args.local_logger:
                                while True:
                                    if not system_signal.empty():
                                        signal_logger = system_signal.get()
                                        signal_logger = signal_logger.signal if isinstance(signal_logger,
                                                                                           Signal) else None
                                        logger.info(f"program signal {SIGNAL_GROUP.get(signal_logger) if signal_logger in [x for x in range(20, 30)] else None}")
                                        # check the logger signal from logger to main
                                        if signal_logger == SIGNAL_LOGGER_END:
                                            logger.info("main -- stop")
                                            system_signal.put(Signal("main", SIGNAL_RECORD_END))
                                            system_signal.put(Signal("main", SIGNAL_LOGGER_END))
                                            break
                            # if use local logger, just end the main program
                            else:
                                logger.info("main -- stop")
                                system_signal.put(Signal("main", SIGNAL_RECORD_END))
                                system_signal.put(Signal("main", SIGNAL_LOGGER_END))
                            break
                    time.sleep(0.1)
                else:
                    cmd = input(f"haf-{PLATFORM_VERSION}# ")
                    if self._run_cmd(cmd):
                        break
            if args.only_bus:
                logger.info("main - wait for other process end !")
                time.sleep(3)
            time.sleep(0.1)
        except KeyboardInterrupt as key_inter:
            self.params_loader.put(Signal("main", SIGNAL_STOP))

    # TODO: Here need CMDER to support cmd command ...
    def _run_cmd(self, cmd):
        if cmd == "rerun" or cmd == "r":
            result = self._rerun()
        elif cmd == "version" or cmd == "v":
            result = self._version()
        elif cmd == "help" or cmd == "h":
            result = self._help()
        elif cmd == "name" or cmd == "n":
            result = self._case_name()
        elif cmd == "exit" or cmd == "e":
            result = self._exit()
        elif cmd == "summary" or cmd == "s":
            result = self._summary()
        else:
            print("unsupported command!")
            result = self._help()
        return result

    def _rerun(self):
        case_handler = self.bus_client.get_case()
        while not case_handler.empty():
            case_handler.get()
        self._start_runner(self.args.runner_count if self.args.runner_count else 1, self.case_log_dir, self.bus_client)
        self._start_loader(1, self.bus_client)
        self._start_recorder(self.bus_client, self.runner_count, self.case_log_dir, self.time_str)
        self.start_main()
        self.put_loader_msg(self.args)
        self.stop_main()
        return False

    def _version(self):
        print(BANNER_STRS)
        return False

    def _help(self):
        help = f"""
haf-{PLATFORM_VERSION}#
# rerun   / r     rerun the input cases
# version / v     version of haf
# help    / h     help information
# name    / n     case name of this test
# summary / s     summary of this test
# exit    / e     exit 
        """
        print(help)
        return False

    def _summary(self):
        result_main = self.bus_client.get_case_result_main()
        if not result_main.empty():
            results = result_main.get()
            if isinstance(results, EndResult):
                self.results = results
        if hasattr(self, "results") and isinstance(self.results, EndResult):
            pass
        else:
            self.results = EndResult()
        result_summary = "|{:^8}|{:^8}|{:^8}|{:^8}|{:^8}|{:^25}|{:^25}|".format(self.results.passed,
                                                                                self.results.failed, self.results.skip, \
                                                                                self.results.error, self.results.all,
                                                                                self.results.begin_time,
                                                                                self.results.end_time)
        print("--------------------------------------------------------------------------------------------------")
        print(
            "|--\33[32mPASS\33[0m--|--\33[31mFAIL\33[0m--|--\33[37mSKIP\33[0m--|--\33[35mERROR\33[0m-|---\33[36mALL\33[0m--|----------\33[36mBegin\33[0m----------|-----------\33[36mEnd\33[0m-----------|")
        print(result_summary)
        print("--------------------------------------------------------------------------------------------------")

    def _case_name(self):
        print(self.case_name)
        return False

    def _exit(self):
        logger.info("main -- stop, wait for bus end")
        print(BANNER_STRS_EXIT)
        return True
示例#2
0
文件: logger.py 项目: hautof/haf
class Logger(Process):
    '''
    Logger
    '''
    def __init__(self, case_name: str, time_str: str, log_dir: str,
                 bus_client: BusClient, args: tuple):
        super().__init__()
        self.daemon = True
        self.bus_client = bus_client
        self.case_name = case_name
        self.log_dir = log_dir
        self.loggers = {}
        self.args = args
        self.time_str = time_str

    def reconnect_bus(self):
        '''
        need reconnect bus by self.bus's infos
        :return:
        '''
        self.bus_client = BusClient(self.bus_client.domain,
                                    self.bus_client.port,
                                    self.bus_client.auth_key)

    def run(self):
        self.reconnect_bus()
        if hasattr(self.args, "debug") and self.args.debug:
            logging.basicConfig(level=logging.DEBUG,
                                format='%(asctime)s %(levelname)s %(message)s')
        else:
            logging.basicConfig(level=logging.INFO,
                                format='%(asctime)s %(levelname)s %(message)s')
        log_home = f"{self.log_dir}/{self.case_name}/{self.time_str}"
        if not os.path.exists(log_home):
            os.makedirs(log_home)
        # here delete BusClient(), using input bus_clients
        # self.bus_client = BusClient()
        try:
            log_queue = self.bus_client.get_log()
            logger_end = self.bus_client.get_logger_end()
            while True:
                if not logger_end.empty():
                    logger_signal = logger_end.get()
                    # check logger end singal to stop logger, from recorder to logger
                    if isinstance(
                            logger_signal, Signal
                    ) and logger_signal.signal == SIGNAL_LOGGER_END:
                        while True:
                            if log_queue.empty():
                                break
                            log = log_queue.get()
                            self.log_handler(log)
                        self.end_handler()
                        break
                elif log_queue.empty():
                    time.sleep(0.001)
                    continue
                else:
                    log = log_queue.get()
                    self.log_handler(log)
        except KeyboardInterrupt as key_e:
            print(BANNER_STRS_EXIT)

    def split_log(self, log):
        '''
        split origin log msg
        :param log:
        :return:
        '''
        try:
            return log.rsplit("$%", 2)
        except Exception as ee:
            return f"log$%error$%{log}"

    def log_print(self, log):
        '''
        to print the log with format
        :param log:
        :return:
        '''
        if self.args.nout:
            return
        logger_name = log.get("logger_name")
        level = log.get("level")
        msg_origin = log.get("msg")
        process = log.get("process")
        if process not in self.loggers:
            self.loggers[process] = logging.getLogger(logger_name)
        logger = self.loggers.get(process)
        if level == "debug":
            msg = f"<{process}> [{logger_name}] {msg_origin}"
            if hasattr(self.args, "debug") and self.args.debug:
                logger.debug(msg)
        elif level == "info":
            msg = f"<{process}> [{logger_name}] {msg_origin}"
            logger.info(msg)
        elif level == "warning":
            msg = f"{msg_origin}"
            logger.warning(
                f"<{process}> [{logger_name}]\33[33m ####################################### \33[0m"
            )
            logger.warning(f"<{process}> [{logger_name}] \33[33m{msg}\33[0m")
            logger.warning(
                f"<{process}> [{logger_name}]\33[33m ####################################### \33[0m"
            )
        elif level == "error":
            msg = f"{msg_origin}"
            logger.error(
                f"<{process}> [{logger_name}]\33[31m >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> \33[0m"
            )
            logger.error(f"<{process}> [{logger_name}]\33[31m | {msg}\33[0m")
            logger.error(
                f"<{process}> [{logger_name}]\33[31m <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< \33[0m"
            )
        elif level == "critical":
            logger.critical(f"\33[5m{log}\33[0m")

    def log_handler(self, log):
        '''
        handler log here
        :param log:
        :return:
        '''
        self.log_print(log)
        log = log.get("msg")
        try:
            temp1, temp2, msg = self.split_log(log)
        except:
            temp1 = "error"
            temp2 = "error"
            msg = log

        if "loader" in temp2:
            self.loader_handler(temp1, msg)
        elif "runner" in temp2:
            self.runner_handler(temp1, msg)
        elif "recorder" in temp2:
            self.recorder_handler(temp1, msg)
        elif "system" in temp2:
            self.system_handler(temp1, temp2, msg)
        elif "error" in temp2:
            self.error_handler(temp1, msg)
        else:
            self.case_handler(temp1, temp2, msg)

    def loader_handler(self, temp1, msg):
        self.write("loader", temp1, msg)

    def runner_handler(self, temp1, msg):
        self.write("runner", temp1, msg)

    def case_handler(self, temp1, temp2, msg):
        self.write(temp1, temp2, msg)

    def recorder_handler(self, temp1, msg):
        self.write("recorder", temp1, msg)

    def system_handler(self, temp1, temp2, msg):
        self.write("system", f"{temp1}.{temp2}", msg)

    def error_handler(self, temp1, msg):
        self.write("error", temp1, msg)

    def write(self, dir, filename, msg):
        '''
        write log to filename's file
        :param dir:
        :param filename:
        :param msg:
        :return:
        '''
        msg = f"{self.now}{msg}\n"
        dir = f"{self.log_dir}/{self.case_name}/{self.time_str}/{dir}"
        if not os.path.exists(dir):
            os.makedirs(dir)
        full_name = f"{dir}/{filename}.log"
        try:
            with open(full_name, 'a+') as f:
                f.write(msg)
                f.close()
        except Exception as e:
            with open(full_name, 'a+', encoding='utf-8') as f:
                f.write(msg)
                f.close()

    @property
    def now(self):
        '''
        get datetime now to str
        :return: time now str
        '''
        current_time = time.time()
        local_time = time.localtime(current_time)
        time_temp = time.strftime("%Y-%m-%d %H:%M:%S", local_time)
        secs = (current_time - int(current_time)) * 1000
        timenow = "%s %03d" % (time_temp, secs)
        return timenow

    def end_handler(self):
        '''
        when logger end, send signal logger end to main
        :return:
        '''
        logger_handler = self.bus_client.get_system()
        logger_handler.put(Signal(self.pid, SIGNAL_LOGGER_END))