Replace the current e2e script with a test suite running e2e tests. (#1514)

* Replace the current e2e script with a test suite running e2e tests.

* Add a build tag to skip e2e while running unit tests.
We want e2e tests to be skipped while running normal unit tests.
This commit is contained in:
Federico Paolinelli
2020-02-20 00:38:08 +01:00
committed by GitHub
parent 4530a58359
commit 27f3683416
6 changed files with 247 additions and 71 deletions
+144
View File
@@ -0,0 +1,144 @@
// +build e2etests
package e2etests
import (
"context"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"os"
"os/exec"
"path/filepath"
"testing"
"github.com/gobuffalo/envy"
"github.com/stretchr/testify/suite"
)
type E2eSuite struct {
suite.Suite
goBinaryPath string
env []string
goPath string
sampleRepoPath string
stopAthens context.CancelFunc
}
type catalogRes struct {
Modules []struct {
Module string `json:"module"`
Version string `json:"version"`
} `json:"modules"`
}
func (m *E2eSuite) SetupSuite() {
var err error
m.goPath, err = ioutil.TempDir("/tmp", "gopath")
if err != nil {
m.Fail("Failed to make temp dir", err)
}
m.sampleRepoPath, err = ioutil.TempDir("/tmp", "repopath")
if err != nil {
m.Fail("Failed to make temp dir for sample repo", err)
}
m.goBinaryPath = envy.Get("GO_BINARY_PATH", "go")
athensBin, err := buildAthens(m.goBinaryPath, m.goPath, m.env)
if err != nil {
m.Fail("Failed to build athens ", err)
}
stopAthens() // in case a dangling instance was around.
// ignoring error as if no athens is running it fails.
ctx := context.Background()
ctx, m.stopAthens = context.WithCancel(ctx)
runAthensAndWait(ctx, athensBin, m.getEnv())
setupTestRepo(m.sampleRepoPath, "https://github.com/athens-artifacts/happy-path.git")
}
func (m *E2eSuite) TearDownSuite() {
m.stopAthens()
chmodR(m.goPath, 0777)
os.RemoveAll(m.goPath)
chmodR(m.sampleRepoPath, 0777)
os.RemoveAll(m.sampleRepoPath)
}
func TestE2E(t *testing.T) {
suite.Run(t, &E2eSuite{})
}
func (m *E2eSuite) SetupTest() {
chmodR(m.goPath, 0777)
err := cleanGoCache(m.getEnv())
if err != nil {
m.Fail("Failed to clear go cache", err)
}
}
func (m *E2eSuite) TestNoGoProxy() {
cmd := exec.Command("go", "run", ".")
cmd.Env = m.env
cmd.Dir = m.sampleRepoPath
err := cmd.Run()
if err != nil {
m.Fail("go run failed on test repo", err)
}
}
func (m *E2eSuite) TestGoProxy() {
cmd := exec.Command("go", "run", ".")
cmd.Env = m.getEnvGoProxy(m.goPath)
cmd.Dir = m.sampleRepoPath
err := cmd.Run()
if err != nil {
m.Fail("go run failed on test repo", err)
}
resp, err := http.Get("http://localhost:3000/catalog")
if err != nil {
m.Fail("failed to read catalog", err)
}
var catalog catalogRes
err = json.NewDecoder(resp.Body).Decode(&catalog)
if err != nil {
m.Fail("failed to decode catalog res", err)
}
m.Assert().Equal(len(catalog.Modules), 1)
m.Assert().Equal(catalog.Modules[0].Module, "github.com/athens-artifacts/no-tags")
}
func (m *E2eSuite) TestWrongGoProxy() {
cmd := exec.Command("go", "run", ".")
cmd.Env = m.getEnvWrongGoProxy(m.goPath)
cmd.Dir = m.sampleRepoPath
err := cmd.Run()
m.Assert().NotNil(err, "Wrong proxy should fail")
}
func (m *E2eSuite) getEnv() []string {
res := []string{
fmt.Sprintf("GOPATH=%s", m.goPath),
"GO111MODULE=on",
fmt.Sprintf("PATH=%s", os.Getenv("PATH")),
fmt.Sprintf("GOCACHE=%s", filepath.Join(m.goPath, "cache")),
}
return res
}
func (m *E2eSuite) getEnvGoProxy(gopath string) []string {
res := m.getEnv()
res = append(res, "GOPROXY=http://localhost:3000")
return res
}
func (m *E2eSuite) getEnvWrongGoProxy(gopath string) []string {
res := m.getEnv()
res = append(res, "GOPROXY=http://localhost:3001")
return res
}
+39
View File
@@ -0,0 +1,39 @@
// +build e2etests
package e2etests
import (
"fmt"
"os"
"os/exec"
"path/filepath"
)
func setupTestRepo(repoPath, repoURL string) {
os.RemoveAll(repoPath)
cmd := exec.Command("git",
"clone",
repoURL,
repoPath)
cmd.Run()
}
func chmodR(path string, mode os.FileMode) error {
return filepath.Walk(path, func(name string, info os.FileInfo, err error) error {
if err == nil {
os.Chmod(name, mode)
}
return err
})
}
func cleanGoCache(env []string) error {
cmd := exec.Command("go", "clean", "--modcache")
cmd.Env = env
output, err := cmd.CombinedOutput()
if err != nil {
return fmt.Errorf("Failed to clear go cache: %v - %s", err, string(output))
}
return nil
}
+61
View File
@@ -0,0 +1,61 @@
// +build e2etests
package e2etests
import (
"context"
"fmt"
"net/http"
"os/exec"
"path"
"path/filepath"
"time"
)
func buildAthens(goBin, destPath string, env []string) (string, error) {
target := path.Join(destPath, "athens-proxy")
binFolder, err := filepath.Abs("../cmd/proxy")
if err != nil {
return "", fmt.Errorf("Failed to get athens source path %v", err)
}
cmd := exec.Command(goBin, "build", "-o", target, binFolder)
cmd.Env = env
output, err := cmd.CombinedOutput()
if err != nil {
return "", fmt.Errorf("Failed to build athens: %v - %s", err, string(output))
}
return target, nil
}
func stopAthens() error {
cmd := exec.Command("pkill", "athens-proxy")
output, err := cmd.CombinedOutput()
if err != nil {
return fmt.Errorf("Failed to stop athens: %v - %s", err, string(output))
}
return err
}
func runAthensAndWait(ctx context.Context, athensBin string, env []string) error {
cmd := exec.CommandContext(ctx, athensBin)
cmd.Env = env
cmd.Start()
ticker := time.NewTicker(time.Second)
timeout := time.After(20 * time.Second)
defer ticker.Stop()
for {
select {
case <-ticker.C:
resp, _ := http.Get("http://localhost:3000/readyz")
if resp.StatusCode == 200 {
return nil
}
case <-timeout:
return fmt.Errorf("Failed to run athens")
}
}
}