1// Copyright 2023 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package testtrace
6
7import (
8	"bytes"
9	"fmt"
10	"internal/trace/raw"
11	"internal/txtar"
12	"io"
13)
14
15// ParseFile parses a test file generated by the testgen package.
16func ParseFile(testPath string) (io.Reader, *Expectation, error) {
17	ar, err := txtar.ParseFile(testPath)
18	if err != nil {
19		return nil, nil, fmt.Errorf("failed to read test file for %s: %v", testPath, err)
20	}
21	if len(ar.Files) != 2 {
22		return nil, nil, fmt.Errorf("malformed test %s: wrong number of files", testPath)
23	}
24	if ar.Files[0].Name != "expect" {
25		return nil, nil, fmt.Errorf("malformed test %s: bad filename %s", testPath, ar.Files[0].Name)
26	}
27	if ar.Files[1].Name != "trace" {
28		return nil, nil, fmt.Errorf("malformed test %s: bad filename %s", testPath, ar.Files[1].Name)
29	}
30	tr, err := raw.NewTextReader(bytes.NewReader(ar.Files[1].Data))
31	if err != nil {
32		return nil, nil, fmt.Errorf("malformed test %s: bad trace file: %v", testPath, err)
33	}
34	var buf bytes.Buffer
35	tw, err := raw.NewWriter(&buf, tr.Version())
36	if err != nil {
37		return nil, nil, fmt.Errorf("failed to create trace byte writer: %v", err)
38	}
39	for {
40		ev, err := tr.ReadEvent()
41		if err == io.EOF {
42			break
43		}
44		if err != nil {
45			return nil, nil, fmt.Errorf("malformed test %s: bad trace file: %v", testPath, err)
46		}
47		if err := tw.WriteEvent(ev); err != nil {
48			return nil, nil, fmt.Errorf("internal error during %s: failed to write trace bytes: %v", testPath, err)
49		}
50	}
51	exp, err := ParseExpectation(ar.Files[0].Data)
52	if err != nil {
53		return nil, nil, fmt.Errorf("internal error during %s: failed to parse expectation %q: %v", testPath, string(ar.Files[0].Data), err)
54	}
55	return &buf, exp, nil
56}
57