162 lines
3.5 KiB
Go
162 lines
3.5 KiB
Go
package thirdparty
|
|
|
|
import (
|
|
"flag"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"runtime"
|
|
"testing"
|
|
|
|
"github.com/mmcloughlin/avo/internal/test"
|
|
)
|
|
|
|
// Custom flags.
|
|
var (
|
|
pkgsfilename = flag.String("pkgs", "", "packages configuration")
|
|
preserve = flag.Bool("preserve", false, "preserve working directories")
|
|
latest = flag.Bool("latest", false, "use latest versions of each package")
|
|
)
|
|
|
|
// TestPackages runs integration tests on all packages specified by packages
|
|
// file given on the command line.
|
|
func TestPackages(t *testing.T) {
|
|
// Load packages.
|
|
if *pkgsfilename == "" {
|
|
t.Skip("no packages specified")
|
|
}
|
|
|
|
pkgs, err := LoadPackagesFile(*pkgsfilename)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
for _, pkg := range pkgs {
|
|
pkg := pkg // scopelint
|
|
t.Run(pkg.Name(), func(t *testing.T) {
|
|
dir, clean := test.TempDir(t)
|
|
if !*preserve {
|
|
defer clean()
|
|
} else {
|
|
t.Logf("working directory: %s", dir)
|
|
}
|
|
pt := PackageTest{
|
|
T: t,
|
|
Package: pkg,
|
|
WorkDir: dir,
|
|
Latest: *latest,
|
|
}
|
|
pt.Run()
|
|
})
|
|
}
|
|
}
|
|
|
|
// PackageTest executes an integration test based on a given third-party package.
|
|
type PackageTest struct {
|
|
*testing.T
|
|
Package
|
|
|
|
WorkDir string // working directory for the test
|
|
Latest bool // use latest version of the package
|
|
|
|
repopath string // path the repo is cloned to
|
|
}
|
|
|
|
// Run the test.
|
|
func (t *PackageTest) Run() {
|
|
t.checkout()
|
|
t.modinit()
|
|
t.replaceavo()
|
|
t.diff()
|
|
t.generate()
|
|
t.diff()
|
|
t.test()
|
|
}
|
|
|
|
// checkout the code at the specified version.
|
|
func (t *PackageTest) checkout() {
|
|
// Clone repo.
|
|
dst := filepath.Join(t.WorkDir, t.Name())
|
|
t.git("clone", "--quiet", t.CloneURL(), dst)
|
|
t.repopath = dst
|
|
|
|
// Checkout specific version.
|
|
if t.Latest {
|
|
t.Log("using latest version")
|
|
return
|
|
}
|
|
t.git("-C", t.repopath, "checkout", "--quiet", t.Version)
|
|
}
|
|
|
|
// modinit initializes the repo as a go module if it isn't one already.
|
|
func (t *PackageTest) modinit() {
|
|
// Check if module path already exists.
|
|
gomod := filepath.Join(t.repopath, "go.mod")
|
|
if _, err := os.Stat(gomod); err == nil {
|
|
t.Logf("already a module")
|
|
return
|
|
}
|
|
|
|
// Initialize the module.
|
|
t.gotool("mod", "init", t.ImportPath)
|
|
}
|
|
|
|
// replaceavo points all avo dependencies to the local version.
|
|
func (t *PackageTest) replaceavo() {
|
|
// Determine the path to avo.
|
|
_, self, _, ok := runtime.Caller(1)
|
|
if !ok {
|
|
t.Fatal("failed to determine path to avo")
|
|
}
|
|
avodir := filepath.Join(filepath.Dir(self), "..", "..")
|
|
|
|
// Edit all go.mod files in the repo.
|
|
err := filepath.Walk(t.repopath, func(path string, info os.FileInfo, err error) error {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if filepath.Base(path) != "go.mod" {
|
|
return nil
|
|
}
|
|
t.gotool("mod", "edit", "-replace=github.com/mmcloughlin/avo="+avodir, path)
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
// generate runs generate commands.
|
|
func (t *PackageTest) generate() {
|
|
if len(t.Generate) == 0 {
|
|
t.Fatal("no commands specified")
|
|
}
|
|
for _, args := range t.Generate {
|
|
cmd := exec.Command(args[0], args[1:]...)
|
|
cmd.Dir = filepath.Join(t.repopath, t.Dir)
|
|
test.ExecCommand(t.T, cmd)
|
|
}
|
|
}
|
|
|
|
// diff runs git diff on the repository.
|
|
func (t *PackageTest) diff() {
|
|
t.git("-C", t.repopath, "diff")
|
|
}
|
|
|
|
// test runs go test.
|
|
func (t *PackageTest) test() {
|
|
t.gotool("test", "./...")
|
|
}
|
|
|
|
// git runs a git command.
|
|
func (t *PackageTest) git(arg ...string) {
|
|
test.Exec(t.T, "git", arg...)
|
|
}
|
|
|
|
// gotool runs a go command.
|
|
func (t *PackageTest) gotool(arg ...string) {
|
|
cmd := exec.Command(test.GoTool(), arg...)
|
|
cmd.Dir = t.repopath
|
|
test.ExecCommand(t.T, cmd)
|
|
}
|