Class: GitlabQuality::TestTooling::CodeCoverage::ClickHouse::TestHealthRiskAggregator
- Inherits:
-
Object
- Object
- GitlabQuality::TestTooling::CodeCoverage::ClickHouse::TestHealthRiskAggregator
- Includes:
- Client
- Defined in:
- lib/gitlab_quality/test_tooling/code_coverage/click_house/test_health_risk_aggregator.rb
Overview
Runs the daily aggregation that turns ‘code_coverage.test_coverage_per_file` rows into a small `code_coverage.test_health_risk_per_group` summary the dashboard reads.
Hybrid model: this Ruby class is the orchestrator (schedule, error handling, parameter substitution); ClickHouse runs the bitmap math via ‘INSERT … SELECT` from the SQL file shipped alongside.
Constant Summary collapse
- SQL_FILE =
File.('test_health_risk_aggregation.sql', __dir__)
- DEFAULT_COVERAGE_WINDOW =
2 DAY rather than 1 DAY makes the aggregation self-healing across a single missed nightly run: if last night’s export failed, this night’s run still sees yesterday’s per-test rows and produces a current snapshot. ReplacingMergeTree FINAL on the source table ensures we read only the latest version per (test_file, source_file). ClickHouse accepts both ‘2 DAY’ and ‘2 DAYS’; we use the singular form for consistency with ‘30 DAY` below.
'2 DAY'- DEFAULT_RISK_WINDOW =
'30 DAY'- DATE_PATTERN =
‘snapshot_date` is YYYY-MM-DD; intervals are `<integer> <unit>` (singular or plural).
/\A\d{4}-\d{2}-\d{2}\z/- INTERVAL_PATTERN =
/\A\d+\s+(SECOND|MINUTE|HOUR|DAY|WEEK|MONTH|QUARTER|YEAR)S?\z/i
Instance Method Summary collapse
-
#initialize(url:, database:, username: nil, password: nil, logger: nil, coverage_window: DEFAULT_COVERAGE_WINDOW, risk_window: DEFAULT_RISK_WINDOW) ⇒ TestHealthRiskAggregator
constructor
A new instance of TestHealthRiskAggregator.
- #run(snapshot_date: Date.today) ⇒ void
Constructor Details
#initialize(url:, database:, username: nil, password: nil, logger: nil, coverage_window: DEFAULT_COVERAGE_WINDOW, risk_window: DEFAULT_RISK_WINDOW) ⇒ TestHealthRiskAggregator
Returns a new instance of TestHealthRiskAggregator.
37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/gitlab_quality/test_tooling/code_coverage/click_house/test_health_risk_aggregator.rb', line 37 def initialize( url:, database:, username: nil, password: nil, logger: nil, coverage_window: DEFAULT_COVERAGE_WINDOW, risk_window: DEFAULT_RISK_WINDOW) @url = url @database = database @username = username @password = password @logger = logger || ::Logger.new($stdout, level: 1) @coverage_window = coverage_window @risk_window = risk_window end |
Instance Method Details
#run(snapshot_date: Date.today) ⇒ void
This method returns an undefined value.
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/gitlab_quality/test_tooling/code_coverage/click_house/test_health_risk_aggregator.rb', line 51 def run(snapshot_date: Date.today) # rubocop:disable Metrics/AbcSize sql = build_sql(snapshot_date: snapshot_date) logger.info( "#{LOG_PREFIX} Running test_health_risk aggregation snapshot_date=#{snapshot_date} " \ "coverage_window=#{coverage_window} risk_window=#{risk_window}" ) client.query(sql, format: "TabSeparated") inserted = fetch_row_count(snapshot_date) if inserted.is_a?(Integer) && inserted.zero? logger.warn( "#{LOG_PREFIX} Aggregation wrote 0 rows for snapshot_date=#{snapshot_date}. " \ "This is valid if no per-test data is in the coverage_window, but worth checking " \ "test_coverage_per_file directly if a recent export ran." ) else logger.info("#{LOG_PREFIX} Aggregation wrote #{inserted} rows for snapshot_date=#{snapshot_date}") end rescue StandardError => e logger.error("#{LOG_PREFIX} Aggregation failed for #{snapshot_date}: #{e.}") raise end |