fastapi-gsap/.venv/lib/python3.12/site-packages/sqlalchemy/testing/suite/test_ddl.py
Tyler J King e744336385 fix: capability enforcement, credential safety, atomic delegations, input validation
C-6: ConnectorRuntime enforces capability_mask per operation.
     READ-only ACs cannot invoke MUTATE operations (wipe, lock, retire).
C-7: AC validated against database (exists, active, not expired)
     before connector invocation.
C-9: Delegated AC capability bounded by delegator's capability.
C-10: Command counter uses atomic SQL increment with limit check.
M-23: expire_stale() uses same atomic SQL pattern.

H-1: Sensitive credential fields hidden from repr/logs via repr=False.
H-2: Stub backend requires ALLOW_STUB_CREDENTIALS=true to activate.
H-3: Kerberos backend raises CredentialResolutionError instead of
     returning stub ticket.
H-4: Chronicle INTENT emitted before execution, RESULT after.
H-5: device_id validated as UUID before Graph API URL interpolation.
H-8: ConnectorRuntime enforces governance for all connector invocations.

Signed-off-by: Tyler King <tking@guildhouse.dev>
2026-04-14 08:13:27 -04:00

389 lines
12 KiB
Python

# testing/suite/test_ddl.py
# Copyright (C) 2005-2026 the SQLAlchemy authors and contributors
# <see AUTHORS file>
#
# This module is part of SQLAlchemy and is released under
# the MIT License: https://www.opensource.org/licenses/mit-license.php
# mypy: ignore-errors
import random
from . import testing
from .. import config
from .. import fixtures
from .. import util
from ..assertions import eq_
from ..assertions import is_false
from ..assertions import is_true
from ..config import requirements
from ..schema import Table
from ... import CheckConstraint
from ... import Column
from ... import ForeignKeyConstraint
from ... import Index
from ... import inspect
from ... import Integer
from ... import schema
from ... import String
from ... import UniqueConstraint
class TableDDLTest(fixtures.TestBase):
__sparse_driver_backend__ = True
def _simple_fixture(self, schema=None):
return Table(
"test_table",
self.metadata,
Column("id", Integer, primary_key=True, autoincrement=False),
Column("data", String(50)),
schema=schema,
)
def _underscore_fixture(self):
return Table(
"_test_table",
self.metadata,
Column("id", Integer, primary_key=True, autoincrement=False),
Column("_data", String(50)),
)
def _table_index_fixture(self, schema=None):
table = self._simple_fixture(schema=schema)
idx = Index("test_index", table.c.data)
return table, idx
def _simple_roundtrip(self, table):
with config.db.begin() as conn:
conn.execute(table.insert().values((1, "some data")))
result = conn.execute(table.select())
eq_(result.first(), (1, "some data"))
@requirements.create_table
@util.provide_metadata
def test_create_table(self):
table = self._simple_fixture()
table.create(config.db, checkfirst=False)
self._simple_roundtrip(table)
@requirements.create_table
@requirements.schemas
@util.provide_metadata
def test_create_table_schema(self):
table = self._simple_fixture(schema=config.test_schema)
table.create(config.db, checkfirst=False)
self._simple_roundtrip(table)
@requirements.drop_table
@util.provide_metadata
def test_drop_table(self):
table = self._simple_fixture()
table.create(config.db, checkfirst=False)
table.drop(config.db, checkfirst=False)
@requirements.create_table
@util.provide_metadata
def test_underscore_names(self):
table = self._underscore_fixture()
table.create(config.db, checkfirst=False)
self._simple_roundtrip(table)
@requirements.comment_reflection
@util.provide_metadata
def test_add_table_comment(self, connection):
table = self._simple_fixture()
table.create(connection, checkfirst=False)
table.comment = "a comment"
connection.execute(schema.SetTableComment(table))
eq_(
inspect(connection).get_table_comment("test_table"),
{"text": "a comment"},
)
@requirements.comment_reflection
@util.provide_metadata
def test_drop_table_comment(self, connection):
table = self._simple_fixture()
table.create(connection, checkfirst=False)
table.comment = "a comment"
connection.execute(schema.SetTableComment(table))
connection.execute(schema.DropTableComment(table))
eq_(
inspect(connection).get_table_comment("test_table"), {"text": None}
)
@requirements.table_ddl_if_exists
@util.provide_metadata
def test_create_table_if_not_exists(self, connection):
table = self._simple_fixture()
connection.execute(schema.CreateTable(table, if_not_exists=True))
is_true(inspect(connection).has_table("test_table"))
connection.execute(schema.CreateTable(table, if_not_exists=True))
@requirements.index_ddl_if_exists
@util.provide_metadata
def test_create_index_if_not_exists(self, connection):
table, idx = self._table_index_fixture()
connection.execute(schema.CreateTable(table, if_not_exists=True))
is_true(inspect(connection).has_table("test_table"))
is_false(
"test_index"
in [
ix["name"]
for ix in inspect(connection).get_indexes("test_table")
]
)
connection.execute(schema.CreateIndex(idx, if_not_exists=True))
is_true(
"test_index"
in [
ix["name"]
for ix in inspect(connection).get_indexes("test_table")
]
)
connection.execute(schema.CreateIndex(idx, if_not_exists=True))
@requirements.table_ddl_if_exists
@util.provide_metadata
def test_drop_table_if_exists(self, connection):
table = self._simple_fixture()
table.create(connection)
is_true(inspect(connection).has_table("test_table"))
connection.execute(schema.DropTable(table, if_exists=True))
is_false(inspect(connection).has_table("test_table"))
connection.execute(schema.DropTable(table, if_exists=True))
@requirements.index_ddl_if_exists
@util.provide_metadata
def test_drop_index_if_exists(self, connection):
table, idx = self._table_index_fixture()
table.create(connection)
is_true(
"test_index"
in [
ix["name"]
for ix in inspect(connection).get_indexes("test_table")
]
)
connection.execute(schema.DropIndex(idx, if_exists=True))
is_false(
"test_index"
in [
ix["name"]
for ix in inspect(connection).get_indexes("test_table")
]
)
connection.execute(schema.DropIndex(idx, if_exists=True))
class FutureTableDDLTest(fixtures.FutureEngineMixin, TableDDLTest):
pass
class LongNameBlowoutTest(fixtures.TestBase):
"""test the creation of a variety of DDL structures and ensure
label length limits pass on backends
"""
__sparse_driver_backend__ = True
def fk(self, metadata, connection):
convention = {
"fk": "foreign_key_%(table_name)s_"
"%(column_0_N_name)s_"
"%(referred_table_name)s_"
+ (
"_".join(
"".join(random.choice("abcdef") for j in range(20))
for i in range(10)
)
),
}
metadata.naming_convention = convention
Table(
"a_things_with_stuff",
metadata,
Column("id_long_column_name", Integer, primary_key=True),
test_needs_fk=True,
)
cons = ForeignKeyConstraint(
["aid"], ["a_things_with_stuff.id_long_column_name"]
)
Table(
"b_related_things_of_value",
metadata,
Column(
"aid",
),
cons,
test_needs_fk=True,
)
actual_name = cons.name
metadata.create_all(connection)
if testing.requires.foreign_key_constraint_name_reflection.enabled:
insp = inspect(connection)
fks = insp.get_foreign_keys("b_related_things_of_value")
reflected_name = fks[0]["name"]
return actual_name, reflected_name
else:
return actual_name, None
def pk(self, metadata, connection):
convention = {
"pk": "primary_key_%(table_name)s_"
"%(column_0_N_name)s"
+ (
"_".join(
"".join(random.choice("abcdef") for j in range(30))
for i in range(10)
)
),
}
metadata.naming_convention = convention
a = Table(
"a_things_with_stuff",
metadata,
Column("id_long_column_name", Integer, primary_key=True),
Column("id_another_long_name", Integer, primary_key=True),
)
cons = a.primary_key
actual_name = cons.name
metadata.create_all(connection)
insp = inspect(connection)
pk = insp.get_pk_constraint("a_things_with_stuff")
reflected_name = pk["name"]
return actual_name, reflected_name
def ix(self, metadata, connection):
convention = {
"ix": "index_%(table_name)s_"
"%(column_0_N_name)s"
+ (
"_".join(
"".join(random.choice("abcdef") for j in range(30))
for i in range(10)
)
),
}
metadata.naming_convention = convention
a = Table(
"a_things_with_stuff",
metadata,
Column("id_long_column_name", Integer, primary_key=True),
Column("id_another_long_name", Integer),
)
cons = Index(None, a.c.id_long_column_name, a.c.id_another_long_name)
actual_name = cons.name
metadata.create_all(connection)
insp = inspect(connection)
ix = insp.get_indexes("a_things_with_stuff")
reflected_name = ix[0]["name"]
return actual_name, reflected_name
def uq(self, metadata, connection):
convention = {
"uq": "unique_constraint_%(table_name)s_"
"%(column_0_N_name)s"
+ (
"_".join(
"".join(random.choice("abcdef") for j in range(30))
for i in range(10)
)
),
}
metadata.naming_convention = convention
cons = UniqueConstraint("id_long_column_name", "id_another_long_name")
Table(
"a_things_with_stuff",
metadata,
Column("id_long_column_name", Integer, primary_key=True),
Column("id_another_long_name", Integer),
cons,
)
actual_name = cons.name
metadata.create_all(connection)
insp = inspect(connection)
uq = insp.get_unique_constraints("a_things_with_stuff")
reflected_name = uq[0]["name"]
return actual_name, reflected_name
def ck(self, metadata, connection):
convention = {
"ck": "check_constraint_%(table_name)s"
+ (
"_".join(
"".join(random.choice("abcdef") for j in range(30))
for i in range(10)
)
),
}
metadata.naming_convention = convention
cons = CheckConstraint("some_long_column_name > 5")
Table(
"a_things_with_stuff",
metadata,
Column("id_long_column_name", Integer, primary_key=True),
Column("some_long_column_name", Integer),
cons,
)
actual_name = cons.name
metadata.create_all(connection)
insp = inspect(connection)
ck = insp.get_check_constraints("a_things_with_stuff")
reflected_name = ck[0]["name"]
return actual_name, reflected_name
@testing.combinations(
("fk",),
("pk",),
("ix",),
("ck", testing.requires.check_constraint_reflection.as_skips()),
("uq", testing.requires.unique_constraint_reflection.as_skips()),
argnames="type_",
)
def test_long_convention_name(self, type_, metadata, connection):
actual_name, reflected_name = getattr(self, type_)(
metadata, connection
)
assert len(actual_name) > 255
if reflected_name is not None:
overlap = actual_name[0 : len(reflected_name)]
if len(overlap) < len(actual_name):
eq_(overlap[0:-5], reflected_name[0 : len(overlap) - 5])
else:
eq_(overlap, reflected_name)
__all__ = ("TableDDLTest", "FutureTableDDLTest", "LongNameBlowoutTest")