def set_up(self): """Set up your applications and the test environment.""" self.path.state = self.path.gen.joinpath("state") if self.path.state.exists(): self.path.state.rmtree(ignore_errors=True) self.path.state.mkdir() self.path.profile = self.path.gen.joinpath("profile") if not self.path.profile.exists(): self.path.profile.mkdir() self.python = project_build( self.path, self.given['python version'], self.given['ruamel version'], ).bin.python self.example_py_code = ExamplePythonCode(self.python, self.path.state)\ .with_code(self.given.get('code', ''))\ .with_setup_code(self.given.get('setup', ''))\ .with_terminal_size(160, 100)\ .with_long_strings( yaml_snippet_1=self.given.get('yaml_snippet_1'), yaml_snippet=self.given.get('yaml_snippet'), yaml_snippet_2=self.given.get('yaml_snippet_2'), modified_yaml_snippet=self.given.get('modified_yaml_snippet'), )
def set_up(self): """Set up your applications and the test environment.""" self.path.state = self.path.gen.joinpath("state") if self.path.state.exists(): self.path.state.rmtree(ignore_errors=True) self.path.state.mkdir() if self.path.gen.joinpath("q").exists(): self.path.gen.joinpath("q").remove() for filename, text in self.given.get("files", {}).items(): filepath = self.path.state.joinpath(filename) if not filepath.dirname().exists(): filepath.dirname().makedirs() filepath.write_text(text) for filename, linkto in self.given.get("symlinks", {}).items(): filepath = self.path.state.joinpath(filename) linktopath = self.path.state.joinpath(linkto) linktopath.symlink(filepath) for filename, permission in self.given.get("permissions", {}).items(): filepath = self.path.state.joinpath(filename) filepath.chmod(int(permission, 8)) pylibrary = hitchbuildpy.PyLibrary( name="py3.5.0", base_python=hitchbuildpy.PyenvBuild("3.5.0").with_build_path( self.path.share), module_name="pathquery", library_src=self.path.project, ).with_build_path(self.path.gen) pylibrary.ensure_built() self.python = pylibrary.bin.python self.example_py_code = ExamplePythonCode(self.python, self.path.state)\ .with_code(self.given.get('code', ''))\ .with_setup_code(self.given.get('setup', ''))\ .with_terminal_size(160, 100)\ .with_env(TMPDIR=self.path.gen)\ .with_long_strings( yaml_snippet_1=self.given.get('yaml_snippet_1'), yaml_snippet=self.given.get('yaml_snippet'), yaml_snippet_2=self.given.get('yaml_snippet_2'), modified_yaml_snippet=self.given.get('modified_yaml_snippet'), )
def set_up(self): """Set up your applications and the test environment.""" self.doc = hitchdoc.Recorder( hitchdoc.HitchStory(self), self.path.gen.joinpath('storydb.sqlite'), ) self.path.state = self.path.gen.joinpath("state") if self.path.state.exists(): self.path.state.rmtree(ignore_errors=True) self.path.state.mkdir() self.path.profile = self.path.gen.joinpath("profile") if not self.path.profile.exists(): self.path.profile.mkdir() self.python_package = hitchpython.PythonPackage( self.given['python version'] ) self.python_package.build() self.pip = self.python_package.cmd.pip self.python = self.python_package.cmd.python # Install debugging packages with hitchtest.monitor([self.path.key.joinpath("debugrequirements.txt")]) as changed: if changed: run(self.pip("install", "-r", "debugrequirements.txt").in_dir(self.path.key)) # Uninstall and reinstall with hitchtest.monitor( pathq(self.path.project.joinpath("strictyaml")).ext("py") ) as changed: if changed: run(self.pip("uninstall", "strictyaml", "-y").ignore_errors()) run(self.pip("install", ".").in_dir(self.path.project)) run(self.pip("install", "ruamel.yaml=={0}".format( self.given["ruamel version"] ))) self.example_py_code = ExamplePythonCode(self.python, self.path.state)\ .with_code(self.given.get('code', ''))\ .with_setup_code(self.given.get('setup', ''))\ .with_long_strings( yaml_snippet_1=self.given.get('yaml_snippet_1'), yaml_snippet=self.given.get('yaml_snippet'), yaml_snippet_2=self.given.get('yaml_snippet_2'), modified_yaml_snippet=self.given.get('modified_yaml_snippet'), )
def set_up(self): self.path.state = self.path.gen.joinpath("state") if self.path.state.exists(): self.path.state.rmtree(ignore_errors=True) self.path.state.mkdir() for filename, text in self.given.get("files", {}).items(): filepath = self.path.state.joinpath(filename) if not filepath.dirname().exists(): filepath.dirname().mkdir() filepath.write_text(str(text)) filepath.chmod("u+x") for filename, text in self.given.get("variables", {}).items(): filepath = self.path.state.joinpath(filename) if not filepath.dirname().exists(): filepath.dirname().mkdir() filepath.write_text(str(text)) self.path.key.joinpath("code_that_does_things.py").copy( self.path.state) self.python_package = hitchpython.PythonPackage( self.given.get('python_version', self.given['python version'])) self.python_package.build() self.pip = self.python_package.cmd.pip self.python = self.python_package.cmd.python with hitchtest.monitor( [self.path.key.joinpath("debugrequirements.txt")]) as changed: if changed: self.pip("install", "-r", "debugrequirements.txt").in_dir(self.path.key).run() with hitchtest.monitor( pathq(self.path.project.joinpath("icommandlib")).ext( "py")) as changed: if changed: self.pip("uninstall", "icommandlib", "-y").ignore_errors().run() self.pip("install", ".").in_dir(self.path.project).run() self.example_py_code = ExamplePythonCode( self.python, self.path.state, ).with_setup_code(self.given.get('setup', '')).with_code( self.given.get('code', '')).with_timeout(4.0)
def set_up(self): """Set up your applications and the test environment.""" self.path.state = self.path.gen.joinpath("state") if self.path.state.exists(): self.path.state.rmtree(ignore_errors=True) self.path.state.mkdir() for script in self.given.get("scripts", []): script_path = self.path.state.joinpath(script) if not script_path.dirname().exists(): script_path.dirname().makedirs() script_path.write_text(self.given["scripts"][script]) script_path.chmod("u+x") for filename, contents in self.given.get("files", {}).items(): self.path.state.joinpath(filename).write_text(contents) self.python = hitchpylibrarytoolkit.project_build( "commandlib", self.path, self.given["python version"] ).bin.python self.example_py_code = ( ExamplePythonCode(self.python, self.path.state) .with_code(self.given.get("code", "")) .with_setup_code(self.given.get("setup", "")) )
def set_up(self): """Set up your applications and the test environment.""" self.path.state = self.path.gen.joinpath("state") if self.path.state.exists(): self.path.state.rmtree(ignore_errors=True) self.path.state.mkdir() self.path.profile = self.path.gen.joinpath("profile") dirtemplate.DirTemplate( "webapp", self.path.key / "htmltemplate", self.path.state ).with_vars(javascript=self.given.get("javascript", "")).with_files( base_html={ filename: { "content": content } for filename, content in self.given.get("website", {}).items() }).ensure_built() self.path.state.joinpath("selectors.yml").write_text( self.given["selectors.yml"]) self.server = (python("-m", "http.server").in_dir(self.path.state / "webapp").pexpect()) self.server.expect("Serving HTTP on 0.0.0.0") if not self.path.profile.exists(): self.path.profile.mkdir() self.python = project_build(self.path, self.given["python version"], self.given["selenium version"]).bin.python self.example_py_code = (ExamplePythonCode( self.python, self.path.state).with_setup_code(self.given.get( "setup", "")).with_terminal_size(160, 100).with_long_strings())
def set_up(self): """Set up your applications and the test environment.""" self.path.profile = self.path.gen.joinpath("profile") if not self.path.profile.exists(): self.path.profile.mkdir() if not self._python_path: self.python = hitchpylibrarytoolkit.project_build( "strictyaml", self.path, self.given["python version"], { "ruamel.yaml": self.given["ruamel version"] }, ).bin.python else: self.python = Path(self._python_path) assert self.python.exists() self.example_py_code = (ExamplePythonCode( self.python, self.path.gen).with_code(self.given.get( "code", "")).with_setup_code(self.given.get( "setup", "")).with_terminal_size(160, 100).with_strings( yaml_snippet_1=self.given.get("yaml_snippet_1"), yaml_snippet=self.given.get("yaml_snippet"), yaml_snippet_2=self.given.get("yaml_snippet_2"), modified_yaml_snippet=self.given.get( "modified_yaml_snippet"), ))
def run(self, code, will_output=None, raises=None): self.example_py_code = ExamplePythonCode(self.python, self.path.state)\ .with_terminal_size(160, 100)\ .with_setup_code(self.given['setup'])\ .in_dir(self.path.state) to_run = self.example_py_code.with_code(code) if self.settings.get("cprofile"): to_run = to_run.with_cprofile( self.path.profile.joinpath("{0}.dat".format(self.story.slug)) ) result = to_run.expect_exceptions().run() if raises is not None else to_run.run() actual_output = result.output if will_output is not None: try: Templex(will_output).assert_match(actual_output) except AssertionError: if self.settings.get("overwrite artefacts"): self.current_step.update(**{"will output": actual_output}) else: raise if raises is not None: exception_type = raises.get('type') message = raises.get('message') try: result.exception_was_raised(exception_type) exception_message = self._process_exception(result.exception.message) Templex(message).assert_match(exception_message) except AssertionError: if self.settings.get("overwrite artefacts"): new_raises = raises.copy() new_raises['message'] = exception_message self.current_step.update(raises=new_raises) else: raise
def set_up(self): virtualenv = (hitchbuildpy.VirtualenvBuild( self.path.gen / "venv", hitchbuildpy.PyenvBuild(self.path.share / "python3.7.0", "3.7.0"), ).with_requirementstxt("requirements.txt")) virtualenv.ensure_built() self.example_py_code = (ExamplePythonCode( virtualenv.bin.python, self.path.gen).with_setup_code( self.given.get("setup", "")).with_terminal_size( 160, 100).with_strings(state=self.given["state"]).with_modules( "game.py", "state.py"))
def set_up(self): """Set up your applications and the test environment.""" self.path.cachestate = self.path.gen.joinpath("cachestate") self.path.state = self.path.gen.joinpath("state") self.path.working_dir = self.path.gen.joinpath("working") self.path.build_path = self.path.gen.joinpath("build_path") self.path.localsync = self.path.gen.joinpath("local_sync") if self.path.state.exists(): self.path.state.rmtree(ignore_errors=True) self.path.state.mkdir() if self.path.localsync.exists(): self.path.localsync.rmtree(ignore_errors=True) self.path.localsync.mkdir() if self.path.build_path.exists(): self.path.build_path.rmtree(ignore_errors=True) self.path.build_path.mkdir() self.python = hitchpylibrarytoolkit.project_build( "hitchbuildvagrant", self.path, self.given.get("python_version", "3.7.0")).bin.python if not self.path.cachestate.exists(): self.path.cachestate.mkdir() for filename, contents in self.given.get("files", {}).items(): filepath = self.path.state.joinpath(filename) if not filepath.dirname().exists(): filepath.dirname().makedirs() filepath.write_text(contents) if self.path.working_dir.exists(): self.path.working_dir.rmtree(ignore_errors=True) self.path.working_dir.mkdir() self.example_py_code = (ExamplePythonCode( self.python, self.path.state).with_setup_code( self.given.get("setup", "").replace( "/path/to/share", self.path.cachestate)).with_terminal_size( 160, 100).with_long_strings( share=str(self.path.cachestate), build_path=str(self.path.build_path), issue=str(self.given.get("issue")), boxname=str(self.given.get("boxname")), vmname=str(self.given.get("vmname")), local_sync_path=str(self.path.localsync), ))
def set_up(self): """Set up your applications and the test environment.""" self.path.cachestate = self.path.gen.joinpath("cachestate") self.path.state = self.path.gen.joinpath("state") self.path.working_dir = self.path.gen.joinpath("working") self.path.build_path = self.path.gen.joinpath("build_path") if self.path.state.exists(): self.path.state.rmtree(ignore_errors=True) self.path.state.mkdir() if self.path.build_path.exists(): self.path.build_path.rmtree(ignore_errors=True) self.path.build_path.mkdir() self.python = project_build(self.path, self.given["python version"]).bin.python if not self.path.cachestate.exists(): self.path.cachestate.mkdir() for filename, contents in self.given.get("files", {}).items(): filepath = self.path.state.joinpath(filename) if not filepath.dirname().exists(): filepath.dirname().makedirs() filepath.write_text(contents) if self.path.working_dir.exists(): self.path.working_dir.rmtree(ignore_errors=True) self.path.working_dir.mkdir() self.example_py_code = (ExamplePythonCode( self.python, self.path.state).with_setup_code(self.given.get( "setup", "")).with_terminal_size(160, 100).with_strings( postgres_version=self.given.get("postgres_version"), share=str(self.path.cachestate), build_path=str(self.path.build_path), ))
class Engine(BaseEngine): """Python engine for running tests.""" given_definition = GivenDefinition( files=GivenProperty(MapPattern(Str(), Str())), python_version=GivenProperty(Str()), setup=GivenProperty(Str()), ) info_definition = InfoDefinition( docs=InfoProperty(schema=Str()), ) def __init__(self, paths, settings): self.path = paths self.settings = settings self._build = hitchpylibrarytoolkit.PyLibraryBuild( "hitchqs", self.path, ) def set_up(self): """Set up the environment ready to run the stories.""" self._build.ensure_built() self.path.state = self.path.gen.joinpath("state") if self.path.state.exists(): self.path.state.rmtree() self.path.state.mkdir() for filename, content in self.given['files'].items(): filepath = self.path.state.joinpath(filename) if not filepath.dirname().exists(): filepath.dirname().makedirs() filepath.write_text(content) self.python = self._build.bin.python def _process_exception(self, string): return string.replace(self.path.state, "/path/to") @no_stacktrace_for(AssertionError) @no_stacktrace_for(HitchRunPyException) @validate( code=Str(), will_output=Str(), raises=Map({ Optional("type"): Str(), Optional("message"): Str(), }) ) def run(self, code, will_output=None, raises=None): self.example_py_code = ExamplePythonCode(self.python, self.path.state)\ .with_terminal_size(160, 100)\ .with_setup_code(self.given['setup'])\ .in_dir(self.path.state) to_run = self.example_py_code.with_code(code) if self.settings.get("cprofile"): to_run = to_run.with_cprofile( self.path.profile.joinpath("{0}.dat".format(self.story.slug)) ) result = to_run.expect_exceptions().run() if raises is not None else to_run.run() actual_output = result.output if will_output is not None: try: Templex(will_output).assert_match(actual_output) except AssertionError: if self.settings.get("overwrite artefacts"): self.current_step.update(**{"will output": actual_output}) else: raise if raises is not None: exception_type = raises.get('type') message = raises.get('message') try: result.exception_was_raised(exception_type) exception_message = self._process_exception(result.exception.message) Templex(message).assert_match(exception_message) except AssertionError: if self.settings.get("overwrite artefacts"): new_raises = raises.copy() new_raises['message'] = exception_message self.current_step.update(raises=new_raises) else: raise @no_stacktrace_for(AssertionError) @validate(files=MapPattern(Str(), Str())) def build_output_is(self, files): for filename, content in files.items(): filepath = self.path.state.joinpath(filename) assert filepath.exists(), "{0} does not exist".format(filename) if content != "": try: Templex(content).assert_match(filepath.text()) except AssertionError as error: raise AssertionError("{0} is nonmatching:\n\n{1}".format(filename, error)) actual_files = [ path.replace(self.path.state + "/", "") for path in pathquery(self.path.state.joinpath("example")).is_not_dir() ] assert len(actual_files) == len(files.keys()), \ "Should be:\n\n{0}\n\nAre actually:\n\n{1}\n".format( '\n'.join(files.keys()), '\n'.join(actual_files), ) def on_success(self): self.new_story.save()
class Engine(BaseEngine): """Python engine for running tests.""" schema = StorySchema( given={ Optional("files"): MapPattern(Str(), Str()), Optional("symlinks"): MapPattern(Str(), Str()), Optional("permissions"): MapPattern(Str(), Str()), Optional("setup"): Str(), Optional("python version"): Str(), Optional("pathpy version"): Str() }, info={}, ) def __init__(self, keypath, settings): self.path = keypath self.settings = settings def set_up(self): """Set up your applications and the test environment.""" self.path.state = self.path.gen.joinpath("state") if self.path.state.exists(): self.path.state.rmtree(ignore_errors=True) self.path.state.mkdir() if self.path.gen.joinpath("q").exists(): self.path.gen.joinpath("q").remove() for filename, text in self.given.get("files", {}).items(): filepath = self.path.state.joinpath(filename) if not filepath.dirname().exists(): filepath.dirname().makedirs() filepath.write_text(text) for filename, linkto in self.given.get("symlinks", {}).items(): filepath = self.path.state.joinpath(filename) linktopath = self.path.state.joinpath(linkto) linktopath.symlink(filepath) for filename, permission in self.given.get("permissions", {}).items(): filepath = self.path.state.joinpath(filename) filepath.chmod(int(permission, 8)) pylibrary = hitchbuildpy.PyLibrary( name="py3.5.0", base_python=hitchbuildpy.PyenvBuild("3.5.0").with_build_path( self.path.share), module_name="pathquery", library_src=self.path.project, ).with_build_path(self.path.gen) pylibrary.ensure_built() self.python = pylibrary.bin.python self.example_py_code = ExamplePythonCode(self.python, self.path.state)\ .with_code(self.given.get('code', ''))\ .with_setup_code(self.given.get('setup', ''))\ .with_terminal_size(160, 100)\ .with_env(TMPDIR=self.path.gen)\ .with_long_strings( yaml_snippet_1=self.given.get('yaml_snippet_1'), yaml_snippet=self.given.get('yaml_snippet'), yaml_snippet_2=self.given.get('yaml_snippet_2'), modified_yaml_snippet=self.given.get('modified_yaml_snippet'), ) @expected_exception(NonMatching) @expected_exception(HitchRunPyException) @validate( code=Str(), will_output=Map({ "in python 2": Str(), "in python 3": Str() }) | Str(), raises=Map({ Optional("type"): Map({ "in python 2": Str(), "in python 3": Str() }) | Str(), Optional("message"): Map({ "in python 2": Str(), "in python 3": Str() }) | Str(), }), in_interpreter=Bool(), ) def run(self, code, will_output=None, yaml_output=True, raises=None, in_interpreter=False): if in_interpreter: code = '{0}\nprint(repr({1}))'.format( '\n'.join(code.strip().split('\n')[:-1]), code.strip().split('\n')[-1]) to_run = self.example_py_code.with_code(code) if self.settings.get("cprofile"): to_run = to_run.with_cprofile( self.path.profile.joinpath("{0}.dat".format(self.story.slug))) result = to_run.expect_exceptions().run( ) if raises is not None else to_run.run() if will_output is not None: actual_output = '\n'.join( [line.rstrip() for line in result.output.split("\n")]) try: Templex(will_output).assert_match(actual_output) except NonMatching: if self.settings.get("rewrite"): self.current_step.update(**{"will output": actual_output}) else: raise if raises is not None: differential = False # Difference between python 2 and python 3 output? exception_type = raises.get('type') message = raises.get('message') if exception_type is not None: if not isinstance(exception_type, str): differential = True exception_type = exception_type['in python 2']\ if self.given['python version'].startswith("2")\ else exception_type['in python 3'] if message is not None: if not isinstance(message, str): differential = True message = message['in python 2']\ if self.given['python version'].startswith("2")\ else message['in python 3'] try: result = self.example_py_code.expect_exceptions().run() result.exception_was_raised(exception_type, message) except ExpectedExceptionMessageWasDifferent as error: if self.settings.get("rewrite") and not differential: new_raises = raises.copy() new_raises['message'] = result.exception.message self.current_step.update(raises=new_raises) else: raise def output_contains(self, expected_contents, but_not=None): try: output_contents = self.path.state.joinpath( "output.txt").text().strip() except FileNotFoundError: raise AssertionError("Output not found") for expected_item in expected_contents: found = False for output_item in output_contents.split('\n'): if output_item.strip() == str( self.path.state.joinpath( expected_item).abspath()).strip(): found = True if not found: raise AssertionError( "Expected:\n{0}\n\nNot found in output:\n{1}".format( expected_item, output_contents, )) if but_not is not None: for unexpected_item in but_not: found = False for output_item in output_contents.split('\n'): if output_item.strip() == str( self.path.state.joinpath( unexpected_item).abspath()).strip(): found = True if found: raise RuntimeError( "Expected NOT to find:\n{0}\n\nBut found in:\n{1}". format( unexpected_item, output_contents, )) def pause(self, message="Pause"): import IPython IPython.embed() def on_success(self): if self.settings.get("rewrite"): self.new_story.save() if self.settings.get("cprofile"): self.python( self.path.key.joinpath("printstats.py"), self.path.profile.joinpath("{0}.dat".format( self.story.slug))).run() def tear_down(self): if self.path.gen.joinpath("q").exists(): print(self.path.gen.joinpath("q").text())
class Engine(BaseEngine): """Python engine for running tests.""" schema = StorySchema( given={ Optional("yaml_snippet"): Str(), Optional("yaml_snippet_1"): Str(), Optional("yaml_snippet_2"): Str(), Optional("modified_yaml_snippet"): Str(), Optional("python version"): Str(), Optional("ruamel version"): Str(), Optional("setup"): Str(), Optional("code"): Str(), }, info={ Optional("description"): Str(), Optional("importance"): Int(), Optional("docs"): Str(), }, ) def __init__(self, keypath, settings): self.path = keypath self.settings = settings def set_up(self): """Set up your applications and the test environment.""" self.doc = hitchdoc.Recorder( hitchdoc.HitchStory(self), self.path.gen.joinpath('storydb.sqlite'), ) self.path.state = self.path.gen.joinpath("state") if self.path.state.exists(): self.path.state.rmtree(ignore_errors=True) self.path.state.mkdir() self.path.profile = self.path.gen.joinpath("profile") if not self.path.profile.exists(): self.path.profile.mkdir() self.python_package = hitchpython.PythonPackage( self.given['python version'] ) self.python_package.build() self.pip = self.python_package.cmd.pip self.python = self.python_package.cmd.python # Install debugging packages with hitchtest.monitor([self.path.key.joinpath("debugrequirements.txt")]) as changed: if changed: run(self.pip("install", "-r", "debugrequirements.txt").in_dir(self.path.key)) # Uninstall and reinstall with hitchtest.monitor( pathq(self.path.project.joinpath("strictyaml")).ext("py") ) as changed: if changed: run(self.pip("uninstall", "strictyaml", "-y").ignore_errors()) run(self.pip("install", ".").in_dir(self.path.project)) run(self.pip("install", "ruamel.yaml=={0}".format( self.given["ruamel version"] ))) self.example_py_code = ExamplePythonCode(self.python, self.path.state)\ .with_code(self.given.get('code', ''))\ .with_setup_code(self.given.get('setup', ''))\ .with_long_strings( yaml_snippet_1=self.given.get('yaml_snippet_1'), yaml_snippet=self.given.get('yaml_snippet'), yaml_snippet_2=self.given.get('yaml_snippet_2'), modified_yaml_snippet=self.given.get('modified_yaml_snippet'), ) @expected_exception(HitchRunPyException) @validate( exception_type=Map({"in python 2": Str(), "in python 3": Str()}) | Str(), message=Map({"in python 2": Str(), "in python 3": Str()}) | Str(), ) def raises_exception(self, exception_type=None, message=None): """ Expect an exception. """ differential = False if exception_type is not None: if not isinstance(exception_type, str): differential = True exception_type = exception_type['in python 2']\ if self.given['python version'].startswith("2")\ else exception_type['in python 3'] if message is not None: if not isinstance(message, str): differential = True message = message['in python 2']\ if self.given['python version'].startswith("2")\ else message['in python 3'] try: result = self.example_py_code.expect_exceptions().run() result.exception_was_raised(exception_type, message) except ExpectedExceptionMessageWasDifferent as error: if self.settings.get("rewrite") and not differential: self.current_step.update(message=error.actual_message) else: raise @expected_exception(NonMatching) @expected_exception(HitchRunPyException) @validate( code=Str(), will_output=Str(), raises=Map({ Optional("type"): Map({"in python 2": Str(), "in python 3": Str()}) | Str(), Optional("message"): Map({"in python 2": Str(), "in python 3": Str()}) | Str(), }) ) def run(self, code, will_output=None, raises=None): to_run = self.example_py_code.with_code(code) if self.settings.get("cprofile"): to_run = to_run.with_cprofile( self.path.profile.joinpath("{0}.dat".format(self.story.slug)) ) result = to_run.expect_exceptions().run() if raises is not None else to_run.run() if will_output is not None: actual_output = '\n'.join([line.rstrip() for line in result.output.split("\n")]) try: Templex(will_output).assert_match(actual_output) except NonMatching: if self.settings.get("rewrite"): self.current_step.update(**{"will output": actual_output}) else: raise if raises is not None: differential = False # Difference between python 2 and python 3 output? exception_type = raises.get('type') message = raises.get('message') if exception_type is not None: if not isinstance(exception_type, str): differential = True exception_type = exception_type['in python 2']\ if self.given['python version'].startswith("2")\ else exception_type['in python 3'] if message is not None: if not isinstance(message, str): differential = True message = message['in python 2']\ if self.given['python version'].startswith("2")\ else message['in python 3'] try: result = self.example_py_code.expect_exceptions().run() result.exception_was_raised(exception_type, message) except ExpectedExceptionMessageWasDifferent as error: if self.settings.get("rewrite") and not differential: new_raises = raises.copy() new_raises['message'] = result.exception.message self.current_step.update(raises=new_raises) else: raise def pause(self, message="Pause"): import IPython IPython.embed() def on_success(self): if self.settings.get("rewrite"): self.new_story.save() if self.settings.get("cprofile"): self.python( self.path.key.joinpath("printstats.py"), self.path.profile.joinpath("{0}.dat".format(self.story.slug)) ).run()
class Engine(BaseEngine): """Python engine for running tests.""" schema = StorySchema( given={ Optional("yaml_snippet"): Str(), Optional("yaml_snippet_1"): Str(), Optional("yaml_snippet_2"): Str(), Optional("modified_yaml_snippet"): Str(), Optional("python version"): Str(), Optional("ruamel version"): Str(), Optional("setup"): Str(), Optional("code"): Str(), }, info={ Optional("description"): Str(), Optional("importance"): Int(), Optional("experimental"): Bool(), Optional("docs"): Str(), Optional("fails on python 2"): Bool(), }, ) def __init__(self, keypath, settings): self.path = keypath self.settings = settings def set_up(self): """Set up your applications and the test environment.""" self.path.state = self.path.gen.joinpath("state") if self.path.state.exists(): self.path.state.rmtree(ignore_errors=True) self.path.state.mkdir() self.path.profile = self.path.gen.joinpath("profile") if not self.path.profile.exists(): self.path.profile.mkdir() self.python = project_build( self.path, self.given['python version'], self.given['ruamel version'], ).bin.python self.example_py_code = ExamplePythonCode(self.python, self.path.state)\ .with_code(self.given.get('code', ''))\ .with_setup_code(self.given.get('setup', ''))\ .with_terminal_size(160, 100)\ .with_long_strings( yaml_snippet_1=self.given.get('yaml_snippet_1'), yaml_snippet=self.given.get('yaml_snippet'), yaml_snippet_2=self.given.get('yaml_snippet_2'), modified_yaml_snippet=self.given.get('modified_yaml_snippet'), ) @expected_exception(NonMatching) @expected_exception(HitchRunPyException) @validate( code=Str(), will_output=Map({ "in python 2": Str(), "in python 3": Str() }) | Str(), raises=Map({ Optional("type"): Map({ "in python 2": Str(), "in python 3": Str() }) | Str(), Optional("message"): Map({ "in python 2": Str(), "in python 3": Str() }) | Str(), }), in_interpreter=Bool(), ) def run(self, code, will_output=None, yaml_output=True, raises=None, in_interpreter=False): if in_interpreter: code = '{0}\nprint(repr({1}))'.format( '\n'.join(code.strip().split('\n')[:-1]), code.strip().split('\n')[-1]) to_run = self.example_py_code.with_code(code) if self.settings.get("cprofile"): to_run = to_run.with_cprofile( self.path.profile.joinpath("{0}.dat".format(self.story.slug))) result = to_run.expect_exceptions().run( ) if raises is not None else to_run.run() if will_output is not None: actual_output = '\n'.join( [line.rstrip() for line in result.output.split("\n")]) try: Templex(will_output).assert_match(actual_output) except NonMatching: if self.settings.get("rewrite"): self.current_step.update(**{"will output": actual_output}) else: raise if raises is not None: differential = False # Difference between python 2 and python 3 output? exception_type = raises.get('type') message = raises.get('message') if exception_type is not None: if not isinstance(exception_type, str): differential = True exception_type = exception_type['in python 2']\ if self.given['python version'].startswith("2")\ else exception_type['in python 3'] if message is not None: if not isinstance(message, str): differential = True message = message['in python 2']\ if self.given['python version'].startswith("2")\ else message['in python 3'] try: result = self.example_py_code.expect_exceptions().run() result.exception_was_raised(exception_type, message) except ExpectedExceptionMessageWasDifferent as error: if self.settings.get("rewrite") and not differential: new_raises = raises.copy() new_raises['message'] = result.exception.message self.current_step.update(raises=new_raises) else: raise def pause(self, message="Pause"): import IPython IPython.embed() def on_success(self): if self.settings.get("rewrite"): self.new_story.save() if self.settings.get("cprofile"): self.python( self.path.key.joinpath("printstats.py"), self.path.profile.joinpath("{0}.dat".format( self.story.slug))).run()
class Engine(BaseEngine): schema = StorySchema(given={ Optional("files"): MapPattern(Str(), Str()), Optional("variables"): MapPattern(Str(), Str()), Optional("python version"): Str(), Optional("setup"): Str(), Optional("code"): Str(), }, ) def __init__(self, pathgroup, settings): self.path = pathgroup self.settings = settings def set_up(self): self.path.state = self.path.gen.joinpath("state") if self.path.state.exists(): self.path.state.rmtree(ignore_errors=True) self.path.state.mkdir() for filename, text in self.given.get("files", {}).items(): filepath = self.path.state.joinpath(filename) if not filepath.dirname().exists(): filepath.dirname().mkdir() filepath.write_text(str(text)) filepath.chmod("u+x") for filename, text in self.given.get("variables", {}).items(): filepath = self.path.state.joinpath(filename) if not filepath.dirname().exists(): filepath.dirname().mkdir() filepath.write_text(str(text)) self.path.key.joinpath("code_that_does_things.py").copy( self.path.state) self.python_package = hitchpython.PythonPackage( self.given.get('python_version', self.given['python version'])) self.python_package.build() self.pip = self.python_package.cmd.pip self.python = self.python_package.cmd.python with hitchtest.monitor( [self.path.key.joinpath("debugrequirements.txt")]) as changed: if changed: self.pip("install", "-r", "debugrequirements.txt").in_dir(self.path.key).run() with hitchtest.monitor( pathq(self.path.project.joinpath("icommandlib")).ext( "py")) as changed: if changed: self.pip("uninstall", "icommandlib", "-y").ignore_errors().run() self.pip("install", ".").in_dir(self.path.project).run() self.example_py_code = ExamplePythonCode( self.python, self.path.state, ).with_setup_code(self.given.get('setup', '')).with_code( self.given.get('code', '')).with_timeout(4.0) @expected_exception(HitchRunPyException) def run_code(self): self.result = self.example_py_code.run() @expected_exception(HitchRunPyException) def start_code(self): self.running_python = self.example_py_code.running_code() def pause_for_half_a_second(self): import time time.sleep(0.5) def send_signal_and_wait_for_finish(self, signal_name): SIGNAL_NAMES_TO_NUMBERS = { name: getattr(signal, name) for name in dir(signal) if name.startswith('SIG') and '_' not in name } self.running_python.iprocess.psutil._send_signal( int(SIGNAL_NAMES_TO_NUMBERS[signal_name])) self.running_python.iprocess.wait_for_finish() @expected_exception(HitchRunPyException) @validate( exception_type=Map({ "in python 2": Str(), "in python 3": Str() }) | Str(), message=Map({ "in python 2": Str(), "in python 3": Str() }) | Str(), ) def raises_exception(self, exception_type=None, message=None): """ Expect an exception. """ differential = False if exception_type is not None: if not isinstance(exception_type, str): differential = True exception_type = exception_type['in python 2']\ if self.given['python version'].startswith("2")\ else exception_type['in python 3'] if message is not None: if not isinstance(message, str): differential = True message = message['in python 2']\ if self.given['python version'].startswith("2")\ else message['in python 3'] try: result = self.example_py_code.expect_exceptions().run() result.exception_was_raised(exception_type, message) except ExpectedExceptionMessageWasDifferent as error: if self.settings.get("overwrite artefacts") and not differential: self.current_step.update(message=error.actual_message) else: raise @validate(from_filenames=Seq(Str())) def processes_not_alive(self, from_filenames=None): still_alive = [] for from_filename in from_filenames: import psutil pid = int( self.path.state.joinpath(from_filename).bytes().decode( 'utf8').strip()) try: proc = psutil.Process(pid) proc.kill() still_alive.append(from_filename) except psutil.NoSuchProcess: pass if len(still_alive) > 0: raise Exception("Processes from {0} still alive.".format( ', '.join(still_alive))) def touch_file(self, filename): self.path.state.joinpath(filename).write_text("\nfile touched!", append=True) def _will_be(self, content, text, reference, changeable=None): if text is not None: if content.strip() == text.strip(): return else: raise RuntimeError( "Expected to find:\n{0}\n\nActual output:\n{1}".format( text, content, )) artefact = self.path.key.joinpath( "artefacts", "{0}.txt".format(reference.replace(" ", "-").lower())) from simex import DefaultSimex simex = DefaultSimex( open_delimeter="(((", close_delimeter=")))", ) simex_contents = content if changeable is not None: for replacement in changeable: simex_contents = simex.compile(replacement).sub( replacement, simex_contents) if not artefact.exists(): artefact.write_text(simex_contents) else: if self.settings.get('overwrite artefacts'): if artefact.bytes().decode('utf8') != simex_contents: artefact.write_text(simex_contents) print(content) else: if simex.compile(artefact.bytes().decode('utf8')).match( content) is None: raise RuntimeError( "Expected to find:\n{0}\n\nActual output:\n{1}".format( artefact.bytes().decode('utf8'), content, )) def file_contents_will_be(self, filename, text=None, reference=None, changeable=None): output_contents = self.path.state.joinpath(filename).bytes().decode( 'utf8') self._will_be(output_contents, text, reference, changeable) def output_will_be(self, text=None, reference=None, changeable=None): output_contents = self.path.state.joinpath( "output.txt").bytes().decode('utf8') self._will_be(output_contents, text, reference, changeable) @validate(seconds=Float()) def sleep(self, seconds): import time time.sleep(float(seconds)) def on_success(self): if self.settings.get("overwrite artefacts"): self.new_story.save()