"""Challenge plugin lifecycle task verdicts and worker cleanup evidence.""" from types import SimpleNamespace import unittest from unittest.mock import Mock, patch from regression_ci import suite_profile from regression_local_cases import DEFAULT_GROUPS from regression_plugin_lifecycle import wait_task, workers_stopped from regression_suite import validate class PluginLifecycleTests(unittest.TestCase): def test_job_is_opt_in_and_does_not_expand_daily(self): profile, _ = suite_profile('plugin-lifecycle', 'run') validate(profile) self.assertEqual(len(profile['cases']), 3) self.assertEqual(profile['resources'], []) self.assertNotIn('plugin-lifecycle', DEFAULT_GROUPS) for name in ('smoke', 'daily'): existing, _ = suite_profile(name, 'run') self.assertFalse(any(c.get('scenario', '').startswith('plugin_') for c in existing['cases'])) def test_expected_failure_requires_a_failed_task_not_http_success(self): suite = SimpleNamespace(timeout=lambda seconds: seconds) for task in ( {'id': 7, 'status': 'succeeded'}, {'id': 7, 'status': 'cancelled'}, {'id': 7, 'status': 'failed', 'error': None}, {'id': 8, 'status': 'failed', 'error': {'type': 'task_failed'}}, ): with self.subTest(task=task), patch('regression_plugin_lifecycle.request', return_value=task): with self.assertRaises(ValueError): wait_task(suite, {}, 7, 'failed', 'broken_upgrade') row = {} task = {'id': 7, 'status': 'failed', 'error': {'type': 'task_failed'}} with patch('regression_plugin_lifecycle.request', return_value=task): wait_task(suite, row, 7, 'failed', 'broken_upgrade') self.assertEqual(row['assertions']['broken_upgrade_task'], 'passed') self.assertEqual(row['plugin_tasks'][0]['status'], 'failed') def test_live_worker_is_a_cleanup_failure_but_reused_pid_is_not(self): suite = SimpleNamespace(timeout=lambda seconds: 0) with patch('regression_plugin_lifecycle.process_identity', return_value='same-start'): with self.assertRaisesRegex(ValueError, 'worker remains'): workers_stopped(suite, {'100': 'same-start'}) for identity in (None, 'new-start'): with patch('regression_plugin_lifecycle.process_identity', return_value=identity): workers_stopped(suite, {'100': 'same-start'}) def test_unfinished_task_cannot_be_accepted(self): suite = SimpleNamespace(timeout=lambda seconds: 0) with patch('regression_plugin_lifecycle.request', Mock(return_value={'id': 7, 'status': 'running'})): with self.assertRaisesRegex(TimeoutError, 'did not finish'): wait_task(suite, {}, 7, 'succeeded', 'install') if __name__ == '__main__': unittest.main()