github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/test/runtime_test.go (about) 1 //go:build integration 2 // +build integration 3 4 package test 5 6 import ( 7 "encoding/json" 8 "errors" 9 "fmt" 10 "io/ioutil" 11 "os" 12 "os/exec" 13 "os/user" 14 "path/filepath" 15 "strings" 16 "testing" 17 "time" 18 ) 19 20 const ( 21 branch = "" 22 version = "latest" 23 ) 24 25 func TestServerModeCall(t *testing.T) { 26 TrySuite(t, ServerModeCall, retryCount) 27 } 28 29 func ServerModeCall(t *T) { 30 t.Parallel() 31 serv := NewServer(t, WithLogin()) 32 33 cmd := serv.Command() 34 35 outp, err := cmd.Exec("call", "runtime", "Runtime.Read", "{}") 36 if err == nil { 37 t.Fatalf("Call to server should fail, got no error, output: %v", string(outp)) 38 return 39 } 40 41 defer serv.Close() 42 if err := serv.Run(); err != nil { 43 return 44 } 45 46 if err := Try("Calling Runtime.Read", t, func() ([]byte, error) { 47 outp, err := cmd.Exec("call", "runtime", "Runtime.Read", "{}") 48 if err != nil { 49 return outp, errors.New("Call to runtime read should succeed") 50 } 51 return outp, err 52 }, 5*time.Second); err != nil { 53 return 54 } 55 } 56 57 func TestRunLocalSource(t *testing.T) { 58 TrySuite(t, testRunLocalSource, retryCount) 59 } 60 61 func testRunLocalSource(t *T) { 62 t.Parallel() 63 serv := NewServer(t, WithLogin()) 64 defer serv.Close() 65 if err := serv.Run(); err != nil { 66 return 67 } 68 69 cmd := serv.Command() 70 71 outp, err := cmd.Exec("run", "./services/helloworld") 72 if err != nil { 73 t.Fatalf("micro run failure, output: %v", string(outp)) 74 return 75 } 76 77 if err := Try("Find helloworld", t, func() ([]byte, error) { 78 outp, err := cmd.Exec("status") 79 if err != nil { 80 return outp, err 81 } 82 83 if !statusRunning("helloworld", "latest", outp) { 84 return outp, errors.New("Can't find helloworld service in runtime") 85 } 86 return outp, err 87 }, 15*time.Second); err != nil { 88 return 89 } 90 91 if err := Try("Find helloworld in list", t, func() ([]byte, error) { 92 outp, err := cmd.Exec("services") 93 if err != nil { 94 return outp, err 95 } 96 if !strings.Contains(string(outp), "helloworld") { 97 return outp, errors.New("Can't find example service in list") 98 } 99 return outp, err 100 }, 90*time.Second); err != nil { 101 return 102 } 103 } 104 105 func TestRunAndKill(t *testing.T) { 106 TrySuite(t, testRunAndKill, retryCount) 107 } 108 109 func testRunAndKill(t *T) { 110 t.Parallel() 111 serv := NewServer(t, WithLogin()) 112 defer serv.Close() 113 if err := serv.Run(); err != nil { 114 return 115 } 116 117 cmd := serv.Command() 118 119 outp, err := cmd.Exec("run", "./services/helloworld") 120 if err != nil { 121 t.Fatalf("micro run failure, output: %v", string(outp)) 122 return 123 } 124 125 if err := Try("Find helloworld", t, func() ([]byte, error) { 126 outp, err = cmd.Exec("status") 127 if err != nil { 128 return outp, err 129 } 130 131 if !statusRunning("helloworld", "latest", outp) { 132 return outp, errors.New("Can't find example service in runtime") 133 } 134 return outp, err 135 }, 30*time.Second); err != nil { 136 return 137 } 138 139 if err := Try("Find helloworld in list", t, func() ([]byte, error) { 140 outp, err := cmd.Exec("services") 141 if err != nil { 142 return outp, err 143 } 144 if !strings.Contains(string(outp), "helloworld") { 145 outp1, _ := cmd.Exec("logs", "helloworld") 146 return append(outp, outp1...), errors.New("Can't find helloworld service in list") 147 } 148 return outp, err 149 }, 90*time.Second); err != nil { 150 return 151 } 152 153 outp, err = cmd.Exec("kill", "helloworld") 154 if err != nil { 155 t.Fatalf("micro kill failure, output: %v", string(outp)) 156 return 157 } 158 159 if err := Try("Find helloworld", t, func() ([]byte, error) { 160 outp, err = cmd.Exec("status") 161 if err != nil { 162 return outp, err 163 } 164 165 // The started service should have the runtime name of "service/example", 166 // as the runtime name is the relative path inside a repo. 167 if strings.Contains(string(outp), "helloworld") { 168 return outp, errors.New("Should not find example service in runtime") 169 } 170 return outp, err 171 }, 15*time.Second); err != nil { 172 return 173 } 174 175 if err := Try("Find helloworld in list", t, func() ([]byte, error) { 176 outp, err := cmd.Exec("services") 177 if err != nil { 178 return outp, err 179 } 180 if strings.Contains(string(outp), "helloworld") { 181 return outp, errors.New("Should not find helloworld service in list") 182 } 183 return outp, err 184 }, 20*time.Second); err != nil { 185 return 186 } 187 } 188 189 func TestRunGithubSource(t *testing.T) { 190 TrySuite(t, testRunGithubSource, retryCount) 191 } 192 193 func testRunGithubSource(t *T) { 194 t.Parallel() 195 196 serv := NewServer(t, WithLogin()) 197 defer serv.Close() 198 if err := serv.Run(); err != nil { 199 return 200 } 201 202 cmd := serv.Command() 203 outp, err := cmd.Exec("run", "--image", "localhost:5000/cells:v3", "github.com/micro/services/helloworld@"+branch) 204 if err != nil { 205 t.Fatalf("micro run failure, output: %v", string(outp)) 206 return 207 } 208 209 if err := Try("Find helloworld in runtime", t, func() ([]byte, error) { 210 outp, err = cmd.Exec("status") 211 if err != nil { 212 return outp, err 213 } 214 215 if !statusRunning("helloworld", version, outp) { 216 return outp, errors.New("Output should contain helloworld") 217 } 218 if !strings.Contains(string(outp), "owner=admin") || !(strings.Contains(string(outp), "group=micro") || strings.Contains(string(outp), "group="+serv.Env())) { 219 return outp, errors.New("micro status does not have correct owner or group") 220 } 221 if strings.Contains(string(outp), "unknown") { 222 return outp, errors.New("there should be no unknown in the micro status output") 223 } 224 return outp, nil 225 }, 60*time.Second); err != nil { 226 return 227 } 228 229 if err := Try("Find helloworld in registry", t, func() ([]byte, error) { 230 outp, err = cmd.Exec("services") 231 if err != nil { 232 return outp, err 233 } 234 if !strings.Contains(string(outp), "helloworld") { 235 return outp, errors.New("helloworld is not running") 236 } 237 return outp, nil 238 }, 180*time.Second); err != nil { 239 return 240 } 241 242 if err := Try("Call helloworld", t, func() ([]byte, error) { 243 outp, err := cmd.Exec("call", "helloworld", "Helloworld.Call", "{\"name\":\"John\"}") 244 if err != nil { 245 return outp, err 246 } 247 rsp := map[string]string{} 248 err = json.Unmarshal(outp, &rsp) 249 if err != nil { 250 return outp, err 251 } 252 if rsp["message"] != "Hello John" { 253 return outp, errors.New("Helloworld resonse is unexpected") 254 } 255 return outp, err 256 }, 60*time.Second); err != nil { 257 return 258 } 259 260 cmd.Exec("kill", "helloworld") 261 262 // test it works for a branch with a funny name 263 outp, err = cmd.Exec("run", "--image", "localhost:5000/cells:v3", "github.com/micro/services/helloworld@integrationtest/branch_name") 264 if err != nil { 265 t.Fatalf("micro run failure, output: %v", string(outp)) 266 return 267 } 268 269 if err := Try("Find helloworld in runtime", t, func() ([]byte, error) { 270 outp, err = cmd.Exec("status") 271 if err != nil { 272 return outp, err 273 } 274 // 275 if !statusRunning("helloworld", "integrationtest/branch_name", outp) { 276 return outp, errors.New("Output should contain helloworld") 277 } 278 if !strings.Contains(string(outp), "owner=admin") || !(strings.Contains(string(outp), "group=micro") || strings.Contains(string(outp), "group="+serv.Env())) { 279 return outp, errors.New("micro status does not have correct owner or group") 280 } 281 if strings.Contains(string(outp), "unknown") { 282 return outp, errors.New("there should be no unknown in the micro status output") 283 } 284 return outp, nil 285 }, 60*time.Second); err != nil { 286 return 287 } 288 289 if err := Try("Find helloworld in registry", t, func() ([]byte, error) { 290 outp, err = cmd.Exec("services") 291 if err != nil { 292 return outp, err 293 } 294 if !strings.Contains(string(outp), "helloworld") { 295 return outp, errors.New("helloworld is not running") 296 } 297 return outp, nil 298 }, 180*time.Second); err != nil { 299 return 300 } 301 302 if err := Try("Call helloworld", t, func() ([]byte, error) { 303 outp, err := cmd.Exec("call", "helloworld", "Helloworld.Call", "{\"name\":\"John\"}") 304 if err != nil { 305 return outp, err 306 } 307 rsp := map[string]string{} 308 err = json.Unmarshal(outp, &rsp) 309 if err != nil { 310 return outp, err 311 } 312 if rsp["msg"] != "Hello John" { 313 return outp, errors.New("Helloworld resonse is unexpected") 314 } 315 return outp, err 316 }, 60*time.Second); err != nil { 317 return 318 } 319 320 } 321 322 // Note: @todo this method should truly be the same as TestGithubSource. 323 func TestRunGitlabSource(t *testing.T) { 324 TrySuite(t, testRunGitlabSource, retryCount) 325 } 326 327 func testRunGitlabSource(t *T) { 328 t.Parallel() 329 330 serv := NewServer(t, WithLogin()) 331 defer serv.Close() 332 if err := serv.Run(); err != nil { 333 return 334 } 335 336 cmd := serv.Command() 337 cmd.Exec("user", "config", "set", "git."+serv.Env()+".baseurl", "gitlab.com/micro-test") 338 339 outp, err := cmd.Exec("run", "basic-micro-service") 340 if err != nil { 341 t.Fatalf("micro run failure, output: %v", string(outp)) 342 return 343 } 344 345 if err := Try("Find basic-micro-service in runtime", t, func() ([]byte, error) { 346 outp, err = cmd.Exec("status") 347 if err != nil { 348 return outp, err 349 } 350 351 if !statusRunning("basic-micro-service", version, outp) { 352 return outp, errors.New("Output should contain basic-micro-service") 353 } 354 return outp, nil 355 }, 60*time.Second); err != nil { 356 return 357 } 358 359 if err := Try("Find example in registry", t, func() ([]byte, error) { 360 outp, err := cmd.Exec("services") 361 if err != nil { 362 return outp, err 363 } 364 if !strings.Contains(string(outp), "example") { 365 return outp, errors.New("Does not example") 366 } 367 return outp, err 368 }, 120*time.Second); err != nil { 369 outp, _ := cmd.Exec("logs", "basic-micro-service") 370 t.Log(string(outp)) 371 return 372 } 373 } 374 375 func TestRunGitlabSourceMonoRepo(t *testing.T) { 376 TrySuite(t, testRunGitlabSourceMonoRepo, retryCount) 377 } 378 379 func testRunGitlabSourceMonoRepo(t *T) { 380 t.Parallel() 381 382 serv := NewServer(t, WithLogin()) 383 defer serv.Close() 384 if err := serv.Run(); err != nil { 385 return 386 } 387 388 cmd := serv.Command() 389 cmd.Exec("user", "config", "set", "git."+serv.Env()+".baseurl", "gitlab.com/micro-test/monorepo-test") 390 391 outp, err := cmd.Exec("run", "subfolder-test"+branch) 392 if err != nil { 393 t.Fatalf("micro run failure, output: %v", string(outp)) 394 return 395 } 396 397 if err := Try("Find helloworld in runtime", t, func() ([]byte, error) { 398 outp, err = cmd.Exec("status") 399 if err != nil { 400 return outp, err 401 } 402 403 if !statusRunning("subfolder-test", version, outp) { 404 return outp, errors.New("Output should contain subfolder-test") 405 } 406 return outp, nil 407 }, 60*time.Second); err != nil { 408 return 409 } 410 411 if err := Try("Find helloworld in registry", t, func() ([]byte, error) { 412 outp, err := cmd.Exec("services") 413 if err != nil { 414 return outp, err 415 } 416 if !strings.Contains(string(outp), "example") { 417 return outp, errors.New("Does not contain example") 418 } 419 return outp, err 420 }, 120*time.Second); err != nil { 421 outp, _ := cmd.Exec("logs", "subfolder-test") 422 t.Log(string(outp)) 423 return 424 } 425 } 426 427 // This test exists to test the path of "generic git checkout", not just bitbucket 428 func TestRunGenericRemote(t *testing.T) { 429 TrySuite(t, testRunGenericRemote, retryCount) 430 } 431 432 func testRunGenericRemote(t *T) { 433 t.Parallel() 434 435 serv := NewServer(t, WithLogin()) 436 defer serv.Close() 437 if err := serv.Run(); err != nil { 438 return 439 } 440 441 cmd := serv.Command() 442 cmd.Exec("user", "config", "set", "git."+serv.Env()+".baseurl", "bitbucket.org/micro-test/monorepo-test") 443 444 outp, err := cmd.Exec("run", "subfolder-test") 445 if err != nil { 446 t.Fatalf("micro run failure, output: %v", string(outp)) 447 return 448 } 449 450 if err := Try("Find subfolder-test in runtime", t, func() ([]byte, error) { 451 outp, err = cmd.Exec("status") 452 if err != nil { 453 return outp, err 454 } 455 456 if !statusRunning("subfolder-test", "latest", outp) { 457 return outp, errors.New("Output should contain subfolder-test") 458 } 459 return outp, nil 460 }, 60*time.Second); err != nil { 461 return 462 } 463 464 if err := Try("Find example in registry", t, func() ([]byte, error) { 465 outp, err := cmd.Exec("services") 466 if err != nil { 467 return outp, err 468 } 469 if !strings.Contains(string(outp), "example") { 470 return outp, errors.New("Does not contain example") 471 } 472 return outp, err 473 }, 120*time.Second); err != nil { 474 outp, _ := cmd.Exec("logs", "subfolder-test") 475 t.Log(string(outp)) 476 return 477 } 478 } 479 480 func TestRunLocalUpdateAndCall(t *testing.T) { 481 TrySuite(t, testRunLocalUpdateAndCall, retryCount) 482 } 483 484 func testRunLocalUpdateAndCall(t *T) { 485 t.Parallel() 486 serv := NewServer(t, WithLogin()) 487 defer serv.Close() 488 if err := serv.Run(); err != nil { 489 return 490 } 491 492 cmd := serv.Command() 493 494 // Run the example service 495 outp, err := cmd.Exec("run", "./services/helloworld") 496 if err != nil { 497 t.Fatalf("micro run failure, output: %v", string(outp)) 498 return 499 } 500 501 if err := Try("Finding helloworld service with micro status", t, func() ([]byte, error) { 502 outp, err = cmd.Exec("status") 503 if err != nil { 504 return outp, err 505 } 506 507 // The started service should have the runtime name of "example". 508 if !statusRunning("helloworld", "latest", outp) { 509 return outp, errors.New("can't find service in runtime") 510 } 511 return outp, err 512 }, 15*time.Second); err != nil { 513 return 514 } 515 516 if err := Try("Call helloworld service", t, func() ([]byte, error) { 517 outp, err := cmd.Exec("helloworld", "--name=Joe") 518 if err != nil { 519 return outp, err 520 } 521 rsp := map[string]string{} 522 err = json.Unmarshal(outp, &rsp) 523 if err != nil { 524 return outp, err 525 } 526 if rsp["message"] != "Hello Joe" { 527 return outp, errors.New("Response is unexpected") 528 } 529 return outp, err 530 }, 50*time.Second); err != nil { 531 return 532 } 533 534 replaceStringInFile(t, "./services/helloworld/handler/helloworld.go", `"Hello "`, `"Hi "`) 535 defer func() { 536 // Change file back 537 replaceStringInFile(t, "./services/helloworld/handler/helloworld.go", `"Hi "`, `"Hello "`) 538 }() 539 540 outp, err = cmd.Exec("update", "./services/helloworld") 541 if err != nil { 542 t.Fatal(err) 543 return 544 } 545 546 if err := Try("Finding helloworld service with micro status", t, func() ([]byte, error) { 547 outp, err = cmd.Exec("status") 548 if err != nil { 549 return outp, err 550 } 551 552 // The started service should have the runtime name of "example". 553 if !statusRunning("helloworld", "latest", outp) { 554 outp1, _ := cmd.Exec("logs", "helloworld") 555 return append(outp, outp1...), errors.New("can't find service in runtime") 556 } 557 return outp, err 558 }, 45*time.Second); err != nil { 559 return 560 } 561 562 if err := Try("Call helloworld service after modification", t, func() ([]byte, error) { 563 outp, err := cmd.Exec("helloworld", "--name=Joe") 564 if err != nil { 565 outp1, _ := cmd.Exec("logs", "helloworld") 566 return append(outp, outp1...), err 567 } 568 rsp := map[string]string{} 569 err = json.Unmarshal(outp, &rsp) 570 if err != nil { 571 return outp, err 572 } 573 if rsp["message"] != "Hi Joe" { 574 return outp, errors.New("Response is not what's expected") 575 } 576 return outp, err 577 }, 45*time.Second); err != nil { 578 return 579 } 580 } 581 582 func TestRunCurrentFolder(t *testing.T) { 583 TrySuite(t, testRunCurrentFolder, retryCount) 584 } 585 586 func testRunCurrentFolder(t *T) { 587 t.Parallel() 588 serv := NewServer(t, WithLogin()) 589 defer serv.Close() 590 if err := serv.Run(); err != nil { 591 return 592 } 593 594 cmd := serv.Command() 595 usr, err := user.Current() 596 if err != nil { 597 t.Fatal(err) 598 } 599 cmd.Dir = usr.HomeDir 600 err = os.RemoveAll(filepath.Join(usr.HomeDir, "helloworld")) 601 if err != nil { 602 t.Fatal(err) 603 } 604 //if err != nil { 605 // t.Fatal(string(outp)) 606 //} 607 608 outp, err := cmd.Exec("new", "helloworld") 609 if err != nil { 610 t.Fatal(string(outp)) 611 } 612 makeProt := exec.Command("make", "proto") 613 makeProt.Dir = filepath.Join(usr.HomeDir, "helloworld") 614 outp, err = makeProt.CombinedOutput() 615 if err != nil { 616 t.Fatal(string(outp)) 617 } 618 619 cmd.Dir = filepath.Join(usr.HomeDir, "helloworld") 620 outp, err = cmd.Exec("run", ".") 621 if err != nil { 622 t.Fatal(outp) 623 } 624 625 Try("Find helloworld", t, func() ([]byte, error) { 626 outp, err = cmd.Exec("status") 627 if !statusRunning("helloworld", "latest", outp) { 628 return outp, errors.New("Can't find helloworld") 629 } 630 return outp, err 631 }, 20*time.Second) 632 } 633 634 func TestRunParentFolder(t *testing.T) { 635 TrySuite(t, testRunParentFolder, retryCount) 636 } 637 638 func testRunParentFolder(t *T) { 639 defer func() { 640 os.RemoveAll("../test-top-level") 641 }() 642 t.Parallel() 643 serv := NewServer(t, WithLogin()) 644 defer serv.Close() 645 if err := serv.Run(); err != nil { 646 return 647 } 648 649 cmd := serv.Command() 650 cmd.Dir = ".." 651 outp, err := cmd.Exec("new", "test-top-level") 652 if err != nil { 653 t.Fatal(string(outp)) 654 } 655 makeProt := exec.Command("make", "proto") 656 makeProt.Dir = "../test-top-level" 657 outp, err = makeProt.CombinedOutput() 658 if err != nil { 659 t.Fatal(string(outp)) 660 } 661 662 gomod := exec.Command("go", "mod", "edit", "-replace", "github.com/tickoalcantara12/micro/v3=github.com/tickoalcantara12/micro/v3@v3.0.0") 663 gomod.Dir = "../test-top-level" 664 if outp, err := gomod.CombinedOutput(); err != nil { 665 t.Fatal(string(outp)) 666 } 667 668 err = os.MkdirAll("../parent/folder/test", 0777) 669 if err != nil { 670 t.Fatal(err) 671 } 672 673 cmd.Dir = "../parent/folder/test" 674 outp, err = cmd.Exec("run", "../../../test-top-level") 675 if err != nil { 676 t.Fatal(string(outp)) 677 } 678 679 if err := Try("Find example", t, func() ([]byte, error) { 680 outp, err := cmd.Exec("status") 681 if err != nil { 682 return outp, err 683 } 684 685 // The started service should have the runtime name of "service/example", 686 // as the runtime name is the relative path inside a repo. 687 if !statusRunning("test-top-level", "latest", outp) { 688 return outp, errors.New("Can't find example service in runtime") 689 } 690 return outp, err 691 }, 15*time.Second); err != nil { 692 return 693 } 694 695 if err := Try("Find example in list", t, func() ([]byte, error) { 696 outp, err := cmd.Exec("services") 697 if err != nil { 698 return outp, err 699 } 700 if !strings.Contains(string(outp), "test-top-level") { 701 l, _ := cmd.Exec("logs", "test-top-level") 702 return outp, fmt.Errorf("Can't find example service in list. \nLogs: %v", string(l)) 703 } 704 return outp, err 705 }, 90*time.Second); err != nil { 706 return 707 } 708 } 709 710 func TestRunNewWithGit(t *testing.T) { 711 TrySuite(t, testRunNewWithGit, retryCount) 712 } 713 714 func testRunNewWithGit(t *T) { 715 defer func() { 716 os.RemoveAll("/tmp/new-with-git") 717 }() 718 t.Parallel() 719 serv := NewServer(t, WithLogin()) 720 defer serv.Close() 721 if err := serv.Run(); err != nil { 722 return 723 } 724 725 cmd := serv.Command() 726 cmd.Dir = "/tmp" 727 728 outp, err := cmd.Exec("new", "new-with-git") 729 if err != nil { 730 t.Fatal(string(outp)) 731 return 732 } 733 makeProt := exec.Command("make", "proto") 734 makeProt.Dir = "/tmp/new-with-git" 735 736 outp, err = makeProt.CombinedOutput() 737 if err != nil { 738 t.Fatal(string(outp)) 739 return 740 } 741 742 // for tests, update the micro import to use the current version of the code. 743 fname := fmt.Sprintf(makeProt.Dir + "/go.mod") 744 f, err := os.OpenFile(fname, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) 745 if err != nil { 746 t.Fatal(string(outp)) 747 return 748 } 749 if _, err := f.WriteString("\nreplace github.com/tickoalcantara12/micro/v3 => github.com/tickoalcantara12/micro/v3 master"); err != nil { 750 t.Fatal(string(outp)) 751 return 752 } 753 // This should point to master, but GOPROXY is not on in the runtime. Remove later. 754 if _, err := f.WriteString("\nreplace github.com/micro/go-micro/v3 => github.com/micro/go-micro/v3 v3.0.0-beta.2.0.20200922112322-927d4f8eced6"); err != nil { 755 t.Fatal(string(outp)) 756 return 757 } 758 f.Close() 759 760 gitInit := exec.Command("git", "init") 761 gitInit.Dir = "/tmp/new-with-git" 762 outp, err = gitInit.CombinedOutput() 763 if err != nil { 764 t.Fatal(string(outp)) 765 } 766 767 cmd = serv.Command() 768 cmd.Dir = "/tmp/new-with-git" 769 outp, err = cmd.Exec("run", ".") 770 if err != nil { 771 t.Fatal(outp) 772 } 773 774 if err := Try("Find example", t, func() ([]byte, error) { 775 outp, err := cmd.Exec("status") 776 outp1, _ := cmd.Exec("logs", "new-with-git") 777 outp = append(outp, outp1...) 778 if err != nil { 779 return outp, err 780 } 781 782 // The started service should have the runtime name of "service/example", 783 // as the runtime name is the relative path inside a repo. 784 if !statusRunning("new-with-git", "latest", outp) { 785 return outp, errors.New("Can't find example service in runtime") 786 } 787 return outp, err 788 }, 15*time.Second); err != nil { 789 return 790 } 791 792 if err := Try("Find example in list", t, func() ([]byte, error) { 793 outp, err := cmd.Exec("services") 794 outp1, _ := cmd.Exec("logs", "new-with-git") 795 outp = append(outp, outp1...) 796 if err != nil { 797 return outp, err 798 } 799 if !strings.Contains(string(outp), "new-with-git") { 800 return outp, errors.New("Can't find example service in list") 801 } 802 return outp, err 803 }, 90*time.Second); err != nil { 804 return 805 } 806 } 807 808 func TestExistingLogs(t *testing.T) { 809 TrySuite(t, testExistingLogs, retryCount) 810 } 811 812 func testExistingLogs(t *T) { 813 t.Parallel() 814 serv := NewServer(t, WithLogin()) 815 defer serv.Close() 816 if err := serv.Run(); err != nil { 817 return 818 } 819 820 cmd := serv.Command() 821 822 outp, err := cmd.Exec("run", "./services/test/logger") 823 if err != nil { 824 t.Fatalf("micro run failure, output: %v", string(outp)) 825 return 826 } 827 828 if err := Try("logger logs", t, func() ([]byte, error) { 829 outp, err = cmd.Exec("logs", "logger") 830 if err != nil { 831 return outp, err 832 } 833 834 if !strings.Contains(string(outp), "Listening on") || !strings.Contains(string(outp), "This is a log line") { 835 return outp, errors.New("Output does not contain expected") 836 } 837 return outp, nil 838 }, 90*time.Second); err != nil { 839 return 840 } 841 } 842 843 func TestBranchCheckout(t *testing.T) { 844 TrySuite(t, testBranchCheckout, retryCount) 845 } 846 847 func testBranchCheckout(t *T) { 848 t.Parallel() 849 serv := NewServer(t, WithLogin()) 850 defer serv.Close() 851 if err := serv.Run(); err != nil { 852 return 853 } 854 855 cmd := serv.Command() 856 857 outp, err := cmd.Exec("run", "./services/test/logger") 858 if err != nil { 859 t.Fatalf("micro run failure, output: %v", string(outp)) 860 return 861 } 862 863 if err := Try("logger logs", t, func() ([]byte, error) { 864 outp, err = cmd.Exec("logs", "logger") 865 if err != nil { 866 return outp, err 867 } 868 869 // The log that this branch outputs is different from master, that's what we look for 870 if !strings.Contains(string(outp), "Listening on") { 871 return outp, errors.New("Output does not contain expected") 872 } 873 return outp, nil 874 }, 60*time.Second); err != nil { 875 return 876 } 877 } 878 879 func TestStreamLogsAndThirdPartyRepo(t *testing.T) { 880 TrySuite(t, testStreamLogsAndThirdPartyRepo, retryCount) 881 } 882 883 func testStreamLogsAndThirdPartyRepo(t *T) { 884 t.Parallel() 885 serv := NewServer(t, WithLogin()) 886 defer serv.Close() 887 if err := serv.Run(); err != nil { 888 return 889 } 890 891 cmd := serv.Command() 892 893 outp, err := cmd.Exec("run", "./services/test/logger") 894 if err != nil { 895 t.Fatalf("micro run failure, output: %v", string(outp)) 896 return 897 } 898 899 if err := Try("logger logs", t, func() ([]byte, error) { 900 outp, err = cmd.Exec("logs", "logger") 901 if err != nil { 902 return outp, err 903 } 904 905 if !strings.Contains(string(outp), "Listening on") || !strings.Contains(string(outp), "This is a log line") { 906 return outp, errors.New("Output does not contain expected") 907 } 908 return outp, nil 909 }, 90*time.Second); err != nil { 910 return 911 } 912 913 cmd.Start("logs", "-n", "1", "-f", "logger") 914 915 time.Sleep(7 * time.Second) 916 917 go func() { 918 outp, err := cmd.Output() 919 if err != nil { 920 t.Log(err) 921 } 922 if len(outp) == 0 { 923 t.Fatal("No log lines streamed") 924 return 925 } 926 if !strings.Contains(string(outp), "This is a log line") { 927 t.Fatalf("Unexpected logs: %v", string(outp)) 928 return 929 } 930 // Logspammer logs every 2 seconds, so we need 2 different 931 now := time.Now() 932 // leaving the hour here to fix a docker issue 933 // when the containers clock is a few hours behind 934 stampA := now.Add(-2 * time.Second).Format("04:05") 935 stampB := now.Add(-1 * time.Second).Format("04:05") 936 if !strings.Contains(string(outp), stampA) && !strings.Contains(string(outp), stampB) { 937 t.Fatalf("Timestamp %v or %v not found in logs: %v", stampA, stampB, string(outp)) 938 return 939 } 940 }() 941 942 time.Sleep(7 * time.Second) 943 944 if err := cmd.Stop(); err != nil { 945 t.Fatal(err) 946 return 947 } 948 949 time.Sleep(2 * time.Second) 950 } 951 952 func replaceStringInFile(t *T, filepath string, original, newone string) { 953 input, err := ioutil.ReadFile(filepath) 954 if err != nil { 955 t.Fatal(err) 956 return 957 } 958 959 output := strings.ReplaceAll(string(input), original, newone) 960 err = ioutil.WriteFile(filepath, []byte(output), 0644) 961 if err != nil { 962 t.Fatal(err) 963 return 964 } 965 } 966 967 func TestParentDependency(t *testing.T) { 968 TrySuite(t, testParentDependency, retryCount) 969 } 970 971 func testParentDependency(t *T) { 972 t.Parallel() 973 serv := NewServer(t, WithLogin()) 974 defer serv.Close() 975 if err := serv.Run(); err != nil { 976 return 977 } 978 979 cmd := serv.Command() 980 981 outp, err := cmd.Exec("run", "./dep-test/dep-test-service") 982 if err != nil { 983 t.Fatalf("micro run failure, output: %v", string(outp)) 984 return 985 } 986 987 if err := Try("Find dep-test-service", t, func() ([]byte, error) { 988 outp, err := cmd.Exec("status") 989 if err != nil { 990 return outp, err 991 } 992 993 if !statusRunning("dep-test-service", "latest", outp) { 994 return outp, errors.New("Output should contain dep-test-service") 995 } 996 return outp, nil 997 }, 30*time.Second); err != nil { 998 return 999 } 1000 } 1001 1002 func TestRunPrivateSource(t *testing.T) { 1003 TrySuite(t, testRunPrivateSource, retryCount) 1004 } 1005 1006 func testRunPrivateSource(t *T) { 1007 t.Parallel() 1008 serv := NewServer(t, WithLogin()) 1009 defer serv.Close() 1010 if err := serv.Run(); err != nil { 1011 return 1012 } 1013 1014 cmd := serv.Command() 1015 1016 // get the git credentials, injected by the k8s integration test 1017 pat := os.Getenv("GITHUB_PAT") 1018 if len(pat) == 0 { 1019 t.Logf("Skipping test, missing GITHUB_PAT") 1020 return 1021 } 1022 1023 // set the pat in the users config 1024 if outp, err := cmd.Exec("user", "config", "set", "git.credentials.github", pat); err != nil { 1025 t.Fatalf("Expected no error, got %v %v", err, string(outp)) 1026 return 1027 } 1028 1029 // run the service 1030 if outp, err := cmd.Exec("run", "--image", "localhost:5000/cells:v3", "github.com/micro/test/helloworld"); err != nil { 1031 t.Fatalf("Expected no run error, got %v %v", err, string(outp)) 1032 return 1033 } 1034 1035 if err := Try("Find helloworld in runtime", t, func() ([]byte, error) { 1036 outp, err := cmd.Exec("status") 1037 if err != nil { 1038 return outp, err 1039 } 1040 1041 if !statusRunning("helloworld", "latest", outp) { 1042 return outp, errors.New("Can't find helloworld service in runtime") 1043 } 1044 return outp, err 1045 }, 60*time.Second); err != nil { 1046 return 1047 } 1048 1049 if err := Try("Find helloworld in registry", t, func() ([]byte, error) { 1050 outp, err := cmd.Exec("services") 1051 if err != nil { 1052 return outp, err 1053 } 1054 if !strings.Contains(string(outp), "helloworld") { 1055 return outp, errors.New("Does not contain helloworld") 1056 } 1057 return outp, err 1058 }, 90*time.Second); err != nil { 1059 outp, _ := cmd.Exec("logs", "helloworld") 1060 t.Logf("logs %s", string(outp)) 1061 return 1062 } 1063 1064 // call the service 1065 if err := Try("Calling helloworld", t, func() ([]byte, error) { 1066 return cmd.Exec("helloworld", "--name=John") 1067 }, 30*time.Second); err != nil { 1068 return 1069 } 1070 } 1071 1072 func TestRunCustomCredentials(t *testing.T) { 1073 TrySuite(t, testRunCustomCredentials, retryCount) 1074 } 1075 1076 func testRunCustomCredentials(t *T) { 1077 t.Parallel() 1078 serv := NewServer(t, WithLogin()) 1079 defer serv.Close() 1080 if err := serv.Run(); err != nil { 1081 return 1082 } 1083 1084 cmd := serv.Command() 1085 1086 // get the git credentials, injected by the k8s integration test 1087 pat := os.Getenv("GITHUB_PAT") 1088 if len(pat) == 0 { 1089 t.Logf("Skipping test, missing GITHUB_PAT") 1090 return 1091 } 1092 1093 // set the pat in the users config 1094 if outp, err := cmd.Exec("user", "config", "set", "git.credentials.url", "github.com"); err != nil { 1095 t.Fatalf("Expected no error, got %v %v", err, string(outp)) 1096 return 1097 } 1098 1099 if outp, err := cmd.Exec("user", "config", "set", "git.credentials.token", pat); err != nil { 1100 t.Fatalf("Expected no error, got %v %v", err, string(outp)) 1101 return 1102 } 1103 1104 // run the service 1105 if outp, err := cmd.Exec("run", "--image", "localhost:5000/cells:v3", "github.com/micro/test/helloworld"+branch); err != nil { 1106 t.Fatalf("Expected no run error, got %v %v", err, string(outp)) 1107 return 1108 } 1109 1110 if err := Try("Find micro/test/helloworld in runtime", t, func() ([]byte, error) { 1111 outp, err := cmd.Exec("status") 1112 if err != nil { 1113 return outp, err 1114 } 1115 1116 if !statusRunning("helloworld", version, outp) { 1117 return outp, errors.New("Can't find helloworld service in runtime") 1118 } 1119 return outp, err 1120 }, 60*time.Second); err != nil { 1121 return 1122 } 1123 1124 if err := Try("Find helloworld in registry", t, func() ([]byte, error) { 1125 outp, err := cmd.Exec("services") 1126 if err != nil { 1127 return outp, err 1128 } 1129 if !strings.Contains(string(outp), "helloworld") { 1130 return outp, errors.New("Does not contain helloworld") 1131 } 1132 return outp, err 1133 }, 300*time.Second); err != nil { 1134 outp, _ := cmd.Exec("logs", "helloworld") 1135 t.Logf("logs %s", string(outp)) 1136 return 1137 } 1138 1139 // call the service 1140 if err := Try("Calling helloworld", t, func() ([]byte, error) { 1141 return cmd.Exec("helloworld", "--name=John") 1142 }, 30*time.Second); err != nil { 1143 return 1144 } 1145 } 1146 1147 func TestGitSourceUpdateByShortName(t *testing.T) { 1148 TrySuite(t, testGitSourceUpdateByShortName, retryCount) 1149 } 1150 1151 func testGitSourceUpdateByShortName(t *T) { 1152 t.Parallel() 1153 serv := NewServer(t, WithLogin()) 1154 defer serv.Close() 1155 if err := serv.Run(); err != nil { 1156 return 1157 } 1158 1159 cmd := serv.Command() 1160 1161 // run the service 1162 if outp, err := cmd.Exec("run", "github.com/m3o/services/invite"); err != nil { 1163 t.Fatalf("Expected no error, got %v %v", err, string(outp)) 1164 return 1165 } 1166 1167 if err := Try("Find invite in runtime", t, func() ([]byte, error) { 1168 outp, err := cmd.Exec("status") 1169 if err != nil { 1170 return outp, err 1171 } 1172 1173 if !statusRunning("invite", version, outp) { 1174 return outp, errors.New("Can't find subfolder-test service in runtime") 1175 } 1176 return outp, err 1177 }, 60*time.Second); err != nil { 1178 return 1179 } 1180 1181 if err := Try("Find invite in registry", t, func() ([]byte, error) { 1182 outp, err := cmd.Exec("services") 1183 if err != nil { 1184 return outp, err 1185 } 1186 if !strings.Contains(string(outp), "invite") { 1187 return outp, errors.New("Does not contain invite") 1188 } 1189 return outp, err 1190 }, 300*time.Second); err != nil { 1191 outp, _ := cmd.Exec("logs", "invite") 1192 t.Log(string(outp)) 1193 return 1194 } 1195 1196 // call the service 1197 if err := Try("Calling invite", t, func() ([]byte, error) { 1198 outp, _ := cmd.Exec("logs", "-n=1000", "invite") 1199 outp1, err := cmd.Exec("invite", "--help") 1200 1201 return append(outp1, outp...), err 1202 }, 70*time.Second); err != nil { 1203 return 1204 } 1205 1206 // update service 1207 1208 // run the service 1209 if outp, err := cmd.Exec("update", "invite"+branch); err != nil { 1210 t.Fatalf("Expected no error, got %v %v", err, string(outp)) 1211 return 1212 } 1213 1214 // look for disconnect 1215 if err := Try("Find invite disconnect proof in logs", t, func() ([]byte, error) { 1216 outp, err := cmd.Exec("logs", "invite") 1217 if err != nil { 1218 return outp, err 1219 } 1220 if !strings.Contains(string(outp), "Disconnect") { 1221 return outp, errors.New("Does not contain Disconnect") 1222 } 1223 return outp, err 1224 }, 40*time.Second); err != nil { 1225 outp, _ := cmd.Exec("logs", "invite") 1226 t.Log(string(outp)) 1227 return 1228 } 1229 1230 if err := Try("Find invite in runtime", t, func() ([]byte, error) { 1231 outp, err := cmd.Exec("status") 1232 if err != nil { 1233 return outp, err 1234 } 1235 1236 if !statusRunning("invite", version, outp) { 1237 return outp, errors.New("Can't find invite service in runtime") 1238 } 1239 return outp, err 1240 }, 60*time.Second); err != nil { 1241 return 1242 } 1243 1244 if err := Try("Find invite in registry", t, func() ([]byte, error) { 1245 outp, err := cmd.Exec("services") 1246 if err != nil { 1247 return outp, err 1248 } 1249 if !strings.Contains(string(outp), "invite") { 1250 return outp, errors.New("Does not contain example") 1251 } 1252 return outp, err 1253 }, 300*time.Second); err != nil { 1254 outp, _ := cmd.Exec("logs", "invite") 1255 t.Log(string(outp)) 1256 return 1257 } 1258 1259 // call the service 1260 if err := Try("Calling invite", t, func() ([]byte, error) { 1261 outp, _ := cmd.Exec("logs", "-n=1000", "invite") 1262 outp1, err := cmd.Exec("invite", "--help") 1263 1264 return append(outp1, outp...), err 1265 }, 70*time.Second); err != nil { 1266 return 1267 } 1268 } 1269 1270 func TestRunPrivateGitlabSource(t *testing.T) { 1271 TrySuite(t, testRunPrivateGitlabSource, retryCount) 1272 } 1273 1274 func testRunPrivateGitlabSource(t *T) { 1275 t.Parallel() 1276 serv := NewServer(t, WithLogin()) 1277 defer serv.Close() 1278 if err := serv.Run(); err != nil { 1279 return 1280 } 1281 1282 cmd := serv.Command() 1283 1284 // get the git credentials, injected by the k8s integration test 1285 pat := os.Getenv("GITLAB_PAT") 1286 if len(pat) == 0 { 1287 t.Logf("Skipping test, missing GITLAB_PAT") 1288 return 1289 } 1290 1291 // set the pat in the users config 1292 if outp, err := cmd.Exec("user", "config", "set", "git.credentials.gitlab", pat); err != nil { 1293 t.Fatalf("Expected no error, got %v %v", err, string(outp)) 1294 return 1295 } 1296 1297 // run the service 1298 if outp, err := cmd.Exec("run", "--image", "localhost:5000/cells:v3", "gitlab.com/micro-test/private-monorepo-test/subfolder-test"); err != nil { 1299 t.Fatalf("Expected no error, got %v %v", err, string(outp)) 1300 return 1301 } 1302 1303 if err := Try("Find subfolder-test in runtime", t, func() ([]byte, error) { 1304 outp, err := cmd.Exec("status") 1305 if err != nil { 1306 return outp, err 1307 } 1308 1309 if !statusRunning("subfolder-test", version, outp) { 1310 return outp, errors.New("Can't find subfolder-test service in runtime") 1311 } 1312 return outp, err 1313 }, 60*time.Second); err != nil { 1314 return 1315 } 1316 1317 if err := Try("Find example in registry", t, func() ([]byte, error) { 1318 outp, err := cmd.Exec("services") 1319 if err != nil { 1320 return outp, err 1321 } 1322 if !strings.Contains(string(outp), "example") { 1323 return outp, errors.New("Does not contain example") 1324 } 1325 return outp, err 1326 }, 300*time.Second); err != nil { 1327 outp, _ := cmd.Exec("logs", "subfolder-test") 1328 t.Log(string(outp)) 1329 return 1330 } 1331 } 1332 1333 func TestRunPrivateGenericRemote(t *testing.T) { 1334 TrySuite(t, testRunPrivateGenericRemote, retryCount) 1335 } 1336 1337 func testRunPrivateGenericRemote(t *T) { 1338 t.Parallel() 1339 serv := NewServer(t, WithLogin()) 1340 defer serv.Close() 1341 if err := serv.Run(); err != nil { 1342 return 1343 } 1344 1345 cmd := serv.Command() 1346 1347 // get the git credentials, injected by the k8s integration test 1348 pat := os.Getenv("BITBUCKET_PAT") 1349 if len(pat) == 0 { 1350 t.Logf("Skipping test, missing BITBUCKET_PAT") 1351 return 1352 } 1353 1354 // set the pat in the users config 1355 if outp, err := cmd.Exec("user", "config", "set", "git.credentials.bitbucket", pat); err != nil { 1356 t.Fatalf("Expected no error, got %v %v", err, string(outp)) 1357 return 1358 } 1359 1360 // run the service 1361 if outp, err := cmd.Exec("run", "--image", "localhost:5000/cells:v3", "bitbucket.org/micro-test/private-monorepo-test/subfolder-test"); err != nil { 1362 t.Fatalf("Expected no error, got %v %v", err, string(outp)) 1363 return 1364 } 1365 1366 if err := Try("Find micro/test/helloworld in runtime", t, func() ([]byte, error) { 1367 outp, err := cmd.Exec("status") 1368 if err != nil { 1369 return outp, err 1370 } 1371 1372 if !statusRunning("subfolder-test", version, outp) { 1373 return outp, errors.New("Can't find helloworld service in runtime") 1374 } 1375 return outp, err 1376 }, 60*time.Second); err != nil { 1377 return 1378 } 1379 1380 if err := Try("Find helloworld in registry", t, func() ([]byte, error) { 1381 outp, err := cmd.Exec("services") 1382 if err != nil { 1383 return outp, err 1384 } 1385 if !strings.Contains(string(outp), "example") { 1386 return outp, errors.New("Does not contain example") 1387 } 1388 return outp, err 1389 }, 300*time.Second); err != nil { 1390 outp, _ := cmd.Exec("logs", "subfolder-test") 1391 t.Log(string(outp)) 1392 return 1393 } 1394 1395 // call the service 1396 if err := Try("Calling example", t, func() ([]byte, error) { 1397 return cmd.Exec("example", "--name=John") 1398 }, 30*time.Second); err != nil { 1399 return 1400 } 1401 1402 // update service 1403 1404 // run the service 1405 if outp, err := cmd.Exec("run", "--image", "localhost:5000/cells:v3", "gitlab.com/micro-test/private-monorepo-test/subfolder-test"+branch); err != nil { 1406 t.Fatalf("Expected no error, got %v %v", err, string(outp)) 1407 return 1408 } 1409 1410 // We need a better way of knowing the server restarted than a sleep... 1411 time.Sleep(5 * time.Second) 1412 1413 if err := Try("Find micro/test/helloworld in runtime", t, func() ([]byte, error) { 1414 outp, err := cmd.Exec("status") 1415 if err != nil { 1416 return outp, err 1417 } 1418 1419 if !statusRunning("subfolder-test", version, outp) { 1420 return outp, errors.New("Can't find helloworld service in runtime") 1421 } 1422 return outp, err 1423 }, 60*time.Second); err != nil { 1424 return 1425 } 1426 1427 if err := Try("Find helloworld in registry", t, func() ([]byte, error) { 1428 outp, err := cmd.Exec("services") 1429 if err != nil { 1430 return outp, err 1431 } 1432 if !strings.Contains(string(outp), "example") { 1433 return outp, errors.New("Does not contain example") 1434 } 1435 return outp, err 1436 }, 300*time.Second); err != nil { 1437 outp, _ := cmd.Exec("logs", "subfolder-test") 1438 t.Log(string(outp)) 1439 return 1440 } 1441 1442 // call the service 1443 if err := Try("Calling example", t, func() ([]byte, error) { 1444 return cmd.Exec("example", "--name=John") 1445 }, 30*time.Second); err != nil { 1446 return 1447 } 1448 } 1449 1450 func TestIdiomaticFolderStructure(t *testing.T) { 1451 TrySuite(t, testIdiomaticFolderStructure, retryCount) 1452 } 1453 1454 func testIdiomaticFolderStructure(t *T) { 1455 t.Parallel() 1456 serv := NewServer(t, WithLogin()) 1457 defer serv.Close() 1458 if err := serv.Run(); err != nil { 1459 return 1460 } 1461 1462 cmd := serv.Command() 1463 src := "./services/test/template" 1464 if outp, err := cmd.Exec("run", "--image", "localhost:5000/cells:v3", src); err != nil { 1465 t.Fatalf("Error running service: %v, %v", err, string(outp)) 1466 return 1467 } 1468 1469 if err := Try("Find template service in the registry", t, func() ([]byte, error) { 1470 outp, err := cmd.Exec("status") 1471 outp1, _ := cmd.Exec("logs", "template") 1472 if err != nil { 1473 return append(outp, outp1...), err 1474 } 1475 1476 // The started service should have the runtime name of "service/example", 1477 // as the runtime name is the relative path inside a repo. 1478 if !statusRunning("template", "latest", outp) { 1479 return outp, errors.New("Can't find template service in runtime") 1480 } 1481 return outp, err 1482 }, 120*time.Second); err != nil { 1483 return 1484 } 1485 }