How to use terminateContainerOnEnd method of testcontainers Package

Best Testcontainers-go code snippet using testcontainers.terminateContainerOnEnd

docker_test.go

Source:docker_test.go Github

copy

Full Screen

...77 require.NoError(t, newNetwork.Remove(ctx))78 })79 nginx, err := GenericContainer(ctx, gcr)80 require.NoError(t, err)81 terminateContainerOnEnd(t, ctx, nginx)82 networks, err := nginx.Networks(ctx)83 if err != nil {84 t.Fatal(err)85 }86 if len(networks) != 1 {87 t.Errorf("Expected networks 1. Got '%d'.", len(networks))88 }89 network := networks[0]90 if network != networkName {91 t.Errorf("Expected network name '%s'. Got '%s'.", networkName, network)92 }93 networkAliases, err := nginx.NetworkAliases(ctx)94 if err != nil {95 t.Fatal(err)96 }97 if len(networkAliases) != 1 {98 t.Errorf("Expected network aliases for 1 network. Got '%d'.", len(networkAliases))99 }100 networkAlias := networkAliases[networkName]101 require.NotEmpty(t, networkAlias)102 for _, alias := range aliases {103 require.Contains(t, networkAlias, alias)104 }105 networkIP, err := nginx.ContainerIP(ctx)106 if err != nil {107 t.Fatal(err)108 }109 if len(networkIP) == 0 {110 t.Errorf("Expected an IP address, got %v", networkIP)111 }112}113func TestContainerWithHostNetworkOptions(t *testing.T) {114 absPath, err := filepath.Abs("./testresources/nginx-highport.conf")115 if err != nil {116 t.Fatal(err)117 }118 ctx := context.Background()119 gcr := GenericContainerRequest{120 ProviderType: providerType,121 ContainerRequest: ContainerRequest{122 Image: nginxAlpineImage,123 Privileged: true,124 SkipReaper: true,125 NetworkMode: "host",126 Mounts: Mounts(BindMount(absPath, "/etc/nginx/conf.d/default.conf")),127 ExposedPorts: []string{128 nginxHighPort,129 },130 WaitingFor: wait.ForListeningPort(nginxHighPort),131 },132 Started: true,133 }134 nginxC, err := GenericContainer(ctx, gcr)135 require.NoError(t, err)136 terminateContainerOnEnd(t, ctx, nginxC)137 // host, err := nginxC.Host(ctx)138 // if err != nil {139 // t.Errorf("Expected host %s. Got '%d'.", host, err)140 // }141 //142 endpoint, err := nginxC.PortEndpoint(ctx, nginxHighPort, "http")143 if err != nil {144 t.Errorf("Expected server endpoint. Got '%v'.", err)145 }146 _, err = http.Get(endpoint)147 if err != nil {148 t.Errorf("Expected OK response. Got '%d'.", err)149 }150}151func TestContainerWithHostNetworkOptions_UseExposePortsFromImageConfigs(t *testing.T) {152 ctx := context.Background()153 gcr := GenericContainerRequest{154 ContainerRequest: ContainerRequest{155 Image: "nginx",156 Privileged: true,157 SkipReaper: true,158 WaitingFor: wait.ForExposedPort(),159 },160 Started: true,161 }162 nginxC, err := GenericContainer(ctx, gcr)163 if err != nil {164 t.Fatal(err)165 }166 defer nginxC.Terminate(ctx)167 endpoint, err := nginxC.Endpoint(ctx, "http")168 if err != nil {169 t.Errorf("Expected server endpoint. Got '%v'.", err)170 }171 _, err = http.Get(endpoint)172 if err != nil {173 t.Errorf("Expected OK response. Got '%d'.", err)174 }175}176func TestContainerWithNetworkModeAndNetworkTogether(t *testing.T) {177 ctx := context.Background()178 gcr := GenericContainerRequest{179 ProviderType: providerType,180 ContainerRequest: ContainerRequest{181 Image: nginxImage,182 SkipReaper: true,183 NetworkMode: "host",184 Networks: []string{"new-network"},185 },186 Started: true,187 }188 nginx, err := GenericContainer(ctx, gcr)189 if err != nil {190 // Error when NetworkMode = host and Network = []string{"bridge"}191 t.Logf("Can't use Network and NetworkMode together, %s", err)192 }193 defer nginx.Terminate(ctx)194}195func TestContainerWithHostNetworkOptionsAndWaitStrategy(t *testing.T) {196 ctx := context.Background()197 absPath, err := filepath.Abs("./testresources/nginx-highport.conf")198 if err != nil {199 t.Fatal(err)200 }201 gcr := GenericContainerRequest{202 ProviderType: providerType,203 ContainerRequest: ContainerRequest{204 Image: nginxAlpineImage,205 SkipReaper: true,206 NetworkMode: "host",207 WaitingFor: wait.ForListeningPort(nginxHighPort),208 Mounts: Mounts(BindMount(absPath, "/etc/nginx/conf.d/default.conf")),209 },210 Started: true,211 }212 nginxC, err := GenericContainer(ctx, gcr)213 require.NoError(t, err)214 terminateContainerOnEnd(t, ctx, nginxC)215 host, err := nginxC.Host(ctx)216 if err != nil {217 t.Errorf("Expected host %s. Got '%d'.", host, err)218 }219 _, err = http.Get("http://" + host + ":8080")220 if err != nil {221 t.Errorf("Expected OK response. Got '%v'.", err)222 }223}224func TestContainerWithHostNetworkAndEndpoint(t *testing.T) {225 ctx := context.Background()226 absPath, err := filepath.Abs("./testresources/nginx-highport.conf")227 if err != nil {228 t.Fatal(err)229 }230 gcr := GenericContainerRequest{231 ProviderType: providerType,232 ContainerRequest: ContainerRequest{233 Image: nginxAlpineImage,234 SkipReaper: true,235 NetworkMode: "host",236 WaitingFor: wait.ForListeningPort(nginxHighPort),237 Mounts: Mounts(BindMount(absPath, "/etc/nginx/conf.d/default.conf")),238 },239 Started: true,240 }241 nginxC, err := GenericContainer(ctx, gcr)242 require.NoError(t, err)243 terminateContainerOnEnd(t, ctx, nginxC)244 hostN, err := nginxC.PortEndpoint(ctx, nginxHighPort, "http")245 if err != nil {246 t.Errorf("Expected host %s. Got '%d'.", hostN, err)247 }248 t.Log(hostN)249 _, err = http.Get(hostN)250 if err != nil {251 t.Errorf("Expected OK response. Got '%v'.", err)252 }253}254func TestContainerWithHostNetworkAndPortEndpoint(t *testing.T) {255 ctx := context.Background()256 absPath, err := filepath.Abs("./testresources/nginx-highport.conf")257 if err != nil {258 t.Fatal(err)259 }260 gcr := GenericContainerRequest{261 ProviderType: providerType,262 ContainerRequest: ContainerRequest{263 Image: nginxAlpineImage,264 SkipReaper: true,265 NetworkMode: "host",266 WaitingFor: wait.ForListeningPort(nginxHighPort),267 Mounts: Mounts(BindMount(absPath, "/etc/nginx/conf.d/default.conf")),268 },269 Started: true,270 }271 nginxC, err := GenericContainer(ctx, gcr)272 require.NoError(t, err)273 terminateContainerOnEnd(t, ctx, nginxC)274 origin, err := nginxC.PortEndpoint(ctx, nginxHighPort, "http")275 if err != nil {276 t.Errorf("Expected host %s. Got '%d'.", origin, err)277 }278 t.Log(origin)279 _, err = http.Get(origin)280 if err != nil {281 t.Errorf("Expected OK response. Got '%d'.", err)282 }283}284func TestContainerReturnItsContainerID(t *testing.T) {285 ctx := context.Background()286 nginxA, err := GenericContainer(ctx, GenericContainerRequest{287 ProviderType: providerType,288 ContainerRequest: ContainerRequest{289 Image: nginxAlpineImage,290 ExposedPorts: []string{291 nginxDefaultPort,292 },293 },294 })295 require.NoError(t, err)296 terminateContainerOnEnd(t, ctx, nginxA)297 if nginxA.GetContainerID() == "" {298 t.Errorf("expected a containerID but we got an empty string.")299 }300}301func TestContainerStartsWithoutTheReaper(t *testing.T) {302 ctx := context.Background()303 client, err := client.NewClientWithOpts(client.FromEnv)304 if err != nil {305 t.Fatal(err)306 }307 client.NegotiateAPIVersion(ctx)308 var container Container309 container, err = GenericContainer(ctx, GenericContainerRequest{310 ProviderType: providerType,311 ContainerRequest: ContainerRequest{312 Image: nginxAlpineImage,313 ExposedPorts: []string{314 nginxDefaultPort,315 },316 SkipReaper: true,317 },318 Started: true,319 })320 require.NoError(t, err)321 terminateContainerOnEnd(t, ctx, container)322 resp, err := client.ContainerList(ctx, types.ContainerListOptions{323 Filters: filters.NewArgs(filters.Arg("label", fmt.Sprintf("%s=%s", TestcontainerLabelSessionID, container.SessionID()))),324 })325 if err != nil {326 t.Fatal(err)327 }328 if len(resp) != 0 {329 t.Fatal("expected zero reaper running.")330 }331}332func TestContainerStartsWithTheReaper(t *testing.T) {333 ctx := context.Background()334 client, err := client.NewClientWithOpts(client.FromEnv)335 if err != nil {336 t.Fatal(err)337 }338 client.NegotiateAPIVersion(ctx)339 _, err = GenericContainer(ctx, GenericContainerRequest{340 ProviderType: providerType,341 ContainerRequest: ContainerRequest{342 Image: nginxAlpineImage,343 ExposedPorts: []string{344 nginxDefaultPort,345 },346 },347 Started: true,348 })349 if err != nil {350 t.Fatal(err)351 }352 filtersJSON := fmt.Sprintf(`{"label":{"%s":true}}`, TestcontainerLabelIsReaper)353 f, err := filters.FromJSON(filtersJSON)354 if err != nil {355 t.Fatal(err)356 }357 resp, err := client.ContainerList(ctx, types.ContainerListOptions{358 Filters: f,359 })360 if err != nil {361 t.Fatal(err)362 }363 if len(resp) == 0 {364 t.Fatal("expected at least one reaper to be running.")365 }366}367func TestContainerTerminationResetsState(t *testing.T) {368 ctx := context.Background()369 nginxA, err := GenericContainer(ctx, GenericContainerRequest{370 ProviderType: providerType,371 ContainerRequest: ContainerRequest{372 Image: nginxAlpineImage,373 ExposedPorts: []string{374 nginxDefaultPort,375 },376 SkipReaper: true,377 },378 Started: true,379 })380 if err != nil {381 t.Fatal(err)382 }383 err = nginxA.Terminate(ctx)384 if err != nil {385 t.Fatal(err)386 }387 if nginxA.SessionID() != "00000000-0000-0000-0000-000000000000" {388 t.Fatal("Internal state must be reset.")389 }390 ports, err := nginxA.Ports(ctx)391 if err == nil || ports != nil {392 t.Fatal("expected error from container inspect.")393 }394}395func TestContainerStopWithReaper(t *testing.T) {396 ctx := context.Background()397 nginxA, err := GenericContainer(ctx, GenericContainerRequest{398 ProviderType: providerType,399 ContainerRequest: ContainerRequest{400 Image: nginxAlpineImage,401 ExposedPorts: []string{402 nginxDefaultPort,403 },404 },405 Started: true,406 })407 require.NoError(t, err)408 terminateContainerOnEnd(t, ctx, nginxA)409 state, err := nginxA.State(ctx)410 if err != nil {411 t.Fatal(err)412 }413 if state.Running != true {414 t.Fatal("The container shoud be in running state")415 }416 stopTimeout := 10 * time.Second417 err = nginxA.Stop(ctx, &stopTimeout)418 if err != nil {419 t.Fatal(err)420 }421 state, err = nginxA.State(ctx)422 if err != nil {423 t.Fatal(err)424 }425 if state.Running != false {426 t.Fatal("The container shoud not be running")427 }428 if state.Status != "exited" {429 t.Fatal("The container shoud be in exited state")430 }431}432func TestContainerTerminationWithReaper(t *testing.T) {433 ctx := context.Background()434 nginxA, err := GenericContainer(ctx, GenericContainerRequest{435 ProviderType: providerType,436 ContainerRequest: ContainerRequest{437 Image: nginxAlpineImage,438 ExposedPorts: []string{439 nginxDefaultPort,440 },441 },442 Started: true,443 })444 if err != nil {445 t.Fatal(err)446 }447 state, err := nginxA.State(ctx)448 if err != nil {449 t.Fatal(err)450 }451 if state.Running != true {452 t.Fatal("The container shoud be in running state")453 }454 err = nginxA.Terminate(ctx)455 if err != nil {456 t.Fatal(err)457 }458 _, err = nginxA.State(ctx)459 if err == nil {460 t.Fatal("expected error from container inspect.")461 }462}463func TestContainerTerminationWithoutReaper(t *testing.T) {464 ctx := context.Background()465 nginxA, err := GenericContainer(ctx, GenericContainerRequest{466 ProviderType: providerType,467 ContainerRequest: ContainerRequest{468 Image: nginxAlpineImage,469 ExposedPorts: []string{470 nginxDefaultPort,471 },472 SkipReaper: true,473 },474 Started: true,475 })476 if err != nil {477 t.Fatal(err)478 }479 state, err := nginxA.State(ctx)480 if err != nil {481 t.Fatal(err)482 }483 if state.Running != true {484 t.Fatal("The container shoud be in running state")485 }486 err = nginxA.Terminate(ctx)487 if err != nil {488 t.Fatal(err)489 }490 _, err = nginxA.State(ctx)491 if err == nil {492 t.Fatal("expected error from container inspect.")493 }494}495func TestContainerTerminationRemovesDockerImage(t *testing.T) {496 t.Run("if not built from Dockerfile", func(t *testing.T) {497 ctx := context.Background()498 client, err := client.NewClientWithOpts(client.FromEnv)499 if err != nil {500 t.Fatal(err)501 }502 client.NegotiateAPIVersion(ctx)503 container, err := GenericContainer(ctx, GenericContainerRequest{504 ProviderType: providerType,505 ContainerRequest: ContainerRequest{506 Image: nginxAlpineImage,507 ExposedPorts: []string{508 nginxDefaultPort,509 },510 SkipReaper: true,511 },512 Started: true,513 })514 if err != nil {515 t.Fatal(err)516 }517 err = container.Terminate(ctx)518 if err != nil {519 t.Fatal(err)520 }521 _, _, err = client.ImageInspectWithRaw(ctx, nginxAlpineImage)522 if err != nil {523 t.Fatal("nginx image should not have been removed")524 }525 })526 t.Run("if built from Dockerfile", func(t *testing.T) {527 ctx := context.Background()528 client, err := client.NewClientWithOpts(client.FromEnv)529 if err != nil {530 t.Fatal(err)531 }532 client.NegotiateAPIVersion(ctx)533 req := ContainerRequest{534 FromDockerfile: FromDockerfile{535 Context: "./testresources",536 },537 ExposedPorts: []string{"6379/tcp"},538 WaitingFor: wait.ForLog("Ready to accept connections"),539 }540 container, err := GenericContainer(ctx, GenericContainerRequest{541 ProviderType: providerType,542 ContainerRequest: req,543 Started: true,544 })545 if err != nil {546 t.Fatal(err)547 }548 containerID := container.GetContainerID()549 resp, err := client.ContainerInspect(ctx, containerID)550 if err != nil {551 t.Fatal(err)552 }553 imageID := resp.Config.Image554 err = container.Terminate(ctx)555 if err != nil {556 t.Fatal(err)557 }558 _, _, err = client.ImageInspectWithRaw(ctx, imageID)559 if err == nil {560 t.Fatal("custom built image should have been removed")561 }562 })563}564func TestTwoContainersExposingTheSamePort(t *testing.T) {565 ctx := context.Background()566 nginxA, err := GenericContainer(ctx, GenericContainerRequest{567 ProviderType: providerType,568 ContainerRequest: ContainerRequest{569 Image: nginxAlpineImage,570 ExposedPorts: []string{571 nginxDefaultPort,572 },573 },574 Started: true,575 })576 require.NoError(t, err)577 terminateContainerOnEnd(t, ctx, nginxA)578 nginxB, err := GenericContainer(ctx, GenericContainerRequest{579 ProviderType: providerType,580 ContainerRequest: ContainerRequest{581 Image: nginxAlpineImage,582 ExposedPorts: []string{583 nginxDefaultPort,584 },585 WaitingFor: wait.ForListeningPort(nginxDefaultPort),586 },587 Started: true,588 })589 require.NoError(t, err)590 terminateContainerOnEnd(t, ctx, nginxB)591 endpointA, err := nginxA.PortEndpoint(ctx, nginxDefaultPort, "http")592 require.NoError(t, err)593 resp, err := http.Get(endpointA)594 if err != nil {595 t.Fatal(err)596 }597 if resp.StatusCode != http.StatusOK {598 t.Errorf("Expected status code %d. Got %d.", http.StatusOK, resp.StatusCode)599 }600 endpointB, err := nginxB.PortEndpoint(ctx, nginxDefaultPort, "http")601 resp, err = http.Get(endpointB)602 if err != nil {603 t.Fatal(err)604 }605 if resp.StatusCode != http.StatusOK {606 t.Errorf("Expected status code %d. Got %d.", http.StatusOK, resp.StatusCode)607 }608}609func TestContainerCreation(t *testing.T) {610 ctx := context.Background()611 nginxC, err := GenericContainer(ctx, GenericContainerRequest{612 ProviderType: providerType,613 ContainerRequest: ContainerRequest{614 Image: nginxAlpineImage,615 ExposedPorts: []string{616 nginxDefaultPort,617 },618 WaitingFor: wait.ForListeningPort(nginxDefaultPort),619 },620 Started: true,621 })622 require.NoError(t, err)623 terminateContainerOnEnd(t, ctx, nginxC)624 endpoint, err := nginxC.PortEndpoint(ctx, nginxDefaultPort, "http")625 require.NoError(t, err)626 resp, err := http.Get(endpoint)627 if err != nil {628 t.Fatal(err)629 }630 if resp.StatusCode != http.StatusOK {631 t.Errorf("Expected status code %d. Got %d.", http.StatusOK, resp.StatusCode)632 }633 networkIP, err := nginxC.ContainerIP(ctx)634 if err != nil {635 t.Fatal(err)636 }637 if len(networkIP) == 0 {638 t.Errorf("Expected an IP address, got %v", networkIP)639 }640 networkAliases, err := nginxC.NetworkAliases(ctx)641 if err != nil {642 t.Fatal(err)643 }644 if len(networkAliases) != 1 {645 fmt.Printf("%v", networkAliases)646 t.Errorf("Expected number of connected networks %d. Got %d.", 0, len(networkAliases))647 }648 if len(networkAliases["bridge"]) != 0 {649 t.Errorf("Expected number of aliases for 'bridge' network %d. Got %d.", 0, len(networkAliases["bridge"]))650 }651}652func TestContainerIPs(t *testing.T) {653 ctx := context.Background()654 networkName := "new-network"655 newNetwork, err := GenericNetwork(ctx, GenericNetworkRequest{656 ProviderType: providerType,657 NetworkRequest: NetworkRequest{658 Name: networkName,659 CheckDuplicate: true,660 },661 })662 if err != nil {663 t.Fatal(err)664 }665 t.Cleanup(func() {666 require.NoError(t, newNetwork.Remove(ctx))667 })668 nginxC, err := GenericContainer(ctx, GenericContainerRequest{669 ProviderType: providerType,670 ContainerRequest: ContainerRequest{671 Image: nginxAlpineImage,672 ExposedPorts: []string{673 nginxDefaultPort,674 },675 Networks: []string{676 "bridge",677 networkName,678 },679 WaitingFor: wait.ForListeningPort(nginxDefaultPort),680 },681 Started: true,682 })683 require.NoError(t, err)684 terminateContainerOnEnd(t, ctx, nginxC)685 ips, err := nginxC.ContainerIPs(ctx)686 if err != nil {687 t.Fatal(err)688 }689 if len(ips) != 2 {690 t.Errorf("Expected two IP addresses, got %v", len(ips))691 }692}693func TestContainerCreationWithName(t *testing.T) {694 ctx := context.Background()695 creationName := fmt.Sprintf("%s_%d", "test_container", time.Now().Unix())696 expectedName := "/" + creationName // inspect adds '/' in the beginning697 nginxC, err := GenericContainer(ctx, GenericContainerRequest{698 ProviderType: providerType,699 ContainerRequest: ContainerRequest{700 Image: nginxAlpineImage,701 ExposedPorts: []string{702 nginxDefaultPort,703 },704 WaitingFor: wait.ForListeningPort(nginxDefaultPort),705 Name: creationName,706 Networks: []string{"bridge"},707 },708 Started: true,709 })710 require.NoError(t, err)711 terminateContainerOnEnd(t, ctx, nginxC)712 name, err := nginxC.Name(ctx)713 if err != nil {714 t.Fatal(err)715 }716 if name != expectedName {717 t.Errorf("Expected container name '%s'. Got '%s'.", expectedName, name)718 }719 networks, err := nginxC.Networks(ctx)720 if err != nil {721 t.Fatal(err)722 }723 if len(networks) != 1 {724 t.Errorf("Expected networks 1. Got '%d'.", len(networks))725 }726 network := networks[0]727 switch providerType {728 case ProviderDocker:729 if network != Bridge {730 t.Errorf("Expected network name '%s'. Got '%s'.", Bridge, network)731 }732 case ProviderPodman:733 if network != Podman {734 t.Errorf("Expected network name '%s'. Got '%s'.", Podman, network)735 }736 }737 endpoint, err := nginxC.PortEndpoint(ctx, nginxDefaultPort, "http")738 require.NoError(t, err)739 resp, err := http.Get(endpoint)740 if err != nil {741 t.Fatal(err)742 }743 if resp.StatusCode != http.StatusOK {744 t.Errorf("Expected status code %d. Got %d.", http.StatusOK, resp.StatusCode)745 }746}747func TestContainerCreationAndWaitForListeningPortLongEnough(t *testing.T) {748 ctx := context.Background()749 // delayed-nginx will wait 2s before opening port750 nginxC, err := GenericContainer(ctx, GenericContainerRequest{751 ProviderType: providerType,752 ContainerRequest: ContainerRequest{753 Image: "docker.io/menedev/delayed-nginx:1.15.2",754 ExposedPorts: []string{755 nginxDefaultPort,756 },757 WaitingFor: wait.ForListeningPort(nginxDefaultPort), // default startupTimeout is 60s758 },759 Started: true,760 })761 require.NoError(t, err)762 terminateContainerOnEnd(t, ctx, nginxC)763 origin, err := nginxC.PortEndpoint(ctx, nginxDefaultPort, "http")764 if err != nil {765 t.Fatal(err)766 }767 resp, err := http.Get(origin)768 if err != nil {769 t.Fatal(err)770 }771 if resp.StatusCode != http.StatusOK {772 t.Errorf("Expected status code %d. Got %d.", http.StatusOK, resp.StatusCode)773 }774}775func TestContainerCreationTimesOut(t *testing.T) {776 ctx := context.Background()777 // delayed-nginx will wait 2s before opening port778 nginxC, err := GenericContainer(ctx, GenericContainerRequest{779 ProviderType: providerType,780 ContainerRequest: ContainerRequest{781 Image: "docker.io/menedev/delayed-nginx:1.15.2",782 ExposedPorts: []string{783 nginxDefaultPort,784 },785 WaitingFor: wait.ForListeningPort(nginxDefaultPort).WithStartupTimeout(1 * time.Second),786 },787 Started: true,788 })789 if err == nil {790 t.Error("Expected timeout")791 err := nginxC.Terminate(ctx)792 if err != nil {793 t.Fatal(err)794 }795 }796}797func TestContainerRespondsWithHttp200ForIndex(t *testing.T) {798 ctx := context.Background()799 // delayed-nginx will wait 2s before opening port800 nginxC, err := GenericContainer(ctx, GenericContainerRequest{801 ProviderType: providerType,802 ContainerRequest: ContainerRequest{803 Image: nginxAlpineImage,804 ExposedPorts: []string{805 nginxDefaultPort,806 },807 WaitingFor: wait.ForHTTP("/"),808 },809 Started: true,810 })811 require.NoError(t, err)812 terminateContainerOnEnd(t, ctx, nginxC)813 origin, err := nginxC.PortEndpoint(ctx, nginxDefaultPort, "http")814 if err != nil {815 t.Fatal(err)816 }817 resp, err := http.Get(origin)818 if err != nil {819 t.Error(err)820 }821 if resp.StatusCode != http.StatusOK {822 t.Errorf("Expected status code %d. Got %d.", http.StatusOK, resp.StatusCode)823 }824}825func TestContainerCreationTimesOutWithHttp(t *testing.T) {826 ctx := context.Background()827 // delayed-nginx will wait 2s before opening port828 nginxC, err := GenericContainer(ctx, GenericContainerRequest{829 ProviderType: providerType,830 ContainerRequest: ContainerRequest{831 Image: "docker.io/menedev/delayed-nginx:1.15.2",832 ExposedPorts: []string{833 nginxDefaultPort,834 },835 WaitingFor: wait.ForHTTP("/").WithStartupTimeout(1 * time.Second),836 },837 Started: true,838 })839 terminateContainerOnEnd(t, ctx, nginxC)840 if err == nil {841 t.Error("Expected timeout")842 }843}844func TestContainerCreationWaitsForLogContextTimeout(t *testing.T) {845 ctx := context.Background()846 req := ContainerRequest{847 Image: "docker.io/mysql:latest",848 ExposedPorts: []string{"3306/tcp", "33060/tcp"},849 Env: map[string]string{850 "MYSQL_ROOT_PASSWORD": "password",851 "MYSQL_DATABASE": "database",852 },853 WaitingFor: wait.ForLog("test context timeout").WithStartupTimeout(1 * time.Second),854 }855 _, err := GenericContainer(ctx, GenericContainerRequest{856 ProviderType: providerType,857 ContainerRequest: req,858 Started: true,859 })860 if err == nil {861 t.Error("Expected timeout")862 }863}864func TestContainerCreationWaitsForLog(t *testing.T) {865 ctx := context.Background()866 req := ContainerRequest{867 Image: "docker.io/mysql:latest",868 ExposedPorts: []string{"3306/tcp", "33060/tcp"},869 Env: map[string]string{870 "MYSQL_ROOT_PASSWORD": "password",871 "MYSQL_DATABASE": "database",872 },873 WaitingFor: wait.ForLog("port: 3306 MySQL Community Server - GPL"),874 }875 mysqlC, err := GenericContainer(ctx, GenericContainerRequest{876 ProviderType: providerType,877 ContainerRequest: req,878 Started: true,879 })880 require.NoError(t, err)881 terminateContainerOnEnd(t, ctx, mysqlC)882 host, _ := mysqlC.Host(ctx)883 p, _ := mysqlC.MappedPort(ctx, "3306/tcp")884 port := p.Int()885 connectionString := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?tls=skip-verify",886 "root", "password", host, port, "database")887 db, err := sql.Open("mysql", connectionString)888 defer db.Close()889 if err = db.Ping(); err != nil {890 t.Errorf("error pinging db: %+v\n", err)891 }892 _, err = db.Exec("CREATE TABLE IF NOT EXISTS a_table ( \n" +893 " `col_1` VARCHAR(128) NOT NULL, \n" +894 " `col_2` VARCHAR(128) NOT NULL, \n" +895 " PRIMARY KEY (`col_1`, `col_2`) \n" +896 ")")897 if err != nil {898 t.Errorf("error creating table: %+v\n", err)899 }900}901func Test_BuildContainerFromDockerfile(t *testing.T) {902 t.Log("getting context")903 ctx := context.Background()904 t.Log("got context, creating container request")905 req := ContainerRequest{906 FromDockerfile: FromDockerfile{907 Context: "./testresources",908 },909 ExposedPorts: []string{"6379/tcp"},910 WaitingFor: wait.ForLog("Ready to accept connections"),911 }912 t.Log("creating generic container request from container request")913 genContainerReq := GenericContainerRequest{914 ProviderType: providerType,915 ContainerRequest: req,916 Started: true,917 }918 t.Log("creating redis container")919 redisC, err := GenericContainer(ctx, genContainerReq)920 require.NoError(t, err)921 terminateContainerOnEnd(t, ctx, redisC)922 t.Log("created redis container")923 t.Log("getting redis container endpoint")924 endpoint, err := redisC.Endpoint(ctx, "")925 if err != nil {926 t.Fatal(err)927 }928 t.Log("retrieved redis container endpoint")929 client := redis.NewClient(&redis.Options{930 Addr: endpoint,931 })932 t.Log("pinging redis")933 pong, err := client.Ping(ctx).Result()934 require.NoError(t, err)935 t.Log("received response from redis")936 if pong != "PONG" {937 t.Fatalf("received unexpected response from redis: %s", pong)938 }939}940func Test_BuildContainerFromDockerfileWithBuildArgs(t *testing.T) {941 t.Log("getting ctx")942 ctx := context.Background()943 ba := "build args value"944 t.Log("got ctx, creating container request")945 req := ContainerRequest{946 FromDockerfile: FromDockerfile{947 Context: "./testresources",948 Dockerfile: "args.Dockerfile",949 BuildArgs: map[string]*string{950 "FOO": &ba,951 },952 },953 ExposedPorts: []string{"8080/tcp"},954 WaitingFor: wait.ForLog("ready"),955 }956 genContainerReq := GenericContainerRequest{957 ProviderType: providerType,958 ContainerRequest: req,959 Started: true,960 }961 c, err := GenericContainer(ctx, genContainerReq)962 require.NoError(t, err)963 terminateContainerOnEnd(t, ctx, c)964 ep, err := c.Endpoint(ctx, "http")965 if err != nil {966 t.Fatal(err)967 }968 resp, err := http.Get(ep + "/env")969 if err != nil {970 t.Fatal(err)971 }972 body, err := ioutil.ReadAll(resp.Body)973 if err != nil {974 t.Fatal(err)975 }976 assert.Equal(t, 200, resp.StatusCode)977 assert.Equal(t, ba, string(body))978}979func Test_BuildContainerFromDockerfileWithBuildLog(t *testing.T) {980 rescueStdout := os.Stderr981 r, w, _ := os.Pipe()982 os.Stderr = w983 t.Log("getting ctx")984 ctx := context.Background()985 t.Log("got ctx, creating container request")986 req := ContainerRequest{987 FromDockerfile: FromDockerfile{988 Context: "./testresources",989 Dockerfile: "buildlog.Dockerfile",990 PrintBuildLog: true,991 },992 }993 genContainerReq := GenericContainerRequest{994 ProviderType: providerType,995 ContainerRequest: req,996 Started: true,997 }998 c, err := GenericContainer(ctx, genContainerReq)999 require.NoError(t, err)1000 terminateContainerOnEnd(t, ctx, c)1001 _ = w.Close()1002 out, _ := ioutil.ReadAll(r)1003 os.Stdout = rescueStdout1004 temp := strings.Split(string(out), "\n")1005 if !regexp.MustCompile(`(?i)^Step\s*1/1\s*:\s*FROM docker.io/alpine$`).MatchString(temp[0]) {1006 t.Errorf("Expected stdout firstline to be %s. Got '%s'.", "Step 1/1 : FROM docker.io/alpine", temp[0])1007 }1008}1009func TestContainerCreationWaitsForLogAndPortContextTimeout(t *testing.T) {1010 ctx := context.Background()1011 req := ContainerRequest{1012 Image: "docker.io/mysql:latest",1013 ExposedPorts: []string{"3306/tcp", "33060/tcp"},1014 Env: map[string]string{1015 "MYSQL_ROOT_PASSWORD": "password",1016 "MYSQL_DATABASE": "database",1017 },1018 WaitingFor: wait.ForAll(1019 wait.ForLog("I love testcontainers-go"),1020 wait.ForListeningPort("3306/tcp"),1021 ),1022 }1023 _, err := GenericContainer(ctx, GenericContainerRequest{1024 ProviderType: providerType,1025 ContainerRequest: req,1026 Started: true,1027 })1028 if err == nil {1029 t.Fatal("Expected timeout")1030 }1031}1032func TestContainerCreationWaitingForHostPort(t *testing.T) {1033 ctx := context.Background()1034 req := ContainerRequest{1035 Image: nginxAlpineImage,1036 ExposedPorts: []string{nginxDefaultPort},1037 WaitingFor: wait.ForListeningPort(nginxDefaultPort),1038 }1039 nginx, err := GenericContainer(ctx, GenericContainerRequest{1040 ProviderType: providerType,1041 ContainerRequest: req,1042 Started: true,1043 })1044 require.NoError(t, err)1045 terminateContainerOnEnd(t, ctx, nginx)1046}1047func TestContainerCreationWaitingForHostPortWithoutBashThrowsAnError(t *testing.T) {1048 ctx := context.Background()1049 req := ContainerRequest{1050 Image: nginxAlpineImage,1051 ExposedPorts: []string{nginxDefaultPort},1052 WaitingFor: wait.ForListeningPort(nginxDefaultPort),1053 }1054 nginx, err := GenericContainer(ctx, GenericContainerRequest{1055 ProviderType: providerType,1056 ContainerRequest: req,1057 Started: true,1058 })1059 require.NoError(t, err)1060 terminateContainerOnEnd(t, ctx, nginx)1061}1062func TestContainerCreationWaitsForLogAndPort(t *testing.T) {1063 ctx := context.Background()1064 req := ContainerRequest{1065 Image: "docker.io/mysql:latest",1066 ExposedPorts: []string{"3306/tcp", "33060/tcp"},1067 Env: map[string]string{1068 "MYSQL_ROOT_PASSWORD": "password",1069 "MYSQL_DATABASE": "database",1070 },1071 WaitingFor: wait.ForAll(1072 wait.ForLog("port: 3306 MySQL Community Server - GPL"),1073 wait.ForListeningPort("3306/tcp"),1074 ),1075 }1076 mysqlC, err := GenericContainer(ctx, GenericContainerRequest{1077 ProviderType: providerType,1078 ContainerRequest: req,1079 Started: true,1080 })1081 require.NoError(t, err)1082 terminateContainerOnEnd(t, ctx, mysqlC)1083 host, _ := mysqlC.Host(ctx)1084 p, _ := mysqlC.MappedPort(ctx, "3306/tcp")1085 port := p.Int()1086 connectionString := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?tls=skip-verify",1087 "root", "password", host, port, "database")1088 db, err := sql.Open("mysql", connectionString)1089 if err != nil {1090 t.Fatal(err)1091 }1092 defer db.Close()1093 if err = db.Ping(); err != nil {1094 t.Errorf("error pinging db: %+v\n", err)1095 }1096}1097func TestCMD(t *testing.T) {1098 /*1099 echo a unique statement to ensure that we1100 can pass in a command to the ContainerRequest1101 and it will be run when we run the container1102 */1103 ctx := context.Background()1104 req := ContainerRequest{1105 Image: "docker.io/alpine",1106 WaitingFor: wait.ForAll(1107 wait.ForLog("command override!"),1108 ),1109 Cmd: []string{"echo", "command override!"},1110 }1111 c, err := GenericContainer(ctx, GenericContainerRequest{1112 ProviderType: providerType,1113 ContainerRequest: req,1114 Started: true,1115 })1116 require.NoError(t, err)1117 terminateContainerOnEnd(t, ctx, c)1118}1119func TestEntrypoint(t *testing.T) {1120 /*1121 echo a unique statement to ensure that we1122 can pass in an entrypoint to the ContainerRequest1123 and it will be run when we run the container1124 */1125 ctx := context.Background()1126 req := ContainerRequest{1127 Image: "docker.io/alpine",1128 WaitingFor: wait.ForAll(1129 wait.ForLog("entrypoint override!"),1130 ),1131 Entrypoint: []string{"echo", "entrypoint override!"},1132 }1133 c, err := GenericContainer(ctx, GenericContainerRequest{1134 ProviderType: providerType,1135 ContainerRequest: req,1136 Started: true,1137 })1138 require.NoError(t, err)1139 terminateContainerOnEnd(t, ctx, c)1140}1141func TestReadTCPropsFile(t *testing.T) {1142 t.Run("HOME is not set", func(t *testing.T) {1143 env.Patch(t, "HOME", "")1144 config := configureTC()1145 assert.Empty(t, config, "TC props file should not exist")1146 })1147 t.Run("HOME is not set - TESTCONTAINERS_ env is set", func(t *testing.T) {1148 env.Patch(t, "HOME", "")1149 env.Patch(t, "TESTCONTAINERS_RYUK_CONTAINER_PRIVILEGED", "true")1150 config := configureTC()1151 expected := TestContainersConfig{}1152 expected.RyukPrivileged = true1153 assert.Equal(t, expected, config)1154 })1155 t.Run("HOME does not contain TC props file", func(t *testing.T) {1156 tmpDir := fs.NewDir(t, os.TempDir())1157 env.Patch(t, "HOME", tmpDir.Path())1158 config := configureTC()1159 assert.Empty(t, config, "TC props file should not exist")1160 })1161 t.Run("HOME does not contain TC props file - TESTCONTAINERS_ env is set", func(t *testing.T) {1162 tmpDir := fs.NewDir(t, os.TempDir())1163 env.Patch(t, "HOME", tmpDir.Path())1164 env.Patch(t, "TESTCONTAINERS_RYUK_CONTAINER_PRIVILEGED", "true")1165 config := configureTC()1166 expected := TestContainersConfig{}1167 expected.RyukPrivileged = true1168 assert.Equal(t, expected, config)1169 })1170 t.Run("HOME contains TC properties file", func(t *testing.T) {1171 tests := []struct {1172 content string1173 env map[string]string1174 expected TestContainersConfig1175 }{1176 {1177 "docker.host = tcp://127.0.0.1:33293",1178 map[string]string{},1179 TestContainersConfig{1180 Host: "tcp://127.0.0.1:33293",1181 TLSVerify: 0,1182 CertPath: "",1183 },1184 },1185 {1186 "docker.host = tcp://127.0.0.1:33293",1187 map[string]string{},1188 TestContainersConfig{1189 Host: "tcp://127.0.0.1:33293",1190 TLSVerify: 0,1191 CertPath: "",1192 },1193 },1194 {1195 `docker.host = tcp://127.0.0.1:332931196 docker.host = tcp://127.0.0.1:47111197 `,1198 map[string]string{},1199 TestContainersConfig{1200 Host: "tcp://127.0.0.1:4711",1201 TLSVerify: 0,1202 CertPath: "",1203 },1204 },1205 {1206 `docker.host = tcp://127.0.0.1:332931207 docker.host = tcp://127.0.0.1:47111208 docker.host = tcp://127.0.0.1:12341209 docker.tls.verify = 11210 `,1211 map[string]string{},1212 TestContainersConfig{1213 Host: "tcp://127.0.0.1:1234",1214 TLSVerify: 1,1215 CertPath: "",1216 },1217 },1218 {1219 "",1220 map[string]string{},1221 TestContainersConfig{1222 Host: "",1223 TLSVerify: 0,1224 CertPath: "",1225 },1226 },1227 {1228 `foo = bar1229 docker.host = tcp://127.0.0.1:12341230 `,1231 map[string]string{},1232 TestContainersConfig{1233 Host: "tcp://127.0.0.1:1234",1234 TLSVerify: 0,1235 CertPath: "",1236 },1237 },1238 {1239 "docker.host=tcp://127.0.0.1:33293",1240 map[string]string{},1241 TestContainersConfig{1242 Host: "tcp://127.0.0.1:33293",1243 TLSVerify: 0,1244 CertPath: "",1245 },1246 },1247 {1248 `#docker.host=tcp://127.0.0.1:33293`,1249 map[string]string{},1250 TestContainersConfig{1251 Host: "",1252 TLSVerify: 0,1253 CertPath: "",1254 },1255 },1256 {1257 `#docker.host = tcp://127.0.0.1:332931258 docker.host = tcp://127.0.0.1:47111259 docker.host = tcp://127.0.0.1:12341260 docker.cert.path=/tmp/certs`,1261 map[string]string{},1262 TestContainersConfig{1263 Host: "tcp://127.0.0.1:1234",1264 TLSVerify: 0,1265 CertPath: "/tmp/certs",1266 },1267 },1268 {1269 `ryuk.container.privileged=true`,1270 map[string]string{},1271 TestContainersConfig{1272 Host: "",1273 TLSVerify: 0,1274 CertPath: "",1275 RyukPrivileged: true,1276 },1277 },1278 {1279 ``,1280 map[string]string{1281 "TESTCONTAINERS_RYUK_CONTAINER_PRIVILEGED": "true",1282 },1283 TestContainersConfig{1284 Host: "",1285 TLSVerify: 0,1286 CertPath: "",1287 RyukPrivileged: true,1288 },1289 },1290 {1291 `ryuk.container.privileged=true`,1292 map[string]string{1293 "TESTCONTAINERS_RYUK_CONTAINER_PRIVILEGED": "true",1294 },1295 TestContainersConfig{1296 Host: "",1297 TLSVerify: 0,1298 CertPath: "",1299 RyukPrivileged: true,1300 },1301 },1302 {1303 `ryuk.container.privileged=false`,1304 map[string]string{1305 "TESTCONTAINERS_RYUK_CONTAINER_PRIVILEGED": "true",1306 },1307 TestContainersConfig{1308 Host: "",1309 TLSVerify: 0,1310 CertPath: "",1311 RyukPrivileged: true,1312 },1313 },1314 {1315 `ryuk.container.privileged=true`,1316 map[string]string{1317 "TESTCONTAINERS_RYUK_CONTAINER_PRIVILEGED": "false",1318 },1319 TestContainersConfig{1320 Host: "",1321 TLSVerify: 0,1322 CertPath: "",1323 RyukPrivileged: false,1324 },1325 },1326 {1327 `ryuk.container.privileged=false`,1328 map[string]string{1329 "TESTCONTAINERS_RYUK_CONTAINER_PRIVILEGED": "false",1330 },1331 TestContainersConfig{1332 Host: "",1333 TLSVerify: 0,1334 CertPath: "",1335 RyukPrivileged: false,1336 },1337 },1338 {1339 `ryuk.container.privileged=false1340 docker.tls.verify = ERROR`,1341 map[string]string{1342 "TESTCONTAINERS_RYUK_CONTAINER_PRIVILEGED": "true",1343 },1344 TestContainersConfig{1345 Host: "",1346 TLSVerify: 0,1347 CertPath: "",1348 RyukPrivileged: true,1349 },1350 },1351 {1352 `ryuk.container.privileged=false`,1353 map[string]string{1354 "TESTCONTAINERS_RYUK_CONTAINER_PRIVILEGED": "foo",1355 },1356 TestContainersConfig{1357 Host: "",1358 TLSVerify: 0,1359 CertPath: "",1360 RyukPrivileged: false,1361 },1362 },1363 }1364 for i, tt := range tests {1365 t.Run(fmt.Sprintf("[%d]", i), func(t *testing.T) {1366 tmpDir := fs.NewDir(t, os.TempDir())1367 env.Patch(t, "HOME", tmpDir.Path())1368 for k, v := range tt.env {1369 env.Patch(t, k, v)1370 }1371 if err := ioutil.WriteFile(tmpDir.Join(".testcontainers.properties"), []byte(tt.content), 0o600); err != nil {1372 t.Errorf("Failed to create the file: %v", err)1373 return1374 }1375 config := configureTC()1376 assert.Equal(t, tt.expected, config, "Configuration doesn't not match")1377 })1378 }1379 })1380}1381func ExampleDockerProvider_CreateContainer() {1382 ctx := context.Background()1383 req := ContainerRequest{1384 Image: "docker.io/nginx:alpine",1385 ExposedPorts: []string{"80/tcp"},1386 WaitingFor: wait.ForHTTP("/"),1387 }1388 nginxC, _ := GenericContainer(ctx, GenericContainerRequest{1389 ContainerRequest: req,1390 Started: true,1391 })1392 defer nginxC.Terminate(ctx)1393}1394func ExampleContainer_Host() {1395 ctx := context.Background()1396 req := ContainerRequest{1397 Image: "docker.io/nginx:alpine",1398 ExposedPorts: []string{"80/tcp"},1399 WaitingFor: wait.ForHTTP("/"),1400 }1401 nginxC, _ := GenericContainer(ctx, GenericContainerRequest{1402 ContainerRequest: req,1403 Started: true,1404 })1405 defer nginxC.Terminate(ctx)1406 ip, _ := nginxC.Host(ctx)1407 println(ip)1408}1409func ExampleContainer_Start() {1410 ctx := context.Background()1411 req := ContainerRequest{1412 Image: "docker.io/nginx:alpine",1413 ExposedPorts: []string{"80/tcp"},1414 WaitingFor: wait.ForHTTP("/"),1415 }1416 nginxC, _ := GenericContainer(ctx, GenericContainerRequest{1417 ContainerRequest: req,1418 })1419 defer nginxC.Terminate(ctx)1420 _ = nginxC.Start(ctx)1421}1422func ExampleContainer_Stop() {1423 ctx := context.Background()1424 req := ContainerRequest{1425 Image: "docker.io/nginx:alpine",1426 ExposedPorts: []string{"80/tcp"},1427 WaitingFor: wait.ForHTTP("/"),1428 }1429 nginxC, _ := GenericContainer(ctx, GenericContainerRequest{1430 ContainerRequest: req,1431 })1432 defer nginxC.Terminate(ctx)1433 timeout := 10 * time.Second1434 _ = nginxC.Stop(ctx, &timeout)1435}1436func ExampleContainer_MappedPort() {1437 ctx := context.Background()1438 req := ContainerRequest{1439 Image: "docker.io/nginx:alpine",1440 ExposedPorts: []string{"80/tcp"},1441 WaitingFor: wait.ForHTTP("/"),1442 }1443 nginxC, _ := GenericContainer(ctx, GenericContainerRequest{1444 ContainerRequest: req,1445 Started: true,1446 })1447 defer nginxC.Terminate(ctx)1448 ip, _ := nginxC.Host(ctx)1449 port, _ := nginxC.MappedPort(ctx, "80")1450 _, _ = http.Get(fmt.Sprintf("http://%s:%s", ip, port.Port()))1451}1452func TestContainerCreationWithBindAndVolume(t *testing.T) {1453 absPath, err := filepath.Abs("./testresources/hello.sh")1454 if err != nil {1455 t.Fatal(err)1456 }1457 ctx, cnl := context.WithTimeout(context.Background(), 30*time.Second)1458 defer cnl()1459 // Create a Docker client.1460 dockerCli, _, _, err := NewDockerClient()1461 if err != nil {1462 t.Fatal(err)1463 }1464 // Create the volume.1465 vol, err := dockerCli.VolumeCreate(ctx, volume.VolumeCreateBody{1466 Driver: "local",1467 })1468 if err != nil {1469 t.Fatal(err)1470 }1471 volumeName := vol.Name1472 t.Cleanup(func() {1473 ctx, cnl := context.WithTimeout(context.Background(), 5*time.Second)1474 defer cnl()1475 err := dockerCli.VolumeRemove(ctx, volumeName, true)1476 if err != nil {1477 t.Fatal(err)1478 }1479 })1480 // Create the container that writes into the mounted volume.1481 bashC, err := GenericContainer(ctx, GenericContainerRequest{1482 ProviderType: providerType,1483 ContainerRequest: ContainerRequest{1484 Image: "docker.io/bash",1485 Mounts: Mounts(BindMount(absPath, "/hello.sh"), VolumeMount(volumeName, "/data")),1486 Cmd: []string{"bash", "/hello.sh"},1487 WaitingFor: wait.ForLog("done"),1488 },1489 Started: true,1490 })1491 require.NoError(t, err)1492 require.NoError(t, bashC.Terminate(ctx))1493}1494func TestContainerWithTmpFs(t *testing.T) {1495 ctx := context.Background()1496 req := ContainerRequest{1497 Image: "docker.io/busybox",1498 Cmd: []string{"sleep", "10"},1499 Tmpfs: map[string]string{"/testtmpfs": "rw"},1500 }1501 container, err := GenericContainer(ctx, GenericContainerRequest{1502 ProviderType: providerType,1503 ContainerRequest: req,1504 Started: true,1505 })1506 require.NoError(t, err)1507 terminateContainerOnEnd(t, ctx, container)1508 path := "/testtmpfs/test.file"1509 c, _, err := container.Exec(ctx, []string{"ls", path})1510 if err != nil {1511 t.Fatal(err)1512 }1513 if c != 1 {1514 t.Fatalf("File %s should not have existed, expected return code 1, got %v", path, c)1515 }1516 c, _, err = container.Exec(ctx, []string{"touch", path})1517 if err != nil {1518 t.Fatal(err)1519 }1520 if c != 0 {1521 t.Fatalf("File %s should have been created successfully, expected return code 0, got %v", path, c)1522 }1523 c, _, err = container.Exec(ctx, []string{"ls", path})1524 if err != nil {1525 t.Fatal(err)1526 }1527 if c != 0 {1528 t.Fatalf("File %s should exist, expected return code 0, got %v", path, c)1529 }1530}1531func TestContainerNonExistentImage(t *testing.T) {1532 t.Run("if the image not found don't propagate the error", func(t *testing.T) {1533 _, err := GenericContainer(context.Background(), GenericContainerRequest{1534 ContainerRequest: ContainerRequest{1535 Image: "postgres:nonexistent-version",1536 SkipReaper: true,1537 },1538 Started: true,1539 })1540 var nf errdefs.ErrNotFound1541 if !errors.As(err, &nf) {1542 t.Fatalf("the error should have bee an errdefs.ErrNotFound: %v", err)1543 }1544 })1545 t.Run("the context cancellation is propagated to container creation", func(t *testing.T) {1546 ctx, cancel := context.WithTimeout(context.Background(), time.Second)1547 defer cancel()1548 _, err := GenericContainer(ctx, GenericContainerRequest{1549 ProviderType: providerType,1550 ContainerRequest: ContainerRequest{1551 Image: "docker.io/postgres:12",1552 WaitingFor: wait.ForLog("log"),1553 SkipReaper: true,1554 },1555 Started: true,1556 })1557 if !errors.Is(err, ctx.Err()) {1558 t.Fatalf("err should be a ctx cancelled error %v", err)1559 }1560 })1561}1562func TestContainerCustomPlatformImage(t *testing.T) {1563 if providerType == ProviderPodman {1564 t.Skip("Incompatible Docker API version for Podman")1565 }1566 t.Run("error with a non-existent platform", func(t *testing.T) {1567 t.Parallel()1568 nonExistentPlatform := "windows/arm12"1569 ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)1570 defer cancel()1571 c, err := GenericContainer(ctx, GenericContainerRequest{1572 ProviderType: providerType,1573 ContainerRequest: ContainerRequest{1574 Image: "docker.io/redis:latest",1575 SkipReaper: true,1576 ImagePlatform: nonExistentPlatform,1577 },1578 Started: false,1579 })1580 t.Cleanup(func() {1581 if c != nil {1582 c.Terminate(ctx)1583 }1584 })1585 assert.Error(t, err)1586 })1587 t.Run("specific platform should be propagated", func(t *testing.T) {1588 t.Parallel()1589 ctx := context.Background()1590 c, err := GenericContainer(ctx, GenericContainerRequest{1591 ProviderType: providerType,1592 ContainerRequest: ContainerRequest{1593 Image: "docker.io/mysql:5.7",1594 SkipReaper: true,1595 ImagePlatform: "linux/amd64",1596 },1597 Started: false,1598 })1599 require.NoError(t, err)1600 terminateContainerOnEnd(t, ctx, c)1601 dockerCli, _, _, err := NewDockerClient()1602 require.NoError(t, err)1603 dockerCli.NegotiateAPIVersion(ctx)1604 ctr, err := dockerCli.ContainerInspect(ctx, c.GetContainerID())1605 assert.NoError(t, err)1606 img, _, err := dockerCli.ImageInspectWithRaw(ctx, ctr.Image)1607 assert.NoError(t, err)1608 assert.Equal(t, "linux", img.Os)1609 assert.Equal(t, "amd64", img.Architecture)1610 })1611}1612func TestContainerWithCustomHostname(t *testing.T) {1613 ctx := context.Background()1614 name := fmt.Sprintf("some-nginx-%s-%d", t.Name(), rand.Int())1615 hostname := fmt.Sprintf("my-nginx-%s-%d", t.Name(), rand.Int())1616 req := ContainerRequest{1617 Name: name,1618 Image: nginxImage,1619 Hostname: hostname,1620 }1621 container, err := GenericContainer(ctx, GenericContainerRequest{1622 ProviderType: providerType,1623 ContainerRequest: req,1624 Started: true,1625 })1626 require.NoError(t, err)1627 terminateContainerOnEnd(t, ctx, container)1628 if actualHostname := readHostname(t, container.GetContainerID()); actualHostname != hostname {1629 t.Fatalf("expected hostname %s, got %s", hostname, actualHostname)1630 }1631}1632func readHostname(tb testing.TB, containerId string) string {1633 containerClient, _, _, err := NewDockerClient()1634 if err != nil {1635 tb.Fatalf("Failed to create Docker client: %v", err)1636 }1637 containerDetails, err := containerClient.ContainerInspect(context.Background(), containerId)1638 if err != nil {1639 tb.Fatalf("Failed to inspect container: %v", err)1640 }1641 return containerDetails.Config.Hostname1642}1643func TestDockerContainerCopyFileToContainer(t *testing.T) {1644 ctx := context.Background()1645 nginxC, err := GenericContainer(ctx, GenericContainerRequest{1646 ProviderType: providerType,1647 ContainerRequest: ContainerRequest{1648 Image: nginxImage,1649 ExposedPorts: []string{nginxDefaultPort},1650 WaitingFor: wait.ForListeningPort(nginxDefaultPort),1651 },1652 Started: true,1653 })1654 require.NoError(t, err)1655 terminateContainerOnEnd(t, ctx, nginxC)1656 copiedFileName := "hello_copy.sh"1657 _ = nginxC.CopyFileToContainer(ctx, "./testresources/hello.sh", "/"+copiedFileName, 700)1658 c, _, err := nginxC.Exec(ctx, []string{"bash", copiedFileName})1659 if err != nil {1660 t.Fatal(err)1661 }1662 if c != 0 {1663 t.Fatalf("File %s should exist, expected return code 0, got %v", copiedFileName, c)1664 }1665}1666func TestDockerContainerCopyDirToContainer(t *testing.T) {1667 ctx := context.Background()1668 nginxC, err := GenericContainer(ctx, GenericContainerRequest{1669 ProviderType: providerType,1670 ContainerRequest: ContainerRequest{1671 Image: nginxImage,1672 ExposedPorts: []string{nginxDefaultPort},1673 WaitingFor: wait.ForListeningPort(nginxDefaultPort),1674 },1675 Started: true,1676 })1677 require.NoError(t, err)1678 terminateContainerOnEnd(t, ctx, nginxC)1679 err = nginxC.CopyDirToContainer(ctx, "./testresources/Dockerfile", "/tmp/testresources/Dockerfile", 700)1680 require.Error(t, err) // copying a file using the directory method will raise an error1681 err = nginxC.CopyDirToContainer(ctx, "./testresources", "/tmp/testresources", 700)1682 if err != nil {1683 t.Fatal(err)1684 }1685 assertExtractedFiles(t, ctx, nginxC, "./testresources", "/tmp/testresources/")1686}1687func TestDockerCreateContainerWithFiles(t *testing.T) {1688 ctx := context.Background()1689 hostFileName := "./testresources/hello.sh"1690 copiedFileName := "/hello_copy.sh"1691 tests := []struct {1692 name string1693 files []ContainerFile1694 errMsg string1695 }{1696 {1697 name: "success copy",1698 files: []ContainerFile{1699 {1700 HostFilePath: hostFileName,1701 ContainerFilePath: copiedFileName,1702 FileMode: 700,1703 },1704 },1705 },1706 {1707 name: "host file not found",1708 files: []ContainerFile{1709 {1710 HostFilePath: hostFileName + "123",1711 ContainerFilePath: copiedFileName,1712 FileMode: 700,1713 },1714 },1715 errMsg: "can't copy " +1716 "./testresources/hello.sh123 to container: open " +1717 "./testresources/hello.sh123: no such file or directory: " +1718 "failed to create container",1719 },1720 }1721 for _, tc := range tests {1722 t.Run(tc.name, func(t *testing.T) {1723 nginxC, err := GenericContainer(ctx, GenericContainerRequest{1724 ContainerRequest: ContainerRequest{1725 Image: "nginx:1.17.6",1726 ExposedPorts: []string{"80/tcp"},1727 WaitingFor: wait.ForListeningPort("80/tcp"),1728 Files: tc.files,1729 },1730 Started: false,1731 })1732 if err != nil {1733 require.Contains(t, err.Error(), tc.errMsg)1734 } else {1735 for _, f := range tc.files {1736 require.NoError(t, err)1737 hostFileData, err := ioutil.ReadFile(f.HostFilePath)1738 require.NoError(t, err)1739 fd, err := nginxC.CopyFileFromContainer(ctx, f.ContainerFilePath)1740 require.NoError(t, err)1741 defer fd.Close()1742 containerFileData, err := ioutil.ReadAll(fd)1743 require.NoError(t, err)1744 require.Equal(t, hostFileData, containerFileData)1745 }1746 }1747 })1748 }1749}1750func TestDockerCreateContainerWithDirs(t *testing.T) {1751 ctx := context.Background()1752 hostDirName := "testresources"1753 tests := []struct {1754 name string1755 dir ContainerFile1756 hasError bool1757 }{1758 {1759 name: "success copy directory",1760 dir: ContainerFile{1761 HostFilePath: "./" + hostDirName,1762 ContainerFilePath: "/tmp/" + hostDirName, // the parent dir must exist1763 FileMode: 700,1764 },1765 hasError: false,1766 },1767 {1768 name: "host dir not found",1769 dir: ContainerFile{1770 HostFilePath: "./testresources123", // does not exist1771 ContainerFilePath: "/tmp/" + hostDirName, // the parent dir must exist1772 FileMode: 700,1773 },1774 hasError: true,1775 },1776 {1777 name: "container dir not found",1778 dir: ContainerFile{1779 HostFilePath: "./" + hostDirName,1780 ContainerFilePath: "/parent-does-not-exist/testresources123", // does not exist1781 FileMode: 700,1782 },1783 hasError: true,1784 },1785 }1786 for _, tc := range tests {1787 t.Run(tc.name, func(t *testing.T) {1788 nginxC, err := GenericContainer(ctx, GenericContainerRequest{1789 ContainerRequest: ContainerRequest{1790 Image: "nginx:1.17.6",1791 ExposedPorts: []string{"80/tcp"},1792 WaitingFor: wait.ForListeningPort("80/tcp"),1793 Files: []ContainerFile{tc.dir},1794 },1795 Started: false,1796 })1797 require.True(t, (err != nil) == tc.hasError)1798 if err == nil {1799 dir := tc.dir1800 assertExtractedFiles(t, ctx, nginxC, dir.HostFilePath, dir.ContainerFilePath)1801 }1802 })1803 }1804}1805func TestDockerContainerCopyToContainer(t *testing.T) {1806 ctx := context.Background()1807 nginxC, err := GenericContainer(ctx, GenericContainerRequest{1808 ProviderType: providerType,1809 ContainerRequest: ContainerRequest{1810 Image: nginxImage,1811 ExposedPorts: []string{nginxDefaultPort},1812 WaitingFor: wait.ForListeningPort(nginxDefaultPort),1813 },1814 Started: true,1815 })1816 require.NoError(t, err)1817 terminateContainerOnEnd(t, ctx, nginxC)1818 copiedFileName := "hello_copy.sh"1819 fileContent, err := ioutil.ReadFile("./testresources/hello.sh")1820 if err != nil {1821 t.Fatal(err)1822 }1823 _ = nginxC.CopyToContainer(ctx, fileContent, "/"+copiedFileName, 700)1824 c, _, err := nginxC.Exec(ctx, []string{"bash", copiedFileName})1825 if err != nil {1826 t.Fatal(err)1827 }1828 if c != 0 {1829 t.Fatalf("File %s should exist, expected return code 0, got %v", copiedFileName, c)1830 }1831}1832func TestDockerContainerCopyFileFromContainer(t *testing.T) {1833 fileContent, err := ioutil.ReadFile("./testresources/hello.sh")1834 if err != nil {1835 t.Fatal(err)1836 }1837 ctx := context.Background()1838 nginxC, err := GenericContainer(ctx, GenericContainerRequest{1839 ProviderType: providerType,1840 ContainerRequest: ContainerRequest{1841 Image: nginxImage,1842 ExposedPorts: []string{nginxDefaultPort},1843 WaitingFor: wait.ForListeningPort(nginxDefaultPort),1844 },1845 Started: true,1846 })1847 require.NoError(t, err)1848 terminateContainerOnEnd(t, ctx, nginxC)1849 copiedFileName := "hello_copy.sh"1850 _ = nginxC.CopyFileToContainer(ctx, "./testresources/hello.sh", "/"+copiedFileName, 700)1851 c, _, err := nginxC.Exec(ctx, []string{"bash", copiedFileName})1852 if err != nil {1853 t.Fatal(err)1854 }1855 if c != 0 {1856 t.Fatalf("File %s should exist, expected return code 0, got %v", copiedFileName, c)1857 }1858 reader, err := nginxC.CopyFileFromContainer(ctx, "/"+copiedFileName)1859 if err != nil {1860 t.Fatal(err)1861 }1862 fileContentFromContainer, err := ioutil.ReadAll(reader)1863 if err != nil {1864 t.Fatal(err)1865 }1866 assert.Equal(t, fileContent, fileContentFromContainer)1867}1868func TestDockerContainerCopyEmptyFileFromContainer(t *testing.T) {1869 ctx := context.Background()1870 nginxC, err := GenericContainer(ctx, GenericContainerRequest{1871 ProviderType: providerType,1872 ContainerRequest: ContainerRequest{1873 Image: nginxImage,1874 ExposedPorts: []string{nginxDefaultPort},1875 WaitingFor: wait.ForListeningPort(nginxDefaultPort),1876 },1877 Started: true,1878 })1879 require.NoError(t, err)1880 terminateContainerOnEnd(t, ctx, nginxC)1881 copiedFileName := "hello_copy.sh"1882 _ = nginxC.CopyFileToContainer(ctx, "./testresources/empty.sh", "/"+copiedFileName, 700)1883 c, _, err := nginxC.Exec(ctx, []string{"bash", copiedFileName})1884 if err != nil {1885 t.Fatal(err)1886 }1887 if c != 0 {1888 t.Fatalf("File %s should exist, expected return code 0, got %v", copiedFileName, c)1889 }1890 reader, err := nginxC.CopyFileFromContainer(ctx, "/"+copiedFileName)1891 if err != nil {1892 t.Fatal(err)1893 }1894 fileContentFromContainer, err := ioutil.ReadAll(reader)1895 if err != nil {1896 t.Fatal(err)1897 }1898 assert.Empty(t, fileContentFromContainer)1899}1900func TestDockerContainerResources(t *testing.T) {1901 if providerType == ProviderPodman {1902 t.Skip("Rootless Podman does not support setting rlimit")1903 }1904 ctx := context.Background()1905 expected := []*units.Ulimit{1906 {1907 Name: "memlock",1908 Hard: -1,1909 Soft: -1,1910 },1911 {1912 Name: "nofile",1913 Hard: 65536,1914 Soft: 65536,1915 },1916 }1917 nginxC, err := GenericContainer(ctx, GenericContainerRequest{1918 ProviderType: providerType,1919 ContainerRequest: ContainerRequest{1920 Image: nginxAlpineImage,1921 ExposedPorts: []string{nginxDefaultPort},1922 WaitingFor: wait.ForListeningPort(nginxDefaultPort),1923 Resources: container.Resources{1924 Ulimits: expected,1925 },1926 },1927 Started: true,1928 })1929 require.NoError(t, err)1930 terminateContainerOnEnd(t, ctx, nginxC)1931 c, err := client.NewClientWithOpts(client.FromEnv)1932 require.NoError(t, err)1933 c.NegotiateAPIVersion(ctx)1934 containerID := nginxC.GetContainerID()1935 resp, err := c.ContainerInspect(ctx, containerID)1936 require.NoError(t, err)1937 assert.Equal(t, expected, resp.HostConfig.Ulimits)1938}1939func TestContainerWithReaperNetwork(t *testing.T) {1940 ctx := context.Background()1941 networks := []string{1942 "test_network_" + randomString(),1943 "test_network_" + randomString(),1944 }1945 for _, nw := range networks {1946 nr := NetworkRequest{1947 Name: nw,1948 Attachable: true,1949 }1950 _, err := GenericNetwork(ctx, GenericNetworkRequest{1951 ProviderType: providerType,1952 NetworkRequest: nr,1953 })1954 assert.Nil(t, err)1955 }1956 req := ContainerRequest{1957 Image: nginxAlpineImage,1958 ExposedPorts: []string{nginxDefaultPort},1959 WaitingFor: wait.ForAll(1960 wait.ForListeningPort(nginxDefaultPort),1961 wait.ForLog("Configuration complete; ready for start up"),1962 ),1963 Networks: networks,1964 }1965 nginxC, err := GenericContainer(ctx, GenericContainerRequest{1966 ProviderType: providerType,1967 ContainerRequest: req,1968 Started: true,1969 })1970 require.NoError(t, err)1971 terminateContainerOnEnd(t, ctx, nginxC)1972 containerId := nginxC.GetContainerID()1973 cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())1974 assert.Nil(t, err)1975 cnt, err := cli.ContainerInspect(ctx, containerId)1976 assert.Nil(t, err)1977 assert.Equal(t, 2, len(cnt.NetworkSettings.Networks))1978 assert.NotNil(t, cnt.NetworkSettings.Networks[networks[0]])1979 assert.NotNil(t, cnt.NetworkSettings.Networks[networks[1]])1980}1981func TestContainerCapAdd(t *testing.T) {1982 if providerType == ProviderPodman {1983 t.Skip("Rootless Podman does not support setting cap-add/cap-drop")1984 }1985 ctx := context.Background()1986 expected := "IPC_LOCK"1987 nginx, err := GenericContainer(ctx, GenericContainerRequest{1988 ProviderType: providerType,1989 ContainerRequest: ContainerRequest{1990 Image: nginxAlpineImage,1991 ExposedPorts: []string{nginxDefaultPort},1992 WaitingFor: wait.ForListeningPort(nginxDefaultPort),1993 CapAdd: []string{expected},1994 },1995 Started: true,1996 })1997 require.NoError(t, err)1998 terminateContainerOnEnd(t, ctx, nginx)1999 dockerClient, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())2000 require.NoError(t, err)2001 defer dockerClient.Close()2002 containerID := nginx.GetContainerID()2003 resp, err := dockerClient.ContainerInspect(ctx, containerID)2004 require.NoError(t, err)2005 assert.Equal(t, strslice.StrSlice{expected}, resp.HostConfig.CapAdd)2006}2007func TestContainerRunningCheckingStatusCode(t *testing.T) {2008 ctx := context.Background()2009 req := ContainerRequest{2010 Image: "influxdb:1.8.10-alpine",2011 ExposedPorts: []string{"8086/tcp"},2012 WaitingFor: wait.ForAll(2013 wait.ForHTTP("/ping").WithPort("8086/tcp").WithStatusCodeMatcher(2014 func(status int) bool {2015 return status == http.StatusNoContent2016 },2017 ),2018 ),2019 }2020 influx, err := GenericContainer(ctx, GenericContainerRequest{2021 ContainerRequest: req,2022 Started: true,2023 })2024 if err != nil {2025 t.Fatal(err)2026 }2027 defer influx.Terminate(ctx)2028}2029func TestContainerWithUserID(t *testing.T) {2030 ctx := context.Background()2031 req := ContainerRequest{2032 Image: "docker.io/alpine:latest",2033 User: "60125",2034 Cmd: []string{"sh", "-c", "id -u"},2035 WaitingFor: wait.ForExit(),2036 }2037 container, err := GenericContainer(ctx, GenericContainerRequest{2038 ProviderType: providerType,2039 ContainerRequest: req,2040 Started: true,2041 })2042 require.NoError(t, err)2043 terminateContainerOnEnd(t, ctx, container)2044 r, err := container.Logs(ctx)2045 if err != nil {2046 t.Fatal(err)2047 }2048 defer r.Close()2049 b, err := ioutil.ReadAll(r)2050 if err != nil {2051 t.Fatal(err)2052 }2053 actual := regexp.MustCompile(`\D+`).ReplaceAllString(string(b), "")2054 assert.Equal(t, req.User, actual)2055}2056func TestContainerWithNoUserID(t *testing.T) {2057 ctx := context.Background()2058 req := ContainerRequest{2059 Image: "docker.io/alpine:latest",2060 Cmd: []string{"sh", "-c", "id -u"},2061 WaitingFor: wait.ForExit(),2062 }2063 container, err := GenericContainer(ctx, GenericContainerRequest{2064 ProviderType: providerType,2065 ContainerRequest: req,2066 Started: true,2067 })2068 require.NoError(t, err)2069 terminateContainerOnEnd(t, ctx, container)2070 r, err := container.Logs(ctx)2071 if err != nil {2072 t.Fatal(err)2073 }2074 defer r.Close()2075 b, err := ioutil.ReadAll(r)2076 if err != nil {2077 t.Fatal(err)2078 }2079 actual := regexp.MustCompile(`\D+`).ReplaceAllString(string(b), "")2080 assert.Equal(t, "0", actual)2081}2082func TestGetGatewayIP(t *testing.T) {2083 // When using docker-compose with DinD mode, and using host port or http wait strategy2084 // It's need to invoke GetGatewayIP for get the host2085 provider, err := providerType.GetProvider(WithLogger(TestLogger(t)))2086 if err != nil {2087 t.Fatal(err)2088 }2089 ip, err := provider.(*DockerProvider).GetGatewayIP(context.Background())2090 if err != nil {2091 t.Fatal(err)2092 }2093 if ip == "" {2094 t.Fatal("could not get gateway ip")2095 }2096}2097func TestProviderHasConfig(t *testing.T) {2098 provider, err := NewDockerProvider(WithLogger(TestLogger(t)))2099 if err != nil {2100 t.Fatal(err)2101 }2102 assert.NotNil(t, provider.Config(), "expecting DockerProvider to provide the configuration")2103}2104func TestNetworkModeWithContainerReference(t *testing.T) {2105 ctx := context.Background()2106 nginxA, err := GenericContainer(ctx, GenericContainerRequest{2107 ProviderType: providerType,2108 ContainerRequest: ContainerRequest{2109 Image: nginxAlpineImage,2110 },2111 Started: true,2112 })2113 require.NoError(t, err)2114 terminateContainerOnEnd(t, ctx, nginxA)2115 networkMode := fmt.Sprintf("container:%v", nginxA.GetContainerID())2116 nginxB, err := GenericContainer(ctx, GenericContainerRequest{2117 ProviderType: providerType,2118 ContainerRequest: ContainerRequest{2119 Image: nginxAlpineImage,2120 NetworkMode: container.NetworkMode(networkMode),2121 },2122 Started: true,2123 })2124 require.NoError(t, err)2125 terminateContainerOnEnd(t, ctx, nginxB)2126}2127// creates a temporary dir in which the files will be extracted. Then it will compare the bytes of each file in the source with the bytes from the copied-from-container file2128func assertExtractedFiles(t *testing.T, ctx context.Context, container Container, hostFilePath string, containerFilePath string) {2129 // create all copied files into a temporary dir2130 tmpDir := filepath.Join(t.TempDir())2131 // compare the bytes of each file in the source with the bytes from the copied-from-container file2132 srcFiles, err := ioutil.ReadDir(hostFilePath)2133 require.NoError(t, err)2134 for _, srcFile := range srcFiles {2135 srcBytes, err := ioutil.ReadFile(filepath.Join(hostFilePath, srcFile.Name()))2136 if err != nil {2137 require.NoError(t, err)2138 }2139 // copy file by file, as there is a limitation in the Docker client to copy an entiry directory from the container2140 // paths for the container files are using Linux path separators2141 fd, err := container.CopyFileFromContainer(ctx, containerFilePath+"/"+srcFile.Name())2142 require.NoError(t, err, "Path not found in container: %s", containerFilePath+"/"+srcFile.Name())2143 defer fd.Close()2144 targetPath := filepath.Join(tmpDir, srcFile.Name())2145 dst, err := os.Create(targetPath)2146 if err != nil {2147 require.NoError(t, err)2148 }2149 defer dst.Close()2150 _, err = io.Copy(dst, fd)2151 if err != nil {2152 require.NoError(t, err)2153 }2154 untarBytes, err := ioutil.ReadFile(targetPath)2155 if err != nil {2156 require.NoError(t, err)2157 }2158 assert.Equal(t, srcBytes, untarBytes)2159 }2160}2161func terminateContainerOnEnd(tb testing.TB, ctx context.Context, ctr Container) {2162 tb.Helper()2163 if ctr == nil {2164 return2165 }2166 tb.Cleanup(func() {2167 tb.Log("terminating container")2168 require.NoError(tb, ctr.Terminate(ctx))2169 })2170}2171func randomString() string {2172 rand.Seed(time.Now().UnixNano())2173 chars := []rune("ABCDEFGHIJKLMNOPQRSTUVWXYZ" +2174 "abcdefghijklmnopqrstuvwxyz" +2175 "0123456789")2176 length := 82177 var b strings.Builder2178 for i := 0; i < length; i++ {2179 b.WriteRune(chars[rand.Intn(len(chars))])2180 }2181 return b.String()2182}2183func TestDockerProviderFindContainerByName(t *testing.T) {2184 ctx := context.Background()2185 provider, err := NewDockerProvider(WithLogger(TestLogger(t)))2186 require.NoError(t, err)2187 c1, err := GenericContainer(ctx, GenericContainerRequest{2188 ProviderType: providerType,2189 ContainerRequest: ContainerRequest{2190 Name: "test",2191 Image: "nginx:1.17.6",2192 WaitingFor: wait.ForExposedPort(),2193 },2194 Started: true,2195 })2196 require.NoError(t, err)2197 c1Name, err := c1.Name(ctx)2198 require.NoError(t, err)2199 terminateContainerOnEnd(t, ctx, c1)2200 c2, err := GenericContainer(ctx, GenericContainerRequest{2201 ProviderType: providerType,2202 ContainerRequest: ContainerRequest{2203 Name: "test2",2204 Image: "nginx:1.17.6",2205 WaitingFor: wait.ForExposedPort(),2206 },2207 Started: true,2208 })2209 require.NoError(t, err)2210 terminateContainerOnEnd(t, ctx, c2)2211 c, err := provider.findContainerByName(ctx, "test")2212 assert.NoError(t, err)2213 require.NotNil(t, c)2214 assert.Contains(t, c.Names, c1Name)2215}...

Full Screen

Full Screen

logconsumer_test.go

Source:logconsumer_test.go Github

copy

Full Screen

...166 Privileged: true,167 },168 })169 require.NoError(t, err)170 terminateContainerOnEnd(t, ctx, dind)171 var remoteDocker string172 ctxEndpoint, cancel := context.WithTimeout(ctx, 5*time.Second)173 defer cancel()174 // todo: remove this temporary fix (test is flaky).175 for {176 remoteDocker, err = dind.Endpoint(ctxEndpoint, "2375/tcp")177 if err == nil {178 break179 }180 if errors.Is(err, context.DeadlineExceeded) {181 break182 }183 time.Sleep(100 * time.Microsecond)184 t.Log("retrying get endpoint")...

Full Screen

Full Screen

generic_test.go

Source:generic_test.go Github

copy

Full Screen

...22 Started: true,23 })24 require.NoError(t, err)25 require.True(t, n1.IsRunning())26 terminateContainerOnEnd(t, ctx, n1)27 copiedFileName := "hello_copy.sh"28 err = n1.CopyFileToContainer(ctx, "./testresources/hello.sh", "/"+copiedFileName, 700)29 require.NoError(t, err)30 tests := []struct {31 name string32 containerName string33 errorMatcher func(err error) error34 reuseOption bool35 }{36 {37 name: "reuse option with empty name",38 errorMatcher: func(err error) error {39 if errors.Is(err, ErrReuseEmptyName) {40 return nil...

Full Screen

Full Screen

terminateContainerOnEnd

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 ctx := context.Background()4 req := testcontainers.ContainerRequest{5 ExposedPorts: []string{"8091/tcp", "8092/tcp", "8093/tcp", "8094/tcp", "11207/tcp", "11210/tcp", "18091/tcp", "18092/tcp", "18093/tcp", "18094/tcp", "21100/tcp", "21150/tcp", "21200/tcp", "21250/tcp", "21300/tcp", "21350/tcp"},6 WaitingFor: wait.ForLog(".*The system is ready to go.*"),7 }8 couchbaseContainer, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{9 })10 if err != nil {11 panic(err)12 }13 defer couchbaseContainer.Terminate(ctx)14 ip, err := couchbaseContainer.Host(ctx)15 if err != nil {16 panic(err)17 }18 port, err := couchbaseContainer.MappedPort(ctx, "8091")19 if err != nil {20 panic(err)21 }22 fmt.Printf("Couchbase is available at %s:%s", ip, port.Port())23}24import (25func main() {26 ctx := context.Background()27 req := testcontainers.ContainerRequest{28 ExposedPorts: []string{"8091/tcp", "8092/tcp", "8093/tcp", "8094/tcp", "11207/tcp", "11210/tcp", "18091/tcp", "18092/tcp", "18093/tcp", "18094/tcp", "21100/tcp", "21150/tcp", "21200/tcp", "21250/tcp", "21300/tcp", "21350/tcp"},29 WaitingFor: wait.ForLog(".*The system is ready to go.*"),30 }31 couchbaseContainer, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{

Full Screen

Full Screen

terminateContainerOnEnd

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 ctx := context.Background()4 req := testcontainers.ContainerRequest{5 Cmd: []string{"sh", "-c", "while true; do echo hello world; sleep 1; done"},6 WaitingFor: wait.ForLog("hello world"),7 }8 c, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{9 })10 if err != nil {11 panic(err)12 }13 err = c.Terminate(ctx)14 if err != nil {15 panic(err)16 }17 time.Sleep(5 * time.Second)18 c, err = testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{19 })20 if err != nil {21 panic(err)22 }23 err = c.Terminate(ctx)24 if err != nil {25 panic(err)26 }27 time.Sleep(5 * time.Second)28 c, err = testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{29 })30 if err != nil {31 panic(err)32 }33 err = c.Terminate(ctx)34 if err != nil {35 panic(err)36 }37 time.Sleep(5 * time.Second)38 c, err = testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{39 })40 if err != nil {41 panic(err)42 }43 err = c.Terminate(ctx)44 if err != nil {45 panic(err)46 }47 time.Sleep(5 * time.Second)48 c, err = testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{49 })

Full Screen

Full Screen

terminateContainerOnEnd

Using AI Code Generation

copy

Full Screen

1import (2func main() {3ctx := context.Background()4req := testcontainers.ContainerRequest{5Cmd: []string{"sleep", "10000"},6WaitingFor: wait.ForLog("10000"),7}8c, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{9})10if err != nil {11panic(err)12}13defer c.Terminate(ctx)14}15import (16func main() {17ctx := context.Background()18req := testcontainers.ContainerRequest{19Cmd: []string{"sleep", "10000"},20WaitingFor: wait.ForLog("10000"),21}22c, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{23})24if err != nil {25panic(err)26}27defer c.Terminate(ctx)28}29import (30func main() {31ctx := context.Background()32req := testcontainers.ContainerRequest{33Cmd: []string{"sleep", "10000"},34WaitingFor: wait.ForLog("10000"),35}36c, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{37})38if err != nil {39panic(err)40}41defer c.Terminate(ctx)42}43import (44func main() {45ctx := context.Background()46req := testcontainers.ContainerRequest{47Cmd: []string{"sleep", "10000"},48WaitingFor: wait.ForLog("10000"),49}50c, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{51})52if err != nil {53panic(err)

Full Screen

Full Screen

terminateContainerOnEnd

Using AI Code Generation

copy

Full Screen

1import (2func TestContainer(t *testing.T) {3 ctx := context.Background()4 req := testcontainers.ContainerRequest{5 ExposedPorts: []string{"80/tcp"},6 Cmd: []string{"sleep", "99999999"},7 WaitingFor: wait.ForLog("99999999"),8 }9 container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{10 })11 if err != nil {12 fmt.Println(err)13 }14 defer container.Terminate(ctx)15}16func TestMain(m *testing.M) {17 os.Exit(m.Run())18}19import (20func TestContainer(t *testing.T) {21 ctx := context.Background()22 req := testcontainers.ContainerRequest{23 ExposedPorts: []string{"80/tcp"},24 Cmd: []string{"sleep", "99999999"},25 WaitingFor: wait.ForLog("99999999"),26 }27 container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{28 })29 if err != nil {30 fmt.Println(err)31 }32 defer container.Terminate(ctx)33}34func TestMain(m *testing.M) {35 os.Exit(m.Run())36}

Full Screen

Full Screen

terminateContainerOnEnd

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 ctx := context.Background()4 req := testcontainers.ContainerRequest{5 Cmd: []string{"sleep", "30"},6 ExposedPorts: []string{"80/tcp"},7 WaitingFor: wait.ForLog("Listening on port 80"),8 }9 container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{10 })11 if err != nil {12 log.Fatalf("Could not start container: %v", err)13 }14 defer container.Terminate(ctx)15 ip, err := container.Host(ctx)16 if err != nil {17 log.Fatalf("Could not get container IP: %v", err)18 }19 port, err := container.MappedPort(ctx, "80")20 if err != nil {21 log.Fatalf("Could not get container port: %v", err)22 }23 fmt.Printf("Container is listening on %s:%s24", ip, port.Port())25 _, err = container.Wait(ctx)26 if err != nil {27 log.Fatalf("Could not wait for container to terminate: %v", err)28 }29 code, err := container.ExitCode(ctx)30 if err != nil {31 log.Fatalf("Could not get container exit code: %v", err)32 }33 fmt.Printf("Container exited with code %d", code)34}35import (

Full Screen

Full Screen

terminateContainerOnEnd

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 ctx := context.Background()4 req := testcontainers.ContainerRequest{5 ExposedPorts: []string{"4444"},6 WaitingFor: wait.ForListeningPort("4444"),7 }8 container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{9 })10 if err != nil {11 panic(err)12 }13 defer container.Terminate(ctx)14 containerID, err := container.ContainerID(ctx)15 if err != nil {16 panic(err)17 }18 host, err := container.Host(ctx)19 if err != nil {20 panic(err)21 }22 port, err := container.MappedPort(ctx, "4444")23 if err != nil {24 panic(err)25 }26 fmt.Printf("Host: %s, Port: %s, ContainerID: %s27", host, port.Port(), containerID)28 file, err := os.Create("container-logs.txt")29 if err != nil {30 panic(err)31 }32 defer file.Close()33 logs, err := container.Logs(ctx, testcontainers.LogsRequest{34 })35 if err != nil {36 panic(err)37 }38 defer logs.Close()39 _, err = io.Copy(file, logs)40 if err != nil {41 panic(err)42 }43 time.Sleep(10 * time.Second)44}45import (

Full Screen

Full Screen

terminateContainerOnEnd

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 ctx := context.Background()4 req := testcontainers.ContainerRequest{5 ExposedPorts: []string{"80/tcp"},6 Cmd: []string{"echo", "hello world"},7 WaitingFor: wait.ForLog("hello world"),8 }9 c, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{10 })11 if err != nil {12 log.Fatalf("Could not create container: %v", err)13 }14 defer c.Terminate(ctx)15}16import (17func main() {18 ctx := context.Background()19 req := testcontainers.ContainerRequest{20 ExposedPorts: []string{"80/tcp"},21 Cmd: []string{"echo", "hello world"},22 WaitingFor: wait.ForLog("hello world"),23 }24 c, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{25 })26 if err != nil {27 log.Fatalf("Could not create container: %v", err)28 }29 c.Terminate(ctx)30}

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run Testcontainers-go automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Most used method in

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful