Files
LangBot/tests/e2e/utils/config_factory.py
huanghuoguoguo adb4b29c94 test(e2e): add minimal startup E2E tests
Add E2E tests for LangBot startup flow:
- tests/e2e/utils/config_factory.py: minimal config generation
- tests/e2e/utils/process_manager.py: LangBot subprocess management
- tests/e2e/conftest.py: E2E fixtures (session-scoped process)
- tests/e2e/test_startup.py: 12 tests for startup verification

Tests verify:
- boot.py + stages execution
- database initialization (SQLite)
- API availability
- migrations applied

Uses embedded databases (SQLite, Chroma) - no external dependencies.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 10:13:15 +08:00

179 lines
5.5 KiB
Python

"""E2E test configuration factory.
Generates minimal config.yaml for testing LangBot startup without external dependencies.
"""
from __future__ import annotations
import yaml
from pathlib import Path
def create_minimal_config(tmpdir: Path, port: int = 15300) -> Path:
"""Create minimal config.yaml for E2E testing.
Uses embedded databases (SQLite, Chroma) to avoid external dependencies.
Config is created at tmpdir/data/config.yaml (LangBot expects this location).
"""
# LangBot expects config at data/config.yaml
data_dir = tmpdir / 'data'
data_dir.mkdir(parents=True, exist_ok=True)
config = {
'admins': [],
'api': {
'port': port,
'webhook_prefix': f'http://127.0.0.1:{port}',
'extra_webhook_prefix': '',
},
'command': {
'enable': True,
'prefix': ['!', '!'],
'privilege': {},
},
'concurrency': {
'pipeline': 20,
'session': 1,
},
'proxy': {
'http': '',
'https': '',
},
'system': {
'instance_id': '',
'edition': 'community',
'recovery_key': '',
'allow_modify_login_info': True,
'disabled_adapters': [],
'limitation': {
'max_bots': -1,
'max_pipelines': -1,
'max_extensions': -1,
},
'task_retention': {
'completed_limit': 200,
},
'jwt': {
'expire': 604800,
'secret': 'e2e-test-secret-key',
},
},
'database': {
'use': 'sqlite',
'sqlite': {
'path': str(tmpdir / 'data' / 'langbot.db'),
},
'postgresql': {
'host': '127.0.0.1',
'port': 5432,
'user': 'postgres',
'password': 'postgres',
'database': 'postgres',
},
},
'vdb': {
'use': 'chroma', # Chroma is embedded, no external dependency
'chroma': {
'path': str(tmpdir / 'chroma'),
},
'qdrant': {
'url': '',
'host': 'localhost',
'port': 6333,
'api_key': '',
},
'seekdb': {
'mode': 'embedded',
'path': str(tmpdir / 'seekdb'),
'database': 'langbot',
'host': 'localhost',
'port': 2881,
'user': 'root',
'password': '',
'tenant': '',
},
'milvus': {
'uri': 'http://127.0.0.1:19530',
'token': '',
'db_name': '',
},
'pgvector': {
'host': '127.0.0.1',
'port': 5433,
'database': 'langbot',
'user': 'postgres',
'password': 'postgres',
},
},
'storage': {
'use': 'local',
'cleanup': {
'enabled': False, # Disable cleanup for tests
'check_interval_hours': 1,
'uploaded_file_retention_days': 7,
'log_retention_days': 3,
},
'local': {
'path': str(tmpdir / 'storage'),
},
's3': {
'endpoint_url': '',
'access_key_id': '',
'secret_access_key': '',
'region': 'us-east-1',
'bucket': 'langbot-storage',
},
},
'plugin': {
'enable': False, # Disable plugin system for minimal startup
'runtime_ws_url': '',
'enable_marketplace': False,
'display_plugin_debug_url': '',
'binary_storage': {
'max_value_bytes': 10485760,
},
},
'monitoring': {
'auto_cleanup': {
'enabled': False, # Disable cleanup for tests
'retention_days': 30,
'check_interval_hours': 1,
'delete_batch_size': 1000,
},
},
'space': {
'url': 'https://space.langbot.app',
'models_gateway_api_url': 'https://api.langbot.cloud/v1',
'oauth_authorize_url': 'https://space.langbot.app/auth/authorize',
'disable_models_service': True, # Disable external services
'disable_telemetry': True, # Disable telemetry for tests
},
'provider': {}, # Empty providers - minimal startup
'llm': [], # Empty LLM models
}
# Ensure data directory exists (LangBot expects config at data/config.yaml)
data_dir = tmpdir / 'data'
data_dir.mkdir(parents=True, exist_ok=True)
# Write config to data/config.yaml (LangBot's expected location)
config_path = data_dir / 'config.yaml'
with open(config_path, 'w', encoding='utf-8') as f:
yaml.dump(config, f, default_flow_style=False)
return config_path
def create_test_directories(tmpdir: Path) -> dict[str, Path]:
"""Create necessary directories for LangBot testing."""
directories = {
'data': tmpdir / 'data',
'logs': tmpdir / 'logs',
'storage': tmpdir / 'storage',
'chroma': tmpdir / 'chroma',
}
for path in directories.values():
path.mkdir(parents=True, exist_ok=True)
return directories