Replace service ps cli tests with service inspect API test.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
This commit is contained in:
parent
98a4613017
commit
6cd6d8646a
|
@ -69,9 +69,7 @@ func (s *DockerSwarmSuite) TestAPISwarmServicesCreate(c *check.C) {
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
defer cli.Close()
|
defer cli.Close()
|
||||||
|
|
||||||
options := types.ServiceInspectOptions{
|
options := types.ServiceInspectOptions{InsertDefaults: true}
|
||||||
InsertDefaults: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
// insertDefaults inserts UpdateConfig when service is fetched by ID
|
// insertDefaults inserts UpdateConfig when service is fetched by ID
|
||||||
resp, _, err := cli.ServiceInspectWithRaw(context.Background(), id, options)
|
resp, _, err := cli.ServiceInspectWithRaw(context.Background(), id, options)
|
||||||
|
|
|
@ -1534,22 +1534,6 @@ func (s *DockerSwarmSuite) TestSwarmManagerAddress(c *check.C) {
|
||||||
c.Assert(out, checker.Contains, expectedOutput)
|
c.Assert(out, checker.Contains, expectedOutput)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DockerSwarmSuite) TestSwarmServiceInspectPretty(c *check.C) {
|
|
||||||
d := s.AddDaemon(c, true, true)
|
|
||||||
|
|
||||||
name := "top"
|
|
||||||
out, err := d.Cmd("service", "create", "--no-resolve-image", "--name", name, "--limit-cpu=0.5", "busybox", "top")
|
|
||||||
c.Assert(err, checker.IsNil, check.Commentf(out))
|
|
||||||
|
|
||||||
expectedOutput := `
|
|
||||||
Resources:
|
|
||||||
Limits:
|
|
||||||
CPU: 0.5`
|
|
||||||
out, err = d.Cmd("service", "inspect", "--pretty", name)
|
|
||||||
c.Assert(err, checker.IsNil, check.Commentf(out))
|
|
||||||
c.Assert(out, checker.Contains, expectedOutput, check.Commentf(out))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *DockerSwarmSuite) TestSwarmNetworkIPAMOptions(c *check.C) {
|
func (s *DockerSwarmSuite) TestSwarmNetworkIPAMOptions(c *check.C) {
|
||||||
d := s.AddDaemon(c, true, true)
|
d := s.AddDaemon(c, true, true)
|
||||||
|
|
||||||
|
@ -1691,76 +1675,6 @@ func (s *DockerSwarmSuite) TestSwarmNetworkCreateDup(c *check.C) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DockerSwarmSuite) TestSwarmServicePsMultipleServiceIDs(c *check.C) {
|
|
||||||
d := s.AddDaemon(c, true, true)
|
|
||||||
|
|
||||||
name1 := "top1"
|
|
||||||
out, err := d.Cmd("service", "create", "--no-resolve-image", "--detach=true", "--name", name1, "--replicas=3", "busybox", "top")
|
|
||||||
c.Assert(err, checker.IsNil)
|
|
||||||
c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "")
|
|
||||||
id1 := strings.TrimSpace(out)
|
|
||||||
|
|
||||||
name2 := "top2"
|
|
||||||
out, err = d.Cmd("service", "create", "--no-resolve-image", "--detach=true", "--name", name2, "--replicas=3", "busybox", "top")
|
|
||||||
c.Assert(err, checker.IsNil)
|
|
||||||
c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "")
|
|
||||||
id2 := strings.TrimSpace(out)
|
|
||||||
|
|
||||||
// make sure task has been deployed.
|
|
||||||
waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, 6)
|
|
||||||
|
|
||||||
out, err = d.Cmd("service", "ps", name1)
|
|
||||||
c.Assert(err, checker.IsNil)
|
|
||||||
c.Assert(out, checker.Contains, name1+".1")
|
|
||||||
c.Assert(out, checker.Contains, name1+".2")
|
|
||||||
c.Assert(out, checker.Contains, name1+".3")
|
|
||||||
c.Assert(out, checker.Not(checker.Contains), name2+".1")
|
|
||||||
c.Assert(out, checker.Not(checker.Contains), name2+".2")
|
|
||||||
c.Assert(out, checker.Not(checker.Contains), name2+".3")
|
|
||||||
|
|
||||||
out, err = d.Cmd("service", "ps", name1, name2)
|
|
||||||
c.Assert(err, checker.IsNil)
|
|
||||||
c.Assert(out, checker.Contains, name1+".1")
|
|
||||||
c.Assert(out, checker.Contains, name1+".2")
|
|
||||||
c.Assert(out, checker.Contains, name1+".3")
|
|
||||||
c.Assert(out, checker.Contains, name2+".1")
|
|
||||||
c.Assert(out, checker.Contains, name2+".2")
|
|
||||||
c.Assert(out, checker.Contains, name2+".3")
|
|
||||||
|
|
||||||
// Name Prefix
|
|
||||||
out, err = d.Cmd("service", "ps", "to")
|
|
||||||
c.Assert(err, checker.IsNil)
|
|
||||||
c.Assert(out, checker.Contains, name1+".1")
|
|
||||||
c.Assert(out, checker.Contains, name1+".2")
|
|
||||||
c.Assert(out, checker.Contains, name1+".3")
|
|
||||||
c.Assert(out, checker.Contains, name2+".1")
|
|
||||||
c.Assert(out, checker.Contains, name2+".2")
|
|
||||||
c.Assert(out, checker.Contains, name2+".3")
|
|
||||||
|
|
||||||
// Name Prefix (no hit)
|
|
||||||
out, err = d.Cmd("service", "ps", "noname")
|
|
||||||
c.Assert(err, checker.NotNil)
|
|
||||||
c.Assert(out, checker.Contains, "no such services: noname")
|
|
||||||
|
|
||||||
out, err = d.Cmd("service", "ps", id1)
|
|
||||||
c.Assert(err, checker.IsNil)
|
|
||||||
c.Assert(out, checker.Contains, name1+".1")
|
|
||||||
c.Assert(out, checker.Contains, name1+".2")
|
|
||||||
c.Assert(out, checker.Contains, name1+".3")
|
|
||||||
c.Assert(out, checker.Not(checker.Contains), name2+".1")
|
|
||||||
c.Assert(out, checker.Not(checker.Contains), name2+".2")
|
|
||||||
c.Assert(out, checker.Not(checker.Contains), name2+".3")
|
|
||||||
|
|
||||||
out, err = d.Cmd("service", "ps", id1, id2)
|
|
||||||
c.Assert(err, checker.IsNil)
|
|
||||||
c.Assert(out, checker.Contains, name1+".1")
|
|
||||||
c.Assert(out, checker.Contains, name1+".2")
|
|
||||||
c.Assert(out, checker.Contains, name1+".3")
|
|
||||||
c.Assert(out, checker.Contains, name2+".1")
|
|
||||||
c.Assert(out, checker.Contains, name2+".2")
|
|
||||||
c.Assert(out, checker.Contains, name2+".3")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *DockerSwarmSuite) TestSwarmPublishDuplicatePorts(c *check.C) {
|
func (s *DockerSwarmSuite) TestSwarmPublishDuplicatePorts(c *check.C) {
|
||||||
d := s.AddDaemon(c, true, true)
|
d := s.AddDaemon(c, true, true)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,145 @@
|
||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/docker/docker/api/types"
|
||||||
|
"github.com/docker/docker/api/types/filters"
|
||||||
|
"github.com/docker/docker/api/types/swarm"
|
||||||
|
"github.com/docker/docker/client"
|
||||||
|
"github.com/docker/docker/integration-cli/daemon"
|
||||||
|
"github.com/docker/docker/integration-cli/request"
|
||||||
|
"github.com/gotestyourself/gotestyourself/poll"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"golang.org/x/net/context"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestInspect(t *testing.T) {
|
||||||
|
d := newSwarm(t)
|
||||||
|
defer d.Stop(t)
|
||||||
|
client, err := request.NewClientForHost(d.Sock())
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
var before = time.Now()
|
||||||
|
var instances uint64 = 2
|
||||||
|
serviceSpec := fullSwarmServiceSpec("test-service-inspect", instances)
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
resp, err := client.ServiceCreate(ctx, serviceSpec, types.ServiceCreateOptions{
|
||||||
|
QueryRegistry: false,
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
id := resp.ID
|
||||||
|
poll.WaitOn(t, serviceContainerCount(client, id, instances))
|
||||||
|
|
||||||
|
service, _, err := client.ServiceInspectWithRaw(ctx, id, types.ServiceInspectOptions{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, serviceSpec, service.Spec)
|
||||||
|
assert.Equal(t, uint64(11), service.Meta.Version.Index)
|
||||||
|
assert.Equal(t, id, service.ID)
|
||||||
|
assert.WithinDuration(t, before, service.CreatedAt, 30*time.Second)
|
||||||
|
assert.WithinDuration(t, before, service.UpdatedAt, 30*time.Second)
|
||||||
|
}
|
||||||
|
|
||||||
|
func fullSwarmServiceSpec(name string, replicas uint64) swarm.ServiceSpec {
|
||||||
|
restartDelay := 100 * time.Millisecond
|
||||||
|
maxAttempts := uint64(4)
|
||||||
|
|
||||||
|
return swarm.ServiceSpec{
|
||||||
|
Annotations: swarm.Annotations{
|
||||||
|
Name: name,
|
||||||
|
Labels: map[string]string{
|
||||||
|
"service-label": "service-label-value",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
TaskTemplate: swarm.TaskSpec{
|
||||||
|
ContainerSpec: &swarm.ContainerSpec{
|
||||||
|
Image: "busybox:latest",
|
||||||
|
Labels: map[string]string{"container-label": "container-value"},
|
||||||
|
Command: []string{"/bin/top"},
|
||||||
|
Args: []string{"-u", "root"},
|
||||||
|
Hostname: "hostname",
|
||||||
|
Env: []string{"envvar=envvalue"},
|
||||||
|
Dir: "/work",
|
||||||
|
User: "root",
|
||||||
|
StopSignal: "SIGINT",
|
||||||
|
StopGracePeriod: &restartDelay,
|
||||||
|
Hosts: []string{"8.8.8.8 google"},
|
||||||
|
DNSConfig: &swarm.DNSConfig{
|
||||||
|
Nameservers: []string{"8.8.8.8"},
|
||||||
|
Search: []string{"somedomain"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
RestartPolicy: &swarm.RestartPolicy{
|
||||||
|
Delay: &restartDelay,
|
||||||
|
Condition: swarm.RestartPolicyConditionOnFailure,
|
||||||
|
MaxAttempts: &maxAttempts,
|
||||||
|
},
|
||||||
|
Runtime: swarm.RuntimeContainer,
|
||||||
|
},
|
||||||
|
Mode: swarm.ServiceMode{
|
||||||
|
Replicated: &swarm.ReplicatedService{
|
||||||
|
Replicas: &replicas,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
UpdateConfig: &swarm.UpdateConfig{
|
||||||
|
Parallelism: 2,
|
||||||
|
Delay: 200 * time.Second,
|
||||||
|
FailureAction: swarm.UpdateFailureActionContinue,
|
||||||
|
Monitor: 2 * time.Second,
|
||||||
|
MaxFailureRatio: 0.2,
|
||||||
|
Order: swarm.UpdateOrderStopFirst,
|
||||||
|
},
|
||||||
|
RollbackConfig: &swarm.UpdateConfig{
|
||||||
|
Parallelism: 3,
|
||||||
|
Delay: 300 * time.Second,
|
||||||
|
FailureAction: swarm.UpdateFailureActionPause,
|
||||||
|
Monitor: 3 * time.Second,
|
||||||
|
MaxFailureRatio: 0.3,
|
||||||
|
Order: swarm.UpdateOrderStartFirst,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultSwarmPort = 2477
|
||||||
|
|
||||||
|
func newSwarm(t *testing.T) *daemon.Swarm {
|
||||||
|
d := &daemon.Swarm{
|
||||||
|
Daemon: daemon.New(t, "", dockerdBinary, daemon.Config{
|
||||||
|
Experimental: testEnv.ExperimentalDaemon(),
|
||||||
|
}),
|
||||||
|
// TODO: better method of finding an unused port
|
||||||
|
Port: defaultSwarmPort,
|
||||||
|
}
|
||||||
|
// TODO: move to a NewSwarm constructor
|
||||||
|
d.ListenAddr = fmt.Sprintf("0.0.0.0:%d", d.Port)
|
||||||
|
|
||||||
|
// avoid networking conflicts
|
||||||
|
args := []string{"--iptables=false", "--swarm-default-advertise-addr=lo"}
|
||||||
|
d.StartWithBusybox(t, args...)
|
||||||
|
|
||||||
|
require.NoError(t, d.Init(swarm.InitRequest{}))
|
||||||
|
return d
|
||||||
|
}
|
||||||
|
|
||||||
|
func serviceContainerCount(client client.ServiceAPIClient, id string, count uint64) func(log poll.LogT) poll.Result {
|
||||||
|
return func(log poll.LogT) poll.Result {
|
||||||
|
filter := filters.NewArgs()
|
||||||
|
filter.Add("service", id)
|
||||||
|
tasks, err := client.TaskList(context.Background(), types.TaskListOptions{
|
||||||
|
Filters: filter,
|
||||||
|
})
|
||||||
|
switch {
|
||||||
|
case err != nil:
|
||||||
|
return poll.Error(err)
|
||||||
|
case len(tasks) == int(count):
|
||||||
|
return poll.Success()
|
||||||
|
default:
|
||||||
|
return poll.Continue("task count at %d waiting for %d", len(tasks), count)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/docker/docker/integration-cli/environment"
|
||||||
|
)
|
||||||
|
|
||||||
|
var testEnv *environment.Execution
|
||||||
|
|
||||||
|
const dockerdBinary = "dockerd"
|
||||||
|
|
||||||
|
func TestMain(m *testing.M) {
|
||||||
|
var err error
|
||||||
|
testEnv, err = environment.New()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: replace this with `testEnv.Print()` to print the full env
|
||||||
|
if testEnv.LocalDaemon() {
|
||||||
|
fmt.Println("INFO: Testing against a local daemon")
|
||||||
|
} else {
|
||||||
|
fmt.Println("INFO: Testing against a remote daemon")
|
||||||
|
}
|
||||||
|
|
||||||
|
res := m.Run()
|
||||||
|
os.Exit(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func setupTest(t *testing.T) func() {
|
||||||
|
environment.ProtectImages(t, testEnv)
|
||||||
|
return func() { testEnv.Clean(t, testEnv.DockerBinary()) }
|
||||||
|
}
|
Loading…
Reference in New Issue