ff9c6540a2
Implement entity synchronization between client and server using the _cleveragents/sync/* A2A extension methods per the specification. Sync models (src/cleveragents/a2a/sync_models.py): - Pydantic v2 models for pull/push/status requests and responses - VectorClock with increment, merge, happens-before, and concurrency detection for distributed conflict detection - SyncEntitySnapshot, SyncConflict, SyncState, SyncQueueEntry models - SyncEntityType enum: actor, skill, action, plan, session - ConflictResolution enum: last_writer_wins, manual, server_wins, client_wins SyncService (src/cleveragents/application/services/sync_service.py): - pull(): download server namespace entities to local cache with incremental sync (since timestamps) and force-overwrite option - push(): push local entity definitions to server namespace with configurable conflict resolution strategy - status(): compare local and server entity versions, detect drift, report local-ahead, server-ahead, and concurrent conflicts - resolve_conflict(): manually resolve detected conflicts with winner selection (local or server) - Offline queue: enqueue_offline() and process_offline_queue() for retry on reconnect, with max-retries enforcement - The local/ namespace is never synced per specification A2A facade (src/cleveragents/a2a/facade.py): - Replaced sync stub handlers with real _handle_sync_pull, _handle_sync_push, _handle_sync_status routing to SyncService - Added sync_service property and TYPE_CHECKING import - Facade returns stubs when no SyncService is registered Tests: - Behave BDD: features/entity_sync.feature (65 scenarios, 247 steps) covering models, vector clocks, pull/push/status, conflict resolution, offline queue, facade integration, constructor validation, edge cases - Robot Framework: robot/entity_sync.robot (8 integration tests) ISSUES CLOSED: #866
75 lines
3.2 KiB
Plaintext
75 lines
3.2 KiB
Plaintext
*** Settings ***
|
|
Documentation Integration tests for entity sync (_cleveragents/sync/*)
|
|
Resource ${CURDIR}/common.resource
|
|
Suite Setup Setup Test Environment
|
|
Suite Teardown Cleanup Test Environment
|
|
|
|
*** Variables ***
|
|
${HELPER} ${CURDIR}/helper_entity_sync.py
|
|
|
|
*** Test Cases ***
|
|
Sync Pull Via Facade
|
|
[Documentation] Verify sync/pull works through A2A facade with SyncService
|
|
${result}= Run Process ${PYTHON} ${HELPER} sync-pull cwd=${WORKSPACE}
|
|
Log ${result.stdout}
|
|
Log ${result.stderr}
|
|
Should Be Equal As Integers ${result.rc} 0
|
|
Should Contain ${result.stdout} sync-pull-ok
|
|
|
|
Sync Push Via Facade
|
|
[Documentation] Verify sync/push works through A2A facade with SyncService
|
|
${result}= Run Process ${PYTHON} ${HELPER} sync-push cwd=${WORKSPACE}
|
|
Log ${result.stdout}
|
|
Log ${result.stderr}
|
|
Should Be Equal As Integers ${result.rc} 0
|
|
Should Contain ${result.stdout} sync-push-ok
|
|
|
|
Sync Status Via Facade
|
|
[Documentation] Verify sync/status detects drift through A2A facade
|
|
${result}= Run Process ${PYTHON} ${HELPER} sync-status cwd=${WORKSPACE}
|
|
Log ${result.stdout}
|
|
Log ${result.stderr}
|
|
Should Be Equal As Integers ${result.rc} 0
|
|
Should Contain ${result.stdout} sync-status-ok
|
|
|
|
Sync Conflict Resolution
|
|
[Documentation] Verify conflict detection and resolution with vector clocks
|
|
${result}= Run Process ${PYTHON} ${HELPER} sync-conflict-resolution cwd=${WORKSPACE}
|
|
Log ${result.stdout}
|
|
Log ${result.stderr}
|
|
Should Be Equal As Integers ${result.rc} 0
|
|
Should Contain ${result.stdout} sync-conflict-resolution-ok
|
|
|
|
Sync Offline Queue
|
|
[Documentation] Verify offline queue enqueue and processing
|
|
${result}= Run Process ${PYTHON} ${HELPER} sync-offline-queue cwd=${WORKSPACE}
|
|
Log ${result.stdout}
|
|
Log ${result.stderr}
|
|
Should Be Equal As Integers ${result.rc} 0
|
|
Should Contain ${result.stdout} sync-offline-queue-ok
|
|
|
|
Sync Vector Clock Operations
|
|
[Documentation] Verify vector clock increment, merge, happens-before, concurrent
|
|
${result}= Run Process ${PYTHON} ${HELPER} sync-vector-clock cwd=${WORKSPACE}
|
|
Log ${result.stdout}
|
|
Log ${result.stderr}
|
|
Should Be Equal As Integers ${result.rc} 0
|
|
Should Contain ${result.stdout} sync-vector-clock-ok
|
|
|
|
Sync Facade Without Service Returns Stubs
|
|
[Documentation] Verify sync operations return stubs when no SyncService is registered
|
|
${result}= Run Process ${PYTHON} ${HELPER} sync-facade-no-service cwd=${WORKSPACE}
|
|
Log ${result.stdout}
|
|
Log ${result.stderr}
|
|
Should Be Equal As Integers ${result.rc} 0
|
|
Should Contain ${result.stdout} sync-facade-no-service-ok
|
|
|
|
Sync Incremental Pull
|
|
[Documentation] Verify incremental sync only pulls entities updated after since timestamp
|
|
${result}= Run Process ${PYTHON} ${HELPER} sync-incremental cwd=${WORKSPACE}
|
|
Log ${result.stdout}
|
|
Log ${result.stderr}
|
|
Should Be Equal As Integers ${result.rc} 0
|
|
Should Contain ${result.stdout} sync-incremental-ok
|
|
*** Keywords ***
|