Some checks failed
Coverage Phase 1 (70% Target) / test-coverage-70 (push) Has been cancelled
Coverage Phase 2 (85% Target) / test-coverage-85 (push) Has been cancelled
Cross-Node Transaction Testing / transaction-test (push) Has been cancelled
Deploy to Testnet / deploy-testnet (push) Has been cancelled
Integration Tests / test-service-integration (push) Has been cancelled
Multi-Node Stress Testing / stress-test (push) Has been cancelled
Python Tests / test-python (push) Has been cancelled
Security Scanning / security-scan (push) Has been cancelled
Documentation Validation / validate-docs (push) Has been cancelled
Documentation Validation / validate-policies-strict (push) Has been cancelled
CLI Tests / test-cli (push) Has been cancelled
Package Tests / Python package - aitbc-agent-sdk (push) Has been cancelled
Package Tests / Python package - aitbc-core (push) Has been cancelled
Package Tests / Python package - aitbc-crypto (push) Has been cancelled
Package Tests / Python package - aitbc-sdk (push) Has been cancelled
Package Tests / JavaScript package - aitbc-sdk-js (push) Has been cancelled
Package Tests / JavaScript package - aitbc-token (push) Has been cancelled
Smart Contract Tests / test-solidity (map[name:aitbc-contracts path:contracts]) (push) Has been cancelled
Smart Contract Tests / test-solidity (map[name:aitbc-token path:packages/solidity/aitbc-token]) (push) Has been cancelled
Smart Contract Tests / test-foundry (push) Has been cancelled
Smart Contract Tests / lint-solidity (push) Has been cancelled
Smart Contract Tests / deploy-contracts (push) Has been cancelled
- Updated CI workflows to track poetry.lock instead of requirements.txt - Removed check-requirements-sync.py step from python-tests.yml - Updated dependency_scanner.py default from requirements.txt to pyproject.toml - Replaced all print() with click.echo() in deploy_edge_node.py (CLI script) - Replaced print() with logger.warning() in zk_cache.py - Updated setup.py files to read dependencies from pyproject.toml via tomli - Removed
152 lines
5.5 KiB
Python
Executable File
152 lines
5.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
Quality Metrics Tracking System
|
|
Tracks bug escape rate, test flakiness, and code review coverage
|
|
"""
|
|
|
|
import json
|
|
import subprocess
|
|
import os
|
|
import click
|
|
from datetime import datetime
|
|
from pathlib import Path
|
|
from typing import Dict, Any
|
|
|
|
|
|
class QualityMetricsTracker:
|
|
"""Track and report quality metrics"""
|
|
|
|
def __init__(self, metrics_file: str = "/var/log/aitbc/quality_metrics.json"):
|
|
self.metrics_file = Path(metrics_file)
|
|
self.metrics = self._load_metrics()
|
|
|
|
def _load_metrics(self) -> Dict[str, Any]:
|
|
"""Load existing metrics from file"""
|
|
if self.metrics_file.exists():
|
|
with open(self.metrics_file, 'r') as f:
|
|
return json.load(f)
|
|
return {
|
|
"bug_escape_rate": {"total_bugs": 0, "escaped_bugs": 0, "rate": 0.0},
|
|
"test_flakiness": {"total_runs": 0, "flaky_runs": 0, "rate": 0.0},
|
|
"code_review_coverage": {"total_prs": 0, "reviewed_prs": 0, "rate": 0.0},
|
|
"last_updated": None
|
|
}
|
|
|
|
def _save_metrics(self):
|
|
"""Save metrics to file"""
|
|
self.metrics["last_updated"] = datetime.now().isoformat()
|
|
self.metrics_file.parent.mkdir(parents=True, exist_ok=True)
|
|
with open(self.metrics_file, 'w') as f:
|
|
json.dump(self.metrics, f, indent=2)
|
|
|
|
def record_bug(self, escaped: bool = False):
|
|
"""Record a bug (escaped or caught in testing)"""
|
|
self.metrics["bug_escape_rate"]["total_bugs"] += 1
|
|
if escaped:
|
|
self.metrics["bug_escape_rate"]["escaped_bugs"] += 1
|
|
self._calculate_bug_escape_rate()
|
|
self._save_metrics()
|
|
|
|
def _calculate_bug_escape_rate(self):
|
|
"""Calculate bug escape rate"""
|
|
total = self.metrics["bug_escape_rate"]["total_bugs"]
|
|
escaped = self.metrics["bug_escape_rate"]["escaped_bugs"]
|
|
if total > 0:
|
|
self.metrics["bug_escape_rate"]["rate"] = (escaped / total) * 100
|
|
|
|
def record_test_run(self, flaky: bool = False):
|
|
"""Record a test run (flaky or stable)"""
|
|
self.metrics["test_flakiness"]["total_runs"] += 1
|
|
if flaky:
|
|
self.metrics["test_flakiness"]["flaky_runs"] += 1
|
|
self._calculate_test_flakiness()
|
|
self._save_metrics()
|
|
|
|
def _calculate_test_flakiness(self):
|
|
"""Calculate test flakiness rate"""
|
|
total = self.metrics["test_flakiness"]["total_runs"]
|
|
flaky = self.metrics["test_flakiness"]["flaky_runs"]
|
|
if total > 0:
|
|
self.metrics["test_flakiness"]["rate"] = (flaky / total) * 100
|
|
|
|
def record_pr(self, reviewed: bool = False):
|
|
"""Record a PR (reviewed or not reviewed)"""
|
|
self.metrics["code_review_coverage"]["total_prs"] += 1
|
|
if reviewed:
|
|
self.metrics["code_review_coverage"]["reviewed_prs"] += 1
|
|
self._calculate_code_review_coverage()
|
|
self._save_metrics()
|
|
|
|
def _calculate_code_review_coverage(self):
|
|
"""Calculate code review coverage rate"""
|
|
total = self.metrics["code_review_coverage"]["total_prs"]
|
|
reviewed = self.metrics["code_review_coverage"]["reviewed_prs"]
|
|
if total > 0:
|
|
self.metrics["code_review_coverage"]["rate"] = (reviewed / total) * 100
|
|
|
|
def get_metrics(self) -> Dict[str, Any]:
|
|
"""Get current metrics"""
|
|
return self.metrics
|
|
|
|
def print_report(self):
|
|
"""Print a formatted metrics report"""
|
|
click.echo("=" * 60)
|
|
click.echo("Quality Metrics Report")
|
|
click.echo("=" * 60)
|
|
click.echo(f"Last Updated: {self.metrics['last_updated']}")
|
|
click.echo()
|
|
click.echo("Bug Escape Rate:")
|
|
click.echo(f" Total Bugs: {self.metrics['bug_escape_rate']['total_bugs']}")
|
|
click.echo(f" Escaped Bugs: {self.metrics['bug_escape_rate']['escaped_bugs']}")
|
|
click.echo(f" Escape Rate: {self.metrics['bug_escape_rate']['rate']:.2f}%")
|
|
click.echo()
|
|
click.echo("Test Flakiness:")
|
|
click.echo(f" Total Runs: {self.metrics['test_flakiness']['total_runs']}")
|
|
click.echo(f" Flaky Runs: {self.metrics['test_flakiness']['flaky_runs']}")
|
|
click.echo(f" Flakiness Rate: {self.metrics['test_flakiness']['rate']:.2f}%")
|
|
click.echo()
|
|
click.echo("Code Review Coverage:")
|
|
click.echo(f" Total PRs: {self.metrics['code_review_coverage']['total_prs']}")
|
|
click.echo(f" Reviewed PRs: {self.metrics['code_review_coverage']['reviewed_prs']}")
|
|
click.echo(f" Review Coverage: {self.metrics['code_review_coverage']['rate']:.2f}%")
|
|
click.echo("=" * 60)
|
|
|
|
|
|
def main():
|
|
"""Main function for CLI usage"""
|
|
import sys
|
|
|
|
tracker = QualityMetricsTracker()
|
|
|
|
if len(sys.argv) < 2:
|
|
tracker.print_report()
|
|
return
|
|
|
|
command = sys.argv[1]
|
|
|
|
if command == "bug":
|
|
escaped = "--escaped" in sys.argv
|
|
tracker.record_bug(escaped=escaped)
|
|
click.echo(f"Recorded bug (escaped={escaped})")
|
|
|
|
elif command == "test":
|
|
flaky = "--flaky" in sys.argv
|
|
tracker.record_test_run(flaky=flaky)
|
|
click.echo(f"Recorded test run (flaky={flaky})")
|
|
|
|
elif command == "pr":
|
|
reviewed = "--reviewed" in sys.argv
|
|
tracker.record_pr(reviewed=reviewed)
|
|
click.echo(f"Recorded PR (reviewed={reviewed})")
|
|
|
|
elif command == "report":
|
|
tracker.print_report()
|
|
|
|
else:
|
|
click.echo(f"Unknown command: {command}")
|
|
click.echo("Available commands: bug, test, pr, report")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|