def test_create_project_that_already_exists(self) -> None: """ Test the output of the create project command with a project name that already exists. """ _ = run_command('tgl create project "project name for tests"') output = run_command('tgl create project "project name for tests"') self.assertIn('ERROR: Project could not be created.', output) self.assertIn('Response: "Name has already been taken"', output)
def test_pause_with_timer_running(self) -> None: """ Test the output of the pause command with a timer running. """ _ = run_command('tgl start "description for pause"') output = run_command('tgl pause') self.assertIn('Timer "description for pause" paused.', output) self.assertIn('Resume using "tgl resume".', output)
def test_resume_with_paused_timer(self) -> None: """ Test the output of the resume command with a paused timer. """ _ = run_command('tgl start "description"') _ = run_command('tgl pause') output = run_command('tgl resume') self.assertIn('Timer "description" resumed.', output)
def test_current_with_timer_running(self) -> None: """ Test the output of the current command with a timer running. """ _ = run_command('tgl start "description"') output = run_command('tgl current') self.assertIn('Current timer:', output) self.assertRegex(output, r'Description:\s*description') self.assertRegex(output, r'Running time:\s*0:00:\d*')
def test_execute_help_details(self): """ Verify that formatting of the execute operation help provides multiple paragraphs with more details. """ lines = run_command( [ "weaver", "execute", "--help", ], trim=False ) start = -1 end = -1 for index, line in enumerate(lines): if "-I INPUTS, --inputs INPUTS" in line: start = index + 1 if "Example:" in line: end = index break assert 0 < start < end indent = " " * lines[start].count(" ") assert len(indent) > 4 assert all(line.startswith(indent) for line in lines[start:end]) assert len([line for line in lines[start:end] if line == indent]) > 3, "Inputs should have a few paragraphs."
def test_create_project(self) -> None: """ Test the output of the create project command. """ output = run_command('tgl create project "project name for tests"') self.assertRegex( output, r'Project "project name for tests" has been created in the ".*" workspace.' )
def test_delete_project_with_none_available(self) -> None: """ Test the output of the delete project command without any available project. """ output = run_command('tgl delete project') self.assertIn('There are no projects available in the config file.', output) self.assertIn( 'If you recently added a project to your account, please use "tgl reconfig" to reconfigure your data.', output)
def test_help_operations(self): lines = run_command( [ "weaver", "--help", ], trim=False, ) operations = [ "deploy", "undeploy", "capabilities", "processes", "describe", "execute", "monitor", "dismiss", "results", "status", ] assert all(any(op in line for line in lines) for op in operations)
def test_resume_without_a_paused_timer(self) -> None: """ Test the output of the resume command without any paused timer. """ output = run_command('tgl resume') self.assertIn('There is no paused timer. Use "tgl start" to start a new timer.', output)
def test_current_with_no_running_timer(self) -> None: """ Test the output of the current command without any timer running. """ output = run_command('tgl current') self.assertIn('There is no timer currently running.', output)
def test_pause_without_any_timer_running(self) -> None: """ Test the output of pause command with no timer running. """ output = run_command('tgl pause') self.assertIn('There is no timer currently running.', output)
def test_create_project_command(self) -> None: """ Test the output of the create project command without the setup being done. """ output = run_command('tgl create project project_name') self.assertIn("Please run 'tgl setup' before you can run a timer.", output)
def test_reconfig_command(self) -> None: """ Test the output of the reconfig command without the setup being done. """ output = run_command('tgl reconfig') self.assertIn("Please run 'tgl setup' before you can run a timer.", output)
def test_current_command(self) -> None: """ Test the output of the current command without the setup being done. """ output = run_command('tgl current') self.assertIn("Please run 'tgl setup' before you can run a timer.", output)
def test_start_command(self) -> None: """ Test the output of the start command without the setup being done. """ output = run_command('tgl start "description"') self.assertIn("Please run 'tgl setup' before you can run a timer.", output)
def test_parse_inputs_with_media_type(): inputs = [] mock_result = OperationResult(True, code=500) def parsed_inputs(_inputs, *_, **__): inputs.append(_inputs) return mock_result # catch and ignore returned error since we generate it # voluntarily with following mock to stop processing def no_error_cli(*args): weaver_cli(*args) return 0 with mock.patch("weaver.cli.WeaverClient._update_files", side_effect=parsed_inputs): with tempfile.NamedTemporaryFile(mode="w", suffix=".yml") as input_yaml: yaml.safe_dump({"info": {"data": "yaml"}}, input_yaml) input_yaml.flush() input_yaml.seek(0) run_command( [ # weaver "execute", # different media-type than YAML on purpose to ensure parsing uses provided value, and not extension "-I", f"input:File={input_yaml.name}@mediaType={ContentType.APP_CWL}", "-p", "fake_process", "-u", "http://fake.domain.com", "-q", # since CLI fails purposely, avoid logging errors which would be confusing if debugging logs ], entrypoint=no_error_cli) assert len(inputs) == 1 assert inputs[0] == { "input": { "href": input_yaml. name, # normally, local file would be uploaded to vault, but we skipped it with mock "format": { "mediaType": ContentType.APP_CWL } } } inputs.clear() schema_json = "http://schema.org/random.json" schema_xml = "http://schema.org/other.xml" with mock.patch("weaver.cli.WeaverClient._update_files", side_effect=parsed_inputs): with ExitStack() as stack: input_yaml = stack.enter_context( tempfile.NamedTemporaryFile(mode="w", suffix=".yml")) yaml.safe_dump({"info": {"data": "yaml"}}, input_yaml) input_yaml.flush() input_yaml.seek(0) input_json = stack.enter_context( tempfile.NamedTemporaryFile(mode="w", suffix=".json")) json.dump({"info": {"data": "json"}}, input_json) input_json.flush() input_json.seek(0) input_xml = stack.enter_context( tempfile.NamedTemporaryFile(mode="w", suffix=".xml")) input_xml.write("<xml>data</xml>") input_xml.flush() input_xml.seek(0) input_tif = stack.enter_context( tempfile.NamedTemporaryFile(mode="wb", suffix=".tif")) input_tif.write(base64.b64encode("012345".encode("utf-8"))) input_tif.flush() input_tif.seek(0) ctype_tif = ContentType.IMAGE_GEOTIFF # must be URL-encoded to avoid parsing issue with separators assert " " in ctype_tif and ";" in ctype_tif # just safeguard in case it is changed at some point ctype_tif_escaped = quote(ctype_tif) assert " " not in ctype_tif_escaped and ";" not in ctype_tif_escaped run_command( [ # weaver "execute", "-I", f"other:File={input_xml.name}@mediaType={ContentType.TEXT_XML}@schema={schema_xml}", "-I", f"input:File={input_yaml.name}@mediaType={ContentType.APP_YAML}@schema={schema_json}", "-I", f"input:File={input_json.name}@type={ContentType.APP_JSON}@rel=schema", "-I", f"other:File={input_tif.name}@mediaType={ctype_tif_escaped}@encoding=base64@rel=image", "-p", "fake_process", "-u", "http://fake.domain.com", "-q", # since CLI fails purposely, avoid logging errors which would be confusing if debugging logs ], entrypoint=no_error_cli) assert len(inputs) == 1 assert inputs[0] == { "input": [ { "href": input_yaml.name, "format": { "mediaType": ContentType.APP_YAML, "schema": schema_json } }, { "href": input_json.name, "type": ContentType. APP_JSON, # valid alternate OGC representation of format/mediaType object "rel": "schema" # known field in this case, ensure schema value is not confused with parameter keys } ], "other": [ { "href": input_xml.name, "format": { "mediaType": ContentType.TEXT_XML, "schema": schema_xml } }, { "href": input_tif.name, "format": { "mediaType": ContentType.IMAGE_GEOTIFF, # must be unescaped "encoding": "base64" }, "rel": "image", # irrelevant for real input in this case, but validate parameters are all propagated } ] }