@@ -49,7 +49,7 @@ public void TestCleanup()
4949 [ TestMethod ]
5050 public void BasicStartOperationWithActivity ( )
5151 {
52- var activity = new Activity ( "name" ) . SetParentId ( "parentId" ) . AddBaggage ( "b1" , "v1" ) . AddTag ( "t1" , "v1" ) ;
52+ var activity = new Activity ( "name" ) . AddBaggage ( "b1" , "v1" ) . AddTag ( "t1" , "v1" ) ;
5353
5454 RequestTelemetry telemetry ;
5555 using ( var operation = this . telemetryClient . StartOperation < RequestTelemetry > ( activity ) )
@@ -64,6 +64,87 @@ public void BasicStartOperationWithActivity()
6464 Assert . AreEqual ( telemetry , this . sendItems . Single ( ) ) ;
6565 }
6666
67+ [ TestMethod ]
68+ public void StartOperationWithActivity_LegacyId1 ( )
69+ {
70+ var activity = new Activity ( "name" )
71+ . SetParentId ( "parentId" )
72+ . AddBaggage ( "b1" , "v1" )
73+ . AddTag ( "t1" , "v1" ) ;
74+
75+ activity . ActivityTraceFlags = ActivityTraceFlags . Recorded ;
76+ activity . TraceStateString = "state=some" ;
77+
78+ RequestTelemetry telemetry ;
79+ using ( var operation = this . telemetryClient . StartOperation < RequestTelemetry > ( activity ) )
80+ {
81+ telemetry = operation . Telemetry ;
82+ Assert . AreEqual ( activity , Activity . Current ) ;
83+ Assert . IsNotNull ( activity . Id ) ;
84+ }
85+
86+ this . ValidateTelemetry ( telemetry , activity , true , "parentId" ) ;
87+ Assert . IsTrue ( telemetry . Properties . TryGetValue ( "ai_legacyRootId" , out var legacyRoot ) ) ;
88+ Assert . AreEqual ( "parentId" , legacyRoot ) ;
89+
90+ Assert . AreEqual ( telemetry , this . sendItems . Single ( ) ) ;
91+ }
92+
93+ [ TestMethod ]
94+ public void StartOperationWithActivity_LegacyId2 ( )
95+ {
96+ var activity = new Activity ( "name" )
97+ . SetParentId ( "|parentId.123." )
98+ . AddBaggage ( "b1" , "v1" )
99+ . AddTag ( "t1" , "v1" ) ;
100+
101+ activity . ActivityTraceFlags = ActivityTraceFlags . Recorded ;
102+ activity . TraceStateString = "state=some" ;
103+
104+ RequestTelemetry telemetry ;
105+ using ( var operation = this . telemetryClient . StartOperation < RequestTelemetry > ( activity ) )
106+ {
107+ telemetry = operation . Telemetry ;
108+ Assert . AreEqual ( activity , Activity . Current ) ;
109+ Assert . IsNotNull ( activity . Id ) ;
110+ }
111+
112+ this . ValidateTelemetry ( telemetry , activity , true , "|parentId.123." ) ;
113+
114+ Assert . IsTrue ( telemetry . Properties . TryGetValue ( "ai_legacyRootId" , out var legacyRoot ) ) ;
115+ Assert . AreEqual ( "parentId" , legacyRoot ) ;
116+ Assert . AreEqual ( telemetry , this . sendItems . Single ( ) ) ;
117+ }
118+
119+ [ TestMethod ]
120+ public void StartOperationWithActivity_LegacyIdCompatible ( )
121+ {
122+ var activity = new Activity ( "name" )
123+ . SetParentId ( "|00112233445566778899aabbccddeeff.123." )
124+ . AddBaggage ( "b1" , "v1" )
125+ . AddTag ( "t1" , "v1" ) ;
126+
127+ activity . ActivityTraceFlags = ActivityTraceFlags . Recorded ;
128+ activity . TraceStateString = "state=some" ;
129+
130+ RequestTelemetry telemetry ;
131+ Activity newActivity = null ;
132+ using ( var operation = this . telemetryClient . StartOperation < RequestTelemetry > ( activity ) )
133+ {
134+ telemetry = operation . Telemetry ;
135+ newActivity = Activity . Current ;
136+ Assert . AreNotEqual ( activity , newActivity ) ;
137+ Assert . IsNotNull ( newActivity ? . Id ) ;
138+ }
139+
140+ this . ValidateTelemetry ( telemetry , newActivity , true , "|00112233445566778899aabbccddeeff.123." ) ;
141+ Assert . AreEqual ( "00112233445566778899aabbccddeeff" , telemetry . Context . Operation . Id ) ;
142+
143+ Assert . IsFalse ( telemetry . Properties . ContainsKey ( "ai_legacyRootId" ) ) ;
144+
145+ Assert . AreEqual ( telemetry , this . sendItems . Single ( ) ) ;
146+ }
147+
67148 [ TestMethod ]
68149 public void BasicStartOperationWithActivityInScopeOfUnrelatedActivity ( )
69150 {
@@ -80,7 +161,7 @@ public void BasicStartOperationWithActivityInScopeOfUnrelatedActivity()
80161 Assert . IsNotNull ( activity . Id ) ;
81162 }
82163
83- this . ValidateTelemetry ( telemetry , activity ) ;
164+ this . ValidateTelemetry ( telemetry , activity , true , "parentId" ) ;
84165
85166 Assert . AreEqual ( telemetry , this . sendItems . Single ( ) ) ;
86167 Assert . AreEqual ( outerActivity , Activity . Current ) ;
@@ -99,7 +180,11 @@ public void BasicStartOperationWithStartedActivityInScopeOfUnrelatedActivity()
99180
100181 // this is not right to give started Activity to StartOperation, but nothing terrible should happen
101182 // except it won't be possible to restore original context after StartOperation completes
102- var activity = new Activity ( "name" ) . SetParentId ( "parentId" ) . AddBaggage ( "b1" , "v1" ) . AddTag ( "t1" , "v1" ) . Start ( ) ;
183+ var activity = new Activity ( "name" )
184+ . SetParentId ( ActivityTraceId . CreateRandom ( ) , ActivitySpanId . CreateRandom ( ) )
185+ . AddBaggage ( "b1" , "v1" )
186+ . AddTag ( "t1" , "v1" )
187+ . Start ( ) ;
103188
104189 RequestTelemetry telemetry ;
105190 using ( var operation = this . telemetryClient . StartOperation < RequestTelemetry > ( activity ) )
@@ -119,7 +204,6 @@ public void BasicStartOperationWithStartedActivityInScopeOfUnrelatedActivity()
119204 Assert . IsNotNull ( request ) ;
120205 Assert . AreEqual ( activity . TraceId . ToHexString ( ) , request . Context . Operation . Id ) ;
121206 Assert . AreEqual ( $ "|{ activity . TraceId . ToHexString ( ) } .{ activity . SpanId . ToHexString ( ) } .", request . Id ) ;
122- Assert . AreEqual ( "parentId" , request . Context . Operation . ParentId ) ;
123207 }
124208
125209 /// <summary>
@@ -128,7 +212,7 @@ public void BasicStartOperationWithStartedActivityInScopeOfUnrelatedActivity()
128212 [ TestMethod ]
129213 public void InvalidStartOperationWithStartedActivity ( )
130214 {
131- var activity = new Activity ( "name" ) . SetParentId ( "parentId" ) . AddBaggage ( "b1" , "v1" ) . AddTag ( "t1" , "v1" ) . Start ( ) ;
215+ var activity = new Activity ( "name" ) . AddBaggage ( "b1" , "v1" ) . AddTag ( "t1" , "v1" ) . Start ( ) ;
132216
133217 DependencyTelemetry telemetry ;
134218 using ( var operation = this . telemetryClient . StartOperation < DependencyTelemetry > ( activity ) )
@@ -150,12 +234,12 @@ public void StartOperationSynchronousInScopeOfOtherUnrelatedActivity()
150234 // nested operation processing.
151235 // E.g. Background Activity is tracking high-level operation "get 5 messages from the queue and process them all"
152236 // In this case, each message processing has it's own correlation scope, passed in the message (i.e. Parent Activity is external)
153- // The requirement is that backgorund Activity must survive each message processing.
237+ // The requirement is that background Activity must survive each message processing.
154238
155239 var backgroundActivity = new Activity ( "background" ) . Start ( ) ;
156240
157241 //since ParentId is set on the activity, it won't be child of the parentActivity
158- var activity = new Activity ( "name" ) . SetParentId ( "parentId" ) ;
242+ var activity = new Activity ( "name" ) . SetParentId ( ActivityTraceId . CreateRandom ( ) , ActivitySpanId . CreateRandom ( ) ) ;
159243
160244 // in order to keep parentActivity, StartOperation and StopOperation(or dispose)
161245 // must be called
@@ -184,7 +268,7 @@ public async Task StartOperationAsyncInScopeOfOtherUnrelatedActivity()
184268 var activity = new Activity ( "name" ) . SetParentId ( "parentId" ) ;
185269 RequestTelemetry telemetry = await ProcessWithStartOperationAsync < RequestTelemetry > ( activity , null ) ;
186270
187- this . ValidateTelemetry ( telemetry , activity ) ;
271+ this . ValidateTelemetry ( telemetry , activity , true , "parentId" ) ;
188272 Assert . AreEqual ( telemetry , this . sendItems . Single ( ) ) ;
189273
190274 // after processing is done and chile activity is finished,
@@ -332,20 +416,34 @@ private async Task ProcessAsync(Activity activity, Activity parentActivity)
332416 return telemetry ;
333417 }
334418
335- private void ValidateTelemetry < T > ( T telemetry , Activity activity , bool isW3C = true ) where T : OperationTelemetry
419+ private void ValidateTelemetry < T > ( T telemetry , Activity activity , bool isW3C = true , string legacyParentId = null ) where T : OperationTelemetry
336420 {
337421 Assert . AreEqual ( activity . OperationName , telemetry . Name ) ;
422+ Assert . AreEqual (
423+ isW3C
424+ ? W3CUtilities . FormatTelemetryId ( activity . TraceId . ToHexString ( ) , activity . SpanId . ToHexString ( ) )
425+ : activity . Id , telemetry . Id ) ;
426+
338427 if ( isW3C )
339428 {
340- Assert . AreEqual ( W3CUtilities . FormatTelemetryId ( activity . TraceId . ToHexString ( ) , activity . SpanId . ToHexString ( ) ) , telemetry . Id ) ;
429+ if ( activity . ParentSpanId != default && activity . ParentSpanId . ToHexString ( ) != "0000000000000000" )
430+ {
431+ Assert . AreEqual (
432+ W3CUtilities . FormatTelemetryId ( activity . TraceId . ToHexString ( ) ,
433+ activity . ParentSpanId . ToHexString ( ) ) , telemetry . Context . Operation . ParentId ) ;
434+ }
435+ else
436+ {
437+ Assert . AreEqual ( legacyParentId , telemetry . Context . Operation . ParentId ) ;
438+ }
439+
440+ Assert . AreEqual ( activity . TraceId . ToHexString ( ) , telemetry . Context . Operation . Id ) ;
341441 }
342442 else
343443 {
344- Assert . AreEqual ( activity . Id , telemetry . Id ) ;
444+ Assert . AreEqual ( activity . ParentId , telemetry . Context . Operation . ParentId ) ;
445+ Assert . AreEqual ( activity . RootId , telemetry . Context . Operation . Id ) ;
345446 }
346-
347- Assert . AreEqual ( activity . ParentId , telemetry . Context . Operation . ParentId ) ;
348- Assert . AreEqual ( activity . RootId , telemetry . Context . Operation . Id ) ;
349447
350448 foreach ( var baggage in activity . Baggage )
351449 {
@@ -358,6 +456,18 @@ private void ValidateTelemetry<T>(T telemetry, Activity activity, bool isW3C = t
358456 Assert . IsTrue ( telemetry . Properties . ContainsKey ( tag . Key ) ) ;
359457 Assert . AreEqual ( tag . Value , telemetry . Properties [ tag . Key ] ) ;
360458 }
459+
460+ if ( activity . TraceStateString != null )
461+ {
462+ Assert . IsTrue ( telemetry . Properties . TryGetValue ( "tracestate" , out var tracestate ) ) ;
463+ Assert . AreEqual ( activity . TraceStateString , tracestate ) ;
464+ }
465+ else
466+ {
467+ Assert . IsFalse ( telemetry . Properties . ContainsKey ( "tracestate" ) ) ;
468+ }
469+
470+ Assert . AreEqual ( activity . Recorded ? SamplingDecision . SampledIn : SamplingDecision . None , ( telemetry as ISupportAdvancedSampling ) . ProactiveSamplingDecision ) ;
361471 }
362472 }
363473}
0 commit comments