1// Copyright 2014 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package tracecontext
16
17import (
18	"testing"
19
20	"cloud.google.com/go/internal/testutil"
21)
22
23var validData = []byte{0, 0, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 1, 97, 98, 99, 100, 101, 102, 103, 104, 2, 1}
24
25func TestDecode(t *testing.T) {
26	tests := []struct {
27		name        string
28		data        []byte
29		wantTraceID []byte
30		wantSpanID  uint64
31		wantOpts    byte
32		wantOk      bool
33	}{
34		{
35			name:        "nil data",
36			data:        nil,
37			wantTraceID: nil,
38			wantSpanID:  0,
39			wantOpts:    0,
40			wantOk:      false,
41		},
42		{
43			name:        "short data",
44			data:        []byte{0, 0, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77},
45			wantTraceID: nil,
46			wantSpanID:  0,
47			wantOpts:    0,
48			wantOk:      false,
49		},
50		{
51			name:        "wrong field number",
52			data:        []byte{0, 1, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77},
53			wantTraceID: nil,
54			wantSpanID:  0,
55			wantOpts:    0,
56			wantOk:      false,
57		},
58		{
59			name:        "valid data",
60			data:        validData,
61			wantTraceID: []byte{64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79},
62			wantSpanID:  0x6867666564636261,
63			wantOpts:    1,
64			wantOk:      true,
65		},
66	}
67	for _, test := range tests {
68		t.Run(test.name, func(t *testing.T) {
69			gotTraceID, gotSpanID, gotOpts, gotOk := Decode(test.data)
70			if !testutil.Equal(gotTraceID, test.wantTraceID) {
71				t.Errorf("%s: Decode() gotTraceID = %v, want %v", test.name, gotTraceID, test.wantTraceID)
72			}
73			if gotSpanID != test.wantSpanID {
74				t.Errorf("%s: Decode() gotSpanID = %v, want %v", test.name, gotSpanID, test.wantSpanID)
75			}
76			if gotOpts != test.wantOpts {
77				t.Errorf("%s: Decode() gotOpts = %v, want %v", test.name, gotOpts, test.wantOpts)
78			}
79			if gotOk != test.wantOk {
80				t.Errorf("%s: Decode() gotOk = %v, want %v", test.name, gotOk, test.wantOk)
81			}
82		})
83	}
84}
85
86func TestEncode(t *testing.T) {
87	tests := []struct {
88		name     string
89		dst      []byte
90		traceID  []byte
91		spanID   uint64
92		opts     byte
93		wantN    int
94		wantData []byte
95	}{
96		{
97			name:     "short data",
98			dst:      make([]byte, 0),
99			traceID:  []byte("00112233445566"),
100			spanID:   0x6867666564636261,
101			opts:     1,
102			wantN:    -1,
103			wantData: make([]byte, 0),
104		},
105		{
106			name:     "valid data",
107			dst:      make([]byte, Len),
108			traceID:  []byte{64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79},
109			spanID:   0x6867666564636261,
110			opts:     1,
111			wantN:    Len,
112			wantData: validData,
113		},
114	}
115	for _, test := range tests {
116		t.Run(test.name, func(t *testing.T) {
117			gotN := Encode(test.dst, test.traceID, test.spanID, test.opts)
118			if gotN != test.wantN {
119				t.Errorf("%s: n = %v, want %v", test.name, gotN, test.wantN)
120			}
121			if gotData := test.dst; !testutil.Equal(gotData, test.wantData) {
122				t.Errorf("%s: dst = %v, want %v", test.name, gotData, test.wantData)
123			}
124		})
125	}
126}
127
128func BenchmarkDecode(b *testing.B) {
129	for i := 0; i < b.N; i++ {
130		Decode(validData)
131	}
132}
133
134func BenchmarkEncode(b *testing.B) {
135	for i := 0; i < b.N; i++ {
136		traceID := make([]byte, 16)
137		var opts byte
138		Encode(validData, traceID, 0, opts)
139	}
140}
141