github.com/uchennaokeke444/nomad@v0.11.8/nomad/structs/network_test.go (about)

     1  package structs
     2  
     3  import (
     4  	"fmt"
     5  	"net"
     6  	"reflect"
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/require"
    10  )
    11  
    12  func TestNetworkIndex_Overcommitted(t *testing.T) {
    13  	idx := NewNetworkIndex()
    14  
    15  	// Consume some network
    16  	reserved := &NetworkResource{
    17  		Device:        "eth0",
    18  		IP:            "192.168.0.100",
    19  		MBits:         505,
    20  		ReservedPorts: []Port{{"one", 8000, 0}, {"two", 9000, 0}},
    21  	}
    22  	collide := idx.AddReserved(reserved)
    23  	if collide {
    24  		t.Fatalf("bad")
    25  	}
    26  	if !idx.Overcommitted() {
    27  		t.Fatalf("have no resources")
    28  	}
    29  
    30  	// Add resources
    31  	n := &Node{
    32  		NodeResources: &NodeResources{
    33  			Networks: []*NetworkResource{
    34  				{
    35  					Device: "eth0",
    36  					CIDR:   "192.168.0.100/32",
    37  					MBits:  1000,
    38  				},
    39  			},
    40  		},
    41  	}
    42  	idx.SetNode(n)
    43  	if idx.Overcommitted() {
    44  		t.Fatalf("have resources")
    45  	}
    46  
    47  	// Double up our usage
    48  	idx.AddReserved(reserved)
    49  	if !idx.Overcommitted() {
    50  		t.Fatalf("should be overcommitted")
    51  	}
    52  }
    53  
    54  func TestNetworkIndex_SetNode(t *testing.T) {
    55  	idx := NewNetworkIndex()
    56  	n := &Node{
    57  		NodeResources: &NodeResources{
    58  			Networks: []*NetworkResource{
    59  				{
    60  					Device: "eth0",
    61  					CIDR:   "192.168.0.100/32",
    62  					IP:     "192.168.0.100",
    63  					MBits:  1000,
    64  				},
    65  			},
    66  		},
    67  		ReservedResources: &NodeReservedResources{
    68  			Networks: NodeReservedNetworkResources{
    69  				ReservedHostPorts: "22",
    70  			},
    71  		},
    72  	}
    73  	collide := idx.SetNode(n)
    74  	if collide {
    75  		t.Fatalf("bad")
    76  	}
    77  
    78  	if len(idx.AvailNetworks) != 1 {
    79  		t.Fatalf("Bad")
    80  	}
    81  	if idx.AvailBandwidth["eth0"] != 1000 {
    82  		t.Fatalf("Bad")
    83  	}
    84  	if !idx.UsedPorts["192.168.0.100"].Check(22) {
    85  		t.Fatalf("Bad")
    86  	}
    87  }
    88  
    89  func TestNetworkIndex_AddAllocs(t *testing.T) {
    90  	idx := NewNetworkIndex()
    91  	allocs := []*Allocation{
    92  		{
    93  			AllocatedResources: &AllocatedResources{
    94  				Tasks: map[string]*AllocatedTaskResources{
    95  					"web": {
    96  						Networks: []*NetworkResource{
    97  							{
    98  								Device:        "eth0",
    99  								IP:            "192.168.0.100",
   100  								MBits:         20,
   101  								ReservedPorts: []Port{{"one", 8000, 0}, {"two", 9000, 0}},
   102  							},
   103  						},
   104  					},
   105  				},
   106  			},
   107  		},
   108  		{
   109  			AllocatedResources: &AllocatedResources{
   110  				Tasks: map[string]*AllocatedTaskResources{
   111  					"api": {
   112  						Networks: []*NetworkResource{
   113  							{
   114  								Device:        "eth0",
   115  								IP:            "192.168.0.100",
   116  								MBits:         50,
   117  								ReservedPorts: []Port{{"one", 10000, 0}},
   118  							},
   119  						},
   120  					},
   121  				},
   122  			},
   123  		},
   124  	}
   125  	collide := idx.AddAllocs(allocs)
   126  	if collide {
   127  		t.Fatalf("bad")
   128  	}
   129  
   130  	if idx.UsedBandwidth["eth0"] != 70 {
   131  		t.Fatalf("Bad")
   132  	}
   133  	if !idx.UsedPorts["192.168.0.100"].Check(8000) {
   134  		t.Fatalf("Bad")
   135  	}
   136  	if !idx.UsedPorts["192.168.0.100"].Check(9000) {
   137  		t.Fatalf("Bad")
   138  	}
   139  	if !idx.UsedPorts["192.168.0.100"].Check(10000) {
   140  		t.Fatalf("Bad")
   141  	}
   142  }
   143  
   144  func TestNetworkIndex_AddReserved(t *testing.T) {
   145  	idx := NewNetworkIndex()
   146  
   147  	reserved := &NetworkResource{
   148  		Device:        "eth0",
   149  		IP:            "192.168.0.100",
   150  		MBits:         20,
   151  		ReservedPorts: []Port{{"one", 8000, 0}, {"two", 9000, 0}},
   152  	}
   153  	collide := idx.AddReserved(reserved)
   154  	if collide {
   155  		t.Fatalf("bad")
   156  	}
   157  
   158  	if idx.UsedBandwidth["eth0"] != 20 {
   159  		t.Fatalf("Bad")
   160  	}
   161  	if !idx.UsedPorts["192.168.0.100"].Check(8000) {
   162  		t.Fatalf("Bad")
   163  	}
   164  	if !idx.UsedPorts["192.168.0.100"].Check(9000) {
   165  		t.Fatalf("Bad")
   166  	}
   167  
   168  	// Try to reserve the same network
   169  	collide = idx.AddReserved(reserved)
   170  	if !collide {
   171  		t.Fatalf("bad")
   172  	}
   173  }
   174  
   175  // XXX Reserving ports doesn't work when yielding from a CIDR block. This is
   176  // okay for now since we do not actually fingerprint CIDR blocks.
   177  func TestNetworkIndex_yieldIP(t *testing.T) {
   178  	idx := NewNetworkIndex()
   179  	n := &Node{
   180  		NodeResources: &NodeResources{
   181  			Networks: []*NetworkResource{
   182  				{
   183  					Device: "eth0",
   184  					CIDR:   "192.168.0.100/30",
   185  					MBits:  1000,
   186  				},
   187  			},
   188  		},
   189  	}
   190  	idx.SetNode(n)
   191  
   192  	var out []string
   193  	idx.yieldIP(func(n *NetworkResource, ip net.IP) (stop bool) {
   194  		out = append(out, ip.String())
   195  		return
   196  	})
   197  
   198  	expect := []string{"192.168.0.100", "192.168.0.101",
   199  		"192.168.0.102", "192.168.0.103"}
   200  	if !reflect.DeepEqual(out, expect) {
   201  		t.Fatalf("bad: %v", out)
   202  	}
   203  }
   204  
   205  func TestNetworkIndex_AssignNetwork(t *testing.T) {
   206  	idx := NewNetworkIndex()
   207  	n := &Node{
   208  		NodeResources: &NodeResources{
   209  			Networks: []*NetworkResource{
   210  				{
   211  					Device: "eth0",
   212  					CIDR:   "192.168.0.100/30",
   213  					MBits:  1000,
   214  				},
   215  			},
   216  		},
   217  	}
   218  	idx.SetNode(n)
   219  
   220  	allocs := []*Allocation{
   221  		{
   222  			TaskResources: map[string]*Resources{
   223  				"web": {
   224  					Networks: []*NetworkResource{
   225  						{
   226  							Device:        "eth0",
   227  							IP:            "192.168.0.100",
   228  							MBits:         20,
   229  							ReservedPorts: []Port{{"one", 8000, 0}, {"two", 9000, 0}},
   230  						},
   231  					},
   232  				},
   233  			},
   234  		},
   235  		{
   236  			TaskResources: map[string]*Resources{
   237  				"api": {
   238  					Networks: []*NetworkResource{
   239  						{
   240  							Device:        "eth0",
   241  							IP:            "192.168.0.100",
   242  							MBits:         50,
   243  							ReservedPorts: []Port{{"main", 10000, 0}},
   244  						},
   245  					},
   246  				},
   247  			},
   248  		},
   249  	}
   250  	idx.AddAllocs(allocs)
   251  
   252  	// Ask for a reserved port
   253  	ask := &NetworkResource{
   254  		ReservedPorts: []Port{{"main", 8000, 0}},
   255  	}
   256  	offer, err := idx.AssignNetwork(ask)
   257  	require.NoError(t, err)
   258  	require.NotNil(t, offer)
   259  	require.Equal(t, "192.168.0.101", offer.IP)
   260  	rp := Port{"main", 8000, 0}
   261  	require.Len(t, offer.ReservedPorts, 1)
   262  	require.Exactly(t, rp, offer.ReservedPorts[0])
   263  
   264  	// Ask for dynamic ports
   265  	ask = &NetworkResource{
   266  		DynamicPorts: []Port{{"http", 0, 80}, {"https", 0, 443}, {"admin", 0, -1}},
   267  	}
   268  	offer, err = idx.AssignNetwork(ask)
   269  	require.NoError(t, err)
   270  	require.NotNil(t, offer)
   271  	require.Equal(t, "192.168.0.100", offer.IP)
   272  	require.Len(t, offer.DynamicPorts, 3)
   273  	var adminPort Port
   274  	for _, port := range offer.DynamicPorts {
   275  		require.NotZero(t, port.Value)
   276  		if port.Label == "admin" {
   277  			adminPort = port
   278  		}
   279  	}
   280  	require.Equal(t, adminPort.Value, adminPort.To)
   281  
   282  	// Ask for reserved + dynamic ports
   283  	ask = &NetworkResource{
   284  		ReservedPorts: []Port{{"main", 2345, 0}},
   285  		DynamicPorts:  []Port{{"http", 0, 80}, {"https", 0, 443}, {"admin", 0, 8080}},
   286  	}
   287  	offer, err = idx.AssignNetwork(ask)
   288  	require.NoError(t, err)
   289  	require.NotNil(t, offer)
   290  	require.Equal(t, "192.168.0.100", offer.IP)
   291  
   292  	rp = Port{"main", 2345, 0}
   293  	require.Len(t, offer.ReservedPorts, 1)
   294  	require.Exactly(t, rp, offer.ReservedPorts[0])
   295  
   296  	// Ask for too much bandwidth
   297  	ask = &NetworkResource{
   298  		MBits: 1000,
   299  	}
   300  	offer, err = idx.AssignNetwork(ask)
   301  	require.Error(t, err)
   302  	require.Equal(t, "bandwidth exceeded", err.Error())
   303  	require.Nil(t, offer)
   304  }
   305  
   306  // This test ensures that even with a small domain of available ports we are
   307  // able to make a dynamic port allocation.
   308  func TestNetworkIndex_AssignNetwork_Dynamic_Contention(t *testing.T) {
   309  
   310  	// Create a node that only has one free port
   311  	idx := NewNetworkIndex()
   312  	n := &Node{
   313  		NodeResources: &NodeResources{
   314  			Networks: []*NetworkResource{
   315  				{
   316  					Device: "eth0",
   317  					CIDR:   "192.168.0.100/32",
   318  					IP:     "192.168.0.100",
   319  					MBits:  1000,
   320  				},
   321  			},
   322  		},
   323  		ReservedResources: &NodeReservedResources{
   324  			Networks: NodeReservedNetworkResources{
   325  				ReservedHostPorts: fmt.Sprintf("%d-%d", MinDynamicPort, MaxDynamicPort-1),
   326  			},
   327  		},
   328  	}
   329  	idx.SetNode(n)
   330  
   331  	// Ask for dynamic ports
   332  	ask := &NetworkResource{
   333  		DynamicPorts: []Port{{"http", 0, 80}},
   334  	}
   335  	offer, err := idx.AssignNetwork(ask)
   336  	if err != nil {
   337  		t.Fatalf("err: %v", err)
   338  	}
   339  	if offer == nil {
   340  		t.Fatalf("bad")
   341  	}
   342  	if offer.IP != "192.168.0.100" {
   343  		t.Fatalf("bad: %#v", offer)
   344  	}
   345  	if len(offer.DynamicPorts) != 1 {
   346  		t.Fatalf("There should be one dynamic ports")
   347  	}
   348  	if p := offer.DynamicPorts[0].Value; p != MaxDynamicPort {
   349  		t.Fatalf("Dynamic Port: should have been assigned %d; got %d", p, MaxDynamicPort)
   350  	}
   351  }
   352  
   353  // COMPAT(0.11): Remove in 0.11
   354  func TestNetworkIndex_Overcommitted_Old(t *testing.T) {
   355  	idx := NewNetworkIndex()
   356  
   357  	// Consume some network
   358  	reserved := &NetworkResource{
   359  		Device:        "eth0",
   360  		IP:            "192.168.0.100",
   361  		MBits:         505,
   362  		ReservedPorts: []Port{{"one", 8000, 0}, {"two", 9000, 0}},
   363  	}
   364  	collide := idx.AddReserved(reserved)
   365  	if collide {
   366  		t.Fatalf("bad")
   367  	}
   368  	if !idx.Overcommitted() {
   369  		t.Fatalf("have no resources")
   370  	}
   371  
   372  	// Add resources
   373  	n := &Node{
   374  		Resources: &Resources{
   375  			Networks: []*NetworkResource{
   376  				{
   377  					Device: "eth0",
   378  					CIDR:   "192.168.0.100/32",
   379  					MBits:  1000,
   380  				},
   381  			},
   382  		},
   383  	}
   384  	idx.SetNode(n)
   385  	if idx.Overcommitted() {
   386  		t.Fatalf("have resources")
   387  	}
   388  
   389  	// Double up our usage
   390  	idx.AddReserved(reserved)
   391  	if !idx.Overcommitted() {
   392  		t.Fatalf("should be overcommitted")
   393  	}
   394  }
   395  
   396  // COMPAT(0.11): Remove in 0.11
   397  func TestNetworkIndex_SetNode_Old(t *testing.T) {
   398  	idx := NewNetworkIndex()
   399  	n := &Node{
   400  		Resources: &Resources{
   401  			Networks: []*NetworkResource{
   402  				{
   403  					Device: "eth0",
   404  					CIDR:   "192.168.0.100/32",
   405  					MBits:  1000,
   406  				},
   407  			},
   408  		},
   409  		Reserved: &Resources{
   410  			Networks: []*NetworkResource{
   411  				{
   412  					Device:        "eth0",
   413  					IP:            "192.168.0.100",
   414  					ReservedPorts: []Port{{"ssh", 22, 0}},
   415  					MBits:         1,
   416  				},
   417  			},
   418  		},
   419  	}
   420  	collide := idx.SetNode(n)
   421  	if collide {
   422  		t.Fatalf("bad")
   423  	}
   424  
   425  	if len(idx.AvailNetworks) != 1 {
   426  		t.Fatalf("Bad")
   427  	}
   428  	if idx.AvailBandwidth["eth0"] != 1000 {
   429  		t.Fatalf("Bad")
   430  	}
   431  	if idx.UsedBandwidth["eth0"] != 1 {
   432  		t.Fatalf("Bad")
   433  	}
   434  	if !idx.UsedPorts["192.168.0.100"].Check(22) {
   435  		t.Fatalf("Bad")
   436  	}
   437  }
   438  
   439  // COMPAT(0.11): Remove in 0.11
   440  func TestNetworkIndex_AddAllocs_Old(t *testing.T) {
   441  	idx := NewNetworkIndex()
   442  	allocs := []*Allocation{
   443  		{
   444  			TaskResources: map[string]*Resources{
   445  				"web": {
   446  					Networks: []*NetworkResource{
   447  						{
   448  							Device:        "eth0",
   449  							IP:            "192.168.0.100",
   450  							MBits:         20,
   451  							ReservedPorts: []Port{{"one", 8000, 0}, {"two", 9000, 0}},
   452  						},
   453  					},
   454  				},
   455  			},
   456  		},
   457  		{
   458  			TaskResources: map[string]*Resources{
   459  				"api": {
   460  					Networks: []*NetworkResource{
   461  						{
   462  							Device:        "eth0",
   463  							IP:            "192.168.0.100",
   464  							MBits:         50,
   465  							ReservedPorts: []Port{{"one", 10000, 0}},
   466  						},
   467  					},
   468  				},
   469  			},
   470  		},
   471  	}
   472  	collide := idx.AddAllocs(allocs)
   473  	if collide {
   474  		t.Fatalf("bad")
   475  	}
   476  
   477  	if idx.UsedBandwidth["eth0"] != 70 {
   478  		t.Fatalf("Bad")
   479  	}
   480  	if !idx.UsedPorts["192.168.0.100"].Check(8000) {
   481  		t.Fatalf("Bad")
   482  	}
   483  	if !idx.UsedPorts["192.168.0.100"].Check(9000) {
   484  		t.Fatalf("Bad")
   485  	}
   486  	if !idx.UsedPorts["192.168.0.100"].Check(10000) {
   487  		t.Fatalf("Bad")
   488  	}
   489  }
   490  
   491  // COMPAT(0.11): Remove in 0.11
   492  func TestNetworkIndex_yieldIP_Old(t *testing.T) {
   493  	idx := NewNetworkIndex()
   494  	n := &Node{
   495  		Resources: &Resources{
   496  			Networks: []*NetworkResource{
   497  				{
   498  					Device: "eth0",
   499  					CIDR:   "192.168.0.100/30",
   500  					MBits:  1000,
   501  				},
   502  			},
   503  		},
   504  		Reserved: &Resources{
   505  			Networks: []*NetworkResource{
   506  				{
   507  					Device:        "eth0",
   508  					IP:            "192.168.0.100",
   509  					ReservedPorts: []Port{{"ssh", 22, 0}},
   510  					MBits:         1,
   511  				},
   512  			},
   513  		},
   514  	}
   515  	idx.SetNode(n)
   516  
   517  	var out []string
   518  	idx.yieldIP(func(n *NetworkResource, ip net.IP) (stop bool) {
   519  		out = append(out, ip.String())
   520  		return
   521  	})
   522  
   523  	expect := []string{"192.168.0.100", "192.168.0.101",
   524  		"192.168.0.102", "192.168.0.103"}
   525  	if !reflect.DeepEqual(out, expect) {
   526  		t.Fatalf("bad: %v", out)
   527  	}
   528  }
   529  
   530  // COMPAT(0.11): Remove in 0.11
   531  func TestNetworkIndex_AssignNetwork_Old(t *testing.T) {
   532  	idx := NewNetworkIndex()
   533  	n := &Node{
   534  		Resources: &Resources{
   535  			Networks: []*NetworkResource{
   536  				{
   537  					Device: "eth0",
   538  					CIDR:   "192.168.0.100/30",
   539  					MBits:  1000,
   540  				},
   541  			},
   542  		},
   543  		Reserved: &Resources{
   544  			Networks: []*NetworkResource{
   545  				{
   546  					Device:        "eth0",
   547  					IP:            "192.168.0.100",
   548  					ReservedPorts: []Port{{"ssh", 22, 0}},
   549  					MBits:         1,
   550  				},
   551  			},
   552  		},
   553  	}
   554  	idx.SetNode(n)
   555  
   556  	allocs := []*Allocation{
   557  		{
   558  			TaskResources: map[string]*Resources{
   559  				"web": {
   560  					Networks: []*NetworkResource{
   561  						{
   562  							Device:        "eth0",
   563  							IP:            "192.168.0.100",
   564  							MBits:         20,
   565  							ReservedPorts: []Port{{"one", 8000, 0}, {"two", 9000, 0}},
   566  						},
   567  					},
   568  				},
   569  			},
   570  		},
   571  		{
   572  			TaskResources: map[string]*Resources{
   573  				"api": {
   574  					Networks: []*NetworkResource{
   575  						{
   576  							Device:        "eth0",
   577  							IP:            "192.168.0.100",
   578  							MBits:         50,
   579  							ReservedPorts: []Port{{"main", 10000, 0}},
   580  						},
   581  					},
   582  				},
   583  			},
   584  		},
   585  	}
   586  	idx.AddAllocs(allocs)
   587  
   588  	// Ask for a reserved port
   589  	ask := &NetworkResource{
   590  		ReservedPorts: []Port{{"main", 8000, 0}},
   591  	}
   592  	offer, err := idx.AssignNetwork(ask)
   593  	if err != nil {
   594  		t.Fatalf("err: %v", err)
   595  	}
   596  	if offer == nil {
   597  		t.Fatalf("bad")
   598  	}
   599  	if offer.IP != "192.168.0.101" {
   600  		t.Fatalf("bad: %#v", offer)
   601  	}
   602  	rp := Port{"main", 8000, 0}
   603  	if len(offer.ReservedPorts) != 1 || offer.ReservedPorts[0] != rp {
   604  		t.Fatalf("bad: %#v", offer)
   605  	}
   606  
   607  	// Ask for dynamic ports
   608  	ask = &NetworkResource{
   609  		DynamicPorts: []Port{{"http", 0, 80}, {"https", 0, 443}, {"admin", 0, 8080}},
   610  	}
   611  	offer, err = idx.AssignNetwork(ask)
   612  	if err != nil {
   613  		t.Fatalf("err: %v", err)
   614  	}
   615  	if offer == nil {
   616  		t.Fatalf("bad")
   617  	}
   618  	if offer.IP != "192.168.0.100" {
   619  		t.Fatalf("bad: %#v", offer)
   620  	}
   621  	if len(offer.DynamicPorts) != 3 {
   622  		t.Fatalf("There should be three dynamic ports")
   623  	}
   624  	for _, port := range offer.DynamicPorts {
   625  		if port.Value == 0 {
   626  			t.Fatalf("Dynamic Port: %v should have been assigned a host port", port.Label)
   627  		}
   628  	}
   629  
   630  	// Ask for reserved + dynamic ports
   631  	ask = &NetworkResource{
   632  		ReservedPorts: []Port{{"main", 2345, 0}},
   633  		DynamicPorts:  []Port{{"http", 0, 80}, {"https", 0, 443}, {"admin", 0, 8080}},
   634  	}
   635  	offer, err = idx.AssignNetwork(ask)
   636  	if err != nil {
   637  		t.Fatalf("err: %v", err)
   638  	}
   639  	if offer == nil {
   640  		t.Fatalf("bad")
   641  	}
   642  	if offer.IP != "192.168.0.100" {
   643  		t.Fatalf("bad: %#v", offer)
   644  	}
   645  
   646  	rp = Port{"main", 2345, 0}
   647  	if len(offer.ReservedPorts) != 1 || offer.ReservedPorts[0] != rp {
   648  		t.Fatalf("bad: %#v", offer)
   649  	}
   650  
   651  	// Ask for too much bandwidth
   652  	ask = &NetworkResource{
   653  		MBits: 1000,
   654  	}
   655  	offer, err = idx.AssignNetwork(ask)
   656  	if err.Error() != "bandwidth exceeded" {
   657  		t.Fatalf("err: %v", err)
   658  	}
   659  	if offer != nil {
   660  		t.Fatalf("bad")
   661  	}
   662  }
   663  
   664  // COMPAT(0.11): Remove in 0.11
   665  // This test ensures that even with a small domain of available ports we are
   666  // able to make a dynamic port allocation.
   667  func TestNetworkIndex_AssignNetwork_Dynamic_Contention_Old(t *testing.T) {
   668  
   669  	// Create a node that only has one free port
   670  	idx := NewNetworkIndex()
   671  	n := &Node{
   672  		Resources: &Resources{
   673  			Networks: []*NetworkResource{
   674  				{
   675  					Device: "eth0",
   676  					CIDR:   "192.168.0.100/32",
   677  					MBits:  1000,
   678  				},
   679  			},
   680  		},
   681  		Reserved: &Resources{
   682  			Networks: []*NetworkResource{
   683  				{
   684  					Device: "eth0",
   685  					IP:     "192.168.0.100",
   686  					MBits:  1,
   687  				},
   688  			},
   689  		},
   690  	}
   691  	for i := MinDynamicPort; i < MaxDynamicPort; i++ {
   692  		n.Reserved.Networks[0].ReservedPorts = append(n.Reserved.Networks[0].ReservedPorts, Port{Value: i})
   693  	}
   694  
   695  	idx.SetNode(n)
   696  
   697  	// Ask for dynamic ports
   698  	ask := &NetworkResource{
   699  		DynamicPorts: []Port{{"http", 0, 80}},
   700  	}
   701  	offer, err := idx.AssignNetwork(ask)
   702  	if err != nil {
   703  		t.Fatalf("err: %v", err)
   704  	}
   705  	if offer == nil {
   706  		t.Fatalf("bad")
   707  	}
   708  	if offer.IP != "192.168.0.100" {
   709  		t.Fatalf("bad: %#v", offer)
   710  	}
   711  	if len(offer.DynamicPorts) != 1 {
   712  		t.Fatalf("There should be three dynamic ports")
   713  	}
   714  	if p := offer.DynamicPorts[0].Value; p != MaxDynamicPort {
   715  		t.Fatalf("Dynamic Port: should have been assigned %d; got %d", p, MaxDynamicPort)
   716  	}
   717  }
   718  
   719  func TestIntContains(t *testing.T) {
   720  	l := []int{1, 2, 10, 20}
   721  	if isPortReserved(l, 50) {
   722  		t.Fatalf("bad")
   723  	}
   724  	if !isPortReserved(l, 20) {
   725  		t.Fatalf("bad")
   726  	}
   727  	if !isPortReserved(l, 1) {
   728  		t.Fatalf("bad")
   729  	}
   730  }