from __future__ import annotations
import dataclasses
from typing import TYPE_CHECKING
import pymssql
import pytest
from pytest_databases.helpers import get_xdist_worker_num
from pytest_databases.types import ServiceContainer, XdistIsolationLevel
if TYPE_CHECKING:
from collections.abc import Generator
from pytest_databases._service import DockerService
[docs]
@pytest.fixture(scope="session")
def xdist_mssql_isolation_level() -> XdistIsolationLevel:
return "database"
[docs]
@pytest.fixture(scope="session")
def mssql_image() -> str:
return "mcr.microsoft.com/mssql/server:2022-latest"
[docs]
@dataclasses.dataclass
class MSSQLService(ServiceContainer):
user: str
password: str
database: str
@property
def connection_string(self) -> str:
return (
"encrypt=no; "
"TrustServerCertificate=yes; "
f"driver={{ODBC Driver 18 for SQL Server}}; "
f"server={self.host},{self.port}; "
f"database={self.database}; "
f"UID={self.user}; "
f"PWD={self.password}"
)
[docs]
@pytest.fixture(autouse=False, scope="session")
def mssql_service(
docker_service: DockerService,
xdist_mssql_isolation_level: XdistIsolationLevel,
mssql_image: str,
) -> Generator[MSSQLService, None, None]:
password = "Super-secret1"
def check(_service: ServiceContainer) -> bool:
try:
with pymssql.connect(
user="sa",
password=password,
database="master",
host=_service.host,
port=str(_service.port),
timeout=2,
) as conn, conn.cursor() as cursor:
cursor.execute("select 1 as is_available")
resp = cursor.fetchone()
return resp[0] == 1 if resp is not None else False
except Exception: # noqa: BLE001
return False
worker_num = get_xdist_worker_num()
db_name = "pytest_databases"
name = "mssql"
if worker_num is not None:
suffix = f"_{worker_num}"
if xdist_mssql_isolation_level == "server":
name += suffix
else:
db_name += suffix
with docker_service.run(
image=mssql_image,
check=check,
container_port=1433,
name=name,
env={
"SA_PASSWORD": password,
"MSSQL_PID": "Developer",
"ACCEPT_EULA": "Y",
"MSSQL_TCP_PORT": "1433",
},
timeout=100,
pause=1,
transient=xdist_mssql_isolation_level == "server",
) as service:
with pymssql.connect(
user="sa",
password=password,
database="master",
host=service.host,
port=str(service.port),
timeout=2,
autocommit=True,
) as conn, conn.cursor() as cursor:
cursor.execute(f"CREATE DATABASE {db_name}")
yield MSSQLService(
database=db_name,
host=service.host,
port=service.port,
user="sa",
password=password,
)
[docs]
@pytest.fixture(autouse=False, scope="session")
def mssql_connection(mssql_service: MSSQLService) -> Generator[pymssql.Connection, None, None]:
with pymssql.connect(
host=mssql_service.host,
port=str(mssql_service.port),
database=mssql_service.database,
user=mssql_service.user,
password=mssql_service.password,
timeout=2,
) as db_connection:
yield db_connection