@@ -29,8 +29,7 @@ public void MergeConfigurations_SingleConfig_ReturnsOriginal()
2929 var result = ApmTracingConfigMerger . MergeConfigurations ( configs , "test-service" , "test-env" ) ;
3030
3131 // Assert
32- var resultJson = JObject . Parse ( result ) ;
33- resultJson [ "lib_config" ] ? [ "tracing_enabled" ] ? . Value < bool > ( ) . Should ( ) . BeTrue ( ) ;
32+ result [ "lib_config" ] ? [ "tracing_enabled" ] ? . Value < bool > ( ) . Should ( ) . BeTrue ( ) ;
3433 }
3534
3635 [ Fact ]
@@ -66,8 +65,7 @@ public void MergeConfigurations_PriorityOrdering_ServiceAndEnvWins()
6665 var result = ApmTracingConfigMerger . MergeConfigurations ( configs , "test-service" , "production" ) ;
6766
6867 // Assert
69- var resultJson = JObject . Parse ( result ) ;
70- var libConfig = resultJson [ "lib_config" ] ;
68+ var libConfig = result [ "lib_config" ] ;
7169
7270 // Service+Env config should override others for log_injection_enabled
7371 libConfig ? [ "log_injection_enabled" ] ? . Value < bool > ( ) . Should ( ) . BeFalse ( ) ;
@@ -94,13 +92,13 @@ public void MergeConfigurations_WildcardMatching_MatchesAllServices()
9492 var result = ApmTracingConfigMerger . MergeConfigurations ( configs , "any-service" , "production" ) ;
9593
9694 // Assert
97- var resultJson = JObject . Parse ( result ) ;
98- resultJson [ "lib_config" ] ? [ "tracing_enabled" ] ? . Value < bool > ( ) . Should ( ) . BeFalse ( ) ;
95+ result [ "lib_config" ] ? [ "tracing_enabled" ] ? . Value < bool > ( ) . Should ( ) . BeFalse ( ) ;
9996 }
10097
10198 [ Fact ]
102- public void MergeConfigurations_NoMatchingConfigs_ReturnsEmpty ( )
99+ public void MergeConfigurations_NoMatchingConfigs_ReturnsNonEmpty ( )
103100 {
101+ // We have decided for now to not filter out non-matching configs. We will address it in a later PR.
104102 // Arrange
105103 var config = CreateRemoteConfig (
106104 "config1" ,
@@ -116,7 +114,7 @@ public void MergeConfigurations_NoMatchingConfigs_ReturnsEmpty()
116114 var result = ApmTracingConfigMerger . MergeConfigurations ( configs , "test-service" , "production" ) ;
117115
118116 // Assert
119- result . Should ( ) . Be ( "{ \" lib_config \" :{}}" ) ;
117+ result ? [ "lib_config" ] ? [ "tracing_enabled" ] ? . Value < bool > ( ) . Should ( ) . BeFalse ( ) ;
120118 }
121119
122120 [ Fact ]
@@ -135,19 +133,18 @@ public void MergeConfigurations_EmptyConfigs_ReturnsOriginal()
135133 // Act
136134 var result = ApmTracingConfigMerger . MergeConfigurations ( configs , "test-service" , "production" ) ;
137135
138- var resultJson = JObject . Parse ( result ) ;
139- resultJson [ "lib_config" ] ? [ "tracing_enabled" ] ? . Value < bool > ( ) . Should ( ) . BeFalse ( ) ;
136+ result [ "lib_config" ] ? [ "tracing_enabled" ] ? . Value < bool > ( ) . Should ( ) . BeFalse ( ) ;
140137 }
141138
142139 [ Fact ]
143140 public void MergeConfigurations_ComplexScenario_CorrectPriorityMerging ( )
144141 {
145- // Arrange - Following the priority order:
146- // 1. Service+env (highest priority)
147- // 2. Service
148- // 3. Env
149- // 4. Cluster-target (not implemented)
150- // 5. Org level (lowest priority)
142+ // Arrange - Following the priority order (bit-based calculation) :
143+ // 6 (110): Service+env (highest priority)
144+ // 4 (100): Service only
145+ // 2 (010): Env only
146+ // 1 (001): Cluster-target only
147+ // 0 (000): Org level (lowest priority)
151148
152149 var orgConfig = CreateRemoteConfig (
153150 "org" ,
@@ -204,8 +201,7 @@ public void MergeConfigurations_ComplexScenario_CorrectPriorityMerging()
204201 var result = ApmTracingConfigMerger . MergeConfigurations ( configs , "test-service" , "production" ) ;
205202
206203 // Assert
207- var resultJson = JObject . Parse ( result ) ;
208- var libConfig = resultJson [ "lib_config" ] ;
204+ var libConfig = result [ "lib_config" ] ;
209205
210206 // Service+Env (highest priority) - should set tracing_sampling_rate
211207 libConfig ? [ "tracing_sampling_rate" ] ? . Value < double > ( ) . Should ( ) . Be ( 0.8 ) ;
@@ -244,12 +240,15 @@ public void ApmTracingConfig_Matches_CorrectBehavior(string configService, strin
244240 }
245241
246242 [ Theory ]
247- [ InlineData ( "test-service" , "production" , null , 5 ) ] // Service+env
248- [ InlineData ( "test-service" , "*" , null , 4 ) ] // Service only
249- [ InlineData ( "*" , "production" , null , 3 ) ] // Env only
250- [ InlineData ( null , null , "" , 2 ) ] // Cluster only
251- [ InlineData ( "*" , "*" , null , 1 ) ] // Wildcard, Org level
252- [ InlineData ( null , null , null , 1 ) ] // Org level
243+ [ InlineData ( "test-service" , "production" , "test-cluster" , 7 ) ] // Service+env+cluster (111 binary = 7)
244+ [ InlineData ( "test-service" , "production" , null , 6 ) ] // Service+env (110 binary = 6)
245+ [ InlineData ( "test-service" , "*" , "test-cluster" , 5 ) ] // Service+cluster (101 binary = 5)
246+ [ InlineData ( "test-service" , "*" , null , 4 ) ] // Service only (100 binary = 4)
247+ [ InlineData ( "*" , "production" , "test-cluster" , 3 ) ] // Env+cluster (011 binary = 3)
248+ [ InlineData ( "*" , "production" , null , 2 ) ] // Env only (010 binary = 2)
249+ [ InlineData ( null , null , "test-cluster" , 1 ) ] // Cluster only (001 binary = 1)
250+ [ InlineData ( "*" , "*" , null , 0 ) ] // Wildcard, Org level (000 binary = 0)
251+ [ InlineData ( null , null , null , 0 ) ] // Org level (000 binary = 0)
253252 public void ApmTracingConfig_Priority_CorrectValues ( string ? service , string ? env , string ? cluster , int expectedPriority )
254253 {
255254 // Arrange
@@ -264,7 +263,10 @@ public void ApmTracingConfig_Priority_CorrectValues(string? service, string? env
264263 K8sTargetV2 ? clusterTarget = null ;
265264 if ( cluster != null )
266265 {
267- clusterTarget = new K8sTargetV2 ( ) ;
266+ clusterTarget = new K8sTargetV2
267+ {
268+ ClusterTargets = [ new ( ) { ClusterName = cluster } ]
269+ } ;
268270 }
269271
270272 var config = new ApmTracingConfig ( "test" , libConfig , serviceTarget , clusterTarget ) ;
@@ -281,10 +283,13 @@ public void MergeConfigurations_ClusterTargetPriority_CorrectOrdering()
281283 "org" ,
282284 new { lib_config = new { tracing_enabled = false } } ) ;
283285
284- var clusterConfig = CreateRemoteConfigWithCluster (
286+ var clusterConfig = CreateRemoteConfig (
285287 "cluster" ,
286- new { tracing_enabled = true } ,
287- new { cluster_targets = new [ ] { new { cluster_name = "prod-cluster" } } } ) ;
288+ new
289+ {
290+ lib_config = new { tracing_enabled = true } ,
291+ k8s_target_v2 = new { cluster_targets = new [ ] { new { cluster_name = "prod-cluster" } } }
292+ } ) ;
288293
289294 var envConfig = CreateRemoteConfig (
290295 "env" ,
@@ -300,13 +305,12 @@ public void MergeConfigurations_ClusterTargetPriority_CorrectOrdering()
300305 var result = ApmTracingConfigMerger . MergeConfigurations ( configs , "test-service" , "production" ) ;
301306
302307 // Assert
303- var resultJson = JObject . Parse ( result ) ;
304- var libConfig = resultJson [ "lib_config" ] ;
308+ var libConfig = result [ "lib_config" ] ;
305309
306- // Env config (priority 3) should override cluster (priority 2) for log_injection_enabled
310+ // Env config should override cluster for log_injection_enabled
307311 libConfig ? [ "log_injection_enabled" ] ? . Value < bool > ( ) . Should ( ) . BeTrue ( ) ;
308312
309- // Env config (priority 3) should override cluster (priority 2) for tracing_enabled
313+ // Env config should override cluster for tracing_enabled
310314 // But if env doesn't specify it, cluster should override org
311315 libConfig ? [ "tracing_enabled" ] ? . Value < bool > ( ) . Should ( ) . BeTrue ( ) ;
312316 }
@@ -315,10 +319,13 @@ public void MergeConfigurations_ClusterTargetPriority_CorrectOrdering()
315319 public void MergeConfigurations_ServiceEnvOverridesCluster_CorrectPriority ( )
316320 {
317321 // Arrange
318- var clusterConfig = CreateRemoteConfigWithCluster (
322+ var clusterConfig = CreateRemoteConfig (
319323 "cluster" ,
320- new { tracing_enabled = false } ,
321- new { cluster_targets = new [ ] { new { cluster_name = "prod-cluster" } } } ) ;
324+ new
325+ {
326+ lib_config = new { tracing_enabled = false } ,
327+ k8s_target_v2 = new { cluster_targets = new [ ] { new { cluster_name = "prod-cluster" } } }
328+ } ) ;
322329
323330 var serviceEnvConfig = CreateRemoteConfig (
324331 "service-env" ,
@@ -334,24 +341,25 @@ public void MergeConfigurations_ServiceEnvOverridesCluster_CorrectPriority()
334341 var result = ApmTracingConfigMerger . MergeConfigurations ( configs , "test-service" , "production" ) ;
335342
336343 // Assert
337- var resultJson = JObject . Parse ( result ) ;
338-
339- // Service+Env (priority 5) should override cluster (priority 2)
340- resultJson [ "lib_config" ] ? [ "tracing_enabled" ] ? . Value < bool > ( ) . Should ( ) . BeTrue ( ) ;
344+ // Service+Env should override cluster
345+ result [ "lib_config" ] ? [ "tracing_enabled" ] ? . Value < bool > ( ) . Should ( ) . BeTrue ( ) ;
341346 }
342347
343348 [ Fact ]
344349 public void MergeConfigurations_AllPriorityLevels_CorrectOrdering ( )
345350 {
346- // Arrange - Test all 5 priority levels
351+ // Arrange - Test all 5 priority levels (org, cluster, env, service, service+env)
347352 var orgConfig = CreateRemoteConfig (
348353 "org" ,
349354 new { lib_config = new { tracing_enabled = true , value = "org" } } ) ;
350355
351- var clusterConfig = CreateRemoteConfigWithCluster (
356+ var clusterConfig = CreateRemoteConfig (
352357 "cluster" ,
353- new { log_injection_enabled = true , value = "cluster" } ,
354- new { cluster_targets = new [ ] { new { cluster_name = "test" } } } ) ;
358+ new
359+ {
360+ lib_config = new { log_injection_enabled = true , value = "cluster" } ,
361+ k8s_target_v2 = new { cluster_targets = new [ ] { new { cluster_name = "test" } } }
362+ } ) ;
355363
356364 var envConfig = CreateRemoteConfig (
357365 "env" ,
@@ -386,15 +394,14 @@ public void MergeConfigurations_AllPriorityLevels_CorrectOrdering()
386394 var result = ApmTracingConfigMerger . MergeConfigurations ( configs , "test-service" , "production" ) ;
387395
388396 // Assert
389- var resultJson = JObject . Parse ( result ) ;
390- var libConfig = resultJson [ "lib_config" ] ;
397+ var libConfig = result [ "lib_config" ] ;
391398
392399 // Verify priority ordering:
393- libConfig ? [ "tracing_tags" ] ? . Value < string > ( ) . Should ( ) . Be ( "tags" ) ; // Service+Env (5 )
400+ libConfig ? [ "tracing_tags" ] ? . Value < string > ( ) . Should ( ) . Be ( "tags" ) ; // Service+Env (6 )
394401 libConfig ? [ "tracing_header_tags" ] ? . Value < string > ( ) . Should ( ) . Be ( "headers" ) ; // Service (4)
395- libConfig ? [ "tracing_sampling_rate" ] ? . Value < double > ( ) . Should ( ) . Be ( 0.3 ) ; // Env (3 )
396- libConfig ? [ "log_injection_enabled" ] ? . Value < bool > ( ) . Should ( ) . BeTrue ( ) ; // Cluster (2 )
397- libConfig ? [ "tracing_enabled" ] ? . Value < bool > ( ) . Should ( ) . BeTrue ( ) ; // Org (1 )
402+ libConfig ? [ "tracing_sampling_rate" ] ? . Value < double > ( ) . Should ( ) . Be ( 0.3 ) ; // Env (2 )
403+ libConfig ? [ "log_injection_enabled" ] ? . Value < bool > ( ) . Should ( ) . BeTrue ( ) ; // Cluster (1 )
404+ libConfig ? [ "tracing_enabled" ] ? . Value < bool > ( ) . Should ( ) . BeTrue ( ) ; // Org (0 )
398405 }
399406
400407 [ Fact ]
@@ -421,38 +428,60 @@ public void ApmTracingConfig_MergeWith_HigherPriorityWins()
421428
422429 // LogInjectionEnabled is null, should use value from low priority
423430 } ,
424- new ServiceTarget { Service = "test-service" , Env = "production" } , // Service+env (priority 5 )
431+ new ServiceTarget { Service = "test-service" , Env = "production" } , // Service+env (priority 6 )
425432 null ) ;
426433
427434 // Act
428435 var merged = lowPriorityConfig . MergeWith ( highPriorityConfig ) ;
429436
430437 // Assert
431438 merged . ConfigId . Should ( ) . Be ( "high" ) ; // Higher priority config's ID
432- merged . Priority . Should ( ) . Be ( 5 ) ; // Higher priority
439+ merged . Priority . Should ( ) . Be ( 6 ) ; // Higher priority (service+env = 110 binary = 6)
433440 merged . LibConfig . TracingEnabled . Should ( ) . BeTrue ( ) ; // From high priority
434441 merged . LibConfig . LogInjectionEnabled . Should ( ) . BeTrue ( ) ; // From low priority
435442 merged . LibConfig . TracingSamplingRate . Should ( ) . Be ( 0.8 ) ; // From high priority
436443 }
437444
438- private static RemoteConfiguration CreateRemoteConfigWithCluster ( string id , object libConfig , object k8sTarget )
445+ [ Fact ]
446+ public void MergeConfigurations_ReturnsValidJToken ( )
439447 {
440- var content = new
441- {
442- lib_config = libConfig ,
443- k8s_target_v2 = k8sTarget
444- } ;
448+ // Arrange
449+ var orgConfig = CreateRemoteConfig (
450+ "org" ,
451+ new
452+ {
453+ lib_config = new
454+ {
455+ tracing_enabled = true ,
456+ log_injection_enabled = true ,
457+ tracing_sampling_rate = 0.1 ,
458+ tracing_tags = "[\" org:global\" ]"
459+ }
460+ } ) ;
445461
446- var json = JsonConvert . SerializeObject ( content ) ;
447- var bytes = Encoding . UTF8 . GetBytes ( json ) ;
448- var path = RemoteConfigurationPath . FromPath ( $ "datadog/123/APM_TRACING/{ id } /config") ;
462+ var serviceConfig = CreateRemoteConfig (
463+ "service" ,
464+ new
465+ {
466+ service_target = new { service = "test-service" } ,
467+ lib_config = new
468+ {
469+ log_injection_enabled = false ,
470+ tracing_sampling_rules = "[{\" sample_rate\" :0.9}]"
471+ }
472+ } ) ;
449473
450- return new RemoteConfiguration (
451- path : path ,
452- contents : bytes ,
453- length : bytes . Length ,
454- hashes : new Dictionary < string , string > { { "sha256" , "dummy-hash" } } ,
455- version : 1 ) ;
474+ var configs = new List < RemoteConfiguration > { orgConfig , serviceConfig } ;
475+
476+ // Act
477+ var result = ApmTracingConfigMerger . MergeConfigurations ( configs , "test-service" , "production" ) ;
478+
479+ // Assert
480+ result . Should ( ) . NotBeNull ( ) ;
481+ result . Type . Should ( ) . Be ( JTokenType . Object ) ;
482+ result [ "lib_config" ] . Should ( ) . NotBeNull ( ) ;
483+ result [ "lib_config" ] ? [ "log_injection_enabled" ] ? . Value < bool > ( ) . Should ( ) . BeFalse ( ) ;
484+ result [ "lib_config" ] ? [ "tracing_enabled" ] ? . Value < bool > ( ) . Should ( ) . BeTrue ( ) ;
456485 }
457486
458487 private static RemoteConfiguration CreateRemoteConfig ( string id , object content )
0 commit comments