diff options
| author | Kirill Rysin <[email protected]> | 2026-04-27 14:43:37 +0200 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-04-27 14:43:37 +0200 |
| commit | ceca83e4fd33bfcc01d6da658280cea4ee46c30b (patch) | |
| tree | f49ea284fe912f06f5ce1adb016969fc22acec17 /.github/scripts | |
| parent | 167479fbfb9aadea4c1bc71cbde8ee66eb5fd4ff (diff) | |
Mute: cleanup after delete different mute dash source (#38891)
Diffstat (limited to '.github/scripts')
7 files changed, 27 insertions, 243 deletions
diff --git a/.github/scripts/analytics/data_mart_queries/muted_tests_daily_by_team.sql b/.github/scripts/analytics/data_mart_queries/muted_tests_daily_by_team.sql index 6050a0b4003..81952e8f167 100644 --- a/.github/scripts/analytics/data_mart_queries/muted_tests_daily_by_team.sql +++ b/.github/scripts/analytics/data_mart_queries/muted_tests_daily_by_team.sql @@ -2,10 +2,12 @@ -- Filters: is_test_chunk = 0, is_muted = 1 (as required for BI). -- effective_area / effective_owner_team are computed in tests_monitor.py (single source of truth). -- Per-test previous effective owner and change date: tests_monitor.previous_effective_owner_team, --- effective_owner_team_changed_date (also in muted_tests_with_issue_and_area / test_muted_monitor_mart). +-- effective_owner_team_changed_date (also in muted_tests_with_issue_and_area). -- This mart only aggregates; grid still uses timeline + mapping for empty cells. $window_days = 365; $muted_sla_days = 30; +$mart_branch = 'main'; +$stable_branches_ge_26_re = '^stable-(2[6-9]|[3-9][0-9])(-.+)?$'; $normalize = ($raw_area) -> { $parts = String::SplitToList(Cast($raw_area AS String), '/'); @@ -60,7 +62,10 @@ $tm = ( Unicode::ToLower(Cast(Coalesce(String::ReplaceAll(t.owner, 'TEAM:@ydb-platform/', ''), '') AS Utf8)) AS owner_team_key FROM `test_results/analytics/tests_monitor` AS t WHERE t.date_window >= CurrentUtcDate() - $window_days * Interval("P1D") - AND t.build_type = 'relwithdebinfo' + AND ( + t.branch = $mart_branch + OR Re2::Match($stable_branches_ge_26_re)(CAST(t.branch AS String)) + ) AND t.is_test_chunk = 0 AND t.state != 'Skipped' ); diff --git a/.github/scripts/analytics/data_mart_queries/muted_tests_with_issue_and_area.sql b/.github/scripts/analytics/data_mart_queries/muted_tests_with_issue_and_area.sql index 98b4cefd665..e2e7717f5e0 100644 --- a/.github/scripts/analytics/data_mart_queries/muted_tests_with_issue_and_area.sql +++ b/.github/scripts/analytics/data_mart_queries/muted_tests_with_issue_and_area.sql @@ -3,7 +3,7 @@ $mart_history_days = 365; -- Mart filter: branch/build_type slice for this dashboard (not necessarily all CI matrix branches). $mart_branch = 'main'; -$mart_build_type = 'relwithdebinfo'; +$stable_branches_ge_26_re = '^stable-(2[6-9]|[3-9][0-9])(-.+)?$'; -- Must match ``manual_unmute_ttl_calendar_days`` in ``.github/config/mute_config.json`` (fast-unmute deadline). $manual_unmute_ttl_calendar_days = 3; @@ -120,8 +120,10 @@ LEFT JOIN $mfu AS mfu AND tm.branch = mfu.branch AND tm.build_type = mfu.build_type WHERE tm.date_window >= CurrentUtcDate() - $mart_history_days * Interval("P1D") - AND tm.branch = $mart_branch - AND tm.build_type = $mart_build_type + AND ( + tm.branch = $mart_branch + OR Re2::Match($stable_branches_ge_26_re)(CAST(tm.branch AS String)) + ) AND tm.is_test_chunk = 0 AND tm.is_muted = 1 AND tm.state != 'Skipped'; diff --git a/.github/scripts/analytics/data_mart_queries/test_monitor_mart.sql b/.github/scripts/analytics/data_mart_queries/test_monitor_mart.sql deleted file mode 100644 index 237233b59cc..00000000000 --- a/.github/scripts/analytics/data_mart_queries/test_monitor_mart.sql +++ /dev/null @@ -1,31 +0,0 @@ -SELECT - state_filtered, - test_name, - suite_folder, - full_name, - date_window, - build_type, - branch, - days_ago_window, - pass_count, - mute_count, - fail_count, - skip_count, - owner, - is_muted, - is_test_chunk, - state, - previous_state, - state_change_date, - days_in_state, - previous_mute_state, - mute_state_change_date, - days_in_mute_state, - previous_state_filtered, - state_change_date_filtered, - days_in_state_filtered, - COALESCE(effective_owner_team, String::ReplaceAll(owner, 'TEAM:@ydb-platform/', '')) AS owner_team -FROM `test_results/analytics/tests_monitor` -WHERE date_window >= CurrentUtcDate() - 1 * Interval("P1D") -- for init table better take 30* Interval("P1D") -and ( branch = 'main' or branch like 'stable-%' or branch like 'stream-nb-2%') - diff --git a/.github/scripts/analytics/data_mart_queries/test_muted_monitor_mart_with_issue.sql b/.github/scripts/analytics/data_mart_queries/test_muted_monitor_mart_with_issue.sql deleted file mode 100644 index 0c539268286..00000000000 --- a/.github/scripts/analytics/data_mart_queries/test_muted_monitor_mart_with_issue.sql +++ /dev/null @@ -1,143 +0,0 @@ --- GitHub issue fields from github_issue_mapping; analytics area/owner + owner hand-off from tests_monitor. --- COALESCE fallback: when effective_* columns are NULL (not yet populated), fall back to owner string + area_to_owner_mapping. - --- Mart slice: last N calendar days of ``tests_monitor`` (not ``mute_config.json``). -$mart_monitor_date_span_days = 1; - --- Mart branch filter: ``main`` plus release branches matching this prefix pattern. -$mart_main_branch = 'main'; -$mart_stable_branch_like = 'stable-%'; - --- ``resolution`` / ``is_muted_or_skipped``: dashboard SLA thresholds (not ``mute_config.json`` windows). -$resolution_skipped_days_threshold = 14; -$resolution_muted_delete_candidate_days = 30; - --- Must match ``manual_unmute_ttl_calendar_days`` in ``.github/config/mute_config.json`` (fast-unmute deadline). -$manual_unmute_ttl_calendar_days = 3; - -$normalize = ($raw_area) -> { - $parts = String::SplitToList(Cast($raw_area AS String), '/'); - RETURN Cast( - IF(ListLength($parts) >= 2, $parts[0] || '/' || $parts[1], Cast($raw_area AS String)) - AS Utf8); -}; - -$area_fallback = ( - SELECT owner_team AS owner_team, MIN($normalize(area)) AS area - FROM `test_results/analytics/area_to_owner_mapping` - GROUP BY owner_team -); - -$gim_latest = ( - SELECT - full_name AS full_name, - branch AS branch, - build_type AS build_type, - github_issue_url AS github_issue_url, - github_issue_number AS github_issue_number, - github_issue_state AS github_issue_state, - github_issue_created_at AS github_issue_created_at, - area_override AS area_override, - area_override_since AS area_override_since - FROM ( - SELECT - g.full_name AS full_name, - g.branch AS branch, - g.build_type AS build_type, - g.github_issue_url AS github_issue_url, - g.github_issue_number AS github_issue_number, - g.github_issue_state AS github_issue_state, - g.github_issue_created_at AS github_issue_created_at, - g.area_override AS area_override, - g.area_override_since AS area_override_since, - ROW_NUMBER() OVER ( - PARTITION BY g.full_name, g.branch, g.build_type - ORDER BY g.github_issue_created_at DESC, g.github_issue_number DESC - ) AS rn - FROM `test_results/analytics/github_issue_mapping` AS g - ) AS g_rnk - WHERE g_rnk.rn = 1 -); - -$mfu = ( - SELECT - full_name AS full_name, - branch AS branch, - build_type AS build_type, - github_issue_number AS mfu_issue_number, - requested_at AS mfu_since, - window_days AS mfu_window_days, - requested_at + $manual_unmute_ttl_calendar_days * Interval("P1D") AS mfu_expires_at - FROM `test_mute/fast_unmute_active` -); - -SELECT - tm.state_filtered AS state_filtered, - tm.test_name AS test_name, - tm.suite_folder AS suite_folder, - tm.full_name AS full_name, - tm.date_window AS date_window, - tm.build_type AS build_type, - tm.branch AS branch, - tm.days_ago_window AS days_ago_window, - tm.pass_count AS pass_count, - tm.mute_count AS mute_count, - tm.fail_count AS fail_count, - tm.skip_count AS skip_count, - tm.owner AS owner, - tm.is_muted AS is_muted, - tm.is_test_chunk AS is_test_chunk, - tm.state AS state, - tm.previous_state AS previous_state, - tm.state_change_date AS state_change_date, - tm.days_in_state AS days_in_state, - tm.previous_mute_state AS previous_mute_state, - tm.mute_state_change_date AS mute_state_change_date, - tm.days_in_mute_state AS days_in_mute_state, - tm.previous_state_filtered AS previous_state_filtered, - tm.state_change_date_filtered AS state_change_date_filtered, - tm.days_in_state_filtered AS days_in_state_filtered, - CAST(CASE - WHEN (tm.state = 'Skipped' AND tm.days_in_state > $resolution_skipped_days_threshold) THEN 'Skipped' - WHEN tm.days_in_mute_state > $resolution_muted_delete_candidate_days THEN 'MUTED: delete candidate' - ELSE 'MUTED: in sla' - END - as String) AS resolution, - CAST(Coalesce( - tm.effective_owner_team, - Unicode::ToLower(Cast(Coalesce(String::ReplaceAll(tm.owner, 'TEAM:@ydb-platform/', ''), '') AS Utf8)) - ) AS String) AS owner_team, - Coalesce(tm.effective_area, $normalize(Coalesce(af.area, 'area/-'))) AS area, - tm.previous_effective_owner_team AS previous_effective_owner_team, - tm.effective_owner_team_changed_date AS effective_owner_team_changed_date, - CAST( - CASE - WHEN tm.is_muted = 1 OR (tm.state = 'Skipped' AND tm.days_in_state > $resolution_skipped_days_threshold) THEN TRUE - ELSE FALSE - END AS Uint8 - ) AS is_muted_or_skipped, - gim.github_issue_url AS github_issue_url, - gim.github_issue_number AS github_issue_number, - gim.github_issue_state AS github_issue_state, - gim.github_issue_created_at AS github_issue_created_at, - gim.area_override AS area_override, - gim.area_override_since AS area_override_since, - CAST(CASE WHEN mfu.full_name IS NOT NULL THEN 1 ELSE 0 END AS Uint8) AS is_manual_fast_unmute, - mfu.mfu_since AS manual_fast_unmute_since, - mfu.mfu_window_days AS manual_fast_unmute_window_days, - mfu.mfu_expires_at AS manual_fast_unmute_expires_at, - mfu.mfu_issue_number AS manual_fast_unmute_issue_number -FROM `test_results/analytics/tests_monitor` AS tm -LEFT JOIN $area_fallback AS af - ON Unicode::ToLower(Cast(Coalesce(String::ReplaceAll(tm.owner, 'TEAM:@ydb-platform/', ''), '') AS Utf8)) = af.owner_team -LEFT JOIN $gim_latest AS gim - ON tm.full_name = gim.full_name - AND tm.branch = gim.branch - AND tm.build_type = gim.build_type -LEFT JOIN $mfu AS mfu - ON tm.full_name = mfu.full_name - AND tm.branch = mfu.branch - AND tm.build_type = mfu.build_type -WHERE tm.date_window >= CurrentUtcDate() - $mart_monitor_date_span_days * Interval("P1D") - AND (tm.branch = $mart_main_branch OR tm.branch LIKE $mart_stable_branch_like) - AND tm.is_test_chunk = 0; diff --git a/.github/scripts/analytics/monitoring_queries/muted_tests_count_by_team.sql b/.github/scripts/analytics/monitoring_queries/muted_tests_count_by_team.sql deleted file mode 100644 index d4d93f54fe2..00000000000 --- a/.github/scripts/analytics/monitoring_queries/muted_tests_count_by_team.sql +++ /dev/null @@ -1,7 +0,0 @@ -SELECT `res_0`, PERCENTILE(`t1`.`days_in_state`, 0.9) AS `res_1`, count(`t1`.`test_name`) AS `res_2` -FROM ( -select * FROM `test_results/analytics/test_muted_monitor_mart` -where is_muted_or_skipped=1 -) AS `t1` -WHERE `t1`.`is_test_chunk` = 0 AND `t1`.`is_muted_or_skipped` = 1 AND `t1`.`date_window` = CurrentUtcDate() AND `t1`.`build_type` IN ('relwithdebinfo') AND `t1`.`branch` IN ('main') AND `t1`.`resolution` IN ('MUTED: delete candidate', 'MUTED: in sla', 'MUTED: delete candidate', 'MUTED: in sla') AND `t1`.`state` IN ('Muted Flaky', 'Muted Stable', 'Skipped', 'no_runs') GROUP BY `t1`.`owner_team` AS `res_0` ORDER BY `res_2` DESC - LIMIT 1000001 diff --git a/.github/scripts/analytics/monitoring_queries/muted_tests_with_issue.sql b/.github/scripts/analytics/monitoring_queries/muted_tests_with_issue.sql deleted file mode 100644 index a7256be8936..00000000000 --- a/.github/scripts/analytics/monitoring_queries/muted_tests_with_issue.sql +++ /dev/null @@ -1,42 +0,0 @@ -SELECT `res_0`, - `res_1`, - `res_2`, - `res_3`, - `res_4`, - `res_5`, - `res_6`, - max(`t1`.`days_in_mute_state`) AS `res_7`, - sum(CASE - WHEN (`t1`.`state` = 'Muted Flaky') THEN - 1 - WHEN (`t1`.`state` = 'Muted Stable') THEN - 3 - ELSE 2 END) AS `res_8`, `res_9`, `res_10` -FROM - (SELECT * - FROM `test_results/analytics/test_muted_monitor_mart` - WHERE is_muted_or_skipped=1 ) AS `t1` -WHERE `t1`.`is_test_chunk` = 0 - AND `t1`.`date_window` = CurrentUtcDate() - AND `t1`.`is_muted_or_skipped` = 1 - AND `t1`.`build_type` IN ('relwithdebinfo') - AND `t1`.`branch` IN ('main') - AND `t1`.`resolution` IN ('MUTED: delete candidate', 'MUTED: in sla', 'MUTED: delete candidate', 'MUTED: in sla') - AND `t1`.`state` IN ('Muted Flaky', 'Muted Stable', 'Skipped', 'no_runs') -GROUP BY `t1`.`owner_team` AS `res_0`, '(a ' || '"' || Unicode::ReplaceAll(CAST('https://github.com/ydb-platform/ydb/blob/' || `t1`.`branch` || '/' || `t1`.`suite_folder` AS UTF8), coalesce(CAST('"' AS UTF8), ''), coalesce(CAST('""' AS UTF8), '')) || '"' || ' ' || '"' || Unicode::ReplaceAll(CAST(`t1`.`suite_folder` AS UTF8), coalesce(CAST('"' AS UTF8), ''), coalesce(CAST('""' AS UTF8), '')) || '"' || ')' AS `res_1`, `t1`.`test_name` AS `res_2`, CAST(`t1`.`mute_state_change_date` AS UTF8) || ': ' || CAST(`t1`.`days_in_mute_state` AS UTF8) || ' д. назад' AS `res_3`, - CASE - WHEN (`t1`.`state` = 'Muted Flaky') THEN - 'Моргает последние ' || CAST(`t1`.`days_in_state` AS UTF8) || ' д.' - WHEN (`t1`.`state` = 'Muted Stable') THEN - 'Стабилен последние ' || CAST(`t1`.`days_in_state` AS UTF8) || ' д.' - ELSE 'Не выполнялся последние ' || CAST(`t1`.`days_in_state` AS UTF8) || ' д.' - END AS `res_4`, '(a ' || '"' || Unicode::ReplaceAll(CAST('https://datalens.yandex/34xnbsom67hcq?&branch=' || `t1`.`branch` || '&full_name=' || `t1`.`full_name` AS UTF8), coalesce(CAST('"' AS UTF8), ''), coalesce(CAST('""' AS UTF8), '')) || '"' || ' "History")' AS `res_5`, '(c ' || '(c ' || '(a ' || '"' || Unicode::ReplaceAll(CAST(`t1`.`github_issue_url` AS UTF8), coalesce(CAST('"' AS UTF8), ''), coalesce(CAST('""' AS UTF8), '')) || '"' || ' ' || '"' || Unicode::ReplaceAll(CAST(CAST(`t1`.`github_issue_number` AS UTF8) || '-' || `t1`.`github_issue_state` AS UTF8), coalesce(CAST('"' AS UTF8), ''), coalesce(CAST('""' AS UTF8), '')) || '"' || ')' || ' "-")' || ' ' || '"' || Unicode::ReplaceAll(CAST(CAST(CAST(`t1`.`github_issue_created_at` AS DATE) AS UTF8) AS UTF8), coalesce(CAST('"' AS UTF8), ''), coalesce(CAST('""' AS UTF8), '')) || '"' || ')' AS `res_6`, `t1`.`days_in_mute_state` AS `res_9`, `t1`.`days_in_state` AS `res_10` -ORDER BY `res_9` ASC, - `res_10` ASC, - `res_0` ASC, - `res_1` ASC, - `res_2` ASC, - `res_3` ASC, - `res_4` ASC, - `res_5` ASC, - `res_6` ASC LIMIT 1200 OFFSET 0 diff --git a/.github/scripts/telegram/parse_and_send_team_issues.py b/.github/scripts/telegram/parse_and_send_team_issues.py index 8fb6784c3d8..a5b44e01488 100644 --- a/.github/scripts/telegram/parse_and_send_team_issues.py +++ b/.github/scripts/telegram/parse_and_send_team_issues.py @@ -39,7 +39,7 @@ except ImportError: print("⚠️ Matplotlib not available. Install with: pip install matplotlib") # Configuration constants -MUTE_UPDATE_SHOW_DIFF = False # Set to True to show +/- statistics in mute update messages +MUTE_UPDATE_SHOW_DIFF = True # Set to True to show +/- statistics in mute update messages # Teams blacklisted from weekly/monthly updates PERIOD_UPDATE_BLACKLIST = { @@ -107,7 +107,7 @@ def get_all_team_data(use_yesterday=False, build_type=DEFAULT_BUILD_TYPE, branch Args: use_yesterday: If True, use yesterday's data for development convenience. - build_type: ``test_muted_monitor_mart.build_type`` filter; ``"all"`` = no filter. + build_type: ``muted_tests_with_issue_and_area.build_type`` filter; ``"all"`` = no filter. Returns: dict: Keys are canonical team slugs from mart ``owner_team`` (effective owner, @@ -136,25 +136,27 @@ def get_all_team_data(use_yesterday=False, build_type=DEFAULT_BUILD_TYPE, branch # Get table path from config with YDBWrapper() as ydb_wrapper: - test_muted_monitor_mart_table = ydb_wrapper.get_table_path("test_muted_monitor_mart") + muted_tests_with_issue_and_area_table = ydb_wrapper.get_table_path("muted_tests_with_issue_and_area") bt_clause = _sql_build_type_clause(build_type) - # Single optimized query for all data (aggregate by owner_team = effective team + area_override, - # same as ``test_muted_monitor_mart_with_issue.sql`` / dashboard — not raw ``owner``). + # Single optimized query for all data from muted tests mart with issue/area enrichment. + # Keep +today semantics event-like: tests whose mute_state_change_date is target date. all_data_query = f""" SELECT owner_team, date_window, - COUNT(*) as daily_count, - SUM(CASE WHEN mute_state_change_date = Date('{target_date.strftime('%Y-%m-%d')}') THEN 1 ELSE 0 END) as today_count - FROM `{test_muted_monitor_mart_table}` + COUNT(DISTINCT full_name) as daily_count, + SUM( + CASE + WHEN mute_state_change_date = Date('{target_date.strftime('%Y-%m-%d')}') THEN 1 + ELSE 0 + END + ) as today_count + FROM `{muted_tests_with_issue_and_area_table}` WHERE date_window >= Date('{start_date.strftime('%Y-%m-%d')}') AND date_window <= Date('{target_date.strftime('%Y-%m-%d')}') - AND is_muted = 1 AND branch = '{branch}'{bt_clause} - AND is_test_chunk = 0 - AND resolution != 'Skipped' GROUP BY owner_team, date_window ORDER BY owner_team, date_window """ @@ -223,8 +225,6 @@ def get_all_team_data(use_yesterday=False, build_type=DEFAULT_BUILD_TYPE, branch yesterday_total = trend[yesterday_str] today_total = data['stats']['total'] today_new = data['stats']['today'] - - # minus_today = yesterday_total - (today_total - today_new) data['stats']['minus_today'] = max(0, yesterday_total - (today_total - today_new)) print(f"📊 Processed data for {len(team_data)} teams") @@ -550,7 +550,7 @@ def format_team_message(team_name, issues, team_responsible=None, muted_stats=No # Format statistics with color coding and emojis if show_diff: if today > 0 and minus_today > 0: - message += f"\n📊 *[Total muted tests: {total}]({dashboard_url}) 🔴+{today} muted /🟢-{minus_today} unmuted*" + message += f"\n📊 *[Total muted tests: {total}]({dashboard_url}) 🟢-{minus_today} unmuted /🔴+{today} muted*" elif today > 0: message += f"\n📊 *[Total muted tests: {total}]({dashboard_url}) 🔴+{today} muted*" elif minus_today > 0: @@ -1196,7 +1196,7 @@ def main(): '--build-type', default=DEFAULT_BUILD_TYPE, dest='build_type', - help='test_muted_monitor_mart filter; use "all" to include every build_type (default: relwithdebinfo)', + help='muted_tests_with_issue_and_area filter; use "all" to include every build_type (default: relwithdebinfo)', ) parser.add_argument( '--branch', |
