Skip to content

UN-3636 [MISC] enable the unit-workers rig group and de-flake its suite#2176

Open
chandrasekharan-zipstack wants to merge 4 commits into
mainfrom
feat/un-3636-enable-unit-workers
Open

UN-3636 [MISC] enable the unit-workers rig group and de-flake its suite#2176
chandrasekharan-zipstack wants to merge 4 commits into
mainfrom
feat/un-3636-enable-unit-workers

Conversation

@chandrasekharan-zipstack

Copy link
Copy Markdown
Contributor

What

The unit-workers rig group filtered markers: "unit", but no worker test carries that marker — so it collected zero tests and silently never ran in CI. This switches it to the negative filter the other unit groups use, so all 734 worker tests actually run and gate.

Enabling collection surfaced pre-existing debt (the suite was never CI-gated). All fixed here — no product code changed.

Fixes

Test isolation (parallel/xdist pollution) — in workers/tests/conftest.py:

  • Worker Celery apps build a live-Postgres result backend from ambient DB_* / CELERY_BACKEND_DB_*; stripped before any app import so eager results stay in-memory.
  • Building a Celery app hijacks current_app; pin celery's finalized default app as current around each test so @worker_task proxies resolve (was NotRegistered / psycopg2 errors, order-dependent).

Stale assertions (prod drifted, tests never caught it since the suite wasn't running):

  • ExecutorToolShim gained execution_id/organization_id/file_execution_id.
  • _run_agentic_extraction() gained required execution_id.
  • Index result now carries usage_records from embedding.flush_pending_usage().
  • Highlight-disabled test over-asserted "plugin loader untouched" — lookup-enrichment is queried unconditionally and returns None in OSS; narrowed to assert the highlight plugin specifically.

Vanity removal — dropped tautological *_enum_exists tests that just mirror the source Operation enum (kept the routing/registration/removed-guard tests).

Renamestest_sanity_phase6* / test_phaseN* → intent-revealing names (git mv, history preserved).

Verification

tox -e groups -- unit-workers734 passed, stable across repeated parallel runs. tox -e rig -- validate OK. Lint clean under the repo's pinned ruff/ruff-format.

🤖 Generated with Claude Code

The unit-workers group filtered `markers: "unit"`, but no worker test carries
that marker, so it collected zero tests and silently never ran in CI. Switch to
the negative filter the other unit groups use so the 734 worker tests actually
run.

Enabling collection surfaced pre-existing debt (the suite was never CI-gated):

- Test isolation: worker Celery apps build a live-Postgres result backend from
  ambient DB_*/CELERY_BACKEND_DB_*, and building an app hijacks `current_app`.
  Both leaked across tests under xdist (psycopg2 connection errors, task
  `NotRegistered`). Fixed in conftest: strip the DB env before any app import,
  and pin celery's finalized default app as current around each test.
- Stale assertions (prod drifted, tests never caught it): ExecutorToolShim /
  _run_agentic_extraction gained args; index result now carries usage_records;
  the highlight-disabled test over-asserted "plugin loader untouched" when
  lookup-enrichment is queried unconditionally (returns None in OSS).
- Dropped tautological enum-existence tests that just mirror the source enum.
- Renamed the cryptic test_sanity_phase6* / test_phaseN* files to
  intent-revealing names.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019EN8hh518CbCVMP3BHTVmG
@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e15ab2e7-1839-4d1e-948a-73d5fa563f17

📥 Commits

Reviewing files that changed from the base of the PR and between f66b9db and 2a1acc6.

📒 Files selected for processing (2)
  • tests/rig/cli.py
  • tests/rig/tests/test_cli.py

Summary by CodeRabbit

  • Tests
    • Improved worker test isolation by loading test env vars and ensuring Celery worker tests don’t connect to real DB-backed result backends.
    • Expanded agentic operation, highlight-data, and log streaming expectations for clearer end-to-end executor behavior.
    • Refined plugin migration and legacy operation coverage, including removing redundant enum-presence checks.
    • Added CLI regression coverage for non-optional test groups that collect zero tests, plus updated test selection rules to better separate unit vs integration/slow runs.
  • Documentation
    • Standardized and updated test module headers/descriptions and various assertion formatting for readability.

Walkthrough

Worker test selection and Celery isolation were updated. Rig handling now treats empty default pytest groups as failures, while worker executor, plugin, pipeline, routing, logging, and challenge/evaluation tests were clarified or reformatted without production-code changes.

Changes

Worker test configuration and execution safeguards

Layer / File(s) Summary
Test selection, environment isolation, and rig exit handling
tests/groups.yaml, workers/conftest.py, workers/tests/conftest.py, tests/rig/cli.py, tests/rig/tests/test_cli.py
Worker selection excludes integration and slow tests; Celery test setup removes database backend variables and restores the current app; default non-optional pytest groups collecting no tests now fail the rig, with regression coverage for marker overrides.

Executor, plugin, and operation coverage

Layer / File(s) Summary
Executor and plugin regression coverage
workers/tests/test_*operation.py, workers/tests/test_plugin_migration_regression.py, workers/tests/test_completion_and_highlight.py, workers/tests/test_table_lineitem_challenge_eval.py
Agentic, SPS, table, smart-table, highlight, migration, challenge, and evaluation tests were narrowed or updated to assert routing and plugin behavior through current execution paths.

Pipeline and dispatch test normalization

Layer / File(s) Summary
Pipeline, dispatch, and logging tests
workers/tests/test_structure_pipeline.py, workers/tests/test_structure_tool_pipeline.py, workers/tests/test_extraction_pipeline_contracts.py, workers/tests/test_dispatch_with_callback.py, workers/tests/test_log_streaming.py, workers/tests/test_prompt_studio_dispatch.py, workers/tests/test_single_pass_extraction.py, workers/tests/test_summarize_operation.py, workers/tests/test_variable_replacement_postprocessor.py
Mock setup, context construction, logging expectations, dispatch helpers, module descriptions, and formatting were updated while preserving the existing assertions except for explicit shim arguments and JSON-safe embedding usage.

Estimated code review effort: 3 (Moderate) | ~25 minutes

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description covers What/Fixes/Verification, but it misses most required template sections, including the breakage, migrations, env, related issues, and checklist fields. Add the missing template sections, especially Why, How, breakage impact, Database Migrations, Env Config, Related Issues, Notes on Testing, and the Checklist.
Docstring Coverage ⚠️ Warning Docstring coverage is 63.36% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: enabling the unit-workers rig group and stabilizing its suite.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/un-3636-enable-unit-workers

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR enables the worker unit suite and updates its tests to match current behavior. The main changes are:

  • Select worker unit tests with a negative integration and slow marker filter.
  • Fail normal rig runs when a required pytest group collects no tests.
  • Isolate worker tests from database-backed Celery results and current-app drift.
  • Update stale worker test contracts and rename tests by intent.

Confidence Score: 5/5

This looks safe to merge.

  • No blocking issues were found in the updated code.
  • The worker-suite selection, empty-group gate, and test-isolation changes are consistent with the intended behavior.

Important Files Changed

Filename Overview
tests/groups.yaml Enables worker unit-test collection with the repository's negative marker pattern.
tests/rig/cli.py Makes empty required pytest groups fail normal rig runs.
tests/rig/tests/test_cli.py Covers empty required groups and explicit marker overrides.
workers/tests/conftest.py Isolates worker tests from ambient database settings and Celery current-app changes.
workers/tests/test_agentic_operations.py Updates agentic extraction tests for the required execution identifier.
workers/tests/test_completion_and_highlight.py Checks that disabled highlighting skips only the highlight plugin lookup.
workers/tests/test_extraction_pipeline_contracts.py Updates indexing mocks for usage-record flushing.

Reviews (4): Last reviewed commit: "UN-3636 [DEV] fail the build on a non-op..." | Re-trigger Greptile

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
workers/tests/test_completion_and_highlight.py (1)

68-71: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Redundant dictionary check for call_kwargs.

In Python's unittest.mock._Call object, call_kwargs.kwargs and call_kwargs[1] refer to the exact same dictionary of keyword arguments. If the intent was to check whether the callback was passed as a positional argument instead, you would need to inspect call_kwargs.args (or call_kwargs[0]).

If process_text is always expected to be passed as a keyword argument, you can simplify this assertion by removing the redundant check.

♻️ Proposed refactor
-        assert (
-            call_kwargs.kwargs.get("process_text") is callback
-            or call_kwargs[1].get("process_text") is callback
-        )
+        assert call_kwargs.kwargs.get("process_text") is callback
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@workers/tests/test_completion_and_highlight.py` around lines 68 - 71, Update
the assertion around call_kwargs to inspect only call_kwargs.kwargs for the
process_text callback, removing the redundant call_kwargs[1] check since
process_text is expected as a keyword argument.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@workers/tests/test_completion_and_highlight.py`:
- Around line 68-71: Update the assertion around call_kwargs to inspect only
call_kwargs.kwargs for the process_text callback, removing the redundant
call_kwargs[1] check since process_text is expected as a keyword argument.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3bf16fee-70b3-4f7f-97e8-3d275d20f635

📥 Commits

Reviewing files that changed from the base of the PR and between 0786a0a and 503c177.

📒 Files selected for processing (19)
  • tests/groups.yaml
  • workers/tests/conftest.py
  • workers/tests/test_agentic_operations.py
  • workers/tests/test_completion_and_highlight.py
  • workers/tests/test_dispatch_with_callback.py
  • workers/tests/test_extraction_pipeline_contracts.py
  • workers/tests/test_log_streaming.py
  • workers/tests/test_plugin_loader.py
  • workers/tests/test_plugin_migration_regression.py
  • workers/tests/test_prompt_studio_dispatch.py
  • workers/tests/test_simple_prompt_studio_operation.py
  • workers/tests/test_single_pass_extraction.py
  • workers/tests/test_smart_table_extract_operation.py
  • workers/tests/test_structure_pipeline.py
  • workers/tests/test_structure_tool_pipeline.py
  • workers/tests/test_summarize_operation.py
  • workers/tests/test_table_extract_operation.py
  • workers/tests/test_table_lineitem_challenge_eval.py
  • workers/tests/test_variable_replacement_postprocessor.py

@chandrasekharan-zipstack chandrasekharan-zipstack changed the title UN-3636 [FIX] enable the unit-workers rig group and de-flake its suite UN-3636 [MISC] enable the unit-workers rig group and de-flake its suite Jul 14, 2026
@athul-rs athul-rs self-requested a review July 14, 2026 12:38
Drop stale-prone specifics (function names, file:line refs, vendor
lists, class names) from groups.yaml comments; keep the WHY.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019EN8hh518CbCVMP3BHTVmG

@athul-rs athul-rs left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the marker fix, the conftest isolation work, the stale-assertion fixes, and the deletions/renames. Net: the direction is right and this is a strict improvement — enabling 734 previously-dead tests is a clear win, and both conftest mechanisms (env strip + current_app pinning) are correct as written.

I ran an adversarial pass over my own findings before posting, and three didn't survive. Recording them so nobody re-litigates:

  • The *_enum_exists deletions are fine. I first read them as the only pin on sdk1's Operation values — they aren't. test_plugin_migration_regression.py:131-176 already pins the whole set bidirectionally (test_every_operation_is_mapped, test_no_extra_mappings, len(Operation) == 19). Genuine dedup, and sdk1 is an in-repo editable path dep, not a versioned external provider. Agreed with the call.
  • shared/tests is not missed by the env strip. os.environ.pop() is process-global and both paths run in one pytest process with conftests loaded before any test executes. Only the autouse current_app fixture doesn't reach shared/tests, and nothing there touches celery — latent, zero impact.
  • The env strip is the right mechanism, not a workaround — it's the only thing that handles an ambient exported DB_HOST and the only thing covering CELERY_BACKEND_DB_*. See the conftest note.

Four comments left. Two I think are worth acting on:

  1. The rig still scores "collected zero tests" as a pass for non-optional groups. This PR fixes the instance, not the class — the next marker typo goes green the same way.
  2. The log_component replica tests are the real tautologies — and one is currently green while asserting the opposite of what production does.

Plus two nits. Nothing blocking; CI is green.

Comment thread tests/groups.yaml
markers: "unit"
# Negative filter like the other unit groups: worker tests aren't tagged
# `unit`; live-infra tests carry `integration`/`slow` and run elsewhere.
markers: "not integration and not slow"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mechanism that hid this bug is still in place.

Flipping the marker fixes this group, but not the reason a zero-collect group reported green. tests/rig/cli.py:52 has _NON_FAILING_PYTEST_EXIT_CODES = (0, 5), and pytest exit 5 means "no tests collected". The aggregation at cli.py:481-486:

if (
    exit_code not in _NON_FAILING_PYTEST_EXIT_CODES   # exit 5 -> False, short-circuits
    and not group.optional
    and overall_exit == 0
):

The not group.optional guard is never reached for exit 5, so a non-optional group that collects nothing folds in as a pass. That is precisely what unit-workers did. tests/rig/ is untouched by this PR, so the next marker typo, renamed marker, or moved directory goes green the same way.

Worth knowing: the rig already has a guard built for exactly this. _coverage_attesting_groups() (cli.py:664) excludes empty groups from attesting coverage, with the comment "a broken marker expression would otherwise report OK with zero tests run". It never fired here only because it applies to groups named in critical_paths.yaml covered_by, and unit-workers is in none of them.

Cheapest close: add unit-workers to a critical path's covered_by so the existing gate does its job. Note a blanket _NON_FAILING_PYTEST_EXIT_CODES = (0,) is not safe — hurl groups synthesize exit 5 at cli.py:897, and --marker/--paths overrides legitimately zero-collect.

Happy for this to be a follow-up ticket if you'd rather keep the PR scoped, but as it stands UN-3636 fixes the instance and leaves the class open.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch on the class-level gap. The fix lives in tests/rig/ (exit-5 handling), which this PR deliberately does not touch, and as you note a blanket (0,) is unsafe given hurl’s synthesized exit 5 and legitimate marker/path zero-collects. Taking your offer to track it as a follow-up rather than widen scope — will file a ticket for a rig-level empty-collect guard on non-optional groups.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Decided to close the class here rather than defer. 2a1acc63 adds a runtime gate: a non-optional pytest group that collects zero tests (exit 5) now fails overall_exit instead of folding in green. Exemptions match the legit zero-collects you called out — optional groups, hurl (its synthesized exit 5 = "no files"), and dev runs with a --marker/--paths override. So _NON_FAILING_PYTEST_EXIT_CODES stays (0, 5) for those; the new guard only fires for the misconfiguration case. Two rig self-tests added (test_empty_nonoptional_group_fails_build, test_empty_group_with_marker_override_does_not_fail).

Comment thread tests/groups.yaml Outdated
Comment thread workers/tests/test_plugin_migration_regression.py Outdated
for c in mock_plugin_get.call_args_list
if c.args and c.args[0] == "highlight-data"
]
assert highlight_fetches == []

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit, but on-theme: this assertion stops asserting if the call style ever changes.

c.args and c.args[0] == "highlight-data" only matches positional calls. legacy_executor.py:1394 does ExecutorPluginLoader.get("highlight-data") today, so it works. But if that ever becomes get(name="highlight-data"), c.args is empty, highlight_fetches is [], and assert highlight_fetches == [] passes vacuously. A test that silently stops testing is the same failure class this PR exists to fix.

assert not [
    c
    for c in mock_plugin_get.call_args_list
    if "highlight-data" in c.args or c.kwargs.get("name") == "highlight-data"
]

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in f66b9db — assertion now matches "highlight-data" in c.args or c.kwargs.get("name") == "highlight-data", so a kwarg-style call cannot pass it vacuously.

Comment thread workers/tests/conftest.py
load_dotenv(_env_test)

# Worker Celery apps build a Postgres result backend from DB_*/CELERY_BACKEND_DB_*.
# Strip these before any app is imported so tests don't reach (or leak) a live DB

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit / maintainability: the root conftest does the exact opposite of this block, four lines at a time.

workers/conftest.py:15-18 (which also covers shared/tests):

os.environ.setdefault("DB_HOST", "localhost")
os.environ.setdefault("DB_USER", "test")
os.environ.setdefault("DB_PASSWORD", "test")
os.environ.setdefault("DB_NAME", "testdb")

Two adjacent conftests with opposing intent on the same four vars, resolving correctly only because pytest loads the root one first.

To be clear, the pop is the right mechanism — keep it. It's the only thing that neutralises an ambient exported DB_HOST (which setdefault would happily leave pointing at a live DB, and the rig copies the ambient env into every group subprocess at tests/rig/cli.py:83), and the only thing covering CELERY_BACKEND_DB_*, which the root conftest never sets and worker_config.py:129-152 checks first.

But those four setdefaults are now dead weight during the group run, and the next reader will reasonably conclude a DB is configured. Worth dropping them in addition to this pop (never instead of), or at minimum cross-referencing between the two files.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kept the pop and cross-referenced both conftests (f66b9db). One correction: those setdefaults are not dead during the group run — the pop only covers workers/tests/, so shared/tests/ (no local conftest) still relies on them. Dropping them would break shared/tests, so I left them and added the cross-reference instead.

chandrasekharan-zipstack and others added 2 commits July 14, 2026 18:58
…tions

- Replace the log_component replica (copied tasks.py if/elif, drifted so the
  ide_index case asserted the opposite of production) with tests that drive the
  real execute_extraction, covering the two special-cased branches.
- Match the highlight-plugin assertion on positional or kwarg calls so it can't
  pass vacuously if the call style changes.
- Reword the unit-workers marker note: integration/slow worker tests are
  currently unrouted, not run "elsewhere".
- Cross-reference the two workers conftests on the DB_* env they set vs strip.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019EN8hh518CbCVMP3BHTVmG
…thing

A zero-collect group returns pytest exit 5, which the rig treats as
non-failing — so a broken marker or moved path silently reported green
(the very way unit-workers stayed dormant). Gate on it: a non-optional
pytest group that collects zero tests now fails the overall exit.

Legit zero-collects are exempt: optional groups, hurl (its exit 5 means
"no files"), and dev runs with a --marker/--paths override.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019EN8hh518CbCVMP3BHTVmG
@sonarqubecloud

Copy link
Copy Markdown

@github-actions

Copy link
Copy Markdown
Contributor

Unstract test results

Per-group results

Status Group Tier Passed Failed Errors Skipped Duration (s)
e2e-login e2e 2 0 0 0 1.4
e2e-smoke e2e 2 0 0 0 1.0
integration-backend integration 74 0 0 27 48.4
integration-connectors integration 1 0 0 7 7.8
unit-backend unit 126 0 0 0 22.3
unit-connectors unit 63 0 0 0 10.0
unit-core unit 27 0 0 0 1.3
unit-platform-service unit 15 0 0 0 2.7
unit-rig unit 71 0 0 0 4.3
unit-sdk1 unit 435 0 0 0 26.1
unit-workers unit 723 0 0 0 48.2
TOTAL 1539 0 0 34 173.7

Critical paths

⚠️ Critical paths not yet covered

  • workflow-create-execute — Create a workflow, configure source+destination, execute, poll, fetch result. (declared coverage: e2e-workflow)
  • api-deployment-run — Deploy a workflow as an API, POST a document, receive structured JSON. (declared coverage: e2e-api-deployment)
  • prompt-studio-fetch-response — Prompt Studio: create project, add prompt, run single-pass, get response. (declared coverage: e2e-prompt-studio)
  • pipeline-etl-execute — Run an ETL pipeline from source connector to destination. (declared coverage: no groups declared)
  • usage-token-tracking — Per-execution token usage is recorded and retrievable. (declared coverage: no groups declared)
  • workflow-execution-fan-out — Multi-file workflow execution fans out to file-processing workers and rejoins. (declared coverage: no groups declared)
  • callback-result-delivery — Async results are posted back via the callback worker. (declared coverage: no groups declared)
✅ Covered critical paths
  • auth-login — covered by e2e-login
  • adapter-register-llm — covered by integration-backend
  • workflow-author — covered by integration-backend
  • api-deployment-provision — covered by integration-backend
  • api-deployment-auth — covered by integration-backend
  • prompt-studio-author — covered by integration-backend
  • connector-register-test — covered by integration-backend
  • usage-aggregate-read — covered by integration-backend

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.

2 participants