gns3-server/tests/controller/test_qemu_cdrom_migration.py
Cristi 58e5591935 feat(qemu): support SATA CD-ROM interfaces
- Add per-drive IDE/SATA selection with backward-compatible IDE defaults
- Persist interfaces in nodes, templates, and appliance imports
- Add database migration support for versioned and unversioned databases
- Prevent partial updates when rejecting live interface changes
- Validate interfaces and support SATA media changes through the monitor
2026-10-18 22:07:37 +03:00

57 lines
2.6 KiB
Python

import pytest
import sqlalchemy as sa
from alembic import command, config
from alembic.operations import Operations
from alembic.runtime.migration import MigrationContext
from fastapi import FastAPI
from gns3server.db.models import Base
from gns3server.db.tasks import connect_to_db
from gns3server.db_migrations.versions import e2a7c9d4b601_add_cdrom_interfaces as migration
def test_cdrom_migration_defaults_idempotence_and_downgrade():
engine = sa.create_engine("sqlite://")
with engine.begin() as connection:
connection.exec_driver_sql("CREATE TABLE qemu_templates (id INTEGER PRIMARY KEY)")
connection.exec_driver_sql("INSERT INTO qemu_templates (id) VALUES (1)")
with Operations.context(MigrationContext.configure(connection)):
migration.upgrade()
migration.upgrade()
assert connection.exec_driver_sql("SELECT cdrom_interface, cdrom2_interface FROM qemu_templates").one() == (
"ide",
"ide",
)
migration.downgrade()
assert [column["name"] for column in sa.inspect(connection).get_columns("qemu_templates")] == ["id"]
engine.dispose()
@pytest.mark.asyncio
@pytest.mark.parametrize("versioned", [False, True])
async def test_database_startup_adds_cdrom_interfaces(tmp_path, monkeypatch, versioned):
path = tmp_path / "controller.db"
engine = sa.create_engine(f"sqlite:///{path}")
with engine.connect() as connection:
Base.metadata.create_all(connection)
connection.exec_driver_sql("ALTER TABLE qemu_templates DROP COLUMN cdrom_interface")
connection.exec_driver_sql("ALTER TABLE qemu_templates DROP COLUMN cdrom2_interface")
if versioned:
cfg = config.Config()
cfg.set_main_option("script_location", "gns3server:db_migrations")
cfg.attributes["connection"] = connection
command.stamp(cfg, migration.down_revision)
connection.commit()
engine.dispose()
monkeypatch.setenv("GNS3_DATABASE_URI", f"sqlite+aiosqlite:///{path}")
app = FastAPI()
await connect_to_db(app)
try:
async with app.state._db_engine.connect() as connection:
columns = await connection.run_sync(lambda conn: sa.inspect(conn).get_columns("qemu_templates"))
assert {"cdrom_interface", "cdrom2_interface"} <= {column["name"] for column in columns}
revision = await connection.scalar(sa.text("SELECT version_num FROM alembic_version"))
assert revision == migration.revision
finally:
await app.state._db_engine.dispose()