Skip to content

Commit

Permalink
\gomods#1500 - prototype for using testcontainers-go for dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
ClaytonNorthey92 committed Feb 16, 2020
1 parent 4530a58 commit 503df2d
Show file tree
Hide file tree
Showing 8 changed files with 381 additions and 47 deletions.
21 changes: 0 additions & 21 deletions .drone.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,6 @@ steps:
- GOPATH=~/emptygopath GOPROXY=http://localhost:3000 go build
environment:
GO111MODULE: on
ATHENS_MONGO_STORAGE_URL: mongodb://mongo:27017
ATHENS_MINIO_ENDPOINT: minio:9000
REDIS_TEST_ENDPOINT: redis:6379
GCS_SERVICE_ACCOUNT:
from_secret: GCS_SERVICE_ACCOUNT
GCS_PROJECT_ID:
Expand Down Expand Up @@ -136,24 +133,6 @@ steps:

# Here we can add any backend storage that can be tested.
services:
- name: mongo
image: mongo
ports:
- 27017
- name: minio
image: minio/minio:latest
command:
- server
- /data
ports:
- 9000
environment:
MINIO_ACCESS_KEY: minio
MINIO_SECRET_KEY: minio123
- name: redis
image: redis
ports:
- 6379
- name: athens-proxy
image: gomods/athens:canary
pull: always
Expand Down
175 changes: 175 additions & 0 deletions e2etests/all_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
// +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"
"github.com/testcontainers/testcontainers-go"
)

type E2eSuite struct {
suite.Suite
goBinaryPath string
env []string
tmpDir string
sampleRepoPath string
stopAthens context.CancelFunc
athensContainer testcontainers.Container
}

type catalogRes struct {
Modules []struct {
Module string `json:"module"`
Version string `json:"version"`
} `json:"modules"`
}

func (m *E2eSuite) SetupSuite() {
var err error
m.tmpDir, 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.tmpDir, m.env)
if err != nil {
m.Fail("Failed to build athens ", err)
}
// ignoring error as if no athens is running it fails.

ctx := context.Background()
ctx, m.stopAthens = context.WithCancel(ctx)

if m.athensContainer != nil {
err = stopAthens(ctx, m.athensContainer)
if err != nil {
m.Fail(err.Error())
}
}

c, err := runAthensAndWait(ctx, athensBin, m.getEnv())
if err != nil {
m.Fail(err.Error())
}

m.athensContainer = c

setupTestRepo(m.sampleRepoPath, "https://github.com/athens-artifacts/happy-path.git")
}

func (m *E2eSuite) TearDownSuite() {
if m.athensContainer == nil {
err := stopAthens(context.Background(), m.athensContainer)
if err != nil {
m.Fail(err.Error())
}
}
m.stopAthens()
}

func TestE2E(t *testing.T) {
suite.Run(t, &E2eSuite{})
}

func (m *E2eSuite) SetupTest() {
chmodR(m.tmpDir, 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() {

// TESTCONTAINERS - sub for docker container
ep, err := m.athensContainer.Endpoint(context.Background(), "http")
if err != nil {
m.Fail(err.Error())
}

cmd := exec.Command("go", "run", ".")
cmd.Env = m.getEnvGoProxy(ep)
cmd.Dir = m.sampleRepoPath
err = cmd.Run()

if err != nil {
m.Fail("go run failed on test repo", err)
}

resp, err := http.Get(fmt.Sprintf("%s/catalog", ep))
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.tmpDir)
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.tmpDir),
"GO111MODULE=on",
fmt.Sprintf("PATH=%s", os.Getenv("PATH")),
fmt.Sprintf("GOCACHE=%s", filepath.Join(m.tmpDir, "cache")),
}
return res
}

func (m *E2eSuite) getEnvGoProxy(goproxyOverride string) []string {
goProxy := "http://localhost:3000"
if goproxyOverride != "" {
goProxy = goproxyOverride
}

res := m.getEnv()
res = append(res, fmt.Sprintf("GOPROXY=%s", goProxy))
return res
}

func (m *E2eSuite) getEnvWrongGoProxy(gopath string) []string {
res := m.getEnv()
res = append(res, "GOPROXY=http://localhost:3001")
return res
}
63 changes: 63 additions & 0 deletions e2etests/run_athens.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// +build e2etests

package e2etests

import (
"context"
"fmt"
"os/exec"
"path"
"path/filepath"
"time"

testcontainers "github.com/testcontainers/testcontainers-go"
"github.com/testcontainers/testcontainers-go/wait"
)

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(ctx context.Context, athensContainer testcontainers.Container) error {
err := athensContainer.Terminate(ctx)
if err != nil {
return err
}

return nil
}

func runAthensAndWait(ctx context.Context, athensBin string, env []string) (testcontainers.Container, error) {
req := testcontainers.ContainerRequest{
FromDockerfile: testcontainers.FromDockerfile{
Dockerfile: "cmd/proxy/Dockerfile",
Context: "./..",
},
ExposedPorts: []string{"3000/tcp"},
WaitingFor: wait.ForLog("Starting application at port :3000").WithStartupTimeout(time.Minute * 2),
Cmd: []string{"athens-proxy", "-config_file=/config/config.toml"},
AutoRemove: true,
}

c, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
ContainerRequest: req,
Started: true,
})
if err != nil {
return nil, fmt.Errorf("Failed to run athens: %s", err)
}

return c, nil
}
5 changes: 2 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ require (
github.com/fatih/color v1.7.0
github.com/go-playground/locales v0.12.1 // indirect
github.com/go-playground/universal-translator v0.16.0 // indirect
github.com/go-redis/redis v6.15.2+incompatible
github.com/go-redis/redis v6.15.7+incompatible
github.com/gobuffalo/envy v1.6.7
github.com/gobuffalo/httptest v1.0.4
github.com/golang/snappy v0.0.1 // indirect
Expand All @@ -34,12 +34,11 @@ require (
github.com/minio/minio-go/v6 v6.0.43
github.com/mitchellh/go-homedir v1.1.0
github.com/philhofer/fwd v1.0.0 // indirect
github.com/pkg/errors v0.8.1 // indirect
github.com/sirupsen/logrus v1.4.2
github.com/spf13/afero v1.1.2
github.com/spf13/pflag v1.0.3 // indirect
github.com/stretchr/testify v1.3.0
github.com/technosophos/moniker v0.0.0-20180509230615-a5dbd03a2245
github.com/testcontainers/testcontainers-go v0.2.0
github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51 // indirect
github.com/tinylib/msgp v1.0.2 // indirect
github.com/unrolled/secure v0.0.0-20181221173256-0d6b5bb13069
Expand Down
Loading

0 comments on commit 503df2d

Please sign in to comment.