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
65 changes: 47 additions & 18 deletions pkg/runtime/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,43 @@ import (
"github.com/stretchr/testify/require"
)

// httptest.Server.Close closes the global pool, so parallel tests need private transports.
func newTestTransport(t *testing.T) *http.Transport {
t.Helper()
transport := http.DefaultTransport.(*http.Transport).Clone()
t.Cleanup(transport.CloseIdleConnections)
return transport
}

func newTestClient(t *testing.T, baseURL string, opts ...ClientOption) *Client {
t.Helper()
opts = append([]ClientOption{WithHTTPClient(&http.Client{
Transport: newTestTransport(t),
Timeout: 30 * time.Second,
})}, opts...)
client, err := NewClient(baseURL, opts...)
require.NoError(t, err)
return client
}

func TestNewTestClientUsesPrivateTransport(t *testing.T) {
t.Parallel()

client := newTestClient(t, "http://127.0.0.1:1")
require.NotNil(t, client.httpClient.Transport)
assert.NotSame(t, http.DefaultTransport, client.httpClient.Transport)
assert.NotSame(t, client.httpClient.Transport, newTestClient(t, "http://127.0.0.1:1").httpClient.Transport)
assert.Equal(t, 30*time.Second, client.httpClient.Timeout)

timed := newTestClient(t, "http://127.0.0.1:1", WithTimeout(100*time.Millisecond))
assert.Equal(t, 100*time.Millisecond, timed.httpClient.Timeout)
assert.NotSame(t, http.DefaultTransport, timed.httpClient.Transport)

streaming := timed.streamingHTTPClient()
assert.Zero(t, streaming.Timeout)
assert.Same(t, timed.httpClient.Transport, streaming.Transport)
}

// TestClient_StreamSessionEvents_DeliversMultipleEvents verifies that the
// SSE stream stays open across multiple events instead of being torn down
// when StreamSessionEvents returns. This is a regression test for a bug
Expand Down Expand Up @@ -50,8 +87,7 @@ func TestClient_StreamSessionEvents_DeliversMultipleEvents(t *testing.T) {
t.Cleanup(srv.Close)
t.Cleanup(func() { close(proceed) })

c, err := NewClient(srv.URL)
require.NoError(t, err)
c := newTestClient(t, srv.URL)

ch, err := c.StreamSessionEvents(t.Context(), "s")
require.NoError(t, err)
Expand Down Expand Up @@ -96,8 +132,7 @@ func TestClient_StreamSessionEvents_StopsWhenContextCancelled(t *testing.T) {
}))
t.Cleanup(srv.Close)

c, err := NewClient(srv.URL)
require.NoError(t, err)
c := newTestClient(t, srv.URL)

ctx, cancel := context.WithCancel(t.Context())
t.Cleanup(cancel)
Expand Down Expand Up @@ -143,8 +178,7 @@ func TestClient_RunAgentIgnoresTotalHTTPTimeout(t *testing.T) {
}
}))
t.Cleanup(srv.Close)
c, err := NewClient(srv.URL, WithHTTPClient(&http.Client{Timeout: 100 * time.Millisecond}))
require.NoError(t, err)
c := newTestClient(t, srv.URL, WithHTTPClient(&http.Client{Timeout: 100 * time.Millisecond, Transport: newTestTransport(t)}))
ctx, cancel := context.WithCancel(t.Context())
t.Cleanup(cancel)
stream, err := c.RunAgent(ctx, "s", "agent.yaml", nil, "")
Expand Down Expand Up @@ -188,8 +222,7 @@ func TestClient_StreamSessionEventsReconnectsFromLastDeliveredID(t *testing.T) {
}
}))
t.Cleanup(srv.Close)
c, err := NewClient(srv.URL, WithAuthToken("secret"))
require.NoError(t, err)
c := newTestClient(t, srv.URL, WithAuthToken("secret"))
ctx, cancel := context.WithTimeout(t.Context(), 5*time.Second)
defer cancel()
stream, err := c.StreamSessionEvents(ctx, "s")
Expand All @@ -216,8 +249,7 @@ func TestClient_StreamSessionEventsGapRequiresSnapshot(t *testing.T) {
fmt.Fprint(w, "data: {\"type\":\"gap\"}\n\nid: 99\ndata: {\"type\":\"session_title\",\"title\":\"partial history\"}\n\n")
}))
t.Cleanup(srv.Close)
c, err := NewClient(srv.URL + "?since=1")
require.NoError(t, err)
c := newTestClient(t, srv.URL+"?since=1")
stream, err := c.StreamSessionEventsSince(t.Context(), "s", 7)
require.NoError(t, err)
var got []Event
Expand Down Expand Up @@ -245,11 +277,11 @@ func TestClient_SSECancelWithUnreadFullBuffer(t *testing.T) {
<-r.Context().Done()
}))
t.Cleanup(srv.Close)
c, err := NewClient(srv.URL)
require.NoError(t, err)
c := newTestClient(t, srv.URL)
ctx, cancel := context.WithCancel(t.Context())
t.Cleanup(cancel)
var stream <-chan Event
var err error
if run {
stream, err = c.RunAgent(ctx, "s", "agent.yaml", nil, "")
} else {
Expand Down Expand Up @@ -287,8 +319,7 @@ func TestClient_StreamSessionEventsReconnectsAfterEmptyConnection(t *testing.T)
fmt.Fprint(w, "id: 1\ndata: {\"type\":\"session_title\",\"title\":\"recovered\"}\n\nid: 2\ndata: {\"type\":\"session_exited\"}\n\n")
}))
t.Cleanup(srv.Close)
c, err := NewClient(srv.URL)
require.NoError(t, err)
c := newTestClient(t, srv.URL)
ctx, cancel := context.WithTimeout(t.Context(), 3*time.Second)
defer cancel()
stream, err := c.StreamSessionEvents(ctx, "s")
Expand Down Expand Up @@ -316,8 +347,7 @@ func TestClient_StreamSessionEventsIgnoresTotalHTTPTimeout(t *testing.T) {
}
}))
t.Cleanup(srv.Close)
client, err := NewClient(srv.URL, WithTimeout(100*time.Millisecond))
require.NoError(t, err)
client := newTestClient(t, srv.URL, WithTimeout(100*time.Millisecond))
ctx, cancel := context.WithTimeout(t.Context(), 3*time.Second)
defer cancel()
stream, err := client.StreamSessionEvents(ctx, "s")
Expand Down Expand Up @@ -356,8 +386,7 @@ func TestClient_RunAgentIncompleteStreamIsAnError(t *testing.T) {
}
}))
t.Cleanup(srv.Close)
client, err := NewClient(srv.URL)
require.NoError(t, err)
client := newTestClient(t, srv.URL)
stream, err := client.RunAgent(t.Context(), "s", "agent.yaml", nil, "")
require.NoError(t, err)
var got []Event
Expand Down
3 changes: 1 addition & 2 deletions pkg/runtime/evaluator_usage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -291,8 +291,7 @@ func TestEvaluatorUsagePersistenceAndSSE(t *testing.T) {
_, _ = fmt.Fprintf(w, "data: %s\n\n", payload)
}))
t.Cleanup(server.Close)
client, err := NewClient(server.URL)
require.NoError(t, err)
client := newTestClient(t, server.URL)
stream, err := client.StreamSessionEvents(t.Context(), sess.ID)
require.NoError(t, err)
var received []*EvaluationUsageEvent
Expand Down
3 changes: 1 addition & 2 deletions pkg/runtime/plan_events_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,7 @@ func TestClient_DecodesPlanChangedEvent(t *testing.T) {
}))
t.Cleanup(srv.Close)

c, err := NewClient(srv.URL)
require.NoError(t, err)
c := newTestClient(t, srv.URL)

ch, err := c.StreamSessionEvents(t.Context(), "s")
require.NoError(t, err)
Expand Down
3 changes: 1 addition & 2 deletions pkg/runtime/recovery_event_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ func TestSessionRecoveredEventContract(t *testing.T) {
fmt.Fprintf(w, "data: %s\n\n", data)
}))
t.Cleanup(srv.Close)
client, err := NewClient(srv.URL)
require.NoError(t, err)
client := newTestClient(t, srv.URL)
events, err := client.StreamSessionEvents(t.Context(), "root")
require.NoError(t, err)
var got []Event
Expand Down
12 changes: 4 additions & 8 deletions pkg/runtime/remote_runtime_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,7 @@ func TestRemoteRuntime_BackgroundEventsSurviveTurnsWithoutReplayingHistory(t *te
}
}))
t.Cleanup(srv.Close)
client, err := NewClient(srv.URL)
require.NoError(t, err)
client := newTestClient(t, srv.URL)
rt, err := NewRemoteRuntime(client)
require.NoError(t, err)
t.Cleanup(func() { require.NoError(t, rt.Close()) })
Expand Down Expand Up @@ -265,8 +264,7 @@ func TestRemoteRuntime_BackgroundSubscriptionWaitsForEventLogAndDeliversElicitat
}
}))
t.Cleanup(srv.Close)
client, err := NewClient(srv.URL)
require.NoError(t, err)
client := newTestClient(t, srv.URL)
rt, err := NewRemoteRuntime(client)
require.NoError(t, err)
t.Cleanup(func() { require.NoError(t, rt.Close()) })
Expand Down Expand Up @@ -345,8 +343,7 @@ func TestRemoteRuntime_BackgroundGapReconcilesSavedTextWithoutReplay(t *testing.
}
}))
t.Cleanup(srv.Close)
client, err := NewClient(srv.URL)
require.NoError(t, err)
client := newTestClient(t, srv.URL)
rt, err := NewRemoteRuntime(client)
require.NoError(t, err)
t.Cleanup(func() { require.NoError(t, rt.Close()) })
Expand Down Expand Up @@ -474,8 +471,7 @@ func TestRemoteRuntime_BackgroundGapWaitsForIdleAndCloseCancelsRecovery(t *testi
}
}))
t.Cleanup(srv.Close)
client, err := NewClient(srv.URL)
require.NoError(t, err)
client := newTestClient(t, srv.URL)
rt, err := NewRemoteRuntime(client)
require.NoError(t, err)
t.Cleanup(func() { require.NoError(t, rt.Close()) })
Expand Down
Loading