github.com/docker/engine@v22.0.0-20211208180946-d456264580cf+incompatible/libnetwork/libnetwork_test.go (about)

     1  //go:build linux
     2  // +build linux
     3  
     4  package libnetwork_test
     5  
     6  import (
     7  	"errors"
     8  	"fmt"
     9  	"net"
    10  	"net/http"
    11  	"net/http/httptest"
    12  	"os"
    13  	"path/filepath"
    14  	"runtime"
    15  	"testing"
    16  
    17  	"github.com/docker/docker/libnetwork"
    18  	"github.com/docker/docker/libnetwork/config"
    19  	"github.com/docker/docker/libnetwork/datastore"
    20  	"github.com/docker/docker/libnetwork/driverapi"
    21  	"github.com/docker/docker/libnetwork/ipamapi"
    22  	"github.com/docker/docker/libnetwork/netlabel"
    23  	"github.com/docker/docker/libnetwork/options"
    24  	"github.com/docker/docker/libnetwork/testutils"
    25  	"github.com/docker/docker/libnetwork/types"
    26  	"github.com/docker/docker/pkg/plugins"
    27  	"github.com/docker/docker/pkg/reexec"
    28  	"github.com/sirupsen/logrus"
    29  )
    30  
    31  var controller libnetwork.NetworkController
    32  
    33  func TestMain(m *testing.M) {
    34  	if runtime.GOOS == "windows" {
    35  		logrus.Info("Test suite does not currently support windows")
    36  		os.Exit(0)
    37  	}
    38  	if reexec.Init() {
    39  		return
    40  	}
    41  
    42  	if err := createController(); err != nil {
    43  		logrus.Errorf("Error creating controller: %v", err)
    44  		os.Exit(1)
    45  	}
    46  
    47  	x := m.Run()
    48  	controller.Stop()
    49  	os.Exit(x)
    50  }
    51  
    52  func createController() error {
    53  	var err error
    54  
    55  	// Cleanup local datastore file
    56  	os.Remove(datastore.DefaultScopes("")[datastore.LocalScope].Client.Address)
    57  
    58  	option := options.Generic{
    59  		"EnableIPForwarding": true,
    60  	}
    61  
    62  	genericOption := make(map[string]interface{})
    63  	genericOption[netlabel.GenericData] = option
    64  
    65  	cfgOptions, err := libnetwork.OptionBoltdbWithRandomDBFile()
    66  	if err != nil {
    67  		return err
    68  	}
    69  	controller, err = libnetwork.New(append(cfgOptions, config.OptionDriverConfig(bridgeNetType, genericOption))...)
    70  	return err
    71  }
    72  
    73  func createTestNetwork(networkType, networkName string, netOption options.Generic, ipamV4Configs, ipamV6Configs []*libnetwork.IpamConf) (libnetwork.Network, error) {
    74  	return controller.NewNetwork(networkType, networkName, "",
    75  		libnetwork.NetworkOptionGeneric(netOption),
    76  		libnetwork.NetworkOptionIpam(ipamapi.DefaultIPAM, "", ipamV4Configs, ipamV6Configs, nil))
    77  }
    78  
    79  func getEmptyGenericOption() map[string]interface{} {
    80  	genericOption := make(map[string]interface{})
    81  	genericOption[netlabel.GenericData] = map[string]string{}
    82  	return genericOption
    83  }
    84  
    85  func getPortMapping() []types.PortBinding {
    86  	return []types.PortBinding{
    87  		{Proto: types.TCP, Port: uint16(230), HostPort: uint16(23000)},
    88  		{Proto: types.UDP, Port: uint16(200), HostPort: uint16(22000)},
    89  		{Proto: types.TCP, Port: uint16(120), HostPort: uint16(12000)},
    90  		{Proto: types.TCP, Port: uint16(320), HostPort: uint16(32000), HostPortEnd: uint16(32999)},
    91  		{Proto: types.UDP, Port: uint16(420), HostPort: uint16(42000), HostPortEnd: uint16(42001)},
    92  	}
    93  }
    94  
    95  func isNotFound(err error) bool {
    96  	_, ok := (err).(types.NotFoundError)
    97  	return ok
    98  }
    99  
   100  func TestNull(t *testing.T) {
   101  	cnt, err := controller.NewSandbox("null_container",
   102  		libnetwork.OptionHostname("test"),
   103  		libnetwork.OptionDomainname("docker.io"),
   104  		libnetwork.OptionExtraHost("web", "192.168.0.1"))
   105  	if err != nil {
   106  		t.Fatal(err)
   107  	}
   108  
   109  	network, err := createTestNetwork("null", "testnull", options.Generic{}, nil, nil)
   110  	if err != nil {
   111  		t.Fatal(err)
   112  	}
   113  
   114  	ep, err := network.CreateEndpoint("testep")
   115  	if err != nil {
   116  		t.Fatal(err)
   117  	}
   118  
   119  	err = ep.Join(cnt)
   120  	if err != nil {
   121  		t.Fatal(err)
   122  	}
   123  
   124  	err = ep.Leave(cnt)
   125  	if err != nil {
   126  		t.Fatal(err)
   127  	}
   128  
   129  	if err := ep.Delete(false); err != nil {
   130  		t.Fatal(err)
   131  	}
   132  
   133  	if err := cnt.Delete(); err != nil {
   134  		t.Fatal(err)
   135  	}
   136  
   137  	// host type is special network. Cannot be removed.
   138  	err = network.Delete()
   139  	if err == nil {
   140  		t.Fatal(err)
   141  	}
   142  	if _, ok := err.(types.ForbiddenError); !ok {
   143  		t.Fatalf("Unexpected error type")
   144  	}
   145  }
   146  
   147  func TestUnknownDriver(t *testing.T) {
   148  	if !testutils.IsRunningInContainer() {
   149  		defer testutils.SetupTestOSContext(t)()
   150  	}
   151  
   152  	_, err := createTestNetwork("unknowndriver", "testnetwork", options.Generic{}, nil, nil)
   153  	if err == nil {
   154  		t.Fatal("Expected to fail. But instead succeeded")
   155  	}
   156  
   157  	if !isNotFound(err) {
   158  		t.Fatalf("Did not fail with expected error. Actual error: %v", err)
   159  	}
   160  }
   161  
   162  func TestNilRemoteDriver(t *testing.T) {
   163  	_, err := controller.NewNetwork("framerelay", "dummy", "",
   164  		libnetwork.NetworkOptionGeneric(getEmptyGenericOption()))
   165  	if err == nil {
   166  		t.Fatal("Expected to fail. But instead succeeded")
   167  	}
   168  
   169  	if !isNotFound(err) {
   170  		t.Fatalf("Did not fail with expected error. Actual error: %v", err)
   171  	}
   172  }
   173  
   174  func TestNetworkName(t *testing.T) {
   175  	if !testutils.IsRunningInContainer() {
   176  		defer testutils.SetupTestOSContext(t)()
   177  	}
   178  
   179  	netOption := options.Generic{
   180  		netlabel.GenericData: options.Generic{
   181  			"BridgeName": "testnetwork",
   182  		},
   183  	}
   184  
   185  	_, err := createTestNetwork(bridgeNetType, "", netOption, nil, nil)
   186  	if err == nil {
   187  		t.Fatal("Expected to fail. But instead succeeded")
   188  	}
   189  
   190  	if _, ok := err.(libnetwork.ErrInvalidName); !ok {
   191  		t.Fatalf("Expected to fail with ErrInvalidName error. Got %v", err)
   192  	}
   193  
   194  	networkName := "testnetwork"
   195  	n, err := createTestNetwork(bridgeNetType, networkName, netOption, nil, nil)
   196  	if err != nil {
   197  		t.Fatal(err)
   198  	}
   199  	defer func() {
   200  		if err := n.Delete(); err != nil {
   201  			t.Fatal(err)
   202  		}
   203  	}()
   204  
   205  	if n.Name() != networkName {
   206  		t.Fatalf("Expected network name %s, got %s", networkName, n.Name())
   207  	}
   208  }
   209  
   210  func TestNetworkType(t *testing.T) {
   211  	if !testutils.IsRunningInContainer() {
   212  		defer testutils.SetupTestOSContext(t)()
   213  	}
   214  
   215  	netOption := options.Generic{
   216  		netlabel.GenericData: options.Generic{
   217  			"BridgeName": "testnetwork",
   218  		},
   219  	}
   220  
   221  	n, err := createTestNetwork(bridgeNetType, "testnetwork", netOption, nil, nil)
   222  	if err != nil {
   223  		t.Fatal(err)
   224  	}
   225  	defer func() {
   226  		if err := n.Delete(); err != nil {
   227  			t.Fatal(err)
   228  		}
   229  	}()
   230  
   231  	if n.Type() != bridgeNetType {
   232  		t.Fatalf("Expected network type %s, got %s", bridgeNetType, n.Type())
   233  	}
   234  }
   235  
   236  func TestNetworkID(t *testing.T) {
   237  	if !testutils.IsRunningInContainer() {
   238  		defer testutils.SetupTestOSContext(t)()
   239  	}
   240  
   241  	netOption := options.Generic{
   242  		netlabel.GenericData: options.Generic{
   243  			"BridgeName": "testnetwork",
   244  		},
   245  	}
   246  
   247  	n, err := createTestNetwork(bridgeNetType, "testnetwork", netOption, nil, nil)
   248  	if err != nil {
   249  		t.Fatal(err)
   250  	}
   251  	defer func() {
   252  		if err := n.Delete(); err != nil {
   253  			t.Fatal(err)
   254  		}
   255  	}()
   256  
   257  	if n.ID() == "" {
   258  		t.Fatal("Expected non-empty network id")
   259  	}
   260  }
   261  
   262  func TestDeleteNetworkWithActiveEndpoints(t *testing.T) {
   263  	if !testutils.IsRunningInContainer() {
   264  		defer testutils.SetupTestOSContext(t)()
   265  	}
   266  
   267  	netOption := options.Generic{
   268  		"BridgeName": "testnetwork",
   269  	}
   270  	option := options.Generic{
   271  		netlabel.GenericData: netOption,
   272  	}
   273  
   274  	network, err := createTestNetwork(bridgeNetType, "testnetwork", option, nil, nil)
   275  	if err != nil {
   276  		t.Fatal(err)
   277  	}
   278  
   279  	ep, err := network.CreateEndpoint("testep")
   280  	if err != nil {
   281  		t.Fatal(err)
   282  	}
   283  
   284  	err = network.Delete()
   285  	if err == nil {
   286  		t.Fatal("Expected to fail. But instead succeeded")
   287  	}
   288  
   289  	if _, ok := err.(*libnetwork.ActiveEndpointsError); !ok {
   290  		t.Fatalf("Did not fail with expected error. Actual error: %v", err)
   291  	}
   292  
   293  	// Done testing. Now cleanup.
   294  	if err := ep.Delete(false); err != nil {
   295  		t.Fatal(err)
   296  	}
   297  
   298  	if err := network.Delete(); err != nil {
   299  		t.Fatal(err)
   300  	}
   301  }
   302  
   303  func TestNetworkConfig(t *testing.T) {
   304  	if !testutils.IsRunningInContainer() {
   305  		defer testutils.SetupTestOSContext(t)()
   306  	}
   307  
   308  	// Verify config network cannot inherit another config network
   309  	_, err := controller.NewNetwork("bridge", "config_network0", "",
   310  		libnetwork.NetworkOptionConfigOnly(),
   311  		libnetwork.NetworkOptionConfigFrom("anotherConfigNw"))
   312  
   313  	if err == nil {
   314  		t.Fatal("Expected to fail. But instead succeeded")
   315  	}
   316  	if _, ok := err.(types.ForbiddenError); !ok {
   317  		t.Fatalf("Did not fail with expected error. Actual error: %v", err)
   318  	}
   319  
   320  	// Create supported config network
   321  	netOption := options.Generic{
   322  		"EnableICC": false,
   323  	}
   324  	option := options.Generic{
   325  		netlabel.GenericData: netOption,
   326  	}
   327  	ipamV4ConfList := []*libnetwork.IpamConf{{PreferredPool: "192.168.100.0/24", SubPool: "192.168.100.128/25", Gateway: "192.168.100.1"}}
   328  	ipamV6ConfList := []*libnetwork.IpamConf{{PreferredPool: "2001:db8:abcd::/64", SubPool: "2001:db8:abcd::ef99/80", Gateway: "2001:db8:abcd::22"}}
   329  
   330  	netOptions := []libnetwork.NetworkOption{
   331  		libnetwork.NetworkOptionConfigOnly(),
   332  		libnetwork.NetworkOptionEnableIPv6(true),
   333  		libnetwork.NetworkOptionGeneric(option),
   334  		libnetwork.NetworkOptionIpam("default", "", ipamV4ConfList, ipamV6ConfList, nil),
   335  	}
   336  
   337  	configNetwork, err := controller.NewNetwork(bridgeNetType, "config_network0", "", netOptions...)
   338  	if err != nil {
   339  		t.Fatal(err)
   340  	}
   341  
   342  	// Verify a config-only network cannot be created with network operator configurations
   343  	for i, opt := range []libnetwork.NetworkOption{
   344  		libnetwork.NetworkOptionInternalNetwork(),
   345  		libnetwork.NetworkOptionAttachable(true),
   346  		libnetwork.NetworkOptionIngress(true),
   347  	} {
   348  		_, err = controller.NewNetwork(bridgeNetType, "testBR", "",
   349  			libnetwork.NetworkOptionConfigOnly(), opt)
   350  		if err == nil {
   351  			t.Fatalf("Expected to fail. But instead succeeded for option: %d", i)
   352  		}
   353  		if _, ok := err.(types.ForbiddenError); !ok {
   354  			t.Fatalf("Did not fail with expected error. Actual error: %v", err)
   355  		}
   356  	}
   357  
   358  	// Verify a network cannot be created with both config-from and network specific configurations
   359  	for i, opt := range []libnetwork.NetworkOption{
   360  		libnetwork.NetworkOptionEnableIPv6(true),
   361  		libnetwork.NetworkOptionIpam("my-ipam", "", nil, nil, nil),
   362  		libnetwork.NetworkOptionIpam("", "", ipamV4ConfList, nil, nil),
   363  		libnetwork.NetworkOptionIpam("", "", nil, ipamV6ConfList, nil),
   364  		libnetwork.NetworkOptionLabels(map[string]string{"number": "two"}),
   365  		libnetwork.NetworkOptionDriverOpts(map[string]string{"com.docker.network.driver.mtu": "1600"}),
   366  	} {
   367  		_, err = controller.NewNetwork(bridgeNetType, "testBR", "",
   368  			libnetwork.NetworkOptionConfigFrom("config_network0"), opt)
   369  		if err == nil {
   370  			t.Fatalf("Expected to fail. But instead succeeded for option: %d", i)
   371  		}
   372  		if _, ok := err.(types.ForbiddenError); !ok {
   373  			t.Fatalf("Did not fail with expected error. Actual error: %v", err)
   374  		}
   375  	}
   376  
   377  	// Create a valid network
   378  	network, err := controller.NewNetwork(bridgeNetType, "testBR", "",
   379  		libnetwork.NetworkOptionConfigFrom("config_network0"))
   380  	if err != nil {
   381  		t.Fatal(err)
   382  	}
   383  
   384  	// Verify the config network cannot be removed
   385  	err = configNetwork.Delete()
   386  	if err == nil {
   387  		t.Fatal("Expected to fail. But instead succeeded")
   388  	}
   389  
   390  	if _, ok := err.(types.ForbiddenError); !ok {
   391  		t.Fatalf("Did not fail with expected error. Actual error: %v", err)
   392  	}
   393  
   394  	// Delete network
   395  	if err := network.Delete(); err != nil {
   396  		t.Fatal(err)
   397  	}
   398  
   399  	// Verify the config network can now be removed
   400  	if err := configNetwork.Delete(); err != nil {
   401  		t.Fatal(err)
   402  	}
   403  
   404  }
   405  
   406  func TestUnknownNetwork(t *testing.T) {
   407  	if !testutils.IsRunningInContainer() {
   408  		defer testutils.SetupTestOSContext(t)()
   409  	}
   410  
   411  	netOption := options.Generic{
   412  		"BridgeName": "testnetwork",
   413  	}
   414  	option := options.Generic{
   415  		netlabel.GenericData: netOption,
   416  	}
   417  
   418  	network, err := createTestNetwork(bridgeNetType, "testnetwork", option, nil, nil)
   419  	if err != nil {
   420  		t.Fatal(err)
   421  	}
   422  
   423  	err = network.Delete()
   424  	if err != nil {
   425  		t.Fatal(err)
   426  	}
   427  
   428  	err = network.Delete()
   429  	if err == nil {
   430  		t.Fatal("Expected to fail. But instead succeeded")
   431  	}
   432  
   433  	if _, ok := err.(*libnetwork.UnknownNetworkError); !ok {
   434  		t.Fatalf("Did not fail with expected error. Actual error: %v", err)
   435  	}
   436  }
   437  
   438  func TestUnknownEndpoint(t *testing.T) {
   439  	if !testutils.IsRunningInContainer() {
   440  		defer testutils.SetupTestOSContext(t)()
   441  	}
   442  
   443  	netOption := options.Generic{
   444  		"BridgeName": "testnetwork",
   445  	}
   446  	option := options.Generic{
   447  		netlabel.GenericData: netOption,
   448  	}
   449  	ipamV4ConfList := []*libnetwork.IpamConf{{PreferredPool: "192.168.100.0/24"}}
   450  
   451  	network, err := createTestNetwork(bridgeNetType, "testnetwork", option, ipamV4ConfList, nil)
   452  	if err != nil {
   453  		t.Fatal(err)
   454  	}
   455  
   456  	_, err = network.CreateEndpoint("")
   457  	if err == nil {
   458  		t.Fatal("Expected to fail. But instead succeeded")
   459  	}
   460  	if _, ok := err.(libnetwork.ErrInvalidName); !ok {
   461  		t.Fatalf("Expected to fail with ErrInvalidName error. Actual error: %v", err)
   462  	}
   463  
   464  	ep, err := network.CreateEndpoint("testep")
   465  	if err != nil {
   466  		t.Fatal(err)
   467  	}
   468  
   469  	err = ep.Delete(false)
   470  	if err != nil {
   471  		t.Fatal(err)
   472  	}
   473  
   474  	// Done testing. Now cleanup
   475  	if err := network.Delete(); err != nil {
   476  		t.Fatal(err)
   477  	}
   478  }
   479  
   480  func TestNetworkEndpointsWalkers(t *testing.T) {
   481  	if !testutils.IsRunningInContainer() {
   482  		defer testutils.SetupTestOSContext(t)()
   483  	}
   484  
   485  	// Create network 1 and add 2 endpoint: ep11, ep12
   486  	netOption := options.Generic{
   487  		netlabel.GenericData: options.Generic{
   488  			"BridgeName": "network1",
   489  		},
   490  	}
   491  
   492  	net1, err := createTestNetwork(bridgeNetType, "network1", netOption, nil, nil)
   493  	if err != nil {
   494  		t.Fatal(err)
   495  	}
   496  	defer func() {
   497  		if err := net1.Delete(); err != nil {
   498  			t.Fatal(err)
   499  		}
   500  	}()
   501  
   502  	ep11, err := net1.CreateEndpoint("ep11")
   503  	if err != nil {
   504  		t.Fatal(err)
   505  	}
   506  	defer func() {
   507  		if err := ep11.Delete(false); err != nil {
   508  			t.Fatal(err)
   509  		}
   510  	}()
   511  
   512  	ep12, err := net1.CreateEndpoint("ep12")
   513  	if err != nil {
   514  		t.Fatal(err)
   515  	}
   516  	defer func() {
   517  		if err := ep12.Delete(false); err != nil {
   518  			t.Fatal(err)
   519  		}
   520  	}()
   521  
   522  	// Test list methods on net1
   523  	epList1 := net1.Endpoints()
   524  	if len(epList1) != 2 {
   525  		t.Fatalf("Endpoints() returned wrong number of elements: %d instead of 2", len(epList1))
   526  	}
   527  	// endpoint order is not guaranteed
   528  	for _, e := range epList1 {
   529  		if e != ep11 && e != ep12 {
   530  			t.Fatal("Endpoints() did not return all the expected elements")
   531  		}
   532  	}
   533  
   534  	// Test Endpoint Walk method
   535  	var epName string
   536  	var epWanted libnetwork.Endpoint
   537  	wlk := func(ep libnetwork.Endpoint) bool {
   538  		if ep.Name() == epName {
   539  			epWanted = ep
   540  			return true
   541  		}
   542  		return false
   543  	}
   544  
   545  	// Look for ep1 on network1
   546  	epName = "ep11"
   547  	net1.WalkEndpoints(wlk)
   548  	if epWanted == nil {
   549  		t.Fatal(err)
   550  	}
   551  	if ep11 != epWanted {
   552  		t.Fatal(err)
   553  	}
   554  
   555  	current := len(controller.Networks())
   556  
   557  	// Create network 2
   558  	netOption = options.Generic{
   559  		netlabel.GenericData: options.Generic{
   560  			"BridgeName": "network2",
   561  		},
   562  	}
   563  
   564  	net2, err := createTestNetwork(bridgeNetType, "network2", netOption, nil, nil)
   565  	if err != nil {
   566  		t.Fatal(err)
   567  	}
   568  	defer func() {
   569  		if err := net2.Delete(); err != nil {
   570  			t.Fatal(err)
   571  		}
   572  	}()
   573  
   574  	// Test Networks method
   575  	if len(controller.Networks()) != current+1 {
   576  		t.Fatalf("Did not find the expected number of networks")
   577  	}
   578  
   579  	// Test Network Walk method
   580  	var netName string
   581  	var netWanted libnetwork.Network
   582  	nwWlk := func(nw libnetwork.Network) bool {
   583  		if nw.Name() == netName {
   584  			netWanted = nw
   585  			return true
   586  		}
   587  		return false
   588  	}
   589  
   590  	// Look for network named "network1" and "network2"
   591  	netName = "network1"
   592  	controller.WalkNetworks(nwWlk)
   593  	if netWanted == nil {
   594  		t.Fatal(err)
   595  	}
   596  	if net1.ID() != netWanted.ID() {
   597  		t.Fatal(err)
   598  	}
   599  
   600  	netName = "network2"
   601  	controller.WalkNetworks(nwWlk)
   602  	if netWanted == nil {
   603  		t.Fatal(err)
   604  	}
   605  	if net2.ID() != netWanted.ID() {
   606  		t.Fatal(err)
   607  	}
   608  }
   609  
   610  func TestDuplicateEndpoint(t *testing.T) {
   611  	if !testutils.IsRunningInContainer() {
   612  		defer testutils.SetupTestOSContext(t)()
   613  	}
   614  
   615  	netOption := options.Generic{
   616  		netlabel.GenericData: options.Generic{
   617  			"BridgeName": "testnetwork",
   618  		},
   619  	}
   620  	n, err := createTestNetwork(bridgeNetType, "testnetwork", netOption, nil, nil)
   621  	if err != nil {
   622  		t.Fatal(err)
   623  	}
   624  	defer func() {
   625  		if err := n.Delete(); err != nil {
   626  			t.Fatal(err)
   627  		}
   628  	}()
   629  
   630  	ep, err := n.CreateEndpoint("ep1")
   631  	if err != nil {
   632  		t.Fatal(err)
   633  	}
   634  	defer func() {
   635  		if err := ep.Delete(false); err != nil {
   636  			t.Fatal(err)
   637  		}
   638  	}()
   639  
   640  	ep2, err := n.CreateEndpoint("ep1")
   641  	defer func() {
   642  		// Cleanup ep2 as well, else network cleanup might fail for failure cases
   643  		if ep2 != nil {
   644  			if err := ep2.Delete(false); err != nil {
   645  				t.Fatal(err)
   646  			}
   647  		}
   648  	}()
   649  
   650  	if err == nil {
   651  		t.Fatal("Expected to fail. But instead succeeded")
   652  	}
   653  
   654  	if _, ok := err.(types.ForbiddenError); !ok {
   655  		t.Fatalf("Did not fail with expected error. Actual error: %v", err)
   656  	}
   657  }
   658  
   659  func TestControllerQuery(t *testing.T) {
   660  	if !testutils.IsRunningInContainer() {
   661  		defer testutils.SetupTestOSContext(t)()
   662  	}
   663  
   664  	// Create network 1
   665  	netOption := options.Generic{
   666  		netlabel.GenericData: options.Generic{
   667  			"BridgeName": "network1",
   668  		},
   669  	}
   670  	net1, err := createTestNetwork(bridgeNetType, "network1", netOption, nil, nil)
   671  	if err != nil {
   672  		t.Fatal(err)
   673  	}
   674  	defer func() {
   675  		if err := net1.Delete(); err != nil {
   676  			t.Fatal(err)
   677  		}
   678  	}()
   679  
   680  	// Create network 2
   681  	netOption = options.Generic{
   682  		netlabel.GenericData: options.Generic{
   683  			"BridgeName": "network2",
   684  		},
   685  	}
   686  	net2, err := createTestNetwork(bridgeNetType, "network2", netOption, nil, nil)
   687  	if err != nil {
   688  		t.Fatal(err)
   689  	}
   690  	defer func() {
   691  		if err := net2.Delete(); err != nil {
   692  			t.Fatal(err)
   693  		}
   694  	}()
   695  
   696  	_, err = controller.NetworkByName("")
   697  	if err == nil {
   698  		t.Fatalf("NetworkByName() succeeded with invalid target name")
   699  	}
   700  	if _, ok := err.(libnetwork.ErrInvalidName); !ok {
   701  		t.Fatalf("Expected NetworkByName() to fail with ErrInvalidName error. Got: %v", err)
   702  	}
   703  
   704  	_, err = controller.NetworkByID("")
   705  	if err == nil {
   706  		t.Fatalf("NetworkByID() succeeded with invalid target id")
   707  	}
   708  	if _, ok := err.(libnetwork.ErrInvalidID); !ok {
   709  		t.Fatalf("NetworkByID() failed with unexpected error: %v", err)
   710  	}
   711  
   712  	g, err := controller.NetworkByID("network1")
   713  	if err == nil {
   714  		t.Fatalf("Unexpected success for NetworkByID(): %v", g)
   715  	}
   716  	if _, ok := err.(libnetwork.ErrNoSuchNetwork); !ok {
   717  		t.Fatalf("NetworkByID() failed with unexpected error: %v", err)
   718  	}
   719  
   720  	g, err = controller.NetworkByName("network1")
   721  	if err != nil {
   722  		t.Fatalf("Unexpected failure for NetworkByName(): %v", err)
   723  	}
   724  	if g == nil {
   725  		t.Fatalf("NetworkByName() did not find the network")
   726  	}
   727  
   728  	if g != net1 {
   729  		t.Fatalf("NetworkByName() returned the wrong network")
   730  	}
   731  
   732  	g, err = controller.NetworkByID(net1.ID())
   733  	if err != nil {
   734  		t.Fatalf("Unexpected failure for NetworkByID(): %v", err)
   735  	}
   736  	if net1.ID() != g.ID() {
   737  		t.Fatalf("NetworkByID() returned unexpected element: %v", g)
   738  	}
   739  
   740  	g, err = controller.NetworkByName("network2")
   741  	if err != nil {
   742  		t.Fatalf("Unexpected failure for NetworkByName(): %v", err)
   743  	}
   744  	if g == nil {
   745  		t.Fatalf("NetworkByName() did not find the network")
   746  	}
   747  
   748  	if g != net2 {
   749  		t.Fatalf("NetworkByName() returned the wrong network")
   750  	}
   751  
   752  	g, err = controller.NetworkByID(net2.ID())
   753  	if err != nil {
   754  		t.Fatalf("Unexpected failure for NetworkByID(): %v", err)
   755  	}
   756  	if net2.ID() != g.ID() {
   757  		t.Fatalf("NetworkByID() returned unexpected element: %v", g)
   758  	}
   759  }
   760  
   761  func TestNetworkQuery(t *testing.T) {
   762  	if !testutils.IsRunningInContainer() {
   763  		defer testutils.SetupTestOSContext(t)()
   764  	}
   765  
   766  	// Create network 1 and add 2 endpoint: ep11, ep12
   767  	netOption := options.Generic{
   768  		netlabel.GenericData: options.Generic{
   769  			"BridgeName": "network1",
   770  		},
   771  	}
   772  	net1, err := createTestNetwork(bridgeNetType, "network1", netOption, nil, nil)
   773  	if err != nil {
   774  		t.Fatal(err)
   775  	}
   776  	defer func() {
   777  		if err := net1.Delete(); err != nil {
   778  			t.Fatal(err)
   779  		}
   780  	}()
   781  
   782  	ep11, err := net1.CreateEndpoint("ep11")
   783  	if err != nil {
   784  		t.Fatal(err)
   785  	}
   786  	defer func() {
   787  		if err := ep11.Delete(false); err != nil {
   788  			t.Fatal(err)
   789  		}
   790  	}()
   791  
   792  	ep12, err := net1.CreateEndpoint("ep12")
   793  	if err != nil {
   794  		t.Fatal(err)
   795  	}
   796  	defer func() {
   797  		if err := ep12.Delete(false); err != nil {
   798  			t.Fatal(err)
   799  		}
   800  	}()
   801  
   802  	e, err := net1.EndpointByName("ep11")
   803  	if err != nil {
   804  		t.Fatal(err)
   805  	}
   806  	if ep11 != e {
   807  		t.Fatalf("EndpointByName() returned %v instead of %v", e, ep11)
   808  	}
   809  
   810  	_, err = net1.EndpointByName("")
   811  	if err == nil {
   812  		t.Fatalf("EndpointByName() succeeded with invalid target name")
   813  	}
   814  	if _, ok := err.(libnetwork.ErrInvalidName); !ok {
   815  		t.Fatalf("Expected EndpointByName() to fail with ErrInvalidName error. Got: %v", err)
   816  	}
   817  
   818  	e, err = net1.EndpointByName("IamNotAnEndpoint")
   819  	if err == nil {
   820  		t.Fatalf("EndpointByName() succeeded with unknown target name")
   821  	}
   822  	if _, ok := err.(libnetwork.ErrNoSuchEndpoint); !ok {
   823  		t.Fatal(err)
   824  	}
   825  	if e != nil {
   826  		t.Fatalf("EndpointByName(): expected nil, got %v", e)
   827  	}
   828  
   829  	e, err = net1.EndpointByID(ep12.ID())
   830  	if err != nil {
   831  		t.Fatal(err)
   832  	}
   833  	if ep12.ID() != e.ID() {
   834  		t.Fatalf("EndpointByID() returned %v instead of %v", e, ep12)
   835  	}
   836  
   837  	_, err = net1.EndpointByID("")
   838  	if err == nil {
   839  		t.Fatalf("EndpointByID() succeeded with invalid target id")
   840  	}
   841  	if _, ok := err.(libnetwork.ErrInvalidID); !ok {
   842  		t.Fatalf("EndpointByID() failed with unexpected error: %v", err)
   843  	}
   844  }
   845  
   846  const containerID = "valid_c"
   847  
   848  type fakeSandbox struct{}
   849  
   850  func (f *fakeSandbox) ID() string {
   851  	return "fake sandbox"
   852  }
   853  
   854  func (f *fakeSandbox) ContainerID() string {
   855  	return ""
   856  }
   857  
   858  func (f *fakeSandbox) Key() string {
   859  	return "fake key"
   860  }
   861  
   862  func (f *fakeSandbox) Labels() map[string]interface{} {
   863  	return nil
   864  }
   865  
   866  func (f *fakeSandbox) Statistics() (map[string]*types.InterfaceStatistics, error) {
   867  	return nil, nil
   868  }
   869  
   870  func (f *fakeSandbox) Refresh(opts ...libnetwork.SandboxOption) error {
   871  	return nil
   872  }
   873  
   874  func (f *fakeSandbox) Delete() error {
   875  	return nil
   876  }
   877  
   878  func (f *fakeSandbox) Rename(name string) error {
   879  	return nil
   880  }
   881  
   882  func (f *fakeSandbox) SetKey(key string) error {
   883  	return nil
   884  }
   885  
   886  func (f *fakeSandbox) ResolveName(name string, ipType int) ([]net.IP, bool) {
   887  	return nil, false
   888  }
   889  
   890  func (f *fakeSandbox) ResolveIP(ip string) string {
   891  	return ""
   892  }
   893  
   894  func (f *fakeSandbox) ResolveService(name string) ([]*net.SRV, []net.IP) {
   895  	return nil, nil
   896  }
   897  
   898  func (f *fakeSandbox) Endpoints() []libnetwork.Endpoint {
   899  	return nil
   900  }
   901  
   902  func (f *fakeSandbox) EnableService() error {
   903  	return nil
   904  }
   905  
   906  func (f *fakeSandbox) DisableService() error {
   907  	return nil
   908  }
   909  
   910  func TestEndpointDeleteWithActiveContainer(t *testing.T) {
   911  	if !testutils.IsRunningInContainer() {
   912  		defer testutils.SetupTestOSContext(t)()
   913  	}
   914  
   915  	n, err := createTestNetwork(bridgeNetType, "testnetwork", options.Generic{
   916  		netlabel.GenericData: options.Generic{
   917  			"BridgeName": "testnetwork",
   918  		},
   919  	}, nil, nil)
   920  	if err != nil {
   921  		t.Fatal(err)
   922  	}
   923  	defer func() {
   924  		if err := n.Delete(); err != nil {
   925  			t.Fatal(err)
   926  		}
   927  	}()
   928  
   929  	n2, err := createTestNetwork(bridgeNetType, "testnetwork2", options.Generic{
   930  		netlabel.GenericData: options.Generic{
   931  			"BridgeName": "testnetwork2",
   932  		},
   933  	}, nil, nil)
   934  	if err != nil {
   935  		t.Fatal(err)
   936  	}
   937  	defer func() {
   938  		if err := n2.Delete(); err != nil {
   939  			t.Fatal(err)
   940  		}
   941  	}()
   942  
   943  	ep, err := n.CreateEndpoint("ep1")
   944  	if err != nil {
   945  		t.Fatal(err)
   946  	}
   947  	defer func() {
   948  		err = ep.Delete(false)
   949  		if err != nil {
   950  			t.Fatal(err)
   951  		}
   952  	}()
   953  
   954  	cnt, err := controller.NewSandbox(containerID,
   955  		libnetwork.OptionHostname("test"),
   956  		libnetwork.OptionDomainname("docker.io"),
   957  		libnetwork.OptionExtraHost("web", "192.168.0.1"))
   958  	defer func() {
   959  		if err := cnt.Delete(); err != nil {
   960  			t.Fatal(err)
   961  		}
   962  	}()
   963  
   964  	err = ep.Join(cnt)
   965  	if err != nil {
   966  		t.Fatal(err)
   967  	}
   968  	defer func() {
   969  		err = ep.Leave(cnt)
   970  		if err != nil {
   971  			t.Fatal(err)
   972  		}
   973  	}()
   974  
   975  	err = ep.Delete(false)
   976  	if err == nil {
   977  		t.Fatal("Expected to fail. But instead succeeded")
   978  	}
   979  
   980  	if _, ok := err.(*libnetwork.ActiveContainerError); !ok {
   981  		t.Fatalf("Did not fail with expected error. Actual error: %v", err)
   982  	}
   983  }
   984  
   985  func TestEndpointMultipleJoins(t *testing.T) {
   986  	if !testutils.IsRunningInContainer() {
   987  		defer testutils.SetupTestOSContext(t)()
   988  	}
   989  
   990  	n, err := createTestNetwork(bridgeNetType, "testmultiple", options.Generic{
   991  		netlabel.GenericData: options.Generic{
   992  			"BridgeName": "testmultiple",
   993  		},
   994  	}, nil, nil)
   995  	if err != nil {
   996  		t.Fatal(err)
   997  	}
   998  	defer func() {
   999  		if err := n.Delete(); err != nil {
  1000  			t.Fatal(err)
  1001  		}
  1002  	}()
  1003  
  1004  	ep, err := n.CreateEndpoint("ep1")
  1005  	if err != nil {
  1006  		t.Fatal(err)
  1007  	}
  1008  	defer func() {
  1009  		if err := ep.Delete(false); err != nil {
  1010  			t.Fatal(err)
  1011  		}
  1012  	}()
  1013  
  1014  	sbx1, err := controller.NewSandbox(containerID,
  1015  		libnetwork.OptionHostname("test"),
  1016  		libnetwork.OptionDomainname("docker.io"),
  1017  		libnetwork.OptionExtraHost("web", "192.168.0.1"))
  1018  	defer func() {
  1019  		if err := sbx1.Delete(); err != nil {
  1020  			t.Fatal(err)
  1021  		}
  1022  	}()
  1023  
  1024  	sbx2, err := controller.NewSandbox("c2")
  1025  	defer func() {
  1026  		if err := sbx2.Delete(); err != nil {
  1027  			t.Fatal(err)
  1028  		}
  1029  	}()
  1030  
  1031  	err = ep.Join(sbx1)
  1032  	if err != nil {
  1033  		t.Fatal(err)
  1034  	}
  1035  	defer func() {
  1036  		err = ep.Leave(sbx1)
  1037  		if err != nil {
  1038  			t.Fatal(err)
  1039  		}
  1040  	}()
  1041  
  1042  	err = ep.Join(sbx2)
  1043  	if err == nil {
  1044  		t.Fatal("Expected to fail multiple joins for the same endpoint")
  1045  	}
  1046  
  1047  	if _, ok := err.(types.ForbiddenError); !ok {
  1048  		t.Fatalf("Failed with unexpected error type: %T. Desc: %s", err, err.Error())
  1049  	}
  1050  
  1051  }
  1052  
  1053  func TestLeaveAll(t *testing.T) {
  1054  	if !testutils.IsRunningInContainer() {
  1055  		defer testutils.SetupTestOSContext(t)()
  1056  	}
  1057  
  1058  	n, err := createTestNetwork(bridgeNetType, "testnetwork", options.Generic{
  1059  		netlabel.GenericData: options.Generic{
  1060  			"BridgeName": "testnetwork",
  1061  		},
  1062  	}, nil, nil)
  1063  	if err != nil {
  1064  		t.Fatal(err)
  1065  	}
  1066  	defer func() {
  1067  		// If this goes through, it means cnt.Delete() effectively detached from all the endpoints
  1068  		if err := n.Delete(); err != nil {
  1069  			t.Fatal(err)
  1070  		}
  1071  	}()
  1072  
  1073  	n2, err := createTestNetwork(bridgeNetType, "testnetwork2", options.Generic{
  1074  		netlabel.GenericData: options.Generic{
  1075  			"BridgeName": "testnetwork2",
  1076  		},
  1077  	}, nil, nil)
  1078  	if err != nil {
  1079  		t.Fatal(err)
  1080  	}
  1081  	defer func() {
  1082  		if err := n2.Delete(); err != nil {
  1083  			t.Fatal(err)
  1084  		}
  1085  	}()
  1086  
  1087  	ep1, err := n.CreateEndpoint("ep1")
  1088  	if err != nil {
  1089  		t.Fatal(err)
  1090  	}
  1091  
  1092  	ep2, err := n2.CreateEndpoint("ep2")
  1093  	if err != nil {
  1094  		t.Fatal(err)
  1095  	}
  1096  
  1097  	cnt, err := controller.NewSandbox("leaveall")
  1098  	if err != nil {
  1099  		t.Fatal(err)
  1100  	}
  1101  
  1102  	err = ep1.Join(cnt)
  1103  	if err != nil {
  1104  		t.Fatalf("Failed to join ep1: %v", err)
  1105  	}
  1106  
  1107  	err = ep2.Join(cnt)
  1108  	if err != nil {
  1109  		t.Fatalf("Failed to join ep2: %v", err)
  1110  	}
  1111  
  1112  	err = cnt.Delete()
  1113  	if err != nil {
  1114  		t.Fatal(err)
  1115  	}
  1116  }
  1117  
  1118  func TestContainerInvalidLeave(t *testing.T) {
  1119  	if !testutils.IsRunningInContainer() {
  1120  		defer testutils.SetupTestOSContext(t)()
  1121  	}
  1122  
  1123  	n, err := createTestNetwork(bridgeNetType, "testnetwork", options.Generic{
  1124  		netlabel.GenericData: options.Generic{
  1125  			"BridgeName": "testnetwork",
  1126  		},
  1127  	}, nil, nil)
  1128  	if err != nil {
  1129  		t.Fatal(err)
  1130  	}
  1131  	defer func() {
  1132  		if err := n.Delete(); err != nil {
  1133  			t.Fatal(err)
  1134  		}
  1135  	}()
  1136  
  1137  	ep, err := n.CreateEndpoint("ep1")
  1138  	if err != nil {
  1139  		t.Fatal(err)
  1140  	}
  1141  	defer func() {
  1142  		if err := ep.Delete(false); err != nil {
  1143  			t.Fatal(err)
  1144  		}
  1145  	}()
  1146  
  1147  	cnt, err := controller.NewSandbox(containerID,
  1148  		libnetwork.OptionHostname("test"),
  1149  		libnetwork.OptionDomainname("docker.io"),
  1150  		libnetwork.OptionExtraHost("web", "192.168.0.1"))
  1151  	if err != nil {
  1152  		t.Fatal(err)
  1153  	}
  1154  	defer func() {
  1155  		if err := cnt.Delete(); err != nil {
  1156  			t.Fatal(err)
  1157  		}
  1158  	}()
  1159  
  1160  	err = ep.Leave(cnt)
  1161  	if err == nil {
  1162  		t.Fatal("Expected to fail leave from an endpoint which has no active join")
  1163  	}
  1164  	if _, ok := err.(types.ForbiddenError); !ok {
  1165  		t.Fatalf("Failed with unexpected error type: %T. Desc: %s", err, err.Error())
  1166  	}
  1167  
  1168  	if err = ep.Leave(nil); err == nil {
  1169  		t.Fatalf("Expected to fail leave nil Sandbox")
  1170  	}
  1171  	if _, ok := err.(types.BadRequestError); !ok {
  1172  		t.Fatalf("Unexpected error type returned: %T. Desc: %s", err, err.Error())
  1173  	}
  1174  
  1175  	fsbx := &fakeSandbox{}
  1176  	if err = ep.Leave(fsbx); err == nil {
  1177  		t.Fatalf("Expected to fail leave with invalid Sandbox")
  1178  	}
  1179  	if _, ok := err.(types.BadRequestError); !ok {
  1180  		t.Fatalf("Unexpected error type returned: %T. Desc: %s", err, err.Error())
  1181  	}
  1182  }
  1183  
  1184  func TestEndpointUpdateParent(t *testing.T) {
  1185  	if !testutils.IsRunningInContainer() {
  1186  		defer testutils.SetupTestOSContext(t)()
  1187  	}
  1188  
  1189  	n, err := createTestNetwork(bridgeNetType, "testnetwork", options.Generic{
  1190  		netlabel.GenericData: options.Generic{
  1191  			"BridgeName": "testnetwork",
  1192  		},
  1193  	}, nil, nil)
  1194  	if err != nil {
  1195  		t.Fatal(err)
  1196  	}
  1197  	defer func() {
  1198  		if err := n.Delete(); err != nil {
  1199  			t.Fatal(err)
  1200  		}
  1201  	}()
  1202  
  1203  	ep1, err := n.CreateEndpoint("ep1")
  1204  	if err != nil {
  1205  		t.Fatal(err)
  1206  	}
  1207  
  1208  	ep2, err := n.CreateEndpoint("ep2")
  1209  	if err != nil {
  1210  		t.Fatal(err)
  1211  	}
  1212  
  1213  	sbx1, err := controller.NewSandbox(containerID,
  1214  		libnetwork.OptionHostname("test"),
  1215  		libnetwork.OptionDomainname("docker.io"),
  1216  		libnetwork.OptionExtraHost("web", "192.168.0.1"))
  1217  	if err != nil {
  1218  		t.Fatal(err)
  1219  	}
  1220  	defer func() {
  1221  		if err := sbx1.Delete(); err != nil {
  1222  			t.Fatal(err)
  1223  		}
  1224  	}()
  1225  
  1226  	sbx2, err := controller.NewSandbox("c2",
  1227  		libnetwork.OptionHostname("test2"),
  1228  		libnetwork.OptionDomainname("docker.io"),
  1229  		libnetwork.OptionHostsPath("/var/lib/docker/test_network/container2/hosts"),
  1230  		libnetwork.OptionExtraHost("web", "192.168.0.2"))
  1231  	if err != nil {
  1232  		t.Fatal(err)
  1233  	}
  1234  	defer func() {
  1235  		if err := sbx2.Delete(); err != nil {
  1236  			t.Fatal(err)
  1237  		}
  1238  	}()
  1239  
  1240  	err = ep1.Join(sbx1)
  1241  	if err != nil {
  1242  		t.Fatal(err)
  1243  	}
  1244  
  1245  	err = ep2.Join(sbx2)
  1246  	if err != nil {
  1247  		t.Fatal(err)
  1248  	}
  1249  }
  1250  
  1251  func TestInvalidRemoteDriver(t *testing.T) {
  1252  	mux := http.NewServeMux()
  1253  	server := httptest.NewServer(mux)
  1254  	if server == nil {
  1255  		t.Fatal("Failed to start an HTTP Server")
  1256  	}
  1257  	defer server.Close()
  1258  
  1259  	mux.HandleFunc("/Plugin.Activate", func(w http.ResponseWriter, r *http.Request) {
  1260  		w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json")
  1261  		fmt.Fprintln(w, `{"Implements": ["InvalidDriver"]}`)
  1262  	})
  1263  
  1264  	if err := os.MkdirAll(specPath, 0755); err != nil {
  1265  		t.Fatal(err)
  1266  	}
  1267  	defer func() {
  1268  		if err := os.RemoveAll(specPath); err != nil {
  1269  			t.Fatal(err)
  1270  		}
  1271  	}()
  1272  
  1273  	if err := os.WriteFile(filepath.Join(specPath, "invalid-network-driver.spec"), []byte(server.URL), 0644); err != nil {
  1274  		t.Fatal(err)
  1275  	}
  1276  
  1277  	ctrlr, err := libnetwork.New()
  1278  	if err != nil {
  1279  		t.Fatal(err)
  1280  	}
  1281  	defer ctrlr.Stop()
  1282  
  1283  	_, err = ctrlr.NewNetwork("invalid-network-driver", "dummy", "",
  1284  		libnetwork.NetworkOptionGeneric(getEmptyGenericOption()))
  1285  	if err == nil {
  1286  		t.Fatal("Expected to fail. But instead succeeded")
  1287  	}
  1288  
  1289  	if !errors.Is(err, plugins.ErrNotImplements) {
  1290  		t.Fatalf("Did not fail with expected error. Actual error: %v", err)
  1291  	}
  1292  }
  1293  
  1294  func TestValidRemoteDriver(t *testing.T) {
  1295  	mux := http.NewServeMux()
  1296  	server := httptest.NewServer(mux)
  1297  	if server == nil {
  1298  		t.Fatal("Failed to start an HTTP Server")
  1299  	}
  1300  	defer server.Close()
  1301  
  1302  	mux.HandleFunc("/Plugin.Activate", func(w http.ResponseWriter, r *http.Request) {
  1303  		w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json")
  1304  		fmt.Fprintf(w, `{"Implements": ["%s"]}`, driverapi.NetworkPluginEndpointType)
  1305  	})
  1306  	mux.HandleFunc(fmt.Sprintf("/%s.GetCapabilities", driverapi.NetworkPluginEndpointType), func(w http.ResponseWriter, r *http.Request) {
  1307  		w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json")
  1308  		fmt.Fprintf(w, `{"Scope":"local"}`)
  1309  	})
  1310  	mux.HandleFunc(fmt.Sprintf("/%s.CreateNetwork", driverapi.NetworkPluginEndpointType), func(w http.ResponseWriter, r *http.Request) {
  1311  		w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json")
  1312  		fmt.Fprintf(w, "null")
  1313  	})
  1314  	mux.HandleFunc(fmt.Sprintf("/%s.DeleteNetwork", driverapi.NetworkPluginEndpointType), func(w http.ResponseWriter, r *http.Request) {
  1315  		w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json")
  1316  		fmt.Fprintf(w, "null")
  1317  	})
  1318  
  1319  	if err := os.MkdirAll(specPath, 0755); err != nil {
  1320  		t.Fatal(err)
  1321  	}
  1322  	defer func() {
  1323  		if err := os.RemoveAll(specPath); err != nil {
  1324  			t.Fatal(err)
  1325  		}
  1326  	}()
  1327  
  1328  	if err := os.WriteFile(filepath.Join(specPath, "valid-network-driver.spec"), []byte(server.URL), 0644); err != nil {
  1329  		t.Fatal(err)
  1330  	}
  1331  
  1332  	n, err := controller.NewNetwork("valid-network-driver", "dummy", "",
  1333  		libnetwork.NetworkOptionGeneric(getEmptyGenericOption()))
  1334  	if err != nil {
  1335  		// Only fail if we could not find the plugin driver
  1336  		if isNotFound(err) {
  1337  			t.Fatal(err)
  1338  		}
  1339  		return
  1340  	}
  1341  	defer func() {
  1342  		if err := n.Delete(); err != nil {
  1343  			t.Fatal(err)
  1344  		}
  1345  	}()
  1346  }
  1347  
  1348  var (
  1349  	start  = make(chan struct{})
  1350  	done   = make(chan chan struct{}, numThreads-1)
  1351  	sboxes = make([]libnetwork.Sandbox, numThreads)
  1352  )
  1353  
  1354  const (
  1355  	iterCnt    = 25
  1356  	numThreads = 3
  1357  	first      = 1
  1358  	last       = numThreads
  1359  	debug      = false
  1360  )
  1361  
  1362  func debugf(format string, a ...interface{}) {
  1363  	if debug {
  1364  		fmt.Printf(format, a...)
  1365  	}
  1366  }