mirror of
https://github.com/gomods/athens
synced 2026-02-03 12:10:32 +00:00
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:
committed by
GitHub
parent
4530a58359
commit
27f3683416
@@ -63,7 +63,7 @@ test-unit-docker: ## run unit tests with docker
|
|||||||
|
|
||||||
.PHONY: test-e2e
|
.PHONY: test-e2e
|
||||||
test-e2e:
|
test-e2e:
|
||||||
./scripts/test_e2e.sh
|
cd e2etests && go test --tags e2etests
|
||||||
|
|
||||||
.PHONY: test-e2e-docker
|
.PHONY: test-e2e-docker
|
||||||
test-e2e-docker:
|
test-e2e-docker:
|
||||||
|
|||||||
+2
-1
@@ -11,4 +11,5 @@ environment:
|
|||||||
stack: go 1.13
|
stack: go 1.13
|
||||||
|
|
||||||
test_script:
|
test_script:
|
||||||
- go test ./...
|
- go test ./...
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# test_e2e.sh
|
|
||||||
# Execute end-to-end (e2e) tests to verify that everything is working right
|
|
||||||
# from the end user perspective
|
|
||||||
set -xeuo pipefail
|
|
||||||
|
|
||||||
REPO_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )/.."
|
|
||||||
|
|
||||||
OGOPATH=${GOPATH:-}
|
|
||||||
OGO111MODULE=${GO111MODULE:-}
|
|
||||||
OGOPROXY=${GOPROXY:-}
|
|
||||||
export GO_BINARY_PATH=${GO_BINARY_PATH:-go}
|
|
||||||
TMPDIR=$(mktemp -d)
|
|
||||||
export GOPATH=$TMPDIR
|
|
||||||
GOMOD_CACHE=$TMPDIR/pkg/mod
|
|
||||||
export PATH=${REPO_DIR}/bin:${PATH}
|
|
||||||
|
|
||||||
clearGoModCache () {
|
|
||||||
chmod -R 0770 ${GOMOD_CACHE}
|
|
||||||
rm -fr ${GOMOD_CACHE}
|
|
||||||
}
|
|
||||||
|
|
||||||
teardown () {
|
|
||||||
# Cleanup after our tests
|
|
||||||
[[ -z "${OGOPATH}" ]] && unset GOPATH || export GOPATH=$OGOPATH
|
|
||||||
[[ -z "${OGO111MODULE}" ]] && unset GO111MODULE || export GO111MODULE=$OGO111MODULE
|
|
||||||
[[ -z "${OGOPROXY}" ]] && unset GOPROXY || export GOPROXY=$OGOPROXY
|
|
||||||
|
|
||||||
clearGoModCache
|
|
||||||
pkill athens-proxy || true
|
|
||||||
rm $REPO_DIR/cmd/proxy/athens-proxy || true
|
|
||||||
rm -fr ${TMPDIR}
|
|
||||||
popd 2> /dev/null || true
|
|
||||||
}
|
|
||||||
trap teardown EXIT
|
|
||||||
|
|
||||||
export GO111MODULE=on
|
|
||||||
|
|
||||||
# Start the proxy in the background and wait for it to be ready
|
|
||||||
cd $REPO_DIR/cmd/proxy
|
|
||||||
pkill athens-proxy || true # cleanup proxy if it is running
|
|
||||||
go build -o athens-proxy && ./athens-proxy &
|
|
||||||
while [[ "$(curl -s -o /dev/null -w ''%{http_code}'' localhost:3000/readyz)" != "200" ]]; do sleep 1; done
|
|
||||||
|
|
||||||
# Clone our test repo
|
|
||||||
TEST_SOURCE=${TMPDIR}/happy-path
|
|
||||||
rm -fr ${TEST_SOURCE} 2> /dev/null || true
|
|
||||||
git clone https://github.com/athens-artifacts/happy-path.git ${TEST_SOURCE}
|
|
||||||
pushd ${TEST_SOURCE}
|
|
||||||
|
|
||||||
# Make sure that our test repo works without the GOPROXY first
|
|
||||||
unset GOPROXY
|
|
||||||
$GO_BINARY_PATH run .
|
|
||||||
|
|
||||||
# clear cache so that go uses the proxy
|
|
||||||
clearGoModCache
|
|
||||||
|
|
||||||
# Verify that the test works against the proxy
|
|
||||||
export GOPROXY=http://localhost:3000
|
|
||||||
$GO_BINARY_PATH run .
|
|
||||||
|
|
||||||
CATALOG_RES=$(curl localhost:3000/catalog)
|
|
||||||
CATALOG_EXPECTED='{"modules":[{"module":"github.com/athens-artifacts/no-tags","version":"v0.0.0-20180803171426-1a540c5d67ab"}]}'
|
|
||||||
|
|
||||||
if [[ "$CATALOG_RES" != "$CATALOG_EXPECTED" ]]; then
|
|
||||||
echo ERROR: catalog endpoint failed
|
|
||||||
exit 1 # terminate and indicate error
|
|
||||||
fi
|
|
||||||
Reference in New Issue
Block a user