Files
privatae-bastion/client-go/goosbuild_test.go
T
Privatae d62da8adb4
ci / personal-data (push) Successful in 4s
ci / fuzz (push) Successful in 2m44s
ci / test (push) Successful in 2m11s
bastion 0.54.0
2026-10-21 22:29:10 +00:00

105 lines
3.0 KiB
Go

package main
import (
"go/ast"
"go/build"
"go/parser"
"go/token"
"os"
"sort"
"strings"
"testing"
)
// EVERY PLATFORM FUNCTION EXISTS ON EVERY TARGET THAT BUILDS THIS PACKAGE.
//
// A function with one file per platform (contextPeerUID in contextsock_linux.go
// and contextsock_darwin.go) and a caller in a file every unix builds
// (contextsock_unix.go) leaves any other unix with an undefined name, and
// nothing in CI cross-builds one: `GOOS=freebsd go build` failed that way.
// The release targets are linux, darwin and windows (deploy/build.sh);
// freebsd and openbsd are not released, but they build, with what has no
// implementation there refusing (contextsock_other.go and the other
// *_other.go files).
//
// This asks the toolchain which files each target compiles (go/build's
// MatchFile) and checks that every package function called from those files
// is declared in them. It is not a type check, and it does not compile; it
// catches the missing-platform-file mistake, which is the one that happened,
// on the platform the tests already run on.
func TestEveryCalledPlatformFunctionIsDeclaredOnEveryTarget(t *testing.T) {
entries, err := os.ReadDir(".")
if err != nil {
t.Fatal(err)
}
type parsed struct {
name string
file *ast.File
}
var files []parsed
declaredAnywhere := map[string]bool{}
fset := token.NewFileSet()
for _, e := range entries {
n := e.Name()
if e.IsDir() || !strings.HasSuffix(n, ".go") || strings.HasSuffix(n, "_test.go") {
continue
}
f, err := parser.ParseFile(fset, n, nil, parser.SkipObjectResolution)
if err != nil {
t.Fatalf("%s: %v", n, err)
}
files = append(files, parsed{n, f})
for _, d := range f.Decls {
if fd, ok := d.(*ast.FuncDecl); ok && fd.Recv == nil {
declaredAnywhere[fd.Name.Name] = true
}
}
}
if len(files) < 50 {
t.Fatalf("parsed only %d files; is the test running in the package directory?", len(files))
}
for _, goos := range []string{"linux", "darwin", "windows", "freebsd", "openbsd"} {
ctx := build.Default
ctx.GOOS = goos
ctx.CgoEnabled = false
declared := map[string]bool{}
var matched []parsed
for _, p := range files {
ok, err := ctx.MatchFile(".", p.name)
if err != nil {
t.Fatalf("%s: %v", p.name, err)
}
if !ok {
continue
}
matched = append(matched, p)
for _, d := range p.file.Decls {
if fd, ok := d.(*ast.FuncDecl); ok && fd.Recv == nil {
declared[fd.Name.Name] = true
}
}
}
missing := map[string]string{}
for _, p := range matched {
ast.Inspect(p.file, func(x ast.Node) bool {
c, ok := x.(*ast.CallExpr)
if !ok {
return true
}
if id, ok := c.Fun.(*ast.Ident); ok && declaredAnywhere[id.Name] && !declared[id.Name] {
missing[id.Name] = p.name
}
return true
})
}
var out []string
for fn, where := range missing {
out = append(out, fn+" (called in "+where+")")
}
sort.Strings(out)
if len(out) > 0 {
t.Errorf("GOOS=%s: called but not declared for this target: %s", goos, strings.Join(out, ", "))
}
}
}