diff --git a/.github/stale.yml b/.github/stale.yml new file mode 100644 index 00000000..3caf0737 --- /dev/null +++ b/.github/stale.yml @@ -0,0 +1,59 @@ +# Configuration for probot-stale - https://github.com/probot/stale + +# Number of days of inactivity before an Issue or Pull Request becomes stale +daysUntilStale: 180 + +# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. +# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. +daysUntilClose: 7 + +# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) +onlyLabels: [] + +# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable +exemptLabels: + - "enhancement ✨" + +# Set to true to ignore issues in a project (defaults to false) +exemptProjects: false + +# Set to true to ignore issues in a milestone (defaults to false) +exemptMilestones: false + +# Set to true to ignore issues with an assignee (defaults to false) +exemptAssignees: true + +# Label to use when marking as stale +staleLabel: stale + +# Comment to post when marking as stale. Set to `false` to disable +markComment: > + This issue has been automatically marked as stale because it has not had + recent activity. It will be closed if no further activity occurs. Thank you + for your contributions. + +# Comment to post when removing the stale label. +unmarkComment: > + This issue has been automatically marked as not stale anymore due to the recent activity. + +# Comment to post when closing a stale Issue or Pull Request. +closeComment: > + This issue has been automatically closed because it had not recent activity during the stale period. + +# Limit the number of actions per hour, from 1-30. Default is 30 +limitPerRun: 30 + +# Limit to only `issues` or `pulls` +only: issues + +# Optionally, specify configuration settings that are specific to just 'issues' or 'pulls': +# pulls: +# daysUntilStale: 30 +# markComment: > +# This pull request has been automatically marked as stale because it has not had +# recent activity. It will be closed if no further activity occurs. Thank you +# for your contributions. + +# issues: +# exemptLabels: +# - confirmed \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 162c4958..d2af599b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -65,12 +65,11 @@ jobs: - name: Test env: - BUILD_TAGS: example run: make -f builder.Makefile test - name: Build for local E2E env: - BUILD_TAGS: example,e2e + BUILD_TAGS: e2e run: make -f builder.Makefile cli - name: E2E Test diff --git a/.github/workflows/windows-ci.yml b/.github/workflows/windows-ci.yml index 6751d97c..33eafee6 100644 --- a/.github/workflows/windows-ci.yml +++ b/.github/workflows/windows-ci.yml @@ -48,13 +48,11 @@ jobs: key: go-${{ hashFiles('**/go.sum') }} - name: Test - env: - BUILD_TAGS: example,local run: make -f builder.Makefile test - name: Build env: - BUILD_TAGS: example,local,e2e + BUILD_TAGS: e2e run: make -f builder.Makefile cli - name: E2E Test diff --git a/BUILDING.md b/BUILDING.md index 253e6ada..012a30b2 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -35,22 +35,6 @@ This will create a symbolic link from the existing Docker CLI to You can statically cross compile the CLI for Windows, macOS, and Linux using the `cross` target. -### Building with specific backends - -You can specify which backends are build using the `BUILD_TAGS` variable. -The available backends are: -* `aci`: For ACI support (always built) -* `ecs`: For ECS support (always built) -* `example`: Testing backend (off by default) -* `local`: Beginnings of a [moby](https://github.com/moby/moby) backend - (off by default) - -If you want the ACI, ECS and example backends, then you can build as follows: - -```console -make BUILD_TAGS=example cli -``` - ### Updating the API code The API provided by the CLI is defined using protobuf. If you make changes to diff --git a/Makefile b/Makefile index af3a2a91..557852de 100644 --- a/Makefile +++ b/Makefile @@ -39,7 +39,7 @@ protos: ## Generate go code from .proto files cli: ## Compile the cli @docker build . --target cli \ --platform local \ - --build-arg BUILD_TAGS=example,e2e \ + --build-arg BUILD_TAGS=e2e \ --build-arg GIT_TAG=$(GIT_TAG) \ --output ./bin @@ -63,7 +63,6 @@ cross: ## Compile the CLI for linux, darwin and windows test: ## Run unit tests @docker build . \ - --build-arg BUILD_TAGS=example \ --build-arg GIT_TAG=$(GIT_TAG) \ --target test @@ -72,7 +71,7 @@ cache-clear: ## Clear the builder cache lint: ## run linter(s) @docker build . \ - --build-arg BUILD_TAGS=example,e2e \ + --build-arg BUILD_TAGS=e2e \ --build-arg GIT_TAG=$(GIT_TAG) \ --target lint diff --git a/api/context/store/contextmetadata.go b/api/context/store/contextmetadata.go index a34c8313..f8b73211 100644 --- a/api/context/store/contextmetadata.go +++ b/api/context/store/contextmetadata.go @@ -61,9 +61,6 @@ type AwsContext EcsContext // LocalContext is the context for the local backend type LocalContext struct{} -// ExampleContext is the context for the example backend -type ExampleContext struct{} - // MarshalJSON implements custom JSON marshalling func (dc ContextMetadata) MarshalJSON() ([]byte, error) { s := map[string]interface{}{} diff --git a/api/context/store/store.go b/api/context/store/store.go index 78b512ea..b79e862b 100644 --- a/api/context/store/store.go +++ b/api/context/store/store.go @@ -55,9 +55,6 @@ const ( // LocalContextType is the endpoint key in the context endpoints for a new // local backend LocalContextType = "local" - // ExampleContextType is the endpoint key in the context endpoints for an - // example backend - ExampleContextType = "example" ) const ( @@ -331,8 +328,5 @@ func getters() map[string]func() interface{} { LocalContextType: func() interface{} { return &LocalContext{} }, - ExampleContextType: func() interface{} { - return &ExampleContext{} - }, } } diff --git a/api/context/store/store_test.go b/api/context/store/store_test.go index 97e7613e..bb05b584 100644 --- a/api/context/store/store_test.go +++ b/api/context/store/store_test.go @@ -64,8 +64,8 @@ func TestGetEndpoint(t *testing.T) { assert.NilError(t, err) assert.Equal(t, ctx.Location, "eu") - var exampleCtx ExampleContext - err = s.GetEndpoint("aci", &exampleCtx) + var localCtx LocalContext + err = s.GetEndpoint("aci", &localCtx) assert.Error(t, err, "wrong context type") } diff --git a/cli/cmd/context/create.go b/cli/cmd/context/create.go index 65354da8..aa24f15d 100644 --- a/cli/cmd/context/create.go +++ b/cli/cmd/context/create.go @@ -39,7 +39,7 @@ func createCommand() *cobra.Command { longHelp := fmt.Sprintf(`Create a new context -Create docker engine context: +Create docker engine context: $ docker context create CONTEXT [flags] %s @@ -78,7 +78,6 @@ $ docker context create my-context --description "some description" --docker "ho cmd.AddCommand( createLocalCommand(), - createExampleCommand(), ) for _, command := range extraCommands { cmd.AddCommand(command()) @@ -111,22 +110,6 @@ func createLocalCommand() *cobra.Command { return cmd } -func createExampleCommand() *cobra.Command { - var opts descriptionCreateOpts - cmd := &cobra.Command{ - Use: "example CONTEXT", - Short: "Create a test context returning fixed output", - Args: cobra.ExactArgs(1), - Hidden: true, - RunE: func(cmd *cobra.Command, args []string) error { - return createDockerContext(cmd.Context(), args[0], store.ExampleContextType, opts.description, store.ExampleContext{}) - }, - } - - addDescriptionFlag(cmd, &opts.description) - return cmd -} - func createDockerContext(ctx context.Context, name string, contextType string, description string, data interface{}) error { s := store.ContextStore(ctx) result := s.Create( diff --git a/cli/main.go b/cli/main.go index 5a772763..e479004a 100644 --- a/cli/main.go +++ b/cli/main.go @@ -51,7 +51,6 @@ import ( _ "github.com/docker/compose-cli/aci" _ "github.com/docker/compose-cli/ecs" _ "github.com/docker/compose-cli/ecs/local" - _ "github.com/docker/compose-cli/example" _ "github.com/docker/compose-cli/local" ) diff --git a/docs/architecture.md b/docs/architecture.md index e21bb3d6..c5ef2ffc 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -20,7 +20,6 @@ These constraints resulted in the following architecture: What follows is a list of useful links to help navigate the code: * The CLI UX code is in [`cli/`](../cli) * The backend interface is defined in [`backend/`](../backend) - * An example backend can be found in [`example/`](../example) * The API is defined by protobufs that can be found in [`protos/`](../protos) * The API server is in [`server/`](../server) * The context management and interface can be found in [`context/`](../api/context) diff --git a/example/backend.go b/example/backend.go deleted file mode 100644 index 94427fda..00000000 --- a/example/backend.go +++ /dev/null @@ -1,187 +0,0 @@ -// +build example - -/* - Copyright 2020 Docker Compose CLI authors - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package example - -import ( - "context" - "errors" - "fmt" - - "github.com/docker/compose-cli/api/backend" - "github.com/docker/compose-cli/api/cloud" - "github.com/docker/compose-cli/api/compose" - "github.com/docker/compose-cli/api/containers" - "github.com/docker/compose-cli/api/errdefs" - "github.com/docker/compose-cli/api/resources" - "github.com/docker/compose-cli/api/secrets" - "github.com/docker/compose-cli/api/volumes" - - "github.com/compose-spec/compose-go/types" -) - -type apiService struct { - containerService - composeService -} - -func (a *apiService) ContainerService() containers.Service { - return &a.containerService -} - -func (a *apiService) ComposeService() compose.Service { - return &a.composeService -} - -func (a *apiService) SecretsService() secrets.Service { - return nil -} - -func (a *apiService) VolumeService() volumes.Service { - return nil -} - -func (a *apiService) ResourceService() resources.Service { - return nil -} - -func init() { - backend.Register("example", "example", service, cloud.NotImplementedCloudService) -} - -func service(ctx context.Context) (backend.Service, error) { - return &apiService{}, nil -} - -type containerService struct{} - -func (cs *containerService) Inspect(ctx context.Context, id string) (containers.Container, error) { - return containers.Container{ - ID: "id", - Image: "nginx", - Platform: "Linux", - HostConfig: &containers.HostConfig{ - RestartPolicy: "none", - }, - }, nil -} - -func (cs *containerService) List(ctx context.Context, all bool) ([]containers.Container, error) { - result := []containers.Container{ - { - ID: "id", - Image: "nginx", - }, - { - ID: "1234", - Image: "alpine", - }, - } - - if all { - result = append(result, containers.Container{ - ID: "stopped", - Image: "nginx", - }) - } - - return result, nil -} - -func (cs *containerService) Run(ctx context.Context, r containers.ContainerConfig) error { - fmt.Printf("Running container %q with name %q\n", r.Image, r.ID) - return nil -} - -func (cs *containerService) Start(ctx context.Context, containerID string) error { - return errors.New("not implemented") -} - -func (cs *containerService) Stop(ctx context.Context, containerName string, timeout *uint32) error { - return errors.New("not implemented") -} - -func (cs *containerService) Kill(ctx context.Context, containerName string, signal string) error { - return errors.New("not implemented") -} - -func (cs *containerService) Exec(ctx context.Context, name string, request containers.ExecRequest) error { - fmt.Printf("Executing command %q on container %q", request.Command, name) - return nil -} - -func (cs *containerService) Logs(ctx context.Context, containerName string, request containers.LogsRequest) error { - fmt.Fprintf(request.Writer, "Following logs for container %q", containerName) - return nil -} - -func (cs *containerService) Delete(ctx context.Context, id string, request containers.DeleteRequest) error { - fmt.Printf("Deleting container %q with force = %t\n", id, request.Force) - return nil -} - -type composeService struct{} - -func (cs *composeService) Build(ctx context.Context, project *types.Project) error { - fmt.Printf("Build command on project %q", project.Name) - return nil -} - -func (cs *composeService) Push(ctx context.Context, project *types.Project) error { - return errdefs.ErrNotImplemented -} - -func (cs *composeService) Pull(ctx context.Context, project *types.Project) error { - return errdefs.ErrNotImplemented -} - -func (cs *composeService) Create(ctx context.Context, project *types.Project, opts compose.CreateOptions) error { - return errdefs.ErrNotImplemented -} - -func (cs *composeService) Start(ctx context.Context, project *types.Project, consumer compose.LogConsumer) error { - return errdefs.ErrNotImplemented -} - -func (cs *composeService) Up(ctx context.Context, project *types.Project, options compose.UpOptions) error { - - fmt.Printf("Up command on project %q", project.Name) - return nil -} - -func (cs *composeService) Down(ctx context.Context, projectName string, options compose.DownOptions) error { - fmt.Printf("Down command on project %q", projectName) - return nil -} - -func (cs *composeService) Ps(ctx context.Context, projectName string) ([]compose.ContainerSummary, error) { - return nil, errdefs.ErrNotImplemented -} -func (cs *composeService) List(ctx context.Context, project string) ([]compose.Stack, error) { - return nil, errdefs.ErrNotImplemented -} -func (cs *composeService) Logs(ctx context.Context, projectName string, consumer compose.LogConsumer, options compose.LogOptions) error { - return errdefs.ErrNotImplemented -} - -func (cs *composeService) Convert(ctx context.Context, project *types.Project, options compose.ConvertOptions) ([]byte, error) { - return nil, errdefs.ErrNotImplemented -} -func (cs *composeService) RunOneOffContainer(ctx context.Context, project *types.Project, opts compose.RunOptions) error { - return errdefs.ErrNotImplemented -} diff --git a/example/doc.go b/example/doc.go deleted file mode 100644 index a1aa20c8..00000000 --- a/example/doc.go +++ /dev/null @@ -1,17 +0,0 @@ -/* - Copyright 2020 Docker Compose CLI authors - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package example diff --git a/import-restrictions.yaml b/import-restrictions.yaml index 6e03d903..bfbdf32e 100644 --- a/import-restrictions.yaml +++ b/import-restrictions.yaml @@ -3,23 +3,14 @@ forbiddenImports: - github.com/docker/compose-cli/cli - github.com/docker/compose-cli/ecs - - github.com/docker/compose-cli/example - github.com/docker/compose-cli/local - path: ./ecs forbiddenImports: - github.com/docker/compose-cli/aci - github.com/docker/compose-cli/cli - - github.com/docker/compose-cli/example - - github.com/docker/compose-cli/local -- path: ./example - forbiddenImports: - - github.com/docker/compose-cli/aci - - github.com/docker/compose-cli/cli - - github.com/docker/compose-cli/ecs - github.com/docker/compose-cli/local - path: ./local forbiddenImports: - github.com/docker/compose-cli/aci - github.com/docker/compose-cli/cli - github.com/docker/compose-cli/ecs - - github.com/docker/compose-cli/example diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 6dc585d6..2372894c 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -189,23 +189,25 @@ func TestContextMetrics(t *testing.T) { t.Run("metrics on other context type", func(t *testing.T) { s.ResetUsage() - c.RunDockerCmd("context", "create", "example", "test-example") + c.RunDockerCmd("context", "create", "local", "test-local") c.RunDockerCmd("ps") - c.RunDockerCmd("context", "use", "test-example") + c.RunDockerCmd("context", "use", "test-local") c.RunDockerCmd("ps") c.RunDockerOrExitError("stop", "unknown") c.RunDockerCmd("context", "use", "default") - c.RunDockerCmd("--context", "test-example", "ps") + c.RunDockerCmd("--context", "test-local", "ps") + c.RunDockerCmd("context", "ls") usage := s.GetUsage() assert.DeepEqual(t, []string{ `{"command":"context create","context":"moby","source":"cli","status":"success"}`, `{"command":"ps","context":"moby","source":"cli","status":"success"}`, `{"command":"context use","context":"moby","source":"cli","status":"success"}`, - `{"command":"ps","context":"example","source":"cli","status":"success"}`, - `{"command":"stop","context":"example","source":"cli","status":"failure"}`, - `{"command":"context use","context":"example","source":"cli","status":"success"}`, - `{"command":"ps","context":"example","source":"cli","status":"success"}`, + `{"command":"ps","context":"local","source":"cli","status":"success"}`, + `{"command":"stop","context":"local","source":"cli","status":"failure"}`, + `{"command":"context use","context":"local","source":"cli","status":"success"}`, + `{"command":"ps","context":"local","source":"cli","status":"success"}`, + `{"command":"context ls","context":"moby","source":"cli","status":"success"}`, }, usage) }) } @@ -418,16 +420,15 @@ func TestLegacy(t *testing.T) { }) t.Run("host flag overrides context", func(t *testing.T) { - c.RunDockerCmd("context", "create", "example", "test-example") - c.RunDockerCmd("context", "use", "test-example") + c.RunDockerCmd("context", "create", "local", "test-local") + c.RunDockerCmd("context", "use", "test-local") endpoint := "unix:///var/run/docker.sock" if runtime.GOOS == "windows" { endpoint = "npipe:////./pipe/docker_engine" } - res := c.RunDockerCmd("-H", endpoint, "ps") - // Example backend's ps output includes these strings - assert.Assert(t, !strings.Contains(res.Stdout(), "id"), "%q does not contains %q", res.Stdout(), "id") - assert.Assert(t, !strings.Contains(res.Stdout(), "1234"), "%q does not contains %q", res.Stdout(), "1234") + res := c.RunDockerCmd("-H", endpoint, "images") + // Local backend does not have images command + assert.Assert(t, strings.Contains(res.Stdout(), "IMAGE ID"), res.Stdout()) }) } @@ -459,11 +460,11 @@ func TestLegacyLogin(t *testing.T) { func TestUnsupportedCommand(t *testing.T) { c := NewParallelE2eCLI(t, binDir) - c.RunDockerCmd("context", "create", "example", "test-example") - res := c.RunDockerOrExitError("--context", "test-example", "images") + c.RunDockerCmd("context", "create", "local", "test-local") + res := c.RunDockerOrExitError("--context", "test-local", "images") res.Assert(t, icmd.Expected{ ExitCode: 1, - Err: `Command "images" not available in current context (test-example), you can use the "default" context to run this command`, + Err: `Command "images" not available in current context (test-local), you can use the "default" context to run this command`, }) } @@ -519,60 +520,13 @@ func TestVersion(t *testing.T) { }) t.Run("delegate version flag", func(t *testing.T) { - c.RunDockerCmd("context", "create", "example", "test-example") - c.RunDockerCmd("context", "use", "test-example") + c.RunDockerCmd("context", "create", "local", "test-local") + c.RunDockerCmd("context", "use", "test-local") res := c.RunDockerCmd("-v") res.Assert(t, icmd.Expected{Out: "Docker version"}) }) } -func TestMockBackend(t *testing.T) { - c := NewParallelE2eCLI(t, binDir) - c.RunDockerCmd("context", "create", "example", "test-example") - res := c.RunDockerCmd("context", "use", "test-example") - res.Assert(t, icmd.Expected{Out: "test-example"}) - - t.Run("use", func(t *testing.T) { - res := c.RunDockerCmd("context", "show") - res.Assert(t, icmd.Expected{Out: "test-example"}) - res = c.RunDockerCmd("context", "ls") - golden.Assert(t, res.Stdout(), GoldenFile("ls-out-test-example")) - }) - - t.Run("ps", func(t *testing.T) { - res := c.RunDockerCmd("ps") - golden.Assert(t, res.Stdout(), "ps-out-example.golden") - - res = c.RunDockerCmd("ps", "--format", "pretty") - golden.Assert(t, res.Stdout(), "ps-out-example.golden") - - res = c.RunDockerCmd("ps", "--format", "json") - golden.Assert(t, res.Stdout(), "ps-out-example-json.golden") - }) - - t.Run("ps quiet", func(t *testing.T) { - res := c.RunDockerCmd("ps", "-q") - golden.Assert(t, res.Stdout(), "ps-quiet-out-example.golden") - }) - - t.Run("ps quiet all", func(t *testing.T) { - res := c.RunDockerCmd("ps", "-q", "--all") - golden.Assert(t, res.Stdout(), "ps-quiet-all-out-example.golden") - }) - - t.Run("inspect", func(t *testing.T) { - res := c.RunDockerCmd("inspect", "id") - golden.Assert(t, res.Stdout(), "inspect-id.golden") - }) - - t.Run("run", func(t *testing.T) { - res := c.RunDockerCmd("run", "-d", "nginx", "-p", "80:80") - res.Assert(t, icmd.Expected{ - Out: `Running container "nginx" with name`, - }) - }) -} - func TestFailOnEcsUsageAsPlugin(t *testing.T) { c := NewParallelE2eCLI(t, binDir) res := c.RunDockerCmd("context", "create", "local", "local") diff --git a/tests/e2e/testdata/inspect-id.golden b/tests/e2e/testdata/inspect-id.golden deleted file mode 100644 index 1200c98e..00000000 --- a/tests/e2e/testdata/inspect-id.golden +++ /dev/null @@ -1,14 +0,0 @@ -{ - "ID": "id", - "Status": "", - "Image": "nginx", - "HostConfig": { - "RestartPolicy": "none", - "CPUReservation": 0, - "CPULimit": 0, - "MemoryReservation": 0, - "MemoryLimit": 0, - "AutoRemove": false - }, - "Platform": "Linux" -} diff --git a/tests/e2e/testdata/ls-out-test-example-windows.golden b/tests/e2e/testdata/ls-out-test-example-windows.golden deleted file mode 100644 index 95878b1a..00000000 --- a/tests/e2e/testdata/ls-out-test-example-windows.golden +++ /dev/null @@ -1,3 +0,0 @@ -NAME TYPE DESCRIPTION DOCKER ENDPOINT KUBERNETES ENDPOINT ORCHESTRATOR -default moby Current DOCKER_HOST based configuration npipe:////./pipe/docker_engine swarm -test-example * example diff --git a/tests/e2e/testdata/ps-out-example-json.golden b/tests/e2e/testdata/ps-out-example-json.golden deleted file mode 100644 index 90711c02..00000000 --- a/tests/e2e/testdata/ps-out-example-json.golden +++ /dev/null @@ -1 +0,0 @@ -[{"ID":"id","Image":"nginx","Status":"","Command":"","Ports":[]},{"ID":"1234","Image":"alpine","Status":"","Command":"","Ports":[]}] diff --git a/tests/e2e/testdata/ps-out-example.golden b/tests/e2e/testdata/ps-out-example.golden deleted file mode 100644 index ee7ef979..00000000 --- a/tests/e2e/testdata/ps-out-example.golden +++ /dev/null @@ -1,3 +0,0 @@ -CONTAINER ID IMAGE COMMAND STATUS PORTS -id nginx -1234 alpine diff --git a/tests/e2e/testdata/ps-quiet-all-out-example.golden b/tests/e2e/testdata/ps-quiet-all-out-example.golden deleted file mode 100644 index e6a6f81a..00000000 --- a/tests/e2e/testdata/ps-quiet-all-out-example.golden +++ /dev/null @@ -1,3 +0,0 @@ -id -1234 -stopped diff --git a/tests/e2e/testdata/ps-quiet-out-example.golden b/tests/e2e/testdata/ps-quiet-out-example.golden deleted file mode 100644 index ceeb39db..00000000 --- a/tests/e2e/testdata/ps-quiet-out-example.golden +++ /dev/null @@ -1,2 +0,0 @@ -id -1234 diff --git a/tests/skip-win-ci-e2e/skip_win_ci_test.go b/tests/skip-win-ci-e2e/skip_win_ci_test.go index 4cfbb4e9..8a52e2dc 100644 --- a/tests/skip-win-ci-e2e/skip_win_ci_test.go +++ b/tests/skip-win-ci-e2e/skip_win_ci_test.go @@ -17,6 +17,7 @@ package main import ( + "encoding/json" "fmt" "io/ioutil" "os" @@ -27,10 +28,12 @@ import ( "testing" "time" + "gotest.tools/golden" "gotest.tools/v3/assert" "gotest.tools/v3/icmd" "gotest.tools/v3/poll" + "github.com/docker/compose-cli/cli/cmd" . "github.com/docker/compose-cli/tests/framework" ) @@ -92,6 +95,59 @@ func TestKillChildProcess(t *testing.T) { poll.WaitOn(t, buildStopped, poll.WithDelay(1*time.Second), poll.WithTimeout(60*time.Second)) } +// no linux containers on GHA Windows CI nodes (windows server) +func TestLocalContainers(t *testing.T) { + c := NewParallelE2eCLI(t, binDir) + c.RunDockerCmd("context", "create", "local", "test-local") + res := c.RunDockerCmd("context", "use", "test-local") + res.Assert(t, icmd.Expected{Out: "test-local"}) + + t.Run("use", func(t *testing.T) { + res := c.RunDockerCmd("context", "show") + res.Assert(t, icmd.Expected{Out: "test-local"}) + res = c.RunDockerCmd("context", "ls") + golden.Assert(t, res.Stdout(), GoldenFile("ls-out-test-local")) + }) + + var nginxContainerName string + t.Run("run", func(t *testing.T) { + res := c.RunDockerCmd("run", "-d", "-p", "85:80", "nginx") + nginxContainerName = strings.TrimSpace(res.Stdout()) + }) + defer c.RunDockerOrExitError("rm", "-f", nginxContainerName) + + var nginxID string + t.Run("inspect", func(t *testing.T) { + res = c.RunDockerCmd("inspect", nginxContainerName) + + inspect := &cmd.ContainerInspectView{} + err := json.Unmarshal([]byte(res.Stdout()), inspect) + assert.NilError(t, err) + nginxID = inspect.ID + }) + + t.Run("ps", func(t *testing.T) { + res = c.RunDockerCmd("ps") + lines := Lines(res.Stdout()) + nginxFound := false + for _, line := range lines { + fields := strings.Fields(line) + if fields[0] == nginxID { + nginxFound = true + assert.Equal(t, fields[1], "nginx") + assert.Equal(t, fields[2], "/docker-entrypoint.sh") + } + } + assert.Assert(t, nginxFound, res.Stdout()) + + res = c.RunDockerCmd("ps", "--format", "json") + res.Assert(t, icmd.Expected{Out: `"Image":"nginx","Status":"Up Less than a second","Command":"/docker-entrypoint.sh nginx -g 'daemon off;'","Ports":["0.0.0.0:85->80/tcp"`}) + + res = c.RunDockerCmd("ps", "--quiet") + res.Assert(t, icmd.Expected{Out: nginxID + "\n"}) + }) +} + func writeDockerfile(t *testing.T) string { d, err := ioutil.TempDir("", "") assert.NilError(t, err) diff --git a/tests/e2e/testdata/ls-out-test-example.golden b/tests/skip-win-ci-e2e/testdata/ls-out-test-local.golden similarity index 84% rename from tests/e2e/testdata/ls-out-test-example.golden rename to tests/skip-win-ci-e2e/testdata/ls-out-test-local.golden index efdb5180..bfab1219 100644 --- a/tests/e2e/testdata/ls-out-test-example.golden +++ b/tests/skip-win-ci-e2e/testdata/ls-out-test-local.golden @@ -1,3 +1,3 @@ NAME TYPE DESCRIPTION DOCKER ENDPOINT KUBERNETES ENDPOINT ORCHESTRATOR default moby Current DOCKER_HOST based configuration unix:///var/run/docker.sock swarm -test-example * example +test-local * local