@@ -165,3 +165,69 @@ fn test_add_event_with_timestamp() {
165
165
event_data. timestamp
166
166
) ;
167
167
}
168
+
169
+ #[ test]
170
+ fn test_add_link_variants ( ) {
171
+ let ( _tracer, provider, exporter, subscriber) = test_tracer ( ) ;
172
+
173
+ let link_builder_cx = opentelemetry:: trace:: SpanContext :: new (
174
+ opentelemetry:: trace:: TraceId :: from_u128 ( 0x1234567890abcdef1234567890abcdef ) ,
175
+ opentelemetry:: trace:: SpanId :: from_u64 ( 0x1234567890abcdef ) ,
176
+ opentelemetry:: trace:: TraceFlags :: default ( ) ,
177
+ true , // Is remote
178
+ opentelemetry:: trace:: TraceState :: default ( ) ,
179
+ ) ;
180
+ let link_current_cx = opentelemetry:: trace:: SpanContext :: new (
181
+ opentelemetry:: trace:: TraceId :: from_u128 ( 0xabcdef1234567890abcdef1234567890 ) ,
182
+ opentelemetry:: trace:: SpanId :: from_u64 ( 0xabcdef1234567890 ) ,
183
+ opentelemetry:: trace:: TraceFlags :: default ( ) ,
184
+ true , // Is remote
185
+ opentelemetry:: trace:: TraceState :: default ( ) ,
186
+ ) ;
187
+ let link_attrs = vec ! [
188
+ opentelemetry:: KeyValue :: new( "link_key_1" , "link_value_1" ) ,
189
+ opentelemetry:: KeyValue :: new( "link_key_2" , 123 ) ,
190
+ ] ;
191
+
192
+ tracing:: subscriber:: with_default ( subscriber, || {
193
+ let root = tracing:: debug_span!( "root" ) ;
194
+ // Add the link using the extension method that now targets the builder
195
+ root. add_link ( link_builder_cx. clone ( ) ) ;
196
+ // Enter span to make it current for the link addition
197
+ let _enter = root. enter ( ) ;
198
+ // Add the link using the extension method that now targets the span in the context
199
+ root. add_link_with_attributes ( link_current_cx. clone ( ) , link_attrs. clone ( ) ) ;
200
+ } ) ;
201
+
202
+ drop ( provider) ; // flush all spans
203
+ let spans = exporter. 0 . lock ( ) . unwrap ( ) ;
204
+
205
+ assert_eq ! ( spans. len( ) , 1 , "Should have exported exactly one span." ) ;
206
+ let root_span_data = spans. first ( ) . unwrap ( ) ;
207
+
208
+ assert_eq ! ( root_span_data. links. len( ) , 2 , "Span should have two links." ) ;
209
+ let mut links = root_span_data. links . iter ( ) . collect :: < Vec < _ > > ( ) ;
210
+ links. sort_by ( |a, b| {
211
+ a. span_context
212
+ . trace_id ( )
213
+ . to_string ( )
214
+ . cmp ( & b. span_context . trace_id ( ) . to_string ( ) )
215
+ } ) ;
216
+ let link1 = & links[ 0 ] ;
217
+ let link2 = & links[ 1 ] ;
218
+
219
+ assert_eq ! (
220
+ link1. span_context, link_builder_cx,
221
+ "Link 1 context mismatch."
222
+ ) ;
223
+ assert_eq ! (
224
+ link1. attributes,
225
+ vec![ ] ,
226
+ "Link 1 attributes should be empty."
227
+ ) ;
228
+ assert_eq ! (
229
+ link2. span_context, link_current_cx,
230
+ "Link 2 context mismatch."
231
+ ) ;
232
+ assert_eq ! ( link2. attributes, link_attrs, "Link 2 attributes mismatch." ) ;
233
+ }
0 commit comments