From bf58e7845eeba5f253f152f5f86523a7582d2a26 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Fri, 31 Oct 2025 17:37:26 -0400 Subject: [PATCH] internal/trace: add "command" to convert text traces to raw This is primarily helpful for parsing traces dumped via CI. cmd/dist doesn't like commands in std which are not actually part of the Go distribution. So rather than using a real command, this is actually a test which does the conversion. Change-Id: I6a6a636c829a4acc0bce8cf7548105ad59d83c67 Reviewed-on: https://go-review.googlesource.com/c/go/+/716882 Reviewed-by: Michael Knyszek LUCI-TryBot-Result: Go LUCI --- src/internal/trace/testtrace/helpers.go | 1 + src/internal/trace/testtrace/helpers_test.go | 79 ++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 src/internal/trace/testtrace/helpers_test.go diff --git a/src/internal/trace/testtrace/helpers.go b/src/internal/trace/testtrace/helpers.go index 50f6825bab5..ef676a9a143 100644 --- a/src/internal/trace/testtrace/helpers.go +++ b/src/internal/trace/testtrace/helpers.go @@ -37,6 +37,7 @@ func Dump(t *testing.T, testName string, traceBytes []byte, forceToFile bool) { t.Logf("text trace too large to dump (%d bytes)", len(s)) } else { t.Log(s) + t.Log("Convert this to a raw trace with `go test internal/trace/testtrace -covert in.tracetxt -out out.trace`") } } else { // We asked to dump the trace or failed. Write the trace to a file. diff --git a/src/internal/trace/testtrace/helpers_test.go b/src/internal/trace/testtrace/helpers_test.go new file mode 100644 index 00000000000..3b874ac6317 --- /dev/null +++ b/src/internal/trace/testtrace/helpers_test.go @@ -0,0 +1,79 @@ +// Copyright 2025 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testtrace + +import ( + "flag" + "fmt" + "io" + "internal/trace/raw" + "os" + "testing" +) + +var ( + convert = flag.String("convert", "", "Path to trace text file to convert to binary format") + output = flag.String("out", "", "Output path for converted trace") +) + +// TestConvertDump is not actually a test, it is a tool for converting trace +// text dumps generated by Dump into the binary trace format. Set -convert and +// -o to perform a converison. +// +// go test internal/trace/testtrace -convert in.tracetxt -out out.trace +// +// This would be cleaner as a dedicated internal command rather than a test, +// but cmd/dist does not handle internal (non-distributed) commands in std +// well. +func TestConvertDump(t *testing.T) { + if *convert == "" { + t.Skip("Set -convert to convert a trace text file") + } + if *output == "" { + t.Fatal("Set -o to specify conversion output") + } + + if err := convertDump(*convert, *output); err != nil { + t.Error(err) + } +} + +func convertDump(inPath, outPath string) error { + in, err := os.Open(inPath) + if err != nil { + return fmt.Errorf("error opening input: %v", err) + } + defer in.Close() + + out, err := os.Create(outPath) + if err != nil { + return fmt.Errorf("error creating output: %v", err) + } + defer out.Close() + + tr, err := raw.NewTextReader(in) + if err != nil { + return fmt.Errorf("error creating text reader: %v", err) + } + tw, err := raw.NewWriter(out, tr.Version()) + if err != nil { + return fmt.Errorf("error creating raw writer: %v", err) + } + + for { + ev, err := tr.ReadEvent() + if err == io.EOF { + break + } + if err != nil { + return fmt.Errorf("bad trace file: %v", err) + } + if err := tw.WriteEvent(ev); err != nil { + return fmt.Errorf("failed to write trace bytes: %v", err) + } + } + + return nil +}