@@ -11,6 +11,7 @@ const { AgentlessJSONEncoder } = require('../../src/encode/agentless-json')
1111describe ( 'AgentlessJSONEncoder' , ( ) => {
1212 let encoder
1313 let data
14+ let childSpan
1415
1516 beforeEach ( ( ) => {
1617 encoder = new AgentlessJSONEncoder ( )
@@ -33,6 +34,20 @@ describe('AgentlessJSONEncoder', () => {
3334 duration : 5000000 ,
3435 links : [ ] ,
3536 } ]
37+ childSpan = {
38+ trace_id : id ( '1234abcd1234abcd' ) ,
39+ span_id : id ( 'aaaa000000000001' ) ,
40+ parent_id : id ( '5678efab5678efab' ) ,
41+ name : 'child' ,
42+ resource : 'child-resource' ,
43+ service : 'test-service' ,
44+ error : 0 ,
45+ meta : { } ,
46+ metrics : { } ,
47+ start : 1234567891000000000 ,
48+ duration : 1000000 ,
49+ links : [ ] ,
50+ }
3651 } )
3752
3853 describe ( 'encode' , ( ) => {
@@ -89,18 +104,20 @@ describe('AgentlessJSONEncoder', () => {
89104 // Start time is converted from nanoseconds to seconds for intake format
90105 assert . strictEqual ( span . start , 1234567890 )
91106 assert . strictEqual ( span . duration , 5000000 )
92- assert . deepStrictEqual ( span . meta , { foo : 'bar' } )
93- assert . deepStrictEqual ( span . metrics , { example : 1.5 } )
107+ assert . deepStrictEqual ( span . meta , { foo : 'bar' , '_dd.compute_stats' : '1' } )
108+ assert . deepStrictEqual ( span . metrics , { example : 1.5 , _trace_root : 1 } )
94109 } )
95110
96111 it ( 'should handle multiple spans in one trace' , ( ) => {
97112 encoder . encode ( data )
98- encoder . encode ( data )
113+ encoder . encode ( [ childSpan ] )
99114
100115 const buffer = encoder . makePayload ( )
101116 const decoded = JSON . parse ( buffer . toString ( ) )
102117
103118 assert . strictEqual ( decoded . spans . length , 2 )
119+ assert . strictEqual ( decoded . spans [ 0 ] . meta [ '_dd.compute_stats' ] , '1' )
120+ assert . strictEqual ( decoded . spans [ 1 ] . meta [ '_dd.compute_stats' ] , undefined )
104121 } )
105122
106123 it ( 'should handle spans without optional fields' , ( ) => {
@@ -155,6 +172,61 @@ describe('AgentlessJSONEncoder', () => {
155172 assert . deepStrictEqual ( decoded . spans [ 0 ] . links , [ { trace_id : 'abc123' , span_id : 'def456' } ] )
156173 } )
157174
175+ it ( 'should set _dd.compute_stats on the first span only' , ( ) => {
176+ encoder . encode ( [ data [ 0 ] , childSpan ] )
177+
178+ const buffer = encoder . makePayload ( )
179+ const decoded = JSON . parse ( buffer . toString ( ) )
180+
181+ assert . strictEqual ( decoded . spans [ 0 ] . meta [ '_dd.compute_stats' ] , '1' )
182+ assert . strictEqual ( decoded . spans [ 1 ] . meta [ '_dd.compute_stats' ] , undefined )
183+ } )
184+
185+ it ( 'should set _trace_root on spans with zero parent_id' , ( ) => {
186+ encoder . encode ( [ data [ 0 ] , childSpan ] )
187+
188+ const buffer = encoder . makePayload ( )
189+ const decoded = JSON . parse ( buffer . toString ( ) )
190+
191+ assert . strictEqual ( decoded . spans [ 0 ] . metrics . _trace_root , 1 )
192+ assert . strictEqual ( decoded . spans [ 1 ] . metrics . _trace_root , undefined )
193+ } )
194+
195+ it ( 'should set _top_level on spans marked as top-level' , ( ) => {
196+ data [ 0 ] . metrics [ '_dd.top_level' ] = 1
197+
198+ encoder . encode ( [ data [ 0 ] , childSpan ] )
199+
200+ const buffer = encoder . makePayload ( )
201+ const decoded = JSON . parse ( buffer . toString ( ) )
202+
203+ assert . strictEqual ( decoded . spans [ 0 ] . metrics . _top_level , 1 )
204+ assert . strictEqual ( decoded . spans [ 1 ] . metrics . _top_level , undefined )
205+ } )
206+
207+ it ( 'should not set _top_level when _dd.top_level is 0' , ( ) => {
208+ data [ 0 ] . metrics [ '_dd.top_level' ] = 0
209+
210+ encoder . encode ( data )
211+
212+ const buffer = encoder . makePayload ( )
213+ const decoded = JSON . parse ( buffer . toString ( ) )
214+
215+ assert . strictEqual ( decoded . spans [ 0 ] . metrics . _top_level , undefined )
216+ } )
217+
218+ it ( 'should set _dd.compute_stats on next span when first span is malformed' , ( ) => {
219+ const badSpan = { name : 'bad' }
220+
221+ encoder . encode ( [ badSpan , childSpan ] )
222+
223+ const buffer = encoder . makePayload ( )
224+ const decoded = JSON . parse ( buffer . toString ( ) )
225+
226+ assert . strictEqual ( decoded . spans . length , 1 )
227+ assert . strictEqual ( decoded . spans [ 0 ] . meta [ '_dd.compute_stats' ] , '1' )
228+ } )
229+
158230 it ( 'should skip malformed spans and continue encoding' , ( ) => {
159231 const goodSpan = data [ 0 ]
160232 const badSpan = { name : 'bad' } // Missing required ID fields
0 commit comments