Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions pytest.ini
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,3 @@ pythonpath = .
addopts = -p no:warnings -p no:ddtrace -p no:ddtrace.pytest_bdd -p no:ddtrace.pytest_benchmark
asyncio_mode = auto
asyncio_default_fixture_loop_scope = function
markers =
postgresql: tests that require a PostgreSQL database
Original file line number Diff line number Diff line change
@@ -1,37 +1,15 @@
import os
import uuid
from datetime import UTC, datetime, timedelta

import pytest
from sqlalchemy import select
from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine
from sqlalchemy.ext.asyncio import async_sessionmaker

from storage.org import Org
from storage.org_store import OrgStore

pytestmark = pytest.mark.postgresql


@pytest.fixture
async def postgres_session_maker():
dsn = os.getenv('POSTGRES_TEST_DATABASE_URL')
if not dsn:
pytest.skip('POSTGRES_TEST_DATABASE_URL is required')

engine = create_async_engine(dsn, echo=False)
async with engine.begin() as conn:
await conn.run_sync(Org.__table__.drop, checkfirst=True)
await conn.run_sync(Org.__table__.create)

try:
yield async_sessionmaker(engine, expire_on_commit=False)
finally:
async with engine.begin() as conn:
await conn.run_sync(Org.__table__.drop, checkfirst=True)
await engine.dispose()


async def _insert_orgs(session_maker, rows):
async def _insert_orgs(session_maker: async_sessionmaker, rows) -> None:
async with session_maker() as session:
async with session.begin():
for name, agent_settings in rows:
Expand All @@ -44,18 +22,18 @@ async def _insert_orgs(session_maker, rows):
)


async def _settings_by_name(session_maker):
async def _settings_by_name(session_maker: async_sessionmaker) -> dict:
async with session_maker() as session:
rows = (await session.execute(select(Org.name, Org.agent_settings))).all()
return {name: settings for name, settings in rows}


@pytest.mark.asyncio
async def test_reconcile_non_overwrite_updates_only_unset_applicable_rows(
postgres_session_maker,
async_session_maker: async_sessionmaker,
):
await _insert_orgs(
postgres_session_maker,
async_session_maker,
[
('missing-condenser', {'agent_kind': 'openhands'}),
('json-null-condenser', {'condenser': None}),
Expand All @@ -69,7 +47,7 @@ async def test_reconcile_non_overwrite_updates_only_unset_applicable_rows(
],
)

async with postgres_session_maker() as session:
async with async_session_maker() as session:
async with session.begin():
result = await OrgStore.reconcile_applicable_org_condenser_max_tokens(
session,
Expand All @@ -82,7 +60,7 @@ async def test_reconcile_non_overwrite_updates_only_unset_applicable_rows(
assert result.skipped_condenser_variant_count == 1
assert result.malformed_repaired_count == 2

settings = await _settings_by_name(postgres_session_maker)
settings = await _settings_by_name(async_session_maker)
assert settings['missing-condenser']['condenser']['max_tokens'] == 200000
assert settings['json-null-condenser']['condenser']['max_tokens'] == 200000
assert settings['missing-max-tokens']['condenser']['enabled'] is True
Expand All @@ -100,18 +78,18 @@ async def test_reconcile_non_overwrite_updates_only_unset_applicable_rows(

@pytest.mark.asyncio
async def test_reconcile_overwrite_forces_applicable_existing_values(
postgres_session_maker,
async_session_maker: async_sessionmaker,
):
await _insert_orgs(
postgres_session_maker,
async_session_maker,
[
('existing-max-tokens', {'condenser': {'max_tokens': 123456}}),
('noop-condenser', {'condenser': {'condenser_kind': 'no_op'}}),
('acp-agent', {'agent_kind': 'acp'}),
],
)

async with postgres_session_maker() as session:
async with async_session_maker() as session:
async with session.begin():
result = await OrgStore.reconcile_applicable_org_condenser_max_tokens(
session,
Expand All @@ -124,18 +102,18 @@ async def test_reconcile_overwrite_forces_applicable_existing_values(
assert result.skipped_condenser_variant_count == 1
assert result.malformed_repaired_count == 0

settings = await _settings_by_name(postgres_session_maker)
settings = await _settings_by_name(async_session_maker)
assert settings['existing-max-tokens']['condenser']['max_tokens'] == 200000
assert settings['noop-condenser']['condenser'] == {'condenser_kind': 'no_op'}
assert 'condenser' not in settings['acp-agent']


@pytest.mark.asyncio
async def test_reconcile_bumps_updated_at_only_for_changed_rows(
postgres_session_maker,
async_session_maker: async_sessionmaker,
):
stale = datetime.now(UTC) - timedelta(days=30)
async with postgres_session_maker() as session:
async with async_session_maker() as session:
async with session.begin():
session.add_all(
[
Expand All @@ -154,15 +132,15 @@ async def test_reconcile_bumps_updated_at_only_for_changed_rows(
]
)

async with postgres_session_maker() as session:
async with async_session_maker() as session:
async with session.begin():
await OrgStore.reconcile_applicable_org_condenser_max_tokens(
session,
max_tokens=200000,
overwrite_existing=False,
)

async with postgres_session_maker() as session:
async with async_session_maker() as session:
rows = dict((await session.execute(select(Org.name, Org.updated_at))).all())

assert rows['changed'] > stale
Expand Down
Loading