From 107fcb820a471da47c900c9091e36d0b24c6a845 Mon Sep 17 00:00:00 2001 From: fanyang Date: Mon, 9 Feb 2026 18:59:56 +0800 Subject: [PATCH 1/2] Limit benchmark-only dependencies --- cmd_vfs_raw_bench_test.go | 382 ++++++++++++++++++++++++++++++++++++++ cmd_vfs_raw_test.go | 372 ------------------------------------- go.mod | 5 +- go.sum | 6 - pterm_writer.go | 5 +- 5 files changed, 385 insertions(+), 385 deletions(-) create mode 100644 cmd_vfs_raw_bench_test.go diff --git a/cmd_vfs_raw_bench_test.go b/cmd_vfs_raw_bench_test.go new file mode 100644 index 0000000..9ca1069 --- /dev/null +++ b/cmd_vfs_raw_bench_test.go @@ -0,0 +1,382 @@ +//go:build benchmark + +package main + +import ( + "bufio" + "bytes" + "context" + "database/sql" + "encoding/binary" + "fmt" + "os" + "testing" + "time" + + "github.com/marcboeker/go-duckdb/v2" + "github.com/negrel/assert" + "github.com/pierrec/lz4/v4" + "github.com/rs/zerolog/log" + "github.com/syndtr/goleveldb/leveldb" + "github.com/syndtr/goleveldb/leveldb/opt" + "github.com/tidwall/wal" +) + +const rows = int64(321039) +const walDir = "vfs-raw-bench.wal" +const rocksName = "rocks-bench" +const rawFileName = "raw-file-bench" + +type walAppender struct { + w *wal.Log + n uint64 +} + +func appendString(buffer []byte, s string) []byte { + b := make([]byte, 4) + binary.LittleEndian.PutUint32(b, uint32(len(s))) + return append(append(buffer, b...), s...) +} + +func makeRowBuffer(e *vfsEvent) []byte { + buffer := make([]byte, 6*(64/8)+2*(32/4)) + + // uint64/int64 + binary.LittleEndian.PutUint64(buffer[0:8], e.Timestamp) + binary.LittleEndian.PutUint64(buffer[8:16], e.Tid) + binary.LittleEndian.PutUint64(buffer[16:24], uint64(e.ReturnValue)) + binary.LittleEndian.PutUint64(buffer[24:32], e.Inode) + binary.LittleEndian.PutUint64(buffer[32:40], e.Offset) + binary.LittleEndian.PutUint64(buffer[40:48], e.Length) + + // string + buffer = appendString(buffer, e.Probe) + buffer = appendString(buffer, e.Path) + return buffer +} + +func (a *walAppender) AppendRow(e *vfsEvent) (err error) { + a.n++ + buffer := makeRowBuffer(e) + err = a.w.Write(a.n, buffer) + return +} + +func BenchmarkSimpleParseWithWal(b *testing.B) { + buffer, err := os.ReadFile(testDataFile) + if err != nil { + b.Fatal(err) + } + + _ = os.RemoveAll(walDir) + w, err := wal.Open(walDir, &wal.Options{NoSync: true}) + if err != nil { + b.Fatal(err) + } + appender := &walAppender{w: w} + + now := time.Now() + for n := 0; n < b.N; n++ { + r := bytes.NewReader(buffer) + err = simpleParseThenAppend(r, appender.AppendRow) + if err != nil { + b.Fatal(err) + } + } + elapsed := time.Since(now) + log.Info(). + Int("n", b.N). + Int64("elapsed_ns", elapsed.Nanoseconds()). + Int64("ops", 1000000000/(elapsed.Nanoseconds()/int64(b.N)/rows)). + Msg("Done in time") +} + +type levelAppender struct { + db *leveldb.DB + n uint64 +} + +var writeOptions = &opt.WriteOptions{} + +func (a *levelAppender) AppendRow(e *vfsEvent) (err error) { + a.n++ + key := make([]byte, 8) + binary.LittleEndian.PutUint64(key, a.n) + buffer := makeRowBuffer(e) + err = a.db.Put(key, buffer, writeOptions) + return +} + +func (a *levelAppender) Close() (err error) { + err = a.db.Close() + return +} + +type fileAppender struct { + file *bufio.Writer +} + +func (a *fileAppender) AppendRow(e *vfsEvent) (err error) { + buffer := makeRowBuffer(e) + lenBuf := make([]byte, 4) + binary.LittleEndian.PutUint32(lenBuf, uint32(len(buffer))) + var n int + n, err = a.file.Write(append(lenBuf, buffer...)) + assert.True(n == len(buffer)+len(lenBuf)) + return +} + +func (a *fileAppender) Close() (err error) { + err = a.file.Flush() + return +} + +// ops=4385964 +// ops=3787878 with lz4 +func BenchmarkSimpleParseWithFile(b *testing.B) { + buffer, err := os.ReadFile(testDataFile) + if err != nil { + b.Fatal(err) + } + + file, err := os.Create(rawFileName) + if err != nil { + b.Fatal(err) + } + defer func() { _ = file.Close() }() + w := bufio.NewWriterSize(lz4.NewWriter(file), 128*1024*1024) + + appender := &fileAppender{file: w} + defer func() { _ = appender.Close() }() + + now := time.Now() + for n := 0; n < b.N; n++ { + r := bytes.NewReader(buffer) + err = simpleParseThenAppend(r, appender.AppendRow) + if err != nil { + b.Fatal(err) + } + } + elapsed := time.Since(now) + log.Info(). + Int("n", b.N). + Int64("elapsed_ns", elapsed.Nanoseconds()). + Int64("ops", 1000000000/(elapsed.Nanoseconds()/int64(b.N)/rows)). + Msg("Done in time") +} + +func BenchmarkSimpleParseWithLevels(b *testing.B) { + buffer, err := os.ReadFile(testDataFile) + if err != nil { + b.Fatal(err) + } + + db, err := leveldb.OpenFile(rocksName, nil) + if err != nil { + b.Fatal(err) + } + appender := &levelAppender{db: db} + + now := time.Now() + for n := 0; n < b.N; n++ { + r := bytes.NewReader(buffer) + err = simpleParseThenAppend(r, appender.AppendRow) + if err != nil { + b.Fatal(err) + } + } + elapsed := time.Since(now) + log.Info(). + Int("n", b.N). + Int64("elapsed_ns", elapsed.Nanoseconds()). + Int64("ops", 1000000000/(elapsed.Nanoseconds()/int64(b.N)/rows)). + Msg("Done in time") + + _ = appender.Close() +} + +// ops=5076142 +func BenchmarkSimpleParseOnly(b *testing.B) { + buffer, err := os.ReadFile(testDataFile) + if err != nil { + b.Fatal(err) + } + + now := time.Now() + + for n := 0; n < b.N; n++ { + r := bytes.NewReader(buffer) + err = simpleParseThenAppend(r, func(*vfsEvent) error { return nil }) + if err != nil { + b.Fatal(err) + } + } + + elapsed := time.Since(now) + log.Info(). + Int("n", b.N). + Int64("elapsed_ns", elapsed.Nanoseconds()). + Int64("ops", 1000000000/(elapsed.Nanoseconds()/int64(b.N)/rows)). + Msg("Done in time") +} + +// Read from memory and parse only +// ops=3378378 +func BenchmarkJsonParseOnly(b *testing.B) { + buffer, err := os.ReadFile(testDataFile) + if err != nil { + b.Fatal(err) + } + + now := time.Now() + + for n := 0; n < b.N; n++ { + r := bytes.NewReader(buffer) + err = jsonParseThenAppend(r, func(*vfsEvent) error { return nil }) + if err != nil { + b.Fatal(err) + } + } + + elapsed := time.Since(now) + log.Info(). + Int("n", b.N). + Int64("elapsed_ns", elapsed.Nanoseconds()). + Int64("ops", 1000000000/(elapsed.Nanoseconds()/int64(b.N)/rows)). + Msg("Done in time") +} + +// Read from memory and write to DuckDB +// ops=1126126 +func BenchmarkReadMemoryWriteDuckDB(b *testing.B) { + ctx := context.Background() + dsn := "bench.ddb" + tableName := "append_bench" + + _ = os.Remove(dsn) + _ = os.Remove(dsn + ".wal") + + connector, err := duckdb.NewConnector(dsn, nil) + if err != nil { + b.Fatal(err) + } + + log.Info().Str("dsn", dsn).Msg("Connecting to db") + conn, err := connector.Connect(ctx) + if err != nil { + b.Fatal(err) + } + + db := sql.OpenDB(connector) + log.Info().Msg("DB created") + + _, err = db.Exec(fmt.Sprintf(dropTableSql, tableName)) + if err != nil { + b.Fatal(err) + } + + _, err = db.Exec(fmt.Sprintf(createTableSql, tableName)) + if err != nil { + b.Fatal(err) + } + + appender, err := duckdb.NewAppenderFromConn(conn, "", tableName) + if err != nil { + b.Fatal(err) + } + defer func() { _ = appender.Close() }() + + buffer, err := os.ReadFile(testDataFile) + if err != nil { + b.Fatal(err) + } + + now := time.Now() + + for n := 0; n < b.N; n++ { + r := bytes.NewReader(buffer) + err = jsonParseThenAppend(r, func(e *vfsEvent) error { + return appender.AppendRow(e.Timestamp, e.Probe, e.Tid, e.ReturnValue, + e.Path, e.Inode, e.Offset, e.Length) + }) + if err != nil { + b.Fatal(err) + } + _ = appender.Flush() + } + + elapsed := time.Since(now) + log.Info(). + Int("n", b.N). + Int64("elapsed_ns", elapsed.Nanoseconds()). + Int64("ops", 1000000000/(elapsed.Nanoseconds()/int64(b.N)/rows)). + Msg("Done in time") +} + +// ops=1164144 +func BenchmarkImportFromBpf(b *testing.B) { + ctx := context.Background() + dsn := "bench.ddb" + tableName := "append_bench" + + _ = os.Remove(dsn) + _ = os.Remove(dsn + ".wal") + + connector, err := duckdb.NewConnector(dsn, nil) + if err != nil { + b.Fatal(err) + } + + log.Info().Str("dsn", dsn).Msg("Connecting to db") + conn, err := connector.Connect(ctx) + if err != nil { + b.Fatal(err) + } + + db := sql.OpenDB(connector) + log.Info().Msg("DB created") + + _, err = db.Exec(fmt.Sprintf(dropTableSql, tableName)) + if err != nil { + b.Fatal(err) + } + + _, err = db.Exec(fmt.Sprintf(createTableSql, tableName)) + if err != nil { + b.Fatal(err) + } + + appender, err := duckdb.NewAppenderFromConn(conn, "", tableName) + if err != nil { + b.Fatal(err) + } + defer func() { _ = appender.Close() }() + + now := time.Now() + + for n := 0; n < b.N; n++ { + var r *os.File + r, err = os.Open("testdata/vfs-raw.ndjson") + if err != nil { + b.Fatal(err) + } + + err = jsonParseThenAppend(r, func(e *vfsEvent) error { + return appender.AppendRow(e.Timestamp, e.Probe, e.Tid, e.ReturnValue, + e.Path, e.Inode, e.Offset, e.Length) + }) + if err != nil { + b.Fatal(err) + } + + _ = appender.Flush() + _ = r.Close() + } + + elapsed := time.Since(now) + log.Info(). + Int("n", b.N). + Int64("elapsed_ns", elapsed.Nanoseconds()). + Int64("ops", 1000000000/(elapsed.Nanoseconds()/int64(b.N)/rows)). + Msg("Done in time") +} diff --git a/cmd_vfs_raw_test.go b/cmd_vfs_raw_test.go index 5622597..46db04b 100644 --- a/cmd_vfs_raw_test.go +++ b/cmd_vfs_raw_test.go @@ -1,31 +1,13 @@ package main import ( - "bufio" "bytes" - "context" - "database/sql" - "encoding/binary" - "fmt" "os" "strings" "testing" - "time" - - "github.com/marcboeker/go-duckdb/v2" - "github.com/negrel/assert" - "github.com/pierrec/lz4/v4" - "github.com/rs/zerolog/log" - "github.com/syndtr/goleveldb/leveldb" - "github.com/syndtr/goleveldb/leveldb/opt" - "github.com/tidwall/wal" ) const testDataFile = "testdata/vfs-raw.ndjson" -const rows = int64(321039) -const walDir = "vfs-raw-bench.wal" -const rocksName = "rocks-bench" -const rawFileName = "raw-file-bench" // linux-amd64, cpu: AMD Ryzen 7 9700X 8-Core Processor @@ -41,360 +23,6 @@ func TestSimpleParse(t *testing.T) { } } -type walAppender struct { - w *wal.Log - n uint64 -} - -func appendString(buffer []byte, s string) []byte { - b := make([]byte, 4) - binary.LittleEndian.PutUint32(b, uint32(len(s))) - return append(append(buffer, b...), s...) -} - -func makeRowBuffer(e *vfsEvent) []byte { - buffer := make([]byte, 6*(64/8)+2*(32/4)) - - // uint64/int64 - binary.LittleEndian.PutUint64(buffer[0:8], e.Timestamp) - binary.LittleEndian.PutUint64(buffer[8:16], e.Tid) - binary.LittleEndian.PutUint64(buffer[16:24], uint64(e.ReturnValue)) - binary.LittleEndian.PutUint64(buffer[24:32], e.Inode) - binary.LittleEndian.PutUint64(buffer[32:40], e.Offset) - binary.LittleEndian.PutUint64(buffer[40:48], e.Length) - - // string - buffer = appendString(buffer, e.Probe) - buffer = appendString(buffer, e.Path) - return buffer -} - -func (a *walAppender) AppendRow(e *vfsEvent) (err error) { - a.n++ - buffer := makeRowBuffer(e) - err = a.w.Write(a.n, buffer) - return -} - -func BenchmarkSimpleParseWithWal(b *testing.B) { - buffer, err := os.ReadFile(testDataFile) - if err != nil { - b.Fatal(err) - } - - _ = os.RemoveAll(walDir) - w, err := wal.Open(walDir, &wal.Options{NoSync: true}) - if err != nil { - b.Fatal(err) - } - appender := &walAppender{w: w} - - now := time.Now() - for n := 0; n < b.N; n++ { - r := bytes.NewReader(buffer) - err = simpleParseThenAppend(r, appender.AppendRow) - if err != nil { - b.Fatal(err) - } - } - elapsed := time.Since(now) - log.Info(). - Int("n", b.N). - Int64("elapsed_ns", elapsed.Nanoseconds()). - Int64("ops", 1000000000/(elapsed.Nanoseconds()/int64(b.N)/rows)). - Msg("Done in time") -} - -type levelAppender struct { - db *leveldb.DB - n uint64 -} - -var writeOptions = &opt.WriteOptions{} - -func (a *levelAppender) AppendRow(e *vfsEvent) (err error) { - a.n++ - key := make([]byte, 8) - binary.LittleEndian.PutUint64(key, a.n) - buffer := makeRowBuffer(e) - err = a.db.Put(key, buffer, writeOptions) - return -} - -func (a *levelAppender) Close() (err error) { - err = a.db.Close() - return -} - -type fileAppender struct { - file *bufio.Writer -} - -func (a *fileAppender) AppendRow(e *vfsEvent) (err error) { - buffer := makeRowBuffer(e) - lenBuf := make([]byte, 4) - binary.LittleEndian.PutUint32(lenBuf, uint32(len(buffer))) - var n int - n, err = a.file.Write(append(lenBuf, buffer...)) - assert.True(n == len(buffer)+len(lenBuf)) - return -} - -func (a *fileAppender) Close() (err error) { - err = a.file.Flush() - return -} - -// ops=4385964 -// ops=3787878 with lz4 -func BenchmarkSimpleParseWithFile(b *testing.B) { - buffer, err := os.ReadFile(testDataFile) - if err != nil { - b.Fatal(err) - } - - file, err := os.Create(rawFileName) - if err != nil { - b.Fatal(err) - } - defer func() { _ = file.Close() }() - w := bufio.NewWriterSize(lz4.NewWriter(file), 128*1024*1024) - - appender := &fileAppender{file: w} - defer func() { _ = appender.Close() }() - - now := time.Now() - for n := 0; n < b.N; n++ { - r := bytes.NewReader(buffer) - err = simpleParseThenAppend(r, appender.AppendRow) - if err != nil { - b.Fatal(err) - } - } - elapsed := time.Since(now) - log.Info(). - Int("n", b.N). - Int64("elapsed_ns", elapsed.Nanoseconds()). - Int64("ops", 1000000000/(elapsed.Nanoseconds()/int64(b.N)/rows)). - Msg("Done in time") -} - -func BenchmarkSimpleParseWithLevels(b *testing.B) { - buffer, err := os.ReadFile(testDataFile) - if err != nil { - b.Fatal(err) - } - - db, err := leveldb.OpenFile(rocksName, nil) - if err != nil { - b.Fatal(err) - } - appender := &levelAppender{db: db} - - now := time.Now() - for n := 0; n < b.N; n++ { - r := bytes.NewReader(buffer) - err = simpleParseThenAppend(r, appender.AppendRow) - if err != nil { - b.Fatal(err) - } - } - elapsed := time.Since(now) - log.Info(). - Int("n", b.N). - Int64("elapsed_ns", elapsed.Nanoseconds()). - Int64("ops", 1000000000/(elapsed.Nanoseconds()/int64(b.N)/rows)). - Msg("Done in time") - - _ = appender.Close() -} - -// ops=5076142 -func BenchmarkSimpleParseOnly(b *testing.B) { - buffer, err := os.ReadFile(testDataFile) - if err != nil { - b.Fatal(err) - } - - now := time.Now() - - for n := 0; n < b.N; n++ { - r := bytes.NewReader(buffer) - err = simpleParseThenAppend(r, func(*vfsEvent) error { return nil }) - if err != nil { - b.Fatal(err) - } - } - - elapsed := time.Since(now) - log.Info(). - Int("n", b.N). - Int64("elapsed_ns", elapsed.Nanoseconds()). - Int64("ops", 1000000000/(elapsed.Nanoseconds()/int64(b.N)/rows)). - Msg("Done in time") -} - -// Read from memory and parse only -// ops=3378378 -func BenchmarkJsonParseOnly(b *testing.B) { - buffer, err := os.ReadFile(testDataFile) - if err != nil { - b.Fatal(err) - } - - now := time.Now() - - for n := 0; n < b.N; n++ { - r := bytes.NewReader(buffer) - err = jsonParseThenAppend(r, func(*vfsEvent) error { return nil }) - if err != nil { - b.Fatal(err) - } - } - - elapsed := time.Since(now) - log.Info(). - Int("n", b.N). - Int64("elapsed_ns", elapsed.Nanoseconds()). - Int64("ops", 1000000000/(elapsed.Nanoseconds()/int64(b.N)/rows)). - Msg("Done in time") -} - -// Read from memory and write to DuckDB -// ops=1126126 -func BenchmarkReadMemoryWriteDuckDB(b *testing.B) { - ctx := context.Background() - dsn := "bench.ddb" - tableName := "append_bench" - - _ = os.Remove(dsn) - _ = os.Remove(dsn + ".wal") - - connector, err := duckdb.NewConnector(dsn, nil) - if err != nil { - b.Fatal(err) - } - - log.Info().Str("dsn", dsn).Msg("Connecting to db") - conn, err := connector.Connect(ctx) - if err != nil { - b.Fatal(err) - } - - db := sql.OpenDB(connector) - log.Info().Msg("DB created") - - _, err = db.Exec(fmt.Sprintf(dropTableSql, tableName)) - if err != nil { - b.Fatal(err) - } - - _, err = db.Exec(fmt.Sprintf(createTableSql, tableName)) - if err != nil { - b.Fatal(err) - } - - appender, err := duckdb.NewAppenderFromConn(conn, "", tableName) - if err != nil { - b.Fatal(err) - } - defer func() { _ = appender.Close() }() - - buffer, err := os.ReadFile(testDataFile) - if err != nil { - b.Fatal(err) - } - - now := time.Now() - - for n := 0; n < b.N; n++ { - r := bytes.NewReader(buffer) - err = jsonParseThenAppend(r, func(e *vfsEvent) error { - return appender.AppendRow(e.Timestamp, e.Probe, e.Tid, e.ReturnValue, - e.Path, e.Inode, e.Offset, e.Length) - }) - if err != nil { - b.Fatal(err) - } - _ = appender.Flush() - } - - elapsed := time.Since(now) - log.Info(). - Int("n", b.N). - Int64("elapsed_ns", elapsed.Nanoseconds()). - Int64("ops", 1000000000/(elapsed.Nanoseconds()/int64(b.N)/rows)). - Msg("Done in time") -} - -// ops=1164144 -func BenchmarkImportFromBpf(b *testing.B) { - ctx := context.Background() - dsn := "bench.ddb" - tableName := "append_bench" - - _ = os.Remove(dsn) - _ = os.Remove(dsn + ".wal") - - connector, err := duckdb.NewConnector(dsn, nil) - if err != nil { - b.Fatal(err) - } - - log.Info().Str("dsn", dsn).Msg("Connecting to db") - conn, err := connector.Connect(ctx) - if err != nil { - b.Fatal(err) - } - - db := sql.OpenDB(connector) - log.Info().Msg("DB created") - - _, err = db.Exec(fmt.Sprintf(dropTableSql, tableName)) - if err != nil { - b.Fatal(err) - } - - _, err = db.Exec(fmt.Sprintf(createTableSql, tableName)) - if err != nil { - b.Fatal(err) - } - - appender, err := duckdb.NewAppenderFromConn(conn, "", tableName) - if err != nil { - b.Fatal(err) - } - defer func() { _ = appender.Close() }() - - now := time.Now() - - for n := 0; n < b.N; n++ { - var r *os.File - r, err = os.Open("testdata/vfs-raw.ndjson") - if err != nil { - b.Fatal(err) - } - - err = jsonParseThenAppend(r, func(e *vfsEvent) error { - return appender.AppendRow(e.Timestamp, e.Probe, e.Tid, e.ReturnValue, - e.Path, e.Inode, e.Offset, e.Length) - }) - if err != nil { - b.Fatal(err) - } - - _ = appender.Flush() - _ = r.Close() - } - - elapsed := time.Since(now) - log.Info(). - Int("n", b.N). - Int64("elapsed_ns", elapsed.Nanoseconds()). - Int64("ops", 1000000000/(elapsed.Nanoseconds()/int64(b.N)/rows)). - Msg("Done in time") -} - // ============================================ // Unit Tests for Parser Error Handling // ============================================ diff --git a/go.mod b/go.mod index 8555d02..666572d 100644 --- a/go.mod +++ b/go.mod @@ -4,17 +4,13 @@ go 1.24.4 require ( github.com/goccy/go-json v0.10.5 - github.com/gookit/color v1.5.3 github.com/kr/logfmt v0.0.0-20210122060352-19f9bcb100e6 github.com/marcboeker/go-duckdb/v2 v2.3.2 github.com/minio/simdjson-go v0.4.5 github.com/negrel/assert v0.5.0 - github.com/pierrec/lz4/v4 v4.1.22 github.com/pkg/errors v0.9.1 github.com/pterm/pterm v0.12.61 github.com/rs/zerolog v1.34.0 - github.com/syndtr/goleveldb v1.0.0 - github.com/tidwall/wal v1.1.8 github.com/urfave/cli/v3 v3.3.8 ) @@ -35,6 +31,7 @@ require ( github.com/golang/snappy v0.0.4 // indirect github.com/google/flatbuffers v25.1.24+incompatible // indirect github.com/google/uuid v1.6.0 // indirect + github.com/gookit/color v1.5.3 // indirect github.com/klauspost/compress v1.17.11 // indirect github.com/klauspost/cpuid/v2 v2.2.9 // indirect github.com/lithammer/fuzzysearch v1.1.7 // indirect diff --git a/go.sum b/go.sum index ddf52fc..87e9381 100644 --- a/go.sum +++ b/go.sum @@ -106,8 +106,6 @@ github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU= -github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -135,8 +133,6 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= -github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/tidwall/gjson v1.10.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= @@ -148,8 +144,6 @@ github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhso github.com/tidwall/tinylru v1.1.0/go.mod h1:3+bX+TJ2baOLMWTnlyNWHh4QMnFyARg2TLTQ6OFbzw8= github.com/tidwall/tinylru v1.2.1 h1:VgBr72c2IEr+V+pCdkPZUwiQ0KJknnWIYbhxAVkYfQk= github.com/tidwall/tinylru v1.2.1/go.mod h1:9bQnEduwB6inr2Y7AkBP7JPgCkyrhTV/ZpX0oOOpBI4= -github.com/tidwall/wal v1.1.8 h1:2qDSGdAdjaY3PEvHRva+9UFqgk+ef7cOiW1Qn5JH1y0= -github.com/tidwall/wal v1.1.8/go.mod h1:r6lR1j27W9EPalgHiB7zLJDYu3mzW5BQP5KrzBpYY/E= github.com/urfave/cli/v3 v3.3.8 h1:BzolUExliMdet9NlJ/u4m5vHSotJ3PzEqSAZ1oPMa/E= github.com/urfave/cli/v3 v3.3.8/go.mod h1:FJSKtM/9AiiTOJL4fJ6TbMUkxBXn7GO9guZqoZtpYpo= github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= diff --git a/pterm_writer.go b/pterm_writer.go index ec6a066..6dca4f8 100644 --- a/pterm_writer.go +++ b/pterm_writer.go @@ -12,7 +12,6 @@ import ( "text/template" "github.com/goccy/go-json" - "github.com/gookit/color" "github.com/pterm/pterm" "github.com/rs/zerolog" ) @@ -59,7 +58,7 @@ func newPtermWriter() *ptermWriter { }, keyOrderFn: func(k1, k2 string) bool { score := func(s string) string { - s = color.ClearCode(s) + s = pterm.RemoveColorFromString(s) if s == zerolog.TimestampFieldName { return string([]byte{0, 0}) } @@ -89,7 +88,7 @@ func newPtermWriter() *ptermWriter { return strings.Repeat(" ", n) }, "totalLength": func(n int, s ...string) int { - return len(color.ClearCode(strings.Join(s, ""))) - n + return len(pterm.RemoveColorFromString(strings.Join(s, ""))) - n }, "last": func(x int, a interface{}) bool { return x == reflect.ValueOf(a).Len()-1 From 4cc8e1332b696090af2f3d7bac6db1fbf1d020dc Mon Sep 17 00:00:00 2001 From: fanyang Date: Tue, 10 Feb 2026 20:00:30 +0800 Subject: [PATCH 2/2] Fix test --- cmd_vfs_raw_test.go | 23 ++++++++++++++++++++--- cmd_vfs_test.go | 12 ++++++++++++ go.work.sum | 10 ++-------- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/cmd_vfs_raw_test.go b/cmd_vfs_raw_test.go index 46db04b..974bd4e 100644 --- a/cmd_vfs_raw_test.go +++ b/cmd_vfs_raw_test.go @@ -2,6 +2,7 @@ package main import ( "bytes" + "fmt" "os" "strings" "testing" @@ -120,6 +121,13 @@ func TestSimpleParseInvalidTime(t *testing.T) { } } +func isErrorUnsupportedPlatform(err error) bool { + if err == nil { + return false + } + return err.Error() == "Unsupported platform" +} + // TestJsonParseValidData tests jsonParseThenAppend with valid input func TestJsonParseValidData(t *testing.T) { r := strings.NewReader(vfsRawTestDataValid) @@ -129,7 +137,10 @@ func TestJsonParseValidData(t *testing.T) { events = append(events, e) return nil }) - + if isErrorUnsupportedPlatform(err) { + t.Skip() + return + } if err != nil { t.Fatalf("jsonParseThenAppend() error = %v", err) } @@ -157,7 +168,10 @@ func TestJsonParseUnknownType(t *testing.T) { events = append(events, e) return nil }) - + if isErrorUnsupportedPlatform(err) { + t.Skip() + return + } if err != nil { t.Fatalf("jsonParseThenAppend() should not error on unknown type, got: %v", err) } @@ -206,7 +220,10 @@ func TestJsonParseProbesNotAttached(t *testing.T) { err := jsonParseThenAppend(r, func(e *vfsEvent) error { return nil }) - + if isErrorUnsupportedPlatform(err) { + t.Skip() + return + } if err == nil { t.Error("expected error when probes not attached, got nil") } diff --git a/cmd_vfs_test.go b/cmd_vfs_test.go index 024932f..a7fc330 100644 --- a/cmd_vfs_test.go +++ b/cmd_vfs_test.go @@ -100,6 +100,10 @@ func TestEventFill(t *testing.T) { // Create a wrapper structure similar to what vfs count receives wrapperJSON := `{"data": {"@": {"vfs_create": 10, "vfs_open": 20, "vfs_read": 30, "vfs_readlink": 5, "vfs_readv": 3, "vfs_write": 15, "vfs_writev": 7, "vfs_fsync": 2}}}` pj, err := simdjson.Parse([]byte(wrapperJSON), nil) + if isErrorUnsupportedPlatform(err) { + t.Skip() + return + } if err != nil { t.Fatalf("failed to parse wrapper JSON: %v", err) } @@ -134,6 +138,10 @@ func TestEventFillError(t *testing.T) { // Missing '@' element testJSON := `{"data": {"other_key": {"vfs_create": 10}}}` pj, err := simdjson.Parse([]byte(testJSON), nil) + if isErrorUnsupportedPlatform(err) { + t.Skip() + return + } if err != nil { t.Fatalf("failed to parse JSON: %v", err) } @@ -159,6 +167,10 @@ func TestEventFillUnknownField(t *testing.T) { // Include unknown field 'vfs_unknown' testJSON := `{"data": {"@": {"vfs_create": 10, "vfs_unknown": 999}}}` pj, err := simdjson.Parse([]byte(testJSON), nil) + if isErrorUnsupportedPlatform(err) { + t.Skip() + return + } if err != nil { t.Fatalf("failed to parse JSON: %v", err) } diff --git a/go.work.sum b/go.work.sum index 61077d5..c7f121f 100644 --- a/go.work.sum +++ b/go.work.sum @@ -70,7 +70,6 @@ github.com/hamba/avro/v2 v2.27.0 h1:IAM4lQ0VzUIKBuo4qlAiLKfqALSrFC+zi1iseTtbBKU= github.com/hamba/avro/v2 v2.27.0/go.mod h1:jN209lopfllfrz7IGoZErlDz+AyUJ3vrBePQFZwYf5I= github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hydrogen18/memlistener v1.0.0 h1:JR7eDj8HD6eXrc5fWLbSUnfcQFL06PYvCc0DKQnWfaU= github.com/hydrogen18/memlistener v1.0.0/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/iris-contrib/schema v0.0.6 h1:CPSBLyx2e91H2yJzPuhGuifVRnZBBJ3pCOMbOvPZaTw= @@ -120,10 +119,10 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= -github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= -github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg= github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas= +github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU= +github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgcC4zIxODThtZNPirFr42+A= @@ -179,8 +178,6 @@ golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= -golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= -golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= @@ -213,11 +210,8 @@ google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojt gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI=