Esempio n. 1
0
    def _request(self,
                 url,
                 data=None,
                 headers=None,
                 method=None,
                 raw_result=False):
        """
        :param url: str
        :type data: Union[dict,str]
        :param headers: dict
        :param method: str
        :return: dict
        """
        if not headers:
            headers = {}

        headers["X-Client-Id"] = "Taurus"
        headers["X-Client-Version"] = VERSION

        if isinstance(self.token, string_types) and ':' in self.token:
            token = self.token
            if isinstance(token, text_type):
                token = token.encode('ascii')
            token = base64.b64encode(token).decode('ascii')
            headers['Authorization'] = 'Basic ' + token
        elif self.token:
            headers["X-Api-Key"] = self.token

        if method:
            log_method = method
        else:
            log_method = 'GET' if data is None else 'POST'

        url = str(url)

        if isinstance(data, text_type):
            data = data.encode("utf8")

        if isinstance(data, (dict, list)):
            data = to_json(data)
            headers["Content-Type"] = "application/json"

        self.log.debug("Request: %s %s %s", log_method, url,
                       data[:self.logger_limit] if data else None)

        response = self.http_request(method=log_method,
                                     url=url,
                                     data=data,
                                     headers=headers,
                                     cookies=self._cookies,
                                     timeout=self.timeout)

        resp = response.content
        if not isinstance(resp, str):
            resp = resp.decode()

        self.log.debug("Response: %s",
                       resp[:self.logger_limit] if resp else None)
        if response.status_code >= 400:
            try:
                result = json.loads(resp) if len(resp) else {}
                if 'error' in result and result['error']:
                    raise TaurusNetworkError("API call error %s: %s" %
                                             (url, result['error']))
            except ValueError:
                raise TaurusNetworkError(
                    "API call error %s: %s %s" %
                    (url, response.status_code, response.reason))

        if raw_result:
            return resp

        try:
            result = json.loads(resp) if len(resp) else {}
        except ValueError as exc:
            self.log.debug('Response: %s', resp)
            raise TaurusNetworkError("Non-JSON response from API: %s" % exc)

        if 'error' in result and result['error']:
            raise TaurusNetworkError("API call error %s: %s" %
                                     (url, result['error']))

        return result
Esempio n. 2
0
    def _request(self, url, data=None, headers=None, method=None, raw_result=False, retry=True):
        """
        :param url: str
        :type data: Union[dict,str]
        :param headers: dict
        :param method: str
        :return: dict
        """
        if not headers:
            headers = {}

        headers["X-Client-Id"] = "Taurus"
        headers["X-Client-Version"] = VERSION

        has_auth = headers and "X-Api-Key" in headers
        if has_auth:
            pass  # all is good, we have auth provided
        elif isinstance(self.token, str) and ':' in self.token:
            token = self.token
            if isinstance(token, str):
                token = token.encode('ascii')
            token = base64.b64encode(token).decode('ascii')
            headers['Authorization'] = 'Basic ' + token
        elif self.token:
            headers["X-Api-Key"] = self.token

        if method:
            log_method = method
        else:
            log_method = 'GET' if data is None else 'POST'

        url = str(url)

        if isinstance(data, str):
            data = data.encode("utf-8")

        if isinstance(data, (dict, list)):
            data = to_json(data)
            headers["Content-Type"] = "application/json"

        self.log.debug("Request: %s %s %s", log_method, url, data[:self.logger_limit] if data else None)

        retry_limit = self._retry_limit

        while True:
            try:
                response = self.http_request(
                    method=log_method, url=url, data=data, headers=headers, timeout=self.timeout)
            except requests.ReadTimeout:
                if retry and retry_limit:
                    retry_limit -= 1
                    self.log.warning("ReadTimeout: %s. Retry..." % url)
                    continue
                raise
            break

        resp = response.content
        if not isinstance(resp, str):
            resp = resp.decode()

        self.log.debug("Response [%s]: %s", response.status_code, resp[:self.logger_limit] if resp else None)
        if response.status_code >= 400:
            try:
                result = json.loads(resp) if len(resp) else {}
                if 'error' in result and result['error']:
                    raise TaurusNetworkError("API call error %s: %s" % (url, result['error']))
                else:
                    raise TaurusNetworkError("API call error %s on %s: %s" % (response.status_code, url, result))
            except ValueError:
                raise TaurusNetworkError("API call error %s: %s %s" % (url, response.status_code, response.reason))

        if raw_result:
            return resp

        try:
            result = json.loads(resp) if len(resp) else {}
        except ValueError as exc:
            self.log.debug('Response: %s', resp)
            raise TaurusNetworkError("Non-JSON response from API: %s" % exc)

        if 'error' in result and result['error']:
            raise TaurusNetworkError("API call error %s: %s" % (url, result['error']))

        return result
Esempio n. 3
0
    def prepare(self):
        reporting = self.engine.config.get(Reporter.REP)

        CloudProvisioning.merge_with_blazemeter_config(self)
        CloudProvisioning.configure_client(self)
        self._workspaces = self.user.accounts().workspaces()
        if not self._workspaces:
            raise TaurusNetworkError("Your account has no active workspaces, please contact BlazeMeter support")

        self.__dump_locations_if_needed()

        super(CloudProvisioning, self).prepare()
        self.browser_open = self.settings.get("browser-open", self.browser_open)
        self.detach = self.settings.get("detach", self.detach)
        self.check_interval = dehumanize_time(self.settings.get("check-interval", self.check_interval))
        self.public_report = self.settings.get("public-report", self.public_report)
        is_execution_empty = not self.engine.config.get("execution")
        self.launch_existing_test = self.settings.get("launch-existing-test", is_execution_empty, force_set=True)

        if not self.launch_existing_test:
            self._filter_reporting()

        finder = ProjectFinder(self.parameters, self.settings, self.user, self._workspaces, self.log)
        finder.default_test_name = "Taurus Cloud Test"

        test_type = self.settings.get("test-type")  # user test type. should we mention it in doc?
        if not test_type:
            func_mode = self.engine.is_functional_mode()
            gui_mode = func_mode and (
                    (len(self.executors) == 1) and
                    isinstance(self.executors[0], SeleniumExecutor))

            if func_mode:
                if gui_mode:
                    test_type = FUNC_GUI_TEST_TYPE
                else:
                    test_type = FUNC_API_TEST_TYPE
            else:
                test_type = TAURUS_TEST_TYPE

        finder.test_type = test_type

        self.router = finder.get_test_router()

        if not self.launch_existing_test:
            self.router.prepare_locations(self.executors, self.engine.config)

            res_files = self.get_rfiles()
            files_for_cloud = self._fix_filenames(res_files)

            config_for_cloud = self.prepare_cloud_config()
            config_for_cloud.dump(self.engine.create_artifact("cloud", ""))
            del_files = self.settings.get("delete-test-files", True)
            self.router.resolve_test(config_for_cloud, files_for_cloud, del_files)

        self.router.sanitize_test()

        self.report_name = self.settings.get("report-name", self.report_name)
        if self.report_name == 'ask' and sys.stdin.isatty():
            self.report_name = input("Please enter report-name: ")

        self.widget = self.get_widget()

        if self.engine.is_functional_mode():
            self.results_reader = FunctionalBZAReader(self.log)
            self.engine.aggregator.add_underling(self.results_reader)
        else:
            self.results_reader = ResultsFromBZA()
            self.results_reader.log = self.log
            self.engine.aggregator.add_underling(self.results_reader)

        validate_passfail = any(reporter.get('module') == 'passfail' for reporter in reporting)

        if validate_passfail:
            if self.router._test.started_passfail_validation():
                timeout = 100
                for i in range(timeout):
                    if self.router._test.get_passfail_validation():
                        return
                    self.log.warning(f"Unsuccessful Passfail validation attempt [{i+1}]. Retrying...")
                    if not i % 10:
                        self.log.warning("Please keep in mind that validation can take time.")
                    sleep(1)
                self.log.error("Unable get Passfail validation!")
            else:
                self.log.error("Unable to validate Passfail configuration!")
Esempio n. 4
0
 def http_error_default(self, url, fp, errcode, errmsg, headers):
     fp.close()
     raise TaurusNetworkError("Unsuccessful download from %s: %s - %s" % (url, errcode, errmsg))
Esempio n. 5
0
    def prepare(self):
        """
        Read options for uploading, check that they're sane
        """
        super(BlazeMeterUploader, self).prepare()

        self.send_interval = dehumanize_time(
            self.settings.get("send-interval", self.send_interval))
        self.send_monitoring = self.settings.get("send-monitoring",
                                                 self.send_monitoring)
        monitoring_buffer_limit = self.settings.get("monitoring-buffer-limit",
                                                    500)
        self.monitoring_buffer = MonitoringBuffer(monitoring_buffer_limit,
                                                  self.log)
        self.browser_open = self.settings.get("browser-open",
                                              self.browser_open)
        self.public_report = self.settings.get("public-report",
                                               self.public_report)
        self.upload_artifacts = self.parameters.get("upload-artifacts",
                                                    self.upload_artifacts)
        self._dpoint_serializer.multi = self.settings.get(
            "report-times-multiplier", self._dpoint_serializer.multi)
        token = self.settings.get("token", "")
        if not token:
            self.log.warning(
                "No BlazeMeter API key provided, will upload anonymously")
        self._user.token = token

        # usual fields
        self._user.logger_limit = self.settings.get("request-logging-limit",
                                                    self._user.logger_limit)
        self._user.address = self.settings.get("address",
                                               self._user.address).rstrip("/")
        self._user.data_address = self.settings.get(
            "data-address", self._user.data_address).rstrip("/")
        self._user.timeout = dehumanize_time(
            self.settings.get("timeout", self._user.timeout))
        if isinstance(self._user.http_session, requests.Session):
            self.log.debug("Installing http client")
            self._user.http_session = self.engine.get_http_client()
            self._user.http_request = self._user.http_session.request

        # direct data feeding case
        sess_id = self.parameters.get("session-id")
        if sess_id:
            self._session = Session(self._user, {'id': sess_id})
            self._session['userId'] = self.parameters.get("user-id", None)
            self._session['testId'] = self.parameters.get("test-id", None)
            self._test = Test(self._user, {'id': self._session['testId']})
            exc = TaurusConfigError("Need signature for session")
            self._session.data_signature = self.parameters.get(
                "signature", exc)
            self._session.kpi_target = self.parameters.get(
                "kpi-target", self._session.kpi_target)
            self.send_data = self.parameters.get("send-data", self.send_data)
        else:
            try:
                self._user.ping()  # to check connectivity and auth
            except HTTPError:
                self.log.error(
                    "Cannot reach online results storage, maybe the address/token is wrong"
                )
                raise

            if token:
                wsp = self._user.accounts().workspaces()
                if not wsp:
                    raise TaurusNetworkError(
                        "Your account has no active workspaces, please contact BlazeMeter support"
                    )
                finder = ProjectFinder(self.parameters, self.settings,
                                       self._user, wsp, self.log)
                self._test = finder.resolve_external_test()
            else:
                self._test = Test(self._user, {'id': None})

        self.report_name = self.parameters.get(
            "report-name", self.settings.get("report-name", self.report_name))
        if self.report_name == 'ask' and sys.stdin.isatty():
            self.report_name = input("Please enter report-name: ")

        if isinstance(self.engine.aggregator, ResultsProvider):
            self.engine.aggregator.add_listener(self)

        for service in self.engine.services:
            if isinstance(service, Monitoring):
                service.add_listener(self)
Esempio n. 6
0
    def prepare(self):
        CloudProvisioning.merge_with_blazemeter_config(self)
        CloudProvisioning.configure_client(self)
        self._workspaces = self.user.accounts().workspaces()
        if not self._workspaces:
            raise TaurusNetworkError(
                "Your account has no active workspaces, please contact BlazeMeter support"
            )

        self.__dump_locations_if_needed()

        super(CloudProvisioning, self).prepare()
        self.browser_open = self.settings.get("browser-open",
                                              self.browser_open)
        self.detach = self.settings.get("detach", self.detach)
        self.check_interval = dehumanize_time(
            self.settings.get("check-interval", self.check_interval))
        self.public_report = self.settings.get("public-report",
                                               self.public_report)
        is_execution_empty = not self.engine.config.get("execution")
        self.launch_existing_test = self.settings.get("launch-existing-test",
                                                      is_execution_empty,
                                                      force_set=True)

        finder = ProjectFinder(self.parameters, self.settings, self.user,
                               self._workspaces, self.log)
        finder.default_test_name = "Taurus Cloud Test"

        test_type = self.settings.get(
            "test-type")  # user test type. should we mention it in doc?
        if not test_type:
            func_mode = self.engine.is_functional_mode()
            gui_mode = func_mode and (
                (len(self.executors) == 1)
                and isinstance(self.executors[0], SeleniumExecutor))

            if func_mode:
                if gui_mode:
                    test_type = FUNC_GUI_TEST_TYPE
                else:
                    test_type = FUNC_API_TEST_TYPE
            else:
                test_type = TAURUS_TEST_TYPE

        finder.test_type = test_type

        self.router = finder.get_test_router()

        if not self.launch_existing_test:
            self.router.prepare_locations(self.executors, self.engine.config)

            res_files = self.get_rfiles()
            files_for_cloud = self._fix_filenames(res_files)
            self._filter_reporting("blazemeter")  # must not be sent to cloud
            config_for_cloud = self.prepare_cloud_config()
            config_for_cloud.dump(self.engine.create_artifact("cloud", ""))
            del_files = self.settings.get("delete-test-files", True)
            self.router.resolve_test(config_for_cloud, files_for_cloud,
                                     del_files)

        self.router.sanitize_test()
        self._validate_passfail()

        self.report_name = self.settings.get("report-name", self.report_name)
        if self.report_name == 'ask' and sys.stdin.isatty():
            self.report_name = input("Please enter report-name: ")

        self.widget = self.get_widget()
        self._filter_reporting(
            "passfail")  # must be sent to claud for conversion

        if self.engine.is_functional_mode():
            self.results_reader = FunctionalBZAReader(self.log)
            self.engine.aggregator.add_underling(self.results_reader)
        else:
            self.results_reader = ResultsFromBZA()
            self.results_reader.log = self.log
            self.engine.aggregator.add_underling(self.results_reader)