mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-10-22 08:25:21 +08:00
Merge pull request #2671 from langbot-app/test/quality-core-oracles-20261017
test(core): strengthen config and task behavior oracles
This commit is contained in:
@@ -50,8 +50,7 @@ class TestCheckDeps:
|
||||
|
||||
result = asyncio.run(check_deps())
|
||||
|
||||
assert 'requests' in result
|
||||
assert 'openai' in result
|
||||
assert result == ['requests', 'openai']
|
||||
|
||||
def test_check_deps_all_missing(self):
|
||||
"""check_deps returns all deps when none present."""
|
||||
@@ -66,8 +65,7 @@ class TestCheckDeps:
|
||||
|
||||
result = asyncio.run(check_deps())
|
||||
|
||||
# Should include all required_deps keys
|
||||
assert len(result) == len(required_deps)
|
||||
assert result == list(required_deps)
|
||||
|
||||
def test_required_deps_dict_exists(self):
|
||||
"""required_deps dictionary is defined."""
|
||||
|
||||
@@ -119,12 +119,11 @@ class TestApplyEnvOverridesToConfig:
|
||||
"""Test that '1', 'yes', 'on' are treated as true."""
|
||||
load_config = get_load_config_module()
|
||||
|
||||
cfg = {'system': {'flag': False}}
|
||||
|
||||
for true_val in ['1', 'yes', 'on', 'TRUE']:
|
||||
cfg = {'system': {'flag': False}}
|
||||
env = {'SYSTEM__FLAG': true_val}
|
||||
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
|
||||
|
||||
def test_override_float_value(self):
|
||||
@@ -237,7 +236,7 @@ class TestApplyEnvOverridesToConfig:
|
||||
with patch.dict(os.environ, env, clear=True):
|
||||
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):
|
||||
"""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):
|
||||
result = load_config._apply_env_overrides_to_config(cfg)
|
||||
|
||||
assert result == cfg
|
||||
assert result == {'system': {'name': 'default'}}
|
||||
assert capsys.readouterr().out == ''
|
||||
|
||||
def test_nested_config_path(self):
|
||||
@@ -299,7 +298,7 @@ class TestApplyEnvOverridesToConfig:
|
||||
with patch.dict(os.environ, env, clear=True):
|
||||
result = load_config._apply_env_overrides_to_config(cfg)
|
||||
|
||||
assert result == cfg
|
||||
assert result == {'system': {'name': 'default'}}
|
||||
|
||||
def test_multiple_env_vars_override(self):
|
||||
"""Test multiple env vars applied in order."""
|
||||
|
||||
@@ -15,7 +15,7 @@ import asyncio
|
||||
import contextvars
|
||||
import inspect
|
||||
import sys
|
||||
from unittest.mock import Mock, MagicMock
|
||||
from unittest.mock import Mock, MagicMock, patch
|
||||
from contextlib import contextmanager
|
||||
from typing import Generator
|
||||
|
||||
@@ -181,12 +181,14 @@ class TestTaskContext:
|
||||
ctx.set_current_action('test_action')
|
||||
ctx.trace('Test message')
|
||||
ctx.metadata['key'] = 'value'
|
||||
ctx.metadata['count'] = 5
|
||||
ctx.metadata['items'] = ['a', 'b', 'c']
|
||||
|
||||
result = ctx.to_dict()
|
||||
|
||||
assert result['current_action'] == 'test_action'
|
||||
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):
|
||||
"""Test TaskContext.new() factory method."""
|
||||
@@ -209,19 +211,9 @@ class TestTaskContext:
|
||||
ctx1 = TaskContext.placeholder()
|
||||
ctx2 = TaskContext.placeholder()
|
||||
|
||||
assert isinstance(ctx1, TaskContext)
|
||||
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:
|
||||
"""Tests for TaskWrapper class."""
|
||||
@@ -346,7 +338,8 @@ class TestTaskWrapper:
|
||||
async def successful_coro():
|
||||
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
|
||||
|
||||
result = wrapper.to_public_dict()
|
||||
@@ -358,7 +351,7 @@ class TestTaskWrapper:
|
||||
'status': 'succeeded',
|
||||
'error': None,
|
||||
'result': {'file_id': 'file-a'},
|
||||
'created_at': result['created_at'],
|
||||
'created_at': 1720000000.25,
|
||||
}
|
||||
assert 'runtime' not in result
|
||||
assert 'traceback' not in str(result).lower()
|
||||
@@ -429,6 +422,29 @@ class TestTaskWrapper:
|
||||
class TestAsyncTaskManager:
|
||||
"""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
|
||||
async def test_create_task_adds_to_list(self):
|
||||
"""Test that create_task adds task to tasks list."""
|
||||
|
||||
Reference in New Issue
Block a user