github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/swarmkit/manager/allocator/allocator_test.go (about)

     1  package allocator
     2  
     3  import (
     4  	"context"
     5  	"net"
     6  	"runtime/debug"
     7  	"strconv"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/docker/go-events"
    12  	"github.com/docker/swarmkit/api"
    13  	"github.com/docker/swarmkit/manager/state"
    14  	"github.com/docker/swarmkit/manager/state/store"
    15  	"github.com/stretchr/testify/assert"
    16  	"github.com/stretchr/testify/require"
    17  )
    18  
    19  func init() {
    20  	// set artificially low retry interval for testing
    21  	retryInterval = 5 * time.Millisecond
    22  }
    23  
    24  func TestAllocator(t *testing.T) {
    25  	s := store.NewMemoryStore(nil)
    26  	assert.NotNil(t, s)
    27  	defer s.Close()
    28  
    29  	a, err := New(s, nil, nil)
    30  	assert.NoError(t, err)
    31  	assert.NotNil(t, a)
    32  
    33  	// Predefined node-local networkTestNoDuplicateIPs
    34  	p := &api.Network{
    35  		ID: "one_unIque_id",
    36  		Spec: api.NetworkSpec{
    37  			Annotations: api.Annotations{
    38  				Name: "pred_bridge_network",
    39  				Labels: map[string]string{
    40  					"com.docker.swarm.predefined": "true",
    41  				},
    42  			},
    43  			DriverConfig: &api.Driver{Name: "bridge"},
    44  		},
    45  	}
    46  
    47  	// Node-local swarm scope network
    48  	nln := &api.Network{
    49  		ID: "another_unIque_id",
    50  		Spec: api.NetworkSpec{
    51  			Annotations: api.Annotations{
    52  				Name: "swarm-macvlan",
    53  			},
    54  			DriverConfig: &api.Driver{Name: "macvlan"},
    55  		},
    56  	}
    57  
    58  	// Try adding some objects to store before allocator is started
    59  	assert.NoError(t, s.Update(func(tx store.Tx) error {
    60  		// populate ingress network
    61  		in := &api.Network{
    62  			ID: "ingress-nw-id",
    63  			Spec: api.NetworkSpec{
    64  				Annotations: api.Annotations{
    65  					Name: "default-ingress",
    66  				},
    67  				Ingress: true,
    68  			},
    69  		}
    70  		assert.NoError(t, store.CreateNetwork(tx, in))
    71  
    72  		n1 := &api.Network{
    73  			ID: "testID1",
    74  			Spec: api.NetworkSpec{
    75  				Annotations: api.Annotations{
    76  					Name: "test1",
    77  				},
    78  			},
    79  		}
    80  		assert.NoError(t, store.CreateNetwork(tx, n1))
    81  
    82  		s1 := &api.Service{
    83  			ID: "testServiceID1",
    84  			Spec: api.ServiceSpec{
    85  				Annotations: api.Annotations{
    86  					Name: "service1",
    87  				},
    88  				Task: api.TaskSpec{
    89  					Networks: []*api.NetworkAttachmentConfig{
    90  						{
    91  							Target: "testID1",
    92  						},
    93  					},
    94  				},
    95  				Endpoint: &api.EndpointSpec{
    96  					Mode: api.ResolutionModeVirtualIP,
    97  					Ports: []*api.PortConfig{
    98  						{
    99  							Name:          "portName",
   100  							Protocol:      api.ProtocolTCP,
   101  							TargetPort:    8000,
   102  							PublishedPort: 8001,
   103  						},
   104  					},
   105  				},
   106  			},
   107  		}
   108  		assert.NoError(t, store.CreateService(tx, s1))
   109  
   110  		t1 := &api.Task{
   111  			ID: "testTaskID1",
   112  			Status: api.TaskStatus{
   113  				State: api.TaskStateNew,
   114  			},
   115  			Networks: []*api.NetworkAttachment{
   116  				{
   117  					Network: n1,
   118  				},
   119  			},
   120  		}
   121  		assert.NoError(t, store.CreateTask(tx, t1))
   122  
   123  		t2 := &api.Task{
   124  			ID: "testTaskIDPreInit",
   125  			Status: api.TaskStatus{
   126  				State: api.TaskStateNew,
   127  			},
   128  			ServiceID:    "testServiceID1",
   129  			DesiredState: api.TaskStateRunning,
   130  		}
   131  		assert.NoError(t, store.CreateTask(tx, t2))
   132  
   133  		// Create the predefined node-local network with one service
   134  		assert.NoError(t, store.CreateNetwork(tx, p))
   135  
   136  		sp1 := &api.Service{
   137  			ID: "predServiceID1",
   138  			Spec: api.ServiceSpec{
   139  				Annotations: api.Annotations{
   140  					Name: "predService1",
   141  				},
   142  				Task: api.TaskSpec{
   143  					Networks: []*api.NetworkAttachmentConfig{
   144  						{
   145  							Target: p.ID,
   146  						},
   147  					},
   148  				},
   149  				Endpoint: &api.EndpointSpec{Mode: api.ResolutionModeDNSRoundRobin},
   150  			},
   151  		}
   152  		assert.NoError(t, store.CreateService(tx, sp1))
   153  
   154  		tp1 := &api.Task{
   155  			ID: "predTaskID1",
   156  			Status: api.TaskStatus{
   157  				State: api.TaskStateNew,
   158  			},
   159  			Networks: []*api.NetworkAttachment{
   160  				{
   161  					Network: p,
   162  				},
   163  			},
   164  		}
   165  		assert.NoError(t, store.CreateTask(tx, tp1))
   166  
   167  		// Create the the swarm level node-local network with one service
   168  		assert.NoError(t, store.CreateNetwork(tx, nln))
   169  
   170  		sp2 := &api.Service{
   171  			ID: "predServiceID2",
   172  			Spec: api.ServiceSpec{
   173  				Annotations: api.Annotations{
   174  					Name: "predService2",
   175  				},
   176  				Task: api.TaskSpec{
   177  					Networks: []*api.NetworkAttachmentConfig{
   178  						{
   179  							Target: nln.ID,
   180  						},
   181  					},
   182  				},
   183  				Endpoint: &api.EndpointSpec{Mode: api.ResolutionModeDNSRoundRobin},
   184  			},
   185  		}
   186  		assert.NoError(t, store.CreateService(tx, sp2))
   187  
   188  		tp2 := &api.Task{
   189  			ID: "predTaskID2",
   190  			Status: api.TaskStatus{
   191  				State: api.TaskStateNew,
   192  			},
   193  			Networks: []*api.NetworkAttachment{
   194  				{
   195  					Network: nln,
   196  				},
   197  			},
   198  		}
   199  		assert.NoError(t, store.CreateTask(tx, tp2))
   200  
   201  		return nil
   202  	}))
   203  
   204  	netWatch, cancel := state.Watch(s.WatchQueue(), api.EventUpdateNetwork{}, api.EventDeleteNetwork{})
   205  	defer cancel()
   206  	taskWatch, cancel := state.Watch(s.WatchQueue(), api.EventUpdateTask{}, api.EventDeleteTask{})
   207  	defer cancel()
   208  	serviceWatch, cancel := state.Watch(s.WatchQueue(), api.EventUpdateService{}, api.EventDeleteService{})
   209  	defer cancel()
   210  
   211  	// Start allocator
   212  	go func() {
   213  		assert.NoError(t, a.Run(context.Background()))
   214  	}()
   215  	defer a.Stop()
   216  
   217  	// Now verify if we get network and tasks updated properly
   218  	watchNetwork(t, netWatch, false, isValidNetwork)
   219  	watchTask(t, s, taskWatch, false, isValidTask) // t1
   220  	watchTask(t, s, taskWatch, false, isValidTask) // t2
   221  	watchService(t, serviceWatch, false, nil)
   222  
   223  	// Verify no allocation was done for the node-local networks
   224  	var (
   225  		ps *api.Network
   226  		sn *api.Network
   227  	)
   228  	s.View(func(tx store.ReadTx) {
   229  		ps = store.GetNetwork(tx, p.ID)
   230  		sn = store.GetNetwork(tx, nln.ID)
   231  
   232  	})
   233  	assert.NotNil(t, ps)
   234  	assert.NotNil(t, sn)
   235  	// Verify no allocation was done for tasks on node-local networks
   236  	var (
   237  		tp1 *api.Task
   238  		tp2 *api.Task
   239  	)
   240  	s.View(func(tx store.ReadTx) {
   241  		tp1 = store.GetTask(tx, "predTaskID1")
   242  		tp2 = store.GetTask(tx, "predTaskID2")
   243  	})
   244  	assert.NotNil(t, tp1)
   245  	assert.NotNil(t, tp2)
   246  	assert.Equal(t, tp1.Networks[0].Network.ID, p.ID)
   247  	assert.Equal(t, tp2.Networks[0].Network.ID, nln.ID)
   248  	assert.Nil(t, tp1.Networks[0].Addresses, "Non nil addresses for task on node-local network")
   249  	assert.Nil(t, tp2.Networks[0].Addresses, "Non nil addresses for task on node-local network")
   250  
   251  	// Add new networks/tasks/services after allocator is started.
   252  	assert.NoError(t, s.Update(func(tx store.Tx) error {
   253  		n2 := &api.Network{
   254  			ID: "testID2",
   255  			Spec: api.NetworkSpec{
   256  				Annotations: api.Annotations{
   257  					Name: "test2",
   258  				},
   259  			},
   260  		}
   261  		assert.NoError(t, store.CreateNetwork(tx, n2))
   262  		return nil
   263  	}))
   264  
   265  	watchNetwork(t, netWatch, false, isValidNetwork)
   266  
   267  	assert.NoError(t, s.Update(func(tx store.Tx) error {
   268  		s2 := &api.Service{
   269  			ID: "testServiceID2",
   270  			Spec: api.ServiceSpec{
   271  				Annotations: api.Annotations{
   272  					Name: "service2",
   273  				},
   274  				Networks: []*api.NetworkAttachmentConfig{
   275  					{
   276  						Target: "testID2",
   277  					},
   278  				},
   279  				Endpoint: &api.EndpointSpec{},
   280  			},
   281  		}
   282  		assert.NoError(t, store.CreateService(tx, s2))
   283  		return nil
   284  	}))
   285  
   286  	watchService(t, serviceWatch, false, nil)
   287  
   288  	assert.NoError(t, s.Update(func(tx store.Tx) error {
   289  		t2 := &api.Task{
   290  			ID: "testTaskID2",
   291  			Status: api.TaskStatus{
   292  				State: api.TaskStateNew,
   293  			},
   294  			ServiceID:    "testServiceID2",
   295  			DesiredState: api.TaskStateRunning,
   296  		}
   297  		assert.NoError(t, store.CreateTask(tx, t2))
   298  		return nil
   299  	}))
   300  
   301  	watchTask(t, s, taskWatch, false, isValidTask)
   302  
   303  	// Now try adding a task which depends on a network before adding the network.
   304  	n3 := &api.Network{
   305  		ID: "testID3",
   306  		Spec: api.NetworkSpec{
   307  			Annotations: api.Annotations{
   308  				Name: "test3",
   309  			},
   310  		},
   311  	}
   312  
   313  	assert.NoError(t, s.Update(func(tx store.Tx) error {
   314  		t3 := &api.Task{
   315  			ID: "testTaskID3",
   316  			Status: api.TaskStatus{
   317  				State: api.TaskStateNew,
   318  			},
   319  			DesiredState: api.TaskStateRunning,
   320  			Networks: []*api.NetworkAttachment{
   321  				{
   322  					Network: n3,
   323  				},
   324  			},
   325  		}
   326  		assert.NoError(t, store.CreateTask(tx, t3))
   327  		return nil
   328  	}))
   329  
   330  	// Wait for a little bit of time before adding network just to
   331  	// test network is not available while task allocation is
   332  	// going through
   333  	time.Sleep(10 * time.Millisecond)
   334  
   335  	assert.NoError(t, s.Update(func(tx store.Tx) error {
   336  		assert.NoError(t, store.CreateNetwork(tx, n3))
   337  		return nil
   338  	}))
   339  
   340  	watchNetwork(t, netWatch, false, isValidNetwork)
   341  	watchTask(t, s, taskWatch, false, isValidTask)
   342  
   343  	assert.NoError(t, s.Update(func(tx store.Tx) error {
   344  		assert.NoError(t, store.DeleteTask(tx, "testTaskID3"))
   345  		return nil
   346  	}))
   347  	watchTask(t, s, taskWatch, false, isValidTask)
   348  
   349  	assert.NoError(t, s.Update(func(tx store.Tx) error {
   350  		t5 := &api.Task{
   351  			ID: "testTaskID5",
   352  			Spec: api.TaskSpec{
   353  				Networks: []*api.NetworkAttachmentConfig{
   354  					{
   355  						Target: "testID2",
   356  					},
   357  				},
   358  			},
   359  			Status: api.TaskStatus{
   360  				State: api.TaskStateNew,
   361  			},
   362  			DesiredState: api.TaskStateRunning,
   363  			ServiceID:    "testServiceID2",
   364  		}
   365  		assert.NoError(t, store.CreateTask(tx, t5))
   366  		return nil
   367  	}))
   368  	watchTask(t, s, taskWatch, false, isValidTask)
   369  
   370  	assert.NoError(t, s.Update(func(tx store.Tx) error {
   371  		assert.NoError(t, store.DeleteNetwork(tx, "testID3"))
   372  		return nil
   373  	}))
   374  	watchNetwork(t, netWatch, false, isValidNetwork)
   375  
   376  	assert.NoError(t, s.Update(func(tx store.Tx) error {
   377  		assert.NoError(t, store.DeleteService(tx, "testServiceID2"))
   378  		return nil
   379  	}))
   380  	watchService(t, serviceWatch, false, nil)
   381  
   382  	// Try to create a task with no network attachments and test
   383  	// that it moves to ALLOCATED state.
   384  	assert.NoError(t, s.Update(func(tx store.Tx) error {
   385  		t4 := &api.Task{
   386  			ID: "testTaskID4",
   387  			Status: api.TaskStatus{
   388  				State: api.TaskStateNew,
   389  			},
   390  			DesiredState: api.TaskStateRunning,
   391  		}
   392  		assert.NoError(t, store.CreateTask(tx, t4))
   393  		return nil
   394  	}))
   395  	watchTask(t, s, taskWatch, false, isValidTask)
   396  
   397  	assert.NoError(t, s.Update(func(tx store.Tx) error {
   398  		n2 := store.GetNetwork(tx, "testID2")
   399  		require.NotEqual(t, nil, n2)
   400  		assert.NoError(t, store.UpdateNetwork(tx, n2))
   401  		return nil
   402  	}))
   403  	watchNetwork(t, netWatch, false, isValidNetwork)
   404  	watchNetwork(t, netWatch, true, nil)
   405  
   406  	// Try updating service which is already allocated with no endpointSpec
   407  	assert.NoError(t, s.Update(func(tx store.Tx) error {
   408  		s := store.GetService(tx, "testServiceID1")
   409  		s.Spec.Endpoint = nil
   410  
   411  		assert.NoError(t, store.UpdateService(tx, s))
   412  		return nil
   413  	}))
   414  	watchService(t, serviceWatch, false, nil)
   415  
   416  	// Try updating task which is already allocated
   417  	assert.NoError(t, s.Update(func(tx store.Tx) error {
   418  		t2 := store.GetTask(tx, "testTaskID2")
   419  		require.NotEqual(t, nil, t2)
   420  		assert.NoError(t, store.UpdateTask(tx, t2))
   421  		return nil
   422  	}))
   423  	watchTask(t, s, taskWatch, false, isValidTask)
   424  	watchTask(t, s, taskWatch, true, nil)
   425  
   426  	// Try adding networks with conflicting network resources and
   427  	// add task which attaches to a network which gets allocated
   428  	// later and verify if task reconciles and moves to ALLOCATED.
   429  	n4 := &api.Network{
   430  		ID: "testID4",
   431  		Spec: api.NetworkSpec{
   432  			Annotations: api.Annotations{
   433  				Name: "test4",
   434  			},
   435  			DriverConfig: &api.Driver{
   436  				Name: "overlay",
   437  				Options: map[string]string{
   438  					"com.docker.network.driver.overlay.vxlanid_list": "328",
   439  				},
   440  			},
   441  		},
   442  	}
   443  
   444  	n5 := n4.Copy()
   445  	n5.ID = "testID5"
   446  	n5.Spec.Annotations.Name = "test5"
   447  	assert.NoError(t, s.Update(func(tx store.Tx) error {
   448  		assert.NoError(t, store.CreateNetwork(tx, n4))
   449  		return nil
   450  	}))
   451  	watchNetwork(t, netWatch, false, isValidNetwork)
   452  
   453  	assert.NoError(t, s.Update(func(tx store.Tx) error {
   454  		assert.NoError(t, store.CreateNetwork(tx, n5))
   455  		return nil
   456  	}))
   457  	watchNetwork(t, netWatch, true, nil)
   458  
   459  	assert.NoError(t, s.Update(func(tx store.Tx) error {
   460  		t6 := &api.Task{
   461  			ID: "testTaskID6",
   462  			Status: api.TaskStatus{
   463  				State: api.TaskStateNew,
   464  			},
   465  			DesiredState: api.TaskStateRunning,
   466  			Networks: []*api.NetworkAttachment{
   467  				{
   468  					Network: n5,
   469  				},
   470  			},
   471  		}
   472  		assert.NoError(t, store.CreateTask(tx, t6))
   473  		return nil
   474  	}))
   475  	watchTask(t, s, taskWatch, true, nil)
   476  
   477  	// Now remove the conflicting network.
   478  	assert.NoError(t, s.Update(func(tx store.Tx) error {
   479  		assert.NoError(t, store.DeleteNetwork(tx, n4.ID))
   480  		return nil
   481  	}))
   482  	watchNetwork(t, netWatch, false, isValidNetwork)
   483  	watchTask(t, s, taskWatch, false, isValidTask)
   484  
   485  	// Try adding services with conflicting port configs and add
   486  	// task which is part of the service whose allocation hasn't
   487  	// happened and when that happens later and verify if task
   488  	// reconciles and moves to ALLOCATED.
   489  	s3 := &api.Service{
   490  		ID: "testServiceID3",
   491  		Spec: api.ServiceSpec{
   492  			Annotations: api.Annotations{
   493  				Name: "service3",
   494  			},
   495  			Endpoint: &api.EndpointSpec{
   496  				Ports: []*api.PortConfig{
   497  					{
   498  						Name:          "http",
   499  						TargetPort:    80,
   500  						PublishedPort: 8080,
   501  					},
   502  					{
   503  						PublishMode: api.PublishModeHost,
   504  						Name:        "http",
   505  						TargetPort:  80,
   506  					},
   507  				},
   508  			},
   509  		},
   510  	}
   511  
   512  	s4 := s3.Copy()
   513  	s4.ID = "testServiceID4"
   514  	s4.Spec.Annotations.Name = "service4"
   515  	assert.NoError(t, s.Update(func(tx store.Tx) error {
   516  		assert.NoError(t, store.CreateService(tx, s3))
   517  		return nil
   518  	}))
   519  	watchService(t, serviceWatch, false, nil)
   520  	assert.NoError(t, s.Update(func(tx store.Tx) error {
   521  		assert.NoError(t, store.CreateService(tx, s4))
   522  		return nil
   523  	}))
   524  	watchService(t, serviceWatch, true, nil)
   525  
   526  	assert.NoError(t, s.Update(func(tx store.Tx) error {
   527  		t7 := &api.Task{
   528  			ID: "testTaskID7",
   529  			Status: api.TaskStatus{
   530  				State: api.TaskStateNew,
   531  			},
   532  			ServiceID:    "testServiceID4",
   533  			DesiredState: api.TaskStateRunning,
   534  		}
   535  		assert.NoError(t, store.CreateTask(tx, t7))
   536  		return nil
   537  	}))
   538  	watchTask(t, s, taskWatch, true, nil)
   539  
   540  	// Now remove the conflicting service.
   541  	assert.NoError(t, s.Update(func(tx store.Tx) error {
   542  		assert.NoError(t, store.DeleteService(tx, s3.ID))
   543  		return nil
   544  	}))
   545  	watchService(t, serviceWatch, false, nil)
   546  	watchTask(t, s, taskWatch, false, isValidTask)
   547  }
   548  
   549  func TestNoDuplicateIPs(t *testing.T) {
   550  	s := store.NewMemoryStore(nil)
   551  	assert.NotNil(t, s)
   552  	defer s.Close()
   553  
   554  	// Try adding some objects to store before allocator is started
   555  	assert.NoError(t, s.Update(func(tx store.Tx) error {
   556  		// populate ingress network
   557  		in := &api.Network{
   558  			ID: "ingress-nw-id",
   559  			Spec: api.NetworkSpec{
   560  				Annotations: api.Annotations{
   561  					Name: "default-ingress",
   562  				},
   563  				Ingress: true,
   564  			},
   565  			IPAM: &api.IPAMOptions{
   566  				Driver: &api.Driver{},
   567  				Configs: []*api.IPAMConfig{
   568  					{
   569  						Subnet:  "10.0.0.0/24",
   570  						Gateway: "10.0.0.1",
   571  					},
   572  				},
   573  			},
   574  			DriverState: &api.Driver{},
   575  		}
   576  		assert.NoError(t, store.CreateNetwork(tx, in))
   577  		n1 := &api.Network{
   578  			ID: "testID1",
   579  			Spec: api.NetworkSpec{
   580  				Annotations: api.Annotations{
   581  					Name: "test1",
   582  				},
   583  			},
   584  			IPAM: &api.IPAMOptions{
   585  				Driver: &api.Driver{},
   586  				Configs: []*api.IPAMConfig{
   587  					{
   588  						Subnet:  "10.1.0.0/24",
   589  						Gateway: "10.1.0.1",
   590  					},
   591  				},
   592  			},
   593  			DriverState: &api.Driver{},
   594  		}
   595  		assert.NoError(t, store.CreateNetwork(tx, n1))
   596  
   597  		s1 := &api.Service{
   598  			ID: "testServiceID1",
   599  			Spec: api.ServiceSpec{
   600  				Annotations: api.Annotations{
   601  					Name: "service1",
   602  				},
   603  				Task: api.TaskSpec{
   604  					Networks: []*api.NetworkAttachmentConfig{
   605  						{
   606  							Target: "testID1",
   607  						},
   608  					},
   609  				},
   610  				Endpoint: &api.EndpointSpec{
   611  					Mode: api.ResolutionModeVirtualIP,
   612  					Ports: []*api.PortConfig{
   613  						{
   614  							Name:          "portName",
   615  							Protocol:      api.ProtocolTCP,
   616  							TargetPort:    8000,
   617  							PublishedPort: 8001,
   618  						},
   619  					},
   620  				},
   621  			},
   622  		}
   623  		assert.NoError(t, store.CreateService(tx, s1))
   624  
   625  		return nil
   626  	}))
   627  
   628  	taskWatch, cancel := state.Watch(s.WatchQueue(), api.EventUpdateTask{}, api.EventDeleteTask{})
   629  	defer cancel()
   630  
   631  	assignedIPs := make(map[string]string)
   632  	hasUniqueIP := func(fakeT assert.TestingT, s *store.MemoryStore, task *api.Task) bool {
   633  		if len(task.Networks) == 0 {
   634  			panic("missing networks")
   635  		}
   636  		if len(task.Networks[0].Addresses) == 0 {
   637  			panic("missing network address")
   638  		}
   639  
   640  		assignedIP := task.Networks[0].Addresses[0]
   641  		oldTaskID, present := assignedIPs[assignedIP]
   642  		if present && task.ID != oldTaskID {
   643  			t.Fatalf("task %s assigned duplicate IP %s, previously assigned to task %s", task.ID, assignedIP, oldTaskID)
   644  		}
   645  		assignedIPs[assignedIP] = task.ID
   646  		return true
   647  	}
   648  
   649  	reps := 100
   650  	for i := 0; i != reps; i++ {
   651  		assert.NoError(t, s.Update(func(tx store.Tx) error {
   652  			t2 := &api.Task{
   653  				// The allocator iterates over the tasks in
   654  				// lexical order, so number tasks in descending
   655  				// order. Note that the problem this test was
   656  				// meant to trigger also showed up with tasks
   657  				// numbered in ascending order, but it took
   658  				// until the 52nd task.
   659  				ID: "testTaskID" + strconv.Itoa(reps-i),
   660  				Status: api.TaskStatus{
   661  					State: api.TaskStateNew,
   662  				},
   663  				ServiceID:    "testServiceID1",
   664  				DesiredState: api.TaskStateRunning,
   665  			}
   666  			assert.NoError(t, store.CreateTask(tx, t2))
   667  
   668  			return nil
   669  		}))
   670  		a, err := New(s, nil, nil)
   671  		assert.NoError(t, err)
   672  		assert.NotNil(t, a)
   673  
   674  		// Start allocator
   675  		go func() {
   676  			assert.NoError(t, a.Run(context.Background()))
   677  		}()
   678  
   679  		// Confirm task gets a unique IP
   680  		watchTask(t, s, taskWatch, false, hasUniqueIP)
   681  		a.Stop()
   682  	}
   683  }
   684  
   685  func TestAllocatorRestoreForDuplicateIPs(t *testing.T) {
   686  	s := store.NewMemoryStore(nil)
   687  	assert.NotNil(t, s)
   688  	defer s.Close()
   689  	// Create 3 services with 1 task each
   690  	numsvcstsks := 3
   691  	assert.NoError(t, s.Update(func(tx store.Tx) error {
   692  		// populate ingress network
   693  		in := &api.Network{
   694  			ID: "ingress-nw-id",
   695  			Spec: api.NetworkSpec{
   696  				Annotations: api.Annotations{
   697  					Name: "default-ingress",
   698  				},
   699  				Ingress: true,
   700  			},
   701  			IPAM: &api.IPAMOptions{
   702  				Driver: &api.Driver{},
   703  				Configs: []*api.IPAMConfig{
   704  					{
   705  						Subnet:  "10.0.0.0/24",
   706  						Gateway: "10.0.0.1",
   707  					},
   708  				},
   709  			},
   710  		}
   711  		assert.NoError(t, store.CreateNetwork(tx, in))
   712  
   713  		for i := 0; i != numsvcstsks; i++ {
   714  			svc := &api.Service{
   715  				ID: "testServiceID" + strconv.Itoa(i),
   716  				Spec: api.ServiceSpec{
   717  					Annotations: api.Annotations{
   718  						Name: "service" + strconv.Itoa(i),
   719  					},
   720  					Endpoint: &api.EndpointSpec{
   721  						Mode: api.ResolutionModeVirtualIP,
   722  
   723  						Ports: []*api.PortConfig{
   724  							{
   725  								Name:          "",
   726  								Protocol:      api.ProtocolTCP,
   727  								TargetPort:    8000,
   728  								PublishedPort: uint32(8001 + i),
   729  							},
   730  						},
   731  					},
   732  				},
   733  				Endpoint: &api.Endpoint{
   734  					Ports: []*api.PortConfig{
   735  						{
   736  							Name:          "",
   737  							Protocol:      api.ProtocolTCP,
   738  							TargetPort:    8000,
   739  							PublishedPort: uint32(8001 + i),
   740  						},
   741  					},
   742  					VirtualIPs: []*api.Endpoint_VirtualIP{
   743  						{
   744  							NetworkID: "ingress-nw-id",
   745  							Addr:      "10.0.0." + strconv.Itoa(2+i) + "/24",
   746  						},
   747  					},
   748  				},
   749  			}
   750  			assert.NoError(t, store.CreateService(tx, svc))
   751  		}
   752  		return nil
   753  	}))
   754  
   755  	for i := 0; i != numsvcstsks; i++ {
   756  		assert.NoError(t, s.Update(func(tx store.Tx) error {
   757  			tsk := &api.Task{
   758  				ID: "testTaskID" + strconv.Itoa(i),
   759  				Status: api.TaskStatus{
   760  					State: api.TaskStateNew,
   761  				},
   762  				ServiceID:    "testServiceID" + strconv.Itoa(i),
   763  				DesiredState: api.TaskStateRunning,
   764  			}
   765  			assert.NoError(t, store.CreateTask(tx, tsk))
   766  			return nil
   767  		}))
   768  	}
   769  
   770  	assignedVIPs := make(map[string]bool)
   771  	assignedIPs := make(map[string]bool)
   772  	hasNoIPOverlapServices := func(fakeT assert.TestingT, service *api.Service) bool {
   773  		assert.NotEqual(fakeT, len(service.Endpoint.VirtualIPs), 0)
   774  		assert.NotEqual(fakeT, len(service.Endpoint.VirtualIPs[0].Addr), 0)
   775  
   776  		assignedVIP := service.Endpoint.VirtualIPs[0].Addr
   777  		if assignedVIPs[assignedVIP] {
   778  			t.Fatalf("service %s assigned duplicate IP %s", service.ID, assignedVIP)
   779  		}
   780  		assignedVIPs[assignedVIP] = true
   781  		if assignedIPs[assignedVIP] {
   782  			t.Fatalf("a task and service %s have the same IP %s", service.ID, assignedVIP)
   783  		}
   784  		return true
   785  	}
   786  
   787  	hasNoIPOverlapTasks := func(fakeT assert.TestingT, s *store.MemoryStore, task *api.Task) bool {
   788  		assert.NotEqual(fakeT, len(task.Networks), 0)
   789  		assert.NotEqual(fakeT, len(task.Networks[0].Addresses), 0)
   790  
   791  		assignedIP := task.Networks[0].Addresses[0]
   792  		if assignedIPs[assignedIP] {
   793  			t.Fatalf("task %s assigned duplicate IP %s", task.ID, assignedIP)
   794  		}
   795  		assignedIPs[assignedIP] = true
   796  		if assignedVIPs[assignedIP] {
   797  			t.Fatalf("a service and task %s have the same IP %s", task.ID, assignedIP)
   798  		}
   799  		return true
   800  	}
   801  
   802  	a, err := New(s, nil, nil)
   803  	assert.NoError(t, err)
   804  	assert.NotNil(t, a)
   805  	// Start allocator
   806  	go func() {
   807  		assert.NoError(t, a.Run(context.Background()))
   808  	}()
   809  	defer a.Stop()
   810  
   811  	taskWatch, cancel := state.Watch(s.WatchQueue(), api.EventUpdateTask{}, api.EventDeleteTask{})
   812  	defer cancel()
   813  
   814  	serviceWatch, cancel := state.Watch(s.WatchQueue(), api.EventUpdateService{}, api.EventDeleteService{})
   815  	defer cancel()
   816  
   817  	// Confirm tasks have no IPs that overlap with the services VIPs on restart
   818  	for i := 0; i != numsvcstsks; i++ {
   819  		watchTask(t, s, taskWatch, false, hasNoIPOverlapTasks)
   820  		watchService(t, serviceWatch, false, hasNoIPOverlapServices)
   821  	}
   822  }
   823  
   824  // TestAllocatorRestartNoEndpointSpec covers the leader election case when the service Spec
   825  // does not contain the EndpointSpec.
   826  // The expected behavior is that the VIP(s) are still correctly populated inside
   827  // the IPAM and that no configuration on the service is changed.
   828  func TestAllocatorRestartNoEndpointSpec(t *testing.T) {
   829  	s := store.NewMemoryStore(nil)
   830  	assert.NotNil(t, s)
   831  	defer s.Close()
   832  	// Create 3 services with 1 task each
   833  	numsvcstsks := 3
   834  	assert.NoError(t, s.Update(func(tx store.Tx) error {
   835  		// populate ingress network
   836  		in := &api.Network{
   837  			ID: "overlay1",
   838  			Spec: api.NetworkSpec{
   839  				Annotations: api.Annotations{
   840  					Name: "net1",
   841  				},
   842  			},
   843  			IPAM: &api.IPAMOptions{
   844  				Driver: &api.Driver{},
   845  				Configs: []*api.IPAMConfig{
   846  					{
   847  						Subnet:  "10.0.0.0/24",
   848  						Gateway: "10.0.0.1",
   849  					},
   850  				},
   851  			},
   852  			DriverState: &api.Driver{},
   853  		}
   854  		assert.NoError(t, store.CreateNetwork(tx, in))
   855  
   856  		for i := 0; i != numsvcstsks; i++ {
   857  			svc := &api.Service{
   858  				ID: "testServiceID" + strconv.Itoa(i),
   859  				Spec: api.ServiceSpec{
   860  					Annotations: api.Annotations{
   861  						Name: "service" + strconv.Itoa(i),
   862  					},
   863  					// Endpoint: &api.EndpointSpec{
   864  					// 	Mode: api.ResolutionModeVirtualIP,
   865  					// },
   866  					Task: api.TaskSpec{
   867  						Networks: []*api.NetworkAttachmentConfig{
   868  							{
   869  								Target: "overlay1",
   870  							},
   871  						},
   872  					},
   873  				},
   874  				Endpoint: &api.Endpoint{
   875  					Spec: &api.EndpointSpec{
   876  						Mode: api.ResolutionModeVirtualIP,
   877  					},
   878  					VirtualIPs: []*api.Endpoint_VirtualIP{
   879  						{
   880  							NetworkID: "overlay1",
   881  							Addr:      "10.0.0." + strconv.Itoa(2+2*i) + "/24",
   882  						},
   883  					},
   884  				},
   885  			}
   886  			assert.NoError(t, store.CreateService(tx, svc))
   887  		}
   888  		return nil
   889  	}))
   890  
   891  	for i := 0; i != numsvcstsks; i++ {
   892  		assert.NoError(t, s.Update(func(tx store.Tx) error {
   893  			tsk := &api.Task{
   894  				ID: "testTaskID" + strconv.Itoa(i),
   895  				Status: api.TaskStatus{
   896  					State: api.TaskStateNew,
   897  				},
   898  				ServiceID:    "testServiceID" + strconv.Itoa(i),
   899  				DesiredState: api.TaskStateRunning,
   900  				Networks: []*api.NetworkAttachment{
   901  					{
   902  						Network: &api.Network{
   903  							ID: "overlay1",
   904  						},
   905  					},
   906  				},
   907  			}
   908  			assert.NoError(t, store.CreateTask(tx, tsk))
   909  			return nil
   910  		}))
   911  	}
   912  
   913  	expectedIPs := map[string]string{
   914  		"testServiceID0": "10.0.0.2/24",
   915  		"testServiceID1": "10.0.0.4/24",
   916  		"testServiceID2": "10.0.0.6/24",
   917  		"testTaskID0":    "10.0.0.3/24",
   918  		"testTaskID1":    "10.0.0.5/24",
   919  		"testTaskID2":    "10.0.0.7/24",
   920  	}
   921  	assignedIPs := make(map[string]bool)
   922  	hasNoIPOverlapServices := func(fakeT assert.TestingT, service *api.Service) bool {
   923  		assert.NotEqual(fakeT, len(service.Endpoint.VirtualIPs), 0)
   924  		assert.NotEqual(fakeT, len(service.Endpoint.VirtualIPs[0].Addr), 0)
   925  		assignedVIP := service.Endpoint.VirtualIPs[0].Addr
   926  		if assignedIPs[assignedVIP] {
   927  			t.Fatalf("service %s assigned duplicate IP %s", service.ID, assignedVIP)
   928  		}
   929  		assignedIPs[assignedVIP] = true
   930  		ip, ok := expectedIPs[service.ID]
   931  		assert.True(t, ok)
   932  		assert.Equal(t, ip, assignedVIP)
   933  		delete(expectedIPs, service.ID)
   934  		return true
   935  	}
   936  
   937  	hasNoIPOverlapTasks := func(fakeT assert.TestingT, s *store.MemoryStore, task *api.Task) bool {
   938  		assert.NotEqual(fakeT, len(task.Networks), 0)
   939  		assert.NotEqual(fakeT, len(task.Networks[0].Addresses), 0)
   940  		assignedIP := task.Networks[0].Addresses[0]
   941  		if assignedIPs[assignedIP] {
   942  			t.Fatalf("task %s assigned duplicate IP %s", task.ID, assignedIP)
   943  		}
   944  		assignedIPs[assignedIP] = true
   945  		ip, ok := expectedIPs[task.ID]
   946  		assert.True(t, ok)
   947  		assert.Equal(t, ip, assignedIP)
   948  		delete(expectedIPs, task.ID)
   949  		return true
   950  	}
   951  
   952  	a, err := New(s, nil, nil)
   953  	assert.NoError(t, err)
   954  	assert.NotNil(t, a)
   955  	// Start allocator
   956  	go func() {
   957  		assert.NoError(t, a.Run(context.Background()))
   958  	}()
   959  	defer a.Stop()
   960  
   961  	taskWatch, cancel := state.Watch(s.WatchQueue(), api.EventUpdateTask{}, api.EventDeleteTask{})
   962  	defer cancel()
   963  
   964  	serviceWatch, cancel := state.Watch(s.WatchQueue(), api.EventUpdateService{}, api.EventDeleteService{})
   965  	defer cancel()
   966  
   967  	// Confirm tasks have no IPs that overlap with the services VIPs on restart
   968  	for i := 0; i != numsvcstsks; i++ {
   969  		watchTask(t, s, taskWatch, false, hasNoIPOverlapTasks)
   970  		watchService(t, serviceWatch, false, hasNoIPOverlapServices)
   971  	}
   972  	assert.Len(t, expectedIPs, 0)
   973  }
   974  
   975  // TestAllocatorRestoreForUnallocatedNetwork tests allocator restart
   976  // scenarios where there is a combination of allocated and unallocated
   977  // networks and tests whether the restore logic ensures the networks
   978  // services and tasks that were preallocated are allocated correctly
   979  // followed by the allocation of unallocated networks prior to the
   980  // restart.
   981  func TestAllocatorRestoreForUnallocatedNetwork(t *testing.T) {
   982  	s := store.NewMemoryStore(nil)
   983  	assert.NotNil(t, s)
   984  	defer s.Close()
   985  	// Create 3 services with 1 task each
   986  	numsvcstsks := 3
   987  	var n1 *api.Network
   988  	var n2 *api.Network
   989  	assert.NoError(t, s.Update(func(tx store.Tx) error {
   990  		// populate ingress network
   991  		in := &api.Network{
   992  			ID: "ingress-nw-id",
   993  			Spec: api.NetworkSpec{
   994  				Annotations: api.Annotations{
   995  					Name: "default-ingress",
   996  				},
   997  				Ingress: true,
   998  			},
   999  			IPAM: &api.IPAMOptions{
  1000  				Driver: &api.Driver{},
  1001  				Configs: []*api.IPAMConfig{
  1002  					{
  1003  						Subnet:  "10.0.0.0/24",
  1004  						Gateway: "10.0.0.1",
  1005  					},
  1006  				},
  1007  			},
  1008  		}
  1009  		assert.NoError(t, store.CreateNetwork(tx, in))
  1010  
  1011  		n1 = &api.Network{
  1012  			ID: "testID1",
  1013  			Spec: api.NetworkSpec{
  1014  				Annotations: api.Annotations{
  1015  					Name: "test1",
  1016  				},
  1017  			},
  1018  			IPAM: &api.IPAMOptions{
  1019  				Driver: &api.Driver{},
  1020  				Configs: []*api.IPAMConfig{
  1021  					{
  1022  						Subnet:  "10.1.0.0/24",
  1023  						Gateway: "10.1.0.1",
  1024  					},
  1025  				},
  1026  			},
  1027  			DriverState: &api.Driver{},
  1028  		}
  1029  		assert.NoError(t, store.CreateNetwork(tx, n1))
  1030  
  1031  		n2 = &api.Network{
  1032  			// Intentionally named testID0 so that in restore this network
  1033  			// is looked into first
  1034  			ID: "testID0",
  1035  			Spec: api.NetworkSpec{
  1036  				Annotations: api.Annotations{
  1037  					Name: "test2",
  1038  				},
  1039  			},
  1040  		}
  1041  		assert.NoError(t, store.CreateNetwork(tx, n2))
  1042  
  1043  		for i := 0; i != numsvcstsks; i++ {
  1044  			svc := &api.Service{
  1045  				ID: "testServiceID" + strconv.Itoa(i),
  1046  				Spec: api.ServiceSpec{
  1047  					Annotations: api.Annotations{
  1048  						Name: "service" + strconv.Itoa(i),
  1049  					},
  1050  					Task: api.TaskSpec{
  1051  						Networks: []*api.NetworkAttachmentConfig{
  1052  							{
  1053  								Target: "testID1",
  1054  							},
  1055  						},
  1056  					},
  1057  					Endpoint: &api.EndpointSpec{
  1058  						Mode: api.ResolutionModeVirtualIP,
  1059  						Ports: []*api.PortConfig{
  1060  							{
  1061  								Name:          "",
  1062  								Protocol:      api.ProtocolTCP,
  1063  								TargetPort:    8000,
  1064  								PublishedPort: uint32(8001 + i),
  1065  							},
  1066  						},
  1067  					},
  1068  				},
  1069  				Endpoint: &api.Endpoint{
  1070  					Ports: []*api.PortConfig{
  1071  						{
  1072  							Name:          "",
  1073  							Protocol:      api.ProtocolTCP,
  1074  							TargetPort:    8000,
  1075  							PublishedPort: uint32(8001 + i),
  1076  						},
  1077  					},
  1078  					VirtualIPs: []*api.Endpoint_VirtualIP{
  1079  						{
  1080  							NetworkID: "ingress-nw-id",
  1081  							Addr:      "10.0.0." + strconv.Itoa(2+i) + "/24",
  1082  						},
  1083  						{
  1084  							NetworkID: "testID1",
  1085  							Addr:      "10.1.0." + strconv.Itoa(2+i) + "/24",
  1086  						},
  1087  					},
  1088  				},
  1089  			}
  1090  			assert.NoError(t, store.CreateService(tx, svc))
  1091  		}
  1092  		return nil
  1093  	}))
  1094  
  1095  	for i := 0; i != numsvcstsks; i++ {
  1096  		assert.NoError(t, s.Update(func(tx store.Tx) error {
  1097  			tsk := &api.Task{
  1098  				ID: "testTaskID" + strconv.Itoa(i),
  1099  				Status: api.TaskStatus{
  1100  					State: api.TaskStateNew,
  1101  				},
  1102  				Spec: api.TaskSpec{
  1103  					Networks: []*api.NetworkAttachmentConfig{
  1104  						{
  1105  							Target: "testID1",
  1106  						},
  1107  					},
  1108  				},
  1109  				ServiceID:    "testServiceID" + strconv.Itoa(i),
  1110  				DesiredState: api.TaskStateRunning,
  1111  			}
  1112  			assert.NoError(t, store.CreateTask(tx, tsk))
  1113  			return nil
  1114  		}))
  1115  	}
  1116  
  1117  	assignedIPs := make(map[string]bool)
  1118  	expectedIPs := map[string]string{
  1119  		"testServiceID0": "10.1.0.2/24",
  1120  		"testServiceID1": "10.1.0.3/24",
  1121  		"testServiceID2": "10.1.0.4/24",
  1122  		"testTaskID0":    "10.1.0.5/24",
  1123  		"testTaskID1":    "10.1.0.6/24",
  1124  		"testTaskID2":    "10.1.0.7/24",
  1125  	}
  1126  	hasNoIPOverlapServices := func(fakeT assert.TestingT, service *api.Service) bool {
  1127  		assert.NotEqual(fakeT, len(service.Endpoint.VirtualIPs), 0)
  1128  		assert.NotEqual(fakeT, len(service.Endpoint.VirtualIPs[0].Addr), 0)
  1129  		assignedVIP := service.Endpoint.VirtualIPs[1].Addr
  1130  		if assignedIPs[assignedVIP] {
  1131  			t.Fatalf("service %s assigned duplicate IP %s", service.ID, assignedVIP)
  1132  		}
  1133  		assignedIPs[assignedVIP] = true
  1134  		ip, ok := expectedIPs[service.ID]
  1135  		assert.True(t, ok)
  1136  		assert.Equal(t, ip, assignedVIP)
  1137  		delete(expectedIPs, service.ID)
  1138  		return true
  1139  	}
  1140  
  1141  	hasNoIPOverlapTasks := func(fakeT assert.TestingT, s *store.MemoryStore, task *api.Task) bool {
  1142  		assert.NotEqual(fakeT, len(task.Networks), 0)
  1143  		assert.NotEqual(fakeT, len(task.Networks[0].Addresses), 0)
  1144  		assignedIP := task.Networks[1].Addresses[0]
  1145  		if assignedIPs[assignedIP] {
  1146  			t.Fatalf("task %s assigned duplicate IP %s", task.ID, assignedIP)
  1147  		}
  1148  		assignedIPs[assignedIP] = true
  1149  		ip, ok := expectedIPs[task.ID]
  1150  		assert.True(t, ok)
  1151  		assert.Equal(t, ip, assignedIP)
  1152  		delete(expectedIPs, task.ID)
  1153  		return true
  1154  	}
  1155  
  1156  	a, err := New(s, nil, nil)
  1157  	assert.NoError(t, err)
  1158  	assert.NotNil(t, a)
  1159  	// Start allocator
  1160  	go func() {
  1161  		assert.NoError(t, a.Run(context.Background()))
  1162  	}()
  1163  	defer a.Stop()
  1164  
  1165  	taskWatch, cancel := state.Watch(s.WatchQueue(), api.EventUpdateTask{}, api.EventDeleteTask{})
  1166  	defer cancel()
  1167  
  1168  	serviceWatch, cancel := state.Watch(s.WatchQueue(), api.EventUpdateService{}, api.EventDeleteService{})
  1169  	defer cancel()
  1170  
  1171  	// Confirm tasks have no IPs that overlap with the services VIPs on restart
  1172  	for i := 0; i != numsvcstsks; i++ {
  1173  		watchTask(t, s, taskWatch, false, hasNoIPOverlapTasks)
  1174  		watchService(t, serviceWatch, false, hasNoIPOverlapServices)
  1175  	}
  1176  }
  1177  
  1178  func TestNodeAllocator(t *testing.T) {
  1179  	s := store.NewMemoryStore(nil)
  1180  	assert.NotNil(t, s)
  1181  	defer s.Close()
  1182  
  1183  	a, err := New(s, nil, nil)
  1184  	assert.NoError(t, err)
  1185  	assert.NotNil(t, a)
  1186  
  1187  	var node1FromStore *api.Node
  1188  	node1 := &api.Node{
  1189  		ID: "nodeID1",
  1190  	}
  1191  
  1192  	// Try adding some objects to store before allocator is started
  1193  	assert.NoError(t, s.Update(func(tx store.Tx) error {
  1194  		// populate ingress network
  1195  		in := &api.Network{
  1196  			ID: "ingress",
  1197  			Spec: api.NetworkSpec{
  1198  				Annotations: api.Annotations{
  1199  					Name: "ingress",
  1200  				},
  1201  				Ingress: true,
  1202  			},
  1203  		}
  1204  		assert.NoError(t, store.CreateNetwork(tx, in))
  1205  
  1206  		n1 := &api.Network{
  1207  			ID: "overlayID1",
  1208  			Spec: api.NetworkSpec{
  1209  				Annotations: api.Annotations{
  1210  					Name: "overlayID1",
  1211  				},
  1212  			},
  1213  		}
  1214  		assert.NoError(t, store.CreateNetwork(tx, n1))
  1215  
  1216  		// this network will never be used for any task
  1217  		nUnused := &api.Network{
  1218  			ID: "overlayIDUnused",
  1219  			Spec: api.NetworkSpec{
  1220  				Annotations: api.Annotations{
  1221  					Name: "overlayIDUnused",
  1222  				},
  1223  			},
  1224  		}
  1225  		assert.NoError(t, store.CreateNetwork(tx, nUnused))
  1226  
  1227  		assert.NoError(t, store.CreateNode(tx, node1))
  1228  
  1229  		return nil
  1230  	}))
  1231  
  1232  	nodeWatch, cancel := state.Watch(s.WatchQueue(), api.EventUpdateNode{}, api.EventDeleteNode{})
  1233  	defer cancel()
  1234  	netWatch, cancel := state.Watch(s.WatchQueue(), api.EventUpdateNetwork{}, api.EventDeleteNetwork{})
  1235  	defer cancel()
  1236  	taskWatch, cancel := state.Watch(s.WatchQueue(), api.EventUpdateTask{})
  1237  	defer cancel()
  1238  
  1239  	// Start allocator
  1240  	go func() {
  1241  		assert.NoError(t, a.Run(context.Background()))
  1242  	}()
  1243  	defer a.Stop()
  1244  
  1245  	assert.NoError(t, s.Update(func(tx store.Tx) error {
  1246  		// create a task assigned to this node that has a network attachment on
  1247  		// n1
  1248  		t1 := &api.Task{
  1249  			ID:           "task1",
  1250  			NodeID:       node1.ID,
  1251  			DesiredState: api.TaskStateRunning,
  1252  			Spec: api.TaskSpec{
  1253  				Networks: []*api.NetworkAttachmentConfig{
  1254  					{
  1255  						Target: "overlayID1",
  1256  					},
  1257  				},
  1258  			},
  1259  		}
  1260  
  1261  		return store.CreateTask(tx, t1)
  1262  	}))
  1263  
  1264  	// validate that the task is created
  1265  	watchTask(t, s, taskWatch, false, isValidTask)
  1266  
  1267  	// Validate node has 2 LB IP address (1 for each network).
  1268  	watchNetwork(t, netWatch, false, isValidNetwork)                                      // ingress
  1269  	watchNetwork(t, netWatch, false, isValidNetwork)                                      // overlayID1
  1270  	watchNetwork(t, netWatch, false, isValidNetwork)                                      // overlayIDUnused
  1271  	watchNode(t, nodeWatch, false, isValidNode, node1, []string{"ingress", "overlayID1"}) // node1
  1272  
  1273  	// Add a node and validate it gets a LB ip only on ingress, as it has no
  1274  	// tasks assigned.
  1275  	node2 := &api.Node{
  1276  		ID: "nodeID2",
  1277  	}
  1278  	assert.NoError(t, s.Update(func(tx store.Tx) error {
  1279  		assert.NoError(t, store.CreateNode(tx, node2))
  1280  		return nil
  1281  	}))
  1282  	watchNode(t, nodeWatch, false, isValidNode, node2, []string{"ingress"}) // node2
  1283  
  1284  	// Add a network and validate that nothing has changed in the nodes
  1285  	n2 := &api.Network{
  1286  		ID: "overlayID2",
  1287  		Spec: api.NetworkSpec{
  1288  			Annotations: api.Annotations{
  1289  				Name: "overlayID2",
  1290  			},
  1291  		},
  1292  	}
  1293  	assert.NoError(t, s.Update(func(tx store.Tx) error {
  1294  		assert.NoError(t, store.CreateNetwork(tx, n2))
  1295  		return nil
  1296  	}))
  1297  	watchNetwork(t, netWatch, false, isValidNetwork) // overlayID2
  1298  	// nothing should change, no updates
  1299  	watchNode(t, nodeWatch, true, isValidNode, node1, []string{"ingress", "overlayID1"}) // node1
  1300  	watchNode(t, nodeWatch, true, isValidNode, node2, []string{"ingress"})               // node2
  1301  
  1302  	// add a task and validate that the node gets the network for the task
  1303  	assert.NoError(t, s.Update(func(tx store.Tx) error {
  1304  		// create a task assigned to this node that has a network attachment on
  1305  		// n1
  1306  		t2 := &api.Task{
  1307  			ID:           "task2",
  1308  			NodeID:       node2.ID,
  1309  			DesiredState: api.TaskStateRunning,
  1310  			Spec: api.TaskSpec{
  1311  				Networks: []*api.NetworkAttachmentConfig{
  1312  					{
  1313  						Target: "overlayID2",
  1314  					},
  1315  				},
  1316  			},
  1317  		}
  1318  
  1319  		return store.CreateTask(tx, t2)
  1320  	}))
  1321  	// validate that the task is created
  1322  	watchTask(t, s, taskWatch, false, isValidTask)
  1323  
  1324  	// validate that node2 gets a new attachment and node1 stays the same
  1325  	watchNode(t, nodeWatch, false, isValidNode, node2, []string{"ingress", "overlayID2"}) // node2
  1326  	watchNode(t, nodeWatch, true, isValidNode, node1, []string{"ingress", "overlayID1"})  // node1
  1327  
  1328  	// add another task with the same network to a node and validate that it
  1329  	// still only has 1 attachment for that network
  1330  	assert.NoError(t, s.Update(func(tx store.Tx) error {
  1331  		// create a task assigned to this node that has a network attachment on
  1332  		// n1
  1333  		t3 := &api.Task{
  1334  			ID:           "task3",
  1335  			NodeID:       node1.ID,
  1336  			DesiredState: api.TaskStateRunning,
  1337  			Spec: api.TaskSpec{
  1338  				Networks: []*api.NetworkAttachmentConfig{
  1339  					{
  1340  						Target: "overlayID1",
  1341  					},
  1342  				},
  1343  			},
  1344  		}
  1345  
  1346  		return store.CreateTask(tx, t3)
  1347  	}))
  1348  
  1349  	// validate that the task is created
  1350  	watchTask(t, s, taskWatch, false, isValidTask)
  1351  
  1352  	// validate that nothing changes
  1353  	watchNode(t, nodeWatch, true, isValidNode, node1, []string{"ingress", "overlayID1"}) // node1
  1354  	watchNode(t, nodeWatch, true, isValidNode, node2, []string{"ingress", "overlayID2"}) // node2
  1355  
  1356  	// now remove that task we just created, and validate that the node still
  1357  	// has an attachment for the other task
  1358  	// Remove a node and validate remaining node has 2 LB IP addresses
  1359  	assert.NoError(t, s.Update(func(tx store.Tx) error {
  1360  		assert.NoError(t, store.DeleteTask(tx, "task1"))
  1361  		return nil
  1362  	}))
  1363  
  1364  	// validate that nothing changes
  1365  	watchNode(t, nodeWatch, true, isValidNode, node1, []string{"ingress", "overlayID1"}) // node1
  1366  	watchNode(t, nodeWatch, true, isValidNode, node2, []string{"ingress", "overlayID2"}) // node2
  1367  
  1368  	// now remove another task. this time the attachment on the node should be
  1369  	// removed as well
  1370  	assert.NoError(t, s.Update(func(tx store.Tx) error {
  1371  		assert.NoError(t, store.DeleteTask(tx, "task2"))
  1372  		return nil
  1373  	}))
  1374  
  1375  	watchNode(t, nodeWatch, false, isValidNode, node2, []string{"ingress"})              // node2
  1376  	watchNode(t, nodeWatch, true, isValidNode, node1, []string{"ingress", "overlayID1"}) // node1
  1377  
  1378  	// Remove a node and validate remaining node has 2 LB IP addresses
  1379  	assert.NoError(t, s.Update(func(tx store.Tx) error {
  1380  		assert.NoError(t, store.DeleteNode(tx, node2.ID))
  1381  		return nil
  1382  	}))
  1383  	watchNode(t, nodeWatch, false, nil, nil, nil) // node2
  1384  	s.View(func(tx store.ReadTx) {
  1385  		node1FromStore = store.GetNode(tx, node1.ID)
  1386  	})
  1387  
  1388  	isValidNode(t, node1, node1FromStore, []string{"ingress", "overlayID1"})
  1389  
  1390  	// Validate that a LB IP address is not allocated for node-local networks
  1391  	p := &api.Network{
  1392  		ID: "bridge",
  1393  		Spec: api.NetworkSpec{
  1394  			Annotations: api.Annotations{
  1395  				Name: "pred_bridge_network",
  1396  				Labels: map[string]string{
  1397  					"com.docker.swarm.predefined": "true",
  1398  				},
  1399  			},
  1400  			DriverConfig: &api.Driver{Name: "bridge"},
  1401  		},
  1402  	}
  1403  	assert.NoError(t, s.Update(func(tx store.Tx) error {
  1404  		assert.NoError(t, store.CreateNetwork(tx, p))
  1405  		return nil
  1406  	}))
  1407  	watchNetwork(t, netWatch, false, isValidNetwork) // bridge
  1408  
  1409  	s.View(func(tx store.ReadTx) {
  1410  		node1FromStore = store.GetNode(tx, node1.ID)
  1411  	})
  1412  
  1413  	isValidNode(t, node1, node1FromStore, []string{"ingress", "overlayID1"})
  1414  }
  1415  
  1416  // TestNodeAttachmentOnLeadershipChange tests that a Node which is only partly
  1417  // allocated during a leadership change is correctly allocated afterward
  1418  func TestNodeAttachmentOnLeadershipChange(t *testing.T) {
  1419  	s := store.NewMemoryStore(nil)
  1420  	assert.NotNil(t, s)
  1421  	defer s.Close()
  1422  
  1423  	a, err := New(s, nil, nil)
  1424  	assert.NoError(t, err)
  1425  	assert.NotNil(t, a)
  1426  
  1427  	net1 := &api.Network{
  1428  		ID: "ingress",
  1429  		Spec: api.NetworkSpec{
  1430  			Annotations: api.Annotations{
  1431  				Name: "ingress",
  1432  			},
  1433  			Ingress: true,
  1434  		},
  1435  	}
  1436  
  1437  	net2 := &api.Network{
  1438  		ID: "net2",
  1439  		Spec: api.NetworkSpec{
  1440  			Annotations: api.Annotations{
  1441  				Name: "net2",
  1442  			},
  1443  		},
  1444  	}
  1445  
  1446  	node1 := &api.Node{
  1447  		ID: "node1",
  1448  	}
  1449  
  1450  	task1 := &api.Task{
  1451  		ID:           "task1",
  1452  		NodeID:       node1.ID,
  1453  		DesiredState: api.TaskStateRunning,
  1454  		Spec:         api.TaskSpec{},
  1455  	}
  1456  
  1457  	// this task is not yet assigned. we will assign it to node1 after running
  1458  	// the allocator a 2nd time. we should create it now so that its network
  1459  	// attachments are allocated.
  1460  	task2 := &api.Task{
  1461  		ID:           "task2",
  1462  		DesiredState: api.TaskStateRunning,
  1463  		Spec: api.TaskSpec{
  1464  			Networks: []*api.NetworkAttachmentConfig{
  1465  				{
  1466  					Target: "net2",
  1467  				},
  1468  			},
  1469  		},
  1470  	}
  1471  
  1472  	// before starting the allocator, populate with these
  1473  	assert.NoError(t, s.Update(func(tx store.Tx) error {
  1474  		require.NoError(t, store.CreateNetwork(tx, net1))
  1475  		require.NoError(t, store.CreateNetwork(tx, net2))
  1476  		require.NoError(t, store.CreateNode(tx, node1))
  1477  		require.NoError(t, store.CreateTask(tx, task1))
  1478  		require.NoError(t, store.CreateTask(tx, task2))
  1479  		return nil
  1480  	}))
  1481  
  1482  	// now start the allocator, let it allocate all of these objects, and then
  1483  	// stop it. it's easier to do this than to manually assign all of the
  1484  	// values
  1485  
  1486  	nodeWatch, cancel := state.Watch(s.WatchQueue(), api.EventUpdateNode{}, api.EventDeleteNode{})
  1487  	defer cancel()
  1488  	netWatch, cancel := state.Watch(s.WatchQueue(), api.EventUpdateNetwork{}, api.EventDeleteNetwork{})
  1489  	defer cancel()
  1490  	taskWatch, cancel := state.Watch(s.WatchQueue(), api.EventUpdateTask{})
  1491  	defer cancel()
  1492  
  1493  	ctx, ctxCancel := context.WithCancel(context.Background())
  1494  	go func() {
  1495  		assert.NoError(t, a.Run(ctx))
  1496  	}()
  1497  
  1498  	// validate that everything gets allocated
  1499  	watchNetwork(t, netWatch, false, isValidNetwork)
  1500  	watchNetwork(t, netWatch, false, isValidNetwork)
  1501  	watchNode(t, nodeWatch, false, isValidNode, node1, []string{"ingress"})
  1502  	watchTask(t, s, taskWatch, false, isValidTask)
  1503  
  1504  	// once everything is created, go ahead and stop the allocator
  1505  	a.Stop()
  1506  	ctxCancel()
  1507  
  1508  	// now update task2 to assign it to node1
  1509  	s.Update(func(tx store.Tx) error {
  1510  		task := store.GetTask(tx, task2.ID)
  1511  		require.NotNil(t, task)
  1512  		// make sure it has 1 network attachment
  1513  		assert.Len(t, task.Networks, 1)
  1514  		task.NodeID = node1.ID
  1515  		require.NoError(t, store.UpdateTask(tx, task))
  1516  		return nil
  1517  	})
  1518  
  1519  	// and now we'll start a new allocator.
  1520  	a2, err := New(s, nil, nil)
  1521  	assert.NoError(t, err)
  1522  	assert.NotNil(t, a2)
  1523  
  1524  	ctx2, cancel2 := context.WithCancel(context.Background())
  1525  	go func() {
  1526  		assert.NoError(t, a2.Run(ctx2))
  1527  	}()
  1528  	defer a2.Stop()
  1529  	defer cancel2()
  1530  
  1531  	// now we should see the node get allocated
  1532  	watchNode(t, nodeWatch, false, isValidNode, node1, []string{"ingress"})
  1533  	watchNode(t, nodeWatch, false, isValidNode, node1, []string{"ingress", "net2"})
  1534  }
  1535  
  1536  func isValidNode(t assert.TestingT, originalNode, updatedNode *api.Node, networks []string) bool {
  1537  
  1538  	if !assert.Equal(t, originalNode.ID, updatedNode.ID) {
  1539  		return false
  1540  	}
  1541  
  1542  	if !assert.Equal(t, len(updatedNode.Attachments), len(networks)) {
  1543  		return false
  1544  	}
  1545  
  1546  	for _, na := range updatedNode.Attachments {
  1547  		if !assert.Equal(t, len(na.Addresses), 1) {
  1548  			return false
  1549  		}
  1550  	}
  1551  
  1552  	return true
  1553  }
  1554  
  1555  func isValidNetwork(t assert.TestingT, n *api.Network) bool {
  1556  	if _, ok := n.Spec.Annotations.Labels["com.docker.swarm.predefined"]; ok {
  1557  		return true
  1558  	}
  1559  	return assert.NotEqual(t, n.IPAM.Configs, nil) &&
  1560  		assert.Equal(t, len(n.IPAM.Configs), 1) &&
  1561  		assert.Equal(t, n.IPAM.Configs[0].Range, "") &&
  1562  		assert.Equal(t, len(n.IPAM.Configs[0].Reserved), 0) &&
  1563  		isValidSubnet(t, n.IPAM.Configs[0].Subnet) &&
  1564  		assert.NotEqual(t, net.ParseIP(n.IPAM.Configs[0].Gateway), nil)
  1565  }
  1566  
  1567  func isValidTask(t assert.TestingT, s *store.MemoryStore, task *api.Task) bool {
  1568  	return isValidNetworkAttachment(t, task) &&
  1569  		isValidEndpoint(t, s, task) &&
  1570  		assert.Equal(t, task.Status.State, api.TaskStatePending)
  1571  }
  1572  
  1573  func isValidNetworkAttachment(t assert.TestingT, task *api.Task) bool {
  1574  	if len(task.Networks) != 0 {
  1575  		return assert.Equal(t, len(task.Networks[0].Addresses), 1) &&
  1576  			isValidSubnet(t, task.Networks[0].Addresses[0])
  1577  	}
  1578  
  1579  	return true
  1580  }
  1581  
  1582  func isValidEndpoint(t assert.TestingT, s *store.MemoryStore, task *api.Task) bool {
  1583  	if task.ServiceID != "" {
  1584  		var service *api.Service
  1585  		s.View(func(tx store.ReadTx) {
  1586  			service = store.GetService(tx, task.ServiceID)
  1587  		})
  1588  
  1589  		if service == nil {
  1590  			return true
  1591  		}
  1592  
  1593  		return assert.Equal(t, service.Endpoint, task.Endpoint)
  1594  
  1595  	}
  1596  
  1597  	return true
  1598  }
  1599  
  1600  func isValidSubnet(t assert.TestingT, subnet string) bool {
  1601  	_, _, err := net.ParseCIDR(subnet)
  1602  	return assert.NoError(t, err)
  1603  }
  1604  
  1605  type mockTester struct{}
  1606  
  1607  func (m mockTester) Errorf(format string, args ...interface{}) {
  1608  }
  1609  
  1610  // Returns a timeout given whether we should expect a timeout:  In the case where we do expect a timeout,
  1611  // the timeout should be short, because it's not very useful to wait long amounts of time just in case
  1612  // an unexpected event comes in - a short timeout should catch an incorrect event at least often enough
  1613  // to make the test flaky and alert us to the problem. But in the cases where we don't expect a timeout,
  1614  // the timeout should be on the order of several seconds, so the test doesn't fail just because it's run
  1615  // on a relatively slow system, or there's a load spike.
  1616  func getWatchTimeout(expectTimeout bool) time.Duration {
  1617  	if expectTimeout {
  1618  		return 350 * time.Millisecond
  1619  	}
  1620  	return 5 * time.Second
  1621  }
  1622  
  1623  func watchNode(t *testing.T, watch chan events.Event, expectTimeout bool,
  1624  	fn func(t assert.TestingT, originalNode, updatedNode *api.Node, networks []string) bool,
  1625  	originalNode *api.Node,
  1626  	networks []string) {
  1627  	for {
  1628  
  1629  		var node *api.Node
  1630  		select {
  1631  		case event := <-watch:
  1632  			if n, ok := event.(api.EventUpdateNode); ok {
  1633  				node = n.Node.Copy()
  1634  				if fn == nil || (fn != nil && fn(mockTester{}, originalNode, node, networks)) {
  1635  					return
  1636  				}
  1637  			}
  1638  
  1639  			if n, ok := event.(api.EventDeleteNode); ok {
  1640  				node = n.Node.Copy()
  1641  				if fn == nil || (fn != nil && fn(mockTester{}, originalNode, node, networks)) {
  1642  					return
  1643  				}
  1644  			}
  1645  
  1646  		case <-time.After(getWatchTimeout(expectTimeout)):
  1647  			if !expectTimeout {
  1648  				if node != nil && fn != nil {
  1649  					fn(t, originalNode, node, networks)
  1650  				}
  1651  
  1652  				t.Fatal("timed out before watchNode found expected node state", string(debug.Stack()))
  1653  			}
  1654  
  1655  			return
  1656  		}
  1657  	}
  1658  }
  1659  
  1660  func watchNetwork(t *testing.T, watch chan events.Event, expectTimeout bool, fn func(t assert.TestingT, n *api.Network) bool) {
  1661  	for {
  1662  		var network *api.Network
  1663  		select {
  1664  		case event := <-watch:
  1665  			if n, ok := event.(api.EventUpdateNetwork); ok {
  1666  				network = n.Network.Copy()
  1667  				if fn == nil || (fn != nil && fn(mockTester{}, network)) {
  1668  					return
  1669  				}
  1670  			}
  1671  
  1672  			if n, ok := event.(api.EventDeleteNetwork); ok {
  1673  				network = n.Network.Copy()
  1674  				if fn == nil || (fn != nil && fn(mockTester{}, network)) {
  1675  					return
  1676  				}
  1677  			}
  1678  
  1679  		case <-time.After(getWatchTimeout(expectTimeout)):
  1680  			if !expectTimeout {
  1681  				if network != nil && fn != nil {
  1682  					fn(t, network)
  1683  				}
  1684  
  1685  				t.Fatal("timed out before watchNetwork found expected network state", string(debug.Stack()))
  1686  			}
  1687  
  1688  			return
  1689  		}
  1690  	}
  1691  }
  1692  
  1693  func watchService(t *testing.T, watch chan events.Event, expectTimeout bool, fn func(t assert.TestingT, n *api.Service) bool) {
  1694  	for {
  1695  		var service *api.Service
  1696  		select {
  1697  		case event := <-watch:
  1698  			if s, ok := event.(api.EventUpdateService); ok {
  1699  				service = s.Service.Copy()
  1700  				if fn == nil || (fn != nil && fn(mockTester{}, service)) {
  1701  					return
  1702  				}
  1703  			}
  1704  
  1705  			if s, ok := event.(api.EventDeleteService); ok {
  1706  				service = s.Service.Copy()
  1707  				if fn == nil || (fn != nil && fn(mockTester{}, service)) {
  1708  					return
  1709  				}
  1710  			}
  1711  
  1712  		case <-time.After(getWatchTimeout(expectTimeout)):
  1713  			if !expectTimeout {
  1714  				if service != nil && fn != nil {
  1715  					fn(t, service)
  1716  				}
  1717  
  1718  				t.Fatalf("timed out before watchService found expected service state\n stack = %s", string(debug.Stack()))
  1719  			}
  1720  
  1721  			return
  1722  		}
  1723  	}
  1724  }
  1725  
  1726  func watchTask(t *testing.T, s *store.MemoryStore, watch chan events.Event, expectTimeout bool, fn func(t assert.TestingT, s *store.MemoryStore, n *api.Task) bool) {
  1727  	for {
  1728  		var task *api.Task
  1729  		select {
  1730  		case event := <-watch:
  1731  			if t, ok := event.(api.EventUpdateTask); ok {
  1732  				task = t.Task.Copy()
  1733  				if fn == nil || (fn != nil && fn(mockTester{}, s, task)) {
  1734  					return
  1735  				}
  1736  			}
  1737  
  1738  			if t, ok := event.(api.EventDeleteTask); ok {
  1739  				task = t.Task.Copy()
  1740  				if fn == nil || (fn != nil && fn(mockTester{}, s, task)) {
  1741  					return
  1742  				}
  1743  			}
  1744  
  1745  		case <-time.After(getWatchTimeout(expectTimeout)):
  1746  			if !expectTimeout {
  1747  				if task != nil && fn != nil {
  1748  					fn(t, s, task)
  1749  				}
  1750  
  1751  				t.Fatalf("timed out before watchTask found expected task state %s", debug.Stack())
  1752  			}
  1753  
  1754  			return
  1755  		}
  1756  	}
  1757  }