Skip to content

fix(workflow): scope _deploy cleanup to what it actually changed - #149

Open
LukasGold wants to merge 1 commit into
mainfrom
test/cover-workflow-deploy
Open

fix(workflow): scope _deploy cleanup to what it actually changed#149
LukasGold wants to merge 1 commit into
mainfrom
test/cover-workflow-deploy

Conversation

@LukasGold

Copy link
Copy Markdown
Contributor

Why

tests/utils/workflow_test.py had no real coverage of the deploy path: test_deploy_serve built the _deploy(...) coroutine and deliberately never awaited it, and test_deploy_runner was @pytest.mark.skip. So flow.to_deployment(), .apply() and serve() never ran, and src/osw/utils/workflow.py sat at 26%.

Awaiting _deploy for the first time uncovered two bugs, both fixed here.

Bugs fixed

Both are the same defect class: cleanup scoped narrower than the state it cleans up. Each was pinned with a failing test before the fix.

  • PREFECT_API_URL deleted when the shim never ran. The gateway shim is entered only when _is_apigateway_url(gateway_url) and param.osw is not None, but the cleanup gated the environ.pop on the URL shape alone. Calling _deploy with osw=None on a machine configured against an ApiGateway silently deleted the caller's PREFECT_API_URL. Fixed with an _api_url_overridden flag set at the point of mutation, so the cleanup condition cannot drift from the entry condition.
  • Global httpx.AsyncClient.__init__ patch leaked. The patch went live during shim setup, but try: wrapped only await serve(...). Any exception in between - install_gateway_hook() hitting PermissionError on read-only site-packages, to_deployment(), or apply() against an unreachable server - left the patch installed for the rest of the process. try: now starts immediately after gateway_url is computed, with all three sentinels initialised above it.

Source change is 6 added lines plus a re-indent; no logic changed in the reflow.

Tests

11 tests replace the 2 non-tests, run under prefect_test_harness() with serve monkeypatched so no live server is needed:

  • test_deploy_serve - awaits _deploy, then reads the deployment back from the Prefect API to prove apply() really registered it
  • test_deploy_defaults_deployment_name, test_deploy_sync_wrapper (sync, since deploy() calls asyncio.run), test_deploy_registers_flow_with_osw
  • test_deploy_apigateway_shim_restores_httpx - asserts the patch is both applied and restored, by identity
  • test_deploy_preserves_ambient_prefect_api_url, test_deploy_restores_previous_prefect_api_url, test_deploy_restores_httpx_when_deployment_fails, test_deploy_restores_httpx_when_gateway_hook_fails - the four regression tests

Also: the shared mutable module-level deploy_param became a make_deploy_param() factory, because _deploy writes to deploy_config.name and the shared object leaked state between tests.

Notes

- PREFECT_API_URL was popped even when the gateway shim never ran
- httpx.AsyncClient.__init__ leaked if shim setup or the loop raised
- replace unawaited/skipped deploy tests with 11 executing tests
- workflow.py coverage 26% -> 43%
- drop permanently skipped test_deploy_runner
@github-actions

Copy link
Copy Markdown
Contributor

Release preview

Merging this PR would release v2.0.3 (current: v2.0.2).

Changelog preview (truncated)
## v2.0.3 (2026-08-28)

### Bug Fixes

- **workflow**: Scope _deploy cleanup to what it actually changed
  ([`4f0593e`](https://github.com/OpenSemanticLab/osw-python/commit/4f0593e47b7a2dd42f304429f2ffb9b5eb5fe47c))

### Testing

- Rename oold.py to oold_test.py so its tests are collected
  ([`20072a9`](https://github.com/OpenSemanticLab/osw-python/commit/20072a9249cd97126a222c62a70f84e0433343ef))

Preview via python-semantic-release and conventional commits.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant