From 1b257b8d876f1d2e8f66be2351265fc265c619cd Mon Sep 17 00:00:00 2001 From: Andrew Rosen Date: Fri, 29 Sep 2023 16:46:49 -1000 Subject: [PATCH] Add missing tests --- CHANGELOG.md | 6 +- tests/functional_tests/workflow_stack_test.py | 228 ++++++++++++++++++ 2 files changed, 231 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 53e967a9e..2d55201c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,10 +14,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Operations +- Added missing tests for the `executor` kwarg in decorators - Changed `actions/checkout@v3` to `actions/checkout@v4` in CI - Dependabot update to npm in changelog action - Update tough-cookie to 4.1.3 version -- Added rich support to cli for better printing statements. +- Added rich support to cli for better printing statements. - Changed semver from 5.7.1 to 5.7.2 in package.json - Updated word-wrap to 1.2.4 version @@ -46,7 +47,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Co-authored-by: Prasanna Venkatesh <54540812+Prasy12@users.noreply.github.com> - FilipBolt - ### Fixed - Formatted executor block under Qelectron job details to handle any class-type values @@ -80,7 +80,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Docs -- Fix autodoc for SSH, Slurm, AWS Braket, AWS Lambda, AWS EC2, AWS Batch, Google Batch +- Fix autodoc for SSH, Slurm, AWS Braket, AWS Lambda, AWS EC2, AWS Batch, Google Batch - Updated documentation links in README - Added tutorial for redispatching workflows with Streamlit diff --git a/tests/functional_tests/workflow_stack_test.py b/tests/functional_tests/workflow_stack_test.py index dc7a72d96..3b2ed8910 100644 --- a/tests/functional_tests/workflow_stack_test.py +++ b/tests/functional_tests/workflow_stack_test.py @@ -925,3 +925,231 @@ def failing_workflow(x, y): assert int(result.result) == 1 assert result.status == "COMPLETED" assert result.get_node_result(0)["start_time"] == result.get_node_result(0)["end_time"] + + +@pytest.mark.parameterize("executor", ["local", ct.executor.LocalExecutor()]) +def test_executor_inheritance_electron(executor): + """Test for executor inheritance via Electron""" + + @ct.electron(executor=executor) + def add(a, b): + return a + b + + @ct.lattice + def workflow(a, b): + return add(a, b) + + dispatch_id = ct.dispatch(workflow)(1, 2) + result = ct.get_result(dispatch_id, wait=True) + assert add.electron_object.get_metadata("executor") == "local" + assert workflow.get_metadata("executor") is None + assert result.status == "COMPLETED" + assert result.result == 3 + + +@pytest.mark.parameterize("executor", ["local", ct.executor.LocalExecutor()]) +def test_executor_inheritance_lattice(executor): + """Test for executor inheritance via Lattice""" + + executor = ct.executor.LocalExecutor() + + @ct.electron + def add(a, b): + return a + b + + @ct.lattice(executor=executor) + def workflow(a, b): + return add(a, b) + + dispatch_id = ct.dispatch(workflow)(1, 2) + result = ct.get_result(dispatch_id, wait=True) + assert add.electron_object.get_metadata("executor") is None + assert workflow.get_metadata("executor") == "local" + assert result.status == "COMPLETED" + assert result.result == 3 + + +@pytest.mark.parameterize("executor", ["local", ct.executor.LocalExecutor()]) +def test_executor_inheritance_electron_and_lattice(executor): + """Test for executor inheritance via Electron and Lattice""" + + @ct.electron(executor=executor) + def add(a, b): + return a + b + + @ct.lattice(executor=executor) + def workflow(a, b): + return add(a, b) + + dispatch_id = ct.dispatch(workflow)(1, 2) + result = ct.get_result(dispatch_id, wait=True) + assert add.electron_object.get_metadata("executor") == "local" + assert workflow.get_metadata("executor") == "local" + assert result.status == "COMPLETED" + assert result.result == 3 + + +@pytest.mark.parameterize("executor", ["local", ct.executor.LocalExecutor()]) +def test_executor_inheritance_electron_with_sublattice(executor): + """Test for executor inheritance with electron specification""" + + @ct.electron(executor=executor) + def add(a, b): + return a + b + + @ct.electron + def make_more(val): + return [val] * 3 + + @ct.electron + @ct.lattice + def add_distributed(vals, c): + return [add(val, c) for val in vals] + + @ct.lattice + def workflow(a, b, c): + result1 = add(a, b) + result2 = make_more(result1) + return add_distributed(result2, c) + + dispatch_id = ct.dispatch(workflow)(1, 2, 3) + result = ct.get_result(dispatch_id, wait=True) + assert add.electron_object.get_metadata("executor") == "local" + assert make_more.electron_object.get_metadata("executor") is None + assert add_distributed.electron_object.get_metadata("executor") is None + assert workflow.get_metadata("executor") is None + assert result.status == "COMPLETED" + assert result.result == [6, 6, 6] + + +@pytest.mark.parameterize("executor", ["local", ct.executor.LocalExecutor()]) +def test_executor_inheritance_lattice_with_sublattice(executor): + """Test for executor inheritance with lattice specification""" + + @ct.electron + def add(a, b): + return a + b + + @ct.electron + def make_more(val): + return [val] * 3 + + @ct.electron + @ct.lattice + def add_distributed(vals, c): + return [add(val, c) for val in vals] + + @ct.lattice(executor=executor) + def workflow(a, b, c): + result1 = add(a, b) + result2 = make_more(result1) + return add_distributed(result2, c) + + # Dispatched + dispatch_id = ct.dispatch(workflow)(1, 2, 3) + result = ct.get_result(dispatch_id, wait=True) + assert add.electron_object.get_metadata("executor") is None + assert make_more.electron_object.get_metadata("executor") is None + assert add_distributed.electron_object.get_metadata("executor") is None + assert workflow.get_metadata("executor") == "local" + assert result.status == "COMPLETED" + assert result.result == [6, 6, 6] + + +@pytest.mark.parameterize("executor", ["local", ct.executor.LocalExecutor()]) +def test_executor_inheritance_electron_and_lattice_with_sublattice(executor): + """Test for executor inheritance with electron and lattice specification""" + + @ct.electron(executor=executor) + def add(a, b): + return a + b + + @ct.electron + def make_more(val): + return [val] * 3 + + @ct.electron + @ct.lattice + def add_distributed(vals, c): + return [add(val, c) for val in vals] + + @ct.lattice(executor=executor) + def workflow(a, b, c): + result1 = add(a, b) + result2 = make_more(result1) + return add_distributed(result2, c) + + dispatch_id = ct.dispatch(workflow)(1, 2, 3) + result = ct.get_result(dispatch_id, wait=True) + assert add.electron_object.get_metadata("executor") == "local" + assert make_more.electron_object.get_metadata("executor") is None + assert add_distributed.electron_object.get_metadata("executor") is None + assert workflow.get_metadata("executor") == "local" + assert result.status == "COMPLETED" + assert result.result == [6, 6, 6] + + +@pytest.mark.parameterize("executor", ["local", ct.executor.LocalExecutor()]) +def test_executor_inheritance_sublattice_v1(executor): + """Test for executor inheritance with sublattice override (in electron)""" + + @ct.electron + def add(a, b): + return a + b + + @ct.electron + def make_more(val): + return [val] * 3 + + @ct.electron(executor="dask") + @ct.lattice + def add_distributed(vals, c): + return [add(val, c) for val in vals] + + @ct.lattice(executor=executor) + def workflow(a, b, c): + result1 = add(a, b) + result2 = make_more(result1) + return add_distributed(result2, c) + + dispatch_id = ct.dispatch(workflow)(1, 2, 3) + result = ct.get_result(dispatch_id, wait=True) + assert add.electron_object.get_metadata("executor") is None + assert make_more.electron_object.get_metadata("executor") is None + assert add_distributed.electron_object.get_metadata("executor") == "dask" + assert workflow.get_metadata("executor") == "local" + assert result.status == "COMPLETED" + assert result.result == [6, 6, 6] + + +@pytest.mark.parameterize("executor", ["local", ct.executor.LocalExecutor()]) +def test_executor_inheritance_sublattice_v2(executor): + """Test for executor inheritance with sublattice override (in lattice)""" + + @ct.electron + def add(a, b): + return a + b + + @ct.electron + def make_more(val): + return [val] * 3 + + @ct.electron + @ct.lattice(executor="dask") + def add_distributed(vals, c): + return [add(val, c) for val in vals] + + @ct.lattice(executor=executor) + def workflow(a, b, c): + result1 = add(a, b) + result2 = make_more(result1) + return add_distributed(result2, c) + + dispatch_id = ct.dispatch(workflow)(1, 2, 3) + result = ct.get_result(dispatch_id, wait=True) + assert add.electron_object.get_metadata("executor") is None + assert make_more.electron_object.get_metadata("executor") is None + assert add_distributed.electron_object.get_metadata("executor") is None + assert workflow.get_metadata("executor") == "local" + assert result.status == "COMPLETED" + assert result.result == [6, 6, 6]