Skip to content

test: harden offline coverage, coverage gate, and nightly integration - #39

Merged
robertoecf merged 2 commits into
mainfrom
test/harden-reliability
Aug 9, 2026
Merged

test: harden offline coverage, coverage gate, and nightly integration#39
robertoecf merged 2 commits into
mainfrom
test/harden-reliability

Conversation

@robertoecf

@robertoecf robertoecf commented Aug 4, 2026

Copy link
Copy Markdown
Owner

Summary

  • Add offline unit/API coverage for previously thin surfaces: HTTP 429 retries, rate-limit helpers/handler, BCB PTAX/Focus, IBGE, CVM companies/financials, Tesouro bonds, B3 quotes (mocked yfinance), thin REST smoke, and CLI smoke.
  • Wire CI coverage on the Python 3.12 leg (--cov-fail-under=60) and a scheduled nightly pytest -m integration workflow (plus workflow_dispatch).
  • Hygiene: AuthError assertion, chart-explorer JS asserts trimmed to high-signal invariants, docs/guardrails aligned with “integration is nightly, not default CI”.

Test plan

  • Local: ruff format --check, ruff check, mypy src/findata, pytest tests/ -q340 passed, 16 integration deselected
  • Local coverage: pytest --cov=findata --cov-fail-under=60~68%
  • CI matrix 3.11/3.12/3.13 green on this PR
  • Optional: Actions → “Nightly integration” → Run workflow

Made with Cursor

Summary by CodeRabbit

  • Tests

    • Expanded automated coverage for data sources, API routes, CLI commands, authentication, retries, rate limiting, and financial data parsing.
    • Added offline smoke tests with mocked external services for more consistent validation.
    • Added checks for chart explorer limits and request timeouts.
  • Documentation

    • Updated contribution guidance and changelog with the latest testing and integration workflow details.
  • Chores

    • Added scheduled and manual integration test runs.
    • Enforced a minimum 60% coverage threshold in CI.

Close reliability gaps for previously thin sources and production paths
(429 retries, rate limits, CLI smoke) while keeping live API checks on a
scheduled workflow instead of default PR CI.

Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 86800afd-0760-4514-8d22-090ab745450f

📥 Commits

Reviewing files that changed from the base of the PR and between 9cbecd6 and 1bb170b.

📒 Files selected for processing (2)
  • pyproject.toml
  • tests/test_mcp_surface.py

📝 Walkthrough

Walkthrough

The pull request expands mocked coverage for data sources, API routes, CLI commands, retries, authentication, rate limiting, and MCP initialization. CI adds a 60% Python 3.12 coverage gate and a scheduled or manual integration workflow.

Changes

Test hardening and CI

Layer / File(s) Summary
Test execution and coverage controls
.github/workflows/ci.yml, .github/workflows/integration.yml, pyproject.toml, CHANGELOG.md, CONTRIBUTING.md, scripts/git/guardrails.sh, tests/conftest.py
CI adds coverage enforcement for Python 3.12. A scheduled or manually triggered workflow runs integration tests and uploads failure logs. Test execution documentation reflects this split.
Source and API validation
tests/test_bcb_ptax_focus.py, tests/test_ibge.py, tests/test_tesouro_bonds.py, tests/test_cvm_companies_financials.py, tests/test_api_sources_smoke.py
Mocked tests cover source requests, parsing, filtering, normalization, pagination, historical data, and API responses for BCB, IBGE, Tesouro, and CVM data.
Client and policy validation
tests/test_b3_quotes.py, tests/test_http_client.py, tests/test_auth.py, tests/test_limits.py
Tests cover deterministic B3 quote and history mapping, HTTP 429 retries, specific authentication errors, and rate-limit behavior.
CLI, asset, and MCP validation
tests/test_cli.py, tests/test_api.py, pyproject.toml, tests/test_mcp_surface.py
Smoke tests cover CLI commands, chart asset constants, and MCP initialization before route mounting. The project constrains the mcp version used with fastapi-mcp.

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

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 1.92% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main changes: stronger offline coverage, a coverage gate, and nightly integration testing.
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 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch test/harden-reliability

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.

Actionable comments posted: 1

🤖 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.

Inline comments:
In @.github/workflows/integration.yml:
- Around line 30-33: Update the integration test workflow step running `pytest
-m integration` to preserve pytest’s nonzero exit status through the `tee`
pipeline by enabling `pipefail` or explicitly checking the pytest result.
Broaden the `Upload failure log` condition to also run when the job is canceled,
using the appropriate `failure()`/`cancelled()` handling alongside
`steps.integration-tests.outcome == 'failure'`.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f3946044-d109-48dc-8c07-a99f996f0448

📥 Commits

Reviewing files that changed from the base of the PR and between f8a932b and 9cbecd6.

📒 Files selected for processing (18)
  • .github/workflows/ci.yml
  • .github/workflows/integration.yml
  • CHANGELOG.md
  • CONTRIBUTING.md
  • pyproject.toml
  • scripts/git/guardrails.sh
  • tests/conftest.py
  • tests/test_api.py
  • tests/test_api_sources_smoke.py
  • tests/test_auth.py
  • tests/test_b3_quotes.py
  • tests/test_bcb_ptax_focus.py
  • tests/test_cli.py
  • tests/test_cvm_companies_financials.py
  • tests/test_http_client.py
  • tests/test_ibge.py
  • tests/test_limits.py
  • tests/test_tesouro_bonds.py
💤 Files with no reviewable changes (2)
  • tests/test_api.py
  • tests/conftest.py

Comment on lines +30 to +33
run: pytest -m integration -v 2>&1 | tee pytest-integration.log

- name: Upload failure log
if: steps.integration-tests.outcome == 'failure'

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files =="
git ls-files | rg '(^|/)(integration\.yml|.*workflow.*\.ya?ml|README|.*\.md)$' || true

echo
echo "== workflow excerpt =="
if [ -f .github/workflows/integration.yml ]; then
  nl -ba .github/workflows/integration.yml | sed -n '1,100p'
fi

echo
echo "== search for related workflows/pytest logs =="
rg -n "Run integration tests|Upload failure log|pytest-integration\.log|steps\.integration-tests\.outcome|failure\(\)|set -o pipefail|pytest -m integration" .github/workflows . || true

echo
echo "== deterministic pipeline/status probes =="
python3 - <<'PY'
import subprocess, shlex, tempfile, os

cases = [
    ("normal_exit", "echo ok | tee /tmp/pytest-integration.log"),
    ("pytest_exit_pipefail_missing", "false | true"),
    ("pytest_exit_pipefail_set", "set -o pipefail; false | true"),
]
original = os.environ.get("SHELL")
os.environ["SHELL"] = "/bin/bash"
for name, cmd in cases:
    rc = subprocess.run(["/bin/bash", "-c", cmd], text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    print(f"{name}: cmd={cmd!r} returncode={rc.returncode} stdout={rc.stdout.strip()!r} stderr={rc.stderr.strip()!r}")
os.environ["SHELL"] = original or ""

from pathlib import Path
if Path("/tmp/pytest-integration.log").exists():
    print("tmp log contains:", Path("/tmp/pytest-integration.log").read_text().strip())
PY

echo
echo "== bash status docs excerpt from local bash if available =="
if command -v bash >/dev/null 2>&1; then
  bash --version | head -1
  bash -c 'false | true; echo pipe=$?'
  bash -c 'set -o pipefail; false | true; echo pipefail=$?'
fi

Repository: robertoecf/OpenFinData

Length of output: 694


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== workflow excerpt =="
if [ -f .github/workflows/integration.yml ]; then
  sed -n '1,120p' .github/workflows/integration.yml
fi

echo
echo "== search for related workflows/pytest logs =="
rg -n "Run integration tests|Upload failure log|pytest-integration\.log|steps\.integration-tests\.outcome|failure\(\)|set -o pipefail|pytest -m integration" .github/workflows . || true

echo
echo "== deterministic pipeline/status probes =="
python3 - <<'PY'
import subprocess, os

cases = {
    "normal_exit": "echo ok | tee /tmp/pytest-integration.log",
    "pytest_exit_pipefail_missing": "false | true",
    "pytest_exit_pipefail_set": "set -o pipefail; false | true",
}
for name, cmd in cases.items():
    rc = subprocess.run(["/bin/bash", "-c", cmd], text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    print(f"{name}: cmd={cmd!r} returncode={rc.returncode} stdout={rc.stdout.strip()!r} stderr={rc.stderr.strip()!r}")
PY

echo
echo "== bash status probes =="
bash -c 'false | true; echo pipe=$?'
bash -c 'set -o pipefail; false | true; echo pipefail=$?'

Repository: robertoecf/OpenFinData

Length of output: 2263


Preserve pytest failures before uploading the failure log.

The run command exits with tee’s status, so a failed pytest can make the step succeed without pipefail. Add Failure() or check() to the upload condition when the job can be canceled, because steps.integration-tests.outcome == 'failure' can have no value if the job is canceled.

🤖 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 @.github/workflows/integration.yml around lines 30 - 33, Update the
integration test workflow step running `pytest -m integration` to preserve
pytest’s nonzero exit status through the `tee` pipeline by enabling `pipefail`
or explicitly checking the pytest result. Broaden the `Upload failure log`
condition to also run when the job is canceled, using the appropriate
`failure()`/`cancelled()` handling alongside `steps.integration-tests.outcome ==
'failure'`.

Fresh CI installs pulled mcp 2.0, whose Server() API dropped the
description arg that fastapi-mcp still passes, leaving /mcp unmounted.

Co-authored-by: Cursor <cursoragent@cursor.com>
@robertoecf
robertoecf merged commit 3f17e03 into main Aug 9, 2026
6 of 7 checks passed
@robertoecf
robertoecf deleted the test/harden-reliability branch August 9, 2026 22:00
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