6f7ab08e12
CI / lint (pull_request) Successful in 13s
CI / typecheck (pull_request) Successful in 28s
CI / quality (pull_request) Successful in 16s
CI / security (pull_request) Successful in 29s
CI / integration_tests (pull_request) Successful in 5m22s
CI / build (pull_request) Successful in 16s
CI / unit_tests (pull_request) Successful in 15m25s
CI / coverage (pull_request) Successful in 8m26s
CI / docker (pull_request) Successful in 40s
# Conflicts: # benchmarks/cli_format_bench.py # benchmarks/plan_phase_migration_bench.py # benchmarks/project_migration_bench.py # benchmarks/resource_registry_migration_bench.py # benchmarks/uow_lifecycle_bench.py
206 lines
6.2 KiB
Python
206 lines
6.2 KiB
Python
"""ASV benchmarks for resource registry migration and ORM operations.
|
|
|
|
Measures:
|
|
- Schema creation time (Base.metadata.create_all)
|
|
- ResourceTypeModel insert throughput
|
|
- ResourceModel insert throughput
|
|
- ResourceEdgeModel insert throughput
|
|
- DAG query performance (children/parents lookup)
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from datetime import UTC, datetime
|
|
|
|
from sqlalchemy import create_engine
|
|
from sqlalchemy.orm import sessionmaker
|
|
|
|
from cleveragents.infrastructure.database.models import (
|
|
Base,
|
|
ResourceEdgeModel,
|
|
ResourceModel,
|
|
ResourceTypeModel,
|
|
)
|
|
|
|
|
|
def _now_iso() -> str:
|
|
return datetime.now(tz=UTC).isoformat()
|
|
|
|
|
|
def _make_ulid(n: int) -> str:
|
|
return str(n).zfill(26)
|
|
|
|
|
|
class SchemaCreation:
|
|
"""Benchmark schema creation (all tables via metadata.create_all)."""
|
|
|
|
def time_create_all_tables(self) -> None:
|
|
engine = create_engine("sqlite:///:memory:")
|
|
Base.metadata.create_all(engine)
|
|
engine.dispose()
|
|
|
|
|
|
class ResourceTypeInsert:
|
|
"""Benchmark inserting resource type records."""
|
|
|
|
def setup(self) -> None:
|
|
self.engine = create_engine("sqlite:///:memory:")
|
|
Base.metadata.create_all(self.engine)
|
|
self.session_factory = sessionmaker(bind=self.engine)
|
|
self._iter = 0
|
|
|
|
def teardown(self) -> None:
|
|
self.engine.dispose()
|
|
|
|
def time_insert_single_resource_type(self) -> None:
|
|
self._iter += 1
|
|
session = self.session_factory()
|
|
rt = ResourceTypeModel()
|
|
rt.name = f"bench/type-single-{self._iter}"
|
|
rt.namespace = "bench"
|
|
rt.resource_kind = "physical"
|
|
rt.user_addable = True
|
|
rt.created_at = _now_iso()
|
|
rt.updated_at = _now_iso()
|
|
session.add(rt)
|
|
session.commit()
|
|
session.close()
|
|
|
|
def time_insert_100_resource_types(self) -> None:
|
|
self._iter += 1
|
|
batch = self._iter
|
|
session = self.session_factory()
|
|
for i in range(100):
|
|
rt = ResourceTypeModel()
|
|
rt.name = f"bench/type-{batch}-{i}"
|
|
rt.namespace = "bench"
|
|
rt.resource_kind = "physical" if i % 2 == 0 else "virtual"
|
|
rt.user_addable = i % 3 == 0
|
|
rt.args_schema_json = json.dumps([{"flag": f"--arg-{batch}-{i}"}])
|
|
rt.created_at = _now_iso()
|
|
rt.updated_at = _now_iso()
|
|
session.add(rt)
|
|
session.commit()
|
|
session.close()
|
|
|
|
|
|
class ResourceInsert:
|
|
"""Benchmark inserting resource records."""
|
|
|
|
def setup(self) -> None:
|
|
self.engine = create_engine("sqlite:///:memory:")
|
|
Base.metadata.create_all(self.engine)
|
|
self.session_factory = sessionmaker(bind=self.engine)
|
|
session = self.session_factory()
|
|
rt = ResourceTypeModel()
|
|
rt.name = "bench/git-checkout"
|
|
rt.namespace = "bench"
|
|
rt.resource_kind = "physical"
|
|
rt.user_addable = True
|
|
rt.created_at = _now_iso()
|
|
rt.updated_at = _now_iso()
|
|
session.add(rt)
|
|
session.commit()
|
|
session.close()
|
|
self._iter = 0
|
|
|
|
def teardown(self) -> None:
|
|
self.engine.dispose()
|
|
|
|
def time_insert_100_resources(self) -> None:
|
|
self._iter += 1
|
|
batch = self._iter
|
|
session = self.session_factory()
|
|
for i in range(100):
|
|
idx = batch * 1000 + i
|
|
r = ResourceModel()
|
|
r.resource_id = _make_ulid(idx)
|
|
r.namespaced_name = f"bench/resource-{batch}-{i}"
|
|
r.namespace = "bench"
|
|
r.type_name = "bench/git-checkout"
|
|
r.resource_kind = "physical"
|
|
r.location = f"/path/to/resource-{idx}"
|
|
r.properties_json = json.dumps({"index": idx})
|
|
r.created_at = _now_iso()
|
|
r.updated_at = _now_iso()
|
|
session.add(r)
|
|
session.commit()
|
|
session.close()
|
|
|
|
|
|
class ResourceEdgeQuery:
|
|
"""Benchmark DAG edge queries (children/parents lookup)."""
|
|
|
|
def setup(self) -> None:
|
|
self.engine = create_engine("sqlite:///:memory:")
|
|
Base.metadata.create_all(self.engine)
|
|
self.session_factory = sessionmaker(bind=self.engine)
|
|
session = self.session_factory()
|
|
|
|
# Create types
|
|
for tname in ("bench/parent-type", "bench/child-type"):
|
|
rt = ResourceTypeModel()
|
|
rt.name = tname
|
|
rt.namespace = "bench"
|
|
rt.resource_kind = "physical"
|
|
rt.user_addable = True
|
|
rt.created_at = _now_iso()
|
|
rt.updated_at = _now_iso()
|
|
session.add(rt)
|
|
|
|
# Create 1 parent + 50 children with edges
|
|
parent = ResourceModel()
|
|
parent.resource_id = _make_ulid(0)
|
|
parent.namespaced_name = "bench/parent"
|
|
parent.namespace = "bench"
|
|
parent.type_name = "bench/parent-type"
|
|
parent.resource_kind = "physical"
|
|
parent.created_at = _now_iso()
|
|
parent.updated_at = _now_iso()
|
|
session.add(parent)
|
|
self.parent_id = parent.resource_id
|
|
|
|
for i in range(1, 51):
|
|
child = ResourceModel()
|
|
child.resource_id = _make_ulid(i)
|
|
child.type_name = "bench/child-type"
|
|
child.resource_kind = "physical"
|
|
child.created_at = _now_iso()
|
|
child.updated_at = _now_iso()
|
|
session.add(child)
|
|
|
|
edge = ResourceEdgeModel()
|
|
edge.parent_id = parent.resource_id
|
|
edge.child_id = child.resource_id
|
|
edge.link_type = "contains"
|
|
edge.created_at = _now_iso()
|
|
session.add(edge)
|
|
|
|
session.commit()
|
|
session.close()
|
|
|
|
def teardown(self) -> None:
|
|
self.engine.dispose()
|
|
|
|
def time_query_50_children(self) -> None:
|
|
session = self.session_factory()
|
|
edges = (
|
|
session.query(ResourceEdgeModel)
|
|
.filter(ResourceEdgeModel.parent_id == self.parent_id)
|
|
.all()
|
|
)
|
|
assert len(edges) == 50
|
|
session.close()
|
|
|
|
def time_query_parent_of_child(self) -> None:
|
|
session = self.session_factory()
|
|
child_id = _make_ulid(25)
|
|
edges = (
|
|
session.query(ResourceEdgeModel)
|
|
.filter(ResourceEdgeModel.child_id == child_id)
|
|
.all()
|
|
)
|
|
assert len(edges) == 1
|
|
session.close()
|