Skip to content

refactor(e2e): rename test rig — specs→metrics, e2e_lib→lib, drop e2e branding#1507

Merged
ktursunov merged 1 commit into
constructorfabric:mainfrom
ktursunov:metrics-rename
Jun 26, 2026
Merged

refactor(e2e): rename test rig — specs→metrics, e2e_lib→lib, drop e2e branding#1507
ktursunov merged 1 commit into
constructorfabric:mainfrom
ktursunov:metrics-rename

Conversation

@ktursunov

@ktursunov ktursunov commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

What

Rename the bronze-to-API test rig so its names reflect what the pieces actually
are. The per-metric *.test.yaml files are metric-smoke tests, not broad
end-to-end scenarios. The harness genuinely is end-to-end (bronze → dbt →
ClickHouse gold views → analytics-api → assertions), so it — and the CI workflow
— keep their e2e names; only the misnamed parts change.

Pure rename/refactor — no behavior change.

Changes

  • src/ingestion/tests/e2e/specs/metrics/ (17 metric tests + schemas/ + templates/)
  • e2e_lib/lib/ (framework package; all imports, the Docker dep-stub, compose refs)
  • pytest fn test_e2e_metric_smoketest_metric_smoke
  • skill .claude/skills/metric-e2e-testmetric-test (slash command /metric-test)
  • moved meta/test_session_smoke.pyapi/ (stack/API smoke; pytest testpaths += api)
  • CI workflow e2e-bronze-to-api.yml: dropped a redundant data-plane image
    pre-pull (docker compose run already pulls them via depends_on). Workflow +
    job names are unchanged
    ("E2E — Bronze to API" / "Run E2E suite"), so the
    existing required status check keeps reporting.

README, the live domain specs under docs/domain/bronze-to-api-e2e/, and the
skill were updated to match.

Verification

  • python -m py_compile passes across the renamed package
  • discover_tests(metrics/) finds all 17 tests; schema lookup resolves via the
    updated parent.name == "metrics"
  • The full e2e suite ("Run E2E suite") runs green in CI
  • Rebased on the latest upstream/main

@ktursunov
ktursunov requested a review from a team as a code owner June 26, 2026 14:07
@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@ktursunov, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 22 minutes and 54 seconds. Learn how PR review limits work.

To continue reviewing without waiting, enable usage-based billing in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4a24de02-f879-4c5d-8843-e333bab9f14b

📥 Commits

Reviewing files that changed from the base of the PR and between 28491c9 and e2faae4.

📒 Files selected for processing (76)
  • .claude/skills/metric-test/SKILL.md
  • .github/workflows/e2e-bronze-to-api.yml
  • cypilot/.core/skills/connector/workflows/create.md
  • cypilot/.core/skills/connector/workflows/validate.md
  • docs/domain/bronze-to-api-e2e/specs/DECOMPOSITION.md
  • docs/domain/bronze-to-api-e2e/specs/DESIGN.md
  • docs/domain/bronze-to-api-e2e/specs/feature-csv-rig/FEATURE.md
  • docs/domain/bronze-to-api-e2e/specs/feature-yaml-rig/FEATURE.md
  • src/ingestion/tests/e2e/README.md
  • src/ingestion/tests/e2e/api/__init__.py
  • src/ingestion/tests/e2e/api/test_session_smoke.py
  • src/ingestion/tests/e2e/compose/Dockerfile.runner
  • src/ingestion/tests/e2e/compose/docker-compose.runner.yml
  • src/ingestion/tests/e2e/compose/docker-compose.yml
  • src/ingestion/tests/e2e/conftest.py
  • src/ingestion/tests/e2e/e2e_lib/__init__.py
  • src/ingestion/tests/e2e/lib/__init__.py
  • src/ingestion/tests/e2e/lib/analytics_api.py
  • src/ingestion/tests/e2e/lib/ch_seeder.py
  • src/ingestion/tests/e2e/lib/clickhouse.py
  • src/ingestion/tests/e2e/lib/compose.py
  • src/ingestion/tests/e2e/lib/config.py
  • src/ingestion/tests/e2e/lib/dbt_runner.py
  • src/ingestion/tests/e2e/lib/enrich.py
  • src/ingestion/tests/e2e/lib/expect_engine.py
  • src/ingestion/tests/e2e/lib/fixture_loader.py
  • src/ingestion/tests/e2e/lib/mariadb.py
  • src/ingestion/tests/e2e/lib/metric_seed.py
  • src/ingestion/tests/e2e/lib/migration_applier.py
  • src/ingestion/tests/e2e/lib/ref_resolver.py
  • src/ingestion/tests/e2e/lib/schema_validator.py
  • src/ingestion/tests/e2e/lib/worker.py
  • src/ingestion/tests/e2e/meta/test_dbt_runner.py
  • src/ingestion/tests/e2e/meta/test_expect_engine.py
  • src/ingestion/tests/e2e/meta/test_ref_resolver.py
  • src/ingestion/tests/e2e/metrics/collab_active_days.test.yaml
  • src/ingestion/tests/e2e/metrics/collab_emails_read.test.yaml
  • src/ingestion/tests/e2e/metrics/collab_emails_received.test.yaml
  • src/ingestion/tests/e2e/metrics/collab_emails_sent.test.yaml
  • src/ingestion/tests/e2e/metrics/collab_files_engaged.test.yaml
  • src/ingestion/tests/e2e/metrics/collab_files_shared_external.test.yaml
  • src/ingestion/tests/e2e/metrics/collab_files_shared_internal.test.yaml
  • src/ingestion/tests/e2e/metrics/collab_meeting_free.test.yaml
  • src/ingestion/tests/e2e/metrics/collab_meeting_hours.test.yaml
  • src/ingestion/tests/e2e/metrics/collab_meetings_count.test.yaml
  • src/ingestion/tests/e2e/metrics/collab_teams_chats.test.yaml
  • src/ingestion/tests/e2e/metrics/collab_teams_meeting_hours.test.yaml
  • src/ingestion/tests/e2e/metrics/collab_teams_meetings.test.yaml
  • src/ingestion/tests/e2e/metrics/collab_zulip_chat.test.yaml
  • src/ingestion/tests/e2e/metrics/schemas/bronze_bamboohr.employees.yaml
  • src/ingestion/tests/e2e/metrics/schemas/bronze_jira.jira_fields.yaml
  • src/ingestion/tests/e2e/metrics/schemas/bronze_jira.jira_issue.yaml
  • src/ingestion/tests/e2e/metrics/schemas/bronze_jira.jira_issue_history.yaml
  • src/ingestion/tests/e2e/metrics/schemas/bronze_jira.jira_user.yaml
  • src/ingestion/tests/e2e/metrics/schemas/bronze_m365.email_activity.yaml
  • src/ingestion/tests/e2e/metrics/schemas/bronze_m365.onedrive_activity.yaml
  • src/ingestion/tests/e2e/metrics/schemas/bronze_m365.sharepoint_activity.yaml
  • src/ingestion/tests/e2e/metrics/schemas/bronze_m365.teams_activity.yaml
  • src/ingestion/tests/e2e/metrics/schemas/bronze_zoom.participants.yaml
  • src/ingestion/tests/e2e/metrics/schemas/bronze_zulip_proxy.messages.yaml
  • src/ingestion/tests/e2e/metrics/schemas/bronze_zulip_proxy.users.yaml
  • src/ingestion/tests/e2e/metrics/task_delivery_bugs_to_task_ratio_jira.test.yaml
  • src/ingestion/tests/e2e/metrics/task_delivery_due_date_compliance_jira.test.yaml
  • src/ingestion/tests/e2e/metrics/task_delivery_tasks_completed_jira.test.yaml
  • src/ingestion/tests/e2e/metrics/templates/jira_task.yaml
  • src/ingestion/tests/e2e/metrics/templates/m365_email.yaml
  • src/ingestion/tests/e2e/metrics/templates/m365_onedrive.yaml
  • src/ingestion/tests/e2e/metrics/templates/m365_sharepoint.yaml
  • src/ingestion/tests/e2e/metrics/templates/m365_teams.yaml
  • src/ingestion/tests/e2e/metrics/templates/people.yaml
  • src/ingestion/tests/e2e/metrics/templates/zoom.yaml
  • src/ingestion/tests/e2e/metrics/templates/zulip.yaml
  • src/ingestion/tests/e2e/metrics/test_fixtures.py
  • src/ingestion/tests/e2e/pyproject.toml
  • src/ingestion/tests/e2e/pytest.ini
  • src/ingestion/tests/e2e/seed/metrics.yaml
📝 Walkthrough

Walkthrough

The PR renames the metric-test skill and API workflow, switches E2E rig paths from specs/e2e_lib to metrics/lib, updates pytest discovery and runner configuration, and refreshes related documentation and smoke tests to match the new paths.

Changes

Metric test rig and helper package migration

Layer / File(s) Summary
Skill and workflow names
.claude/skills/metric-test/SKILL.md, .github/workflows/api-tests.yml, cypilot/.core/skills/connector/workflows/*, docs/domain/bronze-to-api-e2e/specs/DECOMPOSITION.md
The skill, workflow, and connector docs rename the fixture flow to metric-test and api-tests, and update the related CI references.
Metrics rig layout and discovery
docs/domain/bronze-to-api-e2e/specs/DESIGN.md, docs/domain/bronze-to-api-e2e/specs/feature-yaml-rig/FEATURE.md, src/ingestion/tests/e2e/{conftest.py,lib/fixture_loader.py,lib/schema_validator.py,metrics/test_fixtures.py,pytest.ini,api/test_session_smoke.py}
The YAML rig docs and pytest settings switch test authoring, discovery, schema lookup, and smoke-test generation from specs to metrics.
Lib package move
src/ingestion/tests/e2e/lib/*, src/ingestion/tests/e2e/{conftest.py,api/test_session_smoke.py,meta/test_*.py,compose/*,pyproject.toml,seed/metrics.yaml,README.md}, docs/domain/bronze-to-api-e2e/specs/{DECOMPOSITION.md,DESIGN.md,feature-csv-rig/FEATURE.md,feature-yaml-rig/FEATURE.md}
The helper package is moved to lib, and the helper modules, tests, compose files, and path references are updated to the new namespace.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • mitasovr
  • cyberantonz

Poem

A rabbit hops through YAML glade,
With lib burrows freshly made.
metric-test bells softly chime,
api-tests hop in perfect time.
🐇

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the refactor and the main renames: specs to metrics, e2e_lib to lib, and dropping e2e branding.
Docstring Coverage ✅ Passed Docstring coverage is 87.50% which is sufficient. The required threshold is 80.00%.
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
.claude/skills/metric-test/SKILL.md (1)

32-37: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Add language specifier to fenced code block.

The file layout code block is missing a language specifier. Add text or yaml to satisfy markdownlint MD040.

-```
+```text
 src/ingestion/tests/e2e/metrics/
   schemas/<db>.<table>.yaml      # one JSON schema per bronze table (all real columns)
   templates/<group>.yaml         # reusable records (people, m365_email, …)
   <name>.test.yaml               # ONE metric per file (discovered by the *.test.yaml suffix)

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude/skills/metric-test/SKILL.md around lines 32 - 37, The fenced file
layout block in SKILL.md is missing a language specifier, which triggers
markdownlint MD040. Update that code fence to use a valid specifier such as text
or yaml on the block containing the src/ingestion/tests/e2e/metrics layout,
keeping the content unchanged and ensuring the fence is consistently opened and
closed.


</details>

<!-- cr-comment:v1:76647d1b504ea232fef210b6 -->

_Source: Linters/SAST tools_

</blockquote></details>

</blockquote></details>

<details>
<summary>🤖 Prompt for all review comments with AI agents</summary>

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 @.claude/skills/metric-test/SKILL.md:

  • Around line 32-37: The fenced file layout block in SKILL.md is missing a
    language specifier, which triggers markdownlint MD040. Update that code fence to
    use a valid specifier such as text or yaml on the block containing the
    src/ingestion/tests/e2e/metrics layout, keeping the content unchanged and
    ensuring the fence is consistently opened and closed.

</details>

---

<details>
<summary>ℹ️ Review info</summary>

<details>
<summary>⚙️ Run configuration</summary>

**Configuration used**: defaults

**Review profile**: CHILL

**Plan**: Pro

**Run ID**: `59ee3974-6609-4b7a-bca3-9977bff3fcf9`

</details>

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 636f64d4e307905fd4d125bf43da9e6e3b15d72d and 28491c90338363cc72fa620800d9dc24adb0b0b1.

</details>

<details>
<summary>📒 Files selected for processing (76)</summary>

* `.claude/skills/metric-test/SKILL.md`
* `.github/workflows/api-tests.yml`
* `cypilot/.core/skills/connector/workflows/create.md`
* `cypilot/.core/skills/connector/workflows/validate.md`
* `docs/domain/bronze-to-api-e2e/specs/DECOMPOSITION.md`
* `docs/domain/bronze-to-api-e2e/specs/DESIGN.md`
* `docs/domain/bronze-to-api-e2e/specs/feature-csv-rig/FEATURE.md`
* `docs/domain/bronze-to-api-e2e/specs/feature-yaml-rig/FEATURE.md`
* `src/ingestion/tests/e2e/README.md`
* `src/ingestion/tests/e2e/api/__init__.py`
* `src/ingestion/tests/e2e/api/test_session_smoke.py`
* `src/ingestion/tests/e2e/compose/Dockerfile.runner`
* `src/ingestion/tests/e2e/compose/docker-compose.runner.yml`
* `src/ingestion/tests/e2e/compose/docker-compose.yml`
* `src/ingestion/tests/e2e/conftest.py`
* `src/ingestion/tests/e2e/e2e_lib/__init__.py`
* `src/ingestion/tests/e2e/lib/__init__.py`
* `src/ingestion/tests/e2e/lib/analytics_api.py`
* `src/ingestion/tests/e2e/lib/ch_seeder.py`
* `src/ingestion/tests/e2e/lib/clickhouse.py`
* `src/ingestion/tests/e2e/lib/compose.py`
* `src/ingestion/tests/e2e/lib/config.py`
* `src/ingestion/tests/e2e/lib/dbt_runner.py`
* `src/ingestion/tests/e2e/lib/enrich.py`
* `src/ingestion/tests/e2e/lib/expect_engine.py`
* `src/ingestion/tests/e2e/lib/fixture_loader.py`
* `src/ingestion/tests/e2e/lib/mariadb.py`
* `src/ingestion/tests/e2e/lib/metric_seed.py`
* `src/ingestion/tests/e2e/lib/migration_applier.py`
* `src/ingestion/tests/e2e/lib/ref_resolver.py`
* `src/ingestion/tests/e2e/lib/schema_validator.py`
* `src/ingestion/tests/e2e/lib/worker.py`
* `src/ingestion/tests/e2e/meta/test_dbt_runner.py`
* `src/ingestion/tests/e2e/meta/test_expect_engine.py`
* `src/ingestion/tests/e2e/meta/test_ref_resolver.py`
* `src/ingestion/tests/e2e/metrics/collab_active_days.test.yaml`
* `src/ingestion/tests/e2e/metrics/collab_emails_read.test.yaml`
* `src/ingestion/tests/e2e/metrics/collab_emails_received.test.yaml`
* `src/ingestion/tests/e2e/metrics/collab_emails_sent.test.yaml`
* `src/ingestion/tests/e2e/metrics/collab_files_engaged.test.yaml`
* `src/ingestion/tests/e2e/metrics/collab_files_shared_external.test.yaml`
* `src/ingestion/tests/e2e/metrics/collab_files_shared_internal.test.yaml`
* `src/ingestion/tests/e2e/metrics/collab_meeting_free.test.yaml`
* `src/ingestion/tests/e2e/metrics/collab_meeting_hours.test.yaml`
* `src/ingestion/tests/e2e/metrics/collab_meetings_count.test.yaml`
* `src/ingestion/tests/e2e/metrics/collab_teams_chats.test.yaml`
* `src/ingestion/tests/e2e/metrics/collab_teams_meeting_hours.test.yaml`
* `src/ingestion/tests/e2e/metrics/collab_teams_meetings.test.yaml`
* `src/ingestion/tests/e2e/metrics/collab_zulip_chat.test.yaml`
* `src/ingestion/tests/e2e/metrics/schemas/bronze_bamboohr.employees.yaml`
* `src/ingestion/tests/e2e/metrics/schemas/bronze_jira.jira_fields.yaml`
* `src/ingestion/tests/e2e/metrics/schemas/bronze_jira.jira_issue.yaml`
* `src/ingestion/tests/e2e/metrics/schemas/bronze_jira.jira_issue_history.yaml`
* `src/ingestion/tests/e2e/metrics/schemas/bronze_jira.jira_user.yaml`
* `src/ingestion/tests/e2e/metrics/schemas/bronze_m365.email_activity.yaml`
* `src/ingestion/tests/e2e/metrics/schemas/bronze_m365.onedrive_activity.yaml`
* `src/ingestion/tests/e2e/metrics/schemas/bronze_m365.sharepoint_activity.yaml`
* `src/ingestion/tests/e2e/metrics/schemas/bronze_m365.teams_activity.yaml`
* `src/ingestion/tests/e2e/metrics/schemas/bronze_zoom.participants.yaml`
* `src/ingestion/tests/e2e/metrics/schemas/bronze_zulip_proxy.messages.yaml`
* `src/ingestion/tests/e2e/metrics/schemas/bronze_zulip_proxy.users.yaml`
* `src/ingestion/tests/e2e/metrics/task_delivery_bugs_to_task_ratio_jira.test.yaml`
* `src/ingestion/tests/e2e/metrics/task_delivery_due_date_compliance_jira.test.yaml`
* `src/ingestion/tests/e2e/metrics/task_delivery_tasks_completed_jira.test.yaml`
* `src/ingestion/tests/e2e/metrics/templates/jira_task.yaml`
* `src/ingestion/tests/e2e/metrics/templates/m365_email.yaml`
* `src/ingestion/tests/e2e/metrics/templates/m365_onedrive.yaml`
* `src/ingestion/tests/e2e/metrics/templates/m365_sharepoint.yaml`
* `src/ingestion/tests/e2e/metrics/templates/m365_teams.yaml`
* `src/ingestion/tests/e2e/metrics/templates/people.yaml`
* `src/ingestion/tests/e2e/metrics/templates/zoom.yaml`
* `src/ingestion/tests/e2e/metrics/templates/zulip.yaml`
* `src/ingestion/tests/e2e/metrics/test_fixtures.py`
* `src/ingestion/tests/e2e/pyproject.toml`
* `src/ingestion/tests/e2e/pytest.ini`
* `src/ingestion/tests/e2e/seed/metrics.yaml`

</details>

<details>
<summary>💤 Files with no reviewable changes (1)</summary>

* src/ingestion/tests/e2e/e2e_lib/__init__.py

</details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

…e" branding

The per-metric *.test.yaml files under tests/e2e/ are metric-smoke tests, not
broad end-to-end scenarios: the harness is e2e, the specs are not. Rename to
reflect that. The e2e harness directory, ./e2e.sh, and the CI workflow keep
their e2e names (so the existing required status check keeps reporting).

- specs/ → metrics/ (17 metric tests + schemas/ + templates/)
- e2e_lib/ → lib/ (framework package; all imports, Docker dep-stub, compose refs)
- pytest fn test_e2e_metric_smoke → test_metric_smoke
- skill metric-e2e-test → metric-test (slash command /metric-test)
- move meta/test_session_smoke.py → api/ (stack/API smoke; pytest testpaths += api)
- CI workflow e2e-bronze-to-api.yml: drop the redundant data-plane image pre-pull
  (docker compose run pulls them via depends_on); workflow + job names unchanged

README, live domain specs, and the skill updated to match.

Signed-off-by: Konstantin Tursunov <Konstantin.Tursunov@constructor.tech>
@ktursunov
ktursunov merged commit 1f30bc5 into constructorfabric:main Jun 26, 2026
18 checks passed
mitasovr pushed a commit to mitasovr/insight that referenced this pull request Jun 29, 2026
…eline_now (RED)

Two things, after merging main (which renamed the rig specs/→metrics/,
e2e_lib/→lib/ in constructorfabric#1507):

1. Relocate the CRM fixtures from the now-orphaned specs/ into the renamed
   metrics/ tree (tests → metrics/, schemas → metrics/schemas/, template →
   metrics/templates/) so the refactored rig discovers them again.

2. crm_pipeline_now is now a TARGET-BEHAVIOR spec that asserts the intended
   "as of end_date" semantics and FAILS on purpose against the shipped backend
   (RED until the metric is made end-date-aware):
     - open as of end_date ⇔ is_closed = 0 OR close_date > end_date;
     - the period END moves the snapshot boundary; a deal closing after
       end_date is still pipeline, moving the end past its close drops it;
     - the period START does not affect the result;
     - a deal closed on/before end_date is excluded (closed metric).
   Currently RED because the gold view is date-less (is_closed flag) and
   analytics-api errors the per-query when a metric_date bound is supplied.
   The file header lists the three backend files to change to make it pass.

The other four CRM tests (kpis, chart_flow, bullet_quality, bullet_activity)
pass on the new layout; only crm_pipeline_now is intentionally failing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Roman Mitasov <Roman.Mitasov@constructor.tech>
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