test(core): strengthen config and task behavior oracles

This commit is contained in:
huanghuoguoguo
2026-10-17 14:58:17 +08:00
parent bbf517edbc
commit 8d3e99d0fb
3 changed files with 38 additions and 25 deletions
+2 -4
View File
@@ -50,8 +50,7 @@ class TestCheckDeps:
result = asyncio.run(check_deps()) result = asyncio.run(check_deps())
assert 'requests' in result assert result == ['requests', 'openai']
assert 'openai' in result
def test_check_deps_all_missing(self): def test_check_deps_all_missing(self):
"""check_deps returns all deps when none present.""" """check_deps returns all deps when none present."""
@@ -66,8 +65,7 @@ class TestCheckDeps:
result = asyncio.run(check_deps()) result = asyncio.run(check_deps())
# Should include all required_deps keys assert result == list(required_deps)
assert len(result) == len(required_deps)
def test_required_deps_dict_exists(self): def test_required_deps_dict_exists(self):
"""required_deps dictionary is defined.""" """required_deps dictionary is defined."""
+5 -6
View File
@@ -119,12 +119,11 @@ class TestApplyEnvOverridesToConfig:
"""Test that '1', 'yes', 'on' are treated as true.""" """Test that '1', 'yes', 'on' are treated as true."""
load_config = get_load_config_module() load_config = get_load_config_module()
cfg = {'system': {'flag': False}}
for true_val in ['1', 'yes', 'on', 'TRUE']: for true_val in ['1', 'yes', 'on', 'TRUE']:
cfg = {'system': {'flag': False}}
env = {'SYSTEM__FLAG': true_val} env = {'SYSTEM__FLAG': true_val}
with patch.dict(os.environ, env, clear=True): with patch.dict(os.environ, env, clear=True):
result = load_config._apply_env_overrides_to_config(cfg.copy()) result = load_config._apply_env_overrides_to_config(cfg)
assert result['system']['flag'] is True assert result['system']['flag'] is True
def test_override_float_value(self): def test_override_float_value(self):
@@ -237,7 +236,7 @@ class TestApplyEnvOverridesToConfig:
with patch.dict(os.environ, env, clear=True): with patch.dict(os.environ, env, clear=True):
result = load_config._apply_env_overrides_to_config(cfg) result = load_config._apply_env_overrides_to_config(cfg)
assert result['system']['name'] == 'default' assert result == {'system': {'name': 'default'}}
def test_skip_env_vars_with_empty_path_segments(self, capsys): def test_skip_env_vars_with_empty_path_segments(self, capsys):
"""Platform variables such as __CF_USER_TEXT_ENCODING are not config.""" """Platform variables such as __CF_USER_TEXT_ENCODING are not config."""
@@ -249,7 +248,7 @@ class TestApplyEnvOverridesToConfig:
with patch.dict(os.environ, env, clear=True): with patch.dict(os.environ, env, clear=True):
result = load_config._apply_env_overrides_to_config(cfg) result = load_config._apply_env_overrides_to_config(cfg)
assert result == cfg assert result == {'system': {'name': 'default'}}
assert capsys.readouterr().out == '' assert capsys.readouterr().out == ''
def test_nested_config_path(self): def test_nested_config_path(self):
@@ -299,7 +298,7 @@ class TestApplyEnvOverridesToConfig:
with patch.dict(os.environ, env, clear=True): with patch.dict(os.environ, env, clear=True):
result = load_config._apply_env_overrides_to_config(cfg) result = load_config._apply_env_overrides_to_config(cfg)
assert result == cfg assert result == {'system': {'name': 'default'}}
def test_multiple_env_vars_override(self): def test_multiple_env_vars_override(self):
"""Test multiple env vars applied in order.""" """Test multiple env vars applied in order."""
+31 -15
View File
@@ -15,7 +15,7 @@ import asyncio
import contextvars import contextvars
import inspect import inspect
import sys import sys
from unittest.mock import Mock, MagicMock from unittest.mock import Mock, MagicMock, patch
from contextlib import contextmanager from contextlib import contextmanager
from typing import Generator from typing import Generator
@@ -181,12 +181,14 @@ class TestTaskContext:
ctx.set_current_action('test_action') ctx.set_current_action('test_action')
ctx.trace('Test message') ctx.trace('Test message')
ctx.metadata['key'] = 'value' ctx.metadata['key'] = 'value'
ctx.metadata['count'] = 5
ctx.metadata['items'] = ['a', 'b', 'c']
result = ctx.to_dict() result = ctx.to_dict()
assert result['current_action'] == 'test_action' assert result['current_action'] == 'test_action'
assert 'Test message' in result['log'] assert 'Test message' in result['log']
assert result['metadata'] == {'key': 'value'} assert result['metadata'] == {'key': 'value', 'count': 5, 'items': ['a', 'b', 'c']}
def test_static_new_factory(self): def test_static_new_factory(self):
"""Test TaskContext.new() factory method.""" """Test TaskContext.new() factory method."""
@@ -209,19 +211,9 @@ class TestTaskContext:
ctx1 = TaskContext.placeholder() ctx1 = TaskContext.placeholder()
ctx2 = TaskContext.placeholder() ctx2 = TaskContext.placeholder()
assert isinstance(ctx1, TaskContext)
assert ctx1 is ctx2 assert ctx1 is ctx2
def test_metadata_is_mutable_dict(self):
"""Test that metadata is a mutable dict."""
TaskContext, _, _ = get_taskmgr_classes()
ctx = TaskContext()
ctx.metadata['count'] = 5
ctx.metadata['items'] = ['a', 'b', 'c']
assert ctx.metadata['count'] == 5
assert len(ctx.metadata['items']) == 3
class TestTaskWrapper: class TestTaskWrapper:
"""Tests for TaskWrapper class.""" """Tests for TaskWrapper class."""
@@ -346,7 +338,8 @@ class TestTaskWrapper:
async def successful_coro(): async def successful_coro():
return {'file_id': 'file-a'} return {'file_id': 'file-a'}
wrapper = TaskWrapper(mock_app, successful_coro(), kind='knowledge_base.store') with patch('time.time', return_value=1720000000.25):
wrapper = TaskWrapper(mock_app, successful_coro(), kind='knowledge_base.store')
await wrapper.task await wrapper.task
result = wrapper.to_public_dict() result = wrapper.to_public_dict()
@@ -358,7 +351,7 @@ class TestTaskWrapper:
'status': 'succeeded', 'status': 'succeeded',
'error': None, 'error': None,
'result': {'file_id': 'file-a'}, 'result': {'file_id': 'file-a'},
'created_at': result['created_at'], 'created_at': 1720000000.25,
} }
assert 'runtime' not in result assert 'runtime' not in result
assert 'traceback' not in str(result).lower() assert 'traceback' not in str(result).lower()
@@ -429,6 +422,29 @@ class TestTaskWrapper:
class TestAsyncTaskManager: class TestAsyncTaskManager:
"""Tests for AsyncTaskManager class.""" """Tests for AsyncTaskManager class."""
@pytest.mark.asyncio
async def test_completed_retention_keeps_newest_tasks_and_running_task(self):
_, _, AsyncTaskManager = get_taskmgr_classes()
mock_app = create_mock_app()
mock_app.instance_config.data['system']['task_retention']['completed_limit'] = 2
manager = AsyncTaskManager(mock_app)
running = manager.create_task(asyncio.Event().wait())
async def immediate_coro():
return 'done'
try:
completed = [manager.create_task(immediate_coro()) for _ in range(2)]
await asyncio.gather(*(wrapper.task for wrapper in completed))
assert manager.tasks == [running, *completed]
newest = manager.create_task(immediate_coro())
await newest.task
assert manager.tasks == [running, completed[1], newest]
finally:
running.cancel()
await asyncio.gather(running.task, return_exceptions=True)
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_create_task_adds_to_list(self): async def test_create_task_adds_to_list(self):
"""Test that create_task adds task to tasks list.""" """Test that create_task adds task to tasks list."""