@@ -1158,3 +1158,121 @@ func TestListAlertsToolHandler(t *testing.T) {
1158
1158
})
1159
1159
}
1160
1160
}
1161
+
1162
+ func TestLabelValuesToolHandler (t * testing.T ) {
1163
+ testCases := []struct {
1164
+ name string
1165
+ request mcp.CallToolRequest
1166
+ mockLabelValuesFunc func (ctx context.Context , label string , matches []string , startTime time.Time , endTime time.Time , opts ... promv1.Option ) (model.LabelValues , promv1.Warnings , error )
1167
+ validateResult func (t * testing.T , result * mcp.CallToolResult , err error )
1168
+ }{
1169
+ {
1170
+ name : "success" ,
1171
+ request : mcp.CallToolRequest {
1172
+ Request : mcp.Request {Method : string (mcp .MethodToolsCall )},
1173
+ Params : mcp.CallToolParams {
1174
+ Name : "label_values" ,
1175
+ Arguments : map [string ]any {
1176
+ "label" : "__name__" ,
1177
+ "start_time" : "1756142748" ,
1178
+ "end_time" : "1756143048" ,
1179
+ },
1180
+ },
1181
+ },
1182
+ mockLabelValuesFunc : func (ctx context.Context , label string , matches []string , startTime time.Time , endTime time.Time , opts ... promv1.Option ) (model.LabelValues , promv1.Warnings , error ) {
1183
+ require .Equal (t , "__name__" , label )
1184
+ return model.LabelValues {}, nil , nil
1185
+ },
1186
+ validateResult : func (t * testing.T , result * mcp.CallToolResult , err error ) {
1187
+ require .NoError (t , err )
1188
+ require .False (t , result .IsError )
1189
+ },
1190
+ },
1191
+ {
1192
+ name : "missing label" ,
1193
+ request : mcp.CallToolRequest {
1194
+ Request : mcp.Request {Method : string (mcp .MethodToolsCall )},
1195
+ Params : mcp.CallToolParams {
1196
+ Name : "label_values" ,
1197
+ Arguments : map [string ]any {},
1198
+ },
1199
+ },
1200
+ validateResult : func (t * testing.T , result * mcp.CallToolResult , err error ) {
1201
+ require .NoError (t , err )
1202
+ require .True (t , result .IsError )
1203
+ require .Contains (t , toolCallResultAsString (result ), "label must be a string" )
1204
+ },
1205
+ },
1206
+ {
1207
+ name : "API error" ,
1208
+ request : mcp.CallToolRequest {
1209
+ Request : mcp.Request {Method : string (mcp .MethodToolsCall )},
1210
+ Params : mcp.CallToolParams {
1211
+ Name : "label_values" ,
1212
+ Arguments : map [string ]any {"label" : "up" },
1213
+ },
1214
+ },
1215
+ mockLabelValuesFunc : func (ctx context.Context , label string , matches []string , startTime time.Time , endTime time.Time , opts ... promv1.Option ) (model.LabelValues , promv1.Warnings , error ) {
1216
+ return nil , nil , errors .New ("prometheus exploded" )
1217
+ },
1218
+ validateResult : func (t * testing.T , result * mcp.CallToolResult , err error ) {
1219
+ require .NoError (t , err )
1220
+ require .True (t , result .IsError )
1221
+ require .Contains (t , toolCallResultAsString (result ), "prometheus exploded" )
1222
+ },
1223
+ },
1224
+ {
1225
+ name : "invalid start_time" ,
1226
+ request : mcp.CallToolRequest {
1227
+ Request : mcp.Request {Method : string (mcp .MethodToolsCall )},
1228
+ Params : mcp.CallToolParams {
1229
+ Name : "label_values" ,
1230
+ Arguments : map [string ]any {"label" : "up" , "start_time" : "not-a-real-timestamp" },
1231
+ },
1232
+ },
1233
+ validateResult : func (t * testing.T , result * mcp.CallToolResult , err error ) {
1234
+ require .NoError (t , err )
1235
+ require .True (t , result .IsError )
1236
+ require .Contains (t , toolCallResultAsString (result ), "failed to parse start_time" )
1237
+ },
1238
+ },
1239
+ {
1240
+ name : "invalid end_time" ,
1241
+ request : mcp.CallToolRequest {
1242
+ Request : mcp.Request {Method : string (mcp .MethodToolsCall )},
1243
+ Params : mcp.CallToolParams {
1244
+ Name : "label_values" ,
1245
+ Arguments : map [string ]any {"label" : "up" , "end_time" : "not-a-real-timestamp" },
1246
+ },
1247
+ },
1248
+ validateResult : func (t * testing.T , result * mcp.CallToolResult , err error ) {
1249
+ require .NoError (t , err )
1250
+ require .True (t , result .IsError )
1251
+ require .Contains (t , toolCallResultAsString (result ), "failed to parse end_time" )
1252
+ },
1253
+ },
1254
+ }
1255
+
1256
+ mockAPI := & MockPrometheusAPI {}
1257
+ mockServer := mcptest .NewUnstartedServer (t )
1258
+ mockServer .AddTool (labelValuesTool , labelValuesToolHandler )
1259
+
1260
+ ctx := context .WithValue (context .Background (), apiClientKey {}, mockAPI )
1261
+ err := mockServer .Start (ctx )
1262
+ require .NoError (t , err )
1263
+ defer mockServer .Close ()
1264
+
1265
+ mcpClient := mockServer .Client ()
1266
+ defer mcpClient .Close ()
1267
+
1268
+ for _ , tc := range testCases {
1269
+ t .Run (tc .name , func (t * testing.T ) {
1270
+ mockAPI .LabelValuesFunc = tc .mockLabelValuesFunc
1271
+
1272
+ res , err := mcpClient .CallTool (ctx , tc .request )
1273
+ require .NoError (t , err )
1274
+
1275
+ tc .validateResult (t , res , err )
1276
+ })
1277
+ }
1278
+ }
0 commit comments