@@ -32,6 +32,10 @@ func newTestServer(t *testing.T) (*aibridged.Server, *mock.MockDRPCClient, *mock
32
32
client := mock .NewMockDRPCClient (ctrl )
33
33
pool := mock .NewMockPooler (ctrl )
34
34
35
+ conn := & mockDRPCConn {}
36
+ client .EXPECT ().DRPCConn ().AnyTimes ().Return (conn )
37
+ pool .EXPECT ().Shutdown (gomock .Any ()).MinTimes (1 ).Return (nil )
38
+
35
39
srv ,err := aibridged .New (
36
40
t .Context (),
37
41
pool ,
@@ -40,6 +44,9 @@ func newTestServer(t *testing.T) (*aibridged.Server, *mock.MockDRPCClient, *mock
40
44
},
41
45
logger )
42
46
require .NoError (t ,err ,"create new aibridged" )
47
+ t .Cleanup (func () {
48
+ srv .Shutdown (context .Background ())
49
+ })
43
50
44
51
return srv ,client ,pool
45
52
}
@@ -115,7 +122,7 @@ func TestServeHTTP_FailureModes(t *testing.T) {
115
122
// Should pass authorization.
116
123
client .EXPECT ().IsAuthorized (gomock .Any (),gomock .Any ()).AnyTimes ().Return (& proto.IsAuthorizedResponse {OwnerId :uuid .NewString ()},nil )
117
124
// But fail when acquiring a pool instance.
118
- pool .EXPECT ().Acquire (gomock .Any (),gomock .Any (),gomock .Any ()).AnyTimes ().Return (nil ,xerrors .New ("oops" ))
125
+ pool .EXPECT ().Acquire (gomock .Any (),gomock .Any (),gomock .Any (), gomock . Any () ).AnyTimes ().Return (nil ,xerrors .New ("oops" ))
119
126
},
120
127
expectedErr :aibridged .ErrAcquireRequestHandler ,
121
128
expectedStatus :http .StatusInternalServerError ,
@@ -228,38 +235,6 @@ func (*mockHandler) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
228
235
_ ,_ = rw .Write ([]byte (r .URL .Path ))
229
236
}
230
237
231
- // TestPoolHandler validates that an http.Handler can be acquired from a given [aibridged.Pooler]
232
- // and have its HTTP handler invoked.
233
- //
234
- // We're not actually testing the routing, since that is being tested by [aibridge.RequestBridge].
235
- //
236
- // We're validating that a request can be successfully processed by aibridged
237
- // (i.e. authn/z, acquire pool instance) and what happens thereafter is a black box to aibridged.
238
- func TestPoolHandler (t * testing.T ) {
239
- t .Parallel ()
240
-
241
- srv ,client ,pool := newTestServer (t )
242
-
243
- conn := & mockDRPCConn {}
244
- client .EXPECT ().DRPCConn ().AnyTimes ().Return (conn )
245
- // Authorize all requests.
246
- client .EXPECT ().IsAuthorized (gomock .Any (),gomock .Any ()).AnyTimes ().Return (& proto.IsAuthorizedResponse {OwnerId :uuid .NewString ()},nil )
247
- pool .EXPECT ().Acquire (gomock .Any (),gomock .Any (),gomock .Any ()).AnyTimes ().Return (& mockHandler {},nil )
248
-
249
- ctx := testutil .Context (t ,testutil .WaitShort )
250
- path := "/irrelevant"
251
- req ,err := http .NewRequestWithContext (ctx ,http .MethodPost ,path ,nil )
252
- require .NoError (t ,err ,"make request to test server" )
253
- req .Header .Add ("Authorization" ,"Bearer key" )
254
-
255
- rec := httptest .NewRecorder ()
256
- srv .ServeHTTP (rec ,req )
257
-
258
- require .Equal (t ,http .StatusOK ,rec .Code )
259
- require .NotNil (t ,rec .Body )
260
- require .Equal (t ,path ,rec .Body .String ())
261
- }
262
-
263
238
// TestRouting validates that a request which originates with aibridged will be handled
264
239
// by coder/aibridge's handling logic in a provider-specific manner.
265
240
// We must validate that logic that pertains to coder/coder is exercised.
@@ -284,13 +259,13 @@ func TestRouting(t *testing.T) {
284
259
{
285
260
name :"openai chat completions" ,
286
261
path :"/openai/v1/chat/completions" ,
287
- expectedStatus :http .StatusOK ,
262
+ expectedStatus :http .StatusTeapot , // Nonsense status to indicate server was hit.
288
263
expectedHits :1 ,
289
264
},
290
265
{
291
266
name :"anthropic messages" ,
292
267
path :"/anthropic/v1/messages" ,
293
- expectedStatus :http .StatusOK ,
268
+ expectedStatus :http .StatusTeapot , // Nonsense status to indicate server was hit.
294
269
expectedHits :1 ,
295
270
},
296
271
}
@@ -310,14 +285,12 @@ func TestRouting(t *testing.T) {
310
285
logger := slogtest .Make (t ,& slogtest.Options {IgnoreErrors :true })
311
286
ctrl := gomock .NewController (t )
312
287
client := mock .NewMockDRPCClient (ctrl )
313
- pool ,err := aibridged .NewCachedBridgePool (10 , aibridge.Config {
314
- OpenAI : aibridge.ProviderConfig {
315
- BaseURL :openaiSrv .URL ,
316
- },
317
- Anthropic : aibridge.ProviderConfig {
318
- BaseURL :antSrv .URL ,
319
- },
320
- },logger )
288
+
289
+ providers := []aibridge.Provider {
290
+ aibridge .NewOpenAIProvider (aibridge.ProviderConfig {BaseURL :openaiSrv .URL }),
291
+ aibridge .NewAnthropicProvider (aibridge.ProviderConfig {BaseURL :antSrv .URL }),
292
+ }
293
+ pool ,err := aibridged .NewCachedBridgePool (aibridged .DefaultPoolOptions ,providers ,logger )
321
294
require .NoError (t ,err )
322
295
conn := & mockDRPCConn {}
323
296
client .EXPECT ().DRPCConn ().AnyTimes ().Return (conn )
@@ -331,9 +304,6 @@ func TestRouting(t *testing.T) {
331
304
interceptionID = in .GetId ()
332
305
return & proto.RecordInterceptionResponse {},nil
333
306
})
334
- client .EXPECT ().RecordPromptUsage (gomock .Any (),gomock .Any ()).AnyTimes ().Return (& proto.RecordPromptUsageResponse {},nil )
335
- client .EXPECT ().RecordTokenUsage (gomock .Any (),gomock .Any ()).AnyTimes ().Return (& proto.RecordTokenUsageResponse {},nil )
336
- client .EXPECT ().RecordToolUsage (gomock .Any (),gomock .Any ()).AnyTimes ().Return (& proto.RecordToolUsageResponse {},nil )
337
307
338
308
// Given: aibridged is started.
339
309
srv ,err := aibridged .New (t .Context (),pool ,func (ctx context.Context ) (aibridged.DRPCClient ,error ) {
@@ -356,6 +326,8 @@ func TestRouting(t *testing.T) {
356
326
srv .ServeHTTP (rec ,req )
357
327
358
328
// Then: the upstream server will have received a number of hits.
329
+ // NOTE: we *expect* the interceptions to fail because [mockAIUpstreamServer] returns a nonsense status code.
330
+ // We only need to test that the request was routed, NOT processed.
359
331
require .Equal (t ,tc .expectedStatus ,rec .Code )
360
332
assert .EqualValues (t ,tc .expectedHits ,upstreamSrv .Hits ())
361
333
if tc .expectedHits > 0 {