@@ -43,12 +43,16 @@ mod tests {
43
43
testing:: trace:: InMemorySpanExporterBuilder ,
44
44
trace:: span_limit:: { DEFAULT_MAX_EVENT_PER_SPAN , DEFAULT_MAX_LINKS_PER_SPAN } ,
45
45
} ;
46
+ use opentelemetry:: testing:: trace:: TestSpan ;
47
+ use opentelemetry:: trace:: {
48
+ SamplingDecision , SamplingResult , SpanKind , TraceContextExt , TraceState ,
49
+ } ;
46
50
use opentelemetry:: {
47
51
trace:: {
48
52
Event , Link , Span , SpanBuilder , SpanContext , SpanId , TraceFlags , TraceId , Tracer ,
49
53
TracerProvider as _,
50
54
} ,
51
- KeyValue ,
55
+ Context , KeyValue ,
52
56
} ;
53
57
54
58
#[ test]
@@ -176,4 +180,92 @@ mod tests {
176
180
assert_eq ! ( span. events. len( ) , DEFAULT_MAX_EVENT_PER_SPAN as usize ) ;
177
181
assert_eq ! ( span. events. dropped_count, DEFAULT_MAX_EVENT_PER_SPAN + 2 ) ;
178
182
}
183
+
184
+ #[ test]
185
+ fn trace_state_for_dropped_sampler ( ) {
186
+ let exporter = InMemorySpanExporterBuilder :: new ( ) . build ( ) ;
187
+ let provider = TracerProvider :: builder ( )
188
+ . with_config ( config ( ) . with_sampler ( Sampler :: AlwaysOff ) )
189
+ . with_span_processor ( SimpleSpanProcessor :: new ( Box :: new ( exporter. clone ( ) ) ) )
190
+ . build ( ) ;
191
+
192
+ let tracer = provider. tracer ( "test" ) ;
193
+ let trace_state = TraceState :: from_key_value ( vec ! [ ( "foo" , "bar" ) ] ) . unwrap ( ) ;
194
+
195
+ let parent_context = Context :: new ( ) . with_span ( TestSpan ( SpanContext :: new (
196
+ TraceId :: from_u128 ( 10000 ) ,
197
+ SpanId :: from_u64 ( 20 ) ,
198
+ TraceFlags :: SAMPLED ,
199
+ true ,
200
+ trace_state. clone ( ) ,
201
+ ) ) ) ;
202
+
203
+ let span = tracer. start_with_context ( "span" , & parent_context) ;
204
+ assert_eq ! (
205
+ span. span_context( ) . trace_state( ) . get( "foo" ) ,
206
+ trace_state. get( "foo" )
207
+ )
208
+ }
209
+
210
+ #[ derive( Clone , Debug , Default ) ]
211
+ struct TestRecordOnlySampler { }
212
+
213
+ impl ShouldSample for TestRecordOnlySampler {
214
+ fn should_sample (
215
+ & self ,
216
+ parent_context : Option < & Context > ,
217
+ _trace_id : TraceId ,
218
+ _name : & str ,
219
+ _span_kind : & SpanKind ,
220
+ _attributes : & [ KeyValue ] ,
221
+ _links : & [ Link ] ,
222
+ ) -> SamplingResult {
223
+ let trace_state = parent_context
224
+ . unwrap ( )
225
+ . span ( )
226
+ . span_context ( )
227
+ . trace_state ( )
228
+ . clone ( ) ;
229
+ SamplingResult {
230
+ decision : SamplingDecision :: RecordOnly ,
231
+ attributes : vec ! [ KeyValue :: new( "record_only_key" , "record_only_value" ) ] ,
232
+ trace_state,
233
+ }
234
+ }
235
+ }
236
+
237
+ #[ test]
238
+ fn trace_state_for_record_only_sampler ( ) {
239
+ let exporter = InMemorySpanExporterBuilder :: new ( ) . build ( ) ;
240
+ let provider = TracerProvider :: builder ( )
241
+ . with_config ( config ( ) . with_sampler ( TestRecordOnlySampler :: default ( ) ) )
242
+ . with_span_processor ( SimpleSpanProcessor :: new ( Box :: new ( exporter. clone ( ) ) ) )
243
+ . build ( ) ;
244
+
245
+ let tracer = provider. tracer ( "test" ) ;
246
+ let trace_state = TraceState :: from_key_value ( vec ! [ ( "foo" , "bar" ) ] ) . unwrap ( ) ;
247
+
248
+ let parent_context = Context :: new ( ) . with_span ( TestSpan ( SpanContext :: new (
249
+ TraceId :: from_u128 ( 10000 ) ,
250
+ SpanId :: from_u64 ( 20 ) ,
251
+ TraceFlags :: SAMPLED ,
252
+ true ,
253
+ trace_state. clone ( ) ,
254
+ ) ) ) ;
255
+
256
+ let span = tracer. build_with_context (
257
+ SpanBuilder :: from_name ( "span" )
258
+ . with_attributes ( vec ! [ KeyValue :: new( "extra_attr_key" , "extra_attr_value" ) ] ) ,
259
+ & parent_context,
260
+ ) ;
261
+ assert ! ( !span. span_context( ) . trace_flags( ) . is_sampled( ) ) ;
262
+ assert_eq ! (
263
+ span. exported_data( ) . unwrap( ) . attributes,
264
+ vec![
265
+ KeyValue :: new( "extra_attr_key" , "extra_attr_value" ) ,
266
+ KeyValue :: new( "record_only_key" , "record_only_value" )
267
+ ]
268
+ ) ;
269
+ assert_eq ! ( span. span_context( ) . trace_state( ) . get( "foo" ) , Some ( "bar" ) ) ;
270
+ }
179
271
}
0 commit comments