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