Пример #1
0
    def __gen_options(self, scenario):
        options = etree.Element("options")

        global_think_time = scenario.get_think_time()
        if global_think_time:
            think_time = int(dehumanize_time(global_think_time))
            options.append(
                etree.Element("option",
                              name="thinktime",
                              value=str(think_time),
                              random="false"))

        global_tcp_timeout = scenario.get("timeout")
        if global_tcp_timeout:
            timeout = int(dehumanize_time(global_tcp_timeout) * 1000)
            options.append(
                etree.Element("option",
                              name="connect_timeout",
                              value=str(timeout)))

        global_max_retries = scenario.get("max-retries", 1)
        options.append(
            etree.Element("option",
                          name="max_retries",
                          value=str(global_max_retries)))
        return options
Пример #2
0
    def __gen_load(self, load):
        """
        Generate Tsung load profile.

        Tsung load progression is scenario-based. Virtual users are erlang processes which are spawned according to
        load profile. Each user executes assigned session (requests + think-time + logic) and then dies.
        :param scenario:
        :param load:
        :return:
        """
        concurrency = load.concurrency if load.concurrency is not None else 1
        load_elem = etree.Element("load")
        if load.duration:
            duration, unit = self.__time_to_tsung_time(int(round(load.duration)))
            load_elem.set('duration', str(duration))
            load_elem.set('unit', unit)
        phases = []

        if load.hold:
            duration, unit = self.__time_to_tsung_time(int(round(load.hold)))
            users = etree.Element("users", arrivalrate=str(concurrency), unit="second")
            phase = etree.Element("arrivalphase",
                                  phase=str("1"),
                                  duration=str(duration),
                                  unit=unit)
            phase.append(users)
            phases.append(phase)
        else:
            raise TaurusConfigError("Tsung: you must specify test duration with 'hold-for'")

        for phase in phases:
            load_elem.append(phase)

        return load_elem
Пример #3
0
    def __dump_xml(self, filename):
        self.log.info("Dumping final status as XML: %s", filename)
        root = etree.Element("FinalStatus")

        if self.first_ts < float("inf") and self.last_ts > 0:
            duration_elem = etree.Element("TestDuration")
            duration_elem.text = str(
                round(float(self.last_ts - self.first_ts), 3))
            root.append(duration_elem)

        report_info = get_bza_report_info(self.engine, self.log)
        if report_info:
            link, _ = report_info[0]
            report_element = etree.Element("ReportURL")
            report_element.text = link
            root.append(report_element)
        if self.last_sec:
            for label, kpiset in iteritems(
                    self.last_sec[DataPoint.CUMULATIVE]):
                root.append(self.__get_xml_summary(label, kpiset))

        with open(get_full_path(filename), 'wb') as fhd:
            tree = etree.ElementTree(root)
            tree.write(fhd,
                       pretty_print=True,
                       encoding="UTF-8",
                       xml_declaration=True)
Пример #4
0
    def process_sample_labels(self, xunit):
        """
        :type xunit: XUnitFileWriter
        """
        xunit.report_test_suite('sample_labels')
        labels = self.last_second[DataPoint.CUMULATIVE]

        for key in sorted(labels.keys()):
            if key == "":  # skip total label
                continue

            errors = []
            for er_dict in labels[key][KPISet.ERRORS]:
                rc = str(er_dict["rc"])
                msg = str(er_dict["msg"])
                cnt = str(er_dict["cnt"])
                if er_dict["type"] == KPISet.ERRTYPE_ASSERT:
                    err_element = etree.Element("failure",
                                                message=msg,
                                                type="Assertion Failure")
                else:
                    err_element = etree.Element("error",
                                                message=msg,
                                                type="Error")
                err_desc = "%s\n(status code is %s)\n(total errors of this type: %s)" % (
                    msg, rc, cnt)
                err_element.text = err_desc
                errors.append(err_element)

            xunit.report_test_case('sample_labels', key, errors)
Пример #5
0
 def process_functional(self, xunit):
     for suite_name, samples in iteritems(self.cumulative_results):
         duration = max(s.start_time for s in samples) - min(s.start_time for s in samples)
         duration += max(samples, key=lambda s: s.start_time).duration
         attrs = {
             "name": suite_name,
             "tests": str(len(samples)),
             "errors": str(len([sample for sample in samples if sample.status == "BROKEN"])),
             "skipped": str(len([sample for sample in samples if sample.status == "SKIPPED"])),
             "failures": str(len([sample for sample in samples if sample.status == "FAILED"])),
             "time": str(round(duration, 3)),
             # TODO: "timestamp" attribute
         }
         xunit.add_test_suite(suite_name, attributes=attrs)
         for sample in samples:
             attrs = {
                 "classname": sample.test_suite,
                 "name": sample.test_case,
                 "time": str(round(sample.duration, 3))
             }
             children = []
             if sample.status == "BROKEN":
                 error = etree.Element("error", type=sample.error_msg)
                 if sample.error_trace:
                     error.text = sample.error_trace
                 children.append(error)
             elif sample.status == "FAILED":
                 failure = etree.Element("failure", message=sample.error_msg)
                 if sample.error_trace:
                     failure.text = sample.error_trace
                 children.append(failure)
             elif sample.status == "SKIPPED":
                 skipped = etree.Element("skipped")
                 children.append(skipped)
             xunit.add_test_case(suite_name, attributes=attrs, children=children)
Пример #6
0
 def __gen_clients(self):
     # TODO: distributed clients?
     clients = etree.Element("clients")
     client = etree.Element("client",
                            host="localhost",
                            use_controller_vm="true")
     clients.append(client)
     return clients
Пример #7
0
    def __gen_servers(self, scenario):
        default_address = scenario.get("default-address")
        if default_address:
            base_addr = parse.urlparse(default_address)
        else:
            first_request = self.__first_http_request(scenario)
            if not first_request:
                raise TaurusConfigError("Tsung: you must specify requests in scenario")
            base_addr = parse.urlparse(first_request.url)
            self.log.debug("default-address was not specified, using %s instead", base_addr.hostname)

        servers = etree.Element("servers")
        port = base_addr.port if base_addr.port is not None else 80
        server = etree.Element("server", host=base_addr.hostname, port=str(port), type="tcp")
        servers.append(server)
        return servers
Пример #8
0
    def add_test_case(self, suite_name, attributes=None, children=()):
        attributes = attributes or {}

        case = etree.Element("testcase", **attributes)

        for child in children:
            case.append(child)
Пример #9
0
    def save_report(self, fname):
        """
        :type fname: str
        """
        try:
            if os.path.exists(fname):
                self.log.warning(
                    "File %s already exists, it will be overwritten", fname)
            else:
                dirname = os.path.dirname(fname)
                if dirname and not os.path.exists(dirname):
                    os.makedirs(dirname)

            testsuites = etree.Element("testsuites")
            for _, suite in iteritems(self.test_suites):
                testsuites.append(suite)
            etree_obj = etree.ElementTree(testsuites)

            self.log.info("Writing JUnit XML report into: %s", fname)
            with open(get_full_path(fname), 'wb') as _fds:
                etree_obj.write(_fds,
                                xml_declaration=True,
                                encoding="UTF-8",
                                pretty_print=True)
        except BaseException:
            raise TaurusInternalException("Cannot create file %s" % fname)
Пример #10
0
    def __get_kpi_xml(self, kpi_name, kpi_val, param=None):
        kpi = etree.Element(kpi_name)
        kpi.attrib['value'] = self.__val_to_str(kpi_val)
        elm_name = etree.Element("name")
        elm_name.text = kpi_name
        if param is not None:
            kpi.attrib['param'] = self.__val_to_str(param)
            elm_name.text += "/" + param

        kpi.append(elm_name)

        elm_value = etree.Element("value")
        elm_value.text = self.__val_to_str(kpi_val)
        kpi.append(elm_value)

        return kpi
Пример #11
0
    def process_pass_fail(self, xunit):
        """
        :type xunit: XUnitFileWriter
        """
        xunit.report_test_suite('bzt_pass_fail')
        mods = self.engine.reporters + self.engine.services  # TODO: remove it after passfail is only reporter
        pass_fail_objects = [_x for _x in mods if isinstance(_x, PassFailStatus)]
        self.log.debug("Processing passfail objects: %s", pass_fail_objects)
        fail_criteria = []
        for pf_obj in pass_fail_objects:
            if pf_obj.criteria:
                for _fc in pf_obj.criteria:
                    fail_criteria.append(_fc)

        for fc_obj in fail_criteria:
            if 'label' in fc_obj.config:
                data = (fc_obj.config['subject'], fc_obj.config['label'], fc_obj.config['condition'],
                        fc_obj.config['threshold'])
                tpl = "%s of %s%s%s"
            else:
                data = (fc_obj.config['subject'], fc_obj.config['condition'], fc_obj.config['threshold'])
                tpl = "%s%s%s"
            if fc_obj.config['timeframe']:
                tpl += " for %s"
                data += (fc_obj.config['timeframe'],)
            disp_name = tpl % data

            if fc_obj.is_triggered and fc_obj.fail:
                errors = [etree.Element("error", message=str(fc_obj), type="pass/fail criteria triggered")]
            else:
                errors = ()

            xunit.report_test_case('bzt_pass_fail', disp_name, errors)
Пример #12
0
 def __init__(self, tsung_tool):
     self.log = logging.getLogger(self.__class__.__name__)
     self.root = etree.Element("tsung",
                               loglevel="notice",
                               version="1.0",
                               dumptraffic="protocol",
                               backend="text")
     self.tree = etree.ElementTree(self.root)
     self.tool = tsung_tool
Пример #13
0
    def add_test_suite(self, suite_name, attributes=None, children=()):
        attributes = attributes or {}

        suite = etree.Element("testsuite", **attributes)

        for child in children:
            suite.append(child)

        if not suite_name in self.test_suites:
            self.test_suites[suite_name] = suite
Пример #14
0
 def report_test_case(self, suite_name, case_name, children=None):
     """
     :type suite_name: str
     :type case_name: str
     :type children: list[lxml.etree.Element]
     """
     children = children or []
     if self.report_urls:
         system_out = etree.Element("system-out")
         system_out.text = "".join(self.report_urls)
         children.insert(0, system_out)
     self.add_test_case(suite_name, attributes={"classname": self.class_name, "name": case_name}, children=children)
Пример #15
0
    def __gen_sessions(self, scenario):
        sessions = etree.Element("sessions")
        session = etree.Element("session", name="taurus_requests", probability="100", type="ts_http")
        for request in scenario.get_requests():
            if not isinstance(request, HTTPRequest):
                msg = "Tsung config generator doesn't support '%s' blocks, skipping"
                self.log.warning(msg, request.NAME)
                continue

            request_elem = etree.Element("request")
            http_elem = etree.Element("http", url=request.url, method=request.method, version="1.1")
            if request.body:
                http_elem.set('contents', request.body)

            headers = copy.deepcopy(scenario.get_headers())
            headers.update(copy.deepcopy(request.headers))
            for header_name, header_value in iteritems(headers):
                http_elem.append(etree.Element("http_header", name=header_name, value=header_value))

            request_elem.append(http_elem)
            session.append(request_elem)
            if request.get_think_time():
                think_time = int(dehumanize_time(request.get_think_time()))
                session.append(etree.Element("thinktime", value=str(think_time), random="false"))
        sessions.append(session)
        return sessions
Пример #16
0
    def __get_xml_summary(self, label, kpiset):
        elem = etree.Element("Group", label=label)
        for kpi_name, kpi_val in iteritems(kpiset):
            if kpi_name in (KPISet.ERRORS, KPISet.RESP_TIMES):
                continue

            if isinstance(kpi_val, dict):
                for param_name, param_val in iteritems(kpi_val):
                    elem.append(self.__get_kpi_xml(kpi_name, param_val, param_name))
            else:
                elem.append(self.__get_kpi_xml(kpi_name, kpi_val))

        return elem