Skip to content

Commit

Permalink
Add unit tests for bug open-telemetry#5996
Browse files Browse the repository at this point in the history
  • Loading branch information
MrAlias committed Nov 22, 2024
1 parent 2edaccb commit f091f18
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 24 deletions.
2 changes: 1 addition & 1 deletion sdk/trace/span_limits_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ func TestSpanLimits(t *testing.T) {
// Ensure string and string slice attributes are truncated.
assert.Contains(t, attrs, attribute.String("string", "ab"))
assert.Contains(t, attrs, attribute.StringSlice("stringSlice", []string{"ab", "de"}))
assert.Contains(t, attrs, attribute.String("euro", ""))
assert.Contains(t, attrs, attribute.String("euro", ""))

limits.AttributeValueLengthLimit = 0
attrs = testSpanLimits(t, limits).Attributes()
Expand Down
144 changes: 121 additions & 23 deletions sdk/trace/span_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,37 +201,135 @@ func TestTruncateAttr(t *testing.T) {
attr: strSliceAttr,
want: strSliceAttr,
},
}

for _, test := range tests {
name := fmt.Sprintf("%s->%s(limit:%d)", test.attr.Key, test.attr.Value.Emit(), test.limit)
t.Run(name, func(t *testing.T) {
assert.Equal(t, test.want, truncateAttr(test.limit, test.attr))
})
}
}

func TestTruncate(t *testing.T) {
type group struct {
limit int
input string
expected string
}

tests := []struct {
name string
groups []group
}{
// Edge case: limit is negative, no truncation should occur
{
// This tests the ordinary safeTruncate().
limit: 10,
attr: attribute.String(key, "€€€€"), // 3 bytes each
want: attribute.String(key, "€€€"),
name: "NoTruncation",
groups: []group{
{-1, "No truncation!", "No truncation!"},
},
},

// Edge case: string is already shorter than the limit, no truncation
// should occur
{
// This tests truncation with an invalid UTF-8 input.
//
// Note that after removing the invalid rune,
// the string is over length and still has to
// be truncated on a code point boundary.
limit: 10,
attr: attribute.String(key, "€"[0:2]+"hello€€"), // corrupted first rune, then over limit
want: attribute.String(key, "hello€"),
name: "ShortText",
groups: []group{
{10, "Short text", "Short text"},
{15, "Short text", "Short text"},
{100, "Short text", "Short text"},
},
},

// Edge case: truncation happens with ASCII characters only
{
// This tests the fallback to invalidTruncate()
// where after validation the string does not require
// truncation.
limit: 6,
attr: attribute.String(key, "€"[0:2]+"hello"), // corrupted first rune, then not over limit
want: attribute.String(key, "hello"),
name: "ASCIIOnly",
groups: []group{
{1, "Hello World!", "H"},
{5, "Hello World!", "Hello"},
{12, "Hello World!", "Hello World!"},
},
},

// Truncation including multi-byte characters (UTF-8)
{
name: "ValidUTF-8",
groups: []group{
{7, "Hello, 世界", "Hello, "},
{8, "Hello, 世界", "Hello, 世"},
{2, "こんにちは", "こん"},
{3, "こんにちは", "こんに"},
{5, "こんにちは", "こんにちは"},
{12, "こんにちは", "こんにちは"},
},
},

// Truncation with invalid UTF-8 characters
{
name: "InvalidUTF-8",
groups: []group{
{11, "Invalid\x80text", "Invalidtext"},
// Do not modify invalid text if equal to limit.
{11, "Valid text\x80", "Valid text\x80"},
// Do not modify invalid text if under limit.
{15, "Valid text\x80", "Valid text\x80"},
{5, "Hello\x80World", "Hello"},
{11, "Hello\x80World\x80!", "HelloWorld!"},
{15, "Hello\x80World\x80Test", "HelloWorldTest"},
{15, "Hello\x80\x80\x80World\x80Test", "HelloWorldTest"},
{15, "\x80\x80\x80Hello\x80\x80\x80World\x80Test\x80\x80", "HelloWorldTest"},
},
},

// Truncation with mixed validn and invalid UTF-8 characters
{
name: "MixedUTF-8",
groups: []group{
{6, "€"[0:2] + "hello€€", "hello€"},
{6, "€" + "€"[0:2] + "hello", "€hello"},
{11, "Valid text\x80📜", "Valid text📜"},
{11, "Valid text📜\x80", "Valid text📜"},
{14, "😊 Hello\x80World🌍🚀", "😊 HelloWorld🌍🚀"},
{14, "😊\x80 Hello\x80World🌍🚀", "😊 HelloWorld🌍🚀"},
{14, "😊\x80 Hello\x80World🌍\x80🚀", "😊 HelloWorld🌍🚀"},
{14, "😊\x80 Hello\x80World🌍\x80🚀\x80", "😊 HelloWorld🌍🚀"},
{14, "\x80😊\x80 Hello\x80World🌍\x80🚀\x80", "😊 HelloWorld🌍🚀"},
},
},

// Edge case: empty string, should return empty string
{
name: "Empty",
groups: []group{
{5, "", ""},
},
},

// Edge case: limit is 0, should return an empty string
{
name: "Zero",
groups: []group{
{0, "Some text", ""},
{0, "", ""},
},
},
}

for _, test := range tests {
name := fmt.Sprintf("%s->%s(limit:%d)", test.attr.Key, test.attr.Value.Emit(), test.limit)
t.Run(name, func(t *testing.T) {
assert.Equal(t, test.want, truncateAttr(test.limit, test.attr))
})
for _, tt := range tests {
for _, g := range tt.groups {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()

got := safeTruncate(g.input, g.limit)
assert.Equalf(
t, g.expected, got,
"input: %q([]rune%v))\ngot: %q([]rune%v)\nwant %q([]rune%v)",
g.input, []rune(g.input),
got, []rune(got),
g.expected, []rune(g.expected),
)
})
}
}
}

Expand Down

0 comments on commit f091f18

Please sign in to comment.