Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactoring the model package #239

Merged
merged 12 commits into from
Jul 27, 2020
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
builds/*
dist/*
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ matrix:
# Build
- make build
# Test
- go test -v
- go test -v ./...

- name: Linux build w/ tests
os: linux
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ build:
docker run -v $(DIR):/data pygmy-go cp pygmy-go-darwin /data/builds/.
docker run -v $(DIR):/data pygmy-go cp pygmy-go.exe /data/builds/.
@echo "Done"
@echo "Enjoy using pygmy-go binaries in $(DIR)/data/build directory."
@echo "Enjoy using pygmy-go binaries in $(DIR)/build directory."

clean:
docker image rm -f pygmy-go
Expand Down
26 changes: 25 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,33 @@ Content-Type: text/html
```

Thanks for testing, please post issues and successes in the queue.

## Local development

To run full regression tests locally, you can follow this process if you have `cmake`, `git` and `go` installed. This
will prevent a significant amount of build failures and problems after committing.

It will use `dind` and your local daemon to walk through several tests which should pass.

1. First clone the project:
```
git clone https://github.com/fubarhouse/pygmy-go.git pygmy-go && cd pygmy-go
```
2. Perform any updates as required.
3. Clean the environment.
```
go run main.go clean
```
4. Build the project.
```
make
```
5. Test the project prior to commiting.
```
go test -v
```

## Releasing

We use GitHub Actions for simulating the automated release tagging locally. Using [Act](https://github.com/nektos/act) locally, you can simulate this process and have the same build artifacts in your `dist` folder.

This process will inject the appropriate values into the version logic. To start the process, just run `act`!
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ require (
github.com/docker/go-units v0.4.0 // indirect
github.com/fsnotify/fsnotify v1.4.9 // indirect
github.com/ghodss/yaml v1.0.0
github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 // indirect
github.com/gorilla/mux v1.7.4 // indirect
github.com/imdario/mergo v0.3.9
github.com/mitchellh/go-homedir v1.1.0
Expand All @@ -20,6 +21,7 @@ require (
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.0.1 // indirect
github.com/pelletier/go-toml v1.7.0 // indirect
github.com/smartystreets/assertions v1.1.1 // indirect
github.com/smartystreets/goconvey v1.6.4
github.com/spf13/afero v1.2.2 // indirect
github.com/spf13/cast v1.3.1 // indirect
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 h1:l5lAOZEym3oK3SQ2HBHWsJUfbNBiTXJDeW2QDxw9AQ0=
github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc=
github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
Expand Down Expand Up @@ -203,6 +205,8 @@ github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/assertions v1.1.1 h1:T/YLemO5Yp7KPzS+lVtu+WsHn8yoSwTfItdAd1r3cck=
github.com/smartystreets/assertions v1.1.1/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
Expand Down
79 changes: 33 additions & 46 deletions main_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package main
package main_test

import (
"context"
"fmt"
"os"
"testing"
Expand All @@ -10,13 +9,13 @@ import (
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/client"
model "github.com/fubarhouse/pygmy-go/service/interface"
"github.com/fubarhouse/pygmy-go/service/interface/docker"
. "github.com/smartystreets/goconvey/convey"
)

const (
dindContainerName = "exampleTestContainer"
binaryReference = "pygmy-go-linux-x86"
)

var (
Expand All @@ -37,74 +36,66 @@ type config struct {
// run to keep the consistency for as many tests as are required.
func setup(t *testing.T, config *config) {

var cleanCmd = "/builds/pygmy-go-linux-x86 clean"
var statusCmd = "/builds/pygmy-go-linux-x86 status"
var upCmd = "/builds/pygmy-go-linux-x86 up"
var downCmd = "/builds/pygmy-go-linux-x86 down"
var cleanCmd = fmt.Sprintf("/builds/%v clean", binaryReference)
var statusCmd = fmt.Sprintf("/builds/%v status", binaryReference)
var upCmd = fmt.Sprintf("/builds/%v up", binaryReference)
var downCmd = fmt.Sprintf("/builds/%v down", binaryReference)

if config.configpath != "" {
cleanCmd = fmt.Sprintf("/builds/pygmy-go-linux-x86 clean --config %v", config.configpath)
statusCmd = fmt.Sprintf("/builds/pygmy-go-linux-x86 status --config %v", config.configpath)
upCmd = fmt.Sprintf("/builds/pygmy-go-linux-x86 up --config %v", config.configpath)
downCmd = fmt.Sprintf("/builds/pygmy-go-linux-x86 dow --config %v", config.configpath)
cleanCmd = fmt.Sprintf("/builds/%v clean --config %v", binaryReference, config.configpath)
statusCmd = fmt.Sprintf("/builds/%v status --config %v", binaryReference, config.configpath)
upCmd = fmt.Sprintf("/builds/%v up --config %v", binaryReference, config.configpath)
downCmd = fmt.Sprintf("/builds/%v dow --config %v", binaryReference, config.configpath)
}

Convey("Pygmy Application Test: "+config.name, t, func() {

ctx := context.Background()
cli, err := client.NewClientWithOpts()
cli.NegotiateAPIVersion(ctx)

Convey("Provision environment", func() {
Convey("Connection to Docker Client", func() {
So(err, ShouldEqual, nil)
})

Convey("Image pulled", func() {
_, e := model.DockerPull("library/docker:dind")
_, e := docker.DockerPull("library/docker:dind")
So(e, ShouldBeNil)
})

Convey("Container created", func() {
currentWorkingDirectory, err := os.Getwd()
So(err, ShouldBeNil)
x, _ := cli.ContainerCreate(ctx, &container.Config{
x, _ := docker.DockerContainerCreate(dindContainerName, container.Config{
Image: "docker:dind",
}, &container.HostConfig{
}, container.HostConfig{
AutoRemove: false,
Binds: []string{
fmt.Sprintf("%v%vbuilds%v:/builds", currentWorkingDirectory, string(os.PathSeparator), string(os.PathSeparator)),
fmt.Sprintf("%v%vexamples%v:/examples", currentWorkingDirectory, string(os.PathSeparator), string(os.PathSeparator)),
},
Privileged: true,
}, &network.NetworkingConfig{}, dindContainerName)
}, network.NetworkingConfig{})

dindID = x.ID
So(dindID, ShouldNotEqual, "")
})

Convey("Container started", func() {
err = cli.ContainerStart(ctx, dindContainerName, types.ContainerStartOptions{})
err := docker.DockerContainerStart(dindContainerName, types.ContainerStartOptions{})
So(err, ShouldEqual, nil)
})
})

Convey("Populating Daemon", func() {

Convey("Container has started the daemon", func() {
_, e := model.DockerExec(dindContainerName, "dockerd")
_, e := docker.DockerExec(dindContainerName, "dockerd")
So(e, ShouldEqual, nil)
time.Sleep(time.Second * 2)
})

e := cli.ContainerStart(ctx, dindContainerName, types.ContainerStartOptions{})
e := docker.DockerContainerStart(dindContainerName, types.ContainerStartOptions{})
if e != nil {
fmt.Println(e)
}

for _, image := range config.images {
Convey("Pulling "+image, func() {
_, e := model.DockerExec(dindContainerName, "docker pull "+image)
_, e := docker.DockerExec(dindContainerName, "docker pull "+image)
time.Sleep(time.Second * 2)
So(e, ShouldBeNil)
})
Expand All @@ -114,7 +105,7 @@ func setup(t *testing.T, config *config) {
Convey("Application Tests", func() {

Convey("Container has configuration file ("+config.configpath+")", func() {
d, _ := model.DockerExec(dindContainerName, "stat "+config.configpath)
d, _ := docker.DockerExec(dindContainerName, "stat "+config.configpath)
if config.configpath == "" {
SkipSo(string(d), ShouldContainSubstring, config.configpath)
} else {
Expand All @@ -123,30 +114,30 @@ func setup(t *testing.T, config *config) {
})

Convey("Container has compiled binary from host", func() {
d, _ := model.DockerExec(dindContainerName, "stat /builds/pygmy-go-linux-x86")
So(string(d), ShouldContainSubstring, "/builds/pygmy-go-linux-x86")
d, _ := docker.DockerExec(dindContainerName, fmt.Sprintf("stat /builds/%v", binaryReference))
So(string(d), ShouldContainSubstring, fmt.Sprintf("/builds/%v", binaryReference))
})

d, _ := model.DockerExec(dindContainerName, "/builds/pygmy-go-linux-x86")
d, _ := docker.DockerExec(dindContainerName, fmt.Sprintf("/builds/%v", binaryReference))
Convey("Container can run pygmy", func() {
So(string(d), ShouldContainSubstring, "local containers for local development")
})

// While it's safe, we should clean the environment.
_, e := model.DockerExec(dindContainerName, cleanCmd)
_, e := docker.DockerExec(dindContainerName, cleanCmd)
if e != nil {
fmt.Println(e)
}

Convey("Default ports are not allocated", func() {
g, _ := model.DockerExec(dindContainerName, statusCmd)
g, _ := docker.DockerExec(dindContainerName, statusCmd)
for _, service := range config.servicewithports {
So(string(g), ShouldContainSubstring, service+" is able to start")
}
})

Convey("Pygmy started", func() {
d, _ = model.DockerExec(dindContainerName, upCmd)
d, _ = docker.DockerExec(dindContainerName, upCmd)
if config.configpath != "" {
So(string(d), ShouldContainSubstring, "Using config file: "+config.configpath)
}
Expand All @@ -156,7 +147,7 @@ func setup(t *testing.T, config *config) {
})

Convey("Endpoints are serving", func() {
d, _ = model.DockerExec(dindContainerName, statusCmd)
d, _ = docker.DockerExec(dindContainerName, statusCmd)
for _, endpoint := range config.endpoints {
if config.skipendpointchecks {
SkipSo(string(d), ShouldNotContainSubstring, "! "+endpoint)
Expand All @@ -170,25 +161,21 @@ func setup(t *testing.T, config *config) {
Convey("Environment Cleanup", func() {
Convey("Pygmy has cleaned the environment", func() {

_, e := model.DockerExec(dindContainerName, downCmd)
_, e := docker.DockerExec(dindContainerName, downCmd)
So(e, ShouldBeNil)
_, e = model.DockerExec(dindContainerName, cleanCmd)
_, e = docker.DockerExec(dindContainerName, cleanCmd)
So(e, ShouldBeNil)
d, _ := model.DockerExec(dindContainerName, statusCmd)
d, _ := docker.DockerExec(dindContainerName, statusCmd)
for _, service := range config.services {
So(string(d), ShouldContainSubstring, service+" is not running")
}
So(e, ShouldBeNil)
})
// System prune container...
Convey("Removing DinD Container", func() {
ctx := context.Background()
cli, err := client.NewClientWithOpts()
cli.NegotiateAPIVersion(ctx)
So(err, ShouldBeNil)
err = cli.ContainerKill(ctx, "exampleTestContainer", "")
err := docker.DockerKill("exampleTestContainer")
So(err, ShouldBeNil)
err = cli.ContainerRemove(ctx, "exampleTestContainer", types.ContainerRemoveOptions{Force: true})
err = docker.DockerRemove("exampleTestContainer")
So(err, ShouldBeNil)
})
})
Expand All @@ -204,7 +191,7 @@ func TestDefault(t *testing.T) {
images: []string{"amazeeio/haproxy", "andyshinn/dnsmasq:2.78", "mailhog/mailhog"},
services: []string{"amazeeio-haproxy", "amazeeio-dnsmasq", "amazeeio-mailhog"},
servicewithports: []string{"amazeeio-haproxy", "amazeeio-mailhog"},
skipendpointchecks: true,
skipendpointchecks: false,
}
setup(t, configuration)
}
Expand Down
33 changes: 33 additions & 0 deletions service/dnsmasq/dnsmasq_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package dnsmasq_test

import (
"fmt"
"testing"

"github.com/docker/go-connections/nat"
"github.com/fubarhouse/pygmy-go/service/dnsmasq"
. "github.com/smartystreets/goconvey/convey"
)

func Example() {
dnsmasq.New()
}

func Test(t *testing.T) {
Convey("DNSMasq: Field equality tests...", t, func() {
obj := dnsmasq.New()

So(obj.Config.Image, ShouldEqual, "andyshinn/dnsmasq:2.78")
So(fmt.Sprint(obj.Config.Cmd), ShouldEqual, fmt.Sprint([]string{"-A", "/docker.amazee.io/127.0.0.1"}))
So(obj.Config.Labels["pygmy.defaults"], ShouldEqual, "true")
So(obj.Config.Labels["pygmy.enable"], ShouldEqual, "true")
So(obj.Config.Labels["pygmy.name"], ShouldEqual, "amazeeio-dnsmasq")
So(obj.Config.Labels["pygmy.weight"], ShouldEqual, "13")
So(obj.HostConfig.AutoRemove, ShouldBeFalse)
So(fmt.Sprint(obj.HostConfig.CapAdd), ShouldEqual, fmt.Sprint([]string{"NET_ADMIN"}))
So(obj.HostConfig.IpcMode, ShouldEqual, "private")
So(fmt.Sprint(obj.HostConfig.PortBindings), ShouldEqual, fmt.Sprint(nat.PortMap{"53/tcp": []nat.PortBinding{{HostIP: "", HostPort: "6053"}}, "53/udp": []nat.PortBinding{{HostIP: "", HostPort: "6053"}}}))
So(obj.HostConfig.RestartPolicy.Name, ShouldEqual, "on-failure")
So(obj.HostConfig.RestartPolicy.MaximumRetryCount, ShouldBeZeroValue)
})
}
19 changes: 19 additions & 0 deletions service/endpoint/endpoint_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package endpoint_test

import (
"testing"

"github.com/fubarhouse/pygmy-go/service/endpoint"
. "github.com/smartystreets/goconvey/convey"
)

func Example() {
endpoint.Validate("http://127.0.0.1:8080")
}

func Test(t *testing.T) {
Convey("URL Endpoint tests...", t, func() {
valid := endpoint.Validate("https://www.golang.org/")
So(valid, ShouldBeTrue)
})
}
35 changes: 35 additions & 0 deletions service/haproxy/haproxy_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package haproxy_test

import (
"fmt"
"testing"

"github.com/docker/go-connections/nat"
"github.com/fubarhouse/pygmy-go/service/haproxy"
. "github.com/smartystreets/goconvey/convey"
)

func Example() {
haproxy.New()
haproxy.NewDefaultPorts()
}

func Test(t *testing.T) {
Convey("HAProxy: Field equality tests...", t, func() {
obj := haproxy.New()
objPorts := haproxy.NewDefaultPorts()
So(obj.Config.Image, ShouldEqual, "amazeeio/haproxy")
So(obj.Config.Labels["pygmy.defaults"], ShouldEqual, "true")
So(obj.Config.Labels["pygmy.enable"], ShouldEqual, "true")
So(obj.Config.Labels["pygmy.name"], ShouldEqual, "amazeeio-haproxy")
So(obj.Config.Labels["pygmy.network"], ShouldEqual, "amazeeio-network")
So(obj.Config.Labels["pygmy.url"], ShouldEqual, "http://docker.amazee.io/stats")
So(obj.Config.Labels["pygmy.weight"], ShouldEqual, "14")
So(obj.HostConfig.AutoRemove, ShouldBeFalse)
So(fmt.Sprint(obj.HostConfig.Binds), ShouldEqual, fmt.Sprint([]string{"/var/run/docker.sock:/tmp/docker.sock"}))
So(obj.HostConfig.PortBindings, ShouldEqual, nil)
So(obj.HostConfig.RestartPolicy.Name, ShouldEqual, "on-failure")
So(obj.HostConfig.RestartPolicy.MaximumRetryCount, ShouldEqual, 0)
So(fmt.Sprint(objPorts.HostConfig.PortBindings), ShouldEqual, fmt.Sprint(nat.PortMap{"80/tcp": []nat.PortBinding{{HostIP: "", HostPort: "80"}}}))
})
}
Loading