Skip to content

Commit ee6fcd7

Browse files
aykevldeadprogram
authored andcommitted
builder: add testing for -size=full
This helps to make sure this feature continues to work and we won't accidentally introduce regressions.
1 parent ca80c52 commit ee6fcd7

File tree

2 files changed

+79
-25
lines changed

2 files changed

+79
-25
lines changed

builder/build.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ type BuildResult struct {
6161
// correctly printing test results: the import path isn't always the same as
6262
// the path listed on the command line.
6363
ImportPath string
64+
65+
// Map from path to package name. It is needed to attribute binary size to
66+
// the right Go package.
67+
PackagePathMap map[string]string
6468
}
6569

6670
// packageAction is the struct that is serialized to JSON and hashed, to work as
@@ -242,6 +246,12 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
242246
return result, err
243247
}
244248

249+
// Store which filesystem paths map to which package name.
250+
result.PackagePathMap = make(map[string]string, len(lprogram.Packages))
251+
for _, pkg := range lprogram.Sorted() {
252+
result.PackagePathMap[pkg.OriginalDir()] = pkg.Pkg.Path()
253+
}
254+
245255
// Create the *ssa.Program. This does not yet build the entire SSA of the
246256
// program so it's pretty fast and doesn't need to be parallelized.
247257
program := lprogram.LoadSSA()
@@ -916,11 +926,7 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
916926

917927
// Print code size if requested.
918928
if config.Options.PrintSizes == "short" || config.Options.PrintSizes == "full" {
919-
packagePathMap := make(map[string]string, len(lprogram.Packages))
920-
for _, pkg := range lprogram.Sorted() {
921-
packagePathMap[pkg.OriginalDir()] = pkg.Pkg.Path()
922-
}
923-
sizes, err := loadProgramSize(result.Executable, packagePathMap)
929+
sizes, err := loadProgramSize(result.Executable, result.PackagePathMap)
924930
if err != nil {
925931
return err
926932
}

builder/sizes_test.go

Lines changed: 68 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package builder
22

33
import (
4+
"regexp"
45
"runtime"
56
"testing"
67
"time"
@@ -55,26 +56,7 @@ func TestBinarySize(t *testing.T) {
5556
t.Parallel()
5657

5758
// Build the binary.
58-
options := compileopts.Options{
59-
Target: tc.target,
60-
Opt: "z",
61-
Semaphore: sema,
62-
InterpTimeout: 60 * time.Second,
63-
Debug: true,
64-
VerifyIR: true,
65-
}
66-
target, err := compileopts.LoadTarget(&options)
67-
if err != nil {
68-
t.Fatal("could not load target:", err)
69-
}
70-
config := &compileopts.Config{
71-
Options: &options,
72-
Target: target,
73-
}
74-
result, err := Build(tc.path, "", t.TempDir(), config)
75-
if err != nil {
76-
t.Fatal("could not build:", err)
77-
}
59+
result := buildBinary(t, tc.target, tc.path)
7860

7961
// Check whether the size of the binary matches the expected size.
8062
sizes, err := loadProgramSize(result.Executable, nil)
@@ -90,3 +72,69 @@ func TestBinarySize(t *testing.T) {
9072
})
9173
}
9274
}
75+
76+
// Check that the -size=full flag attributes binary size to the correct package
77+
// without filesystem paths and things like that.
78+
func TestSizeFull(t *testing.T) {
79+
tests := []string{
80+
"microbit",
81+
"wasip1",
82+
}
83+
84+
libMatch := regexp.MustCompile(`^C [a-z -]+$`) // example: "C interrupt vector"
85+
pkgMatch := regexp.MustCompile(`^[a-z/]+$`) // example: "internal/task"
86+
87+
for _, target := range tests {
88+
target := target
89+
t.Run(target, func(t *testing.T) {
90+
t.Parallel()
91+
92+
// Build the binary.
93+
result := buildBinary(t, target, "examples/serial")
94+
95+
// Check whether the binary doesn't contain any unexpected package
96+
// names.
97+
sizes, err := loadProgramSize(result.Executable, result.PackagePathMap)
98+
if err != nil {
99+
t.Fatal("could not read program size:", err)
100+
}
101+
for _, pkg := range sizes.sortedPackageNames() {
102+
if pkg == "(padding)" || pkg == "(unknown)" {
103+
// TODO: correctly attribute all unknown binary size.
104+
continue
105+
}
106+
if libMatch.MatchString(pkg) {
107+
continue
108+
}
109+
if pkgMatch.MatchString(pkg) {
110+
continue
111+
}
112+
t.Error("unexpected package name in size output:", pkg)
113+
}
114+
})
115+
}
116+
}
117+
118+
func buildBinary(t *testing.T, targetString, pkgName string) BuildResult {
119+
options := compileopts.Options{
120+
Target: targetString,
121+
Opt: "z",
122+
Semaphore: sema,
123+
InterpTimeout: 60 * time.Second,
124+
Debug: true,
125+
VerifyIR: true,
126+
}
127+
target, err := compileopts.LoadTarget(&options)
128+
if err != nil {
129+
t.Fatal("could not load target:", err)
130+
}
131+
config := &compileopts.Config{
132+
Options: &options,
133+
Target: target,
134+
}
135+
result, err := Build(pkgName, "", t.TempDir(), config)
136+
if err != nil {
137+
t.Fatal("could not build:", err)
138+
}
139+
return result
140+
}

0 commit comments

Comments
 (0)