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

     1  package remote
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"fmt"
     7  	"io"
     8  	"io/ioutil"
     9  	"net"
    10  	"net/http"
    11  	"net/http/httptest"
    12  	"os"
    13  	"testing"
    14  
    15  	"github.com/docker/docker/pkg/plugins"
    16  	"github.com/docker/libnetwork/datastore"
    17  	"github.com/docker/libnetwork/discoverapi"
    18  	"github.com/docker/libnetwork/driverapi"
    19  	_ "github.com/docker/libnetwork/testutils"
    20  	"github.com/docker/libnetwork/types"
    21  )
    22  
    23  func decodeToMap(r *http.Request) (res map[string]interface{}, err error) {
    24  	err = json.NewDecoder(r.Body).Decode(&res)
    25  	return
    26  }
    27  
    28  func handle(t *testing.T, mux *http.ServeMux, method string, h func(map[string]interface{}) interface{}) {
    29  	mux.HandleFunc(fmt.Sprintf("/%s.%s", driverapi.NetworkPluginEndpointType, method), func(w http.ResponseWriter, r *http.Request) {
    30  		ask, err := decodeToMap(r)
    31  		if err != nil && err != io.EOF {
    32  			t.Fatal(err)
    33  		}
    34  		answer := h(ask)
    35  		err = json.NewEncoder(w).Encode(&answer)
    36  		if err != nil {
    37  			t.Fatal(err)
    38  		}
    39  	})
    40  }
    41  
    42  func setupPlugin(t *testing.T, name string, mux *http.ServeMux) func() {
    43  	if err := os.MkdirAll("/etc/docker/plugins", 0755); err != nil {
    44  		t.Fatal(err)
    45  	}
    46  
    47  	server := httptest.NewServer(mux)
    48  	if server == nil {
    49  		t.Fatal("Failed to start an HTTP Server")
    50  	}
    51  
    52  	if err := ioutil.WriteFile(fmt.Sprintf("/etc/docker/plugins/%s.spec", name), []byte(server.URL), 0644); err != nil {
    53  		t.Fatal(err)
    54  	}
    55  
    56  	mux.HandleFunc("/Plugin.Activate", func(w http.ResponseWriter, r *http.Request) {
    57  		w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json")
    58  		fmt.Fprintf(w, `{"Implements": ["%s"]}`, driverapi.NetworkPluginEndpointType)
    59  	})
    60  
    61  	return func() {
    62  		if err := os.RemoveAll("/etc/docker/plugins"); err != nil {
    63  			t.Fatal(err)
    64  		}
    65  		server.Close()
    66  	}
    67  }
    68  
    69  type testEndpoint struct {
    70  	t                     *testing.T
    71  	src                   string
    72  	dst                   string
    73  	address               string
    74  	addressIPv6           string
    75  	macAddress            string
    76  	gateway               string
    77  	gatewayIPv6           string
    78  	resolvConfPath        string
    79  	hostsPath             string
    80  	nextHop               string
    81  	destination           string
    82  	routeType             int
    83  	disableGatewayService bool
    84  }
    85  
    86  func (test *testEndpoint) Interface() driverapi.InterfaceInfo {
    87  	return test
    88  }
    89  
    90  func (test *testEndpoint) Address() *net.IPNet {
    91  	if test.address == "" {
    92  		return nil
    93  	}
    94  	nw, _ := types.ParseCIDR(test.address)
    95  	return nw
    96  }
    97  
    98  func (test *testEndpoint) AddressIPv6() *net.IPNet {
    99  	if test.addressIPv6 == "" {
   100  		return nil
   101  	}
   102  	nw, _ := types.ParseCIDR(test.addressIPv6)
   103  	return nw
   104  }
   105  
   106  func (test *testEndpoint) MacAddress() net.HardwareAddr {
   107  	if test.macAddress == "" {
   108  		return nil
   109  	}
   110  	mac, _ := net.ParseMAC(test.macAddress)
   111  	return mac
   112  }
   113  
   114  func (test *testEndpoint) SetMacAddress(mac net.HardwareAddr) error {
   115  	if test.macAddress != "" {
   116  		return types.ForbiddenErrorf("endpoint interface MAC address present (%s). Cannot be modified with %s.", test.macAddress, mac)
   117  	}
   118  	if mac == nil {
   119  		return types.BadRequestErrorf("tried to set nil MAC address to endpoint interface")
   120  	}
   121  	test.macAddress = mac.String()
   122  	return nil
   123  }
   124  
   125  func (test *testEndpoint) SetIPAddress(address *net.IPNet) error {
   126  	if address.IP == nil {
   127  		return types.BadRequestErrorf("tried to set nil IP address to endpoint interface")
   128  	}
   129  	if address.IP.To4() == nil {
   130  		return setAddress(&test.addressIPv6, address)
   131  	}
   132  	return setAddress(&test.address, address)
   133  }
   134  
   135  func setAddress(ifaceAddr *string, address *net.IPNet) error {
   136  	if *ifaceAddr != "" {
   137  		return types.ForbiddenErrorf("endpoint interface IP present (%s). Cannot be modified with (%s).", *ifaceAddr, address)
   138  	}
   139  	*ifaceAddr = address.String()
   140  	return nil
   141  }
   142  
   143  func (test *testEndpoint) InterfaceName() driverapi.InterfaceNameInfo {
   144  	return test
   145  }
   146  
   147  func compareIPs(t *testing.T, kind string, shouldBe string, supplied net.IP) {
   148  	ip := net.ParseIP(shouldBe)
   149  	if ip == nil {
   150  		t.Fatalf(`Invalid IP to test against: "%s"`, shouldBe)
   151  	}
   152  	if !ip.Equal(supplied) {
   153  		t.Fatalf(`%s IPs are not equal: expected "%s", got %v`, kind, shouldBe, supplied)
   154  	}
   155  }
   156  
   157  func compareIPNets(t *testing.T, kind string, shouldBe string, supplied net.IPNet) {
   158  	_, net, _ := net.ParseCIDR(shouldBe)
   159  	if net == nil {
   160  		t.Fatalf(`Invalid IP network to test against: "%s"`, shouldBe)
   161  	}
   162  	if !types.CompareIPNet(net, &supplied) {
   163  		t.Fatalf(`%s IP networks are not equal: expected "%s", got %v`, kind, shouldBe, supplied)
   164  	}
   165  }
   166  
   167  func (test *testEndpoint) SetGateway(ipv4 net.IP) error {
   168  	compareIPs(test.t, "Gateway", test.gateway, ipv4)
   169  	return nil
   170  }
   171  
   172  func (test *testEndpoint) SetGatewayIPv6(ipv6 net.IP) error {
   173  	compareIPs(test.t, "GatewayIPv6", test.gatewayIPv6, ipv6)
   174  	return nil
   175  }
   176  
   177  func (test *testEndpoint) SetNames(src string, dst string) error {
   178  	if test.src != src {
   179  		test.t.Fatalf(`Wrong SrcName; expected "%s", got "%s"`, test.src, src)
   180  	}
   181  	if test.dst != dst {
   182  		test.t.Fatalf(`Wrong DstPrefix; expected "%s", got "%s"`, test.dst, dst)
   183  	}
   184  	return nil
   185  }
   186  
   187  func (test *testEndpoint) AddStaticRoute(destination *net.IPNet, routeType int, nextHop net.IP) error {
   188  	compareIPNets(test.t, "Destination", test.destination, *destination)
   189  	compareIPs(test.t, "NextHop", test.nextHop, nextHop)
   190  
   191  	if test.routeType != routeType {
   192  		test.t.Fatalf(`Wrong RouteType; expected "%d", got "%d"`, test.routeType, routeType)
   193  	}
   194  
   195  	return nil
   196  }
   197  
   198  func (test *testEndpoint) DisableGatewayService() {
   199  	test.disableGatewayService = true
   200  }
   201  
   202  func (test *testEndpoint) AddTableEntry(tableName string, key string, value []byte) error {
   203  	return nil
   204  }
   205  
   206  func TestGetEmptyCapabilities(t *testing.T) {
   207  	var plugin = "test-net-driver-empty-cap"
   208  
   209  	mux := http.NewServeMux()
   210  	defer setupPlugin(t, plugin, mux)()
   211  
   212  	handle(t, mux, "GetCapabilities", func(msg map[string]interface{}) interface{} {
   213  		return map[string]interface{}{}
   214  	})
   215  
   216  	p, err := plugins.Get(plugin, driverapi.NetworkPluginEndpointType)
   217  	if err != nil {
   218  		t.Fatal(err)
   219  	}
   220  
   221  	d := newDriver(plugin, p.Client())
   222  	if d.Type() != plugin {
   223  		t.Fatal("Driver type does not match that given")
   224  	}
   225  
   226  	_, err = d.(*driver).getCapabilities()
   227  	if err == nil {
   228  		t.Fatal("There should be error reported when get empty capability")
   229  	}
   230  }
   231  
   232  func TestGetExtraCapabilities(t *testing.T) {
   233  	var plugin = "test-net-driver-extra-cap"
   234  
   235  	mux := http.NewServeMux()
   236  	defer setupPlugin(t, plugin, mux)()
   237  
   238  	handle(t, mux, "GetCapabilities", func(msg map[string]interface{}) interface{} {
   239  		return map[string]interface{}{
   240  			"Scope": "local",
   241  			"foo":   "bar",
   242  		}
   243  	})
   244  
   245  	p, err := plugins.Get(plugin, driverapi.NetworkPluginEndpointType)
   246  	if err != nil {
   247  		t.Fatal(err)
   248  	}
   249  
   250  	d := newDriver(plugin, p.Client())
   251  	if d.Type() != plugin {
   252  		t.Fatal("Driver type does not match that given")
   253  	}
   254  
   255  	c, err := d.(*driver).getCapabilities()
   256  	if err != nil {
   257  		t.Fatal(err)
   258  	} else if c.DataScope != datastore.LocalScope {
   259  		t.Fatalf("get capability '%s', expecting 'local'", c.DataScope)
   260  	}
   261  }
   262  
   263  func TestGetInvalidCapabilities(t *testing.T) {
   264  	var plugin = "test-net-driver-invalid-cap"
   265  
   266  	mux := http.NewServeMux()
   267  	defer setupPlugin(t, plugin, mux)()
   268  
   269  	handle(t, mux, "GetCapabilities", func(msg map[string]interface{}) interface{} {
   270  		return map[string]interface{}{
   271  			"Scope": "fake",
   272  		}
   273  	})
   274  
   275  	p, err := plugins.Get(plugin, driverapi.NetworkPluginEndpointType)
   276  	if err != nil {
   277  		t.Fatal(err)
   278  	}
   279  
   280  	d := newDriver(plugin, p.Client())
   281  	if d.Type() != plugin {
   282  		t.Fatal("Driver type does not match that given")
   283  	}
   284  
   285  	_, err = d.(*driver).getCapabilities()
   286  	if err == nil {
   287  		t.Fatal("There should be error reported when get invalid capability")
   288  	}
   289  }
   290  
   291  func TestRemoteDriver(t *testing.T) {
   292  	var plugin = "test-net-driver"
   293  
   294  	ep := &testEndpoint{
   295  		t:              t,
   296  		src:            "vethsrc",
   297  		dst:            "vethdst",
   298  		address:        "192.168.5.7/16",
   299  		addressIPv6:    "2001:DB8::5:7/48",
   300  		macAddress:     "ab:cd:ef:ee:ee:ee",
   301  		gateway:        "192.168.0.1",
   302  		gatewayIPv6:    "2001:DB8::1",
   303  		hostsPath:      "/here/comes/the/host/path",
   304  		resolvConfPath: "/there/goes/the/resolv/conf",
   305  		destination:    "10.0.0.0/8",
   306  		nextHop:        "10.0.0.1",
   307  		routeType:      1,
   308  	}
   309  
   310  	mux := http.NewServeMux()
   311  	defer setupPlugin(t, plugin, mux)()
   312  
   313  	var networkID string
   314  
   315  	handle(t, mux, "GetCapabilities", func(msg map[string]interface{}) interface{} {
   316  		return map[string]interface{}{
   317  			"Scope": "global",
   318  		}
   319  	})
   320  	handle(t, mux, "CreateNetwork", func(msg map[string]interface{}) interface{} {
   321  		nid := msg["NetworkID"]
   322  		var ok bool
   323  		if networkID, ok = nid.(string); !ok {
   324  			t.Fatal("RPC did not include network ID string")
   325  		}
   326  		return map[string]interface{}{}
   327  	})
   328  	handle(t, mux, "DeleteNetwork", func(msg map[string]interface{}) interface{} {
   329  		if nid, ok := msg["NetworkID"]; !ok || nid != networkID {
   330  			t.Fatal("Network ID missing or does not match that created")
   331  		}
   332  		return map[string]interface{}{}
   333  	})
   334  	handle(t, mux, "CreateEndpoint", func(msg map[string]interface{}) interface{} {
   335  		iface := map[string]interface{}{
   336  			"MacAddress":  ep.macAddress,
   337  			"Address":     ep.address,
   338  			"AddressIPv6": ep.addressIPv6,
   339  		}
   340  		return map[string]interface{}{
   341  			"Interface": iface,
   342  		}
   343  	})
   344  	handle(t, mux, "Join", func(msg map[string]interface{}) interface{} {
   345  		options := msg["Options"].(map[string]interface{})
   346  		foo, ok := options["foo"].(string)
   347  		if !ok || foo != "fooValue" {
   348  			t.Fatalf("Did not receive expected foo string in request options: %+v", msg)
   349  		}
   350  		return map[string]interface{}{
   351  			"Gateway":        ep.gateway,
   352  			"GatewayIPv6":    ep.gatewayIPv6,
   353  			"HostsPath":      ep.hostsPath,
   354  			"ResolvConfPath": ep.resolvConfPath,
   355  			"InterfaceName": map[string]interface{}{
   356  				"SrcName":   ep.src,
   357  				"DstPrefix": ep.dst,
   358  			},
   359  			"StaticRoutes": []map[string]interface{}{
   360  				{
   361  					"Destination": ep.destination,
   362  					"RouteType":   ep.routeType,
   363  					"NextHop":     ep.nextHop,
   364  				},
   365  			},
   366  		}
   367  	})
   368  	handle(t, mux, "Leave", func(msg map[string]interface{}) interface{} {
   369  		return map[string]string{}
   370  	})
   371  	handle(t, mux, "DeleteEndpoint", func(msg map[string]interface{}) interface{} {
   372  		return map[string]interface{}{}
   373  	})
   374  	handle(t, mux, "EndpointOperInfo", func(msg map[string]interface{}) interface{} {
   375  		return map[string]interface{}{
   376  			"Value": map[string]string{
   377  				"Arbitrary": "key",
   378  				"Value":     "pairs?",
   379  			},
   380  		}
   381  	})
   382  	handle(t, mux, "DiscoverNew", func(msg map[string]interface{}) interface{} {
   383  		return map[string]string{}
   384  	})
   385  	handle(t, mux, "DiscoverDelete", func(msg map[string]interface{}) interface{} {
   386  		return map[string]interface{}{}
   387  	})
   388  
   389  	p, err := plugins.Get(plugin, driverapi.NetworkPluginEndpointType)
   390  	if err != nil {
   391  		t.Fatal(err)
   392  	}
   393  
   394  	d := newDriver(plugin, p.Client())
   395  	if d.Type() != plugin {
   396  		t.Fatal("Driver type does not match that given")
   397  	}
   398  
   399  	c, err := d.(*driver).getCapabilities()
   400  	if err != nil {
   401  		t.Fatal(err)
   402  	} else if c.DataScope != datastore.GlobalScope {
   403  		t.Fatalf("get capability '%s', expecting 'global'", c.DataScope)
   404  	}
   405  
   406  	netID := "dummy-network"
   407  	err = d.CreateNetwork(netID, map[string]interface{}{}, nil, nil, nil)
   408  	if err != nil {
   409  		t.Fatal(err)
   410  	}
   411  
   412  	endID := "dummy-endpoint"
   413  	ifInfo := &testEndpoint{}
   414  	err = d.CreateEndpoint(netID, endID, ifInfo, map[string]interface{}{})
   415  	if err != nil {
   416  		t.Fatal(err)
   417  	}
   418  
   419  	if !bytes.Equal(ep.MacAddress(), ifInfo.MacAddress()) || !types.CompareIPNet(ep.Address(), ifInfo.Address()) ||
   420  		!types.CompareIPNet(ep.AddressIPv6(), ifInfo.AddressIPv6()) {
   421  		t.Fatalf("Unexpected InterfaceInfo data. Expected (%s, %s, %s). Got (%v, %v, %v)",
   422  			ep.MacAddress(), ep.Address(), ep.AddressIPv6(),
   423  			ifInfo.MacAddress(), ifInfo.Address(), ifInfo.AddressIPv6())
   424  	}
   425  
   426  	joinOpts := map[string]interface{}{"foo": "fooValue"}
   427  	err = d.Join(netID, endID, "sandbox-key", ep, joinOpts)
   428  	if err != nil {
   429  		t.Fatal(err)
   430  	}
   431  	if _, err = d.EndpointOperInfo(netID, endID); err != nil {
   432  		t.Fatal(err)
   433  	}
   434  	if err = d.Leave(netID, endID); err != nil {
   435  		t.Fatal(err)
   436  	}
   437  	if err = d.DeleteEndpoint(netID, endID); err != nil {
   438  		t.Fatal(err)
   439  	}
   440  	if err = d.DeleteNetwork(netID); err != nil {
   441  		t.Fatal(err)
   442  	}
   443  
   444  	data := discoverapi.NodeDiscoveryData{
   445  		Address: "192.168.1.1",
   446  	}
   447  	if err = d.DiscoverNew(discoverapi.NodeDiscovery, data); err != nil {
   448  		t.Fatal(err)
   449  	}
   450  	if err = d.DiscoverDelete(discoverapi.NodeDiscovery, data); err != nil {
   451  		t.Fatal(err)
   452  	}
   453  }
   454  
   455  func TestDriverError(t *testing.T) {
   456  	var plugin = "test-net-driver-error"
   457  
   458  	mux := http.NewServeMux()
   459  	defer setupPlugin(t, plugin, mux)()
   460  
   461  	handle(t, mux, "CreateEndpoint", func(msg map[string]interface{}) interface{} {
   462  		return map[string]interface{}{
   463  			"Err": "this should get raised as an error",
   464  		}
   465  	})
   466  
   467  	p, err := plugins.Get(plugin, driverapi.NetworkPluginEndpointType)
   468  	if err != nil {
   469  		t.Fatal(err)
   470  	}
   471  
   472  	driver := newDriver(plugin, p.Client())
   473  
   474  	if err := driver.CreateEndpoint("dummy", "dummy", &testEndpoint{t: t}, map[string]interface{}{}); err == nil {
   475  		t.Fatalf("Expected error from driver")
   476  	}
   477  }
   478  
   479  func TestMissingValues(t *testing.T) {
   480  	var plugin = "test-net-driver-missing"
   481  
   482  	mux := http.NewServeMux()
   483  	defer setupPlugin(t, plugin, mux)()
   484  
   485  	ep := &testEndpoint{
   486  		t: t,
   487  	}
   488  
   489  	handle(t, mux, "CreateEndpoint", func(msg map[string]interface{}) interface{} {
   490  		iface := map[string]interface{}{
   491  			"Address":     ep.address,
   492  			"AddressIPv6": ep.addressIPv6,
   493  			"MacAddress":  ep.macAddress,
   494  		}
   495  		return map[string]interface{}{
   496  			"Interface": iface,
   497  		}
   498  	})
   499  
   500  	p, err := plugins.Get(plugin, driverapi.NetworkPluginEndpointType)
   501  	if err != nil {
   502  		t.Fatal(err)
   503  	}
   504  	driver := newDriver(plugin, p.Client())
   505  
   506  	if err := driver.CreateEndpoint("dummy", "dummy", ep, map[string]interface{}{}); err != nil {
   507  		t.Fatal(err)
   508  	}
   509  }
   510  
   511  type rollbackEndpoint struct {
   512  }
   513  
   514  func (r *rollbackEndpoint) Interface() driverapi.InterfaceInfo {
   515  	return r
   516  }
   517  
   518  func (r *rollbackEndpoint) MacAddress() net.HardwareAddr {
   519  	return nil
   520  }
   521  
   522  func (r *rollbackEndpoint) Address() *net.IPNet {
   523  	return nil
   524  }
   525  
   526  func (r *rollbackEndpoint) AddressIPv6() *net.IPNet {
   527  	return nil
   528  }
   529  
   530  func (r *rollbackEndpoint) SetMacAddress(mac net.HardwareAddr) error {
   531  	return fmt.Errorf("invalid mac")
   532  }
   533  
   534  func (r *rollbackEndpoint) SetIPAddress(ip *net.IPNet) error {
   535  	return fmt.Errorf("invalid ip")
   536  }
   537  
   538  func TestRollback(t *testing.T) {
   539  	var plugin = "test-net-driver-rollback"
   540  
   541  	mux := http.NewServeMux()
   542  	defer setupPlugin(t, plugin, mux)()
   543  
   544  	rolledback := false
   545  
   546  	handle(t, mux, "CreateEndpoint", func(msg map[string]interface{}) interface{} {
   547  		iface := map[string]interface{}{
   548  			"Address":     "192.168.4.5/16",
   549  			"AddressIPv6": "",
   550  			"MacAddress":  "7a:12:34:56:78:90",
   551  		}
   552  		return map[string]interface{}{
   553  			"Interface": interface{}(iface),
   554  		}
   555  	})
   556  	handle(t, mux, "DeleteEndpoint", func(msg map[string]interface{}) interface{} {
   557  		rolledback = true
   558  		return map[string]interface{}{}
   559  	})
   560  
   561  	p, err := plugins.Get(plugin, driverapi.NetworkPluginEndpointType)
   562  	if err != nil {
   563  		t.Fatal(err)
   564  	}
   565  	driver := newDriver(plugin, p.Client())
   566  
   567  	ep := &rollbackEndpoint{}
   568  
   569  	if err := driver.CreateEndpoint("dummy", "dummy", ep.Interface(), map[string]interface{}{}); err == nil {
   570  		t.Fatalf("Expected error from driver")
   571  	}
   572  	if !rolledback {
   573  		t.Fatalf("Expected to have had DeleteEndpoint called")
   574  	}
   575  }