diff --git a/example/modules/_fixtures.py b/example/modules/_fixtures.py deleted file mode 100644 index 4734a1061..000000000 --- a/example/modules/_fixtures.py +++ /dev/null @@ -1,29 +0,0 @@ -from pyfixtures import fixture -from virtool_workflow import Workflow - - -@fixture -def fixture_a() -> str: - return "a" - - -@fixture -def fixture_b(fixture_a: str) -> str: - return f"{fixture_a}b" - - -@fixture -async def fixture_c() -> str: - return "c" - - -wf = Workflow() - - -@wf.step -def start(fixture_a, fixture_b, fixture_c, results): - results["fixture_a"] = fixture_a - results["fixture_b"] = fixture_b - results["fixture_c"] = fixture_c - - return "In file fixtures are correctly loaded" diff --git a/example/modules/_workflow.py b/example/modules/_workflow.py deleted file mode 100644 index 0bc4059fb..000000000 --- a/example/modules/_workflow.py +++ /dev/null @@ -1,17 +0,0 @@ -from virtool_workflow import Workflow - -wf = Workflow() - - -@wf.step(name="Step One") -def step_1(): - """ - This is a description for the first step. - """ - - -@wf.step -def step_2(): - """ - This is a description for the second step. - """ diff --git a/tests/test_cmd.py b/tests/test_cmd.py new file mode 100644 index 000000000..2ac338dfb --- /dev/null +++ b/tests/test_cmd.py @@ -0,0 +1,64 @@ +import asyncio + +from _pytest._py.path import LocalPath +from aioredis import Redis + +from tests.fixtures.data import Data +from virtool_workflow.runtime.run_subprocess import watch_pipe + + +async def test_cmd( + data: Data, + jobs_api_connection_string: str, + redis: Redis, + redis_connection_string: str, + tmp_path: LocalPath, +): + data.job.args.update( + { + "files": [ + { + "id": 1, + "name": "reads_1.fq.gz", + "size": 100, + }, + { + "id": 2, + "name": "reads_2.fq.gz", + "size": 100, + }, + ], + "sample_id": data.new_sample.id, + } + ) + + await redis.rpush("job_test", "test_job") + + p = await asyncio.create_subprocess_exec( + "poetry", + "run", + "run-workflow", + "--jobs-api-connection-string", + jobs_api_connection_string, + "--redis-connection-string", + redis_connection_string, + "--redis-list-name", + "job_test", + "--work-path", + str(tmp_path), + limit=1024 * 1024 * 128, + stderr=asyncio.subprocess.PIPE, + stdout=asyncio.subprocess.PIPE, + ) + + async def handler(line): + print(line.decode().rstrip()) + + g = asyncio.gather( + watch_pipe(p.stderr, handler), + watch_pipe(p.stdout, handler), + ) + + await p.wait() + await p.communicate() + await g diff --git a/tests/test_discovery.py b/tests/test_discovery.py index b85f4e7cd..caad50e6d 100644 --- a/tests/test_discovery.py +++ b/tests/test_discovery.py @@ -8,11 +8,17 @@ def test_discover_workflow(example_path: Path): """Test that a workflow can be discovered from a module.""" - workflow = discover_workflow(example_path / "modules" / "_workflow.py") + workflow = discover_workflow(Path(__file__).parent.parent / "workflow.py") assert isinstance(workflow, Workflow) assert len(workflow.steps) == 2 - assert workflow.steps[0].display_name == "Step One" - assert workflow.steps[1].display_name == "Step 2" - assert workflow.steps[0].description == "This is a description for the first step." - assert workflow.steps[1].description == "This is a description for the second step." + assert workflow.steps[0].display_name == "Step 1" + assert workflow.steps[1].display_name == "Try Fastqc" + assert ( + workflow.steps[0].description + == "A basic step that doesn't actually do anything." + ) + assert ( + workflow.steps[1].description + == "Make sure the FastQC fixture works in a real workflow run." + ) diff --git a/tests/test_fastqc.py b/tests/test_fastqc.py index f899fddb5..83b97ecd1 100644 --- a/tests/test_fastqc.py +++ b/tests/test_fastqc.py @@ -480,13 +480,14 @@ async def test_fastqc( output_path = work_path / "fastqc" - async for func in fastqc(run_subprocess, work_path): - out = await func( - ( - work_path / "reads_1.fq.gz", - work_path / "reads_2.fq.gz", - ), - output_path, - ) + func = await fastqc(run_subprocess) + + out = await func( + ( + work_path / "reads_1.fq.gz", + work_path / "reads_2.fq.gz", + ), + output_path, + ) - assert out == snapshot + assert out == snapshot diff --git a/virtool_workflow/analysis/fastqc.py b/virtool_workflow/analysis/fastqc.py index 8f638848b..75544b256 100644 --- a/virtool_workflow/analysis/fastqc.py +++ b/virtool_workflow/analysis/fastqc.py @@ -397,15 +397,12 @@ def _parse_fastqc(fastqc_path: Path, output_path: Path) -> dict: class FastQCRunner(Protocol): """A protocol describing callables that can be used to run FastQC.""" - async def __call__(self, paths: ReadPaths) -> dict: + async def __call__(self, paths: ReadPaths, output_path: Path) -> dict: ... @fixture -async def fastqc( - run_subprocess: RunSubprocess, - work_path: Path, -): +async def fastqc(run_subprocess: RunSubprocess): """ Provides an asynchronous function that can run FastQC as a subprocess. @@ -441,6 +438,4 @@ async def func(paths: ReadPaths, output_path: Path) -> dict: return _parse_fastqc(temp_path, output_path) - yield func - - await asyncio.to_thread(shutil.rmtree, temp_path) + return func diff --git a/workflow.py b/workflow.py new file mode 100644 index 000000000..e0a7a3499 --- /dev/null +++ b/workflow.py @@ -0,0 +1,20 @@ +"""An example workflow.""" +import asyncio +from pathlib import Path + +from virtool_workflow import step +from virtool_workflow.analysis.fastqc import FastQCRunner +from virtool_workflow.data.samples import WFNewSample + + +@step +async def step_1(): + """A basic step that doesn't actually do anything.""" + await asyncio.sleep(1) + + +@step +async def try_fastqc(fastqc: FastQCRunner, new_sample: WFNewSample, work_path: Path): + """Make sure the FastQC fixture works in a real workflow run.""" + paths = [u.path for u in new_sample.uploads] + await fastqc(paths, work_path / "reads")