--- /dev/null
+// 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
+}