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 }