forked from cleveragents/cleveragents-core
ae1fd648d5
Implement PlanSyncClient for synchronizing local resources with a remote CleverAgents server and submitting plans for remote execution: - Sync actions, skills, tools, projects with configurable scope flags - Conflict resolution policies (local_wins / server_wins) - Remote plan execution, apply, and status query endpoints - Server-side ID persistence in local item metadata - Sync summary output (created/updated/skipped/errors) - Dry-run mode that skips server mutations - SyncScope, SyncSummary, ExecutionResult data models - Behave scenarios (18 scenarios, 62 steps) - Robot Framework smoke tests - ASV benchmark for sync throughput baseline - Reference documentation at docs/reference/server_sync.md ISSUES CLOSED: #336
132 lines
5.7 KiB
Gherkin
132 lines
5.7 KiB
Gherkin
@phase2 @client @sync
|
|
Feature: Plan sync and remote execution
|
|
As a developer
|
|
I want to sync local plans with a remote server
|
|
So that I can execute plans remotely and keep state in sync
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Sync scope
|
|
# ---------------------------------------------------------------------------
|
|
|
|
Scenario: SyncScope returns all types when all flags are true
|
|
Given a SyncScope with all flags enabled
|
|
Then the active types should be "actions,skills,tools,projects"
|
|
|
|
Scenario: SyncScope returns only selected types
|
|
Given a SyncScope with only actions and tools enabled
|
|
Then the active types should be "actions,tools"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Sync operations
|
|
# ---------------------------------------------------------------------------
|
|
|
|
Scenario: Sync creates new items on the server
|
|
Given a PlanSyncClient with a mock HTTP client
|
|
And a list of 2 new items without server_id
|
|
When I sync the items as "actions"
|
|
Then the sync summary should show 2 created and 0 updated
|
|
And the sync summary should not be a dry run
|
|
|
|
Scenario: Sync updates existing items on the server
|
|
Given a PlanSyncClient with a mock HTTP client
|
|
And a list of 2 existing items with server_id and newer version
|
|
When I sync the items as "tools"
|
|
Then the sync summary should show 0 created and 2 updated
|
|
|
|
Scenario: Sync skips items with matching version
|
|
Given a PlanSyncClient with a mock HTTP client
|
|
And a list of 1 existing items with server_id and same version
|
|
When I sync the items as "skills"
|
|
Then the sync summary should show 0 created and 0 updated and 1 skipped
|
|
|
|
Scenario: Sync dry-run does not mutate server
|
|
Given a PlanSyncClient with a mock HTTP client
|
|
And a list of 2 new items without server_id
|
|
When I sync the items as "actions" with dry_run true
|
|
Then the sync summary should show 2 created and 0 updated
|
|
And the sync summary should be a dry run
|
|
|
|
Scenario: Sync handles items missing id as errors
|
|
Given a PlanSyncClient with a mock HTTP client
|
|
And a list with one item missing id
|
|
When I sync the items as "actions"
|
|
Then the sync summary should show 0 created and 0 updated and 1 error
|
|
|
|
Scenario: Sync server_wins policy skips when server version is newer
|
|
Given a PlanSyncClient with server_wins conflict policy
|
|
And a list of 1 existing items where server version is newer
|
|
When I sync the items as "tools"
|
|
Then the sync summary should show 0 created and 0 updated and 1 skipped
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Sync all
|
|
# ---------------------------------------------------------------------------
|
|
|
|
Scenario: Sync all respects scope flags
|
|
Given a PlanSyncClient with a mock HTTP client
|
|
And resources for actions and tools
|
|
When I sync all with a scope limited to actions only
|
|
Then the sync result should contain actions but not tools
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Remote execution
|
|
# ---------------------------------------------------------------------------
|
|
|
|
Scenario: Execute plan returns execution result
|
|
Given a PlanSyncClient with a mock HTTP client for execution
|
|
When I execute plan "plan-001"
|
|
Then the execution result plan_id should be "plan-001"
|
|
And the execution result status should be "submitted"
|
|
|
|
Scenario: Apply plan returns execution result
|
|
Given a PlanSyncClient with a mock HTTP client for execution
|
|
When I apply plan "plan-002"
|
|
Then the execution result plan_id should be "plan-002"
|
|
And the execution result status should be "applying"
|
|
|
|
Scenario: Get plan status returns status dict
|
|
Given a PlanSyncClient with a mock HTTP client for status
|
|
When I get status for server plan "srv-001"
|
|
Then the plan status should contain phase "running"
|
|
|
|
Scenario: Execute plan with empty id raises ValueError
|
|
Given a PlanSyncClient with a mock HTTP client
|
|
When I execute plan with empty id
|
|
Then a ValueError should be raised for empty sync plan_id
|
|
|
|
Scenario: Apply plan with empty id raises ValueError
|
|
Given a PlanSyncClient with a mock HTTP client
|
|
When I apply plan with empty id
|
|
Then a ValueError should be raised for empty sync plan_id
|
|
|
|
Scenario: Get plan status with empty id raises ValueError
|
|
Given a PlanSyncClient with a mock HTTP client
|
|
When I get status with empty server plan id
|
|
Then a ValueError should be raised for empty sync plan_id
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Conflict policy
|
|
# ---------------------------------------------------------------------------
|
|
|
|
Scenario: Conflict policy can be changed at runtime
|
|
Given a PlanSyncClient with local_wins conflict policy
|
|
When I change the conflict policy to server_wins
|
|
Then the conflict policy should be server_wins
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# SyncSummary
|
|
# ---------------------------------------------------------------------------
|
|
|
|
Scenario: SyncSummary total_processed counts all fields
|
|
Given a SyncSummary with 2 created 1 updated 1 skipped 1 errors
|
|
Then the total processed should be 5
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# ExecutionResult attributes
|
|
# ---------------------------------------------------------------------------
|
|
|
|
Scenario: ExecutionResult stores all attributes
|
|
Given an ExecutionResult with plan_id "p1" server_plan_id "sp1" status "done" message "ok"
|
|
Then the execution result message should be "ok"
|
|
And the execution result server_plan_id should be "sp1"
|