From c73998bd2de2ed2159ed9da4e4190535a22e6171 Mon Sep 17 00:00:00 2001 From: "guillaume.tardif" Date: Mon, 8 Jun 2020 14:43:51 +0200 Subject: [PATCH 1/8] Fix e2e tests using golden files on windows --- tests/e2e/e2e_test.go | 4 ++-- tests/e2e/testdata/ls-out-default-windows.golden | 2 ++ tests/e2e/testdata/ls-out-test-example-windows.golden | 3 +++ tests/framework/helper.go | 8 ++++++++ 4 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 tests/e2e/testdata/ls-out-default-windows.golden create mode 100644 tests/e2e/testdata/ls-out-test-example-windows.golden diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 2d250c583..d8bcc2994 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -65,7 +65,7 @@ func (s *E2eSuite) TestContextDefault() { output := s.NewDockerCommand("context", "show").ExecOrDie() Expect(output).To(ContainSubstring("default")) output = s.NewCommand("docker", "context", "ls").ExecOrDie() - golden.Assert(s.T(), output, "ls-out-default.golden") + golden.Assert(s.T(), output, GoldenFile("ls-out-default")) }) } @@ -187,7 +187,7 @@ func (s *E2eSuite) TestMockBackend() { currentContext := s.NewDockerCommand("context", "use", "test-example").ExecOrDie() Expect(currentContext).To(ContainSubstring("test-example")) output := s.NewDockerCommand("context", "ls").ExecOrDie() - golden.Assert(s.T(), output, "ls-out-test-example.golden") + golden.Assert(s.T(), output, GoldenFile("ls-out-test-example")) output = s.NewDockerCommand("context", "show").ExecOrDie() Expect(output).To(ContainSubstring("test-example")) }) diff --git a/tests/e2e/testdata/ls-out-default-windows.golden b/tests/e2e/testdata/ls-out-default-windows.golden new file mode 100644 index 000000000..d1fad0ef4 --- /dev/null +++ b/tests/e2e/testdata/ls-out-default-windows.golden @@ -0,0 +1,2 @@ +NAME TYPE DESCRIPTION DOCKER ENPOINT KUBERNETES ENDPOINT ORCHESTRATOR +default * docker Current DOCKER_HOST based configuration npipe:////./pipe/docker_engine swarm diff --git a/tests/e2e/testdata/ls-out-test-example-windows.golden b/tests/e2e/testdata/ls-out-test-example-windows.golden new file mode 100644 index 000000000..b83ef4c10 --- /dev/null +++ b/tests/e2e/testdata/ls-out-test-example-windows.golden @@ -0,0 +1,3 @@ +NAME TYPE DESCRIPTION DOCKER ENPOINT KUBERNETES ENDPOINT ORCHESTRATOR +default docker Current DOCKER_HOST based configuration npipe:////./pipe/docker_engine swarm +test-example * example diff --git a/tests/framework/helper.go b/tests/framework/helper.go index 2becf2716..cd18b8599 100644 --- a/tests/framework/helper.go +++ b/tests/framework/helper.go @@ -28,6 +28,7 @@ package framework import ( + "runtime" "strings" "github.com/robpike/filter" @@ -48,6 +49,13 @@ func Columns(line string) []string { return filter.Choose(strings.Split(line, " "), nonEmptyString).([]string) } +func GoldenFile(name string) string { + if runtime.GOOS == "windows" { + return name + "-windows.golden" + } + return name + ".golden" +} + // It runs func func It(description string, test func()) { test() From bed0b813439c00c696c6de254de23f27886395cf Mon Sep 17 00:00:00 2001 From: "guillaume.tardif" Date: Mon, 8 Jun 2020 16:50:47 +0200 Subject: [PATCH 2/8] Fix windows E2E suite setup to work properly on windows --- tests/e2e/e2e_test.go | 2 +- tests/framework/suite.go | 42 +++++++++++++++++++++++++++++++--------- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index d8bcc2994..9e76c5ce9 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -106,7 +106,7 @@ func (s *E2eSuite) TestSetupError() { It("should display an error if cannot shell out to docker-classic", func() { err := os.Setenv("PATH", s.BinDir) Expect(err).To(BeNil()) - err = os.Remove(filepath.Join(s.BinDir, "docker-classic")) + err = os.Remove(filepath.Join(s.BinDir, DockerClassicExecutable())) Expect(err).To(BeNil()) output, err := s.NewDockerCommand("ps").Exec() Expect(output).To(ContainSubstring("docker-classic")) diff --git a/tests/framework/suite.go b/tests/framework/suite.go index b27e9a553..d37822b50 100644 --- a/tests/framework/suite.go +++ b/tests/framework/suite.go @@ -62,7 +62,7 @@ func (s *Suite) SetupSuite() { } s.T().Fail() }) - s.linkClassicDocker() + s.copyExecutablesInBinDir() } // TearDownSuite is run after all tests @@ -79,22 +79,35 @@ func dirContents(dir string) []string { return res } -func (s *Suite) linkClassicDocker() { - p, err := exec.LookPath("docker-classic") +func (s *Suite) copyExecutablesInBinDir() { + p, err := exec.LookPath(DockerClassicExecutable()) if err != nil { - p, err = exec.LookPath("docker") + p, err = exec.LookPath(dockerExecutable()) } gomega.Expect(err).To(gomega.BeNil()) - err = os.Symlink(p, filepath.Join(s.BinDir, "docker-classic")) + err = copyFiles(p, filepath.Join(s.BinDir, DockerClassicExecutable())) gomega.Expect(err).To(gomega.BeNil()) - dockerPath, err := filepath.Abs("../../bin/docker") + dockerPath, err := filepath.Abs("../../bin/" + dockerExecutable()) gomega.Expect(err).To(gomega.BeNil()) - err = os.Symlink(dockerPath, filepath.Join(s.BinDir, "docker")) + err = copyFiles(dockerPath, filepath.Join(s.BinDir, dockerExecutable())) gomega.Expect(err).To(gomega.BeNil()) err = os.Setenv("PATH", fmt.Sprintf("%s:%s", s.BinDir, os.Getenv("PATH"))) gomega.Expect(err).To(gomega.BeNil()) } +func copyFiles(sourceFile string, destinationFile string) error { + input, err := ioutil.ReadFile(sourceFile) + if err != nil { + return err + } + + err = ioutil.WriteFile(destinationFile, input, 0644) + if err != nil { + return err + } + return nil +} + // BeforeTest is run before each test func (s *Suite) BeforeTest(suite, test string) { d, _ := ioutil.TempDir("", "") @@ -109,12 +122,16 @@ func (s *Suite) AfterTest(suite, test string) { // ListProcessesCommand creates a command to list processes, "tasklist" on windows, "ps" otherwise. func (s *Suite) ListProcessesCommand() *CmdContext { - if runtime.GOOS == "windows" { + if isWindows() { return s.NewCommand("tasklist") } return s.NewCommand("ps") } +func isWindows() bool { + return runtime.GOOS == "windows" +} + // NewCommand creates a command context. func (s *Suite) NewCommand(command string, args ...string) *CmdContext { return &CmdContext{ @@ -125,12 +142,19 @@ func (s *Suite) NewCommand(command string, args ...string) *CmdContext { } func dockerExecutable() string { - if runtime.GOOS == "windows" { + if isWindows() { return "docker.exe" } return "docker" } +func DockerClassicExecutable() string { + if isWindows() { + return "docker-classic.exe" + } + return "docker-classic" +} + // NewDockerCommand creates a docker builder. func (s *Suite) NewDockerCommand(args ...string) *CmdContext { return s.NewCommand(dockerExecutable(), args...) From c92df92d297ba7d6716dfeb7a368a76cfe67e5c0 Mon Sep 17 00:00:00 2001 From: "guillaume.tardif" Date: Mon, 8 Jun 2020 17:08:54 +0200 Subject: [PATCH 3/8] Fix API Server E2E test using npipe on windows, not sockets --- tests/e2e/e2e_test.go | 13 +++++++++++-- tests/framework/suite.go | 8 ++++---- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 9e76c5ce9..e33ad169c 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -231,17 +231,26 @@ func (s *E2eSuite) TestAPIServer() { cName := "test-example" s.NewDockerCommand("context", "create", cName, "example").ExecOrDie() - sPath := fmt.Sprintf("unix:///%s/docker.sock", s.ConfigDir) + //sPath := fmt.Sprintf("unix:///%s/docker.sock", s.ConfigDir) + sPath, cliAddress := s.getGrpcServerAndCLientAddress() server, err := serveAPI(s.ConfigDir, sPath) Expect(err).To(BeNil()) defer killProcess(server) s.NewCommand("yarn", "install").WithinDirectory("../node-client").ExecOrDie() - output := s.NewCommand("yarn", "run", "start", cName, sPath).WithinDirectory("../node-client").ExecOrDie() + output := s.NewCommand("yarn", "run", "start", cName, cliAddress).WithinDirectory("../node-client").ExecOrDie() Expect(output).To(ContainSubstring("nginx")) }) } +func (s *E2eSuite) getGrpcServerAndCLientAddress() (string, string) { + if IsWindows() { + return "npipe:////./pipe/clibackend", "unix:////./pipe/clibackend" + } + socketName := fmt.Sprintf("unix:///%s/docker.sock", s.ConfigDir) + return socketName, socketName +} + func TestE2e(t *testing.T) { suite.Run(t, new(E2eSuite)) } diff --git a/tests/framework/suite.go b/tests/framework/suite.go index d37822b50..9ff6e5ef6 100644 --- a/tests/framework/suite.go +++ b/tests/framework/suite.go @@ -122,13 +122,13 @@ func (s *Suite) AfterTest(suite, test string) { // ListProcessesCommand creates a command to list processes, "tasklist" on windows, "ps" otherwise. func (s *Suite) ListProcessesCommand() *CmdContext { - if isWindows() { + if IsWindows() { return s.NewCommand("tasklist") } return s.NewCommand("ps") } -func isWindows() bool { +func IsWindows() bool { return runtime.GOOS == "windows" } @@ -142,14 +142,14 @@ func (s *Suite) NewCommand(command string, args ...string) *CmdContext { } func dockerExecutable() string { - if isWindows() { + if IsWindows() { return "docker.exe" } return "docker" } func DockerClassicExecutable() string { - if isWindows() { + if IsWindows() { return "docker-classic.exe" } return "docker-classic" From df6fc2f18f1a9e36eb6108ac3d583e5b1bee9f2f Mon Sep 17 00:00:00 2001 From: "guillaume.tardif" Date: Mon, 8 Jun 2020 21:36:14 +0200 Subject: [PATCH 4/8] Fix volume path setting for linux containers from windows host --- azure/convert/volume.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/azure/convert/volume.go b/azure/convert/volume.go index 0acafdf68..2f05dfd69 100644 --- a/azure/convert/volume.go +++ b/azure/convert/volume.go @@ -3,7 +3,6 @@ package convert import ( "fmt" "net/url" - "path/filepath" "strings" "github.com/pkg/errors" @@ -113,7 +112,8 @@ func (v *volumeInput) parse(name string, s string) error { v.name = name v.target = volumeURL.Path if v.target == "" { - v.target = filepath.Join("/run/volumes/", v.share) + // Do not use filepath.Join, on Windows it will replace / by \ + v.target = "/run/volumes/" + v.share } return nil } From f3f6bff583480faed6aa8c54e35e0a87fef01b62 Mon Sep 17 00:00:00 2001 From: Guillaume Tardif Date: Mon, 8 Jun 2020 17:30:46 +0200 Subject: [PATCH 5/8] Fix linter --- tests/framework/helper.go | 8 +++++++- tests/framework/suite.go | 15 ++++++--------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/tests/framework/helper.go b/tests/framework/helper.go index cd18b8599..d3353f05f 100644 --- a/tests/framework/helper.go +++ b/tests/framework/helper.go @@ -49,13 +49,19 @@ func Columns(line string) []string { return filter.Choose(strings.Split(line, " "), nonEmptyString).([]string) } +// GoldenFile golden file specific to platform func GoldenFile(name string) string { - if runtime.GOOS == "windows" { + if IsWindows() { return name + "-windows.golden" } return name + ".golden" } +// IsWindows windows or other GOOS +func IsWindows() bool { + return runtime.GOOS == "windows" +} + // It runs func func It(description string, test func()) { test() diff --git a/tests/framework/suite.go b/tests/framework/suite.go index 9ff6e5ef6..8a33b2f90 100644 --- a/tests/framework/suite.go +++ b/tests/framework/suite.go @@ -33,7 +33,6 @@ import ( "os" "os/exec" "path/filepath" - "runtime" "time" "github.com/onsi/gomega" @@ -56,6 +55,7 @@ func (s *Suite) SetupSuite() { log.Error(message) cp := filepath.Join(s.ConfigDir, "config.json") d, _ := ioutil.ReadFile(cp) + fmt.Printf("Bin dir:%s\n", s.BinDir) fmt.Printf("Contents of %s:\n%s\n\nContents of config dir:\n", cp, string(d)) for _, p := range dirContents(s.ConfigDir) { fmt.Println(p) @@ -85,23 +85,23 @@ func (s *Suite) copyExecutablesInBinDir() { p, err = exec.LookPath(dockerExecutable()) } gomega.Expect(err).To(gomega.BeNil()) - err = copyFiles(p, filepath.Join(s.BinDir, DockerClassicExecutable())) + err = copyFile(p, filepath.Join(s.BinDir, DockerClassicExecutable())) gomega.Expect(err).To(gomega.BeNil()) dockerPath, err := filepath.Abs("../../bin/" + dockerExecutable()) gomega.Expect(err).To(gomega.BeNil()) - err = copyFiles(dockerPath, filepath.Join(s.BinDir, dockerExecutable())) + err = copyFile(dockerPath, filepath.Join(s.BinDir, dockerExecutable())) gomega.Expect(err).To(gomega.BeNil()) err = os.Setenv("PATH", fmt.Sprintf("%s:%s", s.BinDir, os.Getenv("PATH"))) gomega.Expect(err).To(gomega.BeNil()) } -func copyFiles(sourceFile string, destinationFile string) error { +func copyFile(sourceFile string, destinationFile string) error { input, err := ioutil.ReadFile(sourceFile) if err != nil { return err } - err = ioutil.WriteFile(destinationFile, input, 0644) + err = ioutil.WriteFile(destinationFile, input, 0777) if err != nil { return err } @@ -128,10 +128,6 @@ func (s *Suite) ListProcessesCommand() *CmdContext { return s.NewCommand("ps") } -func IsWindows() bool { - return runtime.GOOS == "windows" -} - // NewCommand creates a command context. func (s *Suite) NewCommand(command string, args ...string) *CmdContext { return &CmdContext{ @@ -148,6 +144,7 @@ func dockerExecutable() string { return "docker" } +// DockerClassicExecutable binary name based on platform func DockerClassicExecutable() string { if IsWindows() { return "docker-classic.exe" From 6bfdded0471fa1b10e311f5ce05eee48cdab28fa Mon Sep 17 00:00:00 2001 From: Guillaume Tardif Date: Mon, 8 Jun 2020 21:13:51 +0200 Subject: [PATCH 6/8] Windows CI --- .gitattributes | 2 ++ .github/workflows/ci.yml | 41 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..9f24d02b5 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +core.autocrlf false +*.golden text eol=lf \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 106971351..09b301b16 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -62,3 +62,44 @@ jobs: - name: E2E Test run: make e2e-local + + + windows-build: + name: Windows Build + runs-on: windows-latest + env: + GO111MODULE: "on" + steps: + - name: Set up Go 1.14 + uses: actions/setup-go@v1 + with: + go-version: 1.14 + id: go + + - name: Checkout code into the Go module directory + uses: actions/checkout@v2 + + - uses: actions/cache@v1 + with: + path: ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go- + + - name: Test + run: make -f builder.Makefile test + + - name: Build + run: make -f builder.Makefile cli + + - name: Install Protoc + uses: arduino/setup-protoc@master + with: + version: "3.9.1" + + - uses: actions/setup-node@v1 + with: + node-version: "10.x" + + - name: E2E Test + run: make e2e-local From 5258906ce37dfacf924b109207a154145f1202f8 Mon Sep 17 00:00:00 2001 From: Guillaume Tardif Date: Mon, 8 Jun 2020 21:52:34 +0200 Subject: [PATCH 7/8] Fix windows PATH for e2e tests --- tests/framework/suite.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/framework/suite.go b/tests/framework/suite.go index 8a33b2f90..91b7e3d2a 100644 --- a/tests/framework/suite.go +++ b/tests/framework/suite.go @@ -91,10 +91,17 @@ func (s *Suite) copyExecutablesInBinDir() { gomega.Expect(err).To(gomega.BeNil()) err = copyFile(dockerPath, filepath.Join(s.BinDir, dockerExecutable())) gomega.Expect(err).To(gomega.BeNil()) - err = os.Setenv("PATH", fmt.Sprintf("%s:%s", s.BinDir, os.Getenv("PATH"))) + err = os.Setenv("PATH", concatenatePath(s.BinDir)) gomega.Expect(err).To(gomega.BeNil()) } +func concatenatePath(path string) string { + if IsWindows() { + return fmt.Sprintf("%s;%s", path, os.Getenv("PATH")) + } + return fmt.Sprintf("%s:%s", path, os.Getenv("PATH")) +} + func copyFile(sourceFile string, destinationFile string) error { input, err := ioutil.ReadFile(sourceFile) if err != nil { From 93984f8c6810be98bed0481c2932d3f01783bf4e Mon Sep 17 00:00:00 2001 From: Guillaume Tardif Date: Tue, 9 Jun 2020 07:22:40 +0200 Subject: [PATCH 8/8] Removed test requiring linux containers --- .gitattributes | 2 +- .github/workflows/ci.yml | 14 +-- Makefile | 5 +- tests/e2e/e2e_test.go | 81 +------------- tests/skip-win-ci-e2e/skip_win_ci_test.go | 127 ++++++++++++++++++++++ 5 files changed, 135 insertions(+), 94 deletions(-) create mode 100644 tests/skip-win-ci-e2e/skip_win_ci_test.go diff --git a/.gitattributes b/.gitattributes index 9f24d02b5..9c91b7996 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,2 @@ core.autocrlf false -*.golden text eol=lf \ No newline at end of file +*.golden text eol=lf diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 09b301b16..889000a07 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: - name: Run golangci-lint run: | curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b . v1.27.0 - ./golangci-lint run + ./golangci-lint run --timeout 10m0s build: name: Build @@ -63,7 +63,6 @@ jobs: - name: E2E Test run: make e2e-local - windows-build: name: Windows Build runs-on: windows-latest @@ -92,14 +91,5 @@ jobs: - name: Build run: make -f builder.Makefile cli - - name: Install Protoc - uses: arduino/setup-protoc@master - with: - version: "3.9.1" - - - uses: actions/setup-node@v1 - with: - node-version: "10.x" - - name: E2E Test - run: make e2e-local + run: make e2e-win-ci diff --git a/Makefile b/Makefile index aec719638..78bf00fb0 100644 --- a/Makefile +++ b/Makefile @@ -37,7 +37,10 @@ cli: ## Compile the cli --output ./bin e2e-local: ## Run End to end local tests - go test -v ./tests/e2e ./moby/e2e + go test -v ./tests/e2e ./tests/skip-win-ci-e2e ./moby/e2e + +e2e-win-ci: ## Run End to end local tests on windows CI, no docker for linux containers available ATM + go test -v ./tests/e2e e2e-aci: ## Run End to end ACI tests (requires azure login) go test -v ./tests/aci-e2e diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index e33ad169c..bd39c83e9 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -28,13 +28,8 @@ package main import ( - "fmt" - "io/ioutil" - "log" "os" - "os/exec" "path/filepath" - "strings" "testing" "time" @@ -115,37 +110,6 @@ func (s *E2eSuite) TestSetupError() { }) } -func (s *E2eSuite) TestKillChildOnCancel() { - It("should kill docker-classic if parent command is cancelled", func() { - out := s.ListProcessesCommand().ExecOrDie() - Expect(out).NotTo(ContainSubstring("docker-classic")) - - dir := s.ConfigDir - Expect(ioutil.WriteFile(filepath.Join(dir, "Dockerfile"), []byte(`FROM alpine:3.10 -RUN sleep 100`), 0644)).To(Succeed()) - shutdown := make(chan time.Time) - errs := make(chan error) - ctx := s.NewDockerCommand("build", "--no-cache", "-t", "test-sleep-image", ".").WithinDirectory(dir).WithTimeout(shutdown) - go func() { - _, err := ctx.Exec() - errs <- err - }() - err := WaitFor(time.Second, 10*time.Second, errs, func() bool { - out := s.ListProcessesCommand().ExecOrDie() - return strings.Contains(out, "docker-classic") - }) - Expect(err).NotTo(HaveOccurred()) - log.Println("Killing docker process") - - close(shutdown) - err = WaitFor(time.Second, 12*time.Second, nil, func() bool { - out := s.ListProcessesCommand().ExecOrDie() - return !strings.Contains(out, "docker-classic") - }) - Expect(err).NotTo(HaveOccurred()) - }) -} - func (s *E2eSuite) TestLegacy() { It("should list all legacy commands", func() { output := s.NewDockerCommand("--help").ExecOrDie() @@ -159,7 +123,7 @@ func (s *E2eSuite) TestLegacy() { It("should run local container in less than 10 secs", func() { s.NewDockerCommand("pull", "hello-world").ExecOrDie() - output := s.NewDockerCommand("run", "--rm", "hello-world").WithTimeout(time.NewTimer(10 * time.Second).C).ExecOrDie() + output := s.NewDockerCommand("run", "--rm", "hello-world").WithTimeout(time.NewTimer(20 * time.Second).C).ExecOrDie() Expect(output).To(ContainSubstring("Hello from Docker!")) }) } @@ -222,49 +186,6 @@ func (s *E2eSuite) TestMockBackend() { }) } -func (s *E2eSuite) TestAPIServer() { - _, err := exec.LookPath("yarn") - if err != nil || os.Getenv("SKIP_NODE") != "" { - s.T().Skip("skipping, yarn not installed") - } - It("can run 'serve' command", func() { - cName := "test-example" - s.NewDockerCommand("context", "create", cName, "example").ExecOrDie() - - //sPath := fmt.Sprintf("unix:///%s/docker.sock", s.ConfigDir) - sPath, cliAddress := s.getGrpcServerAndCLientAddress() - server, err := serveAPI(s.ConfigDir, sPath) - Expect(err).To(BeNil()) - defer killProcess(server) - - s.NewCommand("yarn", "install").WithinDirectory("../node-client").ExecOrDie() - output := s.NewCommand("yarn", "run", "start", cName, cliAddress).WithinDirectory("../node-client").ExecOrDie() - Expect(output).To(ContainSubstring("nginx")) - }) -} - -func (s *E2eSuite) getGrpcServerAndCLientAddress() (string, string) { - if IsWindows() { - return "npipe:////./pipe/clibackend", "unix:////./pipe/clibackend" - } - socketName := fmt.Sprintf("unix:///%s/docker.sock", s.ConfigDir) - return socketName, socketName -} - func TestE2e(t *testing.T) { suite.Run(t, new(E2eSuite)) } - -func killProcess(process *os.Process) { - err := process.Kill() - Expect(err).To(BeNil()) -} - -func serveAPI(configDir string, address string) (*os.Process, error) { - cmd := exec.Command("../../bin/docker", "--config", configDir, "serve", "--address", address) - err := cmd.Start() - if err != nil { - return nil, err - } - return cmd.Process, nil -} diff --git a/tests/skip-win-ci-e2e/skip_win_ci_test.go b/tests/skip-win-ci-e2e/skip_win_ci_test.go new file mode 100644 index 000000000..cf055464c --- /dev/null +++ b/tests/skip-win-ci-e2e/skip_win_ci_test.go @@ -0,0 +1,127 @@ +/* + Copyright (c) 2020 Docker Inc. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH + THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +package main + +import ( + "fmt" + "io/ioutil" + "log" + "os" + "os/exec" + "path/filepath" + "strings" + "testing" + "time" + + . "github.com/onsi/gomega" + "github.com/stretchr/testify/suite" + + . "github.com/docker/api/tests/framework" +) + +type NonWinCIE2eSuite struct { + Suite +} + +func (s *NonWinCIE2eSuite) TestKillChildOnCancel() { + It("should kill docker-classic if parent command is cancelled", func() { + out := s.ListProcessesCommand().ExecOrDie() + Expect(out).NotTo(ContainSubstring("docker-classic")) + + dir := s.ConfigDir + Expect(ioutil.WriteFile(filepath.Join(dir, "Dockerfile"), []byte(`FROM alpine:3.10 +RUN sleep 100`), 0644)).To(Succeed()) + shutdown := make(chan time.Time) + errs := make(chan error) + ctx := s.NewDockerCommand("build", "--no-cache", "-t", "test-sleep-image", ".").WithinDirectory(dir).WithTimeout(shutdown) + go func() { + _, err := ctx.Exec() + errs <- err + }() + err := WaitFor(time.Second, 10*time.Second, errs, func() bool { + out := s.ListProcessesCommand().ExecOrDie() + return strings.Contains(out, "docker-classic") + }) + Expect(err).NotTo(HaveOccurred()) + log.Println("Killing docker process") + + close(shutdown) + err = WaitFor(time.Second, 12*time.Second, nil, func() bool { + out := s.ListProcessesCommand().ExecOrDie() + return !strings.Contains(out, "docker-classic") + }) + Expect(err).NotTo(HaveOccurred()) + }) +} + +func (s *NonWinCIE2eSuite) TestAPIServer() { + _, err := exec.LookPath("yarn") + if err != nil || os.Getenv("SKIP_NODE") != "" { + s.T().Skip("skipping, yarn not installed") + } + It("can run 'serve' command", func() { + cName := "test-example" + s.NewDockerCommand("context", "create", cName, "example").ExecOrDie() + + //sPath := fmt.Sprintf("unix:///%s/docker.sock", s.ConfigDir) + sPath, cliAddress := s.getGrpcServerAndCLientAddress() + server, err := serveAPI(s.ConfigDir, sPath) + Expect(err).To(BeNil()) + defer killProcess(server) + + s.NewCommand("yarn", "install").WithinDirectory("../node-client").ExecOrDie() + output := s.NewCommand("yarn", "run", "start", cName, cliAddress).WithinDirectory("../node-client").ExecOrDie() + Expect(output).To(ContainSubstring("nginx")) + }) +} + +func (s *NonWinCIE2eSuite) getGrpcServerAndCLientAddress() (string, string) { + if IsWindows() { + return "npipe:////./pipe/clibackend", "unix:////./pipe/clibackend" + } + socketName := fmt.Sprintf("unix:///%s/docker.sock", s.ConfigDir) + return socketName, socketName +} + +func TestE2e(t *testing.T) { + suite.Run(t, new(NonWinCIE2eSuite)) +} + +func killProcess(process *os.Process) { + err := process.Kill() + Expect(err).To(BeNil()) +} + +func serveAPI(configDir string, address string) (*os.Process, error) { + cmd := exec.Command("../../bin/docker", "--config", configDir, "serve", "--address", address) + err := cmd.Start() + if err != nil { + return nil, err + } + return cmd.Process, nil +}