Merge pull request #1155 from docker/remove_example_backend

This commit is contained in:
Nicolas De loof 2021-01-19 11:55:19 +01:00 committed by GitHub
commit ed67111b3d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 83 additions and 360 deletions

View File

@ -65,12 +65,11 @@ jobs:
- name: Test - name: Test
env: env:
BUILD_TAGS: example
run: make -f builder.Makefile test run: make -f builder.Makefile test
- name: Build for local E2E - name: Build for local E2E
env: env:
BUILD_TAGS: example,e2e BUILD_TAGS: e2e
run: make -f builder.Makefile cli run: make -f builder.Makefile cli
- name: E2E Test - name: E2E Test

View File

@ -48,13 +48,11 @@ jobs:
key: go-${{ hashFiles('**/go.sum') }} key: go-${{ hashFiles('**/go.sum') }}
- name: Test - name: Test
env:
BUILD_TAGS: example,local
run: make -f builder.Makefile test run: make -f builder.Makefile test
- name: Build - name: Build
env: env:
BUILD_TAGS: example,local,e2e BUILD_TAGS: e2e
run: make -f builder.Makefile cli run: make -f builder.Makefile cli
- name: E2E Test - name: E2E Test

View File

@ -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 You can statically cross compile the CLI for Windows, macOS, and Linux using the
`cross` target. `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 ### Updating the API code
The API provided by the CLI is defined using protobuf. If you make changes to The API provided by the CLI is defined using protobuf. If you make changes to

View File

@ -39,7 +39,7 @@ protos: ## Generate go code from .proto files
cli: ## Compile the cli cli: ## Compile the cli
@docker build . --target cli \ @docker build . --target cli \
--platform local \ --platform local \
--build-arg BUILD_TAGS=example,e2e \ --build-arg BUILD_TAGS=e2e \
--build-arg GIT_TAG=$(GIT_TAG) \ --build-arg GIT_TAG=$(GIT_TAG) \
--output ./bin --output ./bin
@ -63,7 +63,6 @@ cross: ## Compile the CLI for linux, darwin and windows
test: ## Run unit tests test: ## Run unit tests
@docker build . \ @docker build . \
--build-arg BUILD_TAGS=example \
--build-arg GIT_TAG=$(GIT_TAG) \ --build-arg GIT_TAG=$(GIT_TAG) \
--target test --target test
@ -72,7 +71,7 @@ cache-clear: ## Clear the builder cache
lint: ## run linter(s) lint: ## run linter(s)
@docker build . \ @docker build . \
--build-arg BUILD_TAGS=example,e2e \ --build-arg BUILD_TAGS=e2e \
--build-arg GIT_TAG=$(GIT_TAG) \ --build-arg GIT_TAG=$(GIT_TAG) \
--target lint --target lint

View File

@ -61,9 +61,6 @@ type AwsContext EcsContext
// LocalContext is the context for the local backend // LocalContext is the context for the local backend
type LocalContext struct{} type LocalContext struct{}
// ExampleContext is the context for the example backend
type ExampleContext struct{}
// MarshalJSON implements custom JSON marshalling // MarshalJSON implements custom JSON marshalling
func (dc ContextMetadata) MarshalJSON() ([]byte, error) { func (dc ContextMetadata) MarshalJSON() ([]byte, error) {
s := map[string]interface{}{} s := map[string]interface{}{}

View File

@ -55,9 +55,6 @@ const (
// LocalContextType is the endpoint key in the context endpoints for a new // LocalContextType is the endpoint key in the context endpoints for a new
// local backend // local backend
LocalContextType = "local" LocalContextType = "local"
// ExampleContextType is the endpoint key in the context endpoints for an
// example backend
ExampleContextType = "example"
) )
const ( const (
@ -331,8 +328,5 @@ func getters() map[string]func() interface{} {
LocalContextType: func() interface{} { LocalContextType: func() interface{} {
return &LocalContext{} return &LocalContext{}
}, },
ExampleContextType: func() interface{} {
return &ExampleContext{}
},
} }
} }

View File

@ -64,8 +64,8 @@ func TestGetEndpoint(t *testing.T) {
assert.NilError(t, err) assert.NilError(t, err)
assert.Equal(t, ctx.Location, "eu") assert.Equal(t, ctx.Location, "eu")
var exampleCtx ExampleContext var localCtx LocalContext
err = s.GetEndpoint("aci", &exampleCtx) err = s.GetEndpoint("aci", &localCtx)
assert.Error(t, err, "wrong context type") assert.Error(t, err, "wrong context type")
} }

View File

@ -78,7 +78,6 @@ $ docker context create my-context --description "some description" --docker "ho
cmd.AddCommand( cmd.AddCommand(
createLocalCommand(), createLocalCommand(),
createExampleCommand(),
) )
for _, command := range extraCommands { for _, command := range extraCommands {
cmd.AddCommand(command()) cmd.AddCommand(command())
@ -111,22 +110,6 @@ func createLocalCommand() *cobra.Command {
return cmd 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 { func createDockerContext(ctx context.Context, name string, contextType string, description string, data interface{}) error {
s := store.ContextStore(ctx) s := store.ContextStore(ctx)
result := s.Create( result := s.Create(

View File

@ -51,7 +51,6 @@ import (
_ "github.com/docker/compose-cli/aci" _ "github.com/docker/compose-cli/aci"
_ "github.com/docker/compose-cli/ecs" _ "github.com/docker/compose-cli/ecs"
_ "github.com/docker/compose-cli/ecs/local" _ "github.com/docker/compose-cli/ecs/local"
_ "github.com/docker/compose-cli/example"
_ "github.com/docker/compose-cli/local" _ "github.com/docker/compose-cli/local"
) )

View File

@ -20,7 +20,6 @@ These constraints resulted in the following architecture:
What follows is a list of useful links to help navigate the code: What follows is a list of useful links to help navigate the code:
* The CLI UX code is in [`cli/`](../cli) * The CLI UX code is in [`cli/`](../cli)
* The backend interface is defined in [`backend/`](../backend) * 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 is defined by protobufs that can be found in [`protos/`](../protos)
* The API server is in [`server/`](../server) * The API server is in [`server/`](../server)
* The context management and interface can be found in [`context/`](../api/context) * The context management and interface can be found in [`context/`](../api/context)

View File

@ -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
}

View File

@ -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

View File

@ -3,23 +3,14 @@
forbiddenImports: forbiddenImports:
- github.com/docker/compose-cli/cli - github.com/docker/compose-cli/cli
- github.com/docker/compose-cli/ecs - github.com/docker/compose-cli/ecs
- github.com/docker/compose-cli/example
- github.com/docker/compose-cli/local - github.com/docker/compose-cli/local
- path: ./ecs - path: ./ecs
forbiddenImports: forbiddenImports:
- github.com/docker/compose-cli/aci - github.com/docker/compose-cli/aci
- github.com/docker/compose-cli/cli - 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 - github.com/docker/compose-cli/local
- path: ./local - path: ./local
forbiddenImports: forbiddenImports:
- github.com/docker/compose-cli/aci - github.com/docker/compose-cli/aci
- github.com/docker/compose-cli/cli - github.com/docker/compose-cli/cli
- github.com/docker/compose-cli/ecs - github.com/docker/compose-cli/ecs
- github.com/docker/compose-cli/example

View File

@ -189,23 +189,25 @@ func TestContextMetrics(t *testing.T) {
t.Run("metrics on other context type", func(t *testing.T) { t.Run("metrics on other context type", func(t *testing.T) {
s.ResetUsage() s.ResetUsage()
c.RunDockerCmd("context", "create", "example", "test-example") c.RunDockerCmd("context", "create", "local", "test-local")
c.RunDockerCmd("ps") c.RunDockerCmd("ps")
c.RunDockerCmd("context", "use", "test-example") c.RunDockerCmd("context", "use", "test-local")
c.RunDockerCmd("ps") c.RunDockerCmd("ps")
c.RunDockerOrExitError("stop", "unknown") c.RunDockerOrExitError("stop", "unknown")
c.RunDockerCmd("context", "use", "default") c.RunDockerCmd("context", "use", "default")
c.RunDockerCmd("--context", "test-example", "ps") c.RunDockerCmd("--context", "test-local", "ps")
c.RunDockerCmd("context", "ls")
usage := s.GetUsage() usage := s.GetUsage()
assert.DeepEqual(t, []string{ assert.DeepEqual(t, []string{
`{"command":"context create","context":"moby","source":"cli","status":"success"}`, `{"command":"context create","context":"moby","source":"cli","status":"success"}`,
`{"command":"ps","context":"moby","source":"cli","status":"success"}`, `{"command":"ps","context":"moby","source":"cli","status":"success"}`,
`{"command":"context use","context":"moby","source":"cli","status":"success"}`, `{"command":"context use","context":"moby","source":"cli","status":"success"}`,
`{"command":"ps","context":"example","source":"cli","status":"success"}`, `{"command":"ps","context":"local","source":"cli","status":"success"}`,
`{"command":"stop","context":"example","source":"cli","status":"failure"}`, `{"command":"stop","context":"local","source":"cli","status":"failure"}`,
`{"command":"context use","context":"example","source":"cli","status":"success"}`, `{"command":"context use","context":"local","source":"cli","status":"success"}`,
`{"command":"ps","context":"example","source":"cli","status":"success"}`, `{"command":"ps","context":"local","source":"cli","status":"success"}`,
`{"command":"context ls","context":"moby","source":"cli","status":"success"}`,
}, usage) }, usage)
}) })
} }
@ -418,16 +420,15 @@ func TestLegacy(t *testing.T) {
}) })
t.Run("host flag overrides context", func(t *testing.T) { t.Run("host flag overrides context", func(t *testing.T) {
c.RunDockerCmd("context", "create", "example", "test-example") c.RunDockerCmd("context", "create", "local", "test-local")
c.RunDockerCmd("context", "use", "test-example") c.RunDockerCmd("context", "use", "test-local")
endpoint := "unix:///var/run/docker.sock" endpoint := "unix:///var/run/docker.sock"
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
endpoint = "npipe:////./pipe/docker_engine" endpoint = "npipe:////./pipe/docker_engine"
} }
res := c.RunDockerCmd("-H", endpoint, "ps") res := c.RunDockerCmd("-H", endpoint, "images")
// Example backend's ps output includes these strings // Local backend does not have images command
assert.Assert(t, !strings.Contains(res.Stdout(), "id"), "%q does not contains %q", res.Stdout(), "id") assert.Assert(t, strings.Contains(res.Stdout(), "IMAGE ID"), res.Stdout())
assert.Assert(t, !strings.Contains(res.Stdout(), "1234"), "%q does not contains %q", res.Stdout(), "1234")
}) })
} }
@ -459,11 +460,11 @@ func TestLegacyLogin(t *testing.T) {
func TestUnsupportedCommand(t *testing.T) { func TestUnsupportedCommand(t *testing.T) {
c := NewParallelE2eCLI(t, binDir) c := NewParallelE2eCLI(t, binDir)
c.RunDockerCmd("context", "create", "example", "test-example") c.RunDockerCmd("context", "create", "local", "test-local")
res := c.RunDockerOrExitError("--context", "test-example", "images") res := c.RunDockerOrExitError("--context", "test-local", "images")
res.Assert(t, icmd.Expected{ res.Assert(t, icmd.Expected{
ExitCode: 1, 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) { t.Run("delegate version flag", func(t *testing.T) {
c.RunDockerCmd("context", "create", "example", "test-example") c.RunDockerCmd("context", "create", "local", "test-local")
c.RunDockerCmd("context", "use", "test-example") c.RunDockerCmd("context", "use", "test-local")
res := c.RunDockerCmd("-v") res := c.RunDockerCmd("-v")
res.Assert(t, icmd.Expected{Out: "Docker version"}) 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) { func TestFailOnEcsUsageAsPlugin(t *testing.T) {
c := NewParallelE2eCLI(t, binDir) c := NewParallelE2eCLI(t, binDir)
res := c.RunDockerCmd("context", "create", "local", "local") res := c.RunDockerCmd("context", "create", "local", "local")

View File

@ -1,14 +0,0 @@
{
"ID": "id",
"Status": "",
"Image": "nginx",
"HostConfig": {
"RestartPolicy": "none",
"CPUReservation": 0,
"CPULimit": 0,
"MemoryReservation": 0,
"MemoryLimit": 0,
"AutoRemove": false
},
"Platform": "Linux"
}

View File

@ -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

View File

@ -1 +0,0 @@
[{"ID":"id","Image":"nginx","Status":"","Command":"","Ports":[]},{"ID":"1234","Image":"alpine","Status":"","Command":"","Ports":[]}]

View File

@ -1,3 +0,0 @@
CONTAINER ID IMAGE COMMAND STATUS PORTS
id nginx
1234 alpine

View File

@ -1,3 +0,0 @@
id
1234
stopped

View File

@ -1,2 +0,0 @@
id
1234

View File

@ -17,6 +17,7 @@
package main package main
import ( import (
"encoding/json"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"os" "os"
@ -27,10 +28,12 @@ import (
"testing" "testing"
"time" "time"
"gotest.tools/golden"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
"gotest.tools/v3/icmd" "gotest.tools/v3/icmd"
"gotest.tools/v3/poll" "gotest.tools/v3/poll"
"github.com/docker/compose-cli/cli/cmd"
. "github.com/docker/compose-cli/tests/framework" . "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)) 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 { func writeDockerfile(t *testing.T) string {
d, err := ioutil.TempDir("", "") d, err := ioutil.TempDir("", "")
assert.NilError(t, err) assert.NilError(t, err)

View File

@ -1,3 +1,3 @@
NAME TYPE DESCRIPTION DOCKER ENDPOINT KUBERNETES ENDPOINT ORCHESTRATOR NAME TYPE DESCRIPTION DOCKER ENDPOINT KUBERNETES ENDPOINT ORCHESTRATOR
default moby Current DOCKER_HOST based configuration unix:///var/run/docker.sock swarm default moby Current DOCKER_HOST based configuration unix:///var/run/docker.sock swarm
test-example * example test-local * local