"""Provision (or deactivate) the isolated "loadtest" tenant used by the load test. Runs inside a ServiceOps container: `python provision.py [--deactivate]`. Everything it creates lives in its own tenant, so production users never see it. Environment: LOADTEST_USERS (default 1000), LOADTEST_PASSWORD (required), LOADTEST_TICKETS (default 300). """ import os import sys if os.path.isdir("/app"): sys.path.insert(0, "/app") from serviceops_core.security import hash_password # noqa: E402 from serviceops_models import ( # noqa: E402 GroupMember, SupportGroup, Tenant, Ticket, TicketAssignmentGroup, User, UserRoleGrant, db, now, ) SLUG = "loadtest" USERS = int(os.environ.get("LOADTEST_USERS", "1000")) TICKETS = int(os.environ.get("LOADTEST_TICKETS", "300")) def deactivate(): tenant = Tenant.query.filter_by(slug=SLUG).first() if tenant: tenant.active = False User.query.filter_by(tenant_id=tenant.id).update({"active": False}) db.session.commit() return f"deactivated tenant={SLUG}" def provision(password, users_wanted=USERS, tickets_wanted=TICKETS): tenant = Tenant.query.filter_by(slug=SLUG).first() if not tenant: tenant = Tenant(slug=SLUG, name="Load test (synthetic)") db.session.add(tenant) db.session.flush() tenant.active = True group = SupportGroup.query.filter_by(name="Load Test Desk", tenant_id=tenant.id).first() if not group: group = SupportGroup(name="Load Test Desk", group_type="IT Fulfillment", tenant_id=tenant.id) db.session.add(group) db.session.flush() password_hash = hash_password(password) # one hash shared by every synthetic account existing = {u.username: u for u in User.query.filter(User.username.like("loadtest-%")).all()} members = {m.user_id for m in GroupMember.query.filter_by(group_id=group.id).all()} created = 0 users = [] for index in range(1, users_wanted + 1): username = f"loadtest-{index:04d}" user = existing.get(username) if not user: user = User(username=username, name=f"Load Test {index:04d}", email=f"{username}@loadtest.invalid", password_hash=password_hash, role="agent", tenant_id=tenant.id) db.session.add(user) db.session.flush() db.session.add(UserRoleGrant(user_id=user.id, role="agent")) created += 1 user.active, user.password_hash, user.tenant_id = True, password_hash, tenant.id user.failed_login_count, user.locked_until = 0, None if user.id not in members: db.session.add(GroupMember(group_id=group.id, user_id=user.id, role="member")) users.append(user) db.session.flush() have = Ticket.query.filter_by(tenant_id=tenant.id).count() for index in range(have, tickets_wanted): kind = ("incident", "change", "problem")[index % 3] prefix = {"incident": "LTI", "change": "LTC", "problem": "LTP"}[kind] ticket = Ticket(number=f"{prefix}{index:07d}", kind=kind, title=f"Load test {kind} {index}", description="Synthetic record for load testing.", requester_id=users[index % len(users)].id, assignee_id=users[(index * 7) % len(users)].id, priority=f"P{1 + index % 4}", state="New", tenant_id=tenant.id, created_at=now()) db.session.add(ticket) db.session.flush() db.session.add(TicketAssignmentGroup(ticket_id=ticket.id, group_id=group.id)) db.session.commit() return (f"tenant={SLUG} id={tenant.id} group={group.id} users_created={created} users_total={len(users)} " f"tickets={Ticket.query.filter_by(tenant_id=tenant.id).count()}") if __name__ == "__main__": from app import create_app with create_app().app_context(): print(deactivate() if "--deactivate" in sys.argv else provision(os.environ["LOADTEST_PASSWORD"]))