Esempio n. 1
0
    def __init__(self, options):
        """! ctor
        """
        self.options = options

        self.prn_lock = Lock()
        self.logger = HtrunLogger(self.prn_lock, 'HTST')

        # Handle extra command from
        if options:
            if options.enum_host_tests:
                path = self.options.enum_host_tests
                enum_host_tests(path, verbose=options.verbose)

            if options.list_reg_hts:  # --list option
                print_ht_list()
                sys.exit(0)

            if options.list_plugins:  # --plugins option
                host_tests_plugins.print_plugin_info()
                sys.exit(0)

            if options.version:  # --version
                import pkg_resources  # part of setuptools
                version = pkg_resources.require("mbed-host-tests")[0].version
                print version
                sys.exit(0)

            if options.send_break_cmd:  # -b with -p PORT (and optional -r RESET_TYPE)
                handle_send_break_cmd(port=options.port,
                                      disk=options.disk,
                                      reset_type=options.forced_reset_type,
                                      verbose=options.verbose)
                sys.exit(0)

        DefaultTestSelectorBase.__init__(self, options)
Esempio n. 2
0
    def __init__(self, options):
        """! ctor
        """
        self.options = options

        self.prn_lock = Lock()
        self.logger = HtrunLogger(self.prn_lock, 'HTST')

        # Handle extra command from
        if options:
            if options.enum_host_tests:
                path = self.options.enum_host_tests
                enum_host_tests(path, verbose=options.verbose)

            if options.list_reg_hts:    # --list option
                print_ht_list()
                sys.exit(0)

            if options.list_plugins:    # --plugins option
                host_tests_plugins.print_plugin_info()
                sys.exit(0)

            if options.version:         # --version
                import pkg_resources    # part of setuptools
                version = pkg_resources.require("mbed-host-tests")[0].version
                print version
                sys.exit(0)

            if options.send_break_cmd:  # -b with -p PORT (and optional -r RESET_TYPE)
                handle_send_break_cmd(port=options.port,
                    disk=options.disk,
                    reset_type=options.forced_reset_type,
                    verbose=options.verbose)
                sys.exit(0)

        DefaultTestSelectorBase.__init__(self, options)
Esempio n. 3
0
class DefaultTestSelector(DefaultTestSelectorBase):
    """! Select default host_test supervision (replaced after auto detection) """

    def __init__(self, options):
        """! ctor
        """
        self.options = options

        self.prn_lock = Lock()
        self.logger = HtrunLogger(self.prn_lock, 'HTST')

        # Handle extra command from
        if options:
            if options.enum_host_tests:
                path = self.options.enum_host_tests
                enum_host_tests(path, verbose=options.verbose)

            if options.list_reg_hts:    # --list option
                print_ht_list()
                sys.exit(0)

            if options.list_plugins:    # --plugins option
                host_tests_plugins.print_plugin_info()
                sys.exit(0)

            if options.version:         # --version
                import pkg_resources    # part of setuptools
                version = pkg_resources.require("mbed-host-tests")[0].version
                print version
                sys.exit(0)

            if options.send_break_cmd:  # -b with -p PORT (and optional -r RESET_TYPE)
                handle_send_break_cmd(port=options.port,
                    disk=options.disk,
                    reset_type=options.forced_reset_type,
                    verbose=options.verbose)
                sys.exit(0)

        DefaultTestSelectorBase.__init__(self, options)

    def run_test(self):
        result = None
        timeout_duration = 10       # Default test case timeout
        event_queue = Queue()       # Events from DUT to host
        dut_event_queue = Queue()   # Events from host to DUT {k;v}

        def callback__notify_prn(key, value, timestamp):
            """! Handles __norify_prn. Prints all lines in separate log line """
            for line in value.splitlines():
                self.logger.prn_inf(line)

        callbacks = {
            "__notify_prn" : callback__notify_prn
        }

        # if True we will allow host test to consume all events after test is finished
        callbacks_consume = True
        # Flag check if __exit event occurred
        callbacks__exit = False
        # Handle to dynamically loaded host test object
        self.test_supervisor = None
        # Version: greentea-client version from DUT
        self.client_version = None

        self.logger.prn_inf("starting host test process...")

        def start_conn_process():
            # Create device info here as it may change after restart.
            config = {
                "digest" : "serial",
                "port" : self.mbed.port,
                "baudrate" : self.mbed.serial_baud,
                "program_cycle_s" : self.options.program_cycle_s,
                "reset_type" : self.options.forced_reset_type
            }
            # DUT-host communication process
            args = (event_queue, dut_event_queue, self.prn_lock, config)
            p = Process(target=conn_process, args=args)
            p.deamon = True
            p.start()
            return p
        p = start_conn_process()

        start_time = time()

        try:
            consume_preamble_events = True
            while (time() - start_time) < timeout_duration:
                # Handle default events like timeout, host_test_name, ...
                if not event_queue.empty():
                    try:
                        (key, value, timestamp) = event_queue.get(timeout=1)
                    except QueueEmpty:
                        continue

                    if consume_preamble_events:
                        if key == '__timeout':
                            # Override default timeout for this event queue
                            start_time = time()
                            timeout_duration = int(value) # New timeout
                            self.logger.prn_inf("setting timeout to: %d sec"% int(value))
                        elif key == '__version':
                            self.client_version = value
                            self.logger.prn_inf("DUT greentea-client version: " + self.client_version)
                        elif key == '__host_test_name':
                            # Load dynamically requested host test
                            self.test_supervisor = get_host_test(value)
                            if self.test_supervisor:
                                # Pass communication queues and setup() host test
                                self.test_supervisor.setup_communication(event_queue, dut_event_queue)
                                try:
                                    # After setup() user should already register all callbacks
                                    self.test_supervisor.setup()
                                except (TypeError, ValueError):
                                    # setup() can throw in normal circumstances TypeError and ValueError
                                    self.logger.prn_err("host test setup() failed, reason:")
                                    self.logger.prn_inf("==== Traceback start ====")
                                    for line in traceback.format_exc().splitlines():
                                        print line
                                    self.logger.prn_inf("==== Traceback end ====")
                                    result = self.RESULT_ERROR
                                    break

                                self.logger.prn_inf("host test setup() call...")
                                if self.test_supervisor.get_callbacks():
                                    callbacks.update(self.test_supervisor.get_callbacks())
                                    self.logger.prn_inf("CALLBACKs updated")
                                else:
                                    self.logger.prn_wrn("no CALLBACKs specified by host test")
                                self.logger.prn_inf("host test detected: %s"% value)
                            else:
                                self.logger.prn_err("host test not detected: %s"% value)
                            consume_preamble_events = False
                        elif key == '__sync':
                            # This is DUT-Host Test handshake event
                            self.logger.prn_inf("sync KV found, uuid=%s, timestamp=%f"% (str(value), timestamp))
                        elif key == '__notify_conn_lost':
                            # This event is sent by conn_process, DUT connection was lost
                            self.logger.prn_err(value)
                            self.logger.prn_wrn("stopped to consume events due to %s event"% key)
                            callbacks_consume = False
                            result = self.RESULT_IO_SERIAL
                            break
                        elif key.startswith('__'):
                            # Consume other system level events
                            pass
                        else:
                            self.logger.prn_err("orphan event in preamble phase: {{%s;%s}}, timestamp=%f"% (key, str(value), timestamp))
                    else:
                        if key == '__notify_complete':
                            # This event is sent by Host Test, test result is in value
                            # or if value is None, value will be retrieved from HostTest.result() method
                            self.logger.prn_inf("%s(%s)"% (key, str(value)))
                            result = value
                            break
                        elif key == '__reset_dut':
                            # Disconnecting and re-connecting comm process will reset DUT
                            dut_event_queue.put(('__host_test_finished', True, time()))
                            p.join()
                            # self.mbed.update_device_info() - This call is commented but left as it would be required in hard reset.
                            p = start_conn_process()
                        elif key == '__notify_conn_lost':
                            # This event is sent by conn_process, DUT connection was lost
                            self.logger.prn_err(value)
                            self.logger.prn_wrn("stopped to consume events due to %s event"% key)
                            callbacks_consume = False
                            result = self.RESULT_IO_SERIAL
                            break
                        elif key == '__exit':
                            # This event is sent by DUT, test suite exited
                            self.logger.prn_inf("%s(%s)"% (key, str(value)))
                            callbacks__exit = True
                            break
                        elif key in callbacks:
                            # Handle callback
                            callbacks[key](key, value, timestamp)
                        else:
                            self.logger.prn_err("orphan event in main phase: {{%s;%s}}, timestamp=%f"% (key, str(value), timestamp))
        except Exception:
            self.logger.prn_err("something went wrong in event main loop!")
            self.logger.prn_inf("==== Traceback start ====")
            for line in traceback.format_exc().splitlines():
                print line
            self.logger.prn_inf("==== Traceback end ====")
            result = self.RESULT_ERROR

        time_duration = time() - start_time
        self.logger.prn_inf("test suite run finished after %.2f sec..."% time_duration)

        # Force conn_proxy process to return
        dut_event_queue.put(('__host_test_finished', True, time()))
        p.join()
        self.logger.prn_inf("CONN exited with code: %s"% str(p.exitcode))

        # Callbacks...
        self.logger.prn_inf("No events in queue" if event_queue.empty() else "Some events in queue")

        # If host test was used we will:
        # 1. Consume all existing events in queue if consume=True
        # 2. Check result from host test and call teardown()

        if callbacks_consume:
            # We are consuming all remaining events if requested
            while not event_queue.empty():
                try:
                    (key, value, timestamp) = event_queue.get(timeout=1)
                except QueueEmpty:
                    break

                if key == '__notify_complete':
                    # This event is sent by Host Test, test result is in value
                    # or if value is None, value will be retrieved from HostTest.result() method
                    self.logger.prn_inf("%s(%s)"% (key, str(value)))
                    result = value
                elif key.startswith('__'):
                    # Consume other system level events
                    pass
                elif key in callbacks:
                    callbacks[key](key, value, timestamp)
                else:
                    self.logger.prn_wrn(">>> orphan event: {{%s;%s}}, timestamp=%f"% (key, str(value), timestamp))
            self.logger.prn_inf("stopped consuming events")

        if result is not None:  # We must compare here against None!
            # Here for example we've received some error code like IOERR_COPY
            self.logger.prn_inf("host test result() call skipped, received: %s"% str(result))
        else:
            if self.test_supervisor:
                result = self.test_supervisor.result()
            self.logger.prn_inf("host test result(): %s"% str(result))

        if not callbacks__exit:
            self.logger.prn_wrn("missing __exit event from DUT")

        #if not callbacks__exit and not result:
        if not callbacks__exit and result is None:
            self.logger.prn_err("missing __exit event from DUT and no result from host test, timeout...")
            result = self.RESULT_TIMEOUT

        self.logger.prn_inf("calling blocking teardown()")
        if self.test_supervisor:
            self.test_supervisor.teardown()
        self.logger.prn_inf("teardown() finished")

        return result

    def execute(self):
        """! Test runner for host test.

        @details This function will start executing test and forward test result via serial port
                 to test suite. This function is sensitive to work-flow flags such as --skip-flashing,
                 --skip-reset etc.
                 First function will flash device with binary, initialize serial port for communication,
                 reset target. On serial port handshake with test case will be performed. It is when host
                 test reads property data from serial port (sent over serial port).
                 At the end of the procedure proper host test (defined in set properties) will be executed
                 and test execution timeout will be measured.
        """
        result = self.RESULT_UNDEF

        try:
            # Copy image to device
            if self.options.skip_flashing:
                self.logger.prn_inf("copy image onto target... SKIPPED!")
            else:
                self.logger.prn_inf("copy image onto target...")
                result = self.mbed.copy_image()
                if not result:
                    result = self.RESULT_IOERR_COPY
                    return self.get_test_result_int(result)

            # Execute test if flashing was successful or skipped
            test_result = self.run_test()

            if test_result == True:
                result = self.RESULT_SUCCESS
            elif test_result == False:
                result = self.RESULT_FAILURE
            elif test_result is None:
                result = self.RESULT_ERROR
            else:
                result = test_result

            # This will be captured by Greentea
            self.logger.prn_inf("{{result;%s}}"% result)
            return self.get_test_result_int(result)

        except KeyboardInterrupt:
            return(-3)    # Keyboard interrupt
Esempio n. 4
0
class DefaultTestSelector(DefaultTestSelectorBase):
    """! Select default host_test supervision (replaced after auto detection) """
    def __init__(self, options):
        """! ctor
        """
        self.options = options

        self.prn_lock = Lock()
        self.logger = HtrunLogger(self.prn_lock, 'HTST')

        # Handle extra command from
        if options:
            if options.enum_host_tests:
                path = self.options.enum_host_tests
                enum_host_tests(path, verbose=options.verbose)

            if options.list_reg_hts:  # --list option
                print_ht_list()
                sys.exit(0)

            if options.list_plugins:  # --plugins option
                host_tests_plugins.print_plugin_info()
                sys.exit(0)

            if options.version:  # --version
                import pkg_resources  # part of setuptools
                version = pkg_resources.require("mbed-host-tests")[0].version
                print version
                sys.exit(0)

            if options.send_break_cmd:  # -b with -p PORT (and optional -r RESET_TYPE)
                handle_send_break_cmd(port=options.port,
                                      disk=options.disk,
                                      reset_type=options.forced_reset_type,
                                      verbose=options.verbose)
                sys.exit(0)

        DefaultTestSelectorBase.__init__(self, options)

    def run_test(self):
        result = None
        timeout_duration = 10  # Default test case timeout
        event_queue = Queue()  # Events from DUT to host
        dut_event_queue = Queue()  # Events from host to DUT {k;v}

        def callback__notify_prn(key, value, timestamp):
            """! Handles __norify_prn. Prints all lines in separate log line """
            for line in value.splitlines():
                self.logger.prn_inf(line)

        callbacks = {"__notify_prn": callback__notify_prn}

        # if True we will allow host test to consume all events after test is finished
        callbacks_consume = True
        # Flag check if __exit event occurred
        callbacks__exit = False
        # Handle to dynamically loaded host test object
        self.test_supervisor = None
        # Version: greentea-client version from DUT
        self.client_version = None

        self.logger.prn_inf("starting host test process...")

        def start_conn_process():
            # Create device info here as it may change after restart.
            config = {
                "digest": "serial",
                "port": self.mbed.port,
                "baudrate": self.mbed.serial_baud,
                "program_cycle_s": self.options.program_cycle_s,
                "reset_type": self.options.forced_reset_type
            }
            # DUT-host communication process
            args = (event_queue, dut_event_queue, self.prn_lock, config)
            p = Process(target=conn_process, args=args)
            p.deamon = True
            p.start()
            return p

        p = start_conn_process()

        start_time = time()

        try:
            consume_preamble_events = True
            while (time() - start_time) < timeout_duration:
                # Handle default events like timeout, host_test_name, ...
                if not event_queue.empty():
                    try:
                        (key, value, timestamp) = event_queue.get(timeout=1)
                    except QueueEmpty:
                        continue

                    if consume_preamble_events:
                        if key == '__timeout':
                            # Override default timeout for this event queue
                            start_time = time()
                            timeout_duration = int(value)  # New timeout
                            self.logger.prn_inf("setting timeout to: %d sec" %
                                                int(value))
                        elif key == '__version':
                            self.client_version = value
                            self.logger.prn_inf(
                                "DUT greentea-client version: " +
                                self.client_version)
                        elif key == '__host_test_name':
                            # Load dynamically requested host test
                            self.test_supervisor = get_host_test(value)
                            if self.test_supervisor:
                                # Pass communication queues and setup() host test
                                self.test_supervisor.setup_communication(
                                    event_queue, dut_event_queue)
                                try:
                                    # After setup() user should already register all callbacks
                                    self.test_supervisor.setup()
                                except (TypeError, ValueError):
                                    # setup() can throw in normal circumstances TypeError and ValueError
                                    self.logger.prn_err(
                                        "host test setup() failed, reason:")
                                    self.logger.prn_inf(
                                        "==== Traceback start ====")
                                    for line in traceback.format_exc(
                                    ).splitlines():
                                        print line
                                    self.logger.prn_inf(
                                        "==== Traceback end ====")
                                    result = self.RESULT_ERROR
                                    break

                                self.logger.prn_inf(
                                    "host test setup() call...")
                                if self.test_supervisor.get_callbacks():
                                    callbacks.update(
                                        self.test_supervisor.get_callbacks())
                                    self.logger.prn_inf("CALLBACKs updated")
                                else:
                                    self.logger.prn_wrn(
                                        "no CALLBACKs specified by host test")
                                self.logger.prn_inf("host test detected: %s" %
                                                    value)
                            else:
                                self.logger.prn_err(
                                    "host test not detected: %s" % value)
                            consume_preamble_events = False
                        elif key == '__sync':
                            # This is DUT-Host Test handshake event
                            self.logger.prn_inf(
                                "sync KV found, uuid=%s, timestamp=%f" %
                                (str(value), timestamp))
                        elif key == '__notify_conn_lost':
                            # This event is sent by conn_process, DUT connection was lost
                            self.logger.prn_err(value)
                            self.logger.prn_wrn(
                                "stopped to consume events due to %s event" %
                                key)
                            callbacks_consume = False
                            result = self.RESULT_IO_SERIAL
                            break
                        elif key.startswith('__'):
                            # Consume other system level events
                            pass
                        else:
                            self.logger.prn_err(
                                "orphan event in preamble phase: {{%s;%s}}, timestamp=%f"
                                % (key, str(value), timestamp))
                    else:
                        if key == '__notify_complete':
                            # This event is sent by Host Test, test result is in value
                            # or if value is None, value will be retrieved from HostTest.result() method
                            self.logger.prn_inf("%s(%s)" % (key, str(value)))
                            result = value
                            break
                        elif key == '__reset_dut':
                            # Disconnecting and re-connecting comm process will reset DUT
                            dut_event_queue.put(
                                ('__host_test_finished', True, time()))
                            p.join()
                            # self.mbed.update_device_info() - This call is commented but left as it would be required in hard reset.
                            p = start_conn_process()
                        elif key == '__notify_conn_lost':
                            # This event is sent by conn_process, DUT connection was lost
                            self.logger.prn_err(value)
                            self.logger.prn_wrn(
                                "stopped to consume events due to %s event" %
                                key)
                            callbacks_consume = False
                            result = self.RESULT_IO_SERIAL
                            break
                        elif key == '__exit':
                            # This event is sent by DUT, test suite exited
                            self.logger.prn_inf("%s(%s)" % (key, str(value)))
                            callbacks__exit = True
                            break
                        elif key in callbacks:
                            # Handle callback
                            callbacks[key](key, value, timestamp)
                        else:
                            self.logger.prn_err(
                                "orphan event in main phase: {{%s;%s}}, timestamp=%f"
                                % (key, str(value), timestamp))
        except Exception:
            self.logger.prn_err("something went wrong in event main loop!")
            self.logger.prn_inf("==== Traceback start ====")
            for line in traceback.format_exc().splitlines():
                print line
            self.logger.prn_inf("==== Traceback end ====")
            result = self.RESULT_ERROR

        time_duration = time() - start_time
        self.logger.prn_inf("test suite run finished after %.2f sec..." %
                            time_duration)

        # Force conn_proxy process to return
        dut_event_queue.put(('__host_test_finished', True, time()))
        p.join()
        self.logger.prn_inf("CONN exited with code: %s" % str(p.exitcode))

        # Callbacks...
        self.logger.prn_inf("No events in queue" if event_queue.empty(
        ) else "Some events in queue")

        # If host test was used we will:
        # 1. Consume all existing events in queue if consume=True
        # 2. Check result from host test and call teardown()

        if callbacks_consume:
            # We are consuming all remaining events if requested
            while not event_queue.empty():
                try:
                    (key, value, timestamp) = event_queue.get(timeout=1)
                except QueueEmpty:
                    break

                if key == '__notify_complete':
                    # This event is sent by Host Test, test result is in value
                    # or if value is None, value will be retrieved from HostTest.result() method
                    self.logger.prn_inf("%s(%s)" % (key, str(value)))
                    result = value
                elif key.startswith('__'):
                    # Consume other system level events
                    pass
                elif key in callbacks:
                    callbacks[key](key, value, timestamp)
                else:
                    self.logger.prn_wrn(
                        ">>> orphan event: {{%s;%s}}, timestamp=%f" %
                        (key, str(value), timestamp))
            self.logger.prn_inf("stopped consuming events")

        if result is not None:  # We must compare here against None!
            # Here for example we've received some error code like IOERR_COPY
            self.logger.prn_inf(
                "host test result() call skipped, received: %s" % str(result))
        else:
            if self.test_supervisor:
                result = self.test_supervisor.result()
            self.logger.prn_inf("host test result(): %s" % str(result))

        if not callbacks__exit:
            self.logger.prn_wrn("missing __exit event from DUT")

        #if not callbacks__exit and not result:
        if not callbacks__exit and result is None:
            self.logger.prn_err(
                "missing __exit event from DUT and no result from host test, timeout..."
            )
            result = self.RESULT_TIMEOUT

        self.logger.prn_inf("calling blocking teardown()")
        if self.test_supervisor:
            self.test_supervisor.teardown()
        self.logger.prn_inf("teardown() finished")

        return result

    def execute(self):
        """! Test runner for host test.

        @details This function will start executing test and forward test result via serial port
                 to test suite. This function is sensitive to work-flow flags such as --skip-flashing,
                 --skip-reset etc.
                 First function will flash device with binary, initialize serial port for communication,
                 reset target. On serial port handshake with test case will be performed. It is when host
                 test reads property data from serial port (sent over serial port).
                 At the end of the procedure proper host test (defined in set properties) will be executed
                 and test execution timeout will be measured.
        """
        result = self.RESULT_UNDEF

        try:
            # Copy image to device
            if self.options.skip_flashing:
                self.logger.prn_inf("copy image onto target... SKIPPED!")
            else:
                self.logger.prn_inf("copy image onto target...")
                result = self.mbed.copy_image()
                if not result:
                    result = self.RESULT_IOERR_COPY
                    return self.get_test_result_int(result)

            # Execute test if flashing was successful or skipped
            test_result = self.run_test()

            if test_result == True:
                result = self.RESULT_SUCCESS
            elif test_result == False:
                result = self.RESULT_FAILURE
            elif test_result is None:
                result = self.RESULT_ERROR
            else:
                result = test_result

            # This will be captured by Greentea
            self.logger.prn_inf("{{result;%s}}" % result)
            return self.get_test_result_int(result)

        except KeyboardInterrupt:
            return (-3)  # Keyboard interrupt