Files
cleveragents-core/robot/changeset_persistence.robot
T
freemo e3fcce413b
CI / lint (pull_request) Successful in 24s
CI / typecheck (pull_request) Successful in 59s
CI / security (pull_request) Successful in 53s
CI / quality (pull_request) Successful in 36s
CI / benchmark-publish (pull_request) Has been skipped
CI / build (pull_request) Successful in 27s
CI / integration_tests (pull_request) Successful in 5m30s
CI / benchmark-regression (pull_request) Successful in 25m38s
CI / unit_tests (pull_request) Successful in 36m51s
CI / docker (pull_request) Successful in 1m3s
CI / coverage (pull_request) Successful in 1h48m49s
CI / lint (push) Successful in 22s
CI / security (push) Successful in 58s
CI / typecheck (push) Successful in 1m3s
CI / quality (push) Successful in 46s
CI / build (push) Successful in 23s
CI / integration_tests (push) Successful in 5m23s
CI / benchmark-regression (push) Has been skipped
CI / benchmark-publish (push) Successful in 15m5s
CI / unit_tests (push) Successful in 20m1s
CI / docker (push) Successful in 1m0s
CI / coverage (push) Successful in 1h45m36s
feat(changeset): persist changesets and diff artifacts
Add SQLite persistence for ChangeSet entries and ToolInvocation records
via new changeset_repository module implementing the ChangeSetStore protocol.

- Alembic migration d0_001 creates changeset_entries and tool_invocations tables
- SqliteChangeSetStore, ChangeSetEntryRepository, ToolInvocationRepository
- PlanApplyService.cleanup_changeset() for cancel/failure cleanup
- Behave tests (17 scenarios), Robot tests (5 cases), ASV benchmarks
- Reference documentation in docs/reference/changeset.md

Closes #163
2026-02-26 02:47:14 +00:00

87 lines
3.7 KiB
Plaintext

*** Settings ***
Documentation Integration tests for ChangeSet persistence via CLI plan artifacts output.
Library OperatingSystem
Library Process
Library Collections
Suite Setup Set Suite Variables
Force Tags changeset persistence
*** Variables ***
${PYTHON} python
${TIMEOUT} 30s
*** Keywords ***
Set Suite Variables
Set Suite Variable ${AGENTS} ${PYTHON} -m cleveragents.cli.main
Run Agents Command
[Arguments] @{args}
${result}= Run Process ${PYTHON} -m cleveragents.cli.main @{args}
... timeout=${TIMEOUT}
... env:CLEVERAGENTS_TESTING_USE_MOCK_AI=true
... env:CLEVERAGENTS_AUTO_APPLY_MIGRATIONS=true
... env:NO_COLOR=1
RETURN ${result}
*** Test Cases ***
Plan Artifacts Shows Changeset ID Field
[Documentation] Verify plan artifacts output contains changeset_id field.
${result}= Run Agents Command plan artifacts --help
Should Contain ${result.stdout} plan_id
... msg=Plan artifacts help should mention plan_id
Plan Diff Help Shows Format Options
[Documentation] Verify plan diff command exposes format options.
${result}= Run Agents Command plan diff --help
Should Contain ${result.stdout} format
... msg=Plan diff help should mention format option
Plan Artifacts Help Contains Expected Text
[Documentation] Verify plan artifacts help text is present.
${result}= Run Agents Command plan artifacts --help
Should Contain ${result.stdout} artifacts
... msg=Help text should mention artifacts
Changeset Persistence Module Is Importable
[Documentation] Verify the changeset_repository module can be imported.
${result}= Run Process ${PYTHON} -c
... from cleveragents.infrastructure.database.changeset_repository import SqliteChangeSetStore; print("OK")
... timeout=${TIMEOUT}
... env:PYTHONPATH=src
Should Be Equal As Strings ${result.stdout.strip()} OK
SqliteChangeSetStore Round Trip Via CLI Script
[Documentation] Run a Python script that exercises SqliteChangeSetStore round-trip.
${script}= Catenate SEPARATOR=\n
... import sys
... from sqlalchemy import create_engine
... from sqlalchemy.orm import sessionmaker
... from cleveragents.infrastructure.database.models import Base
... from cleveragents.infrastructure.database.changeset_repository import SqliteChangeSetStore
... from cleveragents.domain.models.core.change import ChangeEntry, ChangeOperation
... engine = create_engine("sqlite:///:memory:", connect_args={"check_same_thread": False})
... Base.metadata.create_all(engine)
... factory = sessionmaker(bind=engine)
... store = SqliteChangeSetStore(factory)
... cs_id = store.start("plan-robot-1")
... entry = ChangeEntry(plan_id="plan-robot-1", resource_id="res-1", tool_name="file-write", operation=ChangeOperation.CREATE, path="src/test.py", after_hash="abc123")
... store.record(cs_id, entry)
... factory().commit()
... cs = store.get(cs_id)
... assert cs is not None
... assert len(cs.entries) == 1
... summary = store.summarize(cs_id)
... assert summary["total"] == 1
... assert summary["creates"] == 1
... store.delete_for_plan("plan-robot-1")
... factory().commit()
... cs2 = store.get(cs_id)
... assert cs2 is None or len(cs2.entries) == 0
... print("PASS")
${result}= Run Process ${PYTHON} -c ${script}
... timeout=${TIMEOUT}
... env:PYTHONPATH=src
Should Contain ${result.stdout} PASS
... msg=SqliteChangeSetStore round-trip failed: ${result.stderr}