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