@@ -282,6 +282,124 @@ func TestCreateRunConfigFromMCPServer(t *testing.T) {
282
282
assert .Len (t , config .Secrets , 0 )
283
283
},
284
284
},
285
+ {
286
+ name : "with telemetry configuration" ,
287
+ mcpServer : & mcpv1alpha1.MCPServer {
288
+ ObjectMeta : metav1.ObjectMeta {
289
+ Name : "telemetry-server" ,
290
+ Namespace : "test-ns" ,
291
+ },
292
+ Spec : mcpv1alpha1.MCPServerSpec {
293
+ Image : testImage ,
294
+ Transport : stdioTransport ,
295
+ Port : 8080 ,
296
+ Telemetry : & mcpv1alpha1.TelemetryConfig {
297
+ OpenTelemetry : & mcpv1alpha1.OpenTelemetryConfig {
298
+ Enabled : true ,
299
+ Endpoint : "http://otel-collector:4317" ,
300
+ ServiceName : "custom-service-name" ,
301
+ Insecure : true ,
302
+ Headers : []string {"Authorization=Bearer token123" , "X-API-Key=abc" },
303
+ Tracing : & mcpv1alpha1.OpenTelemetryTracingConfig {
304
+ Enabled : true ,
305
+ SamplingRate : "0.25" ,
306
+ },
307
+ Metrics : & mcpv1alpha1.OpenTelemetryMetricsConfig {
308
+ Enabled : true ,
309
+ },
310
+ },
311
+ Prometheus : & mcpv1alpha1.PrometheusConfig {
312
+ Enabled : true ,
313
+ },
314
+ },
315
+ },
316
+ },
317
+ //nolint:thelper // We want to see the error at the specific line
318
+ expected : func (t * testing.T , config * runner.RunConfig ) {
319
+ assert .Equal (t , "telemetry-server" , config .Name )
320
+
321
+ // Verify telemetry config is set
322
+ assert .NotNil (t , config .TelemetryConfig )
323
+
324
+ // Check OpenTelemetry settings (endpoint should have http:// prefix stripped)
325
+ assert .Equal (t , "otel-collector:4317" , config .TelemetryConfig .Endpoint )
326
+ assert .Equal (t , "custom-service-name" , config .TelemetryConfig .ServiceName )
327
+ assert .True (t , config .TelemetryConfig .Insecure )
328
+ assert .True (t , config .TelemetryConfig .TracingEnabled )
329
+ assert .True (t , config .TelemetryConfig .MetricsEnabled )
330
+ assert .Equal (t , 0.25 , config .TelemetryConfig .SamplingRate )
331
+ assert .Equal (t , map [string ]string {"Authorization" : "Bearer token123" , "X-API-Key" : "abc" }, config .TelemetryConfig .Headers )
332
+
333
+ // Check Prometheus settings
334
+ assert .True (t , config .TelemetryConfig .EnablePrometheusMetricsPath )
335
+ },
336
+ },
337
+ {
338
+ name : "with minimal telemetry configuration" ,
339
+ mcpServer : & mcpv1alpha1.MCPServer {
340
+ ObjectMeta : metav1.ObjectMeta {
341
+ Name : "minimal-telemetry-server" ,
342
+ Namespace : "test-ns" ,
343
+ },
344
+ Spec : mcpv1alpha1.MCPServerSpec {
345
+ Image : testImage ,
346
+ Transport : stdioTransport ,
347
+ Port : 8080 ,
348
+ Telemetry : & mcpv1alpha1.TelemetryConfig {
349
+ OpenTelemetry : & mcpv1alpha1.OpenTelemetryConfig {
350
+ Enabled : true ,
351
+ Endpoint : "https://secure-otel:4318" ,
352
+ // ServiceName not specified - should default to MCPServer name
353
+ },
354
+ },
355
+ },
356
+ },
357
+ //nolint:thelper // We want to see the error at the specific line
358
+ expected : func (t * testing.T , config * runner.RunConfig ) {
359
+ assert .Equal (t , "minimal-telemetry-server" , config .Name )
360
+
361
+ // Verify telemetry config is set
362
+ assert .NotNil (t , config .TelemetryConfig )
363
+
364
+ // Check that service name defaults to MCPServer name
365
+ assert .Equal (t , "minimal-telemetry-server" , config .TelemetryConfig .ServiceName )
366
+ assert .Equal (t , "secure-otel:4318" , config .TelemetryConfig .Endpoint )
367
+ assert .False (t , config .TelemetryConfig .Insecure ) // Default should be false
368
+ assert .Equal (t , 0.05 , config .TelemetryConfig .SamplingRate ) // Default sampling rate
369
+ },
370
+ },
371
+ {
372
+ name : "with prometheus only telemetry" ,
373
+ mcpServer : & mcpv1alpha1.MCPServer {
374
+ ObjectMeta : metav1.ObjectMeta {
375
+ Name : "prometheus-only-server" ,
376
+ Namespace : "test-ns" ,
377
+ },
378
+ Spec : mcpv1alpha1.MCPServerSpec {
379
+ Image : testImage ,
380
+ Transport : stdioTransport ,
381
+ Port : 8080 ,
382
+ Telemetry : & mcpv1alpha1.TelemetryConfig {
383
+ Prometheus : & mcpv1alpha1.PrometheusConfig {
384
+ Enabled : true ,
385
+ },
386
+ },
387
+ },
388
+ },
389
+ //nolint:thelper // We want to see the error at the specific line
390
+ expected : func (t * testing.T , config * runner.RunConfig ) {
391
+ assert .Equal (t , "prometheus-only-server" , config .Name )
392
+
393
+ // Verify telemetry config is set
394
+ assert .NotNil (t , config .TelemetryConfig )
395
+
396
+ // Only Prometheus should be enabled
397
+ assert .True (t , config .TelemetryConfig .EnablePrometheusMetricsPath )
398
+ assert .False (t , config .TelemetryConfig .TracingEnabled )
399
+ assert .False (t , config .TelemetryConfig .MetricsEnabled )
400
+ assert .Equal (t , "" , config .TelemetryConfig .Endpoint )
401
+ },
402
+ },
285
403
}
286
404
287
405
for _ , tt := range tests {
@@ -533,6 +651,71 @@ func TestEnsureRunConfigConfigMap(t *testing.T) {
533
651
assert .NotEmpty (t , cm .Annotations ["toolhive.stacklok.dev/content-checksum" ])
534
652
},
535
653
},
654
+ {
655
+ name : "configmap with telemetry configuration" ,
656
+ mcpServer : & mcpv1alpha1.MCPServer {
657
+ ObjectMeta : metav1.ObjectMeta {
658
+ Name : "telemetry-test" ,
659
+ Namespace : "toolhive-system" ,
660
+ },
661
+ Spec : mcpv1alpha1.MCPServerSpec {
662
+ Image : "ghcr.io/example/server:v1.0.0" ,
663
+ Transport : "stdio" ,
664
+ Port : 8080 ,
665
+ Telemetry : & mcpv1alpha1.TelemetryConfig {
666
+ OpenTelemetry : & mcpv1alpha1.OpenTelemetryConfig {
667
+ Enabled : true ,
668
+ Endpoint : "http://otel-collector:4317" ,
669
+ ServiceName : "test-service" ,
670
+ Headers : []string {"Authorization=Bearer test-token" },
671
+ Insecure : true ,
672
+ Tracing : & mcpv1alpha1.OpenTelemetryTracingConfig {
673
+ Enabled : true ,
674
+ SamplingRate : "0.1" ,
675
+ },
676
+ Metrics : & mcpv1alpha1.OpenTelemetryMetricsConfig {
677
+ Enabled : true ,
678
+ },
679
+ },
680
+ Prometheus : & mcpv1alpha1.PrometheusConfig {
681
+ Enabled : true ,
682
+ },
683
+ },
684
+ },
685
+ },
686
+ existingCM : nil ,
687
+ expectError : false ,
688
+ validateContent : func (t * testing.T , cm * corev1.ConfigMap ) {
689
+ t .Helper ()
690
+ assert .Equal (t , "telemetry-test-runconfig" , cm .Name )
691
+ assert .Equal (t , "toolhive-system" , cm .Namespace )
692
+ assert .Contains (t , cm .Data , "runconfig.json" )
693
+
694
+ // Parse and validate telemetry configuration in runconfig.json
695
+ var runConfig runner.RunConfig
696
+ err := json .Unmarshal ([]byte (cm .Data ["runconfig.json" ]), & runConfig )
697
+ require .NoError (t , err )
698
+
699
+ // Verify basic fields
700
+ assert .Equal (t , "telemetry-test" , runConfig .Name )
701
+ assert .Equal (t , "ghcr.io/example/server:v1.0.0" , runConfig .Image )
702
+
703
+ // Verify telemetry configuration is properly serialized
704
+ assert .NotNil (t , runConfig .TelemetryConfig , "TelemetryConfig should be present in runconfig.json" )
705
+
706
+ // Check OpenTelemetry settings (endpoint should have http:// prefix stripped)
707
+ assert .Equal (t , "otel-collector:4317" , runConfig .TelemetryConfig .Endpoint )
708
+ assert .Equal (t , "test-service" , runConfig .TelemetryConfig .ServiceName )
709
+ assert .True (t , runConfig .TelemetryConfig .Insecure )
710
+ assert .True (t , runConfig .TelemetryConfig .TracingEnabled )
711
+ assert .True (t , runConfig .TelemetryConfig .MetricsEnabled )
712
+ assert .Equal (t , 0.1 , runConfig .TelemetryConfig .SamplingRate )
713
+ assert .Equal (t , map [string ]string {"Authorization" : "Bearer test-token" }, runConfig .TelemetryConfig .Headers )
714
+
715
+ // Check Prometheus settings
716
+ assert .True (t , runConfig .TelemetryConfig .EnablePrometheusMetricsPath )
717
+ },
718
+ },
536
719
}
537
720
538
721
for _ , tt := range tests {
0 commit comments