Merge pull request #5097 from thaJeztah/context_test_coverage

cli/command/context: improve tests and add coverage for custom metadata in contexts
This commit is contained in:
Sebastiaan van Stijn 2024-05-31 12:24:31 +02:00 committed by GitHub
commit 3da25f6c6d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 102 additions and 36 deletions

View File

@ -24,6 +24,10 @@ type CreateOptions struct {
Description string Description string
Docker map[string]string Docker map[string]string
From string From string
// Additional Metadata to store in the context. This option is not
// currently exposed to the user.
metaData map[string]any
} }
func longCreateDescription() string { func longCreateDescription() string {
@ -94,7 +98,8 @@ func createNewContext(contextStore store.ReaderWriter, o *CreateOptions) error {
docker.DockerEndpoint: dockerEP, docker.DockerEndpoint: dockerEP,
}, },
Metadata: command.DockerContext{ Metadata: command.DockerContext{
Description: o.Description, Description: o.Description,
AdditionalFields: o.metaData,
}, },
Name: o.Name, Name: o.Name,
} }

View File

@ -8,14 +8,18 @@ import (
"path/filepath" "path/filepath"
"testing" "testing"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/streams" "github.com/docker/cli/cli/streams"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
) )
func TestExportImportWithFile(t *testing.T) { func TestExportImportWithFile(t *testing.T) {
contextFile := filepath.Join(t.TempDir(), "exported") contextFile := filepath.Join(t.TempDir(), "exported")
cli := makeFakeCli(t) cli := makeFakeCli(t)
createTestContext(t, cli, "test") createTestContext(t, cli, "test", map[string]any{
"MyCustomMetadata": t.Name(),
})
cli.ErrBuffer().Reset() cli.ErrBuffer().Reset()
assert.NilError(t, RunExport(cli, &ExportOptions{ assert.NilError(t, RunExport(cli, &ExportOptions{
ContextName: "test", ContextName: "test",
@ -29,18 +33,26 @@ func TestExportImportWithFile(t *testing.T) {
assert.NilError(t, err) assert.NilError(t, err)
context2, err := cli.ContextStore().GetMetadata("test2") context2, err := cli.ContextStore().GetMetadata("test2")
assert.NilError(t, err) assert.NilError(t, err)
assert.DeepEqual(t, context1.Endpoints, context2.Endpoints)
assert.DeepEqual(t, context1.Metadata, context2.Metadata)
assert.Equal(t, "test", context1.Name)
assert.Equal(t, "test2", context2.Name)
assert.Equal(t, "test2\n", cli.OutBuffer().String()) assert.Check(t, is.DeepEqual(context1.Metadata, command.DockerContext{
assert.Equal(t, "Successfully imported context \"test2\"\n", cli.ErrBuffer().String()) Description: "description of test",
AdditionalFields: map[string]any{"MyCustomMetadata": t.Name()},
}))
assert.Check(t, is.DeepEqual(context1.Endpoints, context2.Endpoints))
assert.Check(t, is.DeepEqual(context1.Metadata, context2.Metadata))
assert.Check(t, is.Equal("test", context1.Name))
assert.Check(t, is.Equal("test2", context2.Name))
assert.Check(t, is.Equal("test2\n", cli.OutBuffer().String()))
assert.Check(t, is.Equal("Successfully imported context \"test2\"\n", cli.ErrBuffer().String()))
} }
func TestExportImportPipe(t *testing.T) { func TestExportImportPipe(t *testing.T) {
cli := makeFakeCli(t) cli := makeFakeCli(t)
createTestContext(t, cli, "test") createTestContext(t, cli, "test", map[string]any{
"MyCustomMetadata": t.Name(),
})
cli.ErrBuffer().Reset() cli.ErrBuffer().Reset()
cli.OutBuffer().Reset() cli.OutBuffer().Reset()
assert.NilError(t, RunExport(cli, &ExportOptions{ assert.NilError(t, RunExport(cli, &ExportOptions{
@ -56,13 +68,19 @@ func TestExportImportPipe(t *testing.T) {
assert.NilError(t, err) assert.NilError(t, err)
context2, err := cli.ContextStore().GetMetadata("test2") context2, err := cli.ContextStore().GetMetadata("test2")
assert.NilError(t, err) assert.NilError(t, err)
assert.DeepEqual(t, context1.Endpoints, context2.Endpoints)
assert.DeepEqual(t, context1.Metadata, context2.Metadata)
assert.Equal(t, "test", context1.Name)
assert.Equal(t, "test2", context2.Name)
assert.Equal(t, "test2\n", cli.OutBuffer().String()) assert.Check(t, is.DeepEqual(context1.Metadata, command.DockerContext{
assert.Equal(t, "Successfully imported context \"test2\"\n", cli.ErrBuffer().String()) Description: "description of test",
AdditionalFields: map[string]any{"MyCustomMetadata": t.Name()},
}))
assert.Check(t, is.DeepEqual(context1.Endpoints, context2.Endpoints))
assert.Check(t, is.DeepEqual(context1.Metadata, context2.Metadata))
assert.Check(t, is.Equal("test", context1.Name))
assert.Check(t, is.Equal("test2", context2.Name))
assert.Check(t, is.Equal("test2\n", cli.OutBuffer().String()))
assert.Check(t, is.Equal("Successfully imported context \"test2\"\n", cli.ErrBuffer().String()))
} }
func TestExportExistingFile(t *testing.T) { func TestExportExistingFile(t *testing.T) {

View File

@ -10,7 +10,9 @@ import (
func TestInspect(t *testing.T) { func TestInspect(t *testing.T) {
cli := makeFakeCli(t) cli := makeFakeCli(t)
createTestContext(t, cli, "current") createTestContext(t, cli, "current", map[string]any{
"MyCustomMetadata": "MyCustomMetadataValue",
})
cli.OutBuffer().Reset() cli.OutBuffer().Reset()
assert.NilError(t, runInspect(cli, inspectOptions{ assert.NilError(t, runInspect(cli, inspectOptions{
refs: []string{"current"}, refs: []string{"current"},

View File

@ -4,36 +4,70 @@ import (
"testing" "testing"
"github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/formatter"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
"gotest.tools/v3/golden" "gotest.tools/v3/golden"
) )
func createTestContext(t *testing.T, cli command.Cli, name string) { func createTestContexts(t *testing.T, cli command.Cli, name ...string) {
t.Helper()
for _, n := range name {
createTestContext(t, cli, n, nil)
}
}
func createTestContext(t *testing.T, cli command.Cli, name string, metaData map[string]any) {
t.Helper() t.Helper()
err := RunCreate(cli, &CreateOptions{ err := RunCreate(cli, &CreateOptions{
Name: name, Name: name,
Description: "description of " + name, Description: "description of " + name,
Docker: map[string]string{keyHost: "https://someswarmserver.example.com"}, Docker: map[string]string{keyHost: "https://someswarmserver.example.com"},
metaData: metaData,
}) })
assert.NilError(t, err) assert.NilError(t, err)
} }
func TestList(t *testing.T) { func TestList(t *testing.T) {
cli := makeFakeCli(t) cli := makeFakeCli(t)
createTestContext(t, cli, "current") createTestContexts(t, cli, "current", "other", "unset")
createTestContext(t, cli, "other")
createTestContext(t, cli, "unset")
cli.SetCurrentContext("current") cli.SetCurrentContext("current")
cli.OutBuffer().Reset() cli.OutBuffer().Reset()
assert.NilError(t, runList(cli, &listOptions{})) assert.NilError(t, runList(cli, &listOptions{}))
golden.Assert(t, cli.OutBuffer().String(), "list.golden") golden.Assert(t, cli.OutBuffer().String(), "list.golden")
} }
func TestListJSON(t *testing.T) {
cli := makeFakeCli(t)
createTestContext(t, cli, "current", nil)
createTestContext(t, cli, "context1", map[string]any{"Type": "aci"})
createTestContext(t, cli, "context2", map[string]any{"Type": "ecs"})
createTestContext(t, cli, "context3", map[string]any{"Type": "moby"})
cli.SetCurrentContext("current")
t.Run("format={{json .}}", func(t *testing.T) {
cli.OutBuffer().Reset()
assert.NilError(t, runList(cli, &listOptions{format: formatter.JSONFormat}))
golden.Assert(t, cli.OutBuffer().String(), "list-json.golden")
})
t.Run("format=json", func(t *testing.T) {
cli.OutBuffer().Reset()
assert.NilError(t, runList(cli, &listOptions{format: formatter.JSONFormatKey}))
golden.Assert(t, cli.OutBuffer().String(), "list-json.golden")
})
t.Run("format={{ json .Name }}", func(t *testing.T) {
cli.OutBuffer().Reset()
assert.NilError(t, runList(cli, &listOptions{format: `{{ json .Name }}`}))
golden.Assert(t, cli.OutBuffer().String(), "list-json-name.golden")
})
}
func TestListQuiet(t *testing.T) { func TestListQuiet(t *testing.T) {
cli := makeFakeCli(t) cli := makeFakeCli(t)
createTestContext(t, cli, "current") createTestContexts(t, cli, "current", "other")
createTestContext(t, cli, "other")
cli.SetCurrentContext("current") cli.SetCurrentContext("current")
cli.OutBuffer().Reset() cli.OutBuffer().Reset()
assert.NilError(t, runList(cli, &listOptions{quiet: true})) assert.NilError(t, runList(cli, &listOptions{quiet: true}))

View File

@ -13,8 +13,7 @@ import (
func TestRemove(t *testing.T) { func TestRemove(t *testing.T) {
cli := makeFakeCli(t) cli := makeFakeCli(t)
createTestContext(t, cli, "current") createTestContexts(t, cli, "current", "other")
createTestContext(t, cli, "other")
assert.NilError(t, RunRemove(cli, RemoveOptions{}, []string{"other"})) assert.NilError(t, RunRemove(cli, RemoveOptions{}, []string{"other"}))
_, err := cli.ContextStore().GetMetadata("current") _, err := cli.ContextStore().GetMetadata("current")
assert.NilError(t, err) assert.NilError(t, err)
@ -24,8 +23,7 @@ func TestRemove(t *testing.T) {
func TestRemoveNotAContext(t *testing.T) { func TestRemoveNotAContext(t *testing.T) {
cli := makeFakeCli(t) cli := makeFakeCli(t)
createTestContext(t, cli, "current") createTestContexts(t, cli, "current", "other")
createTestContext(t, cli, "other")
err := RunRemove(cli, RemoveOptions{}, []string{"not-a-context"}) err := RunRemove(cli, RemoveOptions{}, []string{"not-a-context"})
assert.ErrorContains(t, err, `context "not-a-context" does not exist`) assert.ErrorContains(t, err, `context "not-a-context" does not exist`)
@ -35,8 +33,7 @@ func TestRemoveNotAContext(t *testing.T) {
func TestRemoveCurrent(t *testing.T) { func TestRemoveCurrent(t *testing.T) {
cli := makeFakeCli(t) cli := makeFakeCli(t)
createTestContext(t, cli, "current") createTestContexts(t, cli, "current", "other")
createTestContext(t, cli, "other")
cli.SetCurrentContext("current") cli.SetCurrentContext("current")
err := RunRemove(cli, RemoveOptions{}, []string{"current"}) err := RunRemove(cli, RemoveOptions{}, []string{"current"})
assert.ErrorContains(t, err, `context "current" is in use, set -f flag to force remove`) assert.ErrorContains(t, err, `context "current" is in use, set -f flag to force remove`)
@ -50,8 +47,7 @@ func TestRemoveCurrentForce(t *testing.T) {
assert.NilError(t, testCfg.Save()) assert.NilError(t, testCfg.Save())
cli := makeFakeCli(t, withCliConfig(testCfg)) cli := makeFakeCli(t, withCliConfig(testCfg))
createTestContext(t, cli, "current") createTestContexts(t, cli, "current", "other")
createTestContext(t, cli, "other")
cli.SetCurrentContext("current") cli.SetCurrentContext("current")
assert.NilError(t, RunRemove(cli, RemoveOptions{Force: true}, []string{"current"})) assert.NilError(t, RunRemove(cli, RemoveOptions{Force: true}, []string{"current"}))
reloadedConfig, err := config.Load(configDir) reloadedConfig, err := config.Load(configDir)
@ -61,7 +57,7 @@ func TestRemoveCurrentForce(t *testing.T) {
func TestRemoveDefault(t *testing.T) { func TestRemoveDefault(t *testing.T) {
cli := makeFakeCli(t) cli := makeFakeCli(t)
createTestContext(t, cli, "other") createTestContext(t, cli, "other", nil)
cli.SetCurrentContext("current") cli.SetCurrentContext("current")
err := RunRemove(cli, RemoveOptions{}, []string{"default"}) err := RunRemove(cli, RemoveOptions{}, []string{"default"})
assert.ErrorContains(t, err, `default: context "default" cannot be removed`) assert.ErrorContains(t, err, `default: context "default" cannot be removed`)

View File

@ -8,7 +8,7 @@ import (
func TestShow(t *testing.T) { func TestShow(t *testing.T) {
cli := makeFakeCli(t) cli := makeFakeCli(t)
createTestContext(t, cli, "current") createTestContext(t, cli, "current", nil)
cli.SetCurrentContext("current") cli.SetCurrentContext("current")
cli.OutBuffer().Reset() cli.OutBuffer().Reset()

View File

@ -2,7 +2,8 @@
{ {
"Name": "current", "Name": "current",
"Metadata": { "Metadata": {
"Description": "description of current" "Description": "description of current",
"MyCustomMetadata": "MyCustomMetadataValue"
}, },
"Endpoints": { "Endpoints": {
"docker": { "docker": {

View File

@ -0,0 +1,5 @@
"context1"
"context2"
"context3"
"current"
"default"

View File

@ -0,0 +1,5 @@
{"Current":false,"Description":"description of context1","DockerEndpoint":"https://someswarmserver.example.com","Error":"","Name":"context1"}
{"Current":false,"Description":"description of context2","DockerEndpoint":"https://someswarmserver.example.com","Error":"","Name":"context2"}
{"Current":false,"Description":"description of context3","DockerEndpoint":"https://someswarmserver.example.com","Error":"","Name":"context3"}
{"Current":true,"Description":"description of current","DockerEndpoint":"https://someswarmserver.example.com","Error":"","Name":"current"}
{"Current":false,"Description":"Current DOCKER_HOST based configuration","DockerEndpoint":"unix:///var/run/docker.sock","Error":"","Name":"default"}

View File

@ -6,7 +6,7 @@ import (
"github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/context/docker" "github.com/docker/cli/cli/context/docker"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
"gotest.tools/v3/assert/cmp" is "gotest.tools/v3/assert/cmp"
) )
func TestUpdateDescriptionOnly(t *testing.T) { func TestUpdateDescriptionOnly(t *testing.T) {
@ -34,7 +34,7 @@ func TestUpdateDescriptionOnly(t *testing.T) {
func TestUpdateDockerOnly(t *testing.T) { func TestUpdateDockerOnly(t *testing.T) {
cli := makeFakeCli(t) cli := makeFakeCli(t)
createTestContext(t, cli, "test") createTestContext(t, cli, "test", nil)
assert.NilError(t, RunUpdate(cli, &UpdateOptions{ assert.NilError(t, RunUpdate(cli, &UpdateOptions{
Name: "test", Name: "test",
Docker: map[string]string{ Docker: map[string]string{
@ -46,7 +46,7 @@ func TestUpdateDockerOnly(t *testing.T) {
dc, err := command.GetDockerContext(c) dc, err := command.GetDockerContext(c)
assert.NilError(t, err) assert.NilError(t, err)
assert.Equal(t, dc.Description, "description of test") assert.Equal(t, dc.Description, "description of test")
assert.Check(t, cmp.Contains(c.Endpoints, docker.DockerEndpoint)) assert.Check(t, is.Contains(c.Endpoints, docker.DockerEndpoint))
assert.Equal(t, c.Endpoints[docker.DockerEndpoint].(docker.EndpointMeta).Host, "tcp://some-host") assert.Equal(t, c.Endpoints[docker.DockerEndpoint].(docker.EndpointMeta).Host, "tcp://some-host")
} }