github.com/LazyboyChen7/engine@v17.12.1-ce-rc2+incompatible/integration/service/inspect_test.go (about)

     1  package service
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/docker/docker/api/types"
     9  	"github.com/docker/docker/api/types/container"
    10  	"github.com/docker/docker/api/types/filters"
    11  	"github.com/docker/docker/api/types/swarm"
    12  	"github.com/docker/docker/client"
    13  	"github.com/docker/docker/integration-cli/daemon"
    14  	"github.com/docker/docker/integration-cli/request"
    15  	"github.com/gotestyourself/gotestyourself/poll"
    16  	"github.com/gotestyourself/gotestyourself/skip"
    17  	"github.com/stretchr/testify/assert"
    18  	"github.com/stretchr/testify/require"
    19  	"golang.org/x/net/context"
    20  )
    21  
    22  func TestInspect(t *testing.T) {
    23  	skip.IfCondition(t, !testEnv.IsLocalDaemon())
    24  	defer setupTest(t)()
    25  	d := newSwarm(t)
    26  	defer d.Stop(t)
    27  	client, err := request.NewClientForHost(d.Sock())
    28  	require.NoError(t, err)
    29  
    30  	var before = time.Now()
    31  	var instances uint64 = 2
    32  	serviceSpec := fullSwarmServiceSpec("test-service-inspect", instances)
    33  
    34  	ctx := context.Background()
    35  	resp, err := client.ServiceCreate(ctx, serviceSpec, types.ServiceCreateOptions{
    36  		QueryRegistry: false,
    37  	})
    38  	require.NoError(t, err)
    39  
    40  	id := resp.ID
    41  	poll.WaitOn(t, serviceContainerCount(client, id, instances))
    42  
    43  	service, _, err := client.ServiceInspectWithRaw(ctx, id, types.ServiceInspectOptions{})
    44  	require.NoError(t, err)
    45  	assert.Equal(t, serviceSpec, service.Spec)
    46  	assert.Equal(t, uint64(11), service.Meta.Version.Index)
    47  	assert.Equal(t, id, service.ID)
    48  	assert.WithinDuration(t, before, service.CreatedAt, 30*time.Second)
    49  	assert.WithinDuration(t, before, service.UpdatedAt, 30*time.Second)
    50  }
    51  
    52  func fullSwarmServiceSpec(name string, replicas uint64) swarm.ServiceSpec {
    53  	restartDelay := 100 * time.Millisecond
    54  	maxAttempts := uint64(4)
    55  
    56  	return swarm.ServiceSpec{
    57  		Annotations: swarm.Annotations{
    58  			Name: name,
    59  			Labels: map[string]string{
    60  				"service-label": "service-label-value",
    61  			},
    62  		},
    63  		TaskTemplate: swarm.TaskSpec{
    64  			ContainerSpec: &swarm.ContainerSpec{
    65  				Image:           "busybox:latest",
    66  				Labels:          map[string]string{"container-label": "container-value"},
    67  				Command:         []string{"/bin/top"},
    68  				Args:            []string{"-u", "root"},
    69  				Hostname:        "hostname",
    70  				Env:             []string{"envvar=envvalue"},
    71  				Dir:             "/work",
    72  				User:            "root",
    73  				StopSignal:      "SIGINT",
    74  				StopGracePeriod: &restartDelay,
    75  				Hosts:           []string{"8.8.8.8  google"},
    76  				DNSConfig: &swarm.DNSConfig{
    77  					Nameservers: []string{"8.8.8.8"},
    78  					Search:      []string{"somedomain"},
    79  				},
    80  				Isolation: container.IsolationDefault,
    81  			},
    82  			RestartPolicy: &swarm.RestartPolicy{
    83  				Delay:       &restartDelay,
    84  				Condition:   swarm.RestartPolicyConditionOnFailure,
    85  				MaxAttempts: &maxAttempts,
    86  			},
    87  			Runtime: swarm.RuntimeContainer,
    88  		},
    89  		Mode: swarm.ServiceMode{
    90  			Replicated: &swarm.ReplicatedService{
    91  				Replicas: &replicas,
    92  			},
    93  		},
    94  		UpdateConfig: &swarm.UpdateConfig{
    95  			Parallelism:     2,
    96  			Delay:           200 * time.Second,
    97  			FailureAction:   swarm.UpdateFailureActionContinue,
    98  			Monitor:         2 * time.Second,
    99  			MaxFailureRatio: 0.2,
   100  			Order:           swarm.UpdateOrderStopFirst,
   101  		},
   102  		RollbackConfig: &swarm.UpdateConfig{
   103  			Parallelism:     3,
   104  			Delay:           300 * time.Second,
   105  			FailureAction:   swarm.UpdateFailureActionPause,
   106  			Monitor:         3 * time.Second,
   107  			MaxFailureRatio: 0.3,
   108  			Order:           swarm.UpdateOrderStartFirst,
   109  		},
   110  	}
   111  }
   112  
   113  const defaultSwarmPort = 2477
   114  
   115  func newSwarm(t *testing.T) *daemon.Swarm {
   116  	d := &daemon.Swarm{
   117  		Daemon: daemon.New(t, "", dockerdBinary, daemon.Config{
   118  			Experimental: testEnv.DaemonInfo.ExperimentalBuild,
   119  		}),
   120  		// TODO: better method of finding an unused port
   121  		Port: defaultSwarmPort,
   122  	}
   123  	// TODO: move to a NewSwarm constructor
   124  	d.ListenAddr = fmt.Sprintf("0.0.0.0:%d", d.Port)
   125  
   126  	// avoid networking conflicts
   127  	args := []string{"--iptables=false", "--swarm-default-advertise-addr=lo"}
   128  	d.StartWithBusybox(t, args...)
   129  
   130  	require.NoError(t, d.Init(swarm.InitRequest{}))
   131  	return d
   132  }
   133  
   134  func serviceContainerCount(client client.ServiceAPIClient, id string, count uint64) func(log poll.LogT) poll.Result {
   135  	return func(log poll.LogT) poll.Result {
   136  		filter := filters.NewArgs()
   137  		filter.Add("service", id)
   138  		tasks, err := client.TaskList(context.Background(), types.TaskListOptions{
   139  			Filters: filter,
   140  		})
   141  		switch {
   142  		case err != nil:
   143  			return poll.Error(err)
   144  		case len(tasks) == int(count):
   145  			return poll.Success()
   146  		default:
   147  			return poll.Continue("task count at %d waiting for %d", len(tasks), count)
   148  		}
   149  	}
   150  }