mirror of https://github.com/docker/cli.git
272 lines
7.4 KiB
Go
272 lines
7.4 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/docker/docker/api/types"
|
|
"github.com/docker/docker/api/types/swarm"
|
|
"gotest.tools/v3/assert"
|
|
is "gotest.tools/v3/assert/cmp"
|
|
|
|
cliopts "github.com/docker/cli/opts"
|
|
)
|
|
|
|
// fakeConfigAPIClientList is used to let us pass a closure as a
|
|
// ConfigAPIClient, to use as ConfigList. for all the other methods in the
|
|
// interface, it does nothing, not even return an error, so don't use them
|
|
type fakeConfigAPIClientList func(context.Context, types.ConfigListOptions) ([]swarm.Config, error)
|
|
|
|
func (f fakeConfigAPIClientList) ConfigList(ctx context.Context, opts types.ConfigListOptions) ([]swarm.Config, error) {
|
|
return f(ctx, opts)
|
|
}
|
|
|
|
func (f fakeConfigAPIClientList) ConfigCreate(_ context.Context, _ swarm.ConfigSpec) (types.ConfigCreateResponse, error) {
|
|
return types.ConfigCreateResponse{}, nil
|
|
}
|
|
|
|
func (f fakeConfigAPIClientList) ConfigRemove(_ context.Context, _ string) error {
|
|
return nil
|
|
}
|
|
|
|
func (f fakeConfigAPIClientList) ConfigInspectWithRaw(_ context.Context, _ string) (swarm.Config, []byte, error) {
|
|
return swarm.Config{}, nil, nil
|
|
}
|
|
|
|
func (f fakeConfigAPIClientList) ConfigUpdate(_ context.Context, _ string, _ swarm.Version, _ swarm.ConfigSpec) error {
|
|
return nil
|
|
}
|
|
|
|
// TestSetConfigsWithCredSpecAndConfigs tests that the setConfigs function for
|
|
// create correctly looks up the right configs, and correctly handles the
|
|
// credentialSpec
|
|
func TestSetConfigsWithCredSpecAndConfigs(t *testing.T) {
|
|
// we can't directly access the internal fields of the ConfigOpt struct, so
|
|
// we need to let it do the parsing
|
|
configOpt := &cliopts.ConfigOpt{}
|
|
configOpt.Set("bar")
|
|
opts := &serviceOptions{
|
|
credentialSpec: credentialSpecOpt{
|
|
value: &swarm.CredentialSpec{
|
|
Config: "foo",
|
|
},
|
|
source: "config://foo",
|
|
},
|
|
configs: *configOpt,
|
|
}
|
|
|
|
// create a service spec. we need to be sure to fill in the nullable
|
|
// fields, like the code expects
|
|
service := &swarm.ServiceSpec{
|
|
TaskTemplate: swarm.TaskSpec{
|
|
ContainerSpec: &swarm.ContainerSpec{
|
|
Privileges: &swarm.Privileges{
|
|
CredentialSpec: opts.credentialSpec.value,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
// set up a function to use as the list function
|
|
var fakeClient fakeConfigAPIClientList = func(_ context.Context, opts types.ConfigListOptions) ([]swarm.Config, error) {
|
|
f := opts.Filters
|
|
|
|
// we're expecting the filter to have names "foo" and "bar"
|
|
names := f.Get("name")
|
|
assert.Equal(t, len(names), 2)
|
|
assert.Assert(t, is.Contains(names, "foo"))
|
|
assert.Assert(t, is.Contains(names, "bar"))
|
|
|
|
return []swarm.Config{
|
|
{
|
|
ID: "fooID",
|
|
Spec: swarm.ConfigSpec{
|
|
Annotations: swarm.Annotations{
|
|
Name: "foo",
|
|
},
|
|
},
|
|
}, {
|
|
ID: "barID",
|
|
Spec: swarm.ConfigSpec{
|
|
Annotations: swarm.Annotations{
|
|
Name: "bar",
|
|
},
|
|
},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
// now call setConfigs
|
|
err := setConfigs(fakeClient, service, opts)
|
|
// verify no error is returned
|
|
assert.NilError(t, err)
|
|
|
|
credSpecConfigValue := service.TaskTemplate.ContainerSpec.Privileges.CredentialSpec.Config
|
|
assert.Equal(t, credSpecConfigValue, "fooID")
|
|
|
|
configRefs := service.TaskTemplate.ContainerSpec.Configs
|
|
assert.Assert(t, is.Contains(configRefs, &swarm.ConfigReference{
|
|
ConfigID: "fooID",
|
|
ConfigName: "foo",
|
|
Runtime: &swarm.ConfigReferenceRuntimeTarget{},
|
|
}), "expected configRefs to contain foo config")
|
|
assert.Assert(t, is.Contains(configRefs, &swarm.ConfigReference{
|
|
ConfigID: "barID",
|
|
ConfigName: "bar",
|
|
File: &swarm.ConfigReferenceFileTarget{
|
|
Name: "bar",
|
|
// these are the default field values
|
|
UID: "0",
|
|
GID: "0",
|
|
Mode: 0o444,
|
|
},
|
|
}), "expected configRefs to contain bar config")
|
|
}
|
|
|
|
// TestSetConfigsOnlyCredSpec tests that even if a CredentialSpec is the only
|
|
// config needed, setConfigs still works
|
|
func TestSetConfigsOnlyCredSpec(t *testing.T) {
|
|
opts := &serviceOptions{
|
|
credentialSpec: credentialSpecOpt{
|
|
value: &swarm.CredentialSpec{
|
|
Config: "foo",
|
|
},
|
|
source: "config://foo",
|
|
},
|
|
}
|
|
|
|
service := &swarm.ServiceSpec{
|
|
TaskTemplate: swarm.TaskSpec{
|
|
ContainerSpec: &swarm.ContainerSpec{
|
|
Privileges: &swarm.Privileges{
|
|
CredentialSpec: opts.credentialSpec.value,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
// set up a function to use as the list function
|
|
var fakeClient fakeConfigAPIClientList = func(_ context.Context, opts types.ConfigListOptions) ([]swarm.Config, error) {
|
|
f := opts.Filters
|
|
|
|
names := f.Get("name")
|
|
assert.Equal(t, len(names), 1)
|
|
assert.Assert(t, is.Contains(names, "foo"))
|
|
|
|
return []swarm.Config{
|
|
{
|
|
ID: "fooID",
|
|
Spec: swarm.ConfigSpec{
|
|
Annotations: swarm.Annotations{
|
|
Name: "foo",
|
|
},
|
|
},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
// now call setConfigs
|
|
err := setConfigs(fakeClient, service, opts)
|
|
// verify no error is returned
|
|
assert.NilError(t, err)
|
|
|
|
credSpecConfigValue := service.TaskTemplate.ContainerSpec.Privileges.CredentialSpec.Config
|
|
assert.Equal(t, credSpecConfigValue, "fooID")
|
|
|
|
configRefs := service.TaskTemplate.ContainerSpec.Configs
|
|
assert.Assert(t, is.Contains(configRefs, &swarm.ConfigReference{
|
|
ConfigID: "fooID",
|
|
ConfigName: "foo",
|
|
Runtime: &swarm.ConfigReferenceRuntimeTarget{},
|
|
}))
|
|
}
|
|
|
|
// TestSetConfigsOnlyConfigs verifies setConfigs when only configs (and not a
|
|
// CredentialSpec) is needed.
|
|
func TestSetConfigsOnlyConfigs(t *testing.T) {
|
|
configOpt := &cliopts.ConfigOpt{}
|
|
configOpt.Set("bar")
|
|
opts := &serviceOptions{
|
|
configs: *configOpt,
|
|
}
|
|
|
|
service := &swarm.ServiceSpec{
|
|
TaskTemplate: swarm.TaskSpec{
|
|
ContainerSpec: &swarm.ContainerSpec{},
|
|
},
|
|
}
|
|
|
|
var fakeClient fakeConfigAPIClientList = func(_ context.Context, opts types.ConfigListOptions) ([]swarm.Config, error) {
|
|
f := opts.Filters
|
|
|
|
names := f.Get("name")
|
|
assert.Equal(t, len(names), 1)
|
|
assert.Assert(t, is.Contains(names, "bar"))
|
|
|
|
return []swarm.Config{
|
|
{
|
|
ID: "barID",
|
|
Spec: swarm.ConfigSpec{
|
|
Annotations: swarm.Annotations{
|
|
Name: "bar",
|
|
},
|
|
},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
// now call setConfigs
|
|
err := setConfigs(fakeClient, service, opts)
|
|
// verify no error is returned
|
|
assert.NilError(t, err)
|
|
|
|
configRefs := service.TaskTemplate.ContainerSpec.Configs
|
|
assert.Assert(t, is.Contains(configRefs, &swarm.ConfigReference{
|
|
ConfigID: "barID",
|
|
ConfigName: "bar",
|
|
File: &swarm.ConfigReferenceFileTarget{
|
|
Name: "bar",
|
|
// these are the default field values
|
|
UID: "0",
|
|
GID: "0",
|
|
Mode: 0o444,
|
|
},
|
|
}))
|
|
}
|
|
|
|
// TestSetConfigsNoConfigs checks that setConfigs works when there are no
|
|
// configs of any kind needed
|
|
func TestSetConfigsNoConfigs(t *testing.T) {
|
|
// add a credentialSpec that isn't a config
|
|
opts := &serviceOptions{
|
|
credentialSpec: credentialSpecOpt{
|
|
value: &swarm.CredentialSpec{
|
|
File: "foo",
|
|
},
|
|
source: "file://foo",
|
|
},
|
|
}
|
|
service := &swarm.ServiceSpec{
|
|
TaskTemplate: swarm.TaskSpec{
|
|
ContainerSpec: &swarm.ContainerSpec{
|
|
Privileges: &swarm.Privileges{
|
|
CredentialSpec: opts.credentialSpec.value,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
var fakeClient fakeConfigAPIClientList = func(_ context.Context, opts types.ConfigListOptions) ([]swarm.Config, error) {
|
|
// assert false -- we should never call this function
|
|
assert.Assert(t, false, "we should not be listing configs")
|
|
return nil, nil
|
|
}
|
|
|
|
err := setConfigs(fakeClient, service, opts)
|
|
assert.NilError(t, err)
|
|
|
|
// ensure that the value of the credentialspec has not changed
|
|
assert.Equal(t, service.TaskTemplate.ContainerSpec.Privileges.CredentialSpec.File, "foo")
|
|
assert.Equal(t, service.TaskTemplate.ContainerSpec.Privileges.CredentialSpec.Config, "")
|
|
}
|