diff --git a/trace/tracestate_test.go b/trace/tracestate_test.go index edb89073de8..a1ef14f6f7b 100644 --- a/trace/tracestate_test.go +++ b/trace/tracestate_test.go @@ -26,74 +26,91 @@ import ( // Taken from the W3C tests: // https://github.com/w3c/trace-context/blob/dcd3ad9b7d6ac36f70ff3739874b73c11b0302a1/test/test_data.json var testcases = []struct { + name string in string tracestate TraceState out string err error }{ { - in: "foo=1,foo=1", - err: errDuplicate, + name: "duplicate with the same value", + in: "foo=1,foo=1", + err: errDuplicate, }, { - in: "foo=1,foo=2", - err: errDuplicate, + name: "duplicate with different values", + in: "foo=1,foo=2", + err: errDuplicate, }, { - in: "foo =1", - err: errInvalidMember, + name: "improperly formatted key/value pair", + in: "foo =1", + err: errInvalidMember, }, { - in: "FOO=1", - err: errInvalidMember, + name: "upper case key", + in: "FOO=1", + err: errInvalidMember, }, { - in: "foo.bar=1", - err: errInvalidMember, + name: "key with invalid character", + in: "foo.bar=1", + err: errInvalidMember, }, { - in: "foo@=1,bar=2", - err: errInvalidMember, + name: "multiple keys, one with empty tenant key", + in: "foo@=1,bar=2", + err: errInvalidMember, }, { - in: "@foo=1,bar=2", - err: errInvalidMember, + name: "multiple keys, one with only tenant", + in: "@foo=1,bar=2", + err: errInvalidMember, }, { - in: "foo@@bar=1,bar=2", - err: errInvalidMember, + name: "multiple keys, one with double tenant separator", + in: "foo@@bar=1,bar=2", + err: errInvalidMember, }, { - in: "foo@bar@baz=1,bar=2", - err: errInvalidMember, + name: "multiple keys, one with multiple tenants", + in: "foo@bar@baz=1,bar=2", + err: errInvalidMember, }, { - in: "foo=1,zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz=1", - err: errInvalidMember, + name: "key too long", + in: "foo=1,zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz=1", + err: errInvalidMember, }, { - in: "foo=1,tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt@v=1", - err: errInvalidMember, + name: "key too long, with tenant", + in: "foo=1,tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt@v=1", + err: errInvalidMember, }, { - in: "foo=1,t@vvvvvvvvvvvvvvv=1", - err: errInvalidMember, + name: "tenant too long", + in: "foo=1,t@vvvvvvvvvvvvvvv=1", + err: errInvalidMember, }, { - in: "foo=bar=baz", - err: errInvalidMember, + name: "multiple values for a single key", + in: "foo=bar=baz", + err: errInvalidMember, }, { - in: "foo=,bar=3", - err: errInvalidMember, + name: "no value", + in: "foo=,bar=3", + err: errInvalidMember, }, { - in: "bar01=01,bar02=02,bar03=03,bar04=04,bar05=05,bar06=06,bar07=07,bar08=08,bar09=09,bar10=10,bar11=11,bar12=12,bar13=13,bar14=14,bar15=15,bar16=16,bar17=17,bar18=18,bar19=19,bar20=20,bar21=21,bar22=22,bar23=23,bar24=24,bar25=25,bar26=26,bar27=27,bar28=28,bar29=29,bar30=30,bar31=31,bar32=32,bar33=33", - err: errMemberNumber, + name: "too many members", + in: "bar01=01,bar02=02,bar03=03,bar04=04,bar05=05,bar06=06,bar07=07,bar08=08,bar09=09,bar10=10,bar11=11,bar12=12,bar13=13,bar14=14,bar15=15,bar16=16,bar17=17,bar18=18,bar19=19,bar20=20,bar21=21,bar22=22,bar23=23,bar24=24,bar25=25,bar26=26,bar27=27,bar28=28,bar29=29,bar30=30,bar31=31,bar32=32,bar33=33", + err: errMemberNumber, }, { - in: "abcdefghijklmnopqrstuvwxyz0123456789_-*/= !\"#$%&'()*+-./0123456789:;<>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", - out: "abcdefghijklmnopqrstuvwxyz0123456789_-*/= !\"#$%&'()*+-./0123456789:;<>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", + name: "valid key/value list", + in: "abcdefghijklmnopqrstuvwxyz0123456789_-*/= !\"#$%&'()*+-./0123456789:;<>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", + out: "abcdefghijklmnopqrstuvwxyz0123456789_-*/= !\"#$%&'()*+-./0123456789:;<>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", tracestate: TraceState{list: []member{ { Key: "abcdefghijklmnopqrstuvwxyz0123456789_-*/", @@ -102,8 +119,9 @@ var testcases = []struct { }}, }, { - in: "abcdefghijklmnopqrstuvwxyz0123456789_-*/@a-z0-9_-*/= !\"#$%&'()*+-./0123456789:;<>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", - out: "abcdefghijklmnopqrstuvwxyz0123456789_-*/@a-z0-9_-*/= !\"#$%&'()*+-./0123456789:;<>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", + name: "valid key/value list with tenant", + in: "abcdefghijklmnopqrstuvwxyz0123456789_-*/@a-z0-9_-*/= !\"#$%&'()*+-./0123456789:;<>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", + out: "abcdefghijklmnopqrstuvwxyz0123456789_-*/@a-z0-9_-*/= !\"#$%&'()*+-./0123456789:;<>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", tracestate: TraceState{list: []member{ { Key: "abcdefghijklmnopqrstuvwxyz0123456789_-*/@a-z0-9_-*/", @@ -112,35 +130,40 @@ var testcases = []struct { }}, }, { + name: "empty input", // Empty input should result in no error and a zero value // TraceState being returned, that TraceState should be encoded as an // empty string. }, { - in: "foo=1", - out: "foo=1", + name: "single key and value", + in: "foo=1", + out: "foo=1", tracestate: TraceState{list: []member{ {Key: "foo", Value: "1"}, }}, }, { - in: "foo=1,", - out: "foo=1", + name: "single key and value with empty separator", + in: "foo=1,", + out: "foo=1", tracestate: TraceState{list: []member{ {Key: "foo", Value: "1"}, }}, }, { - in: "foo=1,bar=2", - out: "foo=1,bar=2", + name: "multiple keys and values", + in: "foo=1,bar=2", + out: "foo=1,bar=2", tracestate: TraceState{list: []member{ {Key: "foo", Value: "1"}, {Key: "bar", Value: "2"}, }}, }, { - in: "foo=1,zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz=1", - out: "foo=1,zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz=1", + name: "with a key at maximum length", + in: "foo=1,zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz=1", + out: "foo=1,zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz=1", tracestate: TraceState{list: []member{ { Key: "foo", @@ -153,8 +176,9 @@ var testcases = []struct { }}, }, { - in: "foo=1,ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt@vvvvvvvvvvvvvv=1", - out: "foo=1,ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt@vvvvvvvvvvvvvv=1", + name: "with a key and tenant at maximum length", + in: "foo=1,ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt@vvvvvvvvvvvvvv=1", + out: "foo=1,ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt@vvvvvvvvvvvvvv=1", tracestate: TraceState{list: []member{ { Key: "foo", @@ -167,8 +191,9 @@ var testcases = []struct { }}, }, { - in: "bar01=01,bar02=02,bar03=03,bar04=04,bar05=05,bar06=06,bar07=07,bar08=08,bar09=09,bar10=10,bar11=11,bar12=12,bar13=13,bar14=14,bar15=15,bar16=16,bar17=17,bar18=18,bar19=19,bar20=20,bar21=21,bar22=22,bar23=23,bar24=24,bar25=25,bar26=26,bar27=27,bar28=28,bar29=29,bar30=30,bar31=31,bar32=32", - out: "bar01=01,bar02=02,bar03=03,bar04=04,bar05=05,bar06=06,bar07=07,bar08=08,bar09=09,bar10=10,bar11=11,bar12=12,bar13=13,bar14=14,bar15=15,bar16=16,bar17=17,bar18=18,bar19=19,bar20=20,bar21=21,bar22=22,bar23=23,bar24=24,bar25=25,bar26=26,bar27=27,bar28=28,bar29=29,bar30=30,bar31=31,bar32=32", + name: "with maximum members", + in: "bar01=01,bar02=02,bar03=03,bar04=04,bar05=05,bar06=06,bar07=07,bar08=08,bar09=09,bar10=10,bar11=11,bar12=12,bar13=13,bar14=14,bar15=15,bar16=16,bar17=17,bar18=18,bar19=19,bar20=20,bar21=21,bar22=22,bar23=23,bar24=24,bar25=25,bar26=26,bar27=27,bar28=28,bar29=29,bar30=30,bar31=31,bar32=32", + out: "bar01=01,bar02=02,bar03=03,bar04=04,bar05=05,bar06=06,bar07=07,bar08=08,bar09=09,bar10=10,bar11=11,bar12=12,bar13=13,bar14=14,bar15=15,bar16=16,bar17=17,bar18=18,bar19=19,bar20=20,bar21=21,bar22=22,bar23=23,bar24=24,bar25=25,bar26=26,bar27=27,bar28=28,bar29=29,bar30=30,bar31=31,bar32=32", tracestate: TraceState{list: []member{ {Key: "bar01", Value: "01"}, {Key: "bar02", Value: "02"}, @@ -205,8 +230,9 @@ var testcases = []struct { }}, }, { - in: "foo=1,bar=2,rojo=1,congo=2,baz=3", - out: "foo=1,bar=2,rojo=1,congo=2,baz=3", + name: "with several members", + in: "foo=1,bar=2,rojo=1,congo=2,baz=3", + out: "foo=1,bar=2,rojo=1,congo=2,baz=3", tracestate: TraceState{list: []member{ {Key: "foo", Value: "1"}, {Key: "bar", Value: "2"}, @@ -216,8 +242,9 @@ var testcases = []struct { }}, }, { - in: "foo=1 \t , \t bar=2, \t baz=3", - out: "foo=1,bar=2,baz=3", + name: "with tabs between members", + in: "foo=1 \t , \t bar=2, \t baz=3", + out: "foo=1,bar=2,baz=3", tracestate: TraceState{list: []member{ {Key: "foo", Value: "1"}, {Key: "bar", Value: "2"}, @@ -225,8 +252,9 @@ var testcases = []struct { }}, }, { - in: "foo=1\t \t,\t \tbar=2,\t \tbaz=3", - out: "foo=1,bar=2,baz=3", + name: "with multiple tabs between members", + in: "foo=1\t \t,\t \tbar=2,\t \tbaz=3", + out: "foo=1,bar=2,baz=3", tracestate: TraceState{list: []member{ {Key: "foo", Value: "1"}, {Key: "bar", Value: "2"}, @@ -234,22 +262,25 @@ var testcases = []struct { }}, }, { - in: "foo=1 ", - out: "foo=1", + name: "with space at the end of the member", + in: "foo=1 ", + out: "foo=1", tracestate: TraceState{list: []member{ {Key: "foo", Value: "1"}, }}, }, { - in: "foo=1\t", - out: "foo=1", + name: "with tab at the end of the member", + in: "foo=1\t", + out: "foo=1", tracestate: TraceState{list: []member{ {Key: "foo", Value: "1"}, }}, }, { - in: "foo=1 \t", - out: "foo=1", + name: "with tab and space at the end of the member", + in: "foo=1 \t", + out: "foo=1", tracestate: TraceState{list: []member{ {Key: "foo", Value: "1"}, }}, @@ -269,13 +300,15 @@ var maxMembers = func() TraceState { func TestParseTraceState(t *testing.T) { for _, tc := range testcases { - got, err := ParseTraceState(tc.in) - assert.Equal(t, tc.tracestate, got) - if tc.err != nil { - assert.ErrorIs(t, err, tc.err, tc.in) - } else { - assert.NoError(t, err, tc.in) - } + t.Run(tc.name, func(t *testing.T) { + got, err := ParseTraceState(tc.in) + assert.Equal(t, tc.tracestate, got) + if tc.err != nil { + assert.ErrorIs(t, err, tc.err, tc.in) + } else { + assert.NoError(t, err, tc.in) + } + }) } } @@ -285,8 +318,9 @@ func TestTraceStateString(t *testing.T) { // Only test non-zero value TraceState. continue } - - assert.Equal(t, tc.out, tc.tracestate.String()) + t.Run(tc.name, func(t *testing.T) { + assert.Equal(t, tc.out, tc.tracestate.String()) + }) } } @@ -296,15 +330,16 @@ func TestTraceStateMarshalJSON(t *testing.T) { // Only test non-zero value TraceState. continue } + t.Run(tc.name, func(t *testing.T) { + // Encode UTF-8. + expected, err := json.Marshal(tc.out) + require.NoError(t, err) - // Encode UTF-8. - expected, err := json.Marshal(tc.out) - require.NoError(t, err) + actual, err := json.Marshal(tc.tracestate) + require.NoError(t, err) - actual, err := json.Marshal(tc.tracestate) - require.NoError(t, err) - - assert.Equal(t, expected, actual) + assert.Equal(t, expected, actual) + }) } } @@ -332,7 +367,9 @@ func TestTraceStateGet(t *testing.T) { } for _, tc := range testCases { - assert.Equal(t, tc.expected, maxMembers.Get(tc.key), tc.name) + t.Run(tc.name, func(t *testing.T) { + assert.Equal(t, tc.expected, maxMembers.Get(tc.key)) + }) } } @@ -377,7 +414,9 @@ func TestTraceStateDelete(t *testing.T) { } for _, tc := range testCases { - assert.Equal(t, tc.expected, ts.Delete(tc.key), tc.name) + t.Run(tc.name, func(t *testing.T) { + assert.Equal(t, tc.expected, ts.Delete(tc.key)) + }) } } @@ -453,13 +492,15 @@ func TestTraceStateInsert(t *testing.T) { } for _, tc := range testCases { - actual, err := tc.tracestate.Insert(tc.key, tc.value) - assert.ErrorIs(t, err, tc.err, tc.name) - if tc.err != nil { - assert.Equal(t, tc.tracestate, actual, tc.name) - } else { - assert.Equal(t, tc.expected, actual, tc.name) - } + t.Run(tc.name, func(t *testing.T) { + actual, err := tc.tracestate.Insert(tc.key, tc.value) + assert.ErrorIs(t, err, tc.err, tc.name) + if tc.err != nil { + assert.Equal(t, tc.tracestate, actual) + } else { + assert.Equal(t, tc.expected, actual) + } + }) } }