初始提交
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from cli.runtime.base import RuntimeEnvironmentService
|
||||
from cli.runtime.db import DatabaseRuntimeService
|
||||
from cli.runtime.db.gateway import DatabaseInfrastructureGateway
|
||||
from cli.runtime.db.support import DatabaseRevisionSupport
|
||||
|
||||
|
||||
class FakeRuntimeEnvironment(RuntimeEnvironmentService):
|
||||
"""
|
||||
模拟运行时环境服务。
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def get_backend_dir() -> str:
|
||||
"""
|
||||
返回固定后端目录。
|
||||
|
||||
:return: 固定目录
|
||||
"""
|
||||
return '/tmp/shierfeng-backend'
|
||||
|
||||
|
||||
def test_database_revision_support_serializes_revision() -> None:
|
||||
"""
|
||||
校验数据库迁移版本支持对象会序列化 Alembic revision。
|
||||
|
||||
:return: None
|
||||
"""
|
||||
|
||||
class FakeRevision:
|
||||
"""
|
||||
模拟 Alembic revision 对象。
|
||||
"""
|
||||
|
||||
revision = '202605110001'
|
||||
down_revision = ('202605100001',)
|
||||
branch_labels = {'main'}
|
||||
dependencies = None
|
||||
doc = ' demo revision '
|
||||
path = Path('/tmp/revision.py')
|
||||
|
||||
support = DatabaseRevisionSupport(DatabaseInfrastructureGateway(), FakeRuntimeEnvironment())
|
||||
|
||||
payload = support.serialize_revision(FakeRevision())
|
||||
|
||||
assert payload == {
|
||||
'revision': '202605110001',
|
||||
'downRevisions': ['202605100001'],
|
||||
'branchLabels': ['main'],
|
||||
'dependsOn': [],
|
||||
'doc': 'demo revision',
|
||||
'path': '/tmp/revision.py',
|
||||
}
|
||||
|
||||
|
||||
def test_database_runtime_service_upgrade_dry_run_returns_command_payload() -> None:
|
||||
"""
|
||||
校验数据库运行时 dry-run 升级会返回命令预览结果。
|
||||
|
||||
:return: None
|
||||
"""
|
||||
service = DatabaseRuntimeService(runtime_environment=FakeRuntimeEnvironment())
|
||||
|
||||
payload = service.upgrade_database('head', dry_run=True)
|
||||
|
||||
assert payload['ok'] is True
|
||||
assert payload['dryRun'] is True
|
||||
assert payload['cwd'] == '/tmp/shierfeng-backend'
|
||||
assert payload['command'] == ['alembic', '-c', '/tmp/shierfeng-backend/alembic.ini', 'upgrade', 'head']
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_database_runtime_service_ping_database_returns_failure() -> None:
|
||||
"""
|
||||
校验数据库运行时在连接异常时会返回失败结果。
|
||||
|
||||
:return: None
|
||||
"""
|
||||
|
||||
class FakeConnection:
|
||||
"""
|
||||
模拟数据库连接对象。
|
||||
"""
|
||||
|
||||
async def __aenter__(self) -> 'FakeConnection':
|
||||
raise RuntimeError('db boom')
|
||||
|
||||
async def __aexit__(
|
||||
self,
|
||||
exc_type: type[BaseException] | None,
|
||||
exc: BaseException | None,
|
||||
tb: object,
|
||||
) -> None:
|
||||
del exc_type, exc, tb
|
||||
|
||||
class FakeEngine:
|
||||
"""
|
||||
模拟数据库引擎。
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def connect() -> FakeConnection:
|
||||
"""
|
||||
返回模拟连接对象。
|
||||
|
||||
:return: 模拟连接对象
|
||||
"""
|
||||
return FakeConnection()
|
||||
|
||||
@staticmethod
|
||||
async def dispose() -> None:
|
||||
"""
|
||||
释放引擎资源。
|
||||
|
||||
:return: None
|
||||
"""
|
||||
|
||||
gateway = DatabaseInfrastructureGateway()
|
||||
service = DatabaseRuntimeService(
|
||||
runtime_environment=FakeRuntimeEnvironment(),
|
||||
infrastructure_gateway=gateway,
|
||||
)
|
||||
|
||||
def _fake_get_async_db_engine_factory() -> object:
|
||||
def _factory(*, echo: bool = False) -> FakeEngine:
|
||||
del echo
|
||||
return FakeEngine()
|
||||
|
||||
return _factory
|
||||
|
||||
def _fake_get_sqlalchemy_text() -> object:
|
||||
return lambda sql: sql
|
||||
|
||||
object.__setattr__(gateway, 'get_async_db_engine_factory', _fake_get_async_db_engine_factory)
|
||||
object.__setattr__(gateway, 'get_sqlalchemy_text', _fake_get_sqlalchemy_text)
|
||||
|
||||
payload = await service.ping_database()
|
||||
|
||||
assert payload['ok'] is False
|
||||
assert payload['message'] == '数据库连接失败'
|
||||
assert 'db boom' in payload['error']
|
||||
Reference in New Issue
Block a user