2016-03-09 00:43:38 +03:00
|
|
|
package builder
|
|
|
|
|
|
|
|
import (
|
|
|
|
"archive/tar"
|
|
|
|
"bytes"
|
|
|
|
"io"
|
|
|
|
"io/ioutil"
|
|
|
|
"path/filepath"
|
2016-04-06 23:42:15 +03:00
|
|
|
"runtime"
|
2016-03-09 00:43:38 +03:00
|
|
|
"strings"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/docker/docker/pkg/archive"
|
|
|
|
)
|
|
|
|
|
2016-05-03 12:10:51 +03:00
|
|
|
var prepareEmpty = func(t *testing.T) (string, func()) {
|
|
|
|
return "", func() {}
|
2016-03-09 00:43:38 +03:00
|
|
|
}
|
|
|
|
|
2016-05-03 12:10:51 +03:00
|
|
|
var prepareNoFiles = func(t *testing.T) (string, func()) {
|
|
|
|
return createTestTempDir(t, "", "builder-context-test")
|
2016-03-09 00:43:38 +03:00
|
|
|
}
|
|
|
|
|
2016-05-03 12:10:51 +03:00
|
|
|
var prepareOneFile = func(t *testing.T) (string, func()) {
|
|
|
|
contextDir, cleanup := createTestTempDir(t, "", "builder-context-test")
|
|
|
|
createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents, 0777)
|
|
|
|
return contextDir, cleanup
|
2016-03-09 00:43:38 +03:00
|
|
|
}
|
|
|
|
|
2016-05-03 12:10:51 +03:00
|
|
|
func testValidateContextDirectory(t *testing.T, prepare func(t *testing.T) (string, func()), excludes []string) {
|
|
|
|
contextDir, cleanup := prepare(t)
|
|
|
|
defer cleanup()
|
2016-03-09 00:43:38 +03:00
|
|
|
|
|
|
|
err := ValidateContextDirectory(contextDir, excludes)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Error should be nil, got: %s", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestGetContextFromLocalDirNoDockerfile(t *testing.T) {
|
2016-05-03 12:10:51 +03:00
|
|
|
contextDir, cleanup := createTestTempDir(t, "", "builder-context-test")
|
|
|
|
defer cleanup()
|
2016-03-09 00:43:38 +03:00
|
|
|
|
|
|
|
absContextDir, relDockerfile, err := GetContextFromLocalDir(contextDir, "")
|
|
|
|
|
|
|
|
if err == nil {
|
|
|
|
t.Fatalf("Error should not be nil")
|
|
|
|
}
|
|
|
|
|
|
|
|
if absContextDir != "" {
|
|
|
|
t.Fatalf("Absolute directory path should be empty, got: %s", absContextDir)
|
|
|
|
}
|
|
|
|
|
|
|
|
if relDockerfile != "" {
|
|
|
|
t.Fatalf("Relative path to Dockerfile should be empty, got: %s", relDockerfile)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestGetContextFromLocalDirNotExistingDir(t *testing.T) {
|
2016-05-03 12:10:51 +03:00
|
|
|
contextDir, cleanup := createTestTempDir(t, "", "builder-context-test")
|
|
|
|
defer cleanup()
|
2016-03-09 00:43:38 +03:00
|
|
|
|
|
|
|
fakePath := filepath.Join(contextDir, "fake")
|
|
|
|
|
|
|
|
absContextDir, relDockerfile, err := GetContextFromLocalDir(fakePath, "")
|
|
|
|
|
|
|
|
if err == nil {
|
|
|
|
t.Fatalf("Error should not be nil")
|
|
|
|
}
|
|
|
|
|
|
|
|
if absContextDir != "" {
|
|
|
|
t.Fatalf("Absolute directory path should be empty, got: %s", absContextDir)
|
|
|
|
}
|
|
|
|
|
|
|
|
if relDockerfile != "" {
|
|
|
|
t.Fatalf("Relative path to Dockerfile should be empty, got: %s", relDockerfile)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestGetContextFromLocalDirNotExistingDockerfile(t *testing.T) {
|
2016-05-03 12:10:51 +03:00
|
|
|
contextDir, cleanup := createTestTempDir(t, "", "builder-context-test")
|
|
|
|
defer cleanup()
|
2016-03-09 00:43:38 +03:00
|
|
|
|
|
|
|
fakePath := filepath.Join(contextDir, "fake")
|
|
|
|
|
|
|
|
absContextDir, relDockerfile, err := GetContextFromLocalDir(contextDir, fakePath)
|
|
|
|
|
|
|
|
if err == nil {
|
|
|
|
t.Fatalf("Error should not be nil")
|
|
|
|
}
|
|
|
|
|
|
|
|
if absContextDir != "" {
|
|
|
|
t.Fatalf("Absolute directory path should be empty, got: %s", absContextDir)
|
|
|
|
}
|
|
|
|
|
|
|
|
if relDockerfile != "" {
|
|
|
|
t.Fatalf("Relative path to Dockerfile should be empty, got: %s", relDockerfile)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestGetContextFromLocalDirWithNoDirectory(t *testing.T) {
|
2016-05-03 12:10:51 +03:00
|
|
|
contextDir, dirCleanup := createTestTempDir(t, "", "builder-context-test")
|
|
|
|
defer dirCleanup()
|
2016-03-09 00:43:38 +03:00
|
|
|
|
2016-05-03 12:10:51 +03:00
|
|
|
createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents, 0777)
|
2016-03-09 00:43:38 +03:00
|
|
|
|
2016-05-03 12:10:51 +03:00
|
|
|
chdirCleanup := chdir(t, contextDir)
|
|
|
|
defer chdirCleanup()
|
2016-03-09 00:43:38 +03:00
|
|
|
|
2016-04-06 23:42:15 +03:00
|
|
|
absContextDir, relDockerfile, err := GetContextFromLocalDir(contextDir, "")
|
2016-03-09 00:43:38 +03:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Error when getting context from local dir: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if absContextDir != contextDir {
|
|
|
|
t.Fatalf("Absolute directory path should be equal to %s, got: %s", contextDir, absContextDir)
|
|
|
|
}
|
|
|
|
|
|
|
|
if relDockerfile != DefaultDockerfileName {
|
|
|
|
t.Fatalf("Relative path to dockerfile should be equal to %s, got: %s", DefaultDockerfileName, relDockerfile)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestGetContextFromLocalDirWithDockerfile(t *testing.T) {
|
2016-05-03 12:10:51 +03:00
|
|
|
contextDir, cleanup := createTestTempDir(t, "", "builder-context-test")
|
|
|
|
defer cleanup()
|
2016-03-09 00:43:38 +03:00
|
|
|
|
2016-05-03 12:10:51 +03:00
|
|
|
createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents, 0777)
|
2016-03-09 00:43:38 +03:00
|
|
|
|
|
|
|
absContextDir, relDockerfile, err := GetContextFromLocalDir(contextDir, "")
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Error when getting context from local dir: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if absContextDir != contextDir {
|
|
|
|
t.Fatalf("Absolute directory path should be equal to %s, got: %s", contextDir, absContextDir)
|
|
|
|
}
|
|
|
|
|
|
|
|
if relDockerfile != DefaultDockerfileName {
|
|
|
|
t.Fatalf("Relative path to dockerfile should be equal to %s, got: %s", DefaultDockerfileName, relDockerfile)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestGetContextFromLocalDirLocalFile(t *testing.T) {
|
2016-05-03 12:10:51 +03:00
|
|
|
contextDir, cleanup := createTestTempDir(t, "", "builder-context-test")
|
|
|
|
defer cleanup()
|
2016-03-09 00:43:38 +03:00
|
|
|
|
2016-05-03 12:10:51 +03:00
|
|
|
createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents, 0777)
|
|
|
|
testFilename := createTestTempFile(t, contextDir, "tmpTest", "test", 0777)
|
2016-03-09 00:43:38 +03:00
|
|
|
|
|
|
|
absContextDir, relDockerfile, err := GetContextFromLocalDir(testFilename, "")
|
|
|
|
|
|
|
|
if err == nil {
|
|
|
|
t.Fatalf("Error should not be nil")
|
|
|
|
}
|
|
|
|
|
|
|
|
if absContextDir != "" {
|
|
|
|
t.Fatalf("Absolute directory path should be empty, got: %s", absContextDir)
|
|
|
|
}
|
|
|
|
|
|
|
|
if relDockerfile != "" {
|
|
|
|
t.Fatalf("Relative path to Dockerfile should be empty, got: %s", relDockerfile)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestGetContextFromLocalDirWithCustomDockerfile(t *testing.T) {
|
2016-05-03 12:10:51 +03:00
|
|
|
contextDir, cleanup := createTestTempDir(t, "", "builder-context-test")
|
|
|
|
defer cleanup()
|
2016-03-09 00:43:38 +03:00
|
|
|
|
2016-05-03 12:10:51 +03:00
|
|
|
chdirCleanup := chdir(t, contextDir)
|
|
|
|
defer chdirCleanup()
|
2016-03-09 00:43:38 +03:00
|
|
|
|
2016-05-03 12:10:51 +03:00
|
|
|
createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents, 0777)
|
2016-03-09 00:43:38 +03:00
|
|
|
|
2016-05-03 12:10:51 +03:00
|
|
|
absContextDir, relDockerfile, err := GetContextFromLocalDir(contextDir, DefaultDockerfileName)
|
2016-03-09 00:43:38 +03:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Error when getting context from local dir: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if absContextDir != contextDir {
|
|
|
|
t.Fatalf("Absolute directory path should be equal to %s, got: %s", contextDir, absContextDir)
|
|
|
|
}
|
|
|
|
|
2016-05-03 12:10:51 +03:00
|
|
|
if relDockerfile != DefaultDockerfileName {
|
|
|
|
t.Fatalf("Relative path to dockerfile should be equal to %s, got: %s", DefaultDockerfileName, relDockerfile)
|
2016-03-09 00:43:38 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestGetContextFromReaderString(t *testing.T) {
|
2016-05-03 12:10:51 +03:00
|
|
|
tarArchive, relDockerfile, err := GetContextFromReader(ioutil.NopCloser(strings.NewReader(dockerfileContents)), "")
|
2016-03-09 00:43:38 +03:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Error when executing GetContextFromReader: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
tarReader := tar.NewReader(tarArchive)
|
|
|
|
|
|
|
|
_, err = tarReader.Next()
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Error when reading tar archive: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
buff := new(bytes.Buffer)
|
|
|
|
buff.ReadFrom(tarReader)
|
|
|
|
contents := buff.String()
|
|
|
|
|
|
|
|
_, err = tarReader.Next()
|
|
|
|
|
|
|
|
if err != io.EOF {
|
|
|
|
t.Fatalf("Tar stream too long: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err = tarArchive.Close(); err != nil {
|
|
|
|
t.Fatalf("Error when closing tar stream: %s", err)
|
|
|
|
}
|
|
|
|
|
2016-05-03 12:10:51 +03:00
|
|
|
if dockerfileContents != contents {
|
|
|
|
t.Fatalf("Uncompressed tar archive does not equal: %s, got: %s", dockerfileContents, contents)
|
2016-03-09 00:43:38 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if relDockerfile != DefaultDockerfileName {
|
|
|
|
t.Fatalf("Relative path not equals %s, got: %s", DefaultDockerfileName, relDockerfile)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestGetContextFromReaderTar(t *testing.T) {
|
2016-05-03 12:10:51 +03:00
|
|
|
contextDir, cleanup := createTestTempDir(t, "", "builder-context-test")
|
|
|
|
defer cleanup()
|
2016-03-09 00:43:38 +03:00
|
|
|
|
2016-05-03 12:10:51 +03:00
|
|
|
createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents, 0777)
|
2016-03-09 00:43:38 +03:00
|
|
|
|
|
|
|
tarStream, err := archive.Tar(contextDir, archive.Uncompressed)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Error when creating tar: %s", err)
|
|
|
|
}
|
|
|
|
|
2016-05-03 12:10:51 +03:00
|
|
|
tarArchive, relDockerfile, err := GetContextFromReader(tarStream, DefaultDockerfileName)
|
2016-03-09 00:43:38 +03:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Error when executing GetContextFromReader: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
tarReader := tar.NewReader(tarArchive)
|
|
|
|
|
|
|
|
header, err := tarReader.Next()
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Error when reading tar archive: %s", err)
|
|
|
|
}
|
|
|
|
|
2016-05-03 12:10:51 +03:00
|
|
|
if header.Name != DefaultDockerfileName {
|
|
|
|
t.Fatalf("Dockerfile name should be: %s, got: %s", DefaultDockerfileName, header.Name)
|
2016-03-09 00:43:38 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
buff := new(bytes.Buffer)
|
|
|
|
buff.ReadFrom(tarReader)
|
|
|
|
contents := buff.String()
|
|
|
|
|
|
|
|
_, err = tarReader.Next()
|
|
|
|
|
|
|
|
if err != io.EOF {
|
|
|
|
t.Fatalf("Tar stream too long: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err = tarArchive.Close(); err != nil {
|
|
|
|
t.Fatalf("Error when closing tar stream: %s", err)
|
|
|
|
}
|
|
|
|
|
2016-05-03 12:10:51 +03:00
|
|
|
if dockerfileContents != contents {
|
|
|
|
t.Fatalf("Uncompressed tar archive does not equal: %s, got: %s", dockerfileContents, contents)
|
2016-03-09 00:43:38 +03:00
|
|
|
}
|
|
|
|
|
2016-05-03 12:10:51 +03:00
|
|
|
if relDockerfile != DefaultDockerfileName {
|
|
|
|
t.Fatalf("Relative path not equals %s, got: %s", DefaultDockerfileName, relDockerfile)
|
2016-03-09 00:43:38 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestValidateContextDirectoryEmptyContext(t *testing.T) {
|
2016-04-06 23:42:15 +03:00
|
|
|
// This isn't a valid test on Windows. See https://play.golang.org/p/RR6z6jxR81.
|
|
|
|
// The test will ultimately end up calling filepath.Abs(""). On Windows,
|
|
|
|
// golang will error. On Linux, golang will return /. Due to there being
|
|
|
|
// drive letters on Windows, this is probably the correct behaviour for
|
|
|
|
// Windows.
|
|
|
|
if runtime.GOOS == "windows" {
|
|
|
|
t.Skip("Invalid test on Windows")
|
|
|
|
}
|
2016-03-09 00:43:38 +03:00
|
|
|
testValidateContextDirectory(t, prepareEmpty, []string{})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestValidateContextDirectoryContextWithNoFiles(t *testing.T) {
|
|
|
|
testValidateContextDirectory(t, prepareNoFiles, []string{})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestValidateContextDirectoryWithOneFile(t *testing.T) {
|
|
|
|
testValidateContextDirectory(t, prepareOneFile, []string{})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestValidateContextDirectoryWithOneFileExcludes(t *testing.T) {
|
2016-05-03 12:10:51 +03:00
|
|
|
testValidateContextDirectory(t, prepareOneFile, []string{DefaultDockerfileName})
|
2016-03-09 00:43:38 +03:00
|
|
|
}
|