Skip to main content

libdd_trace_utils/msgpack_decoder/v04/
mod.rs

1// Copyright 2024-Present Datadog, Inc. https://www.datadoghq.com/
2// SPDX-License-Identifier: Apache-2.0
3
4pub(crate) mod span;
5
6use self::span::decode_span;
7use crate::msgpack_decoder::decode::buffer::Buffer;
8use crate::msgpack_decoder::decode::error::DecodeError;
9use crate::span::v04::{Span, SpanBytes, SpanSlice};
10use crate::span::DeserializableTraceData;
11
12/// Decodes a Bytes buffer into a `Vec<Vec<SpanBytes>>` object, also represented as a vector of
13/// `TracerPayloadV04` objects.
14///
15/// # Arguments
16///
17/// * `data` - A tinybytes Bytes buffer containing the encoded data. Bytes are expected to be
18///   encoded msgpack data containing a list of a list of v04 spans.
19///
20/// # Returns
21///
22/// * `Ok(Vec<TracerPayloadV04>, usize)` - A vector of decoded `Vec<SpanSlice>` objects if
23///   successful. and the number of bytes in the slice used by the decoder.
24/// * `Err(DecodeError)` - An error if the decoding process fails.
25///
26/// # Errors
27///
28/// This function will return an error if:
29/// - The array length for trace count or span count cannot be read.
30/// - Any span cannot be decoded.
31///
32/// # Examples
33///
34/// ```
35/// use libdd_tinybytes;
36/// use libdd_trace_protobuf::pb::Span;
37/// use libdd_trace_utils::msgpack_decoder::v04::from_bytes;
38/// use rmp_serde::to_vec_named;
39///
40/// let span = Span {
41///     name: "test-span".to_owned(),
42///     ..Default::default()
43/// };
44/// let encoded_data = to_vec_named(&vec![vec![span]]).unwrap();
45/// let encoded_data_as_tinybytes = libdd_tinybytes::Bytes::from(encoded_data);
46/// let (decoded_traces, _payload_size) =
47///     from_bytes(encoded_data_as_tinybytes).expect("Decoding failed");
48///
49/// assert_eq!(1, decoded_traces.len());
50/// assert_eq!(1, decoded_traces[0].len());
51/// let decoded_span = &decoded_traces[0][0];
52/// assert_eq!("test-span", decoded_span.name.as_str());
53/// ```
54pub fn from_bytes(
55    data: libdd_tinybytes::Bytes,
56) -> Result<(Vec<Vec<SpanBytes>>, usize), DecodeError> {
57    from_buffer(&mut Buffer::new(data))
58}
59
60/// Decodes a slice of bytes into a `Vec<Vec<SpanSlice>>` object.
61/// The resulting spans have the same lifetime as the initial buffer.
62///
63/// # Arguments
64///
65/// * `data` - A slice of bytes containing the encoded data. Bytes are expected to be encoded
66///   msgpack data containing a list of a list of v04 spans.
67///
68/// # Returns
69///
70/// * `Ok(Vec<TracerPayloadV04>, usize)` - A vector of decoded `Vec<SpanSlice>` objects if
71///   successful. and the number of bytes in the slice used by the decoder.
72/// * `Err(DecodeError)` - An error if the decoding process fails.
73///
74/// # Errors
75///
76/// This function will return an error if:
77/// - The array length for trace count or span count cannot be read.
78/// - Any span cannot be decoded.
79///
80/// # Examples
81///
82/// ```
83/// use libdd_tinybytes;
84/// use libdd_trace_protobuf::pb::Span;
85/// use libdd_trace_utils::msgpack_decoder::v04::from_slice;
86/// use rmp_serde::to_vec_named;
87///
88/// let span = Span {
89///     name: "test-span".to_owned(),
90///     ..Default::default()
91/// };
92/// let encoded_data = to_vec_named(&vec![vec![span]]).unwrap();
93/// let encoded_data_as_tinybytes = libdd_tinybytes::Bytes::from(encoded_data);
94/// let (decoded_traces, _payload_size) =
95///     from_slice(&encoded_data_as_tinybytes).expect("Decoding failed");
96///
97/// assert_eq!(1, decoded_traces.len());
98/// assert_eq!(1, decoded_traces[0].len());
99/// let decoded_span = &decoded_traces[0][0];
100/// assert_eq!("test-span", decoded_span.name);
101/// ```
102pub fn from_slice(data: &[u8]) -> Result<(Vec<Vec<SpanSlice<'_>>>, usize), DecodeError> {
103    from_buffer(&mut Buffer::new(data))
104}
105
106#[allow(clippy::type_complexity)]
107pub fn from_buffer<T: DeserializableTraceData>(
108    data: &mut Buffer<T>,
109) -> Result<(Vec<Vec<Span<T>>>, usize), DecodeError> {
110    let trace_count = rmp::decode::read_array_len(data.as_mut_slice()).map_err(|_| {
111        DecodeError::InvalidFormat("Unable to read array len for trace count".to_owned())
112    })?;
113
114    // Intentionally skip the size of the array (as it will be recomputed after coalescing).
115    let start_len = data.len();
116
117    #[allow(clippy::expect_used)]
118    Ok((
119        (0..trace_count).try_fold(
120            Vec::with_capacity(
121                trace_count
122                    .try_into()
123                    .expect("Unable to cast trace_count to usize"),
124            ),
125            |mut traces, _| {
126                let span_count =
127                    rmp::decode::read_array_len(data.as_mut_slice()).map_err(|_| {
128                        DecodeError::InvalidFormat(
129                            "Unable to read array len for span count".to_owned(),
130                        )
131                    })?;
132
133                let trace = (0..span_count).try_fold(
134                    Vec::with_capacity(
135                        span_count
136                            .try_into()
137                            .expect("Unable to cast span_count to usize"),
138                    ),
139                    |mut trace, _| {
140                        let span = decode_span(data)?;
141                        trace.push(span);
142                        Ok(trace)
143                    },
144                )?;
145
146                traces.push(trace);
147
148                Ok(traces)
149            },
150        )?,
151        start_len - data.len(),
152    ))
153}
154
155#[cfg(test)]
156mod tests {
157    use super::*;
158    use crate::test_utils::{create_test_json_span, create_test_no_alloc_span};
159    use bolero::check;
160    use libdd_tinybytes::{Bytes, BytesString};
161    use rmp_serde;
162    use rmp_serde::to_vec_named;
163    use serde_json::json;
164    use std::collections::HashMap;
165
166    #[test]
167    fn test_empty_array() {
168        let encoded_data = vec![0x90];
169        let slice = encoded_data.as_ref();
170        let (_decoded_traces, decoded_size) = from_slice(slice).expect("Decoding failed");
171
172        assert_eq!(0, decoded_size);
173    }
174
175    #[test]
176    fn test_decoder_size() {
177        let span = SpanBytes {
178            name: BytesString::from_slice("span_name".as_ref()).unwrap(),
179            ..Default::default()
180        };
181        let mut encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
182        let expected_size = encoded_data.len() - 1; // rmp_serde adds additional 0 byte
183        encoded_data.extend_from_slice(&[0, 0, 0, 0]); // some garbage, to be ignored
184        let (_decoded_traces, decoded_size) =
185            from_bytes(libdd_tinybytes::Bytes::from(encoded_data)).expect("Decoding failed");
186
187        assert_eq!(expected_size, decoded_size);
188    }
189
190    #[test]
191    fn test_decoder_read_string_success() {
192        let expected_string = "test-service-name";
193        let span = SpanBytes {
194            name: BytesString::from_slice(expected_string.as_ref()).unwrap(),
195            ..Default::default()
196        };
197        let mut encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
198        encoded_data.extend_from_slice(&[0, 0, 0, 0]); // some garbage, to be ignored
199        let (decoded_traces, _) =
200            from_bytes(libdd_tinybytes::Bytes::from(encoded_data)).expect("Decoding failed");
201
202        assert_eq!(1, decoded_traces.len());
203        assert_eq!(1, decoded_traces[0].len());
204        let decoded_span = &decoded_traces[0][0];
205        assert_eq!(expected_string, decoded_span.name.as_str());
206    }
207
208    #[test]
209    fn test_decoder_read_null_string_success() {
210        let mut span = create_test_json_span(1, 2, 0, 0, false);
211        span["name"] = json!(null);
212        let mut encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
213        encoded_data.extend_from_slice(&[0, 0, 0, 0]); // some garbage, to be ignored
214        let (decoded_traces, _) =
215            from_bytes(libdd_tinybytes::Bytes::from(encoded_data)).expect("Decoding failed");
216
217        assert_eq!(1, decoded_traces.len());
218        assert_eq!(1, decoded_traces[0].len());
219        let decoded_span = &decoded_traces[0][0];
220        assert_eq!("", decoded_span.name.as_str());
221    }
222
223    #[test]
224    fn test_decoder_read_number_success() {
225        let span = create_test_json_span(1, 2, 0, 0, false);
226        let mut encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
227        encoded_data.extend_from_slice(&[0, 0, 0, 0]); // some garbage, to be ignored
228        let (decoded_traces, _) =
229            from_bytes(libdd_tinybytes::Bytes::from(encoded_data)).expect("Decoding failed");
230
231        assert_eq!(1, decoded_traces.len());
232        assert_eq!(1, decoded_traces[0].len());
233        let decoded_span = &decoded_traces[0][0];
234        assert_eq!(1, decoded_span.trace_id);
235    }
236
237    #[test]
238    fn test_decoder_read_null_number_success() {
239        let mut span = create_test_json_span(1, 2, 0, 0, false);
240        span["trace_id"] = json!(null);
241        let mut encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
242        encoded_data.extend_from_slice(&[0, 0, 0, 0]); // some garbage, to be ignored
243        let (decoded_traces, _) =
244            from_bytes(libdd_tinybytes::Bytes::from(encoded_data)).expect("Decoding failed");
245
246        assert_eq!(1, decoded_traces.len());
247        assert_eq!(1, decoded_traces[0].len());
248        let decoded_span = &decoded_traces[0][0];
249        assert_eq!(0, decoded_span.trace_id);
250    }
251
252    #[test]
253    fn test_decoder_meta_struct_null_map_success() {
254        let mut span = create_test_json_span(1, 2, 0, 0, false);
255        span["meta_struct"] = json!(null);
256
257        let encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
258        let (decoded_traces, _) =
259            from_bytes(libdd_tinybytes::Bytes::from(encoded_data)).expect("Decoding failed");
260
261        assert_eq!(1, decoded_traces.len());
262        assert_eq!(1, decoded_traces[0].len());
263        let decoded_span = &decoded_traces[0][0];
264
265        assert!(decoded_span.meta_struct.is_empty());
266    }
267
268    #[test]
269    fn test_decoder_meta_struct_success() {
270        let data = vec![1, 2, 3, 4];
271        let mut span = create_test_no_alloc_span(1, 2, 0, 0, false);
272        span.meta_struct =
273            HashMap::from([(BytesString::from("meta_key"), Bytes::from(data.clone()))]);
274
275        let encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
276        let (decoded_traces, _) =
277            from_bytes(libdd_tinybytes::Bytes::from(encoded_data)).expect("Decoding failed");
278
279        assert_eq!(1, decoded_traces.len());
280        assert_eq!(1, decoded_traces[0].len());
281        let decoded_span = &decoded_traces[0][0];
282
283        assert_eq!(
284            decoded_span.meta_struct.get("meta_key").unwrap().to_vec(),
285            data
286        );
287    }
288
289    #[test]
290    fn test_decoder_meta_fixed_map_success() {
291        let expected_meta = HashMap::from([
292            ("key1".to_string(), "value1".to_string()),
293            ("key2".to_string(), "value2".to_string()),
294        ]);
295
296        let mut span = create_test_json_span(1, 2, 0, 0, false);
297        span["meta"] = json!(expected_meta.clone());
298
299        let encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
300        let (decoded_traces, _) =
301            from_bytes(libdd_tinybytes::Bytes::from(encoded_data)).expect("Decoding failed");
302
303        assert_eq!(1, decoded_traces.len());
304        assert_eq!(1, decoded_traces[0].len());
305        let decoded_span = &decoded_traces[0][0];
306
307        for (key, value) in expected_meta.iter() {
308            assert_eq!(
309                value,
310                &decoded_span.meta[&BytesString::from_slice(key.as_ref()).unwrap()].as_str()
311            );
312        }
313    }
314
315    #[test]
316    fn test_decoder_meta_null_map_success() {
317        let mut span = create_test_json_span(1, 2, 0, 0, false);
318        span["meta"] = json!(null);
319
320        let encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
321        let (decoded_traces, _) =
322            from_bytes(libdd_tinybytes::Bytes::from(encoded_data)).expect("Decoding failed");
323
324        assert_eq!(1, decoded_traces.len());
325        assert_eq!(1, decoded_traces[0].len());
326        let decoded_span = &decoded_traces[0][0];
327
328        assert!(decoded_span.meta.is_empty());
329    }
330
331    #[test]
332    fn test_decoder_meta_map_16_success() {
333        let expected_meta: HashMap<String, String> = (0..20)
334            .map(|i| {
335                (
336                    format!("key {i}").to_owned(),
337                    format!("value {i}").to_owned(),
338                )
339            })
340            .collect();
341
342        let mut span = create_test_json_span(1, 2, 0, 0, false);
343        span["meta"] = json!(expected_meta.clone());
344
345        let encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
346        let (decoded_traces, _) =
347            from_bytes(libdd_tinybytes::Bytes::from(encoded_data)).expect("Decoding failed");
348
349        assert_eq!(1, decoded_traces.len());
350        assert_eq!(1, decoded_traces[0].len());
351        let decoded_span = &decoded_traces[0][0];
352
353        for (key, value) in expected_meta.iter() {
354            assert_eq!(
355                value,
356                &decoded_span.meta[&BytesString::from_slice(key.as_ref()).unwrap()].as_str()
357            );
358        }
359    }
360
361    #[test]
362    fn test_decoder_metrics_fixed_map_success() {
363        let expected_metrics = HashMap::from([("metric1", 1.23), ("metric2", 4.56)]);
364
365        let mut span = create_test_json_span(1, 2, 0, 0, false);
366        span["metrics"] = json!(expected_metrics.clone());
367        let encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
368        let (decoded_traces, _) =
369            from_bytes(libdd_tinybytes::Bytes::from(encoded_data)).expect("Decoding failed");
370
371        assert_eq!(1, decoded_traces.len());
372        assert_eq!(1, decoded_traces[0].len());
373        let decoded_span = &decoded_traces[0][0];
374
375        for (key, value) in expected_metrics.iter() {
376            assert_eq!(
377                value,
378                &decoded_span.metrics[&BytesString::from_slice(key.as_ref()).unwrap()]
379            );
380        }
381    }
382
383    #[test]
384    fn test_decoder_metrics_map16_success() {
385        let expected_metrics: HashMap<String, f64> =
386            (0..20).map(|i| (format!("metric{i}"), i as f64)).collect();
387
388        let mut span = create_test_json_span(1, 2, 0, 0, false);
389        span["metrics"] = json!(expected_metrics.clone());
390        let encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
391        let (decoded_traces, _) =
392            from_bytes(libdd_tinybytes::Bytes::from(encoded_data)).expect("Decoding failed");
393
394        assert_eq!(1, decoded_traces.len());
395        assert_eq!(1, decoded_traces[0].len());
396        let decoded_span = &decoded_traces[0][0];
397
398        for (key, value) in expected_metrics.iter() {
399            assert_eq!(
400                value,
401                &decoded_span.metrics[&BytesString::from_slice(key.as_ref()).unwrap()]
402            );
403        }
404    }
405
406    #[test]
407    fn test_decoder_metrics_null_success() {
408        let mut span = create_test_json_span(1, 2, 0, 0, false);
409        span["metrics"] = json!(null);
410        let encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
411        let (decoded_traces, _) =
412            from_bytes(libdd_tinybytes::Bytes::from(encoded_data)).expect("Decoding failed");
413
414        assert_eq!(1, decoded_traces.len());
415        assert_eq!(1, decoded_traces[0].len());
416        let decoded_span = &decoded_traces[0][0];
417        assert!(decoded_span.metrics.is_empty());
418    }
419
420    #[test]
421    fn test_decoder_span_link_success() {
422        let expected_span_link = json!({
423            "trace_id": 1,
424            "trace_id_high": 0,
425            "span_id": 1,
426            "attributes": {
427                "attr1": "test_value",
428                "attr2": "test_value2"
429            },
430            "tracestate": "state_test",
431            "flags": 0b101
432        });
433
434        let mut span = create_test_json_span(1, 2, 0, 0, false);
435        span["span_links"] = json!([expected_span_link]);
436
437        let encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
438        let (decoded_traces, _) =
439            from_bytes(libdd_tinybytes::Bytes::from(encoded_data)).expect("Decoding failed");
440
441        assert_eq!(1, decoded_traces.len());
442        assert_eq!(1, decoded_traces[0].len());
443        let decoded_span = &decoded_traces[0][0];
444
445        assert_eq!(
446            expected_span_link["trace_id"],
447            decoded_span.span_links[0].trace_id
448        );
449        assert_eq!(
450            expected_span_link["trace_id_high"],
451            decoded_span.span_links[0].trace_id_high
452        );
453        assert_eq!(
454            expected_span_link["span_id"],
455            decoded_span.span_links[0].span_id
456        );
457        assert_eq!(
458            expected_span_link["tracestate"],
459            decoded_span.span_links[0].tracestate.as_str()
460        );
461        assert_eq!(
462            expected_span_link["flags"],
463            decoded_span.span_links[0].flags
464        );
465        assert_eq!(
466            expected_span_link["attributes"]["attr1"],
467            decoded_span.span_links[0].attributes
468                [&BytesString::from_slice("attr1".as_ref()).unwrap()]
469                .as_str()
470        );
471        assert_eq!(
472            expected_span_link["attributes"]["attr2"],
473            decoded_span.span_links[0].attributes
474                [&BytesString::from_slice("attr2".as_ref()).unwrap()]
475                .as_str()
476        );
477    }
478
479    #[test]
480    fn test_decoder_null_span_link_success() {
481        let mut span = create_test_json_span(1, 2, 0, 0, false);
482        span["span_links"] = json!(null);
483
484        let encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
485        let (decoded_traces, _) =
486            from_bytes(libdd_tinybytes::Bytes::from(encoded_data)).expect("Decoding failed");
487
488        assert_eq!(1, decoded_traces.len());
489        assert_eq!(1, decoded_traces[0].len());
490        let decoded_span = &decoded_traces[0][0];
491
492        assert!(decoded_span.span_links.is_empty());
493    }
494
495    #[test]
496    fn test_decoder_meta_with_null_values() {
497        let mut span = create_test_json_span(1, 2, 0, 0, false);
498        span["meta"] = json!({
499            "key1": "value1",
500            "key2": null,  // This null value should be skipped
501            "key3": "value3"
502        });
503
504        let encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
505        let (decoded_traces, _) =
506            from_bytes(libdd_tinybytes::Bytes::from(encoded_data)).expect("Decoding failed");
507
508        assert_eq!(1, decoded_traces.len());
509        assert_eq!(1, decoded_traces[0].len());
510        let decoded_span = &decoded_traces[0][0];
511
512        assert_eq!(
513            "value1",
514            decoded_span.meta[&BytesString::from_slice("key1".as_ref()).unwrap()].as_str()
515        );
516        assert!(
517            !decoded_span
518                .meta
519                .contains_key(&BytesString::from_slice("key2".as_ref()).unwrap()),
520            "Null value should be skipped, but key was present"
521        );
522        assert_eq!(
523            "value3",
524            decoded_span.meta[&BytesString::from_slice("key3".as_ref()).unwrap()].as_str()
525        );
526    }
527
528    #[test]
529    fn test_decoder_read_string_wrong_format() {
530        let span = SpanBytes {
531            service: BytesString::from_slice("my_service".as_ref()).unwrap(),
532            ..Default::default()
533        };
534        let mut encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
535        // This changes the map size from 11 to 12 to trigger an InvalidMarkerRead error.
536        encoded_data[2] = 0x8c;
537        let slice = encoded_data.as_ref();
538
539        let result = from_slice(slice);
540        assert_eq!(
541            Err(DecodeError::InvalidFormat(
542                "Expected at least bytes 1, but only got 0 (pos 0)".to_owned()
543            )),
544            result
545        );
546    }
547
548    #[test]
549    fn test_decoder_read_string_utf8_error() {
550        let invalid_seq = vec![0, 159, 146, 150];
551        let invalid_str = unsafe { String::from_utf8_unchecked(invalid_seq) };
552        let invalid_str_as_bytes = libdd_tinybytes::Bytes::from(invalid_str);
553        let span = SpanBytes {
554            name: unsafe { BytesString::from_bytes_unchecked(invalid_str_as_bytes) },
555            ..Default::default()
556        };
557        let encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
558        let slice = encoded_data.as_ref();
559
560        let result = from_slice(slice);
561        assert_eq!(
562            Err(DecodeError::Utf8Error(
563                "invalid utf-8 sequence of 1 bytes from index 1".to_owned()
564            )),
565            result
566        );
567    }
568
569    #[test]
570    fn test_decoder_invalid_marker_for_trace_count_read() {
571        let span = SpanBytes::default();
572        let mut encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
573        // This changes the entire payload to a map with 12 keys in order to trigger an error when
574        // reading the array len of traces
575        encoded_data[0] = 0x8c;
576        let slice = encoded_data.as_ref();
577
578        let result = from_slice(slice);
579        assert_eq!(
580            Err(DecodeError::InvalidFormat(
581                "Unable to read array len for trace count".to_string()
582            )),
583            result
584        );
585    }
586
587    #[test]
588    fn test_decoder_invalid_marker_for_span_count_read() {
589        let span = SpanBytes::default();
590        let mut encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
591        // This changes the entire payload to a map with 12 keys in order to trigger an error when
592        // reading the array len of spans
593        encoded_data[1] = 0x8c;
594        let slice = encoded_data.as_ref();
595
596        let result = from_slice(slice);
597        assert_eq!(
598            Err(DecodeError::InvalidFormat(
599                "Unable to read array len for span count".to_owned()
600            )),
601            result
602        );
603    }
604
605    #[test]
606    fn test_decoder_read_string_type_mismatch() {
607        let span = SpanBytes::default();
608        let mut encoded_data = rmp_serde::to_vec_named(&vec![vec![span]]).unwrap();
609        // Modify the encoded data to cause a type mismatch by changing the marker for the `name`
610        // field to an integer marker
611        encoded_data[3] = 0x01;
612        let slice = encoded_data.as_ref();
613
614        let result = from_slice(slice);
615        assert_eq!(
616            Err(DecodeError::InvalidType(
617                "Type mismatch at marker FixPos(1)".to_owned()
618            )),
619            result
620        );
621    }
622
623    #[test]
624    #[cfg_attr(miri, ignore)]
625    fn fuzz_from_bytes() {
626        check!()
627            .with_type::<(
628                String,
629                String,
630                String,
631                String,
632                String,
633                String,
634                String,
635                String,
636                u64,
637                u64,
638                u64,
639                i64,
640            )>()
641            .cloned()
642            .for_each(
643                |(
644                    name,
645                    service,
646                    resource,
647                    span_type,
648                    meta_key,
649                    meta_value,
650                    metric_key,
651                    metric_value,
652                    trace_id,
653                    span_id,
654                    parent_id,
655                    start,
656                )| {
657                    let span = SpanBytes {
658                        name: BytesString::from_slice(name.as_ref()).unwrap(),
659                        service: BytesString::from_slice(service.as_ref()).unwrap(),
660                        resource: BytesString::from_slice(resource.as_ref()).unwrap(),
661                        r#type: BytesString::from_slice(span_type.as_ref()).unwrap(),
662                        meta: HashMap::from([(
663                            BytesString::from_slice(meta_key.as_ref()).unwrap(),
664                            BytesString::from_slice(meta_value.as_ref()).unwrap(),
665                        )]),
666                        metrics: HashMap::from([(
667                            BytesString::from_slice(metric_key.as_ref()).unwrap(),
668                            metric_value.parse::<f64>().unwrap_or_default(),
669                        )]),
670                        trace_id: trace_id as u128,
671                        span_id,
672                        parent_id,
673                        start,
674                        ..Default::default()
675                    };
676                    let encoded_data = to_vec_named(&vec![vec![span]]).unwrap();
677                    let result = from_bytes(libdd_tinybytes::Bytes::from(encoded_data));
678
679                    assert!(result.is_ok());
680                },
681            );
682    }
683}