Skip to content

Commit eb71708

Browse files
committed
feat: add tests and stip-line-log-prefixes flag
1 parent 32630dc commit eb71708

File tree

12 files changed

+399
-155
lines changed

12 files changed

+399
-155
lines changed

op-acceptor/config.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ type Config struct {
2727
Timeout time.Duration // Timeout for gateless mode tests (if specified)
2828
LogDir string // Directory to store test logs
2929
OutputRealtimeLogs bool // If enabled, test logs will be outputted in realtime
30+
StripCodeLinePrefixes bool // If enabled, file:line prefixes will be stripped from test logs
3031
TestLogLevel string // Log level to be used for the tests
3132
Orchestrator flags.OrchestratorType // Devstack orchestrator type
3233
DevnetEnvURL string // URL or path to the devnet environment file
@@ -38,7 +39,6 @@ type Config struct {
3839
FlakeShakeIterations int // Number of times to run each test in flake-shake mode
3940
Log log.Logger
4041
ExcludeGates []string // List of gate IDs whose tests should be excluded
41-
StripFileLinePrefixes bool // If enabled, strip file:line prefixes from test output logs
4242
}
4343

4444
// NewConfig creates a new Config from cli context
@@ -126,6 +126,7 @@ func NewConfig(ctx *cli.Context, log log.Logger, testDir string, validatorConfig
126126
DefaultTimeout: ctx.Duration(flags.DefaultTimeout.Name),
127127
Timeout: ctx.Duration(flags.Timeout.Name),
128128
OutputRealtimeLogs: ctx.Bool(flags.OutputRealtimeLogs.Name),
129+
StripCodeLinePrefixes: ctx.Bool(flags.StripCodeLinePrefixes.Name),
129130
TestLogLevel: ctx.String(flags.TestLogLevel.Name),
130131
Orchestrator: orchestrator,
131132
DevnetEnvURL: devnetEnvURL,
@@ -138,7 +139,6 @@ func NewConfig(ctx *cli.Context, log log.Logger, testDir string, validatorConfig
138139
LogDir: logDir,
139140
Log: log,
140141
ExcludeGates: excludeGates,
141-
StripFileLinePrefixes: ctx.Bool(flags.StripFileLinePrefixes.Name),
142142
}, nil
143143
}
144144

op-acceptor/flags/flags.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -121,11 +121,11 @@ var (
121121
EnvVars: opservice.PrefixEnvVar(EnvVarPrefix, "OUTPUT_REALTIME_LOGS"),
122122
Usage: "If enabled, test logs will be outputted to the console in realtime. Defaults to false.",
123123
}
124-
StripFileLinePrefixes = &cli.BoolFlag{
125-
Name: "strip-file-line-prefixes",
124+
StripCodeLinePrefixes = &cli.BoolFlag{
125+
Name: "strip-code-line-prefixes",
126126
Value: true,
127-
EnvVars: opservice.PrefixEnvVar(EnvVarPrefix, "STRIP_FILE_LINE_PREFIXES"),
128-
Usage: "Strip file:line prefixes (e.g., 'system.go:28:') from test output logs. Defaults to true.",
127+
EnvVars: opservice.PrefixEnvVar(EnvVarPrefix, "STRIP_CODE_LINE_PREFIXES"),
128+
Usage: "Strip file:line prefixes (e.g. 'test.go:123:') from test logs. Defaults to true.",
129129
}
130130
ShowProgress = &cli.BoolFlag{
131131
Name: "show-progress",
@@ -202,7 +202,7 @@ var optionalFlags = []cli.Flag{
202202
LogDir,
203203
TestLogLevel,
204204
OutputRealtimeLogs,
205-
StripFileLinePrefixes,
205+
StripCodeLinePrefixes,
206206
ShowProgress,
207207
ProgressInterval,
208208
Orchestrator,
Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
package logging
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
func TestCleanLogOutput(t *testing.T) {
10+
tests := []struct {
11+
name string
12+
input string
13+
expected string
14+
}{
15+
{
16+
name: "empty string",
17+
input: "",
18+
expected: "",
19+
},
20+
{
21+
name: "simple text without special characters",
22+
input: "hello world",
23+
expected: "hello world",
24+
},
25+
{
26+
name: "text with leading and trailing whitespace",
27+
input: " hello world ",
28+
expected: "hello world",
29+
},
30+
{
31+
name: "text with multiple spaces",
32+
input: "hello world",
33+
expected: "hello world",
34+
},
35+
{
36+
name: "text with tabs",
37+
input: "hello\t\tworld",
38+
expected: "hello world",
39+
},
40+
{
41+
name: "text with newlines",
42+
input: "hello\nworld",
43+
expected: "hello world",
44+
},
45+
{
46+
name: "text with mixed whitespace",
47+
input: "hello \t\n world",
48+
expected: "hello world",
49+
},
50+
{
51+
name: "file:line prefix simple",
52+
input: "test.go:123: error message",
53+
expected: "error message",
54+
},
55+
{
56+
name: "file:line prefix with underscore",
57+
input: "da_footprint_test.go:188: some log output",
58+
expected: "some log output",
59+
},
60+
{
61+
name: "file:line prefix with leading whitespace",
62+
input: " test_file.go:456: message here",
63+
expected: "message here",
64+
},
65+
{
66+
name: "file:line prefix with hyphen",
67+
input: "my-file.go:99: content",
68+
expected: "content",
69+
},
70+
{
71+
name: "ANSI color codes",
72+
input: "\x1b[31mred text\x1b[0m",
73+
expected: "red text",
74+
},
75+
{
76+
name: "ANSI codes with other formatting",
77+
input: "\x1b[1;32mbold green\x1b[0m normal",
78+
expected: "bold green normal",
79+
},
80+
{
81+
name: "combination: file prefix, ANSI codes, and whitespace",
82+
input: " test.go:42: \x1b[31m error: failed\x1b[0m ",
83+
expected: "error: failed",
84+
},
85+
{
86+
name: "combination: multiple whitespace types",
87+
input: "test.go:1: hello\t\t world \n foo",
88+
expected: "hello world foo",
89+
},
90+
{
91+
name: "text that looks like but isn't a file:line prefix",
92+
input: "this is not file.go:123: a prefix because text comes before",
93+
expected: "this is not file.go:123: a prefix because text comes before",
94+
},
95+
{
96+
name: "multiple lines with different prefixes",
97+
input: "file1.go:10: first line\nfile2.go:20: second line",
98+
expected: "first line file2.go:20: second line",
99+
},
100+
{
101+
name: "no file extension in prefix",
102+
input: "file:123: should not match",
103+
expected: "file:123: should not match",
104+
},
105+
{
106+
name: "wrong extension in prefix",
107+
input: "file.txt:123: should not match",
108+
expected: "file.txt:123: should not match",
109+
},
110+
{
111+
name: "real-world example with geth logger output",
112+
input: " da_test.go:188: \x1b[36mINFO\x1b[0m [01-01|00:00:00.000] Transaction submitted hash=0x123",
113+
expected: "INFO [01-01|00:00:00.000] Transaction submitted hash=0x123",
114+
},
115+
{
116+
name: "multiple consecutive newlines",
117+
input: "line1\n\n\nline2",
118+
expected: "line1 line2",
119+
},
120+
{
121+
name: "only whitespace",
122+
input: " \t\n ",
123+
expected: "",
124+
},
125+
{
126+
name: "unicode characters preserved",
127+
input: "hello 世界 🌍",
128+
expected: "hello 世界 🌍",
129+
},
130+
{
131+
name: "file prefix at start preserves rest of content",
132+
input: "test.go:1: key=value another=thing",
133+
expected: "key=value another=thing",
134+
},
135+
{
136+
name: "real log from da_footprint_test",
137+
input: " da_footprint_test.go:188: INFO [10-29|23:42:54.881] \"Block 0xbf9f2a47f13a639f439c3bb04070d3186019972b78d694e56e4e61647d4433a0:228357 has DA footprint (0) <= gasUsed (46218), trying next...\"",
138+
expected: "INFO [10-29|23:42:54.881] \"Block 0xbf9f2a47f13a639f439c3bb04070d3186019972b78d694e56e4e61647d4433a0:228357 has DA footprint (0) <= gasUsed (46218), trying next...\"",
139+
},
140+
}
141+
142+
for _, tt := range tests {
143+
t.Run(tt.name, func(t *testing.T) {
144+
result := CleanLogOutput(tt.input, true, true)
145+
assert.Equal(t, tt.expected, result, "CleanLogOutput(%q, true, true) = %q, want %q", tt.input, result, tt.expected)
146+
})
147+
}
148+
}
149+
150+
func TestCleanLogOutputWithoutStrippingPrefixes(t *testing.T) {
151+
tests := []struct {
152+
name string
153+
input string
154+
expected string
155+
}{
156+
{
157+
name: "file:line prefix preserved",
158+
input: "da_footprint_test.go:188: some log output",
159+
expected: "da_footprint_test.go:188: some log output",
160+
},
161+
{
162+
name: "file:line prefix preserved with whitespace collapsed",
163+
input: "test.go:1: hello\t\t world \n foo",
164+
expected: "test.go:1: hello world foo",
165+
},
166+
{
167+
name: "ANSI codes still stripped",
168+
input: "test.go:42: \x1b[31mred text\x1b[0m",
169+
expected: "test.go:42: red text",
170+
},
171+
}
172+
173+
for _, tt := range tests {
174+
t.Run(tt.name, func(t *testing.T) {
175+
result := CleanLogOutput(tt.input, false, true)
176+
assert.Equal(t, tt.expected, result, "CleanLogOutput(%q, false, true) = %q, want %q", tt.input, result, tt.expected)
177+
})
178+
}
179+
}
180+
181+
func TestCleanLogOutputRegexPatterns(t *testing.T) {
182+
t.Run("fileLinePrefixRegex matches valid patterns", func(t *testing.T) {
183+
validPatterns := []string{
184+
"test.go:123: ",
185+
" test.go:1: ",
186+
"my_file.go:999: ",
187+
"My-File.go:1: ",
188+
"FILE123.go:456: ",
189+
}
190+
for _, pattern := range validPatterns {
191+
assert.True(t, fileLinePrefixRegex.MatchString(pattern),
192+
"fileLinePrefixRegex should match %q", pattern)
193+
}
194+
})
195+
196+
t.Run("fileLinePrefixRegex does not match invalid patterns", func(t *testing.T) {
197+
invalidPatterns := []string{
198+
"file.txt:123: ", // not .go file
199+
"prefix file.go:123: ", // not at start
200+
"file.go:abc: ", // not a number
201+
"file:123: ", // missing .go
202+
".go:123: ", // no filename
203+
"file.go:", // missing line number
204+
}
205+
for _, pattern := range invalidPatterns {
206+
assert.False(t, fileLinePrefixRegex.MatchString(pattern),
207+
"fileLinePrefixRegex should not match %q", pattern)
208+
}
209+
})
210+
211+
t.Run("multipleWhitespaceRegex collapses various whitespace", func(t *testing.T) {
212+
testCases := []struct {
213+
input string
214+
expected string
215+
}{
216+
{"a b", "a b"},
217+
{"a\tb", "a b"},
218+
{"a\nb", "a b"},
219+
{"a\r\nb", "a b"},
220+
{"a \t\n b", "a b"},
221+
}
222+
for _, tc := range testCases {
223+
result := multipleWhitespaceRegex.ReplaceAllString(tc.input, " ")
224+
assert.Equal(t, tc.expected, result)
225+
}
226+
})
227+
}

0 commit comments

Comments
 (0)