Beispiel #1
0
    def __read_response(self):
        """
        Internal response reader.

        :return: CliResponse or None
        """
        try:
            line = self.readline()
        except RuntimeError:
            Dut._logger.warning("Failed to read PIPE", extra={'type': '!<-'})
            return -1
        if line:
            self.traces.append(line)
            EventObject(EventTypes.DUT_LINE_RECEIVED, self, line)
            self.response_traces.append(line)
            match = re.search(r"^\[([\w\W]{4})\]\[([\W\w]{4,}?)\]\: (.*)",
                              line)
            if match:
                self.logger.debug(line, extra={'type': '<<<'})
            else:
                self.logger.info(line, extra={'type': '<--'})

            retcode = self.check_retcode(line)
            if retcode is not None:
                resp = CliResponse()
                resp.retcode = retcode
                resp.traces = self.response_traces
                resp.lines = self.response_traces
                self.response_traces = []
                return resp
        return None
Beispiel #2
0
    def execute_command(
            self,
            k,
            cmd,  # pylint: disable=invalid-name
            wait=True,
            timeout=50,
            expected_retcode=0,
            asynchronous=False,
            report_cmd_fail=True):
        """
        Do Command request for DUT.
        If this fails, testcase will be marked as failed in internal mechanisms.
        This will happen even if you later catch the exception in your testcase.
        To get around this (allow command failing without throwing exceptions),
        use the reportCmdFail parameter which disables the raise.

        :param k: Index where command is sent, '*' -send command for all duts.
        :param cmd: Command to be sent to DUT.
        :param wait: For special cases when retcode is not wanted to wait.
        :param timeout: Command timeout in seconds.
        :param expected_retcode: Expecting this retcode, default: 0, can be None when it is ignored.
        :param asynchronous: Send command, but wait for response in parallel.
        When sending next command previous response will be wait. When using async mode,
        response is dummy.
        :param report_cmd_fail: If True (default), exception is thrown on command execution error.
        :return: CliResponse object
        """
        ret = None
        if not report_cmd_fail:
            expected_retcode = None
        if k == '*':
            ret = self._send_cmd_to_all(cmd,
                                        wait=wait,
                                        expected_retcode=expected_retcode,
                                        timeout=timeout,
                                        asynchronous=asynchronous,
                                        report_cmd_fail=report_cmd_fail)
        else:
            if isinstance(k, str):
                k = self._resources.get_dut_index(k)

            if not self._resources.is_allowed_dut_index(k):
                self._logger.error("Invalid DUT number")
                raise ValueError(
                    "Invalid DUT number when calling execute_command(%i)" % k)

            if not self._resources.is_my_dut_index(k):
                self._wait_for_exec_ext_dut_cmd(k, cmd)
                return CliResponse()

            dut = self._resources.get_dut(k)
            ret = self._execute_command(dut,
                                        cmd,
                                        wait=wait,
                                        expected_retcode=expected_retcode,
                                        timeout=timeout,
                                        asynchronous=asynchronous,
                                        report_cmd_fail=report_cmd_fail)
        return ret
Beispiel #3
0
 def _create_line_response_parser(self, command, path):
     output = open(path, 'r').read()
     response = CliResponse()
     for line in output.splitlines():
         response.lines.append(line)
     parser = self.parsermanager
     resp = parser.parse(command, response)
     return resp
    def test_traces_deprecated(self):
        response = CliResponse()
        response.traces = ['aapeli', 'beeveli', 'oopeli', 'huhheli']
        self.assertTrue(response.verify_trace(['oopeli'], False))
        self.assertTrue(response.verify_trace(['oopeli', 'huhheli'], False))
        self.assertFalse(response.verify_trace(['huhheli', 'oopeli'], False))

        with self.assertRaises(LookupError):
            self.assertTrue(response.verify_trace(['oop eli']))
    def test_resps(self):
        response = CliResponse()
        response.lines = ['aapeli', 'beeveli', 'oopeli', 'huhheli']
        self.assertTrue(response.verify_message(['oopeli'], False))
        self.assertTrue(response.verify_message(['oopeli', 'huhheli'], False))
        self.assertFalse(response.verify_message(['huhheli', 'oopeli'], False))

        with self.assertRaises(LookupError):
            self.assertTrue(response.verify_message(['oop eli']))
Beispiel #6
0
    def _execute_command(self,
                         dut,
                         cmd,
                         wait=True,
                         expected_retcode=0,
                         timeout=50,
                         asynchronous=False,
                         report_cmd_fail=True):
        """
        Internal command sender.
        """
        try:
            # construct command object to be execute

            req = CliRequest(cmd,
                             timestamp=self._benchfunctions.get_time(),
                             wait=wait,
                             expected_retcode=expected_retcode,
                             timeout=timeout,
                             asynchronous=asynchronous,
                             dutIndex=dut.index)
            # execute command
            try:
                req.response = dut.execute_command(req)
            except (TestStepFail, TestStepError, TestStepTimeout) as error:
                if not report_cmd_fail:
                    self._logger.error(
                        "An error occured when executing command on dut %s",
                        dut.index)
                    self._logger.debug(
                        "reportCmdFail is set to False, don't raise.")
                    self._logger.error("Supressed error: %s", error)
                    if req.response is None:
                        req.response = CliResponse()
                else:
                    raise

            if wait and not asynchronous:
                # There should be valid responses
                self._check_expected_retcode(expected_retcode, req)
                # Parse response
                parsed = self._plugins.parse_response(
                    cmd.split(' ')[0].strip(), req.response)
                if parsed is not None:
                    req.response.parsed = parsed
                    if parsed.keys():
                        self._logger.info(parsed)
            return req.response

        except (KeyboardInterrupt, SystemExit):
            # shut down tc directly
            self._logger.warning("Keyboard/SystemExit request - shut down TC")
            self._command_fail(CliRequest(), "Aborted by user")
Beispiel #7
0
    def _wait_for_exec_ready(self):
        """
        Wait for response.

        :return: CliResponse object coming in
        :raises: TestStepTimeout, TestStepError
        """
        #wait for response
        while not self.response_received.wait(1) and self.query_timeout != 0:
            if self.query_timeout != 0 and self.query_timeout < self.get_time(
            ):
                if self.prev:
                    cmd = self.prev.cmd
                else:
                    cmd = "???"
                self.logger.error("CMD timeout: " + cmd)
                self.query_timeout = 0
                raise TestStepTimeout(self.name + " CMD timeout: " + cmd)
            self.logger.debug("Waiting for response... "
                              "timeout=%d",
                              self.query_timeout - self.get_time())

        if self.response_coming_in == -1:
            if self.query_async_response is not None:
                # fullfill the async response with a dummy response and clean the state
                self.query_async_response.set_response(CliResponse())
                self.query_async_response = None
            # raise and log the error
            self.logger.error("No response received, DUT died")
            raise TestStepError("No response received, DUT " + self.name +
                                " died")

        # if an async response is pending, fullfill it with the result
        if self.query_async_response is not None:
            self.query_async_response.set_response(self.response_coming_in)
            self.query_async_response = None

        self.query_timeout = 0
        return self.response_coming_in
Beispiel #8
0
    def execute_command(self, req, **kwargs):
        """
        Execute command and return CliResponse

        :param req: String, command to be executed in DUT, or CliRequest, command class which
        contains all configurations like timeout.
        :param kwargs: Configurations (wait, timeout) which will be used when string mode is in use.
        :return: CliResponse, which contains all received data from Dut and parsed retcode.
        """
        if isinstance(req, string_types):
            # backward compatible
            timeout = 50  # Use same default timeout as bench.py
            wait = True
            asynchronous = False
            for key in kwargs:
                if key == 'wait':
                    wait = kwargs[key]
                elif key == 'timeout':
                    timeout = kwargs[key]  # [ms]
                elif key == 'asynchronous':
                    asynchronous = kwargs[key]
            req = CliRequest(req,
                             timestamp=self.get_time(),
                             wait=wait,
                             timeout=timeout,
                             asynchronous=asynchronous)

        # wait for previous command ready
        if req.wait:
            response = self._wait_for_exec_ready()
            if response is not None and self.query_async_expected is not None:
                if response.retcode != self.query_async_expected:
                    self.logger.error(
                        "Asynch call returned unexpected result, "
                        "expected %d was %d", self.query_async_expected,
                        response.retcode)
                    raise TestStepFail(
                        "Asynch call returned unexpected result")
                self.query_async_expected = None

        # Tell Query to worker thread
        self.response_received.clear()
        self.query_timeout = self.get_time() + req.timeout if req.wait else 0
        self.query = req

        msg = "Async CMD {}, timeout={}, time={}" if req.asynchronous else "CMD {}, timeout={}, time={}"
        msg = msg.format(req.cmd, int(self.query_timeout),
                         int(self.get_time()))
        self.logger.debug(msg, extra={'type': '<->'})

        Dut.process_dut(self)

        if req.asynchronous is True:
            self.query_async_expected = req.expected_retcode
            async_response = CliAsyncResponse(self)
            self.query_async_response = async_response
            return async_response

        if req.wait is False:
            self.query_async_expected = req.expected_retcode
            # if an async response was waiting, just discard the result
            # since the new command has already been sent...
            # This is not ideal but when a command has its flags "Wait == False"
            # the result of the previous command is already discarded in previous
            # stages
            if self.query_async_response is not None:
                self.query_async_response.set_response(CliResponse())
            self.query_async_response = None
            return CliResponse()

        return self._wait_for_exec_ready()