Skip to content

Commit c2f9c79

Browse files
committed
chore: refactor tests
Signed-off-by: Danny Kopping <danny@coder.com>
1 parent ad182b7 commit c2f9c79

2 files changed

Lines changed: 121 additions & 168 deletions

File tree

internal/integrationtest/bridge_test.go

Lines changed: 67 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -126,72 +126,76 @@ func TestAnthropicMessages(t *testing.T) {
126126
func TestAnthropicMessagesModelThoughts(t *testing.T) {
127127
t.Parallel()
128128

129-
t.Run("thinking captured with builtin tool", func(t *testing.T) {
130-
t.Parallel()
131-
132-
cases := []struct {
133-
name string
134-
streaming bool
135-
fixture []byte
136-
expectedToolCallID string
137-
expectedThoughts []string
138-
}{
139-
{
140-
name: "single thinking block/streaming",
141-
streaming: true,
142-
fixture: fixtures.AntSingleBuiltinTool,
143-
expectedToolCallID: "toolu_01RX68weRSquLx6HUTj65iBo",
144-
expectedThoughts: []string{"The user wants me to read"},
145-
},
146-
{
147-
name: "single thinking block/blocking",
148-
streaming: false,
149-
fixture: fixtures.AntSingleBuiltinTool,
150-
expectedToolCallID: "toolu_01AusGgY5aKFhzWrFBv9JfHq",
151-
expectedThoughts: []string{"The user wants me to read"},
152-
},
153-
{
154-
name: "multiple thinking blocks/streaming",
155-
streaming: true,
156-
fixture: fixtures.AntMultiThinkingBuiltinTool,
157-
expectedToolCallID: "toolu_01RX68weRSquLx6HUTj65iBo",
158-
expectedThoughts: []string{"The user wants me to read", "I should use the Read tool"},
159-
},
160-
{
161-
name: "multiple thinking blocks/blocking",
162-
streaming: false,
163-
fixture: fixtures.AntMultiThinkingBuiltinTool,
164-
expectedToolCallID: "toolu_01AusGgY5aKFhzWrFBv9JfHq",
165-
expectedThoughts: []string{"The user wants me to read", "I should use the Read tool"},
166-
},
167-
}
129+
cases := []struct {
130+
name string
131+
streaming bool
132+
fixture []byte
133+
expectedToolCallID string
134+
expectedThoughts []string // nil means no tool usages expected at all
135+
}{
136+
{
137+
name: "single thinking block/streaming",
138+
streaming: true,
139+
fixture: fixtures.AntSingleBuiltinTool,
140+
expectedToolCallID: "toolu_01RX68weRSquLx6HUTj65iBo",
141+
expectedThoughts: []string{"The user wants me to read"},
142+
},
143+
{
144+
name: "single thinking block/blocking",
145+
streaming: false,
146+
fixture: fixtures.AntSingleBuiltinTool,
147+
expectedToolCallID: "toolu_01AusGgY5aKFhzWrFBv9JfHq",
148+
expectedThoughts: []string{"The user wants me to read"},
149+
},
150+
{
151+
name: "multiple thinking blocks/streaming",
152+
streaming: true,
153+
fixture: fixtures.AntMultiThinkingBuiltinTool,
154+
expectedToolCallID: "toolu_01RX68weRSquLx6HUTj65iBo",
155+
expectedThoughts: []string{"The user wants me to read", "I should use the Read tool"},
156+
},
157+
{
158+
name: "multiple thinking blocks/blocking",
159+
streaming: false,
160+
fixture: fixtures.AntMultiThinkingBuiltinTool,
161+
expectedToolCallID: "toolu_01AusGgY5aKFhzWrFBv9JfHq",
162+
expectedThoughts: []string{"The user wants me to read", "I should use the Read tool"},
163+
},
164+
{
165+
name: "no thoughts without tool calls",
166+
streaming: true,
167+
fixture: fixtures.AntSimple, // This fixture contains thoughts, but they're not associated with tool calls.
168+
},
169+
}
168170

169-
for _, tc := range cases {
170-
t.Run(tc.name, func(t *testing.T) {
171-
t.Parallel()
171+
for _, tc := range cases {
172+
t.Run(tc.name, func(t *testing.T) {
173+
t.Parallel()
172174

173-
ctx, cancel := context.WithTimeout(t.Context(), time.Second*30)
174-
t.Cleanup(cancel)
175+
ctx, cancel := context.WithTimeout(t.Context(), time.Second*30)
176+
t.Cleanup(cancel)
175177

176-
fix := fixtures.Parse(t, tc.fixture)
177-
upstream := newMockUpstream(t, ctx, newFixtureResponse(fix))
178+
fix := fixtures.Parse(t, tc.fixture)
179+
upstream := newMockUpstream(t, ctx, newFixtureResponse(fix))
178180

179-
bridgeServer := newBridgeTestServer(t, ctx, upstream.URL)
181+
bridgeServer := newBridgeTestServer(t, ctx, upstream.URL)
180182

181-
reqBody, err := sjson.SetBytes(fix.Request(), "stream", tc.streaming)
182-
require.NoError(t, err)
183-
resp := bridgeServer.makeRequest(t, http.MethodPost, pathAnthropicMessages, reqBody)
184-
require.Equal(t, http.StatusOK, resp.StatusCode)
183+
reqBody, err := sjson.SetBytes(fix.Request(), "stream", tc.streaming)
184+
require.NoError(t, err)
185+
resp := bridgeServer.makeRequest(t, http.MethodPost, pathAnthropicMessages, reqBody)
186+
require.Equal(t, http.StatusOK, resp.StatusCode)
185187

186-
if tc.streaming {
187-
sp := aibridge.NewSSEParser()
188-
require.NoError(t, sp.Parse(resp.Body))
189-
assert.Contains(t, sp.AllEvents(), "message_start")
190-
assert.Contains(t, sp.AllEvents(), "message_stop")
191-
}
188+
if tc.streaming {
189+
sp := aibridge.NewSSEParser()
190+
require.NoError(t, sp.Parse(resp.Body))
191+
assert.Contains(t, sp.AllEvents(), "message_start")
192+
assert.Contains(t, sp.AllEvents(), "message_stop")
193+
}
192194

193-
// Verify tool usage was recorded with associated model thoughts.
194-
toolUsages := bridgeServer.Recorder.RecordedToolUsages()
195+
toolUsages := bridgeServer.Recorder.RecordedToolUsages()
196+
if tc.expectedThoughts == nil {
197+
assert.Empty(t, toolUsages)
198+
} else {
195199
require.Len(t, toolUsages, 1)
196200
assert.Equal(t, "Read", toolUsages[0].Tool)
197201
assert.Equal(t, tc.expectedToolCallID, toolUsages[0].ToolCallID)
@@ -200,40 +204,11 @@ func TestAnthropicMessagesModelThoughts(t *testing.T) {
200204
for i, expected := range tc.expectedThoughts {
201205
assert.Contains(t, toolUsages[0].ModelThoughts[i].Content, expected)
202206
}
207+
}
203208

204-
bridgeServer.Recorder.VerifyAllInterceptionsEnded(t)
205-
})
206-
}
207-
})
208-
209-
t.Run("no thoughts without tool calls", func(t *testing.T) {
210-
t.Parallel()
211-
212-
ctx, cancel := context.WithTimeout(t.Context(), time.Second*30)
213-
t.Cleanup(cancel)
214-
215-
// Use the simple fixture which has no tool calls — any thinking blocks
216-
// should not be persisted since they can't be associated with a tool call.
217-
fix := fixtures.Parse(t, fixtures.AntSimple)
218-
upstream := newMockUpstream(t, ctx, newFixtureResponse(fix))
219-
220-
bridgeServer := newBridgeTestServer(t, ctx, upstream.URL)
221-
222-
reqBody, err := sjson.SetBytes(fix.Request(), "stream", true)
223-
require.NoError(t, err)
224-
resp := bridgeServer.makeRequest(t, http.MethodPost, pathAnthropicMessages, reqBody)
225-
require.Equal(t, http.StatusOK, resp.StatusCode)
226-
227-
sp := aibridge.NewSSEParser()
228-
require.NoError(t, sp.Parse(resp.Body))
229-
230-
// No tool usages (and therefore no thoughts) should be recorded
231-
// when there are no tool calls.
232-
toolUsages := bridgeServer.Recorder.RecordedToolUsages()
233-
assert.Empty(t, toolUsages)
234-
235-
bridgeServer.Recorder.VerifyAllInterceptionsEnded(t)
236-
})
209+
bridgeServer.Recorder.VerifyAllInterceptionsEnded(t)
210+
})
211+
}
237212
}
238213

239214
func TestAWSBedrockIntegration(t *testing.T) {

internal/integrationtest/responses_test.go

Lines changed: 54 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -919,61 +919,64 @@ func TestResponsesInjectedTool(t *testing.T) {
919919
func TestResponsesModelThoughts(t *testing.T) {
920920
t.Parallel()
921921

922-
t.Run("reasoning captured with builtin tool", func(t *testing.T) {
923-
t.Parallel()
924-
925-
cases := []struct {
926-
name string
927-
fixture []byte
928-
expectedToolCallID string
929-
expectedThoughts []string
930-
}{
931-
{
932-
name: "single reasoning/blocking",
933-
fixture: fixtures.OaiResponsesBlockingSingleBuiltinTool,
934-
expectedToolCallID: "call_CJSaa2u51JG996575oVljuNq",
935-
expectedThoughts: []string{"The user wants to add 3 and 5"},
936-
},
937-
{
938-
name: "single reasoning/streaming",
939-
fixture: fixtures.OaiResponsesStreamingBuiltinTool,
940-
expectedToolCallID: "call_7VaiUXZYuuuwWwviCrckxq6t",
941-
expectedThoughts: []string{"The user wants to add 3 and 5"},
942-
},
943-
{
944-
name: "multiple reasoning items/blocking",
945-
fixture: fixtures.OaiResponsesBlockingMultiReasoningBuiltinTool,
946-
expectedToolCallID: "call_CJSaa2u51JG996575oVljuNq",
947-
expectedThoughts: []string{"The user wants to add 3 and 5", "After adding, I will check if the result is prime"},
948-
},
949-
{
950-
name: "multiple reasoning items/streaming",
951-
fixture: fixtures.OaiResponsesStreamingMultiReasoningBuiltinTool,
952-
expectedToolCallID: "call_7VaiUXZYuuuwWwviCrckxq6t",
953-
expectedThoughts: []string{"The user wants to add 3 and 5", "After adding, I will check if the result is prime"},
954-
},
955-
}
922+
cases := []struct {
923+
name string
924+
fixture []byte
925+
expectedToolCallID string
926+
expectedThoughts []string // nil means no tool usages expected at all
927+
}{
928+
{
929+
name: "single reasoning/blocking",
930+
fixture: fixtures.OaiResponsesBlockingSingleBuiltinTool,
931+
expectedToolCallID: "call_CJSaa2u51JG996575oVljuNq",
932+
expectedThoughts: []string{"The user wants to add 3 and 5"},
933+
},
934+
{
935+
name: "single reasoning/streaming",
936+
fixture: fixtures.OaiResponsesStreamingBuiltinTool,
937+
expectedToolCallID: "call_7VaiUXZYuuuwWwviCrckxq6t",
938+
expectedThoughts: []string{"The user wants to add 3 and 5"},
939+
},
940+
{
941+
name: "multiple reasoning items/blocking",
942+
fixture: fixtures.OaiResponsesBlockingMultiReasoningBuiltinTool,
943+
expectedToolCallID: "call_CJSaa2u51JG996575oVljuNq",
944+
expectedThoughts: []string{"The user wants to add 3 and 5", "After adding, I will check if the result is prime"},
945+
},
946+
{
947+
name: "multiple reasoning items/streaming",
948+
fixture: fixtures.OaiResponsesStreamingMultiReasoningBuiltinTool,
949+
expectedToolCallID: "call_7VaiUXZYuuuwWwviCrckxq6t",
950+
expectedThoughts: []string{"The user wants to add 3 and 5", "After adding, I will check if the result is prime"},
951+
},
952+
{
953+
name: "no thoughts without tool calls",
954+
fixture: fixtures.OaiResponsesStreamingCodex, // This fixture contains reasoning, but it's not associated with tool calls.
955+
},
956+
}
956957

957-
for _, tc := range cases {
958-
t.Run(tc.name, func(t *testing.T) {
959-
t.Parallel()
958+
for _, tc := range cases {
959+
t.Run(tc.name, func(t *testing.T) {
960+
t.Parallel()
960961

961-
ctx, cancel := context.WithTimeout(t.Context(), time.Second*30)
962-
t.Cleanup(cancel)
962+
ctx, cancel := context.WithTimeout(t.Context(), time.Second*30)
963+
t.Cleanup(cancel)
963964

964-
fix := fixtures.Parse(t, tc.fixture)
965-
upstream := newMockUpstream(t, ctx, newFixtureResponse(fix))
965+
fix := fixtures.Parse(t, tc.fixture)
966+
upstream := newMockUpstream(t, ctx, newFixtureResponse(fix))
966967

967-
bridgeServer := newBridgeTestServer(t, ctx, upstream.URL)
968+
bridgeServer := newBridgeTestServer(t, ctx, upstream.URL)
968969

969-
resp := bridgeServer.makeRequest(t, http.MethodPost, pathOpenAIResponses, fix.Request())
970-
require.Equal(t, http.StatusOK, resp.StatusCode)
970+
resp := bridgeServer.makeRequest(t, http.MethodPost, pathOpenAIResponses, fix.Request())
971+
require.Equal(t, http.StatusOK, resp.StatusCode)
971972

972-
_, err := io.ReadAll(resp.Body)
973-
require.NoError(t, err)
973+
_, err := io.ReadAll(resp.Body)
974+
require.NoError(t, err)
974975

975-
// Verify tool usage was recorded with associated model thoughts.
976-
toolUsages := bridgeServer.Recorder.RecordedToolUsages()
976+
toolUsages := bridgeServer.Recorder.RecordedToolUsages()
977+
if tc.expectedThoughts == nil {
978+
require.Empty(t, toolUsages)
979+
} else {
977980
require.Len(t, toolUsages, 1)
978981
require.Equal(t, "add", toolUsages[0].Tool)
979982
require.Equal(t, tc.expectedToolCallID, toolUsages[0].ToolCallID)
@@ -982,34 +985,9 @@ func TestResponsesModelThoughts(t *testing.T) {
982985
for i, expected := range tc.expectedThoughts {
983986
require.Contains(t, toolUsages[0].ModelThoughts[i].Content, expected)
984987
}
985-
})
986-
}
987-
})
988-
989-
t.Run("no thoughts without tool calls", func(t *testing.T) {
990-
t.Parallel()
991-
992-
ctx, cancel := context.WithTimeout(t.Context(), time.Second*30)
993-
t.Cleanup(cancel)
994-
995-
// Use the simple fixture which has no tool calls — any reasoning
996-
// should not be persisted since it can't be associated with a tool call.
997-
fix := fixtures.Parse(t, fixtures.OaiResponsesStreamingCodex)
998-
upstream := newMockUpstream(t, ctx, newFixtureResponse(fix))
999-
1000-
bridgeServer := newBridgeTestServer(t, ctx, upstream.URL)
1001-
1002-
resp := bridgeServer.makeRequest(t, http.MethodPost, pathOpenAIResponses, fix.Request())
1003-
require.Equal(t, http.StatusOK, resp.StatusCode)
1004-
1005-
_, err := io.ReadAll(resp.Body)
1006-
require.NoError(t, err)
1007-
1008-
// No tool usages (and therefore no thoughts) should be recorded
1009-
// when there are no tool calls.
1010-
toolUsages := bridgeServer.Recorder.RecordedToolUsages()
1011-
require.Empty(t, toolUsages)
1012-
})
988+
}
989+
})
990+
}
1013991
}
1014992

1015993
func requireResponsesError(t *testing.T, code int, message string, body []byte) {

0 commit comments

Comments
 (0)