github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/libnetwork/ipam/allocator_test.go (about)

     1  package ipam
     2  
     3  import (
     4  	"encoding/json"
     5  	"flag"
     6  	"fmt"
     7  	"io/ioutil"
     8  	"math/rand"
     9  	"net"
    10  	"strconv"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/docker/libkv/store"
    15  	"github.com/docker/libkv/store/boltdb"
    16  	"github.com/docker/libnetwork/bitseq"
    17  	"github.com/docker/libnetwork/datastore"
    18  	"github.com/docker/libnetwork/ipamapi"
    19  	"github.com/docker/libnetwork/ipamutils"
    20  	_ "github.com/docker/libnetwork/testutils"
    21  	"github.com/docker/libnetwork/types"
    22  )
    23  
    24  const (
    25  	defaultPrefix = "/tmp/libnetwork/test/ipam"
    26  )
    27  
    28  func init() {
    29  	boltdb.Register()
    30  }
    31  
    32  // OptionBoltdbWithRandomDBFile function returns a random dir for local store backend
    33  func randomLocalStore() (datastore.DataStore, error) {
    34  	tmp, err := ioutil.TempFile("", "libnetwork-")
    35  	if err != nil {
    36  		return nil, fmt.Errorf("Error creating temp file: %v", err)
    37  	}
    38  	if err := tmp.Close(); err != nil {
    39  		return nil, fmt.Errorf("Error closing temp file: %v", err)
    40  	}
    41  	return datastore.NewDataStore(datastore.LocalScope, &datastore.ScopeCfg{
    42  		Client: datastore.ScopeClientCfg{
    43  			Provider: "boltdb",
    44  			Address:  defaultPrefix + tmp.Name(),
    45  			Config: &store.Config{
    46  				Bucket:            "libnetwork",
    47  				ConnectionTimeout: 3 * time.Second,
    48  			},
    49  		},
    50  	})
    51  }
    52  
    53  func getAllocator() (*Allocator, error) {
    54  	ipamutils.InitNetworks()
    55  	ds, err := randomLocalStore()
    56  	if err != nil {
    57  		return nil, err
    58  	}
    59  	a, err := NewAllocator(ds, nil)
    60  	if err != nil {
    61  		return nil, err
    62  	}
    63  	return a, nil
    64  }
    65  
    66  func TestInt2IP2IntConversion(t *testing.T) {
    67  	for i := uint64(0); i < 256*256*256; i++ {
    68  		var array [4]byte // new array at each cycle
    69  		addIntToIP(array[:], i)
    70  		j := ipToUint64(array[:])
    71  		if j != i {
    72  			t.Fatalf("Failed to convert ordinal %d to IP % x and back to ordinal. Got %d", i, array, j)
    73  		}
    74  	}
    75  }
    76  
    77  func TestGetAddressVersion(t *testing.T) {
    78  	if v4 != getAddressVersion(net.ParseIP("172.28.30.112")) {
    79  		t.Fatalf("Failed to detect IPv4 version")
    80  	}
    81  	if v4 != getAddressVersion(net.ParseIP("0.0.0.1")) {
    82  		t.Fatalf("Failed to detect IPv4 version")
    83  	}
    84  	if v6 != getAddressVersion(net.ParseIP("ff01::1")) {
    85  		t.Fatalf("Failed to detect IPv6 version")
    86  	}
    87  	if v6 != getAddressVersion(net.ParseIP("2001:db8::76:51")) {
    88  		t.Fatalf("Failed to detect IPv6 version")
    89  	}
    90  }
    91  
    92  func TestKeyString(t *testing.T) {
    93  	k := &SubnetKey{AddressSpace: "default", Subnet: "172.27.0.0/16"}
    94  	expected := "default/172.27.0.0/16"
    95  	if expected != k.String() {
    96  		t.Fatalf("Unexpected key string: %s", k.String())
    97  	}
    98  
    99  	k2 := &SubnetKey{}
   100  	err := k2.FromString(expected)
   101  	if err != nil {
   102  		t.Fatal(err)
   103  	}
   104  	if k2.AddressSpace != k.AddressSpace || k2.Subnet != k.Subnet {
   105  		t.Fatalf("SubnetKey.FromString() failed. Expected %v. Got %v", k, k2)
   106  	}
   107  
   108  	expected = fmt.Sprintf("%s/%s", expected, "172.27.3.0/24")
   109  	k.ChildSubnet = "172.27.3.0/24"
   110  	if expected != k.String() {
   111  		t.Fatalf("Unexpected key string: %s", k.String())
   112  	}
   113  
   114  	err = k2.FromString(expected)
   115  	if err != nil {
   116  		t.Fatal(err)
   117  	}
   118  	if k2.AddressSpace != k.AddressSpace || k2.Subnet != k.Subnet || k2.ChildSubnet != k.ChildSubnet {
   119  		t.Fatalf("SubnetKey.FromString() failed. Expected %v. Got %v", k, k2)
   120  	}
   121  }
   122  
   123  func TestPoolDataMarshal(t *testing.T) {
   124  	_, nw, err := net.ParseCIDR("172.28.30.1/24")
   125  	if err != nil {
   126  		t.Fatal(err)
   127  	}
   128  
   129  	p := &PoolData{
   130  		ParentKey: SubnetKey{AddressSpace: "Blue", Subnet: "172.28.0.0/16"},
   131  		Pool:      nw,
   132  		Range:     &AddressRange{Sub: &net.IPNet{IP: net.IP{172, 28, 20, 0}, Mask: net.IPMask{255, 255, 255, 0}}, Start: 0, End: 255},
   133  		RefCount:  4,
   134  	}
   135  
   136  	ba, err := json.Marshal(p)
   137  	if err != nil {
   138  		t.Fatal(err)
   139  	}
   140  	var q PoolData
   141  	err = json.Unmarshal(ba, &q)
   142  	if err != nil {
   143  		t.Fatal(err)
   144  	}
   145  
   146  	if p.ParentKey != q.ParentKey || !types.CompareIPNet(p.Range.Sub, q.Range.Sub) ||
   147  		p.Range.Start != q.Range.Start || p.Range.End != q.Range.End || p.RefCount != q.RefCount ||
   148  		!types.CompareIPNet(p.Pool, q.Pool) {
   149  		t.Fatalf("\n%#v\n%#v", p, &q)
   150  	}
   151  
   152  	p = &PoolData{
   153  		ParentKey: SubnetKey{AddressSpace: "Blue", Subnet: "172.28.0.0/16"},
   154  		Pool:      nw,
   155  		RefCount:  4,
   156  	}
   157  
   158  	ba, err = json.Marshal(p)
   159  	if err != nil {
   160  		t.Fatal(err)
   161  	}
   162  	err = json.Unmarshal(ba, &q)
   163  	if err != nil {
   164  		t.Fatal(err)
   165  	}
   166  
   167  	if q.Range != nil {
   168  		t.Fatalf("Unexpected Range")
   169  	}
   170  }
   171  
   172  func TestSubnetsMarshal(t *testing.T) {
   173  	a, err := getAllocator()
   174  	if err != nil {
   175  		t.Fatal(err)
   176  	}
   177  	pid0, _, _, err := a.RequestPool(localAddressSpace, "192.168.0.0/16", "", nil, false)
   178  	if err != nil {
   179  		t.Fatal(err)
   180  	}
   181  	pid1, _, _, err := a.RequestPool(localAddressSpace, "192.169.0.0/16", "", nil, false)
   182  	if err != nil {
   183  		t.Fatal(err)
   184  	}
   185  	_, _, err = a.RequestAddress(pid0, nil, nil)
   186  	if err != nil {
   187  		t.Fatal(err)
   188  	}
   189  
   190  	cfg, err := a.getAddrSpace(localAddressSpace)
   191  	if err != nil {
   192  		t.Fatal(err)
   193  	}
   194  
   195  	ba := cfg.Value()
   196  	if err := cfg.SetValue(ba); err != nil {
   197  		t.Fatal(err)
   198  	}
   199  
   200  	expIP := &net.IPNet{IP: net.IP{192, 168, 0, 2}, Mask: net.IPMask{255, 255, 0, 0}}
   201  	ip, _, err := a.RequestAddress(pid0, nil, nil)
   202  	if err != nil {
   203  		t.Fatal(err)
   204  	}
   205  	if !types.CompareIPNet(expIP, ip) {
   206  		t.Fatalf("Got unexpected ip after pool config restore: %s", ip)
   207  	}
   208  
   209  	expIP = &net.IPNet{IP: net.IP{192, 169, 0, 1}, Mask: net.IPMask{255, 255, 0, 0}}
   210  	ip, _, err = a.RequestAddress(pid1, nil, nil)
   211  	if err != nil {
   212  		t.Fatal(err)
   213  	}
   214  	if !types.CompareIPNet(expIP, ip) {
   215  		t.Fatalf("Got unexpected ip after pool config restore: %s", ip)
   216  	}
   217  }
   218  
   219  func TestAddSubnets(t *testing.T) {
   220  	a, err := getAllocator()
   221  	if err != nil {
   222  		t.Fatal(err)
   223  	}
   224  	a.addrSpaces["abc"] = a.addrSpaces[localAddressSpace]
   225  
   226  	pid0, _, _, err := a.RequestPool(localAddressSpace, "10.0.0.0/8", "", nil, false)
   227  	if err != nil {
   228  		t.Fatalf("Unexpected failure in adding subnet")
   229  	}
   230  
   231  	pid1, _, _, err := a.RequestPool("abc", "10.0.0.0/8", "", nil, false)
   232  	if err != nil {
   233  		t.Fatalf("Unexpected failure in adding overlapping subnets to different address spaces: %v", err)
   234  	}
   235  
   236  	if pid0 == pid1 {
   237  		t.Fatalf("returned same pool id for same subnets in different namespaces")
   238  	}
   239  
   240  	pid, _, _, err := a.RequestPool("abc", "10.0.0.0/8", "", nil, false)
   241  	if err != nil {
   242  		t.Fatalf("Unexpected failure requesting existing subnet: %v", err)
   243  	}
   244  	if pid != pid1 {
   245  		t.Fatalf("returned different pool id for same subnet requests")
   246  	}
   247  
   248  	_, _, _, err = a.RequestPool("abc", "10.128.0.0/9", "", nil, false)
   249  	if err == nil {
   250  		t.Fatalf("Expected failure on adding overlapping base subnet")
   251  	}
   252  
   253  	pid2, _, _, err := a.RequestPool("abc", "10.0.0.0/8", "10.128.0.0/9", nil, false)
   254  	if err != nil {
   255  		t.Fatalf("Unexpected failure on adding sub pool: %v", err)
   256  	}
   257  	pid3, _, _, err := a.RequestPool("abc", "10.0.0.0/8", "10.128.0.0/9", nil, false)
   258  	if err != nil {
   259  		t.Fatalf("Unexpected failure on adding overlapping sub pool: %v", err)
   260  	}
   261  	if pid2 != pid3 {
   262  		t.Fatalf("returned different pool id for same sub pool requests")
   263  	}
   264  
   265  	pid, _, _, err = a.RequestPool(localAddressSpace, "10.20.2.0/24", "", nil, false)
   266  	if err == nil {
   267  		t.Fatalf("Failed to detect overlapping subnets")
   268  	}
   269  
   270  	_, _, _, err = a.RequestPool(localAddressSpace, "10.128.0.0/9", "", nil, false)
   271  	if err == nil {
   272  		t.Fatalf("Failed to detect overlapping subnets")
   273  	}
   274  
   275  	_, _, _, err = a.RequestPool(localAddressSpace, "1003:1:2:3:4:5:6::/112", "", nil, false)
   276  	if err != nil {
   277  		t.Fatalf("Failed to add v6 subnet: %s", err.Error())
   278  	}
   279  
   280  	_, _, _, err = a.RequestPool(localAddressSpace, "1003:1:2:3::/64", "", nil, false)
   281  	if err == nil {
   282  		t.Fatalf("Failed to detect overlapping v6 subnet")
   283  	}
   284  }
   285  
   286  func TestAddReleasePoolID(t *testing.T) {
   287  	var k0, k1, k2 SubnetKey
   288  
   289  	a, err := getAllocator()
   290  	if err != nil {
   291  		t.Fatal(err)
   292  	}
   293  
   294  	aSpace, err := a.getAddrSpace(localAddressSpace)
   295  	if err != nil {
   296  		t.Fatal(err)
   297  	}
   298  
   299  	subnets := aSpace.subnets
   300  	pid0, _, _, err := a.RequestPool(localAddressSpace, "10.0.0.0/8", "", nil, false)
   301  	if err != nil {
   302  		t.Fatalf("Unexpected failure in adding pool")
   303  	}
   304  	if err := k0.FromString(pid0); err != nil {
   305  		t.Fatal(err)
   306  	}
   307  
   308  	aSpace, err = a.getAddrSpace(localAddressSpace)
   309  	if err != nil {
   310  		t.Fatal(err)
   311  	}
   312  
   313  	subnets = aSpace.subnets
   314  
   315  	if subnets[k0].RefCount != 1 {
   316  		t.Fatalf("Unexpected ref count for %s: %d", k0, subnets[k0].RefCount)
   317  	}
   318  
   319  	pid1, _, _, err := a.RequestPool(localAddressSpace, "10.0.0.0/8", "10.0.0.0/16", nil, false)
   320  	if err != nil {
   321  		t.Fatalf("Unexpected failure in adding sub pool")
   322  	}
   323  	if err := k1.FromString(pid1); err != nil {
   324  		t.Fatal(err)
   325  	}
   326  
   327  	aSpace, err = a.getAddrSpace(localAddressSpace)
   328  	if err != nil {
   329  		t.Fatal(err)
   330  	}
   331  
   332  	subnets = aSpace.subnets
   333  	if subnets[k1].RefCount != 1 {
   334  		t.Fatalf("Unexpected ref count for %s: %d", k1, subnets[k1].RefCount)
   335  	}
   336  
   337  	pid2, _, _, err := a.RequestPool(localAddressSpace, "10.0.0.0/8", "10.0.0.0/16", nil, false)
   338  	if err != nil {
   339  		t.Fatalf("Unexpected failure in adding sub pool")
   340  	}
   341  	if pid0 == pid1 || pid0 == pid2 || pid1 != pid2 {
   342  		t.Fatalf("Incorrect poolIDs returned %s, %s, %s", pid0, pid1, pid2)
   343  	}
   344  	if err := k2.FromString(pid2); err != nil {
   345  		t.Fatal(err)
   346  	}
   347  
   348  	aSpace, err = a.getAddrSpace(localAddressSpace)
   349  	if err != nil {
   350  		t.Fatal(err)
   351  	}
   352  
   353  	subnets = aSpace.subnets
   354  	if subnets[k2].RefCount != 2 {
   355  		t.Fatalf("Unexpected ref count for %s: %d", k2, subnets[k2].RefCount)
   356  	}
   357  
   358  	if subnets[k0].RefCount != 3 {
   359  		t.Fatalf("Unexpected ref count for %s: %d", k0, subnets[k0].RefCount)
   360  	}
   361  
   362  	if err := a.ReleasePool(pid1); err != nil {
   363  		t.Fatal(err)
   364  	}
   365  
   366  	aSpace, err = a.getAddrSpace(localAddressSpace)
   367  	if err != nil {
   368  		t.Fatal(err)
   369  	}
   370  
   371  	subnets = aSpace.subnets
   372  	if subnets[k0].RefCount != 2 {
   373  		t.Fatalf("Unexpected ref count for %s: %d", k0, subnets[k0].RefCount)
   374  	}
   375  	if err := a.ReleasePool(pid0); err != nil {
   376  		t.Fatal(err)
   377  	}
   378  
   379  	aSpace, err = a.getAddrSpace(localAddressSpace)
   380  	if err != nil {
   381  		t.Fatal(err)
   382  	}
   383  
   384  	subnets = aSpace.subnets
   385  	if subnets[k0].RefCount != 1 {
   386  		t.Fatalf("Unexpected ref count for %s: %d", k0, subnets[k0].RefCount)
   387  	}
   388  
   389  	pid00, _, _, err := a.RequestPool(localAddressSpace, "10.0.0.0/8", "", nil, false)
   390  	if err != nil {
   391  		t.Fatalf("Unexpected failure in adding pool")
   392  	}
   393  	if pid00 != pid0 {
   394  		t.Fatalf("main pool should still exist")
   395  	}
   396  
   397  	aSpace, err = a.getAddrSpace(localAddressSpace)
   398  	if err != nil {
   399  		t.Fatal(err)
   400  	}
   401  
   402  	subnets = aSpace.subnets
   403  	if subnets[k0].RefCount != 2 {
   404  		t.Fatalf("Unexpected ref count for %s: %d", k0, subnets[k0].RefCount)
   405  	}
   406  
   407  	if err := a.ReleasePool(pid2); err != nil {
   408  		t.Fatal(err)
   409  	}
   410  
   411  	aSpace, err = a.getAddrSpace(localAddressSpace)
   412  	if err != nil {
   413  		t.Fatal(err)
   414  	}
   415  
   416  	subnets = aSpace.subnets
   417  	if subnets[k0].RefCount != 1 {
   418  		t.Fatalf("Unexpected ref count for %s: %d", k0, subnets[k0].RefCount)
   419  	}
   420  
   421  	if err := a.ReleasePool(pid00); err != nil {
   422  		t.Fatal(err)
   423  	}
   424  
   425  	aSpace, err = a.getAddrSpace(localAddressSpace)
   426  	if err != nil {
   427  		t.Fatal(err)
   428  	}
   429  
   430  	subnets = aSpace.subnets
   431  	if bp, ok := subnets[k0]; ok {
   432  		t.Fatalf("Base pool %s is still present: %v", k0, bp)
   433  	}
   434  
   435  	_, _, _, err = a.RequestPool(localAddressSpace, "10.0.0.0/8", "", nil, false)
   436  	if err != nil {
   437  		t.Fatalf("Unexpected failure in adding pool")
   438  	}
   439  
   440  	aSpace, err = a.getAddrSpace(localAddressSpace)
   441  	if err != nil {
   442  		t.Fatal(err)
   443  	}
   444  
   445  	subnets = aSpace.subnets
   446  	if subnets[k0].RefCount != 1 {
   447  		t.Fatalf("Unexpected ref count for %s: %d", k0, subnets[k0].RefCount)
   448  	}
   449  }
   450  
   451  func TestPredefinedPool(t *testing.T) {
   452  	a, err := getAllocator()
   453  	if err != nil {
   454  		t.Fatal(err)
   455  	}
   456  
   457  	if _, err := a.getPredefinedPool("blue", false); err == nil {
   458  		t.Fatalf("Expected failure for non default addr space")
   459  	}
   460  
   461  	pid, nw, _, err := a.RequestPool(localAddressSpace, "", "", nil, false)
   462  	if err != nil {
   463  		t.Fatal(err)
   464  	}
   465  
   466  	nw2, err := a.getPredefinedPool(localAddressSpace, false)
   467  	if err != nil {
   468  		t.Fatal(err)
   469  	}
   470  	if types.CompareIPNet(nw, nw2) {
   471  		t.Fatalf("Unexpected default network returned: %s = %s", nw2, nw)
   472  	}
   473  
   474  	if err := a.ReleasePool(pid); err != nil {
   475  		t.Fatal(err)
   476  	}
   477  }
   478  
   479  func TestRemoveSubnet(t *testing.T) {
   480  	a, err := getAllocator()
   481  	if err != nil {
   482  		t.Fatal(err)
   483  	}
   484  	a.addrSpaces["splane"] = &addrSpace{
   485  		id:      dsConfigKey + "/" + "splane",
   486  		ds:      a.addrSpaces[localAddressSpace].ds,
   487  		alloc:   a.addrSpaces[localAddressSpace].alloc,
   488  		scope:   a.addrSpaces[localAddressSpace].scope,
   489  		subnets: map[SubnetKey]*PoolData{},
   490  	}
   491  
   492  	input := []struct {
   493  		addrSpace string
   494  		subnet    string
   495  		v6        bool
   496  	}{
   497  		{localAddressSpace, "192.168.0.0/16", false},
   498  		{localAddressSpace, "172.17.0.0/16", false},
   499  		{localAddressSpace, "10.0.0.0/8", false},
   500  		{localAddressSpace, "2001:db8:1:2:3:4:ffff::/112", false},
   501  		{"splane", "172.17.0.0/16", false},
   502  		{"splane", "10.0.0.0/8", false},
   503  		{"splane", "2001:db8:1:2:3:4:5::/112", true},
   504  		{"splane", "2001:db8:1:2:3:4:ffff::/112", true},
   505  	}
   506  
   507  	poolIDs := make([]string, len(input))
   508  
   509  	for ind, i := range input {
   510  		if poolIDs[ind], _, _, err = a.RequestPool(i.addrSpace, i.subnet, "", nil, i.v6); err != nil {
   511  			t.Fatalf("Failed to apply input. Can't proceed: %s", err.Error())
   512  		}
   513  	}
   514  
   515  	for ind, id := range poolIDs {
   516  		if err := a.ReleasePool(id); err != nil {
   517  			t.Fatalf("Failed to release poolID %s (%d)", id, ind)
   518  		}
   519  	}
   520  }
   521  
   522  func TestGetSameAddress(t *testing.T) {
   523  	a, err := getAllocator()
   524  	if err != nil {
   525  		t.Fatal(err)
   526  	}
   527  	a.addrSpaces["giallo"] = &addrSpace{
   528  		id:      dsConfigKey + "/" + "giallo",
   529  		ds:      a.addrSpaces[localAddressSpace].ds,
   530  		alloc:   a.addrSpaces[localAddressSpace].alloc,
   531  		scope:   a.addrSpaces[localAddressSpace].scope,
   532  		subnets: map[SubnetKey]*PoolData{},
   533  	}
   534  
   535  	pid, _, _, err := a.RequestPool("giallo", "192.168.100.0/24", "", nil, false)
   536  	if err != nil {
   537  		t.Fatal(err)
   538  	}
   539  
   540  	ip := net.ParseIP("192.168.100.250")
   541  	_, _, err = a.RequestAddress(pid, ip, nil)
   542  	if err != nil {
   543  		t.Fatal(err)
   544  	}
   545  
   546  	_, _, err = a.RequestAddress(pid, ip, nil)
   547  	if err == nil {
   548  		t.Fatal(err)
   549  	}
   550  }
   551  
   552  func TestGetAddressSubPoolEqualPool(t *testing.T) {
   553  	a, err := getAllocator()
   554  	if err != nil {
   555  		t.Fatal(err)
   556  	}
   557  	// Requesting a subpool of same size of the master pool should not cause any problem on ip allocation
   558  	pid, _, _, err := a.RequestPool(localAddressSpace, "172.18.0.0/16", "172.18.0.0/16", nil, false)
   559  	if err != nil {
   560  		t.Fatal(err)
   561  	}
   562  
   563  	_, _, err = a.RequestAddress(pid, nil, nil)
   564  	if err != nil {
   565  		t.Fatal(err)
   566  	}
   567  }
   568  
   569  func TestRequestReleaseAddressFromSubPool(t *testing.T) {
   570  	a, err := getAllocator()
   571  	if err != nil {
   572  		t.Fatal(err)
   573  	}
   574  	a.addrSpaces["rosso"] = &addrSpace{
   575  		id:      dsConfigKey + "/" + "rosso",
   576  		ds:      a.addrSpaces[localAddressSpace].ds,
   577  		alloc:   a.addrSpaces[localAddressSpace].alloc,
   578  		scope:   a.addrSpaces[localAddressSpace].scope,
   579  		subnets: map[SubnetKey]*PoolData{},
   580  	}
   581  
   582  	poolID, _, _, err := a.RequestPool("rosso", "172.28.0.0/16", "172.28.30.0/24", nil, false)
   583  	if err != nil {
   584  		t.Fatal(err)
   585  	}
   586  
   587  	var ip *net.IPNet
   588  	expected := &net.IPNet{IP: net.IP{172, 28, 30, 255}, Mask: net.IPMask{255, 255, 0, 0}}
   589  	for err == nil {
   590  		var c *net.IPNet
   591  		if c, _, err = a.RequestAddress(poolID, nil, nil); err == nil {
   592  			ip = c
   593  		}
   594  	}
   595  	if err != ipamapi.ErrNoAvailableIPs {
   596  		t.Fatal(err)
   597  	}
   598  	if !types.CompareIPNet(expected, ip) {
   599  		t.Fatalf("Unexpected last IP from subpool. Expected: %s. Got: %v.", expected, ip)
   600  	}
   601  	rp := &net.IPNet{IP: net.IP{172, 28, 30, 97}, Mask: net.IPMask{255, 255, 0, 0}}
   602  	if err = a.ReleaseAddress(poolID, rp.IP); err != nil {
   603  		t.Fatal(err)
   604  	}
   605  	if ip, _, err = a.RequestAddress(poolID, nil, nil); err != nil {
   606  		t.Fatal(err)
   607  	}
   608  	if !types.CompareIPNet(rp, ip) {
   609  		t.Fatalf("Unexpected IP from subpool. Expected: %s. Got: %v.", rp, ip)
   610  	}
   611  
   612  	_, _, _, err = a.RequestPool("rosso", "10.0.0.0/8", "10.0.0.0/16", nil, false)
   613  	if err != nil {
   614  		t.Fatal(err)
   615  	}
   616  	poolID, _, _, err = a.RequestPool("rosso", "10.0.0.0/16", "10.0.0.0/24", nil, false)
   617  	if err != nil {
   618  		t.Fatal(err)
   619  	}
   620  	expected = &net.IPNet{IP: net.IP{10, 0, 0, 255}, Mask: net.IPMask{255, 255, 0, 0}}
   621  	for err == nil {
   622  		var c *net.IPNet
   623  		if c, _, err = a.RequestAddress(poolID, nil, nil); err == nil {
   624  			ip = c
   625  		}
   626  	}
   627  	if err != ipamapi.ErrNoAvailableIPs {
   628  		t.Fatal(err)
   629  	}
   630  	if !types.CompareIPNet(expected, ip) {
   631  		t.Fatalf("Unexpected last IP from subpool. Expected: %s. Got: %v.", expected, ip)
   632  	}
   633  	rp = &net.IPNet{IP: net.IP{10, 0, 0, 79}, Mask: net.IPMask{255, 255, 0, 0}}
   634  	if err = a.ReleaseAddress(poolID, rp.IP); err != nil {
   635  		t.Fatal(err)
   636  	}
   637  	if ip, _, err = a.RequestAddress(poolID, nil, nil); err != nil {
   638  		t.Fatal(err)
   639  	}
   640  	if !types.CompareIPNet(rp, ip) {
   641  		t.Fatalf("Unexpected IP from subpool. Expected: %s. Got: %v.", rp, ip)
   642  	}
   643  
   644  	// Request any addresses from subpool after explicit address request
   645  	unoExp, _ := types.ParseCIDR("10.2.2.0/16")
   646  	dueExp, _ := types.ParseCIDR("10.2.2.2/16")
   647  	treExp, _ := types.ParseCIDR("10.2.2.1/16")
   648  	if poolID, _, _, err = a.RequestPool("rosso", "10.2.0.0/16", "10.2.2.0/24", nil, false); err != nil {
   649  		t.Fatal(err)
   650  	}
   651  	tre, _, err := a.RequestAddress(poolID, treExp.IP, nil)
   652  	if err != nil {
   653  		t.Fatal(err)
   654  	}
   655  	if !types.CompareIPNet(tre, treExp) {
   656  		t.Fatalf("Unexpected address: %v", tre)
   657  	}
   658  
   659  	uno, _, err := a.RequestAddress(poolID, nil, nil)
   660  	if err != nil {
   661  		t.Fatal(err)
   662  	}
   663  	if !types.CompareIPNet(uno, unoExp) {
   664  		t.Fatalf("Unexpected address: %v", uno)
   665  	}
   666  
   667  	due, _, err := a.RequestAddress(poolID, nil, nil)
   668  	if err != nil {
   669  		t.Fatal(err)
   670  	}
   671  	if !types.CompareIPNet(due, dueExp) {
   672  		t.Fatalf("Unexpected address: %v", due)
   673  	}
   674  
   675  	if err = a.ReleaseAddress(poolID, uno.IP); err != nil {
   676  		t.Fatal(err)
   677  	}
   678  	uno, _, err = a.RequestAddress(poolID, nil, nil)
   679  	if err != nil {
   680  		t.Fatal(err)
   681  	}
   682  	if !types.CompareIPNet(uno, unoExp) {
   683  		t.Fatalf("Unexpected address: %v", uno)
   684  	}
   685  
   686  	if err = a.ReleaseAddress(poolID, tre.IP); err != nil {
   687  		t.Fatal(err)
   688  	}
   689  	tre, _, err = a.RequestAddress(poolID, nil, nil)
   690  	if err != nil {
   691  		t.Fatal(err)
   692  	}
   693  	if !types.CompareIPNet(tre, treExp) {
   694  		t.Fatalf("Unexpected address: %v", tre)
   695  	}
   696  }
   697  
   698  func TestGetAddress(t *testing.T) {
   699  	input := []string{
   700  		/*"10.0.0.0/8", "10.0.0.0/9", "10.0.0.0/10",*/ "10.0.0.0/11", "10.0.0.0/12", "10.0.0.0/13", "10.0.0.0/14",
   701  		"10.0.0.0/15", "10.0.0.0/16", "10.0.0.0/17", "10.0.0.0/18", "10.0.0.0/19", "10.0.0.0/20", "10.0.0.0/21",
   702  		"10.0.0.0/22", "10.0.0.0/23", "10.0.0.0/24", "10.0.0.0/25", "10.0.0.0/26", "10.0.0.0/27", "10.0.0.0/28",
   703  		"10.0.0.0/29", "10.0.0.0/30", "10.0.0.0/31"}
   704  
   705  	for _, subnet := range input {
   706  		assertGetAddress(t, subnet)
   707  	}
   708  }
   709  
   710  func TestRequestSyntaxCheck(t *testing.T) {
   711  	var (
   712  		pool    = "192.168.0.0/16"
   713  		subPool = "192.168.0.0/24"
   714  		as      = "green"
   715  		err     error
   716  	)
   717  
   718  	a, err := getAllocator()
   719  	if err != nil {
   720  		t.Fatal(err)
   721  	}
   722  	a.addrSpaces[as] = &addrSpace{
   723  		id:      dsConfigKey + "/" + as,
   724  		ds:      a.addrSpaces[localAddressSpace].ds,
   725  		alloc:   a.addrSpaces[localAddressSpace].alloc,
   726  		scope:   a.addrSpaces[localAddressSpace].scope,
   727  		subnets: map[SubnetKey]*PoolData{},
   728  	}
   729  
   730  	_, _, _, err = a.RequestPool("", pool, "", nil, false)
   731  	if err == nil {
   732  		t.Fatalf("Failed to detect wrong request: empty address space")
   733  	}
   734  
   735  	_, _, _, err = a.RequestPool("", pool, subPool, nil, false)
   736  	if err == nil {
   737  		t.Fatalf("Failed to detect wrong request: empty address space")
   738  	}
   739  
   740  	_, _, _, err = a.RequestPool(as, "", subPool, nil, false)
   741  	if err == nil {
   742  		t.Fatalf("Failed to detect wrong request: subPool specified and no pool")
   743  	}
   744  
   745  	pid, _, _, err := a.RequestPool(as, pool, subPool, nil, false)
   746  	if err != nil {
   747  		t.Fatalf("Unexpected failure: %v", err)
   748  	}
   749  
   750  	_, _, err = a.RequestAddress("", nil, nil)
   751  	if err == nil {
   752  		t.Fatalf("Failed to detect wrong request: no pool id specified")
   753  	}
   754  
   755  	ip := net.ParseIP("172.17.0.23")
   756  	_, _, err = a.RequestAddress(pid, ip, nil)
   757  	if err == nil {
   758  		t.Fatalf("Failed to detect wrong request: requested IP from different subnet")
   759  	}
   760  
   761  	ip = net.ParseIP("192.168.0.50")
   762  	_, _, err = a.RequestAddress(pid, ip, nil)
   763  	if err != nil {
   764  		t.Fatalf("Unexpected failure: %v", err)
   765  	}
   766  
   767  	err = a.ReleaseAddress("", ip)
   768  	if err == nil {
   769  		t.Fatalf("Failed to detect wrong request: no pool id specified")
   770  	}
   771  
   772  	err = a.ReleaseAddress(pid, nil)
   773  	if err == nil {
   774  		t.Fatalf("Failed to detect wrong request: no pool id specified")
   775  	}
   776  
   777  	err = a.ReleaseAddress(pid, ip)
   778  	if err != nil {
   779  		t.Fatalf("Unexpected failure: %v: %s, %s", err, pid, ip)
   780  	}
   781  }
   782  
   783  func TestRequest(t *testing.T) {
   784  	// Request N addresses from different size subnets, verifying last request
   785  	// returns expected address. Internal subnet host size is Allocator's default, 16
   786  	input := []struct {
   787  		subnet string
   788  		numReq int
   789  		lastIP string
   790  	}{
   791  		{"192.168.59.0/24", 254, "192.168.59.254"},
   792  		{"192.168.240.0/20", 255, "192.168.240.255"},
   793  		{"192.168.0.0/16", 255, "192.168.0.255"},
   794  		{"192.168.0.0/16", 256, "192.168.1.0"},
   795  		{"10.16.0.0/16", 255, "10.16.0.255"},
   796  		{"10.128.0.0/12", 255, "10.128.0.255"},
   797  		{"10.0.0.0/8", 256, "10.0.1.0"},
   798  
   799  		{"192.168.128.0/18", 4*256 - 1, "192.168.131.255"},
   800  		/*
   801  			{"192.168.240.0/20", 16*256 - 2, "192.168.255.254"},
   802  
   803  			{"192.168.0.0/16", 256*256 - 2, "192.168.255.254"},
   804  			{"10.0.0.0/8", 2 * 256, "10.0.2.0"},
   805  			{"10.0.0.0/8", 5 * 256, "10.0.5.0"},
   806  			{"10.0.0.0/8", 100 * 256 * 254, "10.99.255.254"},
   807  		*/
   808  	}
   809  
   810  	for _, d := range input {
   811  		assertNRequests(t, d.subnet, d.numReq, d.lastIP)
   812  	}
   813  }
   814  
   815  func TestRelease(t *testing.T) {
   816  	var (
   817  		subnet = "192.168.0.0/23"
   818  	)
   819  
   820  	a, err := getAllocator()
   821  	if err != nil {
   822  		t.Fatal(err)
   823  	}
   824  	pid, _, _, err := a.RequestPool(localAddressSpace, subnet, "", nil, false)
   825  	if err != nil {
   826  		t.Fatal(err)
   827  	}
   828  
   829  	bm := a.addresses[SubnetKey{localAddressSpace, subnet, ""}]
   830  
   831  	// Allocate all addresses
   832  	for err != ipamapi.ErrNoAvailableIPs {
   833  		_, _, err = a.RequestAddress(pid, nil, nil)
   834  	}
   835  
   836  	toRelease := []struct {
   837  		address string
   838  	}{
   839  		{"192.168.0.1"},
   840  		{"192.168.0.2"},
   841  		{"192.168.0.3"},
   842  		{"192.168.0.4"},
   843  		{"192.168.0.5"},
   844  		{"192.168.0.6"},
   845  		{"192.168.0.7"},
   846  		{"192.168.0.8"},
   847  		{"192.168.0.9"},
   848  		{"192.168.0.10"},
   849  		{"192.168.0.30"},
   850  		{"192.168.0.31"},
   851  		{"192.168.1.32"},
   852  
   853  		{"192.168.0.254"},
   854  		{"192.168.1.1"},
   855  		{"192.168.1.2"},
   856  
   857  		{"192.168.1.3"},
   858  
   859  		{"192.168.1.253"},
   860  		{"192.168.1.254"},
   861  	}
   862  
   863  	// One by one, relase the address and request again. We should get the same IP
   864  	for i, inp := range toRelease {
   865  		ip0 := net.ParseIP(inp.address)
   866  		a.ReleaseAddress(pid, ip0)
   867  		bm = a.addresses[SubnetKey{localAddressSpace, subnet, ""}]
   868  		if bm.Unselected() != 1 {
   869  			t.Fatalf("Failed to update free address count after release. Expected %d, Found: %d", i+1, bm.Unselected())
   870  		}
   871  
   872  		nw, _, err := a.RequestAddress(pid, nil, nil)
   873  		if err != nil {
   874  			t.Fatalf("Failed to obtain the address: %s", err.Error())
   875  		}
   876  		ip := nw.IP
   877  		if !ip0.Equal(ip) {
   878  			t.Fatalf("Failed to obtain the same address. Expected: %s, Got: %s", ip0, ip)
   879  		}
   880  	}
   881  }
   882  
   883  func assertGetAddress(t *testing.T, subnet string) {
   884  	var (
   885  		err       error
   886  		printTime = false
   887  		a         = &Allocator{}
   888  	)
   889  
   890  	_, sub, _ := net.ParseCIDR(subnet)
   891  	ones, bits := sub.Mask.Size()
   892  	zeroes := bits - ones
   893  	numAddresses := 1 << uint(zeroes)
   894  
   895  	bm, err := bitseq.NewHandle("ipam_test", nil, "default/"+subnet, uint64(numAddresses))
   896  	if err != nil {
   897  		t.Fatal(err)
   898  	}
   899  
   900  	start := time.Now()
   901  	run := 0
   902  	for err != ipamapi.ErrNoAvailableIPs {
   903  		_, err = a.getAddress(sub, bm, nil, nil)
   904  		run++
   905  	}
   906  	if printTime {
   907  		fmt.Printf("\nTaken %v, to allocate all addresses on %s. (nemAddresses: %d. Runs: %d)", time.Since(start), subnet, numAddresses, run)
   908  	}
   909  	if bm.Unselected() != 0 {
   910  		t.Fatalf("Unexpected free count after reserving all addresses: %d", bm.Unselected())
   911  	}
   912  	/*
   913  		if bm.Head.Block != expectedMax || bm.Head.Count != numBlocks {
   914  			t.Fatalf("Failed to effectively reserve all addresses on %s. Expected (0x%x, %d) as first sequence. Found (0x%x,%d)",
   915  				subnet, expectedMax, numBlocks, bm.Head.Block, bm.Head.Count)
   916  		}
   917  	*/
   918  }
   919  
   920  func assertNRequests(t *testing.T, subnet string, numReq int, lastExpectedIP string) {
   921  	var (
   922  		nw        *net.IPNet
   923  		printTime = false
   924  	)
   925  
   926  	lastIP := net.ParseIP(lastExpectedIP)
   927  	a, err := getAllocator()
   928  	if err != nil {
   929  		t.Fatal(err)
   930  	}
   931  	pid, _, _, err := a.RequestPool(localAddressSpace, subnet, "", nil, false)
   932  	if err != nil {
   933  		t.Fatal(err)
   934  	}
   935  
   936  	i := 0
   937  	start := time.Now()
   938  	for ; i < numReq; i++ {
   939  		nw, _, err = a.RequestAddress(pid, nil, nil)
   940  	}
   941  	if printTime {
   942  		fmt.Printf("\nTaken %v, to allocate %d addresses on %s\n", time.Since(start), numReq, subnet)
   943  	}
   944  
   945  	if !lastIP.Equal(nw.IP) {
   946  		t.Fatalf("Wrong last IP. Expected %s. Got: %s (err: %v, ind: %d)", lastExpectedIP, nw.IP.String(), err, i)
   947  	}
   948  }
   949  
   950  func benchmarkRequest(b *testing.B, a *Allocator, subnet string) {
   951  	pid, _, _, err := a.RequestPool(localAddressSpace, subnet, "", nil, false)
   952  	for err != ipamapi.ErrNoAvailableIPs {
   953  		_, _, err = a.RequestAddress(pid, nil, nil)
   954  	}
   955  }
   956  
   957  func benchMarkRequest(subnet string, b *testing.B) {
   958  	a, _ := getAllocator()
   959  	for n := 0; n < b.N; n++ {
   960  		benchmarkRequest(b, a, subnet)
   961  	}
   962  }
   963  
   964  func BenchmarkRequest_24(b *testing.B) {
   965  	a, _ := getAllocator()
   966  	benchmarkRequest(b, a, "10.0.0.0/24")
   967  }
   968  
   969  func BenchmarkRequest_16(b *testing.B) {
   970  	a, _ := getAllocator()
   971  	benchmarkRequest(b, a, "10.0.0.0/16")
   972  }
   973  
   974  func BenchmarkRequest_8(b *testing.B) {
   975  	a, _ := getAllocator()
   976  	benchmarkRequest(b, a, "10.0.0.0/8")
   977  }
   978  
   979  func TestAllocateRandomDeallocate(t *testing.T) {
   980  	testAllocateRandomDeallocate(t, "172.25.0.0/16", "", 384)
   981  	testAllocateRandomDeallocate(t, "172.25.0.0/16", "172.25.252.0/22", 384)
   982  }
   983  
   984  func testAllocateRandomDeallocate(t *testing.T, pool, subPool string, num int) {
   985  	ds, err := randomLocalStore()
   986  	if err != nil {
   987  		t.Fatal(err)
   988  	}
   989  
   990  	a, err := NewAllocator(ds, nil)
   991  	if err != nil {
   992  		t.Fatal(err)
   993  	}
   994  
   995  	pid, _, _, err := a.RequestPool(localAddressSpace, pool, subPool, nil, false)
   996  	if err != nil {
   997  		t.Fatal(err)
   998  	}
   999  
  1000  	// Allocate num ip addresses
  1001  	indices := make(map[int]*net.IPNet, num)
  1002  	allocated := make(map[string]bool, num)
  1003  	for i := 0; i < num; i++ {
  1004  		ip, _, err := a.RequestAddress(pid, nil, nil)
  1005  		if err != nil {
  1006  			t.Fatal(err)
  1007  		}
  1008  		ips := ip.String()
  1009  		if _, ok := allocated[ips]; ok {
  1010  			t.Fatalf("Address %s is already allocated", ips)
  1011  		}
  1012  		allocated[ips] = true
  1013  		indices[i] = ip
  1014  	}
  1015  	if len(indices) != len(allocated) || len(indices) != num {
  1016  		t.Fatalf("Unexpected number of allocated addresses: (%d,%d).", len(indices), len(allocated))
  1017  	}
  1018  
  1019  	seed := time.Now().Unix()
  1020  	rand.Seed(seed)
  1021  
  1022  	// Deallocate half of the allocated addresses following a random pattern
  1023  	pattern := rand.Perm(num)
  1024  	for i := 0; i < num/2; i++ {
  1025  		idx := pattern[i]
  1026  		ip := indices[idx]
  1027  		err := a.ReleaseAddress(pid, ip.IP)
  1028  		if err != nil {
  1029  			t.Fatalf("Unexpected failure on deallocation of %s: %v.\nSeed: %d.", ip, err, seed)
  1030  		}
  1031  		delete(indices, idx)
  1032  		delete(allocated, ip.String())
  1033  	}
  1034  
  1035  	// Request a quarter of addresses
  1036  	for i := 0; i < num/2; i++ {
  1037  		ip, _, err := a.RequestAddress(pid, nil, nil)
  1038  		if err != nil {
  1039  			t.Fatal(err)
  1040  		}
  1041  		ips := ip.String()
  1042  		if _, ok := allocated[ips]; ok {
  1043  			t.Fatalf("\nAddress %s is already allocated.\nSeed: %d.", ips, seed)
  1044  		}
  1045  		allocated[ips] = true
  1046  	}
  1047  	if len(allocated) != num {
  1048  		t.Fatalf("Unexpected number of allocated addresses: %d.\nSeed: %d.", len(allocated), seed)
  1049  	}
  1050  }
  1051  
  1052  func TestRetrieveFromStore(t *testing.T) {
  1053  	num := 200
  1054  	ds, err := randomLocalStore()
  1055  	if err != nil {
  1056  		t.Fatal(err)
  1057  	}
  1058  	a, err := NewAllocator(ds, nil)
  1059  	if err != nil {
  1060  		t.Fatal(err)
  1061  	}
  1062  	pid, _, _, err := a.RequestPool(localAddressSpace, "172.25.0.0/16", "", nil, false)
  1063  	if err != nil {
  1064  		t.Fatal(err)
  1065  	}
  1066  	for i := 0; i < num; i++ {
  1067  		if _, _, err := a.RequestAddress(pid, nil, nil); err != nil {
  1068  			t.Fatal(err)
  1069  		}
  1070  	}
  1071  
  1072  	// Restore
  1073  	a1, err := NewAllocator(ds, nil)
  1074  	if err != nil {
  1075  		t.Fatal(err)
  1076  	}
  1077  	a1.refresh(localAddressSpace)
  1078  	db := a.DumpDatabase()
  1079  	db1 := a1.DumpDatabase()
  1080  	if db != db1 {
  1081  		t.Fatalf("Unexpected db change.\nExpected:%s\nGot:%s", db, db1)
  1082  	}
  1083  	checkDBEquality(a, a1, t)
  1084  	pid, _, _, err = a1.RequestPool(localAddressSpace, "172.25.0.0/16", "172.25.1.0/24", nil, false)
  1085  	if err != nil {
  1086  		t.Fatal(err)
  1087  	}
  1088  	for i := 0; i < num/2; i++ {
  1089  		if _, _, err := a1.RequestAddress(pid, nil, nil); err != nil {
  1090  			t.Fatal(err)
  1091  		}
  1092  	}
  1093  
  1094  	// Restore
  1095  	a2, err := NewAllocator(ds, nil)
  1096  	if err != nil {
  1097  		t.Fatal(err)
  1098  	}
  1099  	a2.refresh(localAddressSpace)
  1100  	checkDBEquality(a1, a2, t)
  1101  	pid, _, _, err = a2.RequestPool(localAddressSpace, "172.25.0.0/16", "172.25.2.0/24", nil, false)
  1102  	if err != nil {
  1103  		t.Fatal(err)
  1104  	}
  1105  	for i := 0; i < num/2; i++ {
  1106  		if _, _, err := a2.RequestAddress(pid, nil, nil); err != nil {
  1107  			t.Fatal(err)
  1108  		}
  1109  	}
  1110  
  1111  	// Restore
  1112  	a3, err := NewAllocator(ds, nil)
  1113  	if err != nil {
  1114  		t.Fatal(err)
  1115  	}
  1116  	a3.refresh(localAddressSpace)
  1117  	checkDBEquality(a2, a3, t)
  1118  	pid, _, _, err = a3.RequestPool(localAddressSpace, "172.26.0.0/16", "", nil, false)
  1119  	if err != nil {
  1120  		t.Fatal(err)
  1121  	}
  1122  	for i := 0; i < num/2; i++ {
  1123  		if _, _, err := a3.RequestAddress(pid, nil, nil); err != nil {
  1124  			t.Fatal(err)
  1125  		}
  1126  	}
  1127  
  1128  	// Restore
  1129  	a4, err := NewAllocator(ds, nil)
  1130  	if err != nil {
  1131  		t.Fatal(err)
  1132  	}
  1133  	a4.refresh(localAddressSpace)
  1134  	checkDBEquality(a3, a4, t)
  1135  }
  1136  
  1137  func checkDBEquality(a1, a2 *Allocator, t *testing.T) {
  1138  	for k, cnf1 := range a1.addrSpaces[localAddressSpace].subnets {
  1139  		cnf2 := a2.addrSpaces[localAddressSpace].subnets[k]
  1140  		if cnf1.String() != cnf2.String() {
  1141  			t.Fatalf("%s\n%s", cnf1, cnf2)
  1142  		}
  1143  		if cnf1.Range == nil {
  1144  			a2.retrieveBitmask(k, cnf1.Pool)
  1145  		}
  1146  	}
  1147  
  1148  	for k, bm1 := range a1.addresses {
  1149  		bm2 := a2.addresses[k]
  1150  		if bm1.String() != bm2.String() {
  1151  			t.Fatalf("%s\n%s", bm1, bm2)
  1152  		}
  1153  	}
  1154  }
  1155  
  1156  const (
  1157  	numInstances = 5
  1158  	first        = 0
  1159  	last         = numInstances - 1
  1160  )
  1161  
  1162  var (
  1163  	allocator *Allocator
  1164  	start     = make(chan struct{})
  1165  	done      = make(chan chan struct{}, numInstances-1)
  1166  	pools     = make([]*net.IPNet, numInstances)
  1167  )
  1168  
  1169  func runParallelTests(t *testing.T, instance int) {
  1170  	var err error
  1171  
  1172  	t.Parallel()
  1173  
  1174  	pTest := flag.Lookup("test.parallel")
  1175  	if pTest == nil {
  1176  		t.Skip("Skipped because test.parallel flag not set;")
  1177  	}
  1178  	numParallel, err := strconv.Atoi(pTest.Value.String())
  1179  	if err != nil {
  1180  		t.Fatal(err)
  1181  	}
  1182  	if numParallel < numInstances {
  1183  		t.Skip("Skipped because t.parallel was less than ", numInstances)
  1184  	}
  1185  
  1186  	// The first instance creates the allocator, gives the start
  1187  	// and finally checks the pools each instance was assigned
  1188  	if instance == first {
  1189  		allocator, err = getAllocator()
  1190  		if err != nil {
  1191  			t.Fatal(err)
  1192  		}
  1193  		close(start)
  1194  	}
  1195  
  1196  	if instance != first {
  1197  		select {
  1198  		case <-start:
  1199  		}
  1200  
  1201  		instDone := make(chan struct{})
  1202  		done <- instDone
  1203  		defer close(instDone)
  1204  
  1205  		if instance == last {
  1206  			defer close(done)
  1207  		}
  1208  	}
  1209  
  1210  	_, pools[instance], _, err = allocator.RequestPool(localAddressSpace, "", "", nil, false)
  1211  	if err != nil {
  1212  		t.Fatal(err)
  1213  	}
  1214  
  1215  	if instance == first {
  1216  		for instDone := range done {
  1217  			select {
  1218  			case <-instDone:
  1219  			}
  1220  		}
  1221  		// Now check each instance got a different pool
  1222  		for i := 0; i < numInstances; i++ {
  1223  			for j := i + 1; j < numInstances; j++ {
  1224  				if types.CompareIPNet(pools[i], pools[j]) {
  1225  					t.Fatalf("Instance %d and %d were given the same predefined pool: %v", i, j, pools)
  1226  				}
  1227  			}
  1228  		}
  1229  	}
  1230  }
  1231  
  1232  func TestParallelPredefinedRequest1(t *testing.T) {
  1233  	runParallelTests(t, 0)
  1234  }
  1235  
  1236  func TestParallelPredefinedRequest2(t *testing.T) {
  1237  	runParallelTests(t, 1)
  1238  }
  1239  
  1240  func TestParallelPredefinedRequest3(t *testing.T) {
  1241  	runParallelTests(t, 2)
  1242  }
  1243  
  1244  func TestParallelPredefinedRequest4(t *testing.T) {
  1245  	runParallelTests(t, 3)
  1246  }
  1247  
  1248  func TestParallelPredefinedRequest5(t *testing.T) {
  1249  	runParallelTests(t, 4)
  1250  }