github.com/devdivbcp/moby@v17.12.0-ce-rc1.0.20200726071732-2d4bfdc789ad+incompatible/integration/network/service_test.go (about)

     1  package network // import "github.com/docker/docker/integration/network"
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/docker/docker/api/types"
     9  	swarmtypes "github.com/docker/docker/api/types/swarm"
    10  	"github.com/docker/docker/api/types/versions"
    11  	"github.com/docker/docker/client"
    12  	"github.com/docker/docker/integration/internal/network"
    13  	"github.com/docker/docker/integration/internal/swarm"
    14  	"github.com/docker/docker/internal/test/daemon"
    15  	"gotest.tools/assert"
    16  	"gotest.tools/icmd"
    17  	"gotest.tools/poll"
    18  	"gotest.tools/skip"
    19  )
    20  
    21  // delInterface removes given network interface
    22  func delInterface(t *testing.T, ifName string) {
    23  	icmd.RunCommand("ip", "link", "delete", ifName).Assert(t, icmd.Success)
    24  	icmd.RunCommand("iptables", "-t", "nat", "--flush").Assert(t, icmd.Success)
    25  	icmd.RunCommand("iptables", "--flush").Assert(t, icmd.Success)
    26  }
    27  
    28  func TestDaemonRestartWithLiveRestore(t *testing.T) {
    29  	skip.If(t, testEnv.OSType == "windows")
    30  	skip.If(t, testEnv.IsRemoteDaemon)
    31  	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.38"), "skip test from new feature")
    32  	d := daemon.New(t)
    33  	defer d.Stop(t)
    34  	d.Start(t)
    35  	d.Restart(t,
    36  		"--live-restore=true",
    37  		"--default-address-pool", "base=175.30.0.0/16,size=16",
    38  		"--default-address-pool", "base=175.33.0.0/16,size=24",
    39  	)
    40  
    41  	// Verify bridge network's subnet
    42  	c := d.NewClientT(t)
    43  	defer c.Close()
    44  	out, err := c.NetworkInspect(context.Background(), "bridge", types.NetworkInspectOptions{})
    45  	assert.NilError(t, err)
    46  	// Make sure docker0 doesn't get override with new IP in live restore case
    47  	assert.Equal(t, out.IPAM.Config[0].Subnet, "172.18.0.0/16")
    48  }
    49  
    50  func TestDaemonDefaultNetworkPools(t *testing.T) {
    51  	skip.If(t, testEnv.OSType == "windows")
    52  	// Remove docker0 bridge and the start daemon defining the predefined address pools
    53  	skip.If(t, testEnv.IsRemoteDaemon)
    54  	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.38"), "skip test from new feature")
    55  	defaultNetworkBridge := "docker0"
    56  	delInterface(t, defaultNetworkBridge)
    57  	d := daemon.New(t)
    58  	defer d.Stop(t)
    59  	d.Start(t,
    60  		"--default-address-pool", "base=175.30.0.0/16,size=16",
    61  		"--default-address-pool", "base=175.33.0.0/16,size=24",
    62  	)
    63  
    64  	c := d.NewClientT(t)
    65  	defer c.Close()
    66  
    67  	// Verify bridge network's subnet
    68  	out, err := c.NetworkInspect(context.Background(), "bridge", types.NetworkInspectOptions{})
    69  	assert.NilError(t, err)
    70  	assert.Equal(t, out.IPAM.Config[0].Subnet, "175.30.0.0/16")
    71  
    72  	// Create a bridge network and verify its subnet is the second default pool
    73  	name := "elango" + t.Name()
    74  	network.CreateNoError(context.Background(), t, c, name,
    75  		network.WithDriver("bridge"),
    76  	)
    77  	out, err = c.NetworkInspect(context.Background(), name, types.NetworkInspectOptions{})
    78  	assert.NilError(t, err)
    79  	assert.Equal(t, out.IPAM.Config[0].Subnet, "175.33.0.0/24")
    80  
    81  	// Create a bridge network and verify its subnet is the third default pool
    82  	name = "saanvi" + t.Name()
    83  	network.CreateNoError(context.Background(), t, c, name,
    84  		network.WithDriver("bridge"),
    85  	)
    86  	out, err = c.NetworkInspect(context.Background(), name, types.NetworkInspectOptions{})
    87  	assert.NilError(t, err)
    88  	assert.Equal(t, out.IPAM.Config[0].Subnet, "175.33.1.0/24")
    89  	delInterface(t, defaultNetworkBridge)
    90  
    91  }
    92  
    93  func TestDaemonRestartWithExistingNetwork(t *testing.T) {
    94  	skip.If(t, testEnv.OSType == "windows")
    95  	skip.If(t, testEnv.IsRemoteDaemon)
    96  	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.38"), "skip test from new feature")
    97  	defaultNetworkBridge := "docker0"
    98  	d := daemon.New(t)
    99  	d.Start(t)
   100  	defer d.Stop(t)
   101  	c := d.NewClientT(t)
   102  	defer c.Close()
   103  
   104  	// Create a bridge network
   105  	name := "elango" + t.Name()
   106  	network.CreateNoError(context.Background(), t, c, name,
   107  		network.WithDriver("bridge"),
   108  	)
   109  
   110  	// Verify bridge network's subnet
   111  	out, err := c.NetworkInspect(context.Background(), name, types.NetworkInspectOptions{})
   112  	assert.NilError(t, err)
   113  	networkip := out.IPAM.Config[0].Subnet
   114  
   115  	// Restart daemon with default address pool option
   116  	d.Restart(t,
   117  		"--default-address-pool", "base=175.30.0.0/16,size=16",
   118  		"--default-address-pool", "base=175.33.0.0/16,size=24")
   119  
   120  	out1, err := c.NetworkInspect(context.Background(), name, types.NetworkInspectOptions{})
   121  	assert.NilError(t, err)
   122  	assert.Equal(t, out1.IPAM.Config[0].Subnet, networkip)
   123  	delInterface(t, defaultNetworkBridge)
   124  }
   125  
   126  func TestDaemonRestartWithExistingNetworkWithDefaultPoolRange(t *testing.T) {
   127  	skip.If(t, testEnv.OSType == "windows")
   128  	skip.If(t, testEnv.IsRemoteDaemon)
   129  	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.38"), "skip test from new feature")
   130  	defaultNetworkBridge := "docker0"
   131  	d := daemon.New(t)
   132  	d.Start(t)
   133  	defer d.Stop(t)
   134  	c := d.NewClientT(t)
   135  	defer c.Close()
   136  
   137  	// Create a bridge network
   138  	name := "elango" + t.Name()
   139  	network.CreateNoError(context.Background(), t, c, name,
   140  		network.WithDriver("bridge"),
   141  	)
   142  
   143  	// Verify bridge network's subnet
   144  	out, err := c.NetworkInspect(context.Background(), name, types.NetworkInspectOptions{})
   145  	assert.NilError(t, err)
   146  	networkip := out.IPAM.Config[0].Subnet
   147  
   148  	// Create a bridge network
   149  	name = "sthira" + t.Name()
   150  	network.CreateNoError(context.Background(), t, c, name,
   151  		network.WithDriver("bridge"),
   152  	)
   153  	out, err = c.NetworkInspect(context.Background(), name, types.NetworkInspectOptions{})
   154  	assert.NilError(t, err)
   155  	networkip2 := out.IPAM.Config[0].Subnet
   156  
   157  	// Restart daemon with default address pool option
   158  	d.Restart(t,
   159  		"--default-address-pool", "base=175.18.0.0/16,size=16",
   160  		"--default-address-pool", "base=175.19.0.0/16,size=24",
   161  	)
   162  
   163  	// Create a bridge network
   164  	name = "saanvi" + t.Name()
   165  	network.CreateNoError(context.Background(), t, c, name,
   166  		network.WithDriver("bridge"),
   167  	)
   168  	out1, err := c.NetworkInspect(context.Background(), name, types.NetworkInspectOptions{})
   169  	assert.NilError(t, err)
   170  
   171  	assert.Check(t, out1.IPAM.Config[0].Subnet != networkip)
   172  	assert.Check(t, out1.IPAM.Config[0].Subnet != networkip2)
   173  	delInterface(t, defaultNetworkBridge)
   174  }
   175  
   176  func TestDaemonWithBipAndDefaultNetworkPool(t *testing.T) {
   177  	skip.If(t, testEnv.OSType == "windows")
   178  	skip.If(t, testEnv.IsRemoteDaemon)
   179  	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.38"), "skip test from new feature")
   180  	defaultNetworkBridge := "docker0"
   181  	d := daemon.New(t)
   182  	defer d.Stop(t)
   183  	d.Start(t,
   184  		"--bip=172.60.0.1/16",
   185  		"--default-address-pool", "base=175.30.0.0/16,size=16",
   186  		"--default-address-pool", "base=175.33.0.0/16,size=24",
   187  	)
   188  
   189  	c := d.NewClientT(t)
   190  	defer c.Close()
   191  
   192  	// Verify bridge network's subnet
   193  	out, err := c.NetworkInspect(context.Background(), "bridge", types.NetworkInspectOptions{})
   194  	assert.NilError(t, err)
   195  	// Make sure BIP IP doesn't get override with new default address pool .
   196  	assert.Equal(t, out.IPAM.Config[0].Subnet, "172.60.0.0/16")
   197  	delInterface(t, defaultNetworkBridge)
   198  }
   199  
   200  func TestServiceWithPredefinedNetwork(t *testing.T) {
   201  	skip.If(t, testEnv.OSType == "windows")
   202  	defer setupTest(t)()
   203  	d := swarm.NewSwarm(t, testEnv)
   204  	defer d.Stop(t)
   205  	c := d.NewClientT(t)
   206  	defer c.Close()
   207  
   208  	hostName := "host"
   209  	var instances uint64 = 1
   210  	serviceName := "TestService" + t.Name()
   211  
   212  	serviceID := swarm.CreateService(t, d,
   213  		swarm.ServiceWithReplicas(instances),
   214  		swarm.ServiceWithName(serviceName),
   215  		swarm.ServiceWithNetwork(hostName),
   216  	)
   217  
   218  	poll.WaitOn(t, swarm.RunningTasksCount(c, serviceID, instances), swarm.ServicePoll)
   219  
   220  	_, _, err := c.ServiceInspectWithRaw(context.Background(), serviceID, types.ServiceInspectOptions{})
   221  	assert.NilError(t, err)
   222  
   223  	err = c.ServiceRemove(context.Background(), serviceID)
   224  	assert.NilError(t, err)
   225  }
   226  
   227  const ingressNet = "ingress"
   228  
   229  func TestServiceRemoveKeepsIngressNetwork(t *testing.T) {
   230  	t.Skip("FLAKY_TEST")
   231  
   232  	skip.If(t, testEnv.OSType == "windows")
   233  	defer setupTest(t)()
   234  	d := swarm.NewSwarm(t, testEnv)
   235  	defer d.Stop(t)
   236  	c := d.NewClientT(t)
   237  	defer c.Close()
   238  
   239  	poll.WaitOn(t, swarmIngressReady(c), swarm.NetworkPoll)
   240  
   241  	var instances uint64 = 1
   242  
   243  	serviceID := swarm.CreateService(t, d,
   244  		swarm.ServiceWithReplicas(instances),
   245  		swarm.ServiceWithName(t.Name()+"-service"),
   246  		swarm.ServiceWithEndpoint(&swarmtypes.EndpointSpec{
   247  			Ports: []swarmtypes.PortConfig{
   248  				{
   249  					Protocol:    swarmtypes.PortConfigProtocolTCP,
   250  					TargetPort:  80,
   251  					PublishMode: swarmtypes.PortConfigPublishModeIngress,
   252  				},
   253  			},
   254  		}),
   255  	)
   256  
   257  	poll.WaitOn(t, swarm.RunningTasksCount(c, serviceID, instances), swarm.ServicePoll)
   258  
   259  	ctx := context.Background()
   260  	_, _, err := c.ServiceInspectWithRaw(ctx, serviceID, types.ServiceInspectOptions{})
   261  	assert.NilError(t, err)
   262  
   263  	err = c.ServiceRemove(ctx, serviceID)
   264  	assert.NilError(t, err)
   265  
   266  	poll.WaitOn(t, noServices(ctx, c), swarm.ServicePoll)
   267  	poll.WaitOn(t, swarm.NoTasks(ctx, c), swarm.ServicePoll)
   268  
   269  	// Ensure that "ingress" is not removed or corrupted
   270  	time.Sleep(10 * time.Second)
   271  	netInfo, err := c.NetworkInspect(ctx, ingressNet, types.NetworkInspectOptions{
   272  		Verbose: true,
   273  		Scope:   "swarm",
   274  	})
   275  	assert.NilError(t, err, "Ingress network was removed after removing service!")
   276  	assert.Assert(t, len(netInfo.Containers) != 0, "No load balancing endpoints in ingress network")
   277  	assert.Assert(t, len(netInfo.Peers) != 0, "No peers (including self) in ingress network")
   278  	_, ok := netInfo.Containers["ingress-sbox"]
   279  	assert.Assert(t, ok, "ingress-sbox not present in ingress network")
   280  }
   281  
   282  func swarmIngressReady(client client.NetworkAPIClient) func(log poll.LogT) poll.Result {
   283  	return func(log poll.LogT) poll.Result {
   284  		netInfo, err := client.NetworkInspect(context.Background(), ingressNet, types.NetworkInspectOptions{
   285  			Verbose: true,
   286  			Scope:   "swarm",
   287  		})
   288  		if err != nil {
   289  			return poll.Error(err)
   290  		}
   291  		np := len(netInfo.Peers)
   292  		nc := len(netInfo.Containers)
   293  		if np == 0 || nc == 0 {
   294  			return poll.Continue("ingress not ready: %d peers and %d containers", nc, np)
   295  		}
   296  		_, ok := netInfo.Containers["ingress-sbox"]
   297  		if !ok {
   298  			return poll.Continue("ingress not ready: does not contain the ingress-sbox")
   299  		}
   300  		return poll.Success()
   301  	}
   302  }
   303  
   304  func noServices(ctx context.Context, client client.ServiceAPIClient) func(log poll.LogT) poll.Result {
   305  	return func(log poll.LogT) poll.Result {
   306  		services, err := client.ServiceList(ctx, types.ServiceListOptions{})
   307  		switch {
   308  		case err != nil:
   309  			return poll.Error(err)
   310  		case len(services) == 0:
   311  			return poll.Success()
   312  		default:
   313  			return poll.Continue("waiting for all services to be removed: service count at %d", len(services))
   314  		}
   315  	}
   316  }
   317  
   318  func TestServiceWithDataPathPortInit(t *testing.T) {
   319  	skip.If(t, testEnv.OSType == "windows")
   320  	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.40"), "DataPathPort was added in API v1.40")
   321  	defer setupTest(t)()
   322  	var datapathPort uint32 = 7777
   323  	d := swarm.NewSwarm(t, testEnv, daemon.WithSwarmDataPathPort(datapathPort))
   324  	c := d.NewClientT(t)
   325  	ctx := context.Background()
   326  	// Create a overlay network
   327  	name := "saanvisthira" + t.Name()
   328  	overlayID := network.CreateNoError(context.Background(), t, c, name,
   329  		network.WithDriver("overlay"))
   330  
   331  	var instances uint64 = 1
   332  	serviceID := swarm.CreateService(t, d,
   333  		swarm.ServiceWithReplicas(instances),
   334  		swarm.ServiceWithName(name),
   335  		swarm.ServiceWithNetwork(name),
   336  	)
   337  
   338  	poll.WaitOn(t, swarm.RunningTasksCount(c, serviceID, instances), swarm.ServicePoll)
   339  
   340  	info := d.Info(t)
   341  	assert.Equal(t, info.Swarm.Cluster.DataPathPort, datapathPort)
   342  	err := c.ServiceRemove(ctx, serviceID)
   343  	assert.NilError(t, err)
   344  	poll.WaitOn(t, noServices(ctx, c), swarm.ServicePoll)
   345  	poll.WaitOn(t, swarm.NoTasks(ctx, c), swarm.ServicePoll)
   346  	err = c.NetworkRemove(ctx, overlayID)
   347  	assert.NilError(t, err)
   348  	c.Close()
   349  	err = d.SwarmLeave(t, true)
   350  	assert.NilError(t, err)
   351  	d.Stop(t)
   352  
   353  	// Clean up , set it back to original one to make sure other tests don't fail
   354  	// call without datapath port option.
   355  	d = swarm.NewSwarm(t, testEnv)
   356  	defer d.Stop(t)
   357  	nc := d.NewClientT(t)
   358  	defer nc.Close()
   359  	// Create a overlay network
   360  	name = "not-saanvisthira" + t.Name()
   361  	overlayID = network.CreateNoError(ctx, t, nc, name,
   362  		network.WithDriver("overlay"))
   363  
   364  	serviceID = swarm.CreateService(t, d,
   365  		swarm.ServiceWithReplicas(instances),
   366  		swarm.ServiceWithName(name),
   367  		swarm.ServiceWithNetwork(name),
   368  	)
   369  
   370  	poll.WaitOn(t, swarm.RunningTasksCount(nc, serviceID, instances), swarm.ServicePoll)
   371  
   372  	info = d.Info(t)
   373  	var defaultDataPathPort uint32 = 4789
   374  	assert.Equal(t, info.Swarm.Cluster.DataPathPort, defaultDataPathPort)
   375  	err = nc.ServiceRemove(ctx, serviceID)
   376  	assert.NilError(t, err)
   377  	poll.WaitOn(t, noServices(ctx, nc), swarm.ServicePoll)
   378  	poll.WaitOn(t, swarm.NoTasks(ctx, nc), swarm.ServicePoll)
   379  	err = nc.NetworkRemove(ctx, overlayID)
   380  	assert.NilError(t, err)
   381  	err = d.SwarmLeave(t, true)
   382  	assert.NilError(t, err)
   383  }
   384  
   385  func TestServiceWithDefaultAddressPoolInit(t *testing.T) {
   386  	skip.If(t, testEnv.OSType == "windows")
   387  	defer setupTest(t)()
   388  	d := swarm.NewSwarm(t, testEnv,
   389  		daemon.WithSwarmDefaultAddrPool([]string{"20.20.0.0/16"}),
   390  		daemon.WithSwarmDefaultAddrPoolSubnetSize(24))
   391  	defer d.Stop(t)
   392  	cli := d.NewClientT(t)
   393  	defer cli.Close()
   394  	ctx := context.Background()
   395  
   396  	// Create a overlay network
   397  	name := "sthira" + t.Name()
   398  	overlayID := network.CreateNoError(ctx, t, cli, name,
   399  		network.WithDriver("overlay"),
   400  		network.WithCheckDuplicate(),
   401  	)
   402  
   403  	var instances uint64 = 1
   404  	serviceName := "TestService" + t.Name()
   405  	serviceID := swarm.CreateService(t, d,
   406  		swarm.ServiceWithReplicas(instances),
   407  		swarm.ServiceWithName(serviceName),
   408  		swarm.ServiceWithNetwork(name),
   409  	)
   410  
   411  	poll.WaitOn(t, swarm.RunningTasksCount(cli, serviceID, instances), swarm.ServicePoll)
   412  
   413  	_, _, err := cli.ServiceInspectWithRaw(ctx, serviceID, types.ServiceInspectOptions{})
   414  	assert.NilError(t, err)
   415  
   416  	out, err := cli.NetworkInspect(ctx, overlayID, types.NetworkInspectOptions{Verbose: true})
   417  	assert.NilError(t, err)
   418  	t.Logf("%s: NetworkInspect: %+v", t.Name(), out)
   419  	assert.Assert(t, len(out.IPAM.Config) > 0)
   420  	assert.Equal(t, out.IPAM.Config[0].Subnet, "20.20.1.0/24")
   421  
   422  	// Also inspect ingress network and make sure its in the same subnet
   423  	out, err = cli.NetworkInspect(ctx, "ingress", types.NetworkInspectOptions{Verbose: true})
   424  	assert.NilError(t, err)
   425  	assert.Assert(t, len(out.IPAM.Config) > 0)
   426  	assert.Equal(t, out.IPAM.Config[0].Subnet, "20.20.0.0/24")
   427  
   428  	err = cli.ServiceRemove(ctx, serviceID)
   429  	poll.WaitOn(t, noServices(ctx, cli), swarm.ServicePoll)
   430  	poll.WaitOn(t, swarm.NoTasks(ctx, cli), swarm.ServicePoll)
   431  	assert.NilError(t, err)
   432  	err = cli.NetworkRemove(ctx, overlayID)
   433  	assert.NilError(t, err)
   434  	err = d.SwarmLeave(t, true)
   435  	assert.NilError(t, err)
   436  
   437  }