import unittest
import time
from olc.task_schedule.task_schedule import ThreadPoolManager, Task, IntervalTask, OlcScheduleManager
class MockTask(Task):
def __init__(self):
self.execution_count = 0
self.last_execution_time = None
def run(self):
self.execution_count += 1
self.last_execution_time = time.time()
class MockTaskWithException(Task):
def run(self):
raise Exception("Test exception")
class TestThreadPoolManager(unittest.TestCase):
"""测试线程池管理器"""
def setUp(self):
self.manager = ThreadPoolManager()
def tearDown(self):
self.manager.shutdown_all()
def test_create_pool_config(self):
"""测试创建线程池配置"""
result = self.manager.create_pool_config("test_pool", 2)
self.assertTrue(self.manager.has_pool_config("test_pool"))
def test_create_pool(self):
"""测试创建线程池"""
self.manager.create_pool_config("test_pool", 2)
result = self.manager.create_pool("test_pool")
self.assertTrue(result)
self.assertTrue(self.manager.is_pool_active("test_pool"))
def test_create_pool_nonexistent_config(self):
"""测试创建不存在配置的线程池"""
result = self.manager.create_pool("nonexistent_pool")
self.assertFalse(result)
def test_submit_task(self):
"""测试提交任务到线程池"""
self.manager.create_pool_config("test_pool", 2)
self.manager.create_pool("test_pool")
test_value = [0]
def test_func():
test_value[0] = 1
future = self.manager.submit("test_pool", test_func)
self.assertIsNotNone(future)
future.result()
self.assertEqual(test_value[0], 1)
def test_submit_task_nonexistent_pool(self):
"""测试提交任务到不存在的线程池"""
future = self.manager.submit("nonexistent_pool", lambda: 1)
self.assertIsNone(future)
def test_shutdown_pool(self):
"""测试关闭线程池"""
self.manager.create_pool_config("test_pool", 2)
self.manager.create_pool("test_pool")
result = self.manager.shutdown_pool("test_pool")
self.assertTrue(result)
self.assertFalse(self.manager.is_pool_active("test_pool"))
def test_shutdown_nonexistent_pool(self):
"""测试关闭不存在的线程池"""
result = self.manager.shutdown_pool("nonexistent_pool")
self.assertFalse(result)
def test_shutdown_all(self):
"""测试关闭所有线程池"""
self.manager.create_pool_config("pool1", 1)
self.manager.create_pool_config("pool2", 1)
self.manager.create_pool("pool1")
self.manager.create_pool("pool2")
self.manager.shutdown_all()
self.assertFalse(self.manager.is_pool_active("pool1"))
self.assertFalse(self.manager.is_pool_active("pool2"))
def test_shutdown_all_multiple_times_safely(self):
"""[核心测试] 验证多次调用 shutdown_all 不会出错或死锁"""
self.manager.create_pool_config("pool1", 1)
self.manager.create_pool_config("pool2", 1)
self.manager.create_pool("pool1")
self.manager.create_pool("pool2")
result1 = self.manager.shutdown_all()
self.assertFalse(self.manager.is_pool_active("pool1"))
self.assertFalse(self.manager.is_pool_active("pool2"))
result2 = self.manager.shutdown_all()
self.assertFalse(self.manager.is_pool_active("pool1"))
self.assertFalse(self.manager.is_pool_active("pool2"))
def test_shutdown_all_then_recreate(self):
"""测试关闭所有后重新创建线程池"""
self.manager.create_pool_config("pool1", 2)
self.manager.create_pool("pool1")
self.manager.shutdown_all()
self.manager.create_pool_config("pool1_new", 2)
result = self.manager.create_pool("pool1_new")
self.assertTrue(result)
self.assertTrue(self.manager.is_pool_active("pool1_new"))
self.manager.shutdown_all()
def test_shutdown_all_empty_manager(self):
"""测试空管理器调用 shutdown_all 不报错"""
try:
self.manager.shutdown_all()
except Exception as e:
self.fail(f"空管理器调用 shutdown_all 不应抛出异常: {e}")
def test_shutdown_all_with_active_tasks(self):
"""测试关闭有活跃任务的线程池"""
import concurrent.futures
self.manager.create_pool_config("busy_pool", 2)
self.manager.create_pool("busy_pool")
def long_running_task():
time.sleep(0.5)
return "done"
future = self.manager.submit("busy_pool", long_running_task)
self.assertIsNotNone(future)
self.manager.shutdown_all()
self.assertFalse(self.manager.is_pool_active("busy_pool"))
def test_remove_pool(self):
"""测试移除线程池"""
self.manager.create_pool_config("test_pool", 2)
self.manager.create_pool("test_pool")
result = self.manager.remove("test_pool")
self.assertTrue(result)
self.assertFalse(self.manager.has_pool_config("test_pool"))
class TestIntervalTask(unittest.TestCase):
"""测试间隔任务"""
def setUp(self):
self.manager = ThreadPoolManager()
self.manager.create_pool_config("test_pool", 2)
self.manager.create_pool("test_pool")
self.test_task = MockTask()
def tearDown(self):
self.manager.shutdown_all()
def test_register(self):
"""测试注册任务"""
from schedule import Scheduler
scheduler = Scheduler()
interval_task = IntervalTask("test_task", self.test_task, 1, "test_pool")
result = interval_task.register(self.manager, scheduler)
self.assertTrue(result)
self.assertTrue(interval_task.is_running())
def test_unregister(self):
"""测试取消注册任务"""
from schedule import Scheduler
scheduler = Scheduler()
interval_task = IntervalTask("test_task", self.test_task, 1, "test_pool")
interval_task.register(self.manager, scheduler)
interval_task.unregister(scheduler)
self.assertFalse(interval_task.is_running())
def test_get_info(self):
"""测试获取任务信息"""
interval_task = IntervalTask("test_task", self.test_task, 1, "test_pool")
info = interval_task.get_info()
self.assertEqual(info["name"], "test_task")
self.assertEqual(info["interval"], 1)
self.assertEqual(info["pool_name"], "test_pool")
self.assertFalse(info["running"])
class TestScheduleManager(unittest.TestCase):
"""测试调度管理器"""
def setUp(self):
OlcScheduleManager._instance = None
self.manager = OlcScheduleManager.get_instance()
self.test_task = MockTask()
def tearDown(self):
self.manager.close()
def test_create_task(self):
"""测试创建任务"""
result = self.manager.create_task("test_task", self.test_task, 1)
self.assertTrue(result)
tasks = self.manager.list_tasks()
self.assertIn("test_task", tasks)
def test_create_existing_task(self):
"""测试创建已存在的任务"""
self.manager.create_task("test_task", self.test_task, 1)
result = self.manager.create_task("test_task", self.test_task, 1)
self.assertFalse(result)
def test_start_task(self):
"""测试启动任务"""
self.manager.create_task("test_task", self.test_task, 1)
result = self.manager.start_task("test_task")
self.assertTrue(result)
info = self.manager.get_task_info("test_task")
self.assertTrue(info["running"])
def test_start_nonexistent_task(self):
"""测试启动不存在的任务"""
result = self.manager.start_task("nonexistent_task")
self.assertFalse(result)
def test_stop_task(self):
"""测试停止任务"""
self.manager.create_task("test_task", self.test_task, 1)
self.manager.start_task("test_task")
result = self.manager.stop_task("test_task")
self.assertTrue(result)
info = self.manager.get_task_info("test_task")
self.assertFalse(info["running"])
def test_stop_nonexistent_task(self):
"""测试停止不存在的任务"""
result = self.manager.stop_task("nonexistent_task")
self.assertFalse(result)
def test_remove_task(self):
"""测试移除任务"""
self.manager.create_task("test_task", self.test_task, 1)
result = self.manager.remove_task("test_task")
self.assertTrue(result)
tasks = self.manager.list_tasks()
self.assertNotIn("test_task", tasks)
def test_remove_nonexistent_task(self):
"""测试移除不存在的任务"""
result = self.manager.remove_task("nonexistent_task")
self.assertFalse(result)
def test_start_all_tasks(self):
"""测试启动所有任务"""
self.manager.create_task("task1", MockTask(), 1)
self.manager.create_task("task2", MockTask(), 1)
result = self.manager.start_all_tasks()
self.assertEqual(len(result), 2)
self.assertTrue(result["task1"])
self.assertTrue(result["task2"])
def test_stop_all_tasks(self):
"""测试停止所有任务"""
self.manager.create_task("task1", MockTask(), 1)
self.manager.create_task("task2", MockTask(), 1)
self.manager.start_all_tasks()
self.manager.stop_all_tasks()
info1 = self.manager.get_task_info("task1")
info2 = self.manager.get_task_info("task2")
self.assertFalse(info1["running"])
self.assertFalse(info2["running"])
def test_get_task_info(self):
"""测试获取任务信息"""
self.manager.create_task("test_task", self.test_task, 1)
info = self.manager.get_task_info("test_task")
self.assertIsNotNone(info)
self.assertEqual(info["name"], "test_task")
self.assertEqual(info["interval"], 1)
def test_get_nonexistent_task_info(self):
"""测试获取不存在任务的信息"""
info = self.manager.get_task_info("nonexistent_task")
self.assertIsNone(info)
def test_list_tasks(self):
"""测试列出所有任务"""
self.manager.create_task("task1", MockTask(), 1)
self.manager.create_task("task2", MockTask(), 1)
tasks = self.manager.list_tasks()
self.assertEqual(len(tasks), 2)
self.assertIn("task1", tasks)
self.assertIn("task2", tasks)
def test_is_running(self):
"""测试是否正在运行"""
self.assertTrue(self.manager.is_running())
def test_task_execution(self):
"""测试任务执行"""
test_task = MockTask()
self.manager.create_task("test_task", test_task, 0.1)
self.manager.start_task("test_task")
time.sleep(1.0)
self.assertGreater(test_task.execution_count, 0)
def test_task_with_exception(self):
"""测试任务异常处理"""
exception_task = MockTaskWithException()
self.manager.create_task("exception_task", exception_task, 0.1)
self.manager.start_task("exception_task")
time.sleep(0.5)
self.assertTrue(self.manager.is_running())
if __name__ == '__main__':
unittest.main()