Files
log/compat/structured_format_test.go
lixen 2417e51da1
Test / test (push) Canceled after 0s
Test / fuzz (./compat, FuzzParseFormat) (push) Canceled after 0s
Test / fuzz (./formatter, FuzzFormatJSON) (push) Canceled after 0s
Test / fuzz (./formatter, FuzzFormatTextPolicy) (push) Canceled after 0s
Test / fuzz (./sanitizer, FuzzSanitize) (push) Canceled after 0s
Test / fuzz (./sanitizer, FuzzSerializerJSON) (push) Canceled after 0s
v0.1.11 harden logging lifecycle, sanitization, and formatter edge cases
2026-09-26 14:25:14 -04:00

55 lines
1.5 KiB
Go

package compat
import (
"fmt"
"reflect"
"testing"
)
func TestParseFormatKeepsArgumentAssociation(t *testing.T) {
for _, tc := range []struct {
format string
args []any
want []any
}{
{"prefix %s id=%d", []any{"alice", 42}, []any{"msg", "prefix alice id=42"}},
{"id=%[2]d name=%[1]s", []any{"alice", 42}, []any{"msg", "id=42 name=alice"}},
{"id=%d suffix", []any{42}, []any{"msg", "suffix", "id", 42}},
{"user=%s id=%d", []any{"alice", 42}, []any{"user", "alice", "id", 42}},
{"id=%d %s", []any{42, "tail"}, []any{"msg", "id=42 tail"}},
{"id=%*d", []any{4, 42}, []any{"msg", "id= 42"}},
{"literal %% id=%d", []any{42}, []any{"msg", "literal % id=42"}},
} {
t.Run(tc.format, func(t *testing.T) {
if got := parseFormat(tc.format, tc.args); !reflect.DeepEqual(got, tc.want) {
t.Fatalf("got %#v, want %#v", got, tc.want)
}
})
}
}
func FuzzParseFormat(f *testing.F) {
for _, format := range []string{"id=%d", "%s id=%d", "%%id=%d", "id=%[1]s"} {
f.Add(format, "value")
}
f.Fuzz(func(t *testing.T, format, value string) {
if len(format) > 1024 {
t.Skip()
}
fields := parseFormat(format, []any{value})
if len(fields)%2 != 0 {
t.Fatalf("odd fields %#v", fields)
}
for i := 0; i < len(fields); i += 2 {
if _, ok := fields[i].(string); !ok {
t.Fatalf("non-string key %#v", fields)
}
}
if len(fields) == 2 && fields[0] == "msg" {
if fields[1] != fmt.Sprintf(format, value) {
t.Fatal("fallback changed message")
}
}
})
}