diff --git a/tracing/identity.go b/tracing/identity.go index e6bbb4cb..a34f8d0a 100644 --- a/tracing/identity.go +++ b/tracing/identity.go @@ -24,7 +24,7 @@ type Identity struct { // TODO: TUN-6604 Remove this. To reconstruct into Jaeger propagation format, convert tracingContext to tracing.Identity func (tc *Identity) String() string { - return fmt.Sprintf("%x%x:%x:0:%x", tc.traceIDUpper, tc.traceIDLower, tc.spanID, tc.flags) + return fmt.Sprintf("%016x%016x:%x:0:%x", tc.traceIDUpper, tc.traceIDLower, tc.spanID, tc.flags) } func (tc *Identity) MarshalBinary() ([]byte, error) { @@ -68,14 +68,9 @@ func NewIdentity(trace string) (*Identity, error) { return nil, fmt.Errorf("trace '%s' doesn't have exactly 4 parts separated by %s", trace, separator) } const base = 16 - tracingID := parts[0] - if len(tracingID) == 0 { - return nil, fmt.Errorf("missing tracing ID") - } - if len(tracingID) != 32 { - // Correctly left pad the trace to a length of 32 - left := traceID128bitsWidth - len(tracingID) - tracingID = strings.Repeat("0", left) + tracingID + tracingID, err := padTracingID(parts[0]) + if err != nil { + return nil, err } traceIDUpper, err := strconv.ParseUint(tracingID[:16], base, 64) if err != nil { @@ -100,3 +95,16 @@ func NewIdentity(trace string) (*Identity, error) { flags: uint8(flags), }, nil } + +func padTracingID(tracingID string) (string, error) { + if len(tracingID) == 0 { + return "", fmt.Errorf("missing tracing ID") + } + if len(tracingID) == traceID128bitsWidth { + return tracingID, nil + } + // Correctly left pad the trace to a length of 32 + left := traceID128bitsWidth - len(tracingID) + paddedTracingID := strings.Repeat("0", left) + tracingID + return paddedTracingID, nil +} diff --git a/tracing/identity_test.go b/tracing/identity_test.go index 3bdb7448..4c3c2623 100644 --- a/tracing/identity_test.go +++ b/tracing/identity_test.go @@ -10,40 +10,55 @@ func TestNewIdentity(t *testing.T) { testCases := []struct { testCase string trace string - valid bool + expected string }{ { testCase: "full length trace", trace: "ec31ad8a01fde11fdcabe2efdce36873:52726f6cabc144f5:0:1", - valid: true, + expected: "ec31ad8a01fde11fdcabe2efdce36873:52726f6cabc144f5:0:1", }, { testCase: "short trace ID", trace: "ad8a01fde11fdcabe2efdce36873:52726f6cabc144f5:0:1", - valid: true, + expected: "0000ad8a01fde11fdcabe2efdce36873:52726f6cabc144f5:0:1", + }, + { + testCase: "short trace ID with 0s in the middle", + trace: "ad8a01fde11f000002efdce36873:52726f6cabc144f5:0:1", + expected: "0000ad8a01fde11f000002efdce36873:52726f6cabc144f5:0:1", + }, + { + testCase: "short trace ID with 0s in the beginning and middle", + trace: "001ad8a01fde11fdcabe2efdce36873:52726f6cabc144f5:0:1", + expected: "0001ad8a01fde11fdcabe2efdce36873:52726f6cabc144f5:0:1", }, { testCase: "no trace", trace: "", - valid: false, }, { testCase: "missing flags", trace: "ec31ad8a01fde11fdcabe2efdce36873:52726f6cabc144f5:0", - valid: false, }, { testCase: "missing separator", trace: "ec31ad8a01fde11fdcabe2efdce3687352726f6cabc144f501", - valid: false, }, } for _, testCase := range testCases { identity, err := NewIdentity(testCase.trace) - if testCase.valid { - require.NoError(t, err, testCase.testCase) - require.Equal(t, testCase.trace, identity.String()) + if testCase.expected != "" { + require.NoError(t, err) + require.Equal(t, testCase.expected, identity.String()) + + serializedIdentity, err := identity.MarshalBinary() + require.NoError(t, err) + deserializedIdentity := new(Identity) + err = deserializedIdentity.UnmarshalBinary(serializedIdentity) + require.NoError(t, err) + require.Equal(t, identity, deserializedIdentity) + } else { require.Error(t, err) require.Nil(t, identity)