1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-01-10 03:47:03 +02:00
goreleaser/pipeline/docker/docker_test.go

454 lines
10 KiB
Go
Raw Normal View History

2017-09-12 05:29:12 +02:00
package docker
import (
"flag"
2017-09-13 01:58:02 +02:00
"io/ioutil"
2017-09-12 05:29:12 +02:00
"os"
2017-09-13 01:58:02 +02:00
"os/exec"
"path/filepath"
2017-12-26 03:53:44 +02:00
"syscall"
"testing"
2017-12-26 03:53:44 +02:00
2017-09-12 05:29:12 +02:00
"github.com/goreleaser/goreleaser/config"
"github.com/goreleaser/goreleaser/context"
"github.com/goreleaser/goreleaser/internal/artifact"
2017-09-12 05:29:12 +02:00
"github.com/goreleaser/goreleaser/pipeline"
2017-09-13 01:58:02 +02:00
"github.com/stretchr/testify/assert"
2017-09-12 05:29:12 +02:00
)
var it = flag.Bool("it", false, "push images to docker hub")
var registry = "localhost:5000/"
func TestMain(m *testing.M) {
if !*it {
registry = "docker.io/"
}
os.Exit(m.Run())
}
func start(t *testing.T) {
if !*it {
return
}
if err := exec.Command(
"docker", "run", "-d", "-p", "5000:5000", "--name", "registry", "registry:2",
).Run(); err != nil {
t.Log("failed to start docker registry", err)
t.FailNow()
}
}
func killAndRm(t *testing.T) {
if !*it {
return
}
t.Log("killing registry")
_ = exec.Command("docker", "kill", "registry").Run()
_ = exec.Command("docker", "rm", "registry").Run()
}
2017-09-13 01:58:02 +02:00
func TestRunPipe(t *testing.T) {
var table = map[string]struct {
docker config.Docker
publish bool
expect []string
err string
}{
"valid": {
publish: true,
docker: config.Docker{
Image: registry + "goreleaser/test_run_pipe",
Goos: "linux",
Goarch: "amd64",
Dockerfile: "testdata/Dockerfile",
Binary: "mybin",
Latest: true,
TagTemplate: "{{.Tag}}-{{.Env.FOO}}",
Files: []string{
"testdata/extra_file.txt",
},
},
expect: []string{
registry + "goreleaser/test_run_pipe:v1.0.0-123",
registry + "goreleaser/test_run_pipe:latest",
},
err: "",
},
"valid_no_latest": {
publish: true,
docker: config.Docker{
Image: registry + "goreleaser/test_run_pipe",
Goos: "linux",
Goarch: "amd64",
Dockerfile: "testdata/Dockerfile",
Binary: "mybin",
Latest: false,
TagTemplate: "{{.Version}}",
Files: []string{
"testdata/extra_file.txt",
},
},
expect: []string{
registry + "goreleaser/test_run_pipe:1.0.0",
},
err: "",
},
"valid_dont_publish": {
publish: false,
docker: config.Docker{
Image: registry + "goreleaser/test_run_pipe",
Goos: "linux",
Goarch: "amd64",
Dockerfile: "testdata/Dockerfile",
Binary: "mybin",
Latest: true,
TagTemplate: "{{.Tag}}-{{.Env.FOO}}",
Files: []string{
"testdata/extra_file.txt",
},
},
expect: []string{
registry + "goreleaser/test_run_pipe:v1.0.0-123",
registry + "goreleaser/test_run_pipe:latest",
},
err: "",
},
"bad_dockerfile": {
publish: true,
docker: config.Docker{
Image: registry + "goreleaser/test_run_pipe",
Goos: "linux",
Goarch: "amd64",
Dockerfile: "testdata/Dockerfile.bad",
Binary: "mybin",
TagTemplate: "{{.Version}}",
},
err: "pull access denied for nope, repository does not exist",
},
"template_error": {
publish: true,
docker: config.Docker{
Image: registry + "goreleaser/test_run_pipe",
Goos: "linux",
Goarch: "amd64",
Dockerfile: "testdata/Dockerfile",
Binary: "mybin",
Latest: true,
TagTemplate: "{{.Tag}",
},
err: `template: tag:1: unexpected "}" in operand`,
},
"no_permissions": {
publish: true,
docker: config.Docker{
Image: "docker.io/nope",
Goos: "linux",
Goarch: "amd64",
Binary: "mybin",
Dockerfile: "testdata/Dockerfile",
TagTemplate: "{{.Tag}}",
},
expect: []string{
"docker.io/nope:latest",
"docker.io/nope:v1.0.0",
},
err: `requested access to the resource is denied`,
},
"dockerfile_doesnt_exist": {
publish: true,
docker: config.Docker{
Image: "whatever",
Goos: "linux",
Goarch: "amd64",
Binary: "mybin",
Dockerfile: "testdata/Dockerfilezzz",
TagTemplate: "{{.Tag}}",
},
err: `failed to link dockerfile`,
},
"extra_file_doesnt_exist": {
publish: true,
docker: config.Docker{
Image: "whatever",
Goos: "linux",
Goarch: "amd64",
Binary: "mybin",
Files: []string{
"testdata/nope.txt",
},
Dockerfile: "testdata/Dockerfile",
TagTemplate: "{{.Tag}}",
},
err: `failed to link extra file 'testdata/nope.txt'`,
},
"no_matching_binaries": {
publish: true,
docker: config.Docker{
Image: "whatever",
Goos: "darwin",
Goarch: "amd64",
Binary: "mybinnnn",
Dockerfile: "testdata/Dockerfile",
},
err: "",
},
}
killAndRm(t)
start(t)
defer killAndRm(t)
for name, docker := range table {
t.Run(name, func(tt *testing.T) {
folder, err := ioutil.TempDir("", "archivetest")
assert.NoError(t, err)
var dist = filepath.Join(folder, "dist")
assert.NoError(t, os.Mkdir(dist, 0755))
assert.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0755))
var binPath = filepath.Join(dist, "mybin", "mybin")
_, err = os.Create(binPath)
assert.NoError(t, err)
var ctx = &context.Context{
2017-12-26 03:53:44 +02:00
Version: "1.0.0",
Publish: docker.publish,
2017-12-26 03:53:44 +02:00
Parallelism: 4,
Artifacts: artifact.New(),
Git: context.GitInfo{
CurrentTag: "v1.0.0",
2017-09-13 01:58:02 +02:00
},
Config: config.Project{
ProjectName: "mybin",
Dist: dist,
Dockers: []config.Docker{
docker.docker,
},
2017-09-13 01:58:02 +02:00
},
Env: map[string]string{"FOO": "123"},
}
for _, os := range []string{"linux", "darwin"} {
for _, arch := range []string{"amd64", "386"} {
ctx.Artifacts.Add(artifact.Artifact{
Name: "mybin",
Path: binPath,
Goarch: arch,
Goos: os,
Type: artifact.Binary,
Extra: map[string]string{
"Binary": "mybin",
},
})
}
}
// this might fail as the image doesnt exist yet, so lets ignore the error
for _, img := range docker.expect {
_ = exec.Command("docker", "rmi", img).Run()
}
err = Pipe{}.Run(ctx)
if docker.err == "" {
assert.NoError(tt, err)
} else {
assert.Contains(tt, err.Error(), docker.err)
}
2017-09-15 01:16:49 +02:00
// this might should not fail as the image should have been created when
// the step ran
for _, img := range docker.expect {
t.Log("removing docker image", img)
assert.NoError(t, exec.Command("docker", "rmi", img).Run(), "could not delete image", img)
}
})
2017-09-15 01:16:49 +02:00
}
2017-09-13 01:58:02 +02:00
}
2017-09-12 05:29:12 +02:00
func TestDescription(t *testing.T) {
assert.NotEmpty(t, Pipe{}.String())
2017-09-12 05:29:12 +02:00
}
func TestNoDockers(t *testing.T) {
assert.True(t, pipeline.IsSkip(Pipe{}.Run(context.New(config.Project{}))))
2017-09-12 05:29:12 +02:00
}
func TestNoDockerWithoutImageName(t *testing.T) {
assert.True(t, pipeline.IsSkip(Pipe{}.Run(context.New(config.Project{
2017-09-12 05:29:12 +02:00
Dockers: []config.Docker{
{
Goos: "linux",
},
},
}))))
}
func TestDockerNotInPath(t *testing.T) {
var path = os.Getenv("PATH")
defer func() {
assert.NoError(t, os.Setenv("PATH", path))
2017-09-12 05:29:12 +02:00
}()
assert.NoError(t, os.Setenv("PATH", ""))
2017-09-12 05:29:12 +02:00
var ctx = &context.Context{
Version: "1.0.0",
Config: config.Project{
Dockers: []config.Docker{
{
Image: "a/b",
},
},
},
}
assert.EqualError(t, Pipe{}.Run(ctx), ErrNoDocker.Error())
2017-09-12 05:29:12 +02:00
}
func TestDefault(t *testing.T) {
var ctx = &context.Context{
Config: config.Project{
Builds: []config.Build{
{
Binary: "foo",
},
},
Dockers: []config.Docker{
{
Latest: true,
},
},
},
}
assert.NoError(t, Pipe{}.Default(ctx))
assert.Len(t, ctx.Config.Dockers, 1)
var docker = ctx.Config.Dockers[0]
assert.Equal(t, "linux", docker.Goos)
assert.Equal(t, "amd64", docker.Goarch)
assert.Equal(t, ctx.Config.Builds[0].Binary, docker.Binary)
assert.Equal(t, "Dockerfile", docker.Dockerfile)
assert.Equal(t, "{{ .Version }}", docker.TagTemplate)
}
func TestDefaultNoDockers(t *testing.T) {
var ctx = &context.Context{
Config: config.Project{
Dockers: []config.Docker{},
},
}
assert.NoError(t, Pipe{}.Default(ctx))
assert.Empty(t, ctx.Config.Dockers)
}
func TestDefaultSet(t *testing.T) {
var ctx = &context.Context{
Config: config.Project{
Dockers: []config.Docker{
{
Goos: "windows",
Goarch: "i386",
Binary: "bar",
Dockerfile: "Dockerfile.foo",
},
},
},
}
assert.NoError(t, Pipe{}.Default(ctx))
assert.Len(t, ctx.Config.Dockers, 1)
var docker = ctx.Config.Dockers[0]
assert.Equal(t, "windows", docker.Goos)
assert.Equal(t, "i386", docker.Goarch)
assert.Equal(t, "bar", docker.Binary)
assert.Equal(t, "{{ .Version }}", docker.TagTemplate)
assert.Equal(t, "Dockerfile.foo", docker.Dockerfile)
}
func TestLinkFile(t *testing.T) {
const srcFile = "/tmp/test"
const dstFile = "/tmp/linked"
err := ioutil.WriteFile(srcFile, []byte("foo"), 0644)
if err != nil {
t.Log("Cannot setup test file")
t.Fail()
}
err = link(srcFile, dstFile)
if err != nil {
t.Log("Failed to link: ", err)
t.Fail()
}
if inode(srcFile) != inode(dstFile) {
t.Log("Inodes do not match, destination file is not a link")
t.Fail()
}
// cleanup
os.Remove(srcFile)
os.Remove(dstFile)
}
func TestLinkDirectory(t *testing.T) {
const srcDir = "/tmp/testdir"
const testFile = "test"
const dstDir = "/tmp/linkedDir"
os.Mkdir(srcDir, 0755)
err := ioutil.WriteFile(srcDir+"/"+testFile, []byte("foo"), 0644)
if err != nil {
t.Log("Cannot setup test file")
t.Fail()
}
2017-12-24 14:14:55 +02:00
err = link(srcDir, dstDir)
if err != nil {
t.Log("Failed to link: ", err)
t.Fail()
}
if inode(srcDir+"/"+testFile) != inode(dstDir+"/"+testFile) {
t.Log("Inodes do not match, destination file is not a link")
t.Fail()
}
// cleanup
os.RemoveAll(srcDir)
os.RemoveAll(dstDir)
}
func TestLinkTwoLevelDirectory(t *testing.T) {
const srcDir = "/tmp/testdir"
2017-12-26 03:53:44 +02:00
const srcLevel2 = srcDir + "/level2"
const testFile = "test"
const dstDir = "/tmp/linkedDir"
os.Mkdir(srcDir, 0755)
os.Mkdir(srcLevel2, 0755)
err := ioutil.WriteFile(srcDir+"/"+testFile, []byte("foo"), 0644)
if err != nil {
t.Log("Cannot setup test file")
t.Fail()
}
err = ioutil.WriteFile(srcLevel2+"/"+testFile, []byte("foo"), 0644)
if err != nil {
t.Log("Cannot setup test file")
t.Fail()
}
2017-12-24 14:14:55 +02:00
err = link(srcDir, dstDir)
if err != nil {
t.Log("Failed to link: ", err)
t.Fail()
}
if inode(srcDir+"/"+testFile) != inode(dstDir+"/"+testFile) {
t.Log("Inodes do not match")
t.Fail()
}
if inode(srcLevel2+"/"+testFile) != inode(dstDir+"/level2/"+testFile) {
t.Log("Inodes do not match")
t.Fail()
}
// cleanup
os.RemoveAll(srcDir)
os.RemoveAll(dstDir)
}
func inode(file string) uint64 {
fileInfo, err := os.Stat(file)
if err != nil {
return 0
}
stat := fileInfo.Sys().(*syscall.Stat_t)
return stat.Ino
}