feat: add size level aggregation
This commit is contained in:
156
internal/build/size_report_test.go
Normal file
156
internal/build/size_report_test.go
Normal file
@@ -0,0 +1,156 @@
|
||||
//go:build !llgo
|
||||
|
||||
package build
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/tools/go/packages"
|
||||
)
|
||||
|
||||
const sampleReadelf = `Sections [
|
||||
Section {
|
||||
Index: 0
|
||||
Name: __text (5F)
|
||||
Segment: __TEXT (5F)
|
||||
Address: 0x1000
|
||||
Size: 0x20
|
||||
}
|
||||
Section {
|
||||
Index: 1
|
||||
Name: __data
|
||||
Segment: __DATA
|
||||
Address: 0x2000
|
||||
Size: 0x10
|
||||
}
|
||||
Section {
|
||||
Index: 2
|
||||
Name: __common
|
||||
Segment: __DATA
|
||||
Address: 0x3000
|
||||
Size: 0x8
|
||||
}
|
||||
]
|
||||
Symbols [
|
||||
Symbol {
|
||||
Name: _main.main
|
||||
Section: __text (0x1)
|
||||
Value: 0x1000
|
||||
}
|
||||
Symbol {
|
||||
Name: _runtime.init
|
||||
Section: __text (0x1)
|
||||
Value: 0x1010
|
||||
}
|
||||
Symbol {
|
||||
Name: _main.dataVar
|
||||
Section: __data (0x2)
|
||||
Value: 0x2000
|
||||
}
|
||||
Symbol {
|
||||
Name: _runtime.dataVar
|
||||
Section: __data (0x2)
|
||||
Value: 0x2008
|
||||
}
|
||||
Symbol {
|
||||
Name: _runtime.bssVar
|
||||
Section: __common (0x3)
|
||||
Value: 0x3000
|
||||
}
|
||||
]
|
||||
`
|
||||
|
||||
func TestParseReadelfOutput(t *testing.T) {
|
||||
parsed, err := parseReadelfOutput(strings.NewReader(sampleReadelf))
|
||||
if err != nil {
|
||||
t.Fatalf("parseReadelfOutput: %v", err)
|
||||
}
|
||||
report := buildSizeReport("fake.bin", parsed, nil, "")
|
||||
if report == nil {
|
||||
t.Fatal("expected report")
|
||||
}
|
||||
modules := report.Modules
|
||||
if len(modules) == 0 {
|
||||
t.Fatal("expected modules in report")
|
||||
}
|
||||
mainMod, ok := modules["main"]
|
||||
if !ok {
|
||||
t.Fatalf("expected main module, got %v", modules)
|
||||
}
|
||||
if mainMod.Code != 0x10 {
|
||||
t.Fatalf("unexpected main code size: %d", mainMod.Code)
|
||||
}
|
||||
if mainMod.Data != 0x8 {
|
||||
t.Fatalf("unexpected main data size: %d", mainMod.Data)
|
||||
}
|
||||
runtimeMod := modules["runtime"]
|
||||
if runtimeMod.Code != 0x10 {
|
||||
t.Fatalf("unexpected runtime code size: %d", runtimeMod.Code)
|
||||
}
|
||||
if runtimeMod.Data != 0x8 {
|
||||
t.Fatalf("unexpected runtime data size: %d", runtimeMod.Data)
|
||||
}
|
||||
if runtimeMod.BSS != 0x8 {
|
||||
t.Fatalf("unexpected runtime bss size: %d", runtimeMod.BSS)
|
||||
}
|
||||
if report.Total.Flash() != 0x10+0x10+0x8+0x8 {
|
||||
t.Fatalf("unexpected flash total: %d", report.Total.Flash())
|
||||
}
|
||||
if report.Total.RAM() != 0x8+0x8+0x8 {
|
||||
t.Fatalf("unexpected ram total: %d", report.Total.RAM())
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseReadelfRealBinary(t *testing.T) {
|
||||
path := os.Getenv("LLGO_SIZE_REPORT_BIN")
|
||||
if path == "" {
|
||||
return
|
||||
}
|
||||
absPath, err := filepath.Abs(path)
|
||||
if err != nil {
|
||||
t.Fatalf("abs path: %v", err)
|
||||
}
|
||||
cmd := exec.Command("llvm-readelf", "--all", absPath)
|
||||
var buf bytes.Buffer
|
||||
cmd.Stdout = &buf
|
||||
cmd.Stderr = os.Stderr
|
||||
if err := cmd.Run(); err != nil {
|
||||
t.Fatalf("llvm-readelf failed: %v", err)
|
||||
}
|
||||
parsed, err := parseReadelfOutput(bytes.NewReader(buf.Bytes()))
|
||||
if err != nil {
|
||||
t.Fatalf("parseReadelfOutput(real): %v", err)
|
||||
}
|
||||
if len(parsed.sections) == 0 {
|
||||
t.Fatal("expected sections in real binary")
|
||||
}
|
||||
report := buildSizeReport(absPath, parsed, nil, "")
|
||||
if len(report.Modules) == 0 {
|
||||
t.Fatalf("expected modules for %s", path)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNameResolver(t *testing.T) {
|
||||
pkgs := []Package{
|
||||
&aPackage{Package: &packages.Package{PkgPath: "github.com/foo/bar", Module: &packages.Module{Path: "github.com/foo"}}},
|
||||
}
|
||||
symbol := "_github.com/foo/bar.Type.method"
|
||||
if got := newNameResolver("package", pkgs).resolve(symbol); got != "github.com/foo/bar" {
|
||||
t.Fatalf("package level want github.com/foo/bar, got %q", got)
|
||||
}
|
||||
if got := newNameResolver("module", pkgs).resolve(symbol); got != "github.com/foo" {
|
||||
t.Fatalf("module level want github.com/foo, got %q", got)
|
||||
}
|
||||
full := newNameResolver("full", pkgs).resolve(symbol)
|
||||
if full != "github.com/foo/bar.Type" {
|
||||
t.Fatalf("full level unexpected: %q", full)
|
||||
}
|
||||
if got := newNameResolver("package", nil).resolve("_llgo_stub.foo"); got != "llgo-stubs" {
|
||||
t.Fatalf("llgo default grouping failed: %q", got)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user