def __init__(self, *args, requests_response=None): if not isinstance(requests_response, requests.Response): raise TypeError( "Refusing to work until given a requests.Response object") self.http_response = requests_response all_args = args + (self.errors_to_string(), ) dependency(super)().__init__(*all_args)
def run_all(path): """ Run all tests beneath the given path """ cfg = config_for_module(__name__) throttle = cfg.delay_between_checks_for_parallel_suite_completion limit = cfg.max_parallel_suites timeout = _float_or_none(name="$RUN_ALL_TIMEOUT", value=cfg.run_all_timeout) if timeout is None: expiry = None else: expiry = dependency(datetime).now() + timedelta(seconds=_float_or_none( name="$RUN_ALL_TIMEOUT", value=cfg.run_all_timeout)) pool = Pool(limit) queue = list(discover(path)) while queue: if expiry and dependency(datetime).now() > expiry: break while pool.has_capacity() and queue: pool.add(queue.pop(0)) log.debug("Waiting in queue: %d" % len(queue)) sleep(throttle) pool.wait_for_jobs(expiry=expiry) return pool.failure_count
def launch_chrome(): config = config_for_module(__name__) opts = dependency(webdriver.chrome.options.Options)() opts.add_argument("start-fullscreen") agent_string = config.chrome_user_agent if agent_string: opts.add_argument("user-agent=%s" % agent_string) return dependency(webdriver).Chrome(chrome_options=opts)
def __init__(self): self._log = dependency(logger_for_module)(__name__) config = config_for_module(__name__) self.element_find_timeout = config.browser_element_find_timeout self.page_load_timeout = config.browser_page_load_timeout self._driver = dependency(launch_browser)() self._failure_detected = False subscribe_event_handlers(self)
def discover(top_dir): walk = dependency(os).walk scripts = [] for path, _, files in walk(top_dir): scripts += [ dependency(os).path.join(path, fn) for fn in files if not fn.startswith("_") and fn.endswith(".py") ] return scripts
def contents_of_file(filename): if UNIT_TEST_MODE: exists = dependency(os.path).exists fopen = dependency(open) else: exists = os.path.exists fopen = open if exists(filename): with fopen(filename, "r") as f: return f.read() return ""
def execute_test_table(*, func, table, suite_name=None, randomize_order=False): if suite_name is None: suite_name = func.__name__ headers = _extract_headers(table) _validate_headers(func=func, headers=headers) EventBroker.publish(event=TestEvent.suite_started, suite_name=suite_name) rows = _parse_table(func=func, table=table) if randomize_order: dependency(shuffle)(rows) for row in rows: _execute_test(func=func, row=row, suite_name=suite_name) EventBroker.publish(event=TestEvent.suite_ended, suite_name=suite_name)
def logger_for_module(module_name): """ Return a Logger for the module with the given name. Its level can be controlled by an environment variable: <module_name.upper()>_LOG_LEVEL=<DEBUG | INFO | WARNING | ERROR> module_name -- (str) Name of the module """ environ = dependency(os).environ handler = dependency(logging).StreamHandler() handler.setFormatter(Formatter(fmt=MESSAGE_FORMAT)) logger = Logger(name=module_name) logger.addHandler(handler) logger.setLevel(_level_for_module(module_name, environ=environ)) return logger
def test_direct_with_context_manager(self): real_spam = 'real spam' fake_spam = 'injected spam' with dependency_context() as outer: with dependency_context(parent=outer) as inner: inner.inject(real_spam, fake_spam) expect(dependency(real_spam)).to(equal(fake_spam))
def test_parent_unaffected_by_child_injection(self): real_spam = 'real spam' fake_spam = 'injected spam' with dependency_context() as outer: with dependency_context(parent=outer) as inner: inner.inject(real_spam, fake_spam) expect(dependency(real_spam)).to(equal(real_spam))
def test_create_file_accepts_strings(self): planted = "some text" filename = "yad.dah" with dependency_context(supply_fs=True) as context: context.create_file(filename, text=planted) with dependency(open)(filename, "r") as f: expect(f.read()).to(equal(planted))
def ci_workspace_path(): vars = dependency(os).environ config = config_for_module(__name__) key = config.ci_workspace_env_var if key in vars.keys(): return vars[key] return None
def import_class(full_name): mat = MODULE_AND_CLASS_PATTERN.match(full_name) if not mat: raise InvalidConfiguration('Failed to parse line in %s: "%s"' % (custom_reporter_filename(), full_name)) module_name, class_name = mat.groups() module = dependency(importlib).import_module(module_name) return getattr(module, class_name)
def test_survives_mutation(self): with dependency_context() as context: dep = ["spam", "eggs", "sausage"] thing = object() context.inject(dep, thing) dep.append("spam") expect(dependency(dep)).to(be(thing))
def test_inherited_with_context_manager(self): real_spam = 'real spam' fake_spam = 'injected spam' with dependency_context() as outer: outer.inject(real_spam, fake_spam) with dependency_context(parent=outer): expect(dependency(real_spam)).to(equal(fake_spam))
def test_survives_mutation(self): with dependency_context() as context: dep = ['spam', 'eggs', 'sausage'] thing = object() context.inject(dep, thing) dep.append('spam') expect(dependency(dep)).to(be(thing))
def _request(self, method, url, headers={}, data=None, redirect_depth=0, **kwargs): self._check_request_kwargs(kwargs) headers = dict(self._persistent_headers, **headers) self._transcript.add_request(method, url, data=data, headers=headers, **kwargs) self._logger.debug("%s %s" % (method.upper(), url)) self._logger.debug(f"Request headers: {headers}") if self._session is None: func = self._send_plain_request else: func = self._send_session_request request_uuid = uuid4() EventBroker.publish( event=TestEvent.http_request_sent, http_method=method.upper(), request_headers=headers, request_url=url, request_data=data, request_uuid=request_uuid, ) resp = func(method, url, headers=headers, data=data, verify=self._verify_certs, **kwargs) EventBroker.publish(event=TestEvent.http_response_received, request_uuid=request_uuid, response=resp) self._logger.debug("HTTP %d\n%s" % (resp.status_code, resp.text)) self._logger.debug(f"Response headers: {resp.headers}") self._transcript.add_response(resp) if resp.status_code in HANDLE_THESE_REDIRECT_STATUS_CODES: if redirect_depth >= STOP_FOLLOWING_REDIRECTS_AFTER_THIS_MANY - 1: raise TooManyRedirects("Detected likely infinite HTTP redirection") return self._request( method, construct_redirect_url(request_url=url, response_location_header=extract_location_header(resp)), data=data, headers=headers, redirect_depth=redirect_depth + 1, **kwargs, ) try: dependency(inspect_response)(resp) except Exception as e: for exception_class, callback in self._exception_callbacks.items(): if isinstance(e, exception_class): response = callback(exception=e) if response is not None: return response raise return resp
def wait_for_jobs(self, *, expiry): cfg = config_for_module(__name__) throttle = cfg.delay_between_checks_for_parallel_suite_completion while self._running: if expiry and dependency(datetime).now() > expiry: self._kill_jobs() raise TimeoutError("Tests ran longer than the configured limit") sleep(throttle) self._prune()
def test_stores_unzipped_binary_from_nexus(self): expected = b"spamspamspam243rwedf24r\x42spamandspam" self.create_fake_archive(content=expected) BrowserStackTunnel() full_path = self.join_path(self.local_binary_path, self.local_binary_filename) fopen = dependency(open) with fopen(full_path, "rb") as f: expect(f.read()).to(equal(expected))
def test_precedence(self): spam = 'SPAM' inner_fake = 'inner fake' outer_fake = 'outer fake' with dependency_context() as outer: outer.inject(spam, outer_fake) with dependency_context(parent=outer) as inner: inner.inject(spam, inner_fake) expect(dependency(spam)).to(equal(inner_fake))
def publish_dom_dump(self, artifact_group=None, suite_name=None, test_name=None, **kwargs): EventBroker.publish( artifact_group=artifact_group, event=TestEvent.artifact_created, artifact=dependency(dump_dom)(self), artifact_mime_type="text/html", artifact_type="dom_dump", suite_name=suite_name, test_name=test_name, )
def infer_package_name(): """ Use the path to the test script to infer a "package" name for the Junit report. """ script = dependency(path_to_entry_script)() if not script: return "" script_path, _ = os.path.split(script) workspace_mask = ci_workspace_path() if workspace_mask: script_path = script_path.replace(workspace_mask, "") else: cwd_mask = dependency(os.getcwd)() script_path = script_path.replace(cwd_mask, "") name = script_path.replace("/", ".") + "." if name.startswith("."): name = name[1:] return name
def test_inherits_origin_context(self): with dependency_context() as context: key = "dennis" value = 37 context.inject(key, "something else") ctl = context.create_time_controller(target=lambda: dependency(key)) context.inject(key, value) ctl.start() ctl.join() expect(ctl.value_returned).to(equal(value))
def test_suite(name): broker = dependency(EventBroker) configure_logging() broker.publish(event=TestEvent.suite_started, suite_name=name) try: yield except Exception as e: broker.publish(event=TestEvent.suite_erred, exception=e, suite_name=name) broker.publish(event=TestEvent.suite_ended, suite_name=name)
def extract_status(filename): with dependency(open)(filename, "r") as f: xml = f.read().strip() root = ElementTree.fromstring(xml) suite = locate_suite(root) if suite is not None: keys = suite.attrib.keys() if "failures" in keys and int(suite.attrib["failures"]): return FAIL if "errors" in keys and int(suite.attrib["errors"]): return ERROR return PASS
def test_recursion(self): spam = 'SPAM' fake_spam = 'Advanced SPAM Substitute' one = open_dependency_context() one.inject(spam, fake_spam) two = open_dependency_context(parent=one) three = open_dependency_context(parent=two) try: expect(dependency(spam)).to(equal(fake_spam)) finally: three.close() two.close() one.close()
def test_reflects_changes_to_parent(self): real_spam = 'real spam' fake_1 = 'first injection' fake_2 = 'second injection' try: parent = open_dependency_context() parent.inject(real_spam, fake_1) child = open_dependency_context(parent=parent) parent.inject(real_spam, fake_2) expect(dependency(real_spam)).to(equal(fake_2)) finally: child.close() parent.close()
def launch_browserstack_browser(): config = config_for_module(__name__) for name in ("browserstack_access_key", "browserstack_username"): if not config[name]: raise InvalidConfiguration('"%s" is not in the environment or a configuration file' % name) if require_browserstack_tunnel(): tunnel = dependency(BrowserStackTunnel)() else: tunnel = None caps = { "browser": config.use_browser, "browserstack.debug": config.browserstack_set_debug, "browserstack.local": config.browserstack_set_local, "resolution": config.browserstack_screen_resolution, "os": config.browserstack_os, "os_version": config.browserstack_os_version, } browser_version = config.use_browser_version if browser_version: caps["browser_version"] = browser_version if tunnel is not None: caps["browserstack.localIdentifier"] = tunnel.local_identifier start = now() expiry = start + timedelta(seconds=config.browserstack_tunnel_timeout) while True: try: remote = dependency(webdriver).Remote( command_executor=insert_bs_credentials(url=config.browserstack_url), desired_capabilities=caps ) break except WebDriverException as e: msg = str(e).lower() if "all parallel tests are currently in use" in msg: raise AllBrowsersBusy(msg) if "browserstack.local" in msg and now() <= expiry: continue raise remote.fullscreen_window() return remote
def launch_selenium_grid_browser(): config = config_for_module(__name__) hub_url = config.selenium_grid_hub_url if not hub_url: raise InvalidConfiguration( "Expected $SELENIUM_GRID_HUB_URL to be configured.") caps = {"browserName": config.use_browser} if config.use_browser: caps["browserName"] = config.use_browser browser_version = config.use_browser_version if browser_version: caps["version"] = browser_version return dependency(webdriver).Remote(command_executor=hub_url, desired_capabilities=caps)
def test_injects_open(self): fname = "reginald" planted = b"some rubbish from test_fake_filesystem" with dependency_context(supply_fs=True) as context: # Write f = context.os.open(fname, flags=os.O_CREAT | os.O_WRONLY) context.os.write(f, planted) context.os.close(f) # Read try: with dependency(open)(fname, "rb") as f: expect(f.read()).to(equal(planted)) except FileNotFoundError: assert False, '"open" not find fake file'