github.com/jfrazelle/docker@v1.1.2-0.20210712172922-bf78e25fe508/libnetwork/api/api_linux_test.go (about) 1 package api 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "errors" 7 "fmt" 8 "io" 9 "net/http" 10 "os" 11 "regexp" 12 "runtime" 13 "testing" 14 15 "github.com/docker/docker/libnetwork" 16 "github.com/docker/docker/libnetwork/datastore" 17 "github.com/docker/docker/libnetwork/drivers/bridge" 18 "github.com/docker/docker/libnetwork/netlabel" 19 "github.com/docker/docker/libnetwork/options" 20 "github.com/docker/docker/libnetwork/testutils" 21 "github.com/docker/docker/libnetwork/types" 22 "github.com/docker/docker/pkg/reexec" 23 ) 24 25 const ( 26 bridgeNetType = "bridge" 27 ) 28 29 func i2s(i interface{}) string { 30 s, ok := i.(string) 31 if !ok { 32 panic(fmt.Sprintf("Failed i2s for %v", i)) 33 } 34 return s 35 } 36 37 func i2e(i interface{}) *endpointResource { 38 s, ok := i.(*endpointResource) 39 if !ok { 40 panic(fmt.Sprintf("Failed i2e for %v", i)) 41 } 42 return s 43 } 44 45 func i2eL(i interface{}) []*endpointResource { 46 s, ok := i.([]*endpointResource) 47 if !ok { 48 panic(fmt.Sprintf("Failed i2eL for %v", i)) 49 } 50 return s 51 } 52 53 func i2n(i interface{}) *networkResource { 54 s, ok := i.(*networkResource) 55 if !ok { 56 panic(fmt.Sprintf("Failed i2n for %v", i)) 57 } 58 return s 59 } 60 61 func i2nL(i interface{}) []*networkResource { 62 s, ok := i.([]*networkResource) 63 if !ok { 64 panic(fmt.Sprintf("Failed i2nL for %v", i)) 65 } 66 return s 67 } 68 69 func i2sb(i interface{}) *sandboxResource { 70 s, ok := i.(*sandboxResource) 71 if !ok { 72 panic(fmt.Sprintf("Failed i2sb for %v", i)) 73 } 74 return s 75 } 76 77 func i2sbL(i interface{}) []*sandboxResource { 78 s, ok := i.([]*sandboxResource) 79 if !ok { 80 panic(fmt.Sprintf("Failed i2sbL for %v", i)) 81 } 82 return s 83 } 84 85 func createTestNetwork(t *testing.T, network string) (libnetwork.NetworkController, libnetwork.Network) { 86 // Cleanup local datastore file 87 os.Remove(datastore.DefaultScopes("")[datastore.LocalScope].Client.Address) 88 89 c, err := libnetwork.New() 90 if err != nil { 91 t.Fatal(err) 92 } 93 94 netOption := options.Generic{ 95 netlabel.GenericData: options.Generic{ 96 "BridgeName": network, 97 }, 98 } 99 netGeneric := libnetwork.NetworkOptionGeneric(netOption) 100 nw, err := c.NewNetwork(bridgeNetType, network, "", netGeneric) 101 if err != nil { 102 t.Fatal(err) 103 } 104 105 return c, nw 106 } 107 108 func GetOpsMap(bridgeName, defaultMTU string) map[string]string { 109 if defaultMTU == "" { 110 return map[string]string{ 111 bridge.BridgeName: bridgeName, 112 } 113 } 114 return map[string]string{ 115 bridge.BridgeName: bridgeName, 116 netlabel.DriverMTU: defaultMTU, 117 } 118 } 119 120 func getExposedPorts() []types.TransportPort { 121 return []types.TransportPort{ 122 {Proto: types.TCP, Port: uint16(5000)}, 123 {Proto: types.UDP, Port: uint16(400)}, 124 {Proto: types.TCP, Port: uint16(600)}, 125 } 126 } 127 128 func getPortMapping() []types.PortBinding { 129 return []types.PortBinding{ 130 {Proto: types.TCP, Port: uint16(230), HostPort: uint16(23000)}, 131 {Proto: types.UDP, Port: uint16(200), HostPort: uint16(22000)}, 132 {Proto: types.TCP, Port: uint16(120), HostPort: uint16(12000)}, 133 } 134 } 135 136 func TestMain(m *testing.M) { 137 if reexec.Init() { 138 return 139 } 140 os.Exit(m.Run()) 141 } 142 143 func TestSandboxOptionParser(t *testing.T) { 144 hn := "host1" 145 dn := "docker.com" 146 hp := "/etc/hosts" 147 rc := "/etc/resolv.conf" 148 dnss := []string{"8.8.8.8", "172.28.34.5"} 149 ehs := []extraHost{{Name: "extra1", Address: "172.28.9.1"}, {Name: "extra2", Address: "172.28.9.2"}} 150 151 sb := sandboxCreate{ 152 HostName: hn, 153 DomainName: dn, 154 HostsPath: hp, 155 ResolvConfPath: rc, 156 DNS: dnss, 157 ExtraHosts: ehs, 158 UseDefaultSandbox: true, 159 } 160 161 if len(sb.parseOptions()) != 9 { 162 t.Fatal("Failed to generate all libnetwork.SandboxOption methods") 163 } 164 } 165 166 func TestJson(t *testing.T) { 167 nc := networkCreate{NetworkType: bridgeNetType} 168 b, err := json.Marshal(nc) 169 if err != nil { 170 t.Fatal(err) 171 } 172 173 var ncp networkCreate 174 err = json.Unmarshal(b, &ncp) 175 if err != nil { 176 t.Fatal(err) 177 } 178 179 if nc.NetworkType != ncp.NetworkType { 180 t.Fatalf("Incorrect networkCreate after json encoding/deconding: %v", ncp) 181 } 182 183 jl := endpointJoin{SandboxID: "abcdef456789"} 184 b, err = json.Marshal(jl) 185 if err != nil { 186 t.Fatal(err) 187 } 188 189 var jld endpointJoin 190 err = json.Unmarshal(b, &jld) 191 if err != nil { 192 t.Fatal(err) 193 } 194 195 if jl.SandboxID != jld.SandboxID { 196 t.Fatalf("Incorrect endpointJoin after json encoding/deconding: %v", jld) 197 } 198 } 199 200 func TestCreateDeleteNetwork(t *testing.T) { 201 defer testutils.SetupTestOSContext(t)() 202 203 // Cleanup local datastore file 204 os.Remove(datastore.DefaultScopes("")[datastore.LocalScope].Client.Address) 205 206 c, err := libnetwork.New() 207 if err != nil { 208 t.Fatal(err) 209 } 210 defer c.Stop() 211 212 badBody, err := json.Marshal("bad body") 213 if err != nil { 214 t.Fatal(err) 215 } 216 217 vars := make(map[string]string) 218 _, errRsp := procCreateNetwork(c, nil, badBody) 219 if errRsp == &createdResponse { 220 t.Fatal("Expected to fail but succeeded") 221 } 222 if errRsp.StatusCode != http.StatusBadRequest { 223 t.Fatalf("Expected StatusBadRequest status code, got: %v", errRsp) 224 } 225 226 incompleteBody, err := json.Marshal(networkCreate{}) 227 if err != nil { 228 t.Fatal(err) 229 } 230 231 _, errRsp = procCreateNetwork(c, vars, incompleteBody) 232 if errRsp == &createdResponse { 233 t.Fatal("Expected to fail but succeeded") 234 } 235 if errRsp.StatusCode != http.StatusBadRequest { 236 t.Fatalf("Expected StatusBadRequest status code, got: %v", errRsp) 237 } 238 239 dops := GetOpsMap("abc", "") 240 nops := map[string]string{} 241 nc := networkCreate{Name: "network_1", NetworkType: bridgeNetType, DriverOpts: dops, NetworkOpts: nops} 242 goodBody, err := json.Marshal(nc) 243 if err != nil { 244 t.Fatal(err) 245 } 246 247 _, errRsp = procCreateNetwork(c, vars, goodBody) 248 if errRsp != &createdResponse { 249 t.Fatalf("Unexpected failure: %v", errRsp) 250 } 251 252 vars[urlNwName] = "" 253 _, errRsp = procDeleteNetwork(c, vars, nil) 254 if errRsp == &successResponse { 255 t.Fatal("Expected to fail but succeeded") 256 } 257 258 vars[urlNwName] = "abc" 259 _, errRsp = procDeleteNetwork(c, vars, nil) 260 if errRsp == &successResponse { 261 t.Fatal("Expected to fail but succeeded") 262 } 263 264 vars[urlNwName] = "network_1" 265 _, errRsp = procDeleteNetwork(c, vars, nil) 266 if errRsp != &successResponse { 267 t.Fatalf("Unexpected failure: %v", errRsp) 268 } 269 } 270 271 func TestGetNetworksAndEndpoints(t *testing.T) { 272 defer testutils.SetupTestOSContext(t)() 273 274 // Cleanup local datastore file 275 os.Remove(datastore.DefaultScopes("")[datastore.LocalScope].Client.Address) 276 277 c, err := libnetwork.New() 278 if err != nil { 279 t.Fatal(err) 280 } 281 defer c.Stop() 282 283 ops := GetOpsMap("api_test_nw", "") 284 nc := networkCreate{Name: "sh", NetworkType: bridgeNetType, DriverOpts: ops} 285 body, err := json.Marshal(nc) 286 if err != nil { 287 t.Fatal(err) 288 } 289 290 vars := make(map[string]string) 291 inid, errRsp := procCreateNetwork(c, vars, body) 292 if errRsp != &createdResponse { 293 t.Fatalf("Unexpected failure: %v", errRsp) 294 } 295 nid, ok := inid.(string) 296 if !ok { 297 t.FailNow() 298 } 299 300 ec1 := endpointCreate{ 301 Name: "ep1", 302 } 303 b1, err := json.Marshal(ec1) 304 if err != nil { 305 t.Fatal(err) 306 } 307 ec2 := endpointCreate{Name: "ep2"} 308 b2, err := json.Marshal(ec2) 309 if err != nil { 310 t.Fatal(err) 311 } 312 313 vars[urlNwName] = "sh" 314 vars[urlEpName] = "ep1" 315 ieid1, errRsp := procCreateEndpoint(c, vars, b1) 316 if errRsp != &createdResponse { 317 t.Fatalf("Unexpected failure: %v", errRsp) 318 } 319 eid1 := i2s(ieid1) 320 vars[urlEpName] = "ep2" 321 ieid2, errRsp := procCreateEndpoint(c, vars, b2) 322 if errRsp != &createdResponse { 323 t.Fatalf("Unexpected failure: %v", errRsp) 324 } 325 eid2 := i2s(ieid2) 326 327 vars[urlNwName] = "" 328 vars[urlEpName] = "ep1" 329 _, errRsp = procGetEndpoint(c, vars, nil) 330 if errRsp == &successResponse { 331 t.Fatalf("Expected failure but succeeded: %v", errRsp) 332 } 333 if errRsp.StatusCode != http.StatusBadRequest { 334 t.Fatalf("Expected to fail with http.StatusBadRequest, but got: %d", errRsp.StatusCode) 335 } 336 337 vars = make(map[string]string) 338 vars[urlNwName] = "sh" 339 vars[urlEpID] = "" 340 _, errRsp = procGetEndpoint(c, vars, nil) 341 if errRsp == &successResponse { 342 t.Fatalf("Expected failure but succeeded: %v", errRsp) 343 } 344 if errRsp.StatusCode != http.StatusBadRequest { 345 t.Fatalf("Expected to fail with http.StatusBadRequest, but got: %d", errRsp.StatusCode) 346 } 347 348 vars = make(map[string]string) 349 vars[urlNwID] = "" 350 vars[urlEpID] = eid1 351 _, errRsp = procGetEndpoint(c, vars, nil) 352 if errRsp == &successResponse { 353 t.Fatalf("Expected failure but succeeded: %v", errRsp) 354 } 355 if errRsp.StatusCode != http.StatusBadRequest { 356 t.Fatalf("Expected to fail with http.StatusBadRequest, but got: %d", errRsp.StatusCode) 357 } 358 359 // nw by name and ep by id 360 vars[urlNwName] = "sh" 361 i1, errRsp := procGetEndpoint(c, vars, nil) 362 if errRsp != &successResponse { 363 t.Fatalf("Unexpected failure: %v", errRsp) 364 } 365 // nw by name and ep by name 366 delete(vars, urlEpID) 367 vars[urlEpName] = "ep1" 368 i2, errRsp := procGetEndpoint(c, vars, nil) 369 if errRsp != &successResponse { 370 t.Fatalf("Unexpected failure: %v", errRsp) 371 } 372 // nw by id and ep by name 373 delete(vars, urlNwName) 374 vars[urlNwID] = nid 375 i3, errRsp := procGetEndpoint(c, vars, nil) 376 if errRsp != &successResponse { 377 t.Fatalf("Unexpected failure: %v", errRsp) 378 } 379 // nw by id and ep by id 380 delete(vars, urlEpName) 381 vars[urlEpID] = eid1 382 i4, errRsp := procGetEndpoint(c, vars, nil) 383 if errRsp != &successResponse { 384 t.Fatalf("Unexpected failure: %v", errRsp) 385 } 386 387 id1 := i2e(i1).ID 388 if id1 != i2e(i2).ID || id1 != i2e(i3).ID || id1 != i2e(i4).ID { 389 t.Fatalf("Endpoints retrieved via different query parameters differ: %v, %v, %v, %v", i1, i2, i3, i4) 390 } 391 392 vars[urlNwName] = "" 393 _, errRsp = procGetEndpoints(c, vars, nil) 394 if errRsp == &successResponse { 395 t.Fatalf("Expected failure, got: %v", errRsp) 396 } 397 398 delete(vars, urlNwName) 399 vars[urlNwID] = "fakeID" 400 _, errRsp = procGetEndpoints(c, vars, nil) 401 if errRsp == &successResponse { 402 t.Fatalf("Expected failure, got: %v", errRsp) 403 } 404 405 vars[urlNwID] = nid 406 _, errRsp = procGetEndpoints(c, vars, nil) 407 if errRsp != &successResponse { 408 t.Fatalf("Unexpected failure: %v", errRsp) 409 } 410 411 vars[urlNwName] = "sh" 412 iepList, errRsp := procGetEndpoints(c, vars, nil) 413 if errRsp != &successResponse { 414 t.Fatalf("Unexpected failure: %v", errRsp) 415 } 416 epList := i2eL(iepList) 417 if len(epList) != 2 { 418 t.Fatalf("Did not return the expected number (2) of endpoint resources: %d", len(epList)) 419 } 420 if "sh" != epList[0].Network || "sh" != epList[1].Network { 421 t.Fatal("Did not find expected network name in endpoint resources") 422 } 423 424 vars = make(map[string]string) 425 vars[urlNwName] = "" 426 _, errRsp = procGetNetwork(c, vars, nil) 427 if errRsp == &successResponse { 428 t.Fatalf("Expected failure, got: %v", errRsp) 429 } 430 vars[urlNwName] = "shhhhh" 431 _, errRsp = procGetNetwork(c, vars, nil) 432 if errRsp == &successResponse { 433 t.Fatalf("Expected failure, got: %v", errRsp) 434 } 435 vars[urlNwName] = "sh" 436 inr1, errRsp := procGetNetwork(c, vars, nil) 437 if errRsp != &successResponse { 438 t.Fatalf("Unexpected failure: %v", errRsp) 439 } 440 nr1 := i2n(inr1) 441 442 delete(vars, urlNwName) 443 vars[urlNwID] = "acacac" 444 _, errRsp = procGetNetwork(c, vars, nil) 445 if errRsp == &successResponse { 446 t.Fatalf("Expected failure. Got: %v", errRsp) 447 } 448 vars[urlNwID] = nid 449 inr2, errRsp := procGetNetwork(c, vars, nil) 450 if errRsp != &successResponse { 451 t.Fatalf("procgetNetworkByName() != procgetNetworkById(), %v vs %v", inr1, inr2) 452 } 453 nr2 := i2n(inr2) 454 if nr1.Name != nr2.Name || nr1.Type != nr2.Type || nr1.ID != nr2.ID || len(nr1.Endpoints) != len(nr2.Endpoints) { 455 t.Fatalf("Get by name and Get failure: %v", errRsp) 456 } 457 458 if len(nr1.Endpoints) != 2 { 459 t.Fatalf("Did not find the expected number (2) of endpoint resources in the network resource: %d", len(nr1.Endpoints)) 460 } 461 for _, er := range nr1.Endpoints { 462 if er.ID != eid1 && er.ID != eid2 { 463 t.Fatalf("Did not find the expected endpoint resources in the network resource: %v", nr1.Endpoints) 464 } 465 } 466 467 iList, errRsp := procGetNetworks(c, nil, nil) 468 if errRsp != &successResponse { 469 t.Fatalf("Unexpected failure: %v", errRsp) 470 } 471 netList := i2nL(iList) 472 if len(netList) != 1 { 473 t.Fatal("Did not return the expected number of network resources") 474 } 475 if nid != netList[0].ID { 476 t.Fatalf("Did not find expected network %s: %v", nid, netList) 477 } 478 479 _, errRsp = procDeleteNetwork(c, vars, nil) 480 if errRsp == &successResponse { 481 t.Fatalf("Expected failure, got: %v", errRsp) 482 } 483 484 vars[urlEpName] = "ep1" 485 _, errRsp = procDeleteEndpoint(c, vars, nil) 486 if errRsp != &successResponse { 487 t.Fatalf("Unexpected failure: %v", errRsp) 488 } 489 delete(vars, urlEpName) 490 iepList, errRsp = procGetEndpoints(c, vars, nil) 491 if errRsp != &successResponse { 492 t.Fatalf("Unexpected failure: %v", errRsp) 493 } 494 epList = i2eL(iepList) 495 if len(epList) != 1 { 496 t.Fatalf("Did not return the expected number (1) of endpoint resources: %d", len(epList)) 497 } 498 499 vars[urlEpName] = "ep2" 500 _, errRsp = procDeleteEndpoint(c, vars, nil) 501 if errRsp != &successResponse { 502 t.Fatalf("Unexpected failure: %v", errRsp) 503 } 504 iepList, errRsp = procGetEndpoints(c, vars, nil) 505 if errRsp != &successResponse { 506 t.Fatalf("Unexpected failure: %v", errRsp) 507 } 508 epList = i2eL(iepList) 509 if len(epList) != 0 { 510 t.Fatalf("Did not return the expected number (0) of endpoint resources: %d", len(epList)) 511 } 512 513 _, errRsp = procDeleteNetwork(c, vars, nil) 514 if errRsp != &successResponse { 515 t.Fatalf("Unexpected failure: %v", errRsp) 516 } 517 518 iList, errRsp = procGetNetworks(c, nil, nil) 519 if errRsp != &successResponse { 520 t.Fatalf("Unexpected failure: %v", errRsp) 521 } 522 netList = i2nL(iList) 523 if len(netList) != 0 { 524 t.Fatal("Did not return the expected number of network resources") 525 } 526 } 527 528 func TestProcGetServices(t *testing.T) { 529 defer testutils.SetupTestOSContext(t)() 530 531 // Cleanup local datastore file 532 os.Remove(datastore.DefaultScopes("")[datastore.LocalScope].Client.Address) 533 534 c, err := libnetwork.New() 535 if err != nil { 536 t.Fatal(err) 537 } 538 defer c.Stop() 539 540 // Create 2 networks 541 netName1 := "production" 542 netOption := options.Generic{ 543 netlabel.GenericData: options.Generic{ 544 "BridgeName": netName1, 545 }, 546 } 547 nw1, err := c.NewNetwork(bridgeNetType, netName1, "", libnetwork.NetworkOptionGeneric(netOption)) 548 if err != nil { 549 t.Fatal(err) 550 } 551 552 netName2 := "workdev" 553 netOption = options.Generic{ 554 netlabel.GenericData: options.Generic{ 555 "BridgeName": netName2, 556 }, 557 } 558 nw2, err := c.NewNetwork(bridgeNetType, netName2, "", libnetwork.NetworkOptionGeneric(netOption)) 559 if err != nil { 560 t.Fatal(err) 561 } 562 563 vars := make(map[string]string) 564 li, errRsp := procGetServices(c, vars, nil) 565 if !errRsp.isOK() { 566 t.Fatalf("Unexpected failure: %v", errRsp) 567 } 568 list := i2eL(li) 569 if len(list) != 0 { 570 t.Fatalf("Unexpected services in response: %v", list) 571 } 572 573 // Add a couple of services on one network and one on the other network 574 ep11, err := nw1.CreateEndpoint("db-prod") 575 if err != nil { 576 t.Fatal(err) 577 } 578 ep12, err := nw1.CreateEndpoint("web-prod") 579 if err != nil { 580 t.Fatal(err) 581 } 582 ep21, err := nw2.CreateEndpoint("db-dev") 583 if err != nil { 584 t.Fatal(err) 585 } 586 587 li, errRsp = procGetServices(c, vars, nil) 588 if !errRsp.isOK() { 589 t.Fatalf("Unexpected failure: %v", errRsp) 590 } 591 list = i2eL(li) 592 if len(list) != 3 { 593 t.Fatalf("Unexpected services in response: %v", list) 594 } 595 596 // Filter by network 597 vars[urlNwName] = netName1 598 li, errRsp = procGetServices(c, vars, nil) 599 if !errRsp.isOK() { 600 t.Fatalf("Unexpected failure: %v", errRsp) 601 } 602 list = i2eL(li) 603 if len(list) != 2 { 604 t.Fatalf("Unexpected services in response: %v", list) 605 } 606 607 vars[urlNwName] = netName2 608 li, errRsp = procGetServices(c, vars, nil) 609 if !errRsp.isOK() { 610 t.Fatalf("Unexpected failure: %v", errRsp) 611 } 612 list = i2eL(li) 613 if len(list) != 1 { 614 t.Fatalf("Unexpected services in response: %v", list) 615 } 616 617 vars[urlNwName] = "unknown-network" 618 li, errRsp = procGetServices(c, vars, nil) 619 if !errRsp.isOK() { 620 t.Fatalf("Unexpected failure: %v", errRsp) 621 } 622 list = i2eL(li) 623 if len(list) != 0 { 624 t.Fatalf("Unexpected services in response: %v", list) 625 } 626 627 // Query by name 628 delete(vars, urlNwName) 629 vars[urlEpName] = "db-prod" 630 li, errRsp = procGetServices(c, vars, nil) 631 if !errRsp.isOK() { 632 t.Fatalf("Unexpected failure: %v", errRsp) 633 } 634 list = i2eL(li) 635 if len(list) != 1 { 636 t.Fatalf("Unexpected services in response: %v", list) 637 } 638 639 vars[urlEpName] = "no-service" 640 li, errRsp = procGetServices(c, vars, nil) 641 if !errRsp.isOK() { 642 t.Fatalf("Unexpected failure: %v", errRsp) 643 } 644 list = i2eL(li) 645 if len(list) != 0 { 646 t.Fatalf("Unexpected services in response: %v", list) 647 } 648 649 // Query by id or partial id 650 delete(vars, urlEpName) 651 vars[urlEpPID] = ep12.ID() 652 li, errRsp = procGetServices(c, vars, nil) 653 if !errRsp.isOK() { 654 t.Fatalf("Unexpected failure: %v", errRsp) 655 } 656 list = i2eL(li) 657 if len(list) != 1 { 658 t.Fatalf("Unexpected services in response: %v", list) 659 } 660 if list[0].ID != ep12.ID() { 661 t.Fatalf("Unexpected element in response: %v", list) 662 } 663 664 vars[urlEpPID] = "non-id" 665 li, errRsp = procGetServices(c, vars, nil) 666 if !errRsp.isOK() { 667 t.Fatalf("Unexpected failure: %v", errRsp) 668 } 669 list = i2eL(li) 670 if len(list) != 0 { 671 t.Fatalf("Unexpected services in response: %v", list) 672 } 673 674 delete(vars, urlEpPID) 675 err = ep11.Delete(false) 676 if err != nil { 677 t.Fatal(err) 678 } 679 err = ep12.Delete(false) 680 if err != nil { 681 t.Fatal(err) 682 } 683 err = ep21.Delete(false) 684 if err != nil { 685 t.Fatal(err) 686 } 687 688 li, errRsp = procGetServices(c, vars, nil) 689 if !errRsp.isOK() { 690 t.Fatalf("Unexpected failure: %v", errRsp) 691 } 692 list = i2eL(li) 693 if len(list) != 0 { 694 t.Fatalf("Unexpected services in response: %v", list) 695 } 696 } 697 698 func TestProcGetService(t *testing.T) { 699 defer testutils.SetupTestOSContext(t)() 700 701 c, nw := createTestNetwork(t, "network") 702 defer c.Stop() 703 ep1, err := nw.CreateEndpoint("db") 704 if err != nil { 705 t.Fatal(err) 706 } 707 ep2, err := nw.CreateEndpoint("web") 708 if err != nil { 709 t.Fatal(err) 710 } 711 712 vars := map[string]string{urlEpID: ""} 713 _, errRsp := procGetService(c, vars, nil) 714 if errRsp.isOK() { 715 t.Fatal("Expected failure, but succeeded") 716 } 717 if errRsp.StatusCode != http.StatusBadRequest { 718 t.Fatalf("Expected %d, but got: %d", http.StatusBadRequest, errRsp.StatusCode) 719 } 720 721 vars[urlEpID] = "unknown-service-id" 722 _, errRsp = procGetService(c, vars, nil) 723 if errRsp.isOK() { 724 t.Fatal("Expected failure, but succeeded") 725 } 726 if errRsp.StatusCode != http.StatusNotFound { 727 t.Fatalf("Expected %d, but got: %d. (%v)", http.StatusNotFound, errRsp.StatusCode, errRsp) 728 } 729 730 vars[urlEpID] = ep1.ID() 731 si, errRsp := procGetService(c, vars, nil) 732 if !errRsp.isOK() { 733 t.Fatalf("Unexpected failure: %v", errRsp) 734 } 735 sv := i2e(si) 736 if sv.ID != ep1.ID() { 737 t.Fatalf("Unexpected service resource returned: %v", sv) 738 } 739 740 vars[urlEpID] = ep2.ID() 741 si, errRsp = procGetService(c, vars, nil) 742 if !errRsp.isOK() { 743 t.Fatalf("Unexpected failure: %v", errRsp) 744 } 745 sv = i2e(si) 746 if sv.ID != ep2.ID() { 747 t.Fatalf("Unexpected service resource returned: %v", sv) 748 } 749 } 750 751 func TestProcPublishUnpublishService(t *testing.T) { 752 defer testutils.SetupTestOSContext(t)() 753 754 c, _ := createTestNetwork(t, "network") 755 defer c.Stop() 756 757 vars := make(map[string]string) 758 759 vbad, err := json.Marshal("bad service create data") 760 if err != nil { 761 t.Fatal(err) 762 } 763 _, errRsp := procPublishService(c, vars, vbad) 764 if errRsp == &createdResponse { 765 t.Fatal("Expected to fail but succeeded") 766 } 767 if errRsp.StatusCode != http.StatusBadRequest { 768 t.Fatalf("Expected %d. Got: %v", http.StatusBadRequest, errRsp) 769 } 770 771 b, err := json.Marshal(servicePublish{Name: ""}) 772 if err != nil { 773 t.Fatal(err) 774 } 775 _, errRsp = procPublishService(c, vars, b) 776 if errRsp == &createdResponse { 777 t.Fatal("Expected to fail but succeeded") 778 } 779 if errRsp.StatusCode != http.StatusBadRequest { 780 t.Fatalf("Expected %d. Got: %v", http.StatusBadRequest, errRsp) 781 } 782 783 b, err = json.Marshal(servicePublish{Name: "db"}) 784 if err != nil { 785 t.Fatal(err) 786 } 787 _, errRsp = procPublishService(c, vars, b) 788 if errRsp == &createdResponse { 789 t.Fatal("Expected to fail but succeeded") 790 } 791 if errRsp.StatusCode != http.StatusBadRequest { 792 t.Fatalf("Expected %d. Got: %v", http.StatusBadRequest, errRsp) 793 } 794 795 b, err = json.Marshal(servicePublish{Name: "db", Network: "unknown-network"}) 796 if err != nil { 797 t.Fatal(err) 798 } 799 _, errRsp = procPublishService(c, vars, b) 800 if errRsp == &createdResponse { 801 t.Fatal("Expected to fail but succeeded") 802 } 803 if errRsp.StatusCode != http.StatusNotFound { 804 t.Fatalf("Expected %d. Got: %v", http.StatusNotFound, errRsp) 805 } 806 807 b, err = json.Marshal(servicePublish{Name: "", Network: "network"}) 808 if err != nil { 809 t.Fatal(err) 810 } 811 _, errRsp = procPublishService(c, vars, b) 812 if errRsp == &createdResponse { 813 t.Fatal("Expected to fail but succeeded") 814 } 815 if errRsp.StatusCode != http.StatusBadRequest { 816 t.Fatalf("Expected %d. Got: %v", http.StatusBadRequest, errRsp) 817 } 818 819 b, err = json.Marshal(servicePublish{Name: "db", Network: "network"}) 820 if err != nil { 821 t.Fatal(err) 822 } 823 _, errRsp = procPublishService(c, vars, b) 824 if errRsp != &createdResponse { 825 t.Fatalf("Unexpected failure: %v", errRsp) 826 } 827 828 sp := servicePublish{ 829 Name: "web", 830 Network: "network", 831 } 832 b, err = json.Marshal(sp) 833 if err != nil { 834 t.Fatal(err) 835 } 836 si, errRsp := procPublishService(c, vars, b) 837 if errRsp != &createdResponse { 838 t.Fatalf("Unexpected failure: %v", errRsp) 839 } 840 sid := i2s(si) 841 842 vars[urlEpID] = "" 843 _, errRsp = procUnpublishService(c, vars, nil) 844 if errRsp.isOK() { 845 t.Fatal("Expected failure but succeeded") 846 } 847 if errRsp.StatusCode != http.StatusBadRequest { 848 t.Fatalf("Expected %d. Got: %v", http.StatusBadRequest, errRsp) 849 } 850 851 vars[urlEpID] = "unknown-service-id" 852 _, errRsp = procUnpublishService(c, vars, nil) 853 if errRsp.isOK() { 854 t.Fatal("Expected failure but succeeded") 855 } 856 if errRsp.StatusCode != http.StatusNotFound { 857 t.Fatalf("Expected %d. Got: %v", http.StatusNotFound, errRsp) 858 } 859 860 vars[urlEpID] = sid 861 _, errRsp = procUnpublishService(c, vars, nil) 862 if !errRsp.isOK() { 863 t.Fatalf("Unexpected failure: %v", errRsp) 864 } 865 866 _, errRsp = procGetService(c, vars, nil) 867 if errRsp.isOK() { 868 t.Fatal("Expected failure, but succeeded") 869 } 870 if errRsp.StatusCode != http.StatusNotFound { 871 t.Fatalf("Expected %d, but got: %d. (%v)", http.StatusNotFound, errRsp.StatusCode, errRsp) 872 } 873 } 874 875 func TestAttachDetachBackend(t *testing.T) { 876 defer testutils.SetupTestOSContext(t)() 877 878 c, nw := createTestNetwork(t, "network") 879 defer c.Stop() 880 ep1, err := nw.CreateEndpoint("db") 881 if err != nil { 882 t.Fatal(err) 883 } 884 885 vars := make(map[string]string) 886 887 vbad, err := json.Marshal("bad data") 888 if err != nil { 889 t.Fatal(err) 890 } 891 _, errRsp := procAttachBackend(c, vars, vbad) 892 if errRsp == &successResponse { 893 t.Fatalf("Expected failure, got: %v", errRsp) 894 } 895 896 vars[urlEpName] = "endpoint" 897 bad, err := json.Marshal(endpointJoin{}) 898 if err != nil { 899 t.Fatal(err) 900 } 901 _, errRsp = procAttachBackend(c, vars, bad) 902 if errRsp == &successResponse { 903 t.Fatalf("Expected failure, got: %v", errRsp) 904 } 905 if errRsp.StatusCode != http.StatusNotFound { 906 t.Fatalf("Expected %d. Got: %v", http.StatusNotFound, errRsp) 907 } 908 909 vars[urlEpID] = "db" 910 _, errRsp = procGetSandbox(c, vars, nil) 911 if errRsp.isOK() { 912 t.Fatalf("Expected failure. Got %v", errRsp) 913 } 914 if errRsp.StatusCode != http.StatusNotFound { 915 t.Fatalf("Expected %d. Got: %v", http.StatusNotFound, errRsp) 916 } 917 918 vars[urlEpName] = "db" 919 _, errRsp = procAttachBackend(c, vars, bad) 920 if errRsp == &successResponse { 921 t.Fatalf("Expected failure, got: %v", errRsp) 922 } 923 if errRsp.StatusCode != http.StatusBadRequest { 924 t.Fatalf("Expected %d. Got: %v", http.StatusBadRequest, errRsp) 925 } 926 927 cid := "abcdefghi" 928 sbox, err := c.NewSandbox(cid) 929 if err != nil { 930 t.Fatal(err) 931 } 932 sid := sbox.ID() 933 defer sbox.Delete() 934 935 jl := endpointJoin{SandboxID: sid} 936 jlb, err := json.Marshal(jl) 937 if err != nil { 938 t.Fatal(err) 939 } 940 941 _, errRsp = procAttachBackend(c, vars, jlb) 942 if errRsp != &successResponse { 943 t.Fatalf("Unexpected failure, got: %v", errRsp) 944 } 945 946 sli, errRsp := procGetSandboxes(c, vars, nil) 947 if errRsp != &successResponse { 948 t.Fatalf("Unexpected failure, got: %v", errRsp) 949 } 950 sl := i2sbL(sli) 951 if len(sl) != 1 { 952 t.Fatalf("Did not find expected number of sandboxes attached to the service: %d", len(sl)) 953 } 954 if sl[0].ContainerID != cid { 955 t.Fatalf("Did not find expected sandbox attached to the service: %v", sl[0]) 956 } 957 958 _, errRsp = procUnpublishService(c, vars, nil) 959 if errRsp.isOK() { 960 t.Fatal("Expected failure but succeeded") 961 } 962 if errRsp.StatusCode != http.StatusForbidden { 963 t.Fatalf("Expected %d. Got: %v", http.StatusForbidden, errRsp) 964 } 965 966 vars[urlEpName] = "endpoint" 967 _, errRsp = procDetachBackend(c, vars, nil) 968 if errRsp == &successResponse { 969 t.Fatalf("Expected failure, got: %v", errRsp) 970 } 971 if errRsp.StatusCode != http.StatusNotFound { 972 t.Fatalf("Expected %d. Got: %v", http.StatusNotFound, errRsp) 973 } 974 975 vars[urlEpName] = "db" 976 _, errRsp = procDetachBackend(c, vars, nil) 977 if errRsp == &successResponse { 978 t.Fatalf("Expected failure, got: %v", errRsp) 979 } 980 if errRsp.StatusCode != http.StatusBadRequest { 981 t.Fatalf("Expected %d. Got: %v", http.StatusBadRequest, errRsp) 982 } 983 984 vars[urlSbID] = sid 985 _, errRsp = procDetachBackend(c, vars, nil) 986 if errRsp != &successResponse { 987 t.Fatalf("Unexpected failure, got: %v", errRsp) 988 } 989 990 delete(vars, urlEpID) 991 si, errRsp := procGetSandbox(c, vars, nil) 992 if errRsp != &successResponse { 993 t.Fatalf("Unexpected failure, got: %v", errRsp) 994 } 995 sb := i2sb(si) 996 if sb.ContainerID != cid { 997 t.Fatalf("Did not find expected sandbox. Got %v", sb) 998 } 999 1000 err = ep1.Delete(false) 1001 if err != nil { 1002 t.Fatal(err) 1003 } 1004 } 1005 1006 func TestDetectGetNetworksInvalidQueryComposition(t *testing.T) { 1007 // Cleanup local datastore file 1008 os.Remove(datastore.DefaultScopes("")[datastore.LocalScope].Client.Address) 1009 1010 c, err := libnetwork.New() 1011 if err != nil { 1012 t.Fatal(err) 1013 } 1014 defer c.Stop() 1015 1016 vars := map[string]string{urlNwName: "x", urlNwPID: "y"} 1017 _, errRsp := procGetNetworks(c, vars, nil) 1018 if errRsp.StatusCode != http.StatusBadRequest { 1019 t.Fatalf("Expected %d. Got: %v", http.StatusBadRequest, errRsp) 1020 } 1021 } 1022 1023 func TestDetectGetEndpointsInvalidQueryComposition(t *testing.T) { 1024 defer testutils.SetupTestOSContext(t)() 1025 1026 c, _ := createTestNetwork(t, "network") 1027 defer c.Stop() 1028 1029 vars := map[string]string{urlNwName: "network", urlEpName: "x", urlEpPID: "y"} 1030 _, errRsp := procGetEndpoints(c, vars, nil) 1031 if errRsp.StatusCode != http.StatusBadRequest { 1032 t.Fatalf("Expected %d. Got: %v", http.StatusBadRequest, errRsp) 1033 } 1034 } 1035 1036 func TestDetectGetServicesInvalidQueryComposition(t *testing.T) { 1037 defer testutils.SetupTestOSContext(t)() 1038 1039 c, _ := createTestNetwork(t, "network") 1040 defer c.Stop() 1041 1042 vars := map[string]string{urlNwName: "network", urlEpName: "x", urlEpPID: "y"} 1043 _, errRsp := procGetServices(c, vars, nil) 1044 if errRsp.StatusCode != http.StatusBadRequest { 1045 t.Fatalf("Expected %d. Got: %v", http.StatusBadRequest, errRsp) 1046 } 1047 } 1048 1049 func TestFindNetworkUtilPanic(t *testing.T) { 1050 defer checkPanic(t) 1051 findNetwork(nil, "", -1) 1052 } 1053 1054 func TestFindNetworkUtil(t *testing.T) { 1055 defer testutils.SetupTestOSContext(t)() 1056 1057 c, nw := createTestNetwork(t, "network") 1058 defer c.Stop() 1059 1060 nid := nw.ID() 1061 1062 _, errRsp := findNetwork(c, "", byName) 1063 if errRsp == &successResponse { 1064 t.Fatal("Expected to fail but succeeded") 1065 } 1066 if errRsp.StatusCode != http.StatusBadRequest { 1067 t.Fatalf("Expected %d, but got: %d", http.StatusBadRequest, errRsp.StatusCode) 1068 } 1069 1070 n, errRsp := findNetwork(c, nid, byID) 1071 if errRsp != &successResponse { 1072 t.Fatalf("Unexpected failure: %v", errRsp) 1073 } 1074 if n == nil { 1075 t.Fatal("Unexpected nil libnetwork.Network") 1076 } 1077 if nid != n.ID() { 1078 t.Fatalf("Incorrect libnetwork.Network resource. It has different id: %v", n) 1079 } 1080 if "network" != n.Name() { 1081 t.Fatalf("Incorrect libnetwork.Network resource. It has different name: %v", n) 1082 } 1083 1084 n, errRsp = findNetwork(c, "network", byName) 1085 if errRsp != &successResponse { 1086 t.Fatalf("Unexpected failure: %v", errRsp) 1087 } 1088 if n == nil { 1089 t.Fatal("Unexpected nil libnetwork.Network") 1090 } 1091 if nid != n.ID() { 1092 t.Fatalf("Incorrect libnetwork.Network resource. It has different id: %v", n) 1093 } 1094 if "network" != n.Name() { 1095 t.Fatalf("Incorrect libnetwork.Network resource. It has different name: %v", n) 1096 } 1097 1098 if err := n.Delete(); err != nil { 1099 t.Fatalf("Failed to delete the network: %s", err.Error()) 1100 } 1101 1102 _, errRsp = findNetwork(c, nid, byID) 1103 if errRsp == &successResponse { 1104 t.Fatal("Expected to fail but succeeded") 1105 } 1106 if errRsp.StatusCode != http.StatusNotFound { 1107 t.Fatalf("Expected %d, but got: %d", http.StatusNotFound, errRsp.StatusCode) 1108 } 1109 1110 _, errRsp = findNetwork(c, "network", byName) 1111 if errRsp == &successResponse { 1112 t.Fatal("Expected to fail but succeeded") 1113 } 1114 if errRsp.StatusCode != http.StatusNotFound { 1115 t.Fatalf("Expected %d, but got: %d", http.StatusNotFound, errRsp.StatusCode) 1116 } 1117 } 1118 1119 func TestCreateDeleteEndpoints(t *testing.T) { 1120 defer testutils.SetupTestOSContext(t)() 1121 1122 // Cleanup local datastore file 1123 os.Remove(datastore.DefaultScopes("")[datastore.LocalScope].Client.Address) 1124 1125 c, err := libnetwork.New() 1126 if err != nil { 1127 t.Fatal(err) 1128 } 1129 defer c.Stop() 1130 1131 nc := networkCreate{Name: "firstNet", NetworkType: bridgeNetType} 1132 body, err := json.Marshal(nc) 1133 if err != nil { 1134 t.Fatal(err) 1135 } 1136 1137 vars := make(map[string]string) 1138 i, errRsp := procCreateNetwork(c, vars, body) 1139 if errRsp != &createdResponse { 1140 t.Fatalf("Unexpected failure: %v", errRsp) 1141 } 1142 nid := i2s(i) 1143 1144 vbad, err := json.Marshal("bad endpoint create data") 1145 if err != nil { 1146 t.Fatal(err) 1147 } 1148 1149 vars[urlNwName] = "firstNet" 1150 _, errRsp = procCreateEndpoint(c, vars, vbad) 1151 if errRsp == &createdResponse { 1152 t.Fatal("Expected to fail but succeeded") 1153 } 1154 1155 b, err := json.Marshal(endpointCreate{Name: ""}) 1156 if err != nil { 1157 t.Fatal(err) 1158 } 1159 1160 vars[urlNwName] = "secondNet" 1161 _, errRsp = procCreateEndpoint(c, vars, b) 1162 if errRsp == &createdResponse { 1163 t.Fatal("Expected to fail but succeeded") 1164 } 1165 1166 vars[urlNwName] = "firstNet" 1167 _, errRsp = procCreateEndpoint(c, vars, b) 1168 if errRsp == &successResponse { 1169 t.Fatalf("Expected failure but succeeded: %v", errRsp) 1170 } 1171 1172 b, err = json.Marshal(endpointCreate{Name: "firstEp"}) 1173 if err != nil { 1174 t.Fatal(err) 1175 } 1176 1177 i, errRsp = procCreateEndpoint(c, vars, b) 1178 if errRsp != &createdResponse { 1179 t.Fatalf("Unexpected failure: %v", errRsp) 1180 } 1181 eid := i2s(i) 1182 1183 _, errRsp = findEndpoint(c, "myNet", "firstEp", byName, byName) 1184 if errRsp == &successResponse { 1185 t.Fatalf("Expected failure but succeeded: %v", errRsp) 1186 } 1187 1188 ep0, errRsp := findEndpoint(c, nid, "firstEp", byID, byName) 1189 if errRsp != &successResponse { 1190 t.Fatalf("Unexpected failure: %v", errRsp) 1191 } 1192 1193 ep1, errRsp := findEndpoint(c, "firstNet", "firstEp", byName, byName) 1194 if errRsp != &successResponse { 1195 t.Fatalf("Unexpected failure: %v", errRsp) 1196 } 1197 1198 ep2, errRsp := findEndpoint(c, nid, eid, byID, byID) 1199 if errRsp != &successResponse { 1200 t.Fatalf("Unexpected failure: %v", errRsp) 1201 } 1202 1203 ep3, errRsp := findEndpoint(c, "firstNet", eid, byName, byID) 1204 if errRsp != &successResponse { 1205 t.Fatalf("Unexpected failure: %v", errRsp) 1206 } 1207 1208 if ep0.ID() != ep1.ID() || ep0.ID() != ep2.ID() || ep0.ID() != ep3.ID() { 1209 t.Fatalf("Different queries returned different endpoints: \nep0: %v\nep1: %v\nep2: %v\nep3: %v", ep0, ep1, ep2, ep3) 1210 } 1211 1212 vars = make(map[string]string) 1213 vars[urlNwName] = "" 1214 vars[urlEpName] = "ep1" 1215 _, errRsp = procDeleteEndpoint(c, vars, nil) 1216 if errRsp == &successResponse { 1217 t.Fatalf("Expected failure, got: %v", errRsp) 1218 } 1219 1220 vars[urlNwName] = "firstNet" 1221 vars[urlEpName] = "" 1222 _, errRsp = procDeleteEndpoint(c, vars, nil) 1223 if errRsp == &successResponse { 1224 t.Fatalf("Expected failure, got: %v", errRsp) 1225 } 1226 1227 vars[urlEpName] = "ep2" 1228 _, errRsp = procDeleteEndpoint(c, vars, nil) 1229 if errRsp == &successResponse { 1230 t.Fatalf("Expected failure, got: %v", errRsp) 1231 } 1232 1233 vars[urlEpName] = "firstEp" 1234 _, errRsp = procDeleteEndpoint(c, vars, nil) 1235 if errRsp != &successResponse { 1236 t.Fatalf("Unexpected failure: %v", errRsp) 1237 } 1238 1239 _, errRsp = findEndpoint(c, "firstNet", "firstEp", byName, byName) 1240 if errRsp == &successResponse { 1241 t.Fatalf("Expected failure, got: %v", errRsp) 1242 } 1243 } 1244 1245 func TestJoinLeave(t *testing.T) { 1246 if runtime.GOARCH == "arm64" { 1247 t.Skip("This test fails on arm64 foor some reason... this need to be fixed") 1248 } 1249 defer testutils.SetupTestOSContext(t)() 1250 1251 // Cleanup local datastore file 1252 os.Remove(datastore.DefaultScopes("")[datastore.LocalScope].Client.Address) 1253 1254 c, err := libnetwork.New() 1255 if err != nil { 1256 t.Fatal(err) 1257 } 1258 defer c.Stop() 1259 1260 nb, err := json.Marshal(networkCreate{Name: "network", NetworkType: bridgeNetType}) 1261 if err != nil { 1262 t.Fatal(err) 1263 } 1264 vars := make(map[string]string) 1265 _, errRsp := procCreateNetwork(c, vars, nb) 1266 if errRsp != &createdResponse { 1267 t.Fatalf("Unexpected failure: %v", errRsp) 1268 } 1269 1270 eb, err := json.Marshal(endpointCreate{Name: "endpoint"}) 1271 if err != nil { 1272 t.Fatal(err) 1273 } 1274 vars[urlNwName] = "network" 1275 _, errRsp = procCreateEndpoint(c, vars, eb) 1276 if errRsp != &createdResponse { 1277 t.Fatalf("Unexpected failure: %v", errRsp) 1278 } 1279 1280 vbad, err := json.Marshal("bad data") 1281 if err != nil { 1282 t.Fatal(err) 1283 } 1284 _, errRsp = procJoinEndpoint(c, vars, vbad) 1285 if errRsp == &successResponse { 1286 t.Fatalf("Expected failure, got: %v", errRsp) 1287 } 1288 1289 vars[urlEpName] = "endpoint" 1290 bad, err := json.Marshal(endpointJoin{}) 1291 if err != nil { 1292 t.Fatal(err) 1293 } 1294 _, errRsp = procJoinEndpoint(c, vars, bad) 1295 if errRsp == &successResponse { 1296 t.Fatalf("Expected failure, got: %v", errRsp) 1297 } 1298 1299 cid := "abcdefghi" 1300 sb, err := c.NewSandbox(cid) 1301 if err != nil { 1302 t.Fatal(err) 1303 } 1304 defer sb.Delete() 1305 1306 jl := endpointJoin{SandboxID: sb.ID()} 1307 jlb, err := json.Marshal(jl) 1308 if err != nil { 1309 t.Fatal(err) 1310 } 1311 1312 vars = make(map[string]string) 1313 vars[urlNwName] = "" 1314 vars[urlEpName] = "" 1315 _, errRsp = procJoinEndpoint(c, vars, jlb) 1316 if errRsp == &successResponse { 1317 t.Fatalf("Expected failure, got: %v", errRsp) 1318 } 1319 1320 vars[urlNwName] = "network" 1321 vars[urlEpName] = "" 1322 _, errRsp = procJoinEndpoint(c, vars, jlb) 1323 if errRsp == &successResponse { 1324 t.Fatalf("Expected failure, got: %v", errRsp) 1325 } 1326 1327 vars[urlEpName] = "epoint" 1328 _, errRsp = procJoinEndpoint(c, vars, jlb) 1329 if errRsp == &successResponse { 1330 t.Fatalf("Expected failure, got: %v", errRsp) 1331 } 1332 1333 // bad labels 1334 vars[urlEpName] = "endpoint" 1335 key, errRsp := procJoinEndpoint(c, vars, jlb) 1336 if errRsp != &successResponse { 1337 t.Fatalf("Unexpected failure, got: %v", errRsp) 1338 } 1339 1340 keyStr := i2s(key) 1341 if keyStr == "" { 1342 t.Fatal("Empty sandbox key") 1343 } 1344 _, errRsp = procDeleteEndpoint(c, vars, nil) 1345 if errRsp == &successResponse { 1346 t.Fatalf("Expected failure, got: %v", errRsp) 1347 } 1348 1349 vars[urlNwName] = "network2" 1350 _, errRsp = procLeaveEndpoint(c, vars, vbad) 1351 if errRsp == &successResponse { 1352 t.Fatalf("Expected failure, got: %v", errRsp) 1353 } 1354 _, errRsp = procLeaveEndpoint(c, vars, bad) 1355 if errRsp == &successResponse { 1356 t.Fatalf("Expected failure, got: %v", errRsp) 1357 } 1358 _, errRsp = procLeaveEndpoint(c, vars, jlb) 1359 if errRsp == &successResponse { 1360 t.Fatalf("Expected failure, got: %v", errRsp) 1361 } 1362 vars = make(map[string]string) 1363 vars[urlNwName] = "" 1364 vars[urlEpName] = "" 1365 _, errRsp = procLeaveEndpoint(c, vars, jlb) 1366 if errRsp == &successResponse { 1367 t.Fatalf("Expected failure, got: %v", errRsp) 1368 } 1369 vars[urlNwName] = "network" 1370 vars[urlEpName] = "" 1371 _, errRsp = procLeaveEndpoint(c, vars, jlb) 1372 if errRsp == &successResponse { 1373 t.Fatalf("Expected failure, got: %v", errRsp) 1374 } 1375 vars[urlEpName] = "2epoint" 1376 _, errRsp = procLeaveEndpoint(c, vars, jlb) 1377 if errRsp == &successResponse { 1378 t.Fatalf("Expected failure, got: %v", errRsp) 1379 } 1380 vars[urlEpName] = "epoint" 1381 vars[urlCnID] = "who" 1382 _, errRsp = procLeaveEndpoint(c, vars, jlb) 1383 if errRsp == &successResponse { 1384 t.Fatalf("Expected failure, got: %v", errRsp) 1385 } 1386 1387 delete(vars, urlCnID) 1388 vars[urlEpName] = "endpoint" 1389 _, errRsp = procLeaveEndpoint(c, vars, jlb) 1390 if errRsp == &successResponse { 1391 t.Fatalf("Expected failure, got: %v", errRsp) 1392 } 1393 1394 vars[urlSbID] = sb.ID() 1395 _, errRsp = procLeaveEndpoint(c, vars, jlb) 1396 if errRsp != &successResponse { 1397 t.Fatalf("Unexpected failure: %v", errRsp) 1398 } 1399 1400 _, errRsp = procLeaveEndpoint(c, vars, jlb) 1401 if errRsp == &successResponse { 1402 t.Fatalf("Expected failure, got: %v", errRsp) 1403 } 1404 1405 _, errRsp = procDeleteEndpoint(c, vars, nil) 1406 if errRsp != &successResponse { 1407 t.Fatalf("Unexpected failure: %v", errRsp) 1408 } 1409 } 1410 1411 func TestFindEndpointUtilPanic(t *testing.T) { 1412 defer testutils.SetupTestOSContext(t)() 1413 defer checkPanic(t) 1414 c, nw := createTestNetwork(t, "network") 1415 defer c.Stop() 1416 1417 nid := nw.ID() 1418 findEndpoint(c, nid, "", byID, -1) 1419 } 1420 1421 func TestFindServiceUtilPanic(t *testing.T) { 1422 defer testutils.SetupTestOSContext(t)() 1423 defer checkPanic(t) 1424 c, _ := createTestNetwork(t, "network") 1425 defer c.Stop() 1426 1427 findService(c, "random_service", -1) 1428 } 1429 1430 func TestFindEndpointUtil(t *testing.T) { 1431 defer testutils.SetupTestOSContext(t)() 1432 1433 c, nw := createTestNetwork(t, "network") 1434 defer c.Stop() 1435 1436 nid := nw.ID() 1437 1438 ep, err := nw.CreateEndpoint("secondEp", nil) 1439 if err != nil { 1440 t.Fatal(err) 1441 } 1442 eid := ep.ID() 1443 1444 _, errRsp := findEndpoint(c, nid, "", byID, byName) 1445 if errRsp == &successResponse { 1446 t.Fatalf("Expected failure, but got: %v", errRsp) 1447 } 1448 if errRsp.StatusCode != http.StatusBadRequest { 1449 t.Fatalf("Expected %d, but got: %d", http.StatusBadRequest, errRsp.StatusCode) 1450 } 1451 1452 ep0, errRsp := findEndpoint(c, nid, "secondEp", byID, byName) 1453 if errRsp != &successResponse { 1454 t.Fatalf("Unexpected failure: %v", errRsp) 1455 } 1456 1457 ep1, errRsp := findEndpoint(c, "network", "secondEp", byName, byName) 1458 if errRsp != &successResponse { 1459 t.Fatalf("Unexpected failure: %v", errRsp) 1460 } 1461 1462 ep2, errRsp := findEndpoint(c, nid, eid, byID, byID) 1463 if errRsp != &successResponse { 1464 t.Fatalf("Unexpected failure: %v", errRsp) 1465 } 1466 1467 ep3, errRsp := findEndpoint(c, "network", eid, byName, byID) 1468 if errRsp != &successResponse { 1469 t.Fatalf("Unexpected failure: %v", errRsp) 1470 } 1471 1472 ep4, errRsp := findService(c, "secondEp", byName) 1473 if errRsp != &successResponse { 1474 t.Fatalf("Unexpected failure: %v", errRsp) 1475 } 1476 1477 ep5, errRsp := findService(c, eid, byID) 1478 if errRsp != &successResponse { 1479 t.Fatalf("Unexpected failure: %v", errRsp) 1480 } 1481 1482 if ep0.ID() != ep1.ID() || ep0.ID() != ep2.ID() || 1483 ep0.ID() != ep3.ID() || ep0.ID() != ep4.ID() || ep0.ID() != ep5.ID() { 1484 t.Fatal("Different queries returned different endpoints") 1485 } 1486 1487 ep.Delete(false) 1488 1489 _, errRsp = findEndpoint(c, nid, "secondEp", byID, byName) 1490 if errRsp == &successResponse { 1491 t.Fatalf("Expected failure, but got: %v", errRsp) 1492 } 1493 if errRsp.StatusCode != http.StatusNotFound { 1494 t.Fatalf("Expected %d, but got: %d", http.StatusNotFound, errRsp.StatusCode) 1495 } 1496 1497 _, errRsp = findEndpoint(c, "network", "secondEp", byName, byName) 1498 if errRsp == &successResponse { 1499 t.Fatalf("Expected failure, but got: %v", errRsp) 1500 } 1501 if errRsp.StatusCode != http.StatusNotFound { 1502 t.Fatalf("Expected %d, but got: %d", http.StatusNotFound, errRsp.StatusCode) 1503 } 1504 1505 _, errRsp = findEndpoint(c, nid, eid, byID, byID) 1506 if errRsp == &successResponse { 1507 t.Fatalf("Expected failure, but got: %v", errRsp) 1508 } 1509 if errRsp.StatusCode != http.StatusNotFound { 1510 t.Fatalf("Expected %d, but got: %d", http.StatusNotFound, errRsp.StatusCode) 1511 } 1512 1513 _, errRsp = findEndpoint(c, "network", eid, byName, byID) 1514 if errRsp == &successResponse { 1515 t.Fatalf("Expected failure, but got: %v", errRsp) 1516 } 1517 if errRsp.StatusCode != http.StatusNotFound { 1518 t.Fatalf("Expected %d, but got: %d", http.StatusNotFound, errRsp.StatusCode) 1519 } 1520 1521 _, errRsp = findService(c, "secondEp", byName) 1522 if errRsp == &successResponse { 1523 t.Fatalf("Expected failure, but got: %v", errRsp) 1524 } 1525 if errRsp.StatusCode != http.StatusNotFound { 1526 t.Fatalf("Expected %d, but got: %d", http.StatusNotFound, errRsp.StatusCode) 1527 } 1528 1529 _, errRsp = findService(c, eid, byID) 1530 if errRsp == &successResponse { 1531 t.Fatalf("Expected failure, but got: %v", errRsp) 1532 } 1533 if errRsp.StatusCode != http.StatusNotFound { 1534 t.Fatalf("Expected %d, but got: %d", http.StatusNotFound, errRsp.StatusCode) 1535 } 1536 } 1537 1538 func TestEndpointToService(t *testing.T) { 1539 r := &responseStatus{Status: "this is one endpoint", StatusCode: http.StatusOK} 1540 r = endpointToService(r) 1541 if r.Status != "this is one service" { 1542 t.Fatalf("endpointToService returned unexpected status string: %s", r.Status) 1543 } 1544 1545 r = &responseStatus{Status: "this is one network", StatusCode: http.StatusOK} 1546 r = endpointToService(r) 1547 if r.Status != "this is one network" { 1548 t.Fatalf("endpointToService returned unexpected status string: %s", r.Status) 1549 } 1550 } 1551 1552 func checkPanic(t *testing.T) { 1553 if r := recover(); r != nil { 1554 if _, ok := r.(runtime.Error); ok { 1555 panic(r) 1556 } 1557 } else { 1558 t.Fatal("Expected to panic, but succeeded") 1559 } 1560 } 1561 1562 func TestDetectNetworkTargetPanic(t *testing.T) { 1563 defer checkPanic(t) 1564 vars := make(map[string]string) 1565 detectNetworkTarget(vars) 1566 } 1567 1568 func TestDetectEndpointTargetPanic(t *testing.T) { 1569 defer checkPanic(t) 1570 vars := make(map[string]string) 1571 detectEndpointTarget(vars) 1572 } 1573 1574 func TestResponseStatus(t *testing.T) { 1575 list := []int{ 1576 http.StatusBadGateway, 1577 http.StatusBadRequest, 1578 http.StatusConflict, 1579 http.StatusContinue, 1580 http.StatusExpectationFailed, 1581 http.StatusForbidden, 1582 http.StatusFound, 1583 http.StatusGatewayTimeout, 1584 http.StatusGone, 1585 http.StatusHTTPVersionNotSupported, 1586 http.StatusInternalServerError, 1587 http.StatusLengthRequired, 1588 http.StatusMethodNotAllowed, 1589 http.StatusMovedPermanently, 1590 http.StatusMultipleChoices, 1591 http.StatusNoContent, 1592 http.StatusNonAuthoritativeInfo, 1593 http.StatusNotAcceptable, 1594 http.StatusNotFound, 1595 http.StatusNotModified, 1596 http.StatusPartialContent, 1597 http.StatusPaymentRequired, 1598 http.StatusPreconditionFailed, 1599 http.StatusProxyAuthRequired, 1600 http.StatusRequestEntityTooLarge, 1601 http.StatusRequestTimeout, 1602 http.StatusRequestURITooLong, 1603 http.StatusRequestedRangeNotSatisfiable, 1604 http.StatusResetContent, 1605 http.StatusServiceUnavailable, 1606 http.StatusSwitchingProtocols, 1607 http.StatusTemporaryRedirect, 1608 http.StatusUnauthorized, 1609 http.StatusUnsupportedMediaType, 1610 http.StatusUseProxy, 1611 } 1612 for _, c := range list { 1613 r := responseStatus{StatusCode: c} 1614 if r.isOK() { 1615 t.Fatalf("isOK() returned true for code% d", c) 1616 } 1617 } 1618 1619 r := responseStatus{StatusCode: http.StatusOK} 1620 if !r.isOK() { 1621 t.Fatal("isOK() failed") 1622 } 1623 1624 r = responseStatus{StatusCode: http.StatusCreated} 1625 if !r.isOK() { 1626 t.Fatal("isOK() failed") 1627 } 1628 } 1629 1630 // Local structs for end to end testing of api.go 1631 type localReader struct { 1632 data []byte 1633 beBad bool 1634 } 1635 1636 func newLocalReader(data []byte) *localReader { 1637 lr := &localReader{data: make([]byte, len(data))} 1638 copy(lr.data, data) 1639 return lr 1640 } 1641 1642 func (l *localReader) Read(p []byte) (n int, err error) { 1643 if l.beBad { 1644 return 0, errors.New("I am a bad reader") 1645 } 1646 if p == nil { 1647 return -1, errors.New("nil buffer passed") 1648 } 1649 if l.data == nil || len(l.data) == 0 { 1650 return 0, io.EOF 1651 } 1652 copy(p[:], l.data[:]) 1653 return len(l.data), io.EOF 1654 } 1655 1656 type localResponseWriter struct { 1657 body []byte 1658 statusCode int 1659 } 1660 1661 func newWriter() *localResponseWriter { 1662 return &localResponseWriter{} 1663 } 1664 1665 func (f *localResponseWriter) Header() http.Header { 1666 return make(map[string][]string) 1667 } 1668 1669 func (f *localResponseWriter) Write(data []byte) (int, error) { 1670 if data == nil { 1671 return -1, errors.New("nil data passed") 1672 } 1673 1674 f.body = make([]byte, len(data)) 1675 copy(f.body, data) 1676 1677 return len(f.body), nil 1678 } 1679 1680 func (f *localResponseWriter) WriteHeader(c int) { 1681 f.statusCode = c 1682 } 1683 1684 func testWriteJSON(t *testing.T, testCode int, testData interface{}) { 1685 testDataMarshalled, err := json.Marshal(testData) 1686 if err != nil { 1687 t.Fatal(err) 1688 } 1689 1690 rsp := newWriter() 1691 writeJSON(rsp, testCode, testData) 1692 if rsp.statusCode != testCode { 1693 t.Fatalf("writeJSON() failed to set the status code. Expected %d. Got %d", testCode, rsp.statusCode) 1694 } 1695 // writeJSON calls json.Encode and it appends '\n' to the result, 1696 // while json.Marshal not 1697 expected := append(testDataMarshalled, byte('\n')) 1698 if !bytes.Equal(expected, rsp.body) { 1699 t.Fatalf("writeJSON() failed to set the body. Expected %q. Got %q", expected, rsp.body) 1700 } 1701 } 1702 1703 func TestWriteJSON(t *testing.T) { 1704 testWriteJSON(t, 55, "test data as string") 1705 testWriteJSON(t, 55, []byte("test data as bytes")) 1706 } 1707 1708 func TestHttpHandlerUninit(t *testing.T) { 1709 defer testutils.SetupTestOSContext(t)() 1710 1711 // Cleanup local datastore file 1712 os.Remove(datastore.DefaultScopes("")[datastore.LocalScope].Client.Address) 1713 1714 c, err := libnetwork.New() 1715 if err != nil { 1716 t.Fatal(err) 1717 } 1718 defer c.Stop() 1719 1720 h := &httpHandler{c: c} 1721 h.initRouter() 1722 if h.r == nil { 1723 t.Fatal("initRouter() did not initialize the router") 1724 } 1725 1726 rsp := newWriter() 1727 req, err := http.NewRequest("GET", "/v1.19/networks", nil) 1728 if err != nil { 1729 t.Fatal(err) 1730 } 1731 1732 handleRequest := NewHTTPHandler(nil) 1733 handleRequest(rsp, req) 1734 if rsp.statusCode != http.StatusServiceUnavailable { 1735 t.Fatalf("Expected (%d). Got (%d): %s", http.StatusServiceUnavailable, rsp.statusCode, rsp.body) 1736 } 1737 1738 handleRequest = NewHTTPHandler(c) 1739 1740 handleRequest(rsp, req) 1741 if rsp.statusCode != http.StatusOK { 1742 t.Fatalf("Expected (%d). Got: (%d): %s", http.StatusOK, rsp.statusCode, rsp.body) 1743 } 1744 1745 var list []*networkResource 1746 err = json.Unmarshal(rsp.body, &list) 1747 if err != nil { 1748 t.Fatal(err) 1749 } 1750 if len(list) != 0 { 1751 t.Fatalf("Expected empty list. Got %v", list) 1752 } 1753 1754 n, err := c.NewNetwork(bridgeNetType, "didietro", "", nil) 1755 if err != nil { 1756 t.Fatal(err) 1757 } 1758 nwr := buildNetworkResource(n) 1759 expected, err := json.Marshal([]*networkResource{nwr}) 1760 if err != nil { 1761 t.Fatal(err) 1762 } 1763 1764 handleRequest(rsp, req) 1765 if rsp.statusCode != http.StatusOK { 1766 t.Fatalf("Unexpected failure: (%d): %s", rsp.statusCode, rsp.body) 1767 } 1768 if len(rsp.body) == 0 { 1769 t.Fatal("Empty list of networks") 1770 } 1771 if bytes.Equal(rsp.body, expected) { 1772 t.Fatal("Incorrect list of networks in response's body") 1773 } 1774 } 1775 1776 func TestHttpHandlerBadBody(t *testing.T) { 1777 defer testutils.SetupTestOSContext(t)() 1778 1779 rsp := newWriter() 1780 1781 // Cleanup local datastore file 1782 os.Remove(datastore.DefaultScopes("")[datastore.LocalScope].Client.Address) 1783 1784 c, err := libnetwork.New() 1785 if err != nil { 1786 t.Fatal(err) 1787 } 1788 defer c.Stop() 1789 handleRequest := NewHTTPHandler(c) 1790 1791 req, err := http.NewRequest("POST", "/v1.19/networks", &localReader{beBad: true}) 1792 if err != nil { 1793 t.Fatal(err) 1794 } 1795 handleRequest(rsp, req) 1796 if rsp.statusCode != http.StatusBadRequest { 1797 t.Fatalf("Unexpected status code. Expected (%d). Got (%d): %s.", http.StatusBadRequest, rsp.statusCode, string(rsp.body)) 1798 } 1799 1800 body := []byte{} 1801 lr := newLocalReader(body) 1802 req, err = http.NewRequest("POST", "/v1.19/networks", lr) 1803 if err != nil { 1804 t.Fatal(err) 1805 } 1806 handleRequest(rsp, req) 1807 if rsp.statusCode != http.StatusBadRequest { 1808 t.Fatalf("Unexpected status code. Expected (%d). Got (%d): %s.", http.StatusBadRequest, rsp.statusCode, string(rsp.body)) 1809 } 1810 } 1811 1812 func TestEndToEnd(t *testing.T) { 1813 defer testutils.SetupTestOSContext(t)() 1814 1815 rsp := newWriter() 1816 1817 // Cleanup local datastore file 1818 os.Remove(datastore.DefaultScopes("")[datastore.LocalScope].Client.Address) 1819 1820 c, err := libnetwork.New() 1821 if err != nil { 1822 t.Fatal(err) 1823 } 1824 defer c.Stop() 1825 1826 handleRequest := NewHTTPHandler(c) 1827 1828 dops := GetOpsMap("cdef", "1460") 1829 nops := map[string]string{} 1830 1831 // Create network 1832 nc := networkCreate{Name: "network-fiftyfive", NetworkType: bridgeNetType, DriverOpts: dops, NetworkOpts: nops} 1833 body, err := json.Marshal(nc) 1834 if err != nil { 1835 t.Fatal(err) 1836 } 1837 lr := newLocalReader(body) 1838 req, err := http.NewRequest("POST", "/v1.19/networks", lr) 1839 if err != nil { 1840 t.Fatal(err) 1841 } 1842 handleRequest(rsp, req) 1843 if rsp.statusCode != http.StatusCreated { 1844 t.Fatalf("Unexpected status code. Expected (%d). Got (%d): %s.", http.StatusCreated, rsp.statusCode, string(rsp.body)) 1845 } 1846 if len(rsp.body) == 0 { 1847 t.Fatal("Empty response body") 1848 } 1849 1850 var nid string 1851 err = json.Unmarshal(rsp.body, &nid) 1852 if err != nil { 1853 t.Fatal(err) 1854 } 1855 1856 // Query networks collection 1857 req, err = http.NewRequest("GET", "/v1.19/networks?name=", nil) 1858 if err != nil { 1859 t.Fatal(err) 1860 } 1861 handleRequest(rsp, req) 1862 if rsp.statusCode != http.StatusOK { 1863 t.Fatalf("Expected StatusOK. Got (%d): %s", rsp.statusCode, rsp.body) 1864 } 1865 var list []*networkResource 1866 err = json.Unmarshal(rsp.body, &list) 1867 if err != nil { 1868 t.Fatal(err) 1869 } 1870 if len(list) != 0 { 1871 t.Fatalf("Expected empty list. Got %v", list) 1872 } 1873 1874 req, err = http.NewRequest("GET", "/v1.19/networks", nil) 1875 if err != nil { 1876 t.Fatal(err) 1877 } 1878 handleRequest(rsp, req) 1879 if rsp.statusCode != http.StatusOK { 1880 t.Fatalf("Expected StatusOK. Got (%d): %s", rsp.statusCode, rsp.body) 1881 } 1882 1883 b0 := make([]byte, len(rsp.body)) 1884 copy(b0, rsp.body) 1885 1886 req, err = http.NewRequest("GET", "/v1.19/networks?name=network-fiftyfive", nil) 1887 if err != nil { 1888 t.Fatal(err) 1889 } 1890 handleRequest(rsp, req) 1891 if rsp.statusCode != http.StatusOK { 1892 t.Fatalf("Expected StatusOK. Got (%d): %s", rsp.statusCode, rsp.body) 1893 } 1894 1895 if !bytes.Equal(b0, rsp.body) { 1896 t.Fatal("Expected same body from GET /networks and GET /networks?name=<nw> when only network <nw> exist.") 1897 } 1898 1899 // Query network by name 1900 req, err = http.NewRequest("GET", "/v1.19/networks?name=culo", nil) 1901 if err != nil { 1902 t.Fatal(err) 1903 } 1904 handleRequest(rsp, req) 1905 if rsp.statusCode != http.StatusOK { 1906 t.Fatalf("Expected StatusOK. Got (%d): %s", rsp.statusCode, rsp.body) 1907 } 1908 1909 err = json.Unmarshal(rsp.body, &list) 1910 if err != nil { 1911 t.Fatal(err) 1912 } 1913 if len(list) != 0 { 1914 t.Fatalf("Expected empty list. Got %v", list) 1915 } 1916 1917 req, err = http.NewRequest("GET", "/v1.19/networks?name=network-fiftyfive", nil) 1918 if err != nil { 1919 t.Fatal(err) 1920 } 1921 handleRequest(rsp, req) 1922 if rsp.statusCode != http.StatusOK { 1923 t.Fatalf("Unexpected failure: (%d): %s", rsp.statusCode, rsp.body) 1924 } 1925 1926 err = json.Unmarshal(rsp.body, &list) 1927 if err != nil { 1928 t.Fatal(err) 1929 } 1930 if len(list) == 0 { 1931 t.Fatal("Expected non empty list") 1932 } 1933 if list[0].Name != "network-fiftyfive" || nid != list[0].ID { 1934 t.Fatalf("Incongruent resource found: %v", list[0]) 1935 } 1936 1937 // Query network by partial id 1938 chars := []byte(nid) 1939 partial := string(chars[0 : len(chars)/2]) 1940 req, err = http.NewRequest("GET", "/v1.19/networks?partial-id="+partial, nil) 1941 if err != nil { 1942 t.Fatal(err) 1943 } 1944 handleRequest(rsp, req) 1945 if rsp.statusCode != http.StatusOK { 1946 t.Fatalf("Unexpected failure: (%d): %s", rsp.statusCode, rsp.body) 1947 } 1948 1949 err = json.Unmarshal(rsp.body, &list) 1950 if err != nil { 1951 t.Fatal(err) 1952 } 1953 if len(list) == 0 { 1954 t.Fatal("Expected non empty list") 1955 } 1956 if list[0].Name != "network-fiftyfive" || nid != list[0].ID { 1957 t.Fatalf("Incongruent resource found: %v", list[0]) 1958 } 1959 1960 // Get network by id 1961 req, err = http.NewRequest("GET", "/v1.19/networks/"+nid, nil) 1962 if err != nil { 1963 t.Fatal(err) 1964 } 1965 handleRequest(rsp, req) 1966 if rsp.statusCode != http.StatusOK { 1967 t.Fatalf("Unexpected failure: (%d): %s", rsp.statusCode, rsp.body) 1968 } 1969 1970 var nwr networkResource 1971 err = json.Unmarshal(rsp.body, &nwr) 1972 if err != nil { 1973 t.Fatal(err) 1974 } 1975 if nwr.Name != "network-fiftyfive" || nid != nwr.ID { 1976 t.Fatalf("Incongruent resource found: %v", nwr) 1977 } 1978 1979 // Create endpoint 1980 eb, err := json.Marshal(endpointCreate{Name: "ep-TwentyTwo"}) 1981 if err != nil { 1982 t.Fatal(err) 1983 } 1984 1985 lr = newLocalReader(eb) 1986 req, err = http.NewRequest("POST", "/v1.19/networks/"+nid+"/endpoints", lr) 1987 if err != nil { 1988 t.Fatal(err) 1989 } 1990 handleRequest(rsp, req) 1991 if rsp.statusCode != http.StatusCreated { 1992 t.Fatalf("Unexpected status code. Expected (%d). Got (%d): %s.", http.StatusCreated, rsp.statusCode, string(rsp.body)) 1993 } 1994 if len(rsp.body) == 0 { 1995 t.Fatal("Empty response body") 1996 } 1997 1998 var eid string 1999 err = json.Unmarshal(rsp.body, &eid) 2000 if err != nil { 2001 t.Fatal(err) 2002 } 2003 2004 // Query endpoint(s) 2005 req, err = http.NewRequest("GET", "/v1.19/networks/"+nid+"/endpoints", nil) 2006 if err != nil { 2007 t.Fatal(err) 2008 } 2009 handleRequest(rsp, req) 2010 if rsp.statusCode != http.StatusOK { 2011 t.Fatalf("Expected StatusOK. Got (%d): %s", rsp.statusCode, rsp.body) 2012 } 2013 2014 req, err = http.NewRequest("GET", "/v1.19/networks/"+nid+"/endpoints?name=bla", nil) 2015 if err != nil { 2016 t.Fatal(err) 2017 } 2018 handleRequest(rsp, req) 2019 if rsp.statusCode != http.StatusOK { 2020 t.Fatalf("Unexpected failure: (%d): %s", rsp.statusCode, rsp.body) 2021 } 2022 var epList []*endpointResource 2023 err = json.Unmarshal(rsp.body, &epList) 2024 if err != nil { 2025 t.Fatal(err) 2026 } 2027 if len(epList) != 0 { 2028 t.Fatalf("Expected empty list. Got %v", epList) 2029 } 2030 2031 // Query endpoint by name 2032 req, err = http.NewRequest("GET", "/v1.19/networks/"+nid+"/endpoints?name=ep-TwentyTwo", nil) 2033 if err != nil { 2034 t.Fatal(err) 2035 } 2036 handleRequest(rsp, req) 2037 if rsp.statusCode != http.StatusOK { 2038 t.Fatalf("Unexpected failure: (%d): %s", rsp.statusCode, rsp.body) 2039 } 2040 2041 err = json.Unmarshal(rsp.body, &epList) 2042 if err != nil { 2043 t.Fatal(err) 2044 } 2045 if len(epList) == 0 { 2046 t.Fatal("Empty response body") 2047 } 2048 if epList[0].Name != "ep-TwentyTwo" || eid != epList[0].ID { 2049 t.Fatalf("Incongruent resource found: %v", epList[0]) 2050 } 2051 2052 // Query endpoint by partial id 2053 chars = []byte(eid) 2054 partial = string(chars[0 : len(chars)/2]) 2055 req, err = http.NewRequest("GET", "/v1.19/networks/"+nid+"/endpoints?partial-id="+partial, nil) 2056 if err != nil { 2057 t.Fatal(err) 2058 } 2059 handleRequest(rsp, req) 2060 if rsp.statusCode != http.StatusOK { 2061 t.Fatalf("Unexpected failure: (%d): %s", rsp.statusCode, rsp.body) 2062 } 2063 2064 err = json.Unmarshal(rsp.body, &epList) 2065 if err != nil { 2066 t.Fatal(err) 2067 } 2068 if len(epList) == 0 { 2069 t.Fatal("Empty response body") 2070 } 2071 if epList[0].Name != "ep-TwentyTwo" || eid != epList[0].ID { 2072 t.Fatalf("Incongruent resource found: %v", epList[0]) 2073 } 2074 2075 // Get endpoint by id 2076 req, err = http.NewRequest("GET", "/v1.19/networks/"+nid+"/endpoints/"+eid, nil) 2077 if err != nil { 2078 t.Fatal(err) 2079 } 2080 handleRequest(rsp, req) 2081 if rsp.statusCode != http.StatusOK { 2082 t.Fatalf("Unexpected failure: (%d): %s", rsp.statusCode, rsp.body) 2083 } 2084 2085 var epr endpointResource 2086 err = json.Unmarshal(rsp.body, &epr) 2087 if err != nil { 2088 t.Fatal(err) 2089 } 2090 if epr.Name != "ep-TwentyTwo" || epr.ID != eid { 2091 t.Fatalf("Incongruent resource found: %v", epr) 2092 } 2093 2094 // Store two container ids and one partial ids 2095 cid1 := "container10010000000" 2096 cid2 := "container20010000000" 2097 chars = []byte(cid1) 2098 cpid1 := string(chars[0 : len(chars)/2]) 2099 2100 // Create sandboxes 2101 sb1, err := json.Marshal(sandboxCreate{ 2102 ContainerID: cid1, 2103 PortMapping: getPortMapping(), 2104 }) 2105 if err != nil { 2106 t.Fatal(err) 2107 } 2108 2109 lr = newLocalReader(sb1) 2110 req, err = http.NewRequest("POST", "/v5.22/sandboxes", lr) 2111 if err != nil { 2112 t.Fatal(err) 2113 } 2114 handleRequest(rsp, req) 2115 if rsp.statusCode != http.StatusCreated { 2116 t.Fatalf("Unexpected status code. Expected (%d). Got (%d): %s.", http.StatusCreated, rsp.statusCode, string(rsp.body)) 2117 } 2118 if len(rsp.body) == 0 { 2119 t.Fatal("Empty response body") 2120 } 2121 // Get sandbox id and partial id 2122 var sid1 string 2123 err = json.Unmarshal(rsp.body, &sid1) 2124 if err != nil { 2125 t.Fatal(err) 2126 } 2127 2128 sb2, err := json.Marshal(sandboxCreate{ 2129 ContainerID: cid2, 2130 ExposedPorts: getExposedPorts(), 2131 }) 2132 if err != nil { 2133 t.Fatal(err) 2134 } 2135 2136 lr = newLocalReader(sb2) 2137 req, err = http.NewRequest("POST", "/v5.22/sandboxes", lr) 2138 if err != nil { 2139 t.Fatal(err) 2140 } 2141 handleRequest(rsp, req) 2142 if rsp.statusCode != http.StatusCreated { 2143 t.Fatalf("Unexpected status code. Expected (%d). Got (%d): %s.", http.StatusCreated, rsp.statusCode, string(rsp.body)) 2144 } 2145 if len(rsp.body) == 0 { 2146 t.Fatal("Empty response body") 2147 } 2148 // Get sandbox id and partial id 2149 var sid2 string 2150 err = json.Unmarshal(rsp.body, &sid2) 2151 if err != nil { 2152 t.Fatal(err) 2153 } 2154 chars = []byte(sid2) 2155 spid2 := string(chars[0 : len(chars)/2]) 2156 2157 // Query sandboxes 2158 req, err = http.NewRequest("GET", "/sandboxes", nil) 2159 if err != nil { 2160 t.Fatal(err) 2161 } 2162 handleRequest(rsp, req) 2163 if rsp.statusCode != http.StatusOK { 2164 t.Fatalf("Expected StatusOK. Got (%d): %s", rsp.statusCode, rsp.body) 2165 } 2166 2167 var sbList []*sandboxResource 2168 err = json.Unmarshal(rsp.body, &sbList) 2169 if err != nil { 2170 t.Fatal(err) 2171 } 2172 if len(sbList) != 2 { 2173 t.Fatalf("Expected 2 elements in list. Got %v", sbList) 2174 } 2175 2176 // Get sandbox by id 2177 req, err = http.NewRequest("GET", "/sandboxes/"+sid1, nil) 2178 if err != nil { 2179 t.Fatal(err) 2180 } 2181 handleRequest(rsp, req) 2182 if rsp.statusCode != http.StatusOK { 2183 t.Fatalf("Unexpected failure: (%d): %s", rsp.statusCode, rsp.body) 2184 } 2185 2186 var sbr sandboxResource 2187 err = json.Unmarshal(rsp.body, &sbr) 2188 if err != nil { 2189 t.Fatal(err) 2190 } 2191 if sbr.ContainerID != cid1 { 2192 t.Fatalf("Incongruent resource found: %v", sbr) 2193 } 2194 2195 // Query sandbox by partial sandbox id 2196 req, err = http.NewRequest("GET", "/sandboxes?partial-id="+spid2, nil) 2197 if err != nil { 2198 t.Fatal(err) 2199 } 2200 handleRequest(rsp, req) 2201 if rsp.statusCode != http.StatusOK { 2202 t.Fatalf("Unexpected failure: (%d): %s", rsp.statusCode, rsp.body) 2203 } 2204 2205 err = json.Unmarshal(rsp.body, &sbList) 2206 if err != nil { 2207 t.Fatal(err) 2208 } 2209 if len(sbList) == 0 { 2210 t.Fatal("Empty response body") 2211 } 2212 if sbList[0].ID != sid2 { 2213 t.Fatalf("Incongruent resource found: %v", sbList[0]) 2214 } 2215 2216 // Query sandbox by container id 2217 req, err = http.NewRequest("GET", "/sandboxes?container-id="+cid2, nil) 2218 if err != nil { 2219 t.Fatal(err) 2220 } 2221 handleRequest(rsp, req) 2222 if rsp.statusCode != http.StatusOK { 2223 t.Fatalf("Unexpected failure: (%d): %s", rsp.statusCode, rsp.body) 2224 } 2225 2226 err = json.Unmarshal(rsp.body, &sbList) 2227 if err != nil { 2228 t.Fatal(err) 2229 } 2230 if len(sbList) == 0 { 2231 t.Fatal("Empty response body") 2232 } 2233 if sbList[0].ContainerID != cid2 { 2234 t.Fatalf("Incongruent resource found: %v", sbList[0]) 2235 } 2236 2237 // Query sandbox by partial container id 2238 req, err = http.NewRequest("GET", "/sandboxes?partial-container-id="+cpid1, nil) 2239 if err != nil { 2240 t.Fatal(err) 2241 } 2242 handleRequest(rsp, req) 2243 if rsp.statusCode != http.StatusOK { 2244 t.Fatalf("Unexpected failure: (%d): %s", rsp.statusCode, rsp.body) 2245 } 2246 2247 err = json.Unmarshal(rsp.body, &sbList) 2248 if err != nil { 2249 t.Fatal(err) 2250 } 2251 if len(sbList) == 0 { 2252 t.Fatal("Empty response body") 2253 } 2254 if sbList[0].ContainerID != cid1 { 2255 t.Fatalf("Incongruent resource found: %v", sbList[0]) 2256 } 2257 } 2258 2259 func TestEndToEndErrorMessage(t *testing.T) { 2260 defer testutils.SetupTestOSContext(t)() 2261 2262 rsp := newWriter() 2263 2264 // Cleanup local datastore file 2265 os.Remove(datastore.DefaultScopes("")[datastore.LocalScope].Client.Address) 2266 2267 c, err := libnetwork.New() 2268 if err != nil { 2269 t.Fatal(err) 2270 } 2271 defer c.Stop() 2272 handleRequest := NewHTTPHandler(c) 2273 2274 body := []byte{} 2275 lr := newLocalReader(body) 2276 req, err := http.NewRequest("POST", "/v1.19/networks", lr) 2277 if err != nil { 2278 t.Fatal(err) 2279 } 2280 handleRequest(rsp, req) 2281 2282 if len(rsp.body) == 0 { 2283 t.Fatal("Empty response body.") 2284 } 2285 empty := []byte("\"\"") 2286 if bytes.Equal(empty, bytes.TrimSpace(rsp.body)) { 2287 t.Fatal("Empty response error message.") 2288 } 2289 } 2290 2291 type bre struct{} 2292 2293 func (b *bre) Error() string { 2294 return "I am a bad request error" 2295 } 2296 func (b *bre) BadRequest() {} 2297 2298 type nfe struct{} 2299 2300 func (n *nfe) Error() string { 2301 return "I am a not found error" 2302 } 2303 func (n *nfe) NotFound() {} 2304 2305 type forb struct{} 2306 2307 func (f *forb) Error() string { 2308 return "I am a bad request error" 2309 } 2310 func (f *forb) Forbidden() {} 2311 2312 type notimpl struct{} 2313 2314 func (nip *notimpl) Error() string { 2315 return "I am a not implemented error" 2316 } 2317 func (nip *notimpl) NotImplemented() {} 2318 2319 type inter struct{} 2320 2321 func (it *inter) Error() string { 2322 return "I am an internal error" 2323 } 2324 func (it *inter) Internal() {} 2325 2326 type tout struct{} 2327 2328 func (to *tout) Error() string { 2329 return "I am a timeout error" 2330 } 2331 func (to *tout) Timeout() {} 2332 2333 type noserv struct{} 2334 2335 func (nos *noserv) Error() string { 2336 return "I am a no service error" 2337 } 2338 func (nos *noserv) NoService() {} 2339 2340 type notclassified struct{} 2341 2342 func (noc *notclassified) Error() string { 2343 return "I am a non classified error" 2344 } 2345 2346 func TestErrorConversion(t *testing.T) { 2347 if convertNetworkError(new(bre)).StatusCode != http.StatusBadRequest { 2348 t.Fatal("Failed to recognize BadRequest error") 2349 } 2350 2351 if convertNetworkError(new(nfe)).StatusCode != http.StatusNotFound { 2352 t.Fatal("Failed to recognize NotFound error") 2353 } 2354 2355 if convertNetworkError(new(forb)).StatusCode != http.StatusForbidden { 2356 t.Fatal("Failed to recognize Forbidden error") 2357 } 2358 2359 if convertNetworkError(new(notimpl)).StatusCode != http.StatusNotImplemented { 2360 t.Fatal("Failed to recognize NotImplemented error") 2361 } 2362 2363 if convertNetworkError(new(inter)).StatusCode != http.StatusInternalServerError { 2364 t.Fatal("Failed to recognize Internal error") 2365 } 2366 2367 if convertNetworkError(new(tout)).StatusCode != http.StatusRequestTimeout { 2368 t.Fatal("Failed to recognize Timeout error") 2369 } 2370 2371 if convertNetworkError(new(noserv)).StatusCode != http.StatusServiceUnavailable { 2372 t.Fatal("Failed to recognize No Service error") 2373 } 2374 2375 if convertNetworkError(new(notclassified)).StatusCode != http.StatusInternalServerError { 2376 t.Fatal("Failed to recognize not classified error as Internal error") 2377 } 2378 } 2379 2380 func TestFieldRegex(t *testing.T) { 2381 pr := regexp.MustCompile(regex) 2382 qr := regexp.MustCompile(`^` + qregx + `$`) // mux compiles it like this 2383 2384 if pr.MatchString("") { 2385 t.Fatal("Unexpected match") 2386 } 2387 if !qr.MatchString("") { 2388 t.Fatal("Unexpected match failure") 2389 } 2390 2391 if pr.MatchString(":") { 2392 t.Fatal("Unexpected match") 2393 } 2394 if qr.MatchString(":") { 2395 t.Fatal("Unexpected match") 2396 } 2397 2398 if pr.MatchString(".") { 2399 t.Fatal("Unexpected match") 2400 } 2401 if qr.MatchString(".") { 2402 t.Fatal("Unexpected match") 2403 } 2404 }