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
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
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!")
def http_error_default(self, url, fp, errcode, errmsg, headers): fp.close() raise TaurusNetworkError("Unsuccessful download from %s: %s - %s" % (url, errcode, errmsg))
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)
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)