github.com/zhouyu0/docker-note@v0.0.0-20190722021225-b8d3825084db/integration/service/create_test.go (about)

     1  package service // import "github.com/docker/docker/integration/service"
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/docker/docker/api/types"
    11  	"github.com/docker/docker/api/types/filters"
    12  	swarmtypes "github.com/docker/docker/api/types/swarm"
    13  	"github.com/docker/docker/client"
    14  	"github.com/docker/docker/integration/internal/network"
    15  	"github.com/docker/docker/integration/internal/swarm"
    16  	"github.com/docker/docker/internal/test/daemon"
    17  	"gotest.tools/assert"
    18  	is "gotest.tools/assert/cmp"
    19  	"gotest.tools/poll"
    20  	"gotest.tools/skip"
    21  )
    22  
    23  func TestServiceCreateInit(t *testing.T) {
    24  	defer setupTest(t)()
    25  	t.Run("daemonInitDisabled", testServiceCreateInit(false))
    26  	t.Run("daemonInitEnabled", testServiceCreateInit(true))
    27  }
    28  
    29  func testServiceCreateInit(daemonEnabled bool) func(t *testing.T) {
    30  	return func(t *testing.T) {
    31  		var ops = []func(*daemon.Daemon){}
    32  
    33  		if daemonEnabled {
    34  			ops = append(ops, daemon.WithInit)
    35  		}
    36  		d := swarm.NewSwarm(t, testEnv, ops...)
    37  		defer d.Stop(t)
    38  		client := d.NewClientT(t)
    39  		defer client.Close()
    40  
    41  		booleanTrue := true
    42  		booleanFalse := false
    43  
    44  		serviceID := swarm.CreateService(t, d)
    45  		poll.WaitOn(t, swarm.RunningTasksCount(client, serviceID, 1), swarm.ServicePoll)
    46  		i := inspectServiceContainer(t, client, serviceID)
    47  		// HostConfig.Init == nil means that it delegates to daemon configuration
    48  		assert.Check(t, i.HostConfig.Init == nil)
    49  
    50  		serviceID = swarm.CreateService(t, d, swarm.ServiceWithInit(&booleanTrue))
    51  		poll.WaitOn(t, swarm.RunningTasksCount(client, serviceID, 1), swarm.ServicePoll)
    52  		i = inspectServiceContainer(t, client, serviceID)
    53  		assert.Check(t, is.Equal(true, *i.HostConfig.Init))
    54  
    55  		serviceID = swarm.CreateService(t, d, swarm.ServiceWithInit(&booleanFalse))
    56  		poll.WaitOn(t, swarm.RunningTasksCount(client, serviceID, 1), swarm.ServicePoll)
    57  		i = inspectServiceContainer(t, client, serviceID)
    58  		assert.Check(t, is.Equal(false, *i.HostConfig.Init))
    59  	}
    60  }
    61  
    62  func inspectServiceContainer(t *testing.T, client client.APIClient, serviceID string) types.ContainerJSON {
    63  	t.Helper()
    64  	filter := filters.NewArgs()
    65  	filter.Add("label", fmt.Sprintf("com.docker.swarm.service.id=%s", serviceID))
    66  	containers, err := client.ContainerList(context.Background(), types.ContainerListOptions{Filters: filter})
    67  	assert.NilError(t, err)
    68  	assert.Check(t, is.Len(containers, 1))
    69  
    70  	i, err := client.ContainerInspect(context.Background(), containers[0].ID)
    71  	assert.NilError(t, err)
    72  	return i
    73  }
    74  
    75  func TestCreateServiceMultipleTimes(t *testing.T) {
    76  	skip.If(t, testEnv.DaemonInfo.OSType == "windows")
    77  	defer setupTest(t)()
    78  	d := swarm.NewSwarm(t, testEnv)
    79  	defer d.Stop(t)
    80  	client := d.NewClientT(t)
    81  	defer client.Close()
    82  	ctx := context.Background()
    83  
    84  	overlayName := "overlay1_" + t.Name()
    85  	overlayID := network.CreateNoError(t, ctx, client, overlayName,
    86  		network.WithCheckDuplicate(),
    87  		network.WithDriver("overlay"),
    88  	)
    89  
    90  	var instances uint64 = 4
    91  
    92  	serviceName := "TestService_" + t.Name()
    93  	serviceSpec := []swarm.ServiceSpecOpt{
    94  		swarm.ServiceWithReplicas(instances),
    95  		swarm.ServiceWithName(serviceName),
    96  		swarm.ServiceWithNetwork(overlayName),
    97  	}
    98  
    99  	serviceID := swarm.CreateService(t, d, serviceSpec...)
   100  	poll.WaitOn(t, swarm.RunningTasksCount(client, serviceID, instances), swarm.ServicePoll)
   101  
   102  	_, _, err := client.ServiceInspectWithRaw(context.Background(), serviceID, types.ServiceInspectOptions{})
   103  	assert.NilError(t, err)
   104  
   105  	err = client.ServiceRemove(context.Background(), serviceID)
   106  	assert.NilError(t, err)
   107  
   108  	poll.WaitOn(t, swarm.NoTasksForService(ctx, client, serviceID), swarm.ServicePoll)
   109  
   110  	serviceID2 := swarm.CreateService(t, d, serviceSpec...)
   111  	poll.WaitOn(t, swarm.RunningTasksCount(client, serviceID2, instances), swarm.ServicePoll)
   112  
   113  	err = client.ServiceRemove(context.Background(), serviceID2)
   114  	assert.NilError(t, err)
   115  
   116  	poll.WaitOn(t, swarm.NoTasksForService(ctx, client, serviceID2), swarm.ServicePoll)
   117  
   118  	err = client.NetworkRemove(context.Background(), overlayID)
   119  	assert.NilError(t, err)
   120  
   121  	poll.WaitOn(t, network.IsRemoved(context.Background(), client, overlayID), poll.WithTimeout(1*time.Minute), poll.WithDelay(10*time.Second))
   122  }
   123  
   124  func TestCreateWithDuplicateNetworkNames(t *testing.T) {
   125  	skip.If(t, testEnv.DaemonInfo.OSType == "windows")
   126  	defer setupTest(t)()
   127  	d := swarm.NewSwarm(t, testEnv)
   128  	defer d.Stop(t)
   129  	client := d.NewClientT(t)
   130  	defer client.Close()
   131  	ctx := context.Background()
   132  
   133  	name := "foo_" + t.Name()
   134  	n1 := network.CreateNoError(t, ctx, client, name, network.WithDriver("bridge"))
   135  	n2 := network.CreateNoError(t, ctx, client, name, network.WithDriver("bridge"))
   136  
   137  	// Duplicates with name but with different driver
   138  	n3 := network.CreateNoError(t, ctx, client, name, network.WithDriver("overlay"))
   139  
   140  	// Create Service with the same name
   141  	var instances uint64 = 1
   142  
   143  	serviceName := "top_" + t.Name()
   144  	serviceID := swarm.CreateService(t, d,
   145  		swarm.ServiceWithReplicas(instances),
   146  		swarm.ServiceWithName(serviceName),
   147  		swarm.ServiceWithNetwork(name),
   148  	)
   149  
   150  	poll.WaitOn(t, swarm.RunningTasksCount(client, serviceID, instances), swarm.ServicePoll)
   151  
   152  	resp, _, err := client.ServiceInspectWithRaw(ctx, serviceID, types.ServiceInspectOptions{})
   153  	assert.NilError(t, err)
   154  	assert.Check(t, is.Equal(n3, resp.Spec.TaskTemplate.Networks[0].Target))
   155  
   156  	// Remove Service, and wait for its tasks to be removed
   157  	err = client.ServiceRemove(ctx, serviceID)
   158  	assert.NilError(t, err)
   159  	poll.WaitOn(t, swarm.NoTasksForService(ctx, client, serviceID), swarm.ServicePoll)
   160  
   161  	// Remove networks
   162  	err = client.NetworkRemove(context.Background(), n3)
   163  	assert.NilError(t, err)
   164  
   165  	err = client.NetworkRemove(context.Background(), n2)
   166  	assert.NilError(t, err)
   167  
   168  	err = client.NetworkRemove(context.Background(), n1)
   169  	assert.NilError(t, err)
   170  
   171  	// Make sure networks have been destroyed.
   172  	poll.WaitOn(t, network.IsRemoved(context.Background(), client, n3), poll.WithTimeout(1*time.Minute), poll.WithDelay(10*time.Second))
   173  	poll.WaitOn(t, network.IsRemoved(context.Background(), client, n2), poll.WithTimeout(1*time.Minute), poll.WithDelay(10*time.Second))
   174  	poll.WaitOn(t, network.IsRemoved(context.Background(), client, n1), poll.WithTimeout(1*time.Minute), poll.WithDelay(10*time.Second))
   175  }
   176  
   177  func TestCreateServiceSecretFileMode(t *testing.T) {
   178  	skip.If(t, testEnv.DaemonInfo.OSType == "windows")
   179  	defer setupTest(t)()
   180  	d := swarm.NewSwarm(t, testEnv)
   181  	defer d.Stop(t)
   182  	client := d.NewClientT(t)
   183  	defer client.Close()
   184  
   185  	ctx := context.Background()
   186  	secretName := "TestSecret_" + t.Name()
   187  	secretResp, err := client.SecretCreate(ctx, swarmtypes.SecretSpec{
   188  		Annotations: swarmtypes.Annotations{
   189  			Name: secretName,
   190  		},
   191  		Data: []byte("TESTSECRET"),
   192  	})
   193  	assert.NilError(t, err)
   194  
   195  	var instances uint64 = 1
   196  	serviceName := "TestService_" + t.Name()
   197  	serviceID := swarm.CreateService(t, d,
   198  		swarm.ServiceWithReplicas(instances),
   199  		swarm.ServiceWithName(serviceName),
   200  		swarm.ServiceWithCommand([]string{"/bin/sh", "-c", "ls -l /etc/secret || /bin/top"}),
   201  		swarm.ServiceWithSecret(&swarmtypes.SecretReference{
   202  			File: &swarmtypes.SecretReferenceFileTarget{
   203  				Name: "/etc/secret",
   204  				UID:  "0",
   205  				GID:  "0",
   206  				Mode: 0777,
   207  			},
   208  			SecretID:   secretResp.ID,
   209  			SecretName: secretName,
   210  		}),
   211  	)
   212  
   213  	poll.WaitOn(t, swarm.RunningTasksCount(client, serviceID, instances), swarm.ServicePoll)
   214  
   215  	filter := filters.NewArgs()
   216  	filter.Add("service", serviceID)
   217  	tasks, err := client.TaskList(ctx, types.TaskListOptions{
   218  		Filters: filter,
   219  	})
   220  	assert.NilError(t, err)
   221  	assert.Check(t, is.Equal(len(tasks), 1))
   222  
   223  	body, err := client.ContainerLogs(ctx, tasks[0].Status.ContainerStatus.ContainerID, types.ContainerLogsOptions{
   224  		ShowStdout: true,
   225  	})
   226  	assert.NilError(t, err)
   227  	defer body.Close()
   228  
   229  	content, err := ioutil.ReadAll(body)
   230  	assert.NilError(t, err)
   231  	assert.Check(t, is.Contains(string(content), "-rwxrwxrwx"))
   232  
   233  	err = client.ServiceRemove(ctx, serviceID)
   234  	assert.NilError(t, err)
   235  	poll.WaitOn(t, swarm.NoTasksForService(ctx, client, serviceID), swarm.ServicePoll)
   236  
   237  	err = client.SecretRemove(ctx, secretName)
   238  	assert.NilError(t, err)
   239  }
   240  
   241  func TestCreateServiceConfigFileMode(t *testing.T) {
   242  	skip.If(t, testEnv.DaemonInfo.OSType == "windows")
   243  	defer setupTest(t)()
   244  	d := swarm.NewSwarm(t, testEnv)
   245  	defer d.Stop(t)
   246  	client := d.NewClientT(t)
   247  	defer client.Close()
   248  
   249  	ctx := context.Background()
   250  	configName := "TestConfig_" + t.Name()
   251  	configResp, err := client.ConfigCreate(ctx, swarmtypes.ConfigSpec{
   252  		Annotations: swarmtypes.Annotations{
   253  			Name: configName,
   254  		},
   255  		Data: []byte("TESTCONFIG"),
   256  	})
   257  	assert.NilError(t, err)
   258  
   259  	var instances uint64 = 1
   260  	serviceName := "TestService_" + t.Name()
   261  	serviceID := swarm.CreateService(t, d,
   262  		swarm.ServiceWithName(serviceName),
   263  		swarm.ServiceWithCommand([]string{"/bin/sh", "-c", "ls -l /etc/config || /bin/top"}),
   264  		swarm.ServiceWithReplicas(instances),
   265  		swarm.ServiceWithConfig(&swarmtypes.ConfigReference{
   266  			File: &swarmtypes.ConfigReferenceFileTarget{
   267  				Name: "/etc/config",
   268  				UID:  "0",
   269  				GID:  "0",
   270  				Mode: 0777,
   271  			},
   272  			ConfigID:   configResp.ID,
   273  			ConfigName: configName,
   274  		}),
   275  	)
   276  
   277  	poll.WaitOn(t, swarm.RunningTasksCount(client, serviceID, instances))
   278  
   279  	filter := filters.NewArgs()
   280  	filter.Add("service", serviceID)
   281  	tasks, err := client.TaskList(ctx, types.TaskListOptions{
   282  		Filters: filter,
   283  	})
   284  	assert.NilError(t, err)
   285  	assert.Check(t, is.Equal(len(tasks), 1))
   286  
   287  	body, err := client.ContainerLogs(ctx, tasks[0].Status.ContainerStatus.ContainerID, types.ContainerLogsOptions{
   288  		ShowStdout: true,
   289  	})
   290  	assert.NilError(t, err)
   291  	defer body.Close()
   292  
   293  	content, err := ioutil.ReadAll(body)
   294  	assert.NilError(t, err)
   295  	assert.Check(t, is.Contains(string(content), "-rwxrwxrwx"))
   296  
   297  	err = client.ServiceRemove(ctx, serviceID)
   298  	assert.NilError(t, err)
   299  	poll.WaitOn(t, swarm.NoTasksForService(ctx, client, serviceID))
   300  
   301  	err = client.ConfigRemove(ctx, configName)
   302  	assert.NilError(t, err)
   303  }