From 96a6a8dbee96b0b24946bda22e4fd612fe613cb4 Mon Sep 17 00:00:00 2001 From: Lexy2 <38648992+Lexy2@users.noreply.github.com> Date: Tue, 11 May 2021 18:00:02 +1000 Subject: [PATCH] fix: test spaces for windows (#190) * fix running tests in directories with spaces * REGISTRY_STORAGE_DELETE * Updated Windows testing scripts Co-authored-by: Zhitenev-Lexy Co-authored-by: Manuel Vogel --- .../resource_docker_container_funcs.go | 7 +++++- .../resource_docker_container_test.go | 9 ++++---- .../provider/resource_docker_image_funcs.go | 6 +++++ .../provider/resource_docker_image_test.go | 9 ++++---- .../resource_docker_registry_image_funcs.go | 3 +-- ...source_docker_registry_image_funcs_test.go | 9 ++++++-- .../provider/resource_docker_service_test.go | 2 +- scripts/runAccTests.bat | 22 ++++++++++++++---- scripts/testing/setup_private_registry.bat | 23 ++++++++++--------- 9 files changed, 60 insertions(+), 30 deletions(-) diff --git a/internal/provider/resource_docker_container_funcs.go b/internal/provider/resource_docker_container_funcs.go index 2f146460..b34051cf 100644 --- a/internal/provider/resource_docker_container_funcs.go +++ b/internal/provider/resource_docker_container_funcs.go @@ -484,9 +484,10 @@ func resourceDockerContainerCreate(ctx context.Context, d *schema.ResourceData, if d.Get("attach").(bool) { var b bytes.Buffer - + logsRead := make(chan bool) if d.Get("logs").(bool) { go func() { + defer func() { logsRead <- true }() reader, err := client.ContainerLogs(ctx, retContainer.ID, types.ContainerLogsOptions{ ShowStdout: true, ShowStderr: true, @@ -520,6 +521,10 @@ func resourceDockerContainerCreate(ctx context.Context, d *schema.ResourceData, } case <-attachCh: if d.Get("logs").(bool) { + // There is a race condition here. + // If the goroutine does not finish writing into the buffer by this line, we will have no logs. + // Thus, waiting for the goroutine to finish + <-logsRead d.Set("container_logs", b.String()) } } diff --git a/internal/provider/resource_docker_container_test.go b/internal/provider/resource_docker_container_test.go index c1e931bc..496f09e1 100644 --- a/internal/provider/resource_docker_container_test.go +++ b/internal/provider/resource_docker_container_test.go @@ -7,6 +7,7 @@ import ( "fmt" "io/ioutil" "os" + "path/filepath" "reflect" "regexp" "strconv" @@ -35,7 +36,7 @@ func TestAccDockerContainer_private_image(t *testing.T) { registry := "127.0.0.1:15000" image := "127.0.0.1:15000/tftest-service:v1" wd, _ := os.Getwd() - dockerConfig := wd + "/../../scripts/testing/dockerconfig.json" + dockerConfig := strings.ReplaceAll(filepath.Join(wd, "..", "..", "scripts", "testing", "dockerconfig.json"), "\\", "\\\\") ctx := context.Background() var c types.ContainerJSON @@ -741,7 +742,7 @@ func TestAccDockerContainer_uploadSource(t *testing.T) { ctx := context.Background() wd, _ := os.Getwd() - testFile := wd + "/../../scripts/testing/testingFile" + testFile := strings.ReplaceAll(filepath.Join(wd, "..", "..", "scripts", "testing", "testingFile"), "\\", "\\\\") testFileContent, _ := ioutil.ReadFile(testFile) testCheck := func(*terraform.State) error { @@ -806,7 +807,7 @@ func TestAccDockerContainer_uploadSourceHash(t *testing.T) { var firstRunId string wd, _ := os.Getwd() - testFile := wd + "/../../scripts/testing/testingFile" + testFile := strings.ReplaceAll(filepath.Join(wd, "..", "..", "scripts", "testing", "testingFile"), "\\", "\\\\") hash, _ := ioutil.ReadFile(testFile + ".base64") grabFirstCheck := func(*terraform.State) error { firstRunId = c.ID @@ -1909,7 +1910,7 @@ resource "docker_image" "foo" { resource "docker_container" "foo" { name = "tf-test" image = docker_image.foo.latest - entrypoint = ["/bin/bash", "-c", "ping localhost"] + entrypoint = ["/bin/bash", "-c", "cat /proc/kmsg"] user = "root:root" restart = "on-failure" destroy_grace_seconds = 10 diff --git a/internal/provider/resource_docker_image_funcs.go b/internal/provider/resource_docker_image_funcs.go index 30d5a492..96deccbd 100644 --- a/internal/provider/resource_docker_image_funcs.go +++ b/internal/provider/resource_docker_image_funcs.go @@ -8,6 +8,7 @@ import ( "fmt" "io" "log" + "path/filepath" "strings" "github.com/docker/cli/cli/command/image/build" @@ -331,6 +332,11 @@ func buildDockerImage(ctx context.Context, rawBuild map[string]interface{}, imag func getBuildContext(filePath string, excludes []string) io.Reader { filePath, _ = homedir.Expand(filePath) + //TarWithOptions works only with absolute paths in Windows. + filePath, err := filepath.Abs(filePath) + if err != nil { + log.Fatalf("Invalid build directory: %s", filePath) + } ctx, _ := archive.TarWithOptions(filePath, &archive.TarOptions{ ExcludePatterns: excludes, }) diff --git a/internal/provider/resource_docker_image_test.go b/internal/provider/resource_docker_image_test.go index 08b3ec48..2ea8874e 100644 --- a/internal/provider/resource_docker_image_test.go +++ b/internal/provider/resource_docker_image_test.go @@ -6,8 +6,9 @@ import ( "io/ioutil" "os" "os/exec" - "path" + "path/filepath" "regexp" + "strings" "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" @@ -161,7 +162,7 @@ func TestAccDockerImage_data_private_config_file(t *testing.T) { registry := "127.0.0.1:15000" image := "127.0.0.1:15000/tftest-service:v1" wd, _ := os.Getwd() - dockerConfig := wd + "/../../scripts/testing/dockerconfig.json" + dockerConfig := strings.ReplaceAll(filepath.Join(wd, "..", "..", "scripts", "testing", "dockerconfig.json"), "\\", "\\\\") ctx := context.Background() resource.Test(t, resource.TestCase{ @@ -186,7 +187,7 @@ func TestAccDockerImage_data_private_config_file_content(t *testing.T) { registry := "127.0.0.1:15000" image := "127.0.0.1:15000/tftest-service:v1" wd, _ := os.Getwd() - dockerConfig := wd + "/../../scripts/testing/dockerconfig.json" + dockerConfig := strings.ReplaceAll(filepath.Join(wd, "..", "..", "scripts", "testing", "dockerconfig.json"), "\\", "\\\\") ctx := context.Background() resource.Test(t, resource.TestCase{ @@ -263,7 +264,7 @@ func TestAccDockerImage_tag_sha265(t *testing.T) { func TestAccDockerImage_build(t *testing.T) { ctx := context.Background() wd, _ := os.Getwd() - dfPath := path.Join(wd, "Dockerfile") + dfPath := filepath.Join(wd, "Dockerfile") if err := ioutil.WriteFile(dfPath, []byte(testDockerFileExample), 0o644); err != nil { t.Fatalf("failed to create a Dockerfile %s for test: %+v", dfPath, err) } diff --git a/internal/provider/resource_docker_registry_image_funcs.go b/internal/provider/resource_docker_registry_image_funcs.go index 236250bb..a1af3edc 100644 --- a/internal/provider/resource_docker_registry_image_funcs.go +++ b/internal/provider/resource_docker_registry_image_funcs.go @@ -239,7 +239,7 @@ func buildDockerRegistryImage(ctx context.Context, client *client.Client, buildO // the tar hash is passed only after the initial creation buildContext := buildOptions["context"].(string) - if lastIndex := strings.LastIndexByte(buildContext, ':'); lastIndex > -1 { + if lastIndex := strings.LastIndexByte(buildContext, ':'); (lastIndex > -1) && (buildContext[lastIndex+1] != filepath.Separator) { buildContext = buildContext[:lastIndex] } dockerContextTarPath, err := buildDockerImageContextTar(buildContext) @@ -275,7 +275,6 @@ func buildDockerImageContextTar(buildContext string) (string, error) { } defer tmpFile.Close() - if _, err = os.Stat(buildContext); err != nil { return "", fmt.Errorf("Unable to read build context - %v", err.Error()) } diff --git a/internal/provider/resource_docker_registry_image_funcs_test.go b/internal/provider/resource_docker_registry_image_funcs_test.go index de63fc21..bd129969 100644 --- a/internal/provider/resource_docker_registry_image_funcs_test.go +++ b/internal/provider/resource_docker_registry_image_funcs_test.go @@ -3,8 +3,11 @@ package provider import ( "context" "fmt" + "os" + "path/filepath" "reflect" "regexp" + "strings" "testing" "github.com/docker/docker/api/types" @@ -111,7 +114,8 @@ func TestAccDockerRegistryImageResource_mapping(t *testing.T) { func TestAccDockerRegistryImageResource_build(t *testing.T) { pushOptions := createPushImageOptions("127.0.0.1:15000/tftest-dockerregistryimage:1.0") - context := "../../scripts/testing/docker_registry_image_context" + wd, _ := os.Getwd() + context := strings.ReplaceAll((filepath.Join(wd, "..", "..", "scripts", "testing", "docker_registry_image_context")), "\\", "\\\\") resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, ProviderFactories: providerFactories, @@ -130,7 +134,8 @@ func TestAccDockerRegistryImageResource_build(t *testing.T) { func TestAccDockerRegistryImageResource_buildAndKeep(t *testing.T) { t.Skip("mavogel: need to check") pushOptions := createPushImageOptions("127.0.0.1:15000/tftest-dockerregistryimage:1.0") - context := "../../scripts/testing/docker_registry_image_context" + wd, _ := os.Getwd() + context := strings.ReplaceAll(filepath.Join(wd, "..", "..", "scripts", "testing", "docker_registry_image_context"), "\\", "\\\\") resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, ProviderFactories: providerFactories, diff --git a/internal/provider/resource_docker_service_test.go b/internal/provider/resource_docker_service_test.go index cbf9779d..fb02d4a6 100644 --- a/internal/provider/resource_docker_service_test.go +++ b/internal/provider/resource_docker_service_test.go @@ -1664,7 +1664,7 @@ func checkAndRemoveImages(ctx context.Context, s *terraform.State) error { } if len(imagesAfterDelete) != 0 { - return fmt.Errorf("Expected images of patter '%s' to be deleted, but there is/are still %d", imagePattern, len(imagesAfterDelete)) + return fmt.Errorf("Expected images of pattern '%s' to be deleted, but there is/are still %d", imagePattern, len(imagesAfterDelete)) } return nil diff --git a/scripts/runAccTests.bat b/scripts/runAccTests.bat index c66bcf43..5e8ba883 100644 --- a/scripts/runAccTests.bat +++ b/scripts/runAccTests.bat @@ -1,5 +1,6 @@ @echo off setlocal +setlocal EnableDelayedExpansion :: As of `go-dockerclient` v1.2.0, the default endpoint to the Docker daemon :: is a UNIX socket. We need to force it to use the Windows named pipe when @@ -55,26 +56,37 @@ exit /b %outcome% :setup call:log "setup" - call %~dp0testing\setup_private_registry.bat + :: Setup testing files + echo | set /p=foo > "%~dp0testing\testingFile" + call openssl base64 -in "%~dp0testing\testingFile" -out "%~dp0testing\tmp.base64" + type nul > "%~dp0testing\testingFile.base64" + for /f "usebackq" %%x in ("%~dp0testing\tmp.base64") do echo | set /p=%%x >> "%~dp0testing\testingFile.base64" + del /Q "%~dp0testing\tmp.base64" + + call "%~dp0testing\setup_private_registry.bat" exit /b %ErrorLevel% :run call:log "run" + call go clean -testcache call go test ./internal/provider -v -timeout 120m exit /b %ErrorLevel% :cleanup call:log "cleanup" - call:print "### unsetted env ###" + call:print "### unset env ###" + del /Q "%~dp0testing\testingFile" + del /Q "%~dp0testing\testingFile.base64" + call:print "### deleted testing files ###" for /F %%p in ('docker container ls -f "name=private_registry" -q') do ( call docker stop %%p call docker rm -f -v %%p ) call:print "### stopped private registry ###" - rmdir /q /s %~dp0testing\auth - rmdir /q /s %~dp0testing\certs + rmdir /q /s "%~dp0testing\auth" + rmdir /q /s "%~dp0testing\certs" call:print "### removed auth and certs ###" for %%r in ("container" "volume") do ( call docker %%r ls -f "name=tftest-" -q @@ -97,7 +109,7 @@ exit /b %outcome% call:print "### removed %%r ###" ) for /F %%i in ('docker images -aq 127.0.0.1:5000/tftest-service') do ( - echo Deleting imag %%i + echo Deleting image %%i docker rmi -f %%i ) call:print "### removed service images ###" diff --git a/scripts/testing/setup_private_registry.bat b/scripts/testing/setup_private_registry.bat index c58f870a..c7f77688 100644 --- a/scripts/testing/setup_private_registry.bat +++ b/scripts/testing/setup_private_registry.bat @@ -2,28 +2,28 @@ setlocal :: Create self-signed certificate. -call:mkdirp %~dp0certs +call:mkdirp "%~dp0certs" call openssl req ^ -newkey rsa:2048 ^ -nodes ^ -x509 ^ -days 365 ^ -subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=127.0.0.1" ^ - -keyout %~dp0certs\registry_auth.key ^ - -out %~dp0certs\registry_auth.crt + -keyout "%~dp0certs\registry_auth.key" ^ + -out "%~dp0certs\registry_auth.crt" if %ErrorLevel% neq 0 ( call:print "Failed to generate self-signed certificate." exit /b %ErrorLevel% ) :: Generate random credentials. -call:mkdirp %~dp0auth +call:mkdirp "%~dp0auth" call docker run ^ --rm ^ --entrypoint htpasswd ^ registry:2.7.0 ^ -Bbn testuser testpwd ^ - > %~dp0auth\htpasswd + > "%~dp0auth\htpasswd" if %ErrorLevel% neq 0 ( call:print "Failed to generate random credentials." exit /b %ErrorLevel% @@ -36,13 +36,14 @@ call docker run ^ -d ^ --name private_registry ^ -p 15000:5000 ^ - -v %~dp0auth:/auth ^ + -v "%~dp0auth":/auth ^ -e "REGISTRY_AUTH=htpasswd" ^ -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" ^ -e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" ^ - -v %~dp0certs:/certs ^ + -v "%~dp0certs":/certs ^ -e "REGISTRY_HTTP_TLS_CERTIFICATE=/certs/registry_auth.crt" ^ -e "REGISTRY_HTTP_TLS_KEY=/certs/registry_auth.key" ^ + -e "REGISTRY_STORAGE_DELETE_ENABLED=true" ^ registry:2.7.0 if %ErrorLevel% neq 0 ( call:print "Failed to create ephemeral Docker registry." @@ -64,8 +65,8 @@ for /L %%i in (1,1,3) do ( call docker build ^ -t tftest-service ^ --build-arg JS_FILE_PATH=server_v%%i.js ^ - %~dp0 ^ - -f %~dp0Dockerfile + -f "%~dp0Dockerfile" ^ + "%~dp0." call docker tag ^ tftest-service ^ 127.0.0.1:15000/tftest-service:v%%i @@ -82,7 +83,7 @@ exit /b %ErrorLevel% :mkdirp - if not exist %~1\nul ( - mkdir %~1 + if not exist "%~1" ( + mkdir "%~1" ) exit /b %ErrorLevel%