def format_api_calls(self):
        """When converted to string, the API requests and responses will be formatted."""
        request1 = re.match(VPatterns.get_std_details_request()[0], self._details)
        request2 = re.match(VPatterns.get_std_details_request()[1], self._details)
        response = re.match(VPatterns.get_std_details_response(), self._details)

        if request1:
            # "Sending HTTP POST request to server_url: ..."
            if request1.group(2) != 'None':
                request_json = json.loads(request1.group(2))
                self._request_url = request1.group(1)
                self._request_id = int(request_json['id'])
                self._request_method = request_json['method']
                self._request_params = request_json['params']
        elif request2:
            # "JSON-RPC-POST: method= ..."
            self._request_url = request2.group(2)
            self._request_id = int(request2.group(3))
            self._request_method = request2.group(1)
            self._request_params = ""
        elif response:
            # "JSON-RPC-POST response: ..."
            string = response.group(1)
            json_response = json.loads(string)
            self._response_id = json_response['id']
            if 'result' in json_response:
                self._response_result = json_response['result']
                self._response_type = 'Result'
            elif 'error' in json_response:
                self._response_result = json_response['error']
                self._response_type = 'Error'
 def is_at2_formatting(self, filepath):
     """Determines if the logs are using the AT2 format."""
     with open(filepath, 'r') as f:
         for line in f:
             if re.match(VPatterns.get_std(), line):
                if re.search(VPatterns.get_at2_time(), line):
                    return True
                else:
                    return False
    def _handle_raw_traceback(self, unf_log):
        """Handle traceback operations.

        Since tracebacks are contained in multiple lines, the separate elements must be stored.
        They are identified as follows and can be prepended by the same leading characters::

            Traceback (most recent call last):
              File "<file name>", line <line num>, in <func call>
                <line>
              ...
            <exception>: <description>

        Leading characters can be ``!``, ``|>``, etc.

        :rtype: str | list(str) | None
        :returns: unf_str if not part of a traceback
        :returns: None if unf_log is part of traceback but not exception
        :returns: list of log lines gathered from traceback if unf_log is the last line.
        """
        output = ""
        if unf_log is None:
            return None
        # First line of traceback ('Traceback (most recent call last):')
        if self._lm.curr_log_type == VLogType.TRACEBACK:
            self._lm.hold = True
            self.tb_leading_char = re.match(VPatterns.get_traceback(),
                                            unf_log).group(1)
            self._store_log(unf_log)
            self.traceback_flag = True
            output = None
        # Non-traceback log line
        elif not self.traceback_flag:
            output = unf_log
        # Last line of traceback ('<exception>: <description')
        elif re.match(VPatterns.get_traceback_exception(),
                      unf_log[len(self.tb_leading_char):]):
            output = self.stored_logs
            output.append(unf_log)
            self._lm.curr_log_type = VLogType.TRACEBACK
            self.stored_logs = []
            self.traceback_flag = False
            self.tb_leading_char = ""
            self._lm.hold = False
        # Inner traceback element
        elif self._lm.curr_log_type == VLogType.OTHER and unf_log:
            self._store_log(unf_log)
            output = None
        # Traceback doesn't meet vl specifications
        elif self._lm.curr_log_type:
            self._lm.enqueue_log(self._pull_logs())
            self._lm.hold = False
            output = unf_log
        return output
示例#4
0
        def test_get_patterns(self):
            dt_pattern = " ".join(
                ["\d{4}-\d{2}-\d{2}", "\d{2}:\d{2}:\d{2}\.\d{6}"])
            type_pattern = "(DEBUG|INFO|NOTICE|WARNING|ERROR|CRITICAL)"
            source_pattern = "\[.*:.*\]"
            thread_pattern = "\[.*:.*\]"
            details_pattern = ".*"

            self.assertEqual(VPatterns.get_std_datetime(), dt_pattern)
            self.assertEqual(VPatterns.get_std_type(), type_pattern)
            self.assertEqual(VPatterns.get_std_source(), source_pattern)
            self.assertEqual(VPatterns.get_std_thread(), thread_pattern)
            self.assertEqual(VPatterns.get_std_details(), details_pattern)
    def _create_log_line(self, unf_str, log_type):
        """Create the appropriate VLogLine object based on type.

        :param str unf_str: Unformatted VL log line
        :param VLogType log_type: Type of VLogLine object to create.
        :rtype: LogLine | None
        :returns: VLogLine if unf_str matches pattern of type and is in specified test case, else None
        """
        if not log_type or not unf_str:
            return unf_str

        output = None
        # Standard Log Line
        if log_type in VPatterns.std_log_types(
        ) and self._hm.std_log_in_specified_testcase():
            output = vlogline.Standard(unf_str, log_type)

            # Store Start time
            self._store_curr_time(output)

            # Associate Error with Header
            if self.SUMMARY and output and output.logtype == VLogType.ERROR:
                self._hm.add_error(output)
        # Traceback Log Lines
        elif log_type == VLogType.TRACEBACK and self._hm.std_log_in_specified_testcase(
        ):
            output = vlogline.Traceback(unf_str)
        # Step Header
        elif log_type == VLogType.STEP_H:
            fmt_log = vlogline.StepHeader(unf_str)
            output = self._hm.update_current_log(fmt_log)
        # Test Case Header
        elif log_type == VLogType.TEST_CASE_H:
            fmt_log = vlogline.TestCaseHeader(unf_str)
            output = self._hm.update_current_log(fmt_log)
        # Suite Header
        elif log_type == VLogType.SUITE_H:
            fmt_log = vlogline.SuiteHeader(unf_str)
            output = self._hm.update_current_log(fmt_log)
        # General Header
        elif log_type == VLogType.GENERAL_H:
            fmt_log = vlogline.GeneralHeader(unf_str)
            output = self._hm.update_current_log(fmt_log)
        # Other Log Line
        elif log_type == VLogType.OTHER and self._hm.std_log_in_specified_testcase(
        ):
            output = vlogline.Other(unf_str)

        if output:
            self._prev_fmt_log = output

        return output
    def _parse_fields(self, unf_str):
        """Parse the string into the suite header fields.

        Fields::

            Suite Name, Description

        :return a list of the suite header fields
        :rtype list(str)
        """
        unf_str = unf_str.strip(self.BORDER_CHAR)
        _, desc_token = unf_str.split(": ")
        fields = []
        suite_name = re.search(VPatterns.get_suite_name(), desc_token).group(0)
        fields.append(suite_name)
        fields.append(desc_token)
        return fields
    def _store_curr_time(self, log):
        """Store the datetime object of the time from the current log or None if no time available."""
        if self.SUMMARY:
            set_root = False
            if not self._hm.is_test_start_time_added():
                set_root = True

            if isinstance(log, str):
                pattern = "^(" + VPatterns.get_std_datetime() + ")"
                m = re.match(pattern, log)
                if m and m.group(1):
                    self._curr_time = vlogfield.Datetime(m.group(1)).datetime
            else:
                self._curr_time = log.datetime

            if isinstance(self._prev_fmt_log, vlogline.Header) or set_root:
                self._hm.start_time(self._curr_time, root=set_root)
    def _parse_fields(self, unf_str):
        """Parse the string into the test case header fields.

        Fields::

            Test Case Name, Number, Description

        :return a list of the test case header fields
        :rtype list(str)
        """
        unf_str = unf_str.strip(self.BORDER_CHAR)
        unf_str = unf_str.lstrip("Test Case ")
        number, desc_token = unf_str.split(": ")
        case_name = re.search(VPatterns.get_test_case_name(),
                              desc_token).group(0)
        fields = []
        fields.append(case_name)
        fields.append(int(number))
        fields.append(desc_token)
        return fields
    def _parse_fields(self, unf_str_list):
        """Parse the list of strings into the header, steps, and exception fields.

        :param list(str) unf_str_list: Unformatted VL log line
        """
        unf_header = unf_str_list[0]
        unf_steps = unf_str_list[1:-1]
        unf_exception = unf_str_list[-1]

        self.leading_chars = re.match(VPatterns.get_traceback(),
                                      unf_header).group(1)
        fmt_steps = []
        for line1, line2 in zip(unf_steps[0::2], unf_steps[1::2]):
            line1 = self._remove_leading_chars(line1)
            line2 = self._remove_leading_chars(line2)
            step = "\n".join([line1, line2])
            fmt_steps.append(vlogfield.TracebackStep(step, self.leading_chars))
        unf_exception = self._remove_leading_chars(unf_exception)
        fmt_exception = vlogfield.TracebackException(unf_exception,
                                                     self.leading_chars)
        return fmt_steps, fmt_exception
示例#10
0
    def _parse_fields(self, unf_str):
        """Parse the string into the step header fields.

        Fields::

            Test Case Name, Number, Action, Expected Results

        :return a list of the step header fields
        :rtype list(str)
        """
        line1, line2 = unf_str.split("\n")
        line1 = line1.strip(self.BORDER_CHAR)
        line2 = line2.strip(self.BORDER_CHAR)
        id, action = line1.split(": ")
        case_name = re.search(VPatterns.get_test_case_name(), id).group(0)
        number = re.search("\d+", id).group(0)
        _, expected_result = line2.split(": ")
        fields = []
        fields.append(case_name)
        fields.append(int(number))
        fields.append(action)
        fields.append(expected_result)
        return fields
    def parse_step(self, tc_log_file, step_num):
        """Parses step logs from a test case log file.

        The specified step logs are placed into a file labelled with the step info,
        and the file will be located in a directory labelled tc_logs in the same directory as the
        log file.
        If the file already exists, the method will return.

        Example::

            parse_step("~/logs/tc_logs/TcExample.log", step=0)

            # File location
            ~/logs/tc_logs/TcExample_Step-0.log

        :param str tc_log_file: Filepath of log file to be parsed.
        :param int step_num: Number of step to be parsed.
        """

        tc_dir = os.path.dirname(tc_log_file)
        tc_filename = re.search("(Tc-?\w+).log", tc_log_file)
        step_filename = "%s_Step-%d.log" % (tc_filename.group(1), step_num)
        step_file = os.path.join(tc_dir, step_filename)
        if os.path.exists(step_file):
            return step_file
        else:
            open(step_file, "w").close()

        step_regex = VPatterns.get_step_header()
        tc_regex = VPatterns.get_test_case_header()
        in_specified_step = False
        completed_specified_step = False

        with open(tc_log_file) as original_file:
            for line in original_file:
                line = self._handle_raw_header(line.rstrip("\n"))
                if line is None:
                    continue

                tc_match = re.match(tc_regex, line)
                step_match = re.match(step_regex, line)

                # Line is step
                if step_match:
                    step = vlogline.StepHeader(line)

                    # Step number matches current line
                    if step_num == step.number:
                        in_specified_step = True
                    # New step is reached
                    elif in_specified_step:
                        completed_specified_step = True
                        in_specified_step = False

                    if in_specified_step:
                        with open(step_file, "a") as f:
                            f.write(str(step) + "\n")

                # Next Test Case reached
                elif tc_match and in_specified_step:
                    completed_specified_step = True
                    in_specified_step = False

                # Logs in specified step
                elif in_specified_step:
                    with open(step_file, "a") as f:
                        f.write(str(line) + "\n")

                if completed_specified_step:
                    return step_file
        return step_file
    def parse_test_case(self, log_file, tc_name=None, tc_num=None):
        """Parses test case logs from a log file.

        The specified test case logs are placed into a file labelled with the tc info,
        and the file will be located in a directory labelled tc_logs in the same directory as the
        log file.
        If the file already exists, the method will return.

        Example::

            parse_test_case("~/logs/test.log", tc_name="TcExample")

            # File location
            ~/logs/tc_logs/TcExample.log

        :param str log_file: Filepath of log file to be parsed.
        :param str tc_name: Name of test case to be parsed, will supercede tc_num if specified
        :param int tc_num: Number of test case to be parsed.
        :returns: String filepath to parsed log file.
        """

        dir = os.path.dirname(log_file)
        tc_dir = os.path.join(dir, "tc_logs")
        if not os.path.exists(tc_dir):
            os.mkdir(tc_dir)
        tc_filename = "%s.log" % (tc_name) if tc_name else ("Tc-%d.log" %
                                                            (tc_num))
        tc_file = os.path.join(tc_dir, tc_filename)
        if os.path.exists(tc_file):
            return tc_file
        else:
            open(tc_file, "w").close()

        step_regex = VPatterns.get_step_header()
        tc_regex = VPatterns.get_test_case_header()
        suite_regex = VPatterns.get_suite_header()
        general_regex = VPatterns.get_general_header()
        in_specified_tc = False
        completed_specified_tc = False

        with open(log_file) as original_file:
            for line in original_file:
                line = self._handle_raw_header(line.rstrip("\n"))
                if line is None:
                    continue

                tc_match = re.match(tc_regex, line)
                step_match = re.match(step_regex, line)
                header_match = re.match(
                    "".join([suite_regex, "|", general_regex]), line)

                # Line is test case
                if tc_match:
                    tc = vlogline.TestCaseHeader(line)

                    # TC name matches current line
                    if tc_name and tc_name == tc.test_case_name:
                        in_specified_tc = True
                    # TC number matches current line
                    elif tc_num >= 0 and tc_num == tc.number:
                        in_specified_tc = True
                    # New TC is reached
                    elif in_specified_tc:
                        completed_specified_tc = True
                        in_specified_tc = False

                    if in_specified_tc:
                        with open(tc_file, "a") as f:
                            f.write(str(tc) + "\n")

                # Line is a step header
                elif step_match and in_specified_tc:
                    step = vlogline.StepHeader(line)
                    with open(tc_file, "a") as f:
                        f.write(str(step) + "\n")

                # New General or Suite header found to signal end of specified test case
                elif header_match and in_specified_tc:
                    completed_specified_tc = True

                # Logs in specified test case
                elif in_specified_tc:
                    with open(tc_file, "a") as f:
                        f.write(str(line) + "\n")

                if completed_specified_tc:
                    return tc_file
        return tc_file