1// Copyright 2022 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 debug_test
6
7import (
8	"reflect"
9	"runtime/debug"
10	"strings"
11	"testing"
12)
13
14// strip removes two leading tabs after each newline of s.
15func strip(s string) string {
16	replaced := strings.ReplaceAll(s, "\n\t\t", "\n")
17	if len(replaced) > 0 && replaced[0] == '\n' {
18		replaced = replaced[1:]
19	}
20	return replaced
21}
22
23func FuzzParseBuildInfoRoundTrip(f *testing.F) {
24	// Package built from outside a module, missing some fields..
25	f.Add(strip(`
26		path	rsc.io/fortune
27		mod	rsc.io/fortune	v1.0.0
28		`))
29
30	// Package built from the standard library, missing some fields..
31	f.Add(`path	cmd/test2json`)
32
33	// Package built from inside a module.
34	f.Add(strip(`
35		go	1.18
36		path	example.com/m
37		mod	example.com/m	(devel)
38		build	-compiler=gc
39		`))
40
41	// Package built in GOPATH mode.
42	f.Add(strip(`
43		go	1.18
44		path	example.com/m
45		build	-compiler=gc
46		`))
47
48	// Escaped build info.
49	f.Add(strip(`
50		go 1.18
51		path example.com/m
52		build CRAZY_ENV="requires\nescaping"
53		`))
54
55	f.Fuzz(func(t *testing.T, s string) {
56		bi, err := debug.ParseBuildInfo(s)
57		if err != nil {
58			// Not a round-trippable BuildInfo string.
59			t.Log(err)
60			return
61		}
62
63		// s2 could have different escaping from s.
64		// However, it should parse to exactly the same contents.
65		s2 := bi.String()
66		bi2, err := debug.ParseBuildInfo(s2)
67		if err != nil {
68			t.Fatalf("%v:\n%s", err, s2)
69		}
70
71		if !reflect.DeepEqual(bi2, bi) {
72			t.Fatalf("Parsed representation differs.\ninput:\n%s\noutput:\n%s", s, s2)
73		}
74	})
75}
76