internal/buildbinary: add more tests/slightly modify bin.go
This change modifies bin.go to return a map from binary path -> import
path of the package the binary was built from. It also adds additional
testing for buildbinary.runBuild()
Change-Id: Iee132a2c84a0a8aea7f49e69aa9e7fa0c5ae9db1
Reviewed-on: https://go-review.googlesource.com/c/pkgsite-metrics/+/509356
Run-TryBot: Maceo Thompson <maceothompson@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
diff --git a/internal/buildbinary/bin.go b/internal/buildbinary/bin.go
index 3db7682..47ab1a4 100644
--- a/internal/buildbinary/bin.go
+++ b/internal/buildbinary/bin.go
@@ -5,6 +5,7 @@
package buildbinary
import (
+ "fmt"
"os/exec"
"path/filepath"
"strings"
@@ -16,30 +17,32 @@
// be aware if building others failed for some reason.
// FindAndBuildBinaries finds and builds all possible binaries from a given module.
-func FindAndBuildBinaries(modulePath string) (binaries []string, err error) {
+func FindAndBuildBinaries(modulePath string) (binaries map[string]string, err error) {
defer derrors.Wrap(&err, "FindAndBuildBinaries")
buildTargets, err := findBinaries(modulePath)
if err != nil {
return nil, err
}
+ binaries = make(map[string]string)
- for _, target := range buildTargets {
- path, err := runBuild(modulePath, target)
+ for i, target := range buildTargets {
+ path, err := runBuild(modulePath, target, i)
if err != nil {
return nil, err
}
- binaries = append(binaries, path)
+ binaries[path] = target
}
return binaries, nil
}
// runBuild takes a given module and import path and attempts to build a binary
-func runBuild(modulePath, importPath string) (binaryPath string, err error) {
- cmd := exec.Command("go", "build", "-C", modulePath, importPath)
+func runBuild(modulePath, importPath string, i int) (binaryPath string, err error) {
+ binName := fmt.Sprintf("bin%d", i)
+ cmd := exec.Command("go", "build", "-C", modulePath, "-o", binName, importPath)
if err = cmd.Run(); err != nil {
return "", err
}
- binaryPath = filepath.Join(modulePath, filepath.Base(importPath))
+ binaryPath = filepath.Join(modulePath, binName)
return binaryPath, nil
}
diff --git a/internal/buildbinary/bin_test.go b/internal/buildbinary/bin_test.go
index f1561c4..9ea9a9c 100644
--- a/internal/buildbinary/bin_test.go
+++ b/internal/buildbinary/bin_test.go
@@ -5,12 +5,18 @@
package buildbinary
import (
+ "os"
+ "path/filepath"
"testing"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
)
+const (
+ localTestData = "../testdata"
+)
+
func less(a, b string) bool {
return a < b
}
@@ -24,7 +30,7 @@
}{
{
name: "local test",
- dir: "../testdata/module",
+ dir: filepath.Join(localTestData, "module"),
want: []string{"golang.org/vuln"},
wantErr: false,
},
@@ -43,3 +49,44 @@
})
}
}
+
+func TestRunBuild(t *testing.T) {
+ tests := []struct {
+ name string
+ modulePath string
+ importPath string
+ want string
+ wantErr bool
+ }{
+ {
+ name: "local test",
+ modulePath: filepath.Join(localTestData, "module"),
+ importPath: "golang.org/vuln",
+ want: filepath.Join(localTestData, "module", "bin1"),
+ },
+ {
+ name: "multiple binaries",
+ modulePath: filepath.Join(localTestData, "multipleBinModule"),
+ importPath: "example.com/test/multipleBinModule",
+ want: filepath.Join(localTestData, "multipleBinModule", "bin1"),
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ got, err := runBuild(tt.modulePath, tt.importPath, 1)
+ defer os.Remove(got)
+ if (err != nil) != tt.wantErr {
+ t.Errorf("runBuild() error = %v, wantErr %v", err, tt.wantErr)
+ return
+ }
+
+ if diff := cmp.Diff(tt.want, got); diff != "" {
+ t.Errorf("mismatch (-want, +got):%s", diff)
+ }
+ _, err = os.Stat(got)
+ if err != nil && os.IsNotExist(err) {
+ t.Errorf("runBuild did not produce the expected binary")
+ }
+ })
+ }
+}
diff --git a/internal/testdata/multipleBinModule/go.mod b/internal/testdata/multipleBinModule/go.mod
new file mode 100644
index 0000000..b96158c
--- /dev/null
+++ b/internal/testdata/multipleBinModule/go.mod
@@ -0,0 +1,3 @@
+module example.com/test
+
+go 1.20
\ No newline at end of file
diff --git a/internal/testdata/multipleBinModule/main.go b/internal/testdata/multipleBinModule/main.go
new file mode 100644
index 0000000..91e7378
--- /dev/null
+++ b/internal/testdata/multipleBinModule/main.go
@@ -0,0 +1,7 @@
+package main
+
+import "fmt"
+
+func main() {
+ fmt.Println("Hello World")
+}
diff --git a/internal/testdata/multipleBinModule/multipleBinModule/main.go b/internal/testdata/multipleBinModule/multipleBinModule/main.go
new file mode 100644
index 0000000..80027d4
--- /dev/null
+++ b/internal/testdata/multipleBinModule/multipleBinModule/main.go
@@ -0,0 +1,11 @@
+package main
+
+import (
+ "fmt"
+ "math"
+)
+
+func main() {
+ x := math.Abs(-3)
+ fmt.Print(x)
+}
diff --git a/internal/testdata/multipleBinModule/p1/main.go b/internal/testdata/multipleBinModule/p1/main.go
new file mode 100644
index 0000000..4b0c0e7
--- /dev/null
+++ b/internal/testdata/multipleBinModule/p1/main.go
@@ -0,0 +1,14 @@
+package main
+
+import (
+ "fmt"
+ "strings"
+)
+
+// This package doesn't use any of the code in M, but instead
+// is used to build something or as a helper
+
+func main() {
+ s := strings.Join([]string{"One", "Two"}, " ")
+ fmt.Println(s)
+}
diff --git a/internal/testdata/multipleBinModule/p2/file.go b/internal/testdata/multipleBinModule/p2/file.go
new file mode 100644
index 0000000..ad4f7c4
--- /dev/null
+++ b/internal/testdata/multipleBinModule/p2/file.go
@@ -0,0 +1,7 @@
+package p2
+
+import "fmt"
+
+func DoSmthn() {
+ fmt.Print("test")
+}