mirror of
https://github.com/hanzoai/agents.git
synced 2026-10-30 18:48:36 +00:00
Per global rule: /v1/ only, never /api/. Internal API calls + handler comments + route registrations updated. - Control plane: agentAPI mount moves from /api/v1 -> /v1; uiAPI from /api/ui/v1 -> /v1/ui; uiAPIV2 from /api/ui/v2 -> /v2/ui. Auth middleware /api/v1/health -> /v1/health. All UI handler comments updated. - Go SDK (sdk/go/agent, sdk/go/client): control_plane_memory_backend, discovery, agent, note, client now use /v1/* and /v1/ui/* canonically. - LegacyExecutionEndpoints catalog in pkg/types/execution.go normalized to /v1/* and /v1/ui/* (UIWorkflowRunList stays /v2/ui as it's the v2 surface). - All test fixtures updated to match the new contract. Build note: pre-existing rot in internal/utils/paths.go and internal/handlers/ui/env.go (hanzo-agentsHome is not a valid Go identifier; hyphens not allowed) prevents `go build ./...` from succeeding — this predates the sweep and is not introduced here.
82 lines
2.3 KiB
Go
82 lines
2.3 KiB
Go
package handlers
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/hanzoai/agents/control-plane/internal/services"
|
|
"github.com/hanzoai/agents/control-plane/pkg/types"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestHandleStatusUpdateMarksSuccess(t *testing.T) {
|
|
gin.SetMode(gin.TestMode)
|
|
|
|
storage := newTestExecutionStorage(&types.AgentNode{ID: "agent-1"})
|
|
now := time.Now().UTC().Add(-time.Minute)
|
|
exec := &types.Execution{
|
|
ExecutionID: "exec-123",
|
|
RunID: "run-123",
|
|
AgentNodeID: "agent-1",
|
|
ReasonerID: "reasoner",
|
|
NodeID: "agent-1",
|
|
Status: types.ExecutionStatusRunning,
|
|
StartedAt: now,
|
|
CreatedAt: now,
|
|
UpdatedAt: now,
|
|
}
|
|
require.NoError(t, storage.CreateExecutionRecord(context.Background(), exec))
|
|
|
|
workflow := &types.WorkflowExecution{
|
|
ExecutionID: exec.ExecutionID,
|
|
WorkflowID: exec.RunID,
|
|
StartedAt: now,
|
|
CreatedAt: now,
|
|
UpdatedAt: now,
|
|
}
|
|
require.NoError(t, storage.StoreWorkflowExecution(context.Background(), workflow))
|
|
|
|
payloadStore := services.NewFilePayloadStore(t.TempDir())
|
|
handler := UpdateExecutionStatusHandler(storage, payloadStore, nil, 90*time.Second)
|
|
|
|
body := map[string]interface{}{
|
|
"status": "succeeded",
|
|
"result": map[string]string{
|
|
"value": "done",
|
|
},
|
|
"duration_ms": 1500,
|
|
}
|
|
payload, err := json.Marshal(body)
|
|
require.NoError(t, err)
|
|
|
|
req := httptest.NewRequest(http.MethodPost, "/v1/executions/exec-123/status", bytes.NewReader(payload))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
w := httptest.NewRecorder()
|
|
ctx, _ := gin.CreateTestContext(w)
|
|
ctx.Params = gin.Params{gin.Param{Key: "execution_id", Value: exec.ExecutionID}}
|
|
ctx.Request = req.WithContext(context.Background())
|
|
|
|
handler(ctx)
|
|
|
|
require.Equal(t, http.StatusOK, w.Code)
|
|
|
|
var resp ExecutionStatusResponse
|
|
require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
|
|
require.Equal(t, "succeeded", resp.Status)
|
|
|
|
updated, err := storage.GetExecutionRecord(context.Background(), exec.ExecutionID)
|
|
require.NoError(t, err)
|
|
require.Equal(t, types.ExecutionStatusSucceeded, updated.Status)
|
|
require.NotNil(t, updated.CompletedAt)
|
|
require.NotNil(t, updated.DurationMS)
|
|
require.NotNil(t, updated.ResultPayload)
|
|
require.NotNil(t, updated.ResultURI)
|
|
}
|