@@ -1276,3 +1276,121 @@ func TestLabelValuesToolHandler(t *testing.T) {
1276
1276
})
1277
1277
}
1278
1278
}
1279
+
1280
+ func TestSeriesToolHandler (t * testing.T ) {
1281
+ testCases := []struct {
1282
+ name string
1283
+ request mcp.CallToolRequest
1284
+ mockSeriesFunc func (ctx context.Context , matches []string , startTime time.Time , endTime time.Time , opts ... promv1.Option ) ([]model.LabelSet , promv1.Warnings , error )
1285
+ validateResult func (t * testing.T , result * mcp.CallToolResult , err error )
1286
+ }{
1287
+ {
1288
+ name : "success" ,
1289
+ request : mcp.CallToolRequest {
1290
+ Request : mcp.Request {Method : string (mcp .MethodToolsCall )},
1291
+ Params : mcp.CallToolParams {
1292
+ Name : "series" ,
1293
+ Arguments : map [string ]any {
1294
+ "matches" : []string {"up" },
1295
+ "start_time" : "1756142748" ,
1296
+ "end_time" : "1756143048" ,
1297
+ },
1298
+ },
1299
+ },
1300
+ mockSeriesFunc : func (ctx context.Context , matches []string , startTime time.Time , endTime time.Time , opts ... promv1.Option ) ([]model.LabelSet , promv1.Warnings , error ) {
1301
+ require .Equal (t , []string {"up" }, matches )
1302
+ return []model.LabelSet {}, nil , nil
1303
+ },
1304
+ validateResult : func (t * testing.T , result * mcp.CallToolResult , err error ) {
1305
+ require .NoError (t , err )
1306
+ require .False (t , result .IsError )
1307
+ },
1308
+ },
1309
+ {
1310
+ name : "missing matches" ,
1311
+ request : mcp.CallToolRequest {
1312
+ Request : mcp.Request {Method : string (mcp .MethodToolsCall )},
1313
+ Params : mcp.CallToolParams {
1314
+ Name : "series" ,
1315
+ Arguments : map [string ]any {},
1316
+ },
1317
+ },
1318
+ validateResult : func (t * testing.T , result * mcp.CallToolResult , err error ) {
1319
+ require .NoError (t , err )
1320
+ require .True (t , result .IsError )
1321
+ require .Contains (t , toolCallResultAsString (result ), "matches must be an array" )
1322
+ },
1323
+ },
1324
+ {
1325
+ name : "API error" ,
1326
+ request : mcp.CallToolRequest {
1327
+ Request : mcp.Request {Method : string (mcp .MethodToolsCall )},
1328
+ Params : mcp.CallToolParams {
1329
+ Name : "series" ,
1330
+ Arguments : map [string ]any {"matches" : []string {"up" }},
1331
+ },
1332
+ },
1333
+ mockSeriesFunc : func (ctx context.Context , matches []string , startTime time.Time , endTime time.Time , opts ... promv1.Option ) ([]model.LabelSet , promv1.Warnings , error ) {
1334
+ return nil , nil , errors .New ("prometheus exploded" )
1335
+ },
1336
+ validateResult : func (t * testing.T , result * mcp.CallToolResult , err error ) {
1337
+ require .NoError (t , err )
1338
+ require .True (t , result .IsError )
1339
+ require .Contains (t , toolCallResultAsString (result ), "prometheus exploded" )
1340
+ },
1341
+ },
1342
+ {
1343
+ name : "invalid start_time" ,
1344
+ request : mcp.CallToolRequest {
1345
+ Request : mcp.Request {Method : string (mcp .MethodToolsCall )},
1346
+ Params : mcp.CallToolParams {
1347
+ Name : "series" ,
1348
+ Arguments : map [string ]any {"matches" : []string {"up" }, "start_time" : "not-a-real-timestamp" },
1349
+ },
1350
+ },
1351
+ validateResult : func (t * testing.T , result * mcp.CallToolResult , err error ) {
1352
+ require .NoError (t , err )
1353
+ require .True (t , result .IsError )
1354
+ require .Contains (t , toolCallResultAsString (result ), "failed to parse start_time" )
1355
+ },
1356
+ },
1357
+ {
1358
+ name : "invalid end_time" ,
1359
+ request : mcp.CallToolRequest {
1360
+ Request : mcp.Request {Method : string (mcp .MethodToolsCall )},
1361
+ Params : mcp.CallToolParams {
1362
+ Name : "series" ,
1363
+ Arguments : map [string ]any {"matches" : []string {"up" }, "end_time" : "not-a-real-timestamp" },
1364
+ },
1365
+ },
1366
+ validateResult : func (t * testing.T , result * mcp.CallToolResult , err error ) {
1367
+ require .NoError (t , err )
1368
+ require .True (t , result .IsError )
1369
+ require .Contains (t , toolCallResultAsString (result ), "failed to parse end_time" )
1370
+ },
1371
+ },
1372
+ }
1373
+
1374
+ mockAPI := & MockPrometheusAPI {}
1375
+ mockServer := mcptest .NewUnstartedServer (t )
1376
+ mockServer .AddTool (seriesTool , seriesToolHandler )
1377
+
1378
+ ctx := context .WithValue (context .Background (), apiClientKey {}, mockAPI )
1379
+ err := mockServer .Start (ctx )
1380
+ require .NoError (t , err )
1381
+ defer mockServer .Close ()
1382
+
1383
+ mcpClient := mockServer .Client ()
1384
+ defer mcpClient .Close ()
1385
+
1386
+ for _ , tc := range testCases {
1387
+ t .Run (tc .name , func (t * testing.T ) {
1388
+ mockAPI .SeriesFunc = tc .mockSeriesFunc
1389
+
1390
+ res , err := mcpClient .CallTool (ctx , tc .request )
1391
+ require .NoError (t , err )
1392
+
1393
+ tc .validateResult (t , res , err )
1394
+ })
1395
+ }
1396
+ }
0 commit comments