e8d2f76466
CI / push-validation (pull_request) Successful in 45s
CI / helm (pull_request) Successful in 57s
CI / build (pull_request) Successful in 1m8s
CI / lint (pull_request) Successful in 1m31s
CI / tdd_quality_gate (pull_request) Failing after 1m26s
CI / quality (pull_request) Successful in 1m30s
CI / typecheck (pull_request) Successful in 1m43s
CI / security (pull_request) Successful in 1m42s
CI / e2e_tests (pull_request) Failing after 4m10s
CI / integration_tests (pull_request) Successful in 5m2s
CI / unit_tests (pull_request) Successful in 6m6s
CI / docker (pull_request) Successful in 1m32s
CI / coverage (pull_request) Successful in 12m12s
CI / status-check (push) Blocked by required conditions
CI / status-check (pull_request) Failing after 3s
CI / tdd_quality_gate (push) Has been skipped
CI / benchmark-regression (push) Failing after 1m8s
CI / build (push) Successful in 1m2s
CI / lint (push) Successful in 1m16s
CI / helm (push) Successful in 45s
CI / push-validation (push) Successful in 45s
CI / quality (push) Successful in 1m37s
CI / typecheck (push) Successful in 2m1s
CI / security (push) Successful in 2m1s
CI / integration_tests (push) Successful in 3m34s
CI / unit_tests (push) Successful in 5m14s
CI / docker (push) Successful in 1m37s
CI / coverage (push) Failing after 19m17s
CI / benchmark-publish (push) Successful in 1h20m43s
CI / e2e_tests (push) Successful in 4m13s
Add an automated quality gate that enforces TDD bug fix workflow rules on pull requests. The gate parses PR descriptions for bug-closing keywords (Closes/Fixes/Resolves #N, ISSUES CLOSED: #N), searches the codebase for corresponding TDD tests tagged @tdd_bug_N, and verifies that @tdd_expected_fail tags have been removed. Key components: - scripts/tdd_quality_gate.py: Main quality gate script with PR description parsing, TDD test discovery, and tag removal verification. All public functions validate arguments fail-fast and are statically typed. - noxfile.py: New tdd_quality_gate session that reads PR_DESCRIPTION from the environment and runs the quality gate script. - .forgejo/workflows/ci.yml: New tdd_quality_gate CI job that runs only on pull_request events, passing the PR body as PR_DESCRIPTION. - features/tdd_quality_gate.feature: 46 Behave scenarios covering PR parsing, TDD test search, tag removal verification, full gate logic, robot diff handling, edge cases, argument validation, bool guards, co-located bug false-positive guard, and main() CLI entry point. - features/steps/tdd_quality_gate_steps.py: Step definitions for all Behave scenarios using temporary directories for isolation. - robot/tdd_quality_gate.robot: 15 Robot Framework integration tests exercising the gate end-to-end via a helper subprocess. - robot/helper_tdd_quality_gate.py: Helper script for Robot tests with sentinel-based sub-commands. Review-round fixes applied: - check_expected_fail_removed now uses _contains_tag_token for word-boundary matching (avoids false positives on partial tag names) - Diff expected-fail removal detection tracks flags at file level instead of per-hunk (fixes false negatives when tags span hunks) - parse_bug_refs filters out issue number zero - Redundant double error reporting eliminated (file-level check short-circuits the diff-level check) - run_quality_gate returns (errors, bug_refs) tuple to avoid redundant re-parsing in main() - Regex compilation cached via functools.lru_cache - Nox session no longer installs the full project (stdlib only) - CI checkout uses fetch-depth: 0 for reliable merge-base resolution Review-round 2 fixes applied: - _diff_has_expected_fail_removal_for_bug now requires the removed line to contain both the expected-fail tag and the specific bug tag (fixes false positives when two bugs share the same test file) - check_expected_fail_removed error messages use the correct tag prefix per file type (@tdd_bug_N for .feature, tdd_bug_N for .robot) - bool values rejected by bug-number validation guards in find_tdd_tests, check_expected_fail_removed, and _diff_has_expected_fail_removal_for_bug - File-read error handling catches UnicodeDecodeError alongside OSError (root-safe unreadable-file handling via invalid-UTF-8 test fixture) - Temp directory cleanup added to after_scenario hook in environment.py - 8 new Behave scenarios: bool type guards (2), co-located bug false-positive regression (1), run_quality_gate argument validation (3), and main() CLI entry point exit codes (2) Review-round 3 fixes applied: - Synthetic PR diff helper (_default_pr_diff_for_bug_refs) now auto-detects .robot vs .feature file type from the temp search tree and generates the matching diff format (fixes under-tested robot-format diff code path in multi-bug integration scenarios) - check_expected_fail_removed test step now filters files by bug tag via find_tdd_tests before checking (matches production path in run_quality_gate) - after_scenario temp directory cleanup no longer sets context.temp_dir = None (fixes cleanup conflict with cli_init_yes_flag_steps.py cleanup functions that run after hooks) - 2 new Behave scenarios: multi-line PR description parsing, and non-string pr_diff type guard for run_quality_gate ISSUES CLOSED: #629
150 lines
7.0 KiB
Plaintext
150 lines
7.0 KiB
Plaintext
*** Settings ***
|
|
Documentation Integration tests for the TDD quality gate script.
|
|
...
|
|
... Exercises ``scripts/tdd_quality_gate.py`` end-to-end by
|
|
... invoking it as a subprocess with various PR_DESCRIPTION
|
|
... values and temporary file trees, then verifying exit codes
|
|
... and output messages.
|
|
...
|
|
... See CONTRIBUTING.md > Bug Fix Workflow for the full
|
|
... specification.
|
|
Resource ${CURDIR}/common.resource
|
|
Suite Setup Setup Test Environment
|
|
Suite Teardown Cleanup Test Environment
|
|
|
|
*** Variables ***
|
|
${HELPER} ${CURDIR}/helper_tdd_quality_gate.py
|
|
|
|
*** Test Cases ***
|
|
# ===========================================================================
|
|
# PR description parsing
|
|
# ===========================================================================
|
|
|
|
Parse Single Fixes Reference
|
|
[Documentation] Verify the script extracts a single Fixes #N reference
|
|
[Tags] ci quality tdd
|
|
${result}= Run Process ${PYTHON} ${HELPER} parse_fixes_single
|
|
... cwd=${WORKSPACE}
|
|
Should Be Equal As Integers ${result.rc} 0 msg=${result.stderr}
|
|
Should Contain ${result.stdout} parse-fixes-single-ok
|
|
|
|
Parse Multiple Mixed References
|
|
[Documentation] Verify the script extracts multiple closing keywords
|
|
[Tags] ci quality tdd
|
|
${result}= Run Process ${PYTHON} ${HELPER} parse_mixed_refs
|
|
... cwd=${WORKSPACE}
|
|
Should Be Equal As Integers ${result.rc} 0 msg=${result.stderr}
|
|
Should Contain ${result.stdout} parse-mixed-refs-ok
|
|
|
|
Parse Issues Closed Block
|
|
[Documentation] Verify the script extracts ISSUES CLOSED: #N references
|
|
[Tags] ci quality tdd
|
|
${result}= Run Process ${PYTHON} ${HELPER} parse_issues_closed
|
|
... cwd=${WORKSPACE}
|
|
Should Be Equal As Integers ${result.rc} 0 msg=${result.stderr}
|
|
Should Contain ${result.stdout} parse-issues-closed-ok
|
|
|
|
Parse Non Closing Words
|
|
[Documentation] Verify parser ignores embedded keyword substrings
|
|
[Tags] ci quality tdd
|
|
${result}= Run Process ${PYTHON} ${HELPER} parse_non_closing_words
|
|
... cwd=${WORKSPACE}
|
|
Should Be Equal As Integers ${result.rc} 0 msg=${result.stderr}
|
|
Should Contain ${result.stdout} parse-non-closing-words-ok
|
|
|
|
No Bug References Passes Trivially
|
|
[Documentation] Verify the quality gate passes when no bug refs in PR
|
|
[Tags] ci quality tdd
|
|
${result}= Run Process ${PYTHON} ${HELPER} no_bug_refs_pass
|
|
... cwd=${WORKSPACE}
|
|
Should Be Equal As Integers ${result.rc} 0 msg=${result.stderr}
|
|
Should Contain ${result.stdout} no-bug-refs-pass-ok
|
|
|
|
# ===========================================================================
|
|
# TDD test search and tag verification
|
|
# ===========================================================================
|
|
|
|
Find TDD Test In Feature File
|
|
[Documentation] Verify the script finds @tdd_bug_N in .feature files
|
|
[Tags] ci quality tdd
|
|
${result}= Run Process ${PYTHON} ${HELPER} find_feature_test
|
|
... cwd=${WORKSPACE}
|
|
Should Be Equal As Integers ${result.rc} 0 msg=${result.stderr}
|
|
Should Contain ${result.stdout} find-feature-test-ok
|
|
|
|
Find TDD Test In Robot File
|
|
[Documentation] Verify the script finds tdd_bug_N in .robot files
|
|
[Tags] ci quality tdd
|
|
${result}= Run Process ${PYTHON} ${HELPER} find_robot_test
|
|
... cwd=${WORKSPACE}
|
|
Should Be Equal As Integers ${result.rc} 0 msg=${result.stderr}
|
|
Should Contain ${result.stdout} find-robot-test-ok
|
|
|
|
Find TDD Test Uses Exact Tag Match
|
|
[Documentation] Verify partial tags are not matched as exact bug tags
|
|
[Tags] ci quality tdd
|
|
${result}= Run Process ${PYTHON} ${HELPER} find_exact_tag_match
|
|
... cwd=${WORKSPACE}
|
|
Should Be Equal As Integers ${result.rc} 0 msg=${result.stderr}
|
|
Should Contain ${result.stdout} find-exact-tag-match-ok
|
|
|
|
No TDD Test Found Fails Gate
|
|
[Documentation] Verify the gate fails when no TDD test exists
|
|
[Tags] ci quality tdd
|
|
${result}= Run Process ${PYTHON} ${HELPER} no_tdd_test_fails
|
|
... cwd=${WORKSPACE}
|
|
Should Be Equal As Integers ${result.rc} 0 msg=${result.stderr}
|
|
Should Contain ${result.stdout} no-tdd-test-fails-ok
|
|
|
|
Expected Fail Tag Still Present Fails Gate
|
|
[Documentation] Verify the gate fails when @tdd_expected_fail is still present
|
|
[Tags] ci quality tdd
|
|
${result}= Run Process ${PYTHON} ${HELPER} expected_fail_present
|
|
... cwd=${WORKSPACE}
|
|
Should Be Equal As Integers ${result.rc} 0 msg=${result.stderr}
|
|
Should Contain ${result.stdout} expected-fail-present-ok
|
|
|
|
Expected Fail Tag Removed Passes Gate
|
|
[Documentation] Verify the gate passes when @tdd_expected_fail is removed
|
|
[Tags] ci quality tdd
|
|
${result}= Run Process ${PYTHON} ${HELPER} expected_fail_removed
|
|
... cwd=${WORKSPACE}
|
|
Should Be Equal As Integers ${result.rc} 0 msg=${result.stderr}
|
|
Should Contain ${result.stdout} expected-fail-removed-ok
|
|
|
|
# ===========================================================================
|
|
# Full quality gate integration
|
|
# ===========================================================================
|
|
|
|
Full Gate Multiple Bugs Mixed Results
|
|
[Documentation] Verify the gate handles multiple bugs with mixed outcomes
|
|
[Tags] ci quality tdd
|
|
${result}= Run Process ${PYTHON} ${HELPER} multi_bug_mixed
|
|
... cwd=${WORKSPACE}
|
|
Should Be Equal As Integers ${result.rc} 0 msg=${result.stderr}
|
|
Should Contain ${result.stdout} multi-bug-mixed-ok
|
|
|
|
Full Gate All Clean Passes
|
|
[Documentation] Verify the gate passes when all referenced bugs have clean tests
|
|
[Tags] ci quality tdd
|
|
${result}= Run Process ${PYTHON} ${HELPER} all_clean_passes
|
|
... cwd=${WORKSPACE}
|
|
Should Be Equal As Integers ${result.rc} 0 msg=${result.stderr}
|
|
Should Contain ${result.stdout} all-clean-passes-ok
|
|
|
|
TDD Tests In Both Behave And Robot
|
|
[Documentation] Verify the gate checks tests in both .feature and .robot files
|
|
[Tags] ci quality tdd
|
|
${result}= Run Process ${PYTHON} ${HELPER} both_behave_and_robot
|
|
... cwd=${WORKSPACE}
|
|
Should Be Equal As Integers ${result.rc} 0 msg=${result.stderr}
|
|
Should Contain ${result.stdout} both-behave-and-robot-ok
|
|
|
|
Diff Removal Is Required
|
|
[Documentation] Verify the gate fails when PR diff has no expected-fail removal
|
|
[Tags] ci quality tdd
|
|
${result}= Run Process ${PYTHON} ${HELPER} diff_removal_required
|
|
... cwd=${WORKSPACE}
|
|
Should Be Equal As Integers ${result.rc} 0 msg=${result.stderr}
|
|
Should Contain ${result.stdout} diff-removal-required-ok
|