How to use TestLogger method of testcontainers Package

Best Testcontainers-go code snippet using testcontainers.TestLogger

frontend_test.go

Source:frontend_test.go Github

copy

Full Screen

1package containerutil_test2import (3 "bufio"4 "bytes"5 "context"6 "fmt"7 "os"8 "os/exec"9 "strings"10 "sync"11 "testing"12 "time"13 "github.com/earthly/earthly/conslogging"14 "github.com/earthly/earthly/util/containerutil"15 "github.com/hashicorp/go-multierror"16 "github.com/pkg/errors"17 "github.com/stretchr/testify/assert"18)19func TestFrontendNew(t *testing.T) {20 testCases := []struct {21 binary string22 newFunc func(context.Context, *containerutil.FrontendConfig) (containerutil.ContainerFrontend, error)23 }{24 {"docker", containerutil.NewDockerShellFrontend},25 {"podman", containerutil.NewPodmanShellFrontend},26 }27 for _, tC := range testCases {28 t.Run(tC.binary, func(t *testing.T) {29 ctx := context.Background()30 onlyIfBinaryIsInstalled(ctx, t, tC.binary)31 fe, err := tC.newFunc(ctx, &containerutil.FrontendConfig{Console: testLogger()})32 assert.NoError(t, err)33 assert.NotNil(t, fe)34 })35 }36}37func TestFrontendScheme(t *testing.T) {38 testCases := []struct {39 binary string40 newFunc func(context.Context, *containerutil.FrontendConfig) (containerutil.ContainerFrontend, error)41 scheme string42 }{43 {"docker", containerutil.NewDockerShellFrontend, "docker-container"},44 {"podman", containerutil.NewPodmanShellFrontend, "podman-container"},45 }46 for _, tC := range testCases {47 t.Run(tC.binary, func(t *testing.T) {48 ctx := context.Background()49 onlyIfBinaryIsInstalled(ctx, t, tC.binary)50 fe, err := tC.newFunc(ctx, &containerutil.FrontendConfig{Console: testLogger()})51 assert.NoError(t, err)52 scheme := fe.Scheme()53 assert.Equal(t, tC.scheme, scheme)54 })55 }56}57func TestFrontendIsAvailable(t *testing.T) {58 testCases := []struct {59 binary string60 newFunc func(context.Context, *containerutil.FrontendConfig) (containerutil.ContainerFrontend, error)61 }{62 {"docker", containerutil.NewDockerShellFrontend},63 {"podman", containerutil.NewPodmanShellFrontend},64 }65 for _, tC := range testCases {66 t.Run(tC.binary, func(t *testing.T) {67 ctx := context.Background()68 onlyIfBinaryIsInstalled(ctx, t, tC.binary)69 fe, err := tC.newFunc(ctx, &containerutil.FrontendConfig{Console: testLogger()})70 assert.NoError(t, err)71 avaliable := fe.IsAvailable(ctx)72 assert.True(t, avaliable)73 })74 }75}76func TestFrontendInformation(t *testing.T) {77 testCases := []struct {78 binary string79 newFunc func(context.Context, *containerutil.FrontendConfig) (containerutil.ContainerFrontend, error)80 }{81 {"docker", containerutil.NewDockerShellFrontend},82 {"podman", containerutil.NewPodmanShellFrontend},83 }84 for _, tC := range testCases {85 t.Run(tC.binary, func(t *testing.T) {86 ctx := context.Background()87 onlyIfBinaryIsInstalled(ctx, t, tC.binary)88 fe, err := tC.newFunc(ctx, &containerutil.FrontendConfig{Console: testLogger()})89 assert.NoError(t, err)90 info, err := fe.Information(ctx)91 assert.NoError(t, err)92 assert.NotNil(t, info)93 })94 }95}96func TestFrontendContainerInfo(t *testing.T) {97 testCases := []struct {98 binary string99 newFunc func(context.Context, *containerutil.FrontendConfig) (containerutil.ContainerFrontend, error)100 }{101 {"docker", containerutil.NewDockerShellFrontend},102 {"podman", containerutil.NewPodmanShellFrontend},103 }104 for _, tC := range testCases {105 t.Run(tC.binary, func(t *testing.T) {106 ctx := context.Background()107 onlyIfBinaryIsInstalled(ctx, t, tC.binary)108 testContainers := []string{"test-1", "test-2"}109 cleanup, err := spawnTestContainers(ctx, tC.binary, testContainers...)110 t.Cleanup(cleanup)111 assert.NoError(t, err)112 fe, err := tC.newFunc(ctx, &containerutil.FrontendConfig{Console: testLogger()})113 assert.NoError(t, err)114 getInfos := append(testContainers, "missing")115 info, err := fe.ContainerInfo(ctx, getInfos...)116 assert.NoError(t, err)117 assert.NotNil(t, info)118 assert.Len(t, info, 3)119 assert.Equal(t, getInfos[0], info[getInfos[0]].Name)120 assert.Equal(t, "docker.io/library/nginx:1.21", info[getInfos[0]].Image)121 assert.Equal(t, getInfos[1], info[getInfos[1]].Name)122 assert.Equal(t, "docker.io/library/nginx:1.21", info[getInfos[1]].Image)123 assert.Equal(t, getInfos[2], info[getInfos[2]].Name)124 assert.Equal(t, containerutil.StatusMissing, info[getInfos[2]].Status)125 })126 }127}128func TestFrontendContainerRemove(t *testing.T) {129 testCases := []struct {130 binary string131 newFunc func(context.Context, *containerutil.FrontendConfig) (containerutil.ContainerFrontend, error)132 }{133 {"docker", containerutil.NewDockerShellFrontend},134 {"podman", containerutil.NewPodmanShellFrontend},135 }136 for _, tC := range testCases {137 t.Run(tC.binary, func(t *testing.T) {138 ctx := context.Background()139 onlyIfBinaryIsInstalled(ctx, t, tC.binary)140 testContainers := []string{"remove-1", "remove-2"}141 cleanup, err := spawnTestContainers(ctx, tC.binary, testContainers...)142 t.Cleanup(cleanup)143 assert.NoError(t, err)144 fe, err := tC.newFunc(ctx, &containerutil.FrontendConfig{Console: testLogger()})145 assert.NoError(t, err)146 info, err := fe.ContainerInfo(ctx, testContainers...)147 assert.NoError(t, err)148 assert.Len(t, info, 2)149 err = fe.ContainerRemove(ctx, true, testContainers...)150 assert.NoError(t, err)151 info, err = fe.ContainerInfo(ctx, testContainers...)152 assert.NoError(t, err)153 assert.Equal(t, containerutil.StatusMissing, info[testContainers[0]].Status)154 assert.Equal(t, containerutil.StatusMissing, info[testContainers[1]].Status)155 })156 }157}158func TestFrontendContainerStop(t *testing.T) {159 testCases := []struct {160 binary string161 newFunc func(context.Context, *containerutil.FrontendConfig) (containerutil.ContainerFrontend, error)162 }{163 {"docker", containerutil.NewDockerShellFrontend},164 {"podman", containerutil.NewPodmanShellFrontend},165 }166 for _, tC := range testCases {167 t.Run(tC.binary, func(t *testing.T) {168 ctx := context.Background()169 onlyIfBinaryIsInstalled(ctx, t, tC.binary)170 testContainers := []string{"stop-1", "stop-2"}171 cleanup, err := spawnTestContainers(ctx, tC.binary, testContainers...)172 t.Cleanup(cleanup)173 assert.NoError(t, err)174 fe, err := tC.newFunc(ctx, &containerutil.FrontendConfig{Console: testLogger()})175 assert.NoError(t, err)176 info, err := fe.ContainerInfo(ctx, testContainers...)177 assert.NoError(t, err)178 assert.Len(t, info, 2)179 err = fe.ContainerStop(ctx, 0, testContainers...)180 assert.NoError(t, err)181 _, err = fe.ContainerInfo(ctx, testContainers...)182 assert.NoError(t, err)183 assert.Len(t, info, 2)184 })185 }186}187func TestFrontendContainerLogs(t *testing.T) {188 testCases := []struct {189 binary string190 newFunc func(context.Context, *containerutil.FrontendConfig) (containerutil.ContainerFrontend, error)191 }{192 {"docker", containerutil.NewDockerShellFrontend},193 {"podman", containerutil.NewPodmanShellFrontend},194 }195 for _, tC := range testCases {196 t.Run(tC.binary, func(t *testing.T) {197 ctx := context.Background()198 onlyIfBinaryIsInstalled(ctx, t, tC.binary)199 testContainers := []string{"logs-1", "logs-2"}200 cleanup, err := spawnTestContainers(ctx, tC.binary, testContainers...)201 t.Cleanup(cleanup)202 assert.NoError(t, err)203 fe, err := tC.newFunc(ctx, &containerutil.FrontendConfig{Console: testLogger()})204 assert.NoError(t, err)205 logs, err := fe.ContainerLogs(ctx, testContainers...)206 assert.NoError(t, err)207 assert.Len(t, logs, 2)208 assert.Equal(t, "output stream\n", logs[testContainers[0]].Stdout)209 assert.Equal(t, "error stream\n", logs[testContainers[0]].Stderr)210 assert.Equal(t, "output stream\n", logs[testContainers[1]].Stdout)211 assert.Equal(t, "error stream\n", logs[testContainers[1]].Stderr)212 })213 }214}215func TestFrontendContainerRun(t *testing.T) {216 testCases := []struct {217 binary string218 newFunc func(context.Context, *containerutil.FrontendConfig) (containerutil.ContainerFrontend, error)219 }{220 {"docker", containerutil.NewDockerShellFrontend},221 {"podman", containerutil.NewPodmanShellFrontend},222 }223 for _, tC := range testCases {224 t.Run(tC.binary, func(t *testing.T) {225 ctx := context.Background()226 onlyIfBinaryIsInstalled(ctx, t, tC.binary)227 fe, err := tC.newFunc(ctx, &containerutil.FrontendConfig{Console: testLogger()})228 assert.NoError(t, err)229 testContainers := []string{"create-1", "create-2"}230 runs := []containerutil.ContainerRun{}231 for _, name := range testContainers {232 runs = append(runs, containerutil.ContainerRun{233 NameOrID: name,234 ImageRef: "docker.io/nginx:1.21",235 Privileged: false,236 Envs: containerutil.EnvMap{"test": name},237 Labels: containerutil.LabelMap{"test": name},238 ContainerArgs: []string{"nginx-debug", "-g", "daemon off;"},239 AdditionalArgs: []string{"--rm"},240 Mounts: containerutil.MountOpt{241 containerutil.Mount{242 Type: containerutil.MountVolume,243 Source: fmt.Sprintf("vol-%s", name),244 Dest: "/test",245 ReadOnly: true,246 },247 },248 Ports: containerutil.PortOpt{249 containerutil.Port{250 IP: "127.0.0.1",251 HostPort: 0,252 ContainerPort: 5678,253 Protocol: containerutil.ProtocolTCP,254 },255 },256 })257 }258 defer func() {259 for _, name := range testContainers {260 // Roll our own cleanup since we can't use the spawn test containers helper... since261 // the whole point of this test is to create them with a frontend. Also theres a volume262 cmd := exec.CommandContext(ctx, tC.binary, "rm", "-f", name)263 _ = cmd.Run() // Just best effort264 cmd = exec.CommandContext(ctx, tC.binary, "volume", "rm", "-f", fmt.Sprintf("vol-%s", name))265 _ = cmd.Run()266 }267 }()268 info, err := fe.ContainerInfo(ctx, testContainers...)269 assert.NoError(t, err)270 assert.Equal(t, containerutil.StatusMissing, info[testContainers[0]].Status)271 assert.Equal(t, containerutil.StatusMissing, info[testContainers[1]].Status)272 err = fe.ContainerRun(ctx, runs...)273 assert.NoError(t, err)274 info, err = fe.ContainerInfo(ctx, testContainers...)275 assert.NoError(t, err)276 assert.Equal(t, containerutil.StatusRunning, info[testContainers[0]].Status)277 assert.Equal(t, containerutil.StatusRunning, info[testContainers[1]].Status)278 })279 }280}281func TestFrontendImagePull(t *testing.T) {282 testCases := []struct {283 binary string284 newFunc func(context.Context, *containerutil.FrontendConfig) (containerutil.ContainerFrontend, error)285 refList []string286 }{287 {"docker", containerutil.NewDockerShellFrontend, []string{"nginx:1.21", "alpine:3.15"}},288 {"podman", containerutil.NewPodmanShellFrontend, []string{"docker.io/nginx:1.21", "docker.io/alpine:3.15"}}, // Podman prefers... and exports fully-qualified image tags289 }290 for _, tC := range testCases {291 t.Run(tC.binary, func(t *testing.T) {292 ctx := context.Background()293 onlyIfBinaryIsInstalled(ctx, t, tC.binary)294 fe, err := tC.newFunc(ctx, &containerutil.FrontendConfig{295 LocalRegistryHostFileValue: "tcp://some-host:5309", // podman pull needs some potentially valid address to check against, otherwise panic296 Console: testLogger(),297 })298 assert.NoError(t, err)299 err = fe.ImagePull(ctx, tC.refList...)300 assert.NoError(t, err)301 defer func() {302 for _, ref := range tC.refList {303 cmd := exec.CommandContext(ctx, "docker", "image", "rm", "-f", ref)304 _ = cmd.Run()305 }306 }()307 })308 }309}310func TestFrontendImageInfo(t *testing.T) {311 testCases := []struct {312 binary string313 newFunc func(context.Context, *containerutil.FrontendConfig) (containerutil.ContainerFrontend, error)314 refList []string315 }{316 {"docker", containerutil.NewDockerShellFrontend, []string{"info:1", "info:2"}},317 {"podman", containerutil.NewPodmanShellFrontend, []string{"localhost/info:1", "localhost/info:2"}},318 }319 for _, tC := range testCases {320 t.Run(tC.binary, func(t *testing.T) {321 ctx := context.Background()322 onlyIfBinaryIsInstalled(ctx, t, tC.binary)323 cleanup, err := spawnTestImages(ctx, tC.binary, tC.refList...)324 assert.NoError(t, err)325 t.Cleanup(cleanup)326 fe, err := tC.newFunc(ctx, &containerutil.FrontendConfig{Console: testLogger()})327 assert.NoError(t, err)328 info, err := fe.ImageInfo(ctx, tC.refList...)329 assert.NoError(t, err)330 assert.Len(t, info, 2)331 assert.Contains(t, info[tC.refList[0]].Tags, tC.refList[0])332 assert.Contains(t, info[tC.refList[1]].Tags, tC.refList[1])333 })334 }335}336func TestFrontendImageRemove(t *testing.T) {337 testCases := []struct {338 binary string339 newFunc func(context.Context, *containerutil.FrontendConfig) (containerutil.ContainerFrontend, error)340 }{341 {"docker", containerutil.NewDockerShellFrontend},342 {"podman", containerutil.NewPodmanShellFrontend},343 }344 for _, tC := range testCases {345 t.Run(tC.binary, func(t *testing.T) {346 ctx := context.Background()347 onlyIfBinaryIsInstalled(ctx, t, tC.binary)348 refList := []string{"remove:1", "remove:2"}349 cleanup, err := spawnTestImages(ctx, tC.binary, refList...)350 assert.NoError(t, err)351 t.Cleanup(cleanup)352 fe, err := tC.newFunc(ctx, &containerutil.FrontendConfig{Console: testLogger()})353 assert.NoError(t, err)354 info, err := fe.ImageInfo(ctx, refList...)355 assert.NoError(t, err)356 assert.Len(t, info, 2)357 err = fe.ImageRemove(ctx, true, refList...)358 assert.NoError(t, err)359 info, err = fe.ImageInfo(ctx, refList...)360 assert.NoError(t, err)361 assert.Empty(t, info[refList[0]].ID)362 assert.Empty(t, info[refList[1]].ID)363 })364 }365}366func TestFrontendImageTag(t *testing.T) {367 testCases := []struct {368 binary string369 newFunc func(context.Context, *containerutil.FrontendConfig) (containerutil.ContainerFrontend, error)370 tagList []string371 }{372 {"docker", containerutil.NewDockerShellFrontend, []string{"tag:1", "tag:2"}},373 {"podman", containerutil.NewPodmanShellFrontend, []string{"localhost/tag:1", "localhost/tag:2"}},374 }375 for _, tC := range testCases {376 t.Run(tC.binary, func(t *testing.T) {377 ctx := context.Background()378 onlyIfBinaryIsInstalled(ctx, t, tC.binary)379 ref := "tag:me"380 cleanup, err := spawnTestImages(ctx, tC.binary, ref)381 assert.NoError(t, err)382 t.Cleanup(cleanup)383 fe, err := tC.newFunc(ctx, &containerutil.FrontendConfig{Console: testLogger()})384 assert.NoError(t, err)385 info, err := fe.ImageInfo(ctx, ref)386 assert.NoError(t, err)387 imageID := info[ref].ID388 tags := []containerutil.ImageTag{}389 for _, tagName := range tC.tagList {390 tags = append(tags, containerutil.ImageTag{391 SourceRef: imageID,392 TargetRef: tagName,393 })394 }395 err = fe.ImageTag(ctx, tags...)396 assert.NoError(t, err)397 info, err = fe.ImageInfo(ctx, tC.tagList...)398 assert.NoError(t, err)399 assert.Contains(t, info[tC.tagList[0]].Tags, tC.tagList[0])400 assert.Contains(t, info[tC.tagList[1]].Tags, tC.tagList[1])401 })402 }403}404func TestFrontendImageLoad(t *testing.T) {405 testCases := []struct {406 binary string407 newFunc func(context.Context, *containerutil.FrontendConfig) (containerutil.ContainerFrontend, error)408 ref string409 }{410 {"docker", containerutil.NewDockerShellFrontend, "load:me"},411 {"podman", containerutil.NewPodmanShellFrontend, "localhost/load:me"},412 }413 for _, tC := range testCases {414 t.Run(tC.binary, func(t *testing.T) {415 ctx := context.Background()416 onlyIfBinaryIsInstalled(ctx, t, tC.binary)417 cleanup, err := spawnTestImages(ctx, tC.binary, tC.ref)418 assert.NoError(t, err)419 imgBuffer := &bytes.Buffer{}420 cmd := exec.CommandContext(ctx, tC.binary, "image", "save", tC.ref)421 cmd.Stdout = bufio.NewWriter(imgBuffer)422 err = cmd.Run()423 assert.NoError(t, err)424 cleanup()425 fe, err := tC.newFunc(ctx, &containerutil.FrontendConfig{Console: testLogger()})426 assert.NoError(t, err)427 err = fe.ImageLoad(ctx, bufio.NewReader(imgBuffer))428 assert.NoError(t, err)429 defer func() {430 cmd := exec.CommandContext(ctx, tC.binary, "image", "rm", "-f", tC.ref)431 _ = cmd.Run()432 }()433 info, err := fe.ImageInfo(ctx, tC.ref)434 assert.NoError(t, err)435 assert.Contains(t, info[tC.ref].Tags, tC.ref)436 })437 }438}439func TestFrontendImageLoadHybrid(t *testing.T) {440 testCases := []struct {441 binary string442 newFunc func(context.Context, *containerutil.FrontendConfig) (containerutil.ContainerFrontend, error)443 ref string444 }{445 {"docker", containerutil.NewDockerShellFrontend, "hybrid:test"},446 {"podman", containerutil.NewPodmanShellFrontend, "localhost/hybrid:test"},447 }448 for _, tC := range testCases {449 t.Run(tC.binary, func(t *testing.T) {450 ctx := context.Background()451 onlyIfBinaryIsInstalled(ctx, t, tC.binary)452 fe, err := tC.newFunc(ctx, &containerutil.FrontendConfig{Console: testLogger()})453 assert.NoError(t, err)454 data, err := os.ReadFile("./testdata/hybrid.tar")455 assert.NoError(t, err)456 reader := bytes.NewReader(data)457 err = fe.ImageLoad(ctx, reader)458 assert.NoError(t, err)459 defer func() {460 cmd := exec.CommandContext(ctx, tC.binary, "image", "rm", "-f", tC.ref)461 _ = cmd.Run()462 }()463 info, err := fe.ImageInfo(ctx, tC.ref)464 assert.NoError(t, err)465 assert.Contains(t, info[tC.ref].Tags, tC.ref)466 })467 }468}469func TestFrontendVolumeInfo(t *testing.T) {470 testCases := []struct {471 binary string472 newFunc func(context.Context, *containerutil.FrontendConfig) (containerutil.ContainerFrontend, error)473 }{474 {"docker", containerutil.NewDockerShellFrontend},475 {"podman", containerutil.NewPodmanShellFrontend},476 }477 for _, tC := range testCases {478 t.Run(tC.binary, func(t *testing.T) {479 ctx := context.Background()480 onlyIfBinaryIsInstalled(ctx, t, tC.binary)481 volList := []string{"test1", "test2"}482 cleanup, err := spawnTestVolumes(ctx, tC.binary, volList...)483 assert.NoError(t, err)484 t.Cleanup(cleanup)485 fe, err := tC.newFunc(ctx, &containerutil.FrontendConfig{Console: testLogger()})486 assert.NoError(t, err)487 info, err := fe.VolumeInfo(ctx, volList...)488 assert.NoError(t, err)489 assert.Len(t, info, 2)490 })491 }492}493func onlyIfBinaryIsInstalled(ctx context.Context, t *testing.T, binary string) {494 if !isBinaryInstalled(ctx, binary) {495 t.Skipf("%s is not avaliable for tests, skipping", binary)496 }497}498func isBinaryInstalled(ctx context.Context, binary string) bool {499 // This is almost a re-implementation of IsAvailable... but relying on that presupposes the500 // binary exists to allow the New**** to run (it gathers info from the CLI).501 cmd := exec.CommandContext(ctx, binary, "--help")502 return cmd.Run() == nil503}504// First, we attempt to stop the containers that may be running.505// Next, we start the containers506// After that, we attempt to wait for the containers for up to 20 seconds507// Then we return508// Caller is always expected to call cleanup509func spawnTestContainers(ctx context.Context, feBinary string, names ...string) (func(), error) {510 _ = removeContainers(ctx, feBinary, names...) // best effort511 err := startTestContainers(ctx, feBinary, names...)512 cleanup := func() {513 _ = removeContainers(ctx, feBinary, names...) // best-effort514 }515 if err != nil {516 return cleanup, err517 }518 err = waitForContainers(ctx, feBinary, names...)519 return cleanup, err520}521func startTestContainers(ctx context.Context, feBinary string, names ...string) error {522 var err error523 m := sync.Mutex{}524 wg := sync.WaitGroup{}525 image := "docker.io/library/nginx:1.21"526 pullErr := pullImageIfNecessary(ctx, feBinary, image)527 if pullErr != nil {528 return fmt.Errorf("failed to pull image %s: %w", image, pullErr)529 }530 for _, name := range names {531 wg.Add(1)532 go func(name string) {533 defer wg.Done()534 cmd := exec.CommandContext(ctx, feBinary, "run", "-d", "--rm", "--name", name, image, "sh", "-c", `echo output stream&&>&2 echo error stream&&sleep 100`)535 output, createErr := cmd.CombinedOutput()536 m.Lock()537 defer m.Unlock()538 if createErr != nil {539 // the frontend exists but is non-functional. This is... not likely to work at all.540 err = multierror.Append(err, errors.Wrap(createErr, string(output)))541 }542 }(name)543 }544 wg.Wait()545 return err546}547// pullImageIfNecessary will only pull the image if it does not exist locally548// This helps us avoid unauthenticated rate limits in tests549func pullImageIfNecessary(ctx context.Context, feBinary string, image string) error {550 cmd := exec.CommandContext(ctx, feBinary, "inspect", "--type=image", image)551 _, inspectErr := cmd.CombinedOutput()552 if inspectErr == nil {553 // If we are able to inspect the image then it must exist locally554 return nil555 }556 cmd = exec.CommandContext(ctx, feBinary, "pull", image)557 _, pullErr := cmd.CombinedOutput()558 if pullErr != nil {559 return fmt.Errorf("failed to pull image %s: %w", image, pullErr)560 }561 return nil562}563func removeContainers(ctx context.Context, feBinary string, names ...string) error {564 var err error565 m := sync.Mutex{}566 wg := sync.WaitGroup{}567 for _, name := range names {568 wg.Add(1)569 go func(name string) {570 defer wg.Done()571 removeCmd := exec.CommandContext(ctx, feBinary, "rm", "-f", name)572 _, removeErr := removeCmd.CombinedOutput()573 m.Lock()574 defer m.Unlock()575 if removeErr != nil {576 err = multierror.Append(err, fmt.Errorf("failed to remove container %s", name))577 }578 }(name)579 }580 wg.Wait()581 return err582}583func waitForContainers(ctx context.Context, feBinary string, names ...string) error {584 var err error585 m := sync.Mutex{}586 wg := sync.WaitGroup{}587 for _, name := range names {588 const maxAttempts = 100589 wg.Add(1)590 go func(name string) {591 defer wg.Done()592 attempts := 0593 for attempts < maxAttempts {594 attempts++595 // docker inspect -f {{.State.Running}} CONTAINERNAME`"=="true"596 cmd := exec.CommandContext(ctx, feBinary, "inspect", "-f", "{{.State.Running}}", name)597 output, inspectErr := cmd.CombinedOutput()598 if inspectErr != nil {599 m.Lock()600 err = multierror.Append(err, inspectErr)601 m.Unlock()602 return603 }604 if strings.Contains(string(output), "true") {605 return606 }607 time.Sleep(time.Millisecond * 200)608 }609 m.Lock()610 defer m.Unlock()611 err = multierror.Append(err, fmt.Errorf("failed to wait for container %s to start", name))612 }(name)613 }614 wg.Wait()615 return err616}617func spawnTestImages(ctx context.Context, feBinary string, refs ...string) (func(), error) {618 var err error619 for _, ref := range refs {620 cmd := exec.CommandContext(ctx, feBinary, "image", "pull", "docker.io/nginx:1.21")621 output, createErr := cmd.CombinedOutput()622 if createErr != nil {623 // the frontend exists but is non-functional. This is... not likely to work at all.624 err = multierror.Append(err, errors.Wrap(createErr, string(output)))625 break626 }627 cmd = exec.CommandContext(ctx, feBinary, "image", "tag", "docker.io/nginx:1.21", ref)628 output, tagErr := cmd.CombinedOutput()629 if tagErr != nil {630 // the frontend exists but is non-functional. This is... not likely to work at all.631 err = multierror.Append(err, errors.Wrap(tagErr, string(output)))632 break633 }634 }635 return func() {636 for _, ref := range refs {637 cmd := exec.CommandContext(ctx, feBinary, "image", "rm", "-f", ref)638 _ = cmd.Run() // Just best effort639 }640 }, err641}642func spawnTestVolumes(ctx context.Context, feBinary string, names ...string) (func(), error) {643 var err error644 for _, name := range names {645 cmd := exec.CommandContext(ctx, feBinary, "volume", "create", name)646 output, createErr := cmd.CombinedOutput()647 if createErr != nil {648 // the frontend exists but is non-functional. This is... not likely to work at all.649 err = multierror.Append(err, errors.Wrap(createErr, string(output)))650 }651 }652 return func() {653 for _, name := range names {654 cmd := exec.CommandContext(ctx, feBinary, "volume", "rm", "-f", name)655 _ = cmd.Run() // Just best effort656 }657 }, nil658}659func testLogger() conslogging.ConsoleLogger {660 var logs strings.Builder661 logger := conslogging.Current(conslogging.NoColor, conslogging.DefaultPadding, conslogging.Info)662 return logger.WithWriter(&logs)663}...

Full Screen

Full Screen

logger.go

Source:logger.go Github

copy

Full Screen

...9// Logging defines the Logger interface10type Logging interface {11 Printf(format string, v ...interface{})12}13// TestLogger returns a Logging implementation for testing.TB14// This way logs from testcontainers are part of the test output of a test suite or test case15func TestLogger(tb testing.TB) Logging {16 tb.Helper()17 return testLogger{TB: tb}18}19// WithLogger is a generic option that implements GenericProviderOption, DockerProviderOption and LocalDockerComposeOption20// It replaces the global Logging implementation with a user defined one e.g. to aggregate logs from testcontainers21// with the logs of specific test case22func WithLogger(logger Logging) LoggerOption {23 return LoggerOption{24 logger: logger,25 }26}27type LoggerOption struct {28 logger Logging29}...

Full Screen

Full Screen

TestLogger

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 ctx := context.Background()4 req := testcontainers.ContainerRequest{5 Cmd: []string{"echo", "hello world"},6 ExposedPorts: []string{"80/tcp"},7 WaitingFor: wait.ForLog("hello world"),8 }9 c, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{10 })11 if err != nil {12 log.Fatal(err)13 }14 logs, err := c.Logs(ctx)15 if err != nil {16 log.Fatal(err)17 }18 fmt.Println(logs)19 if err := c.Terminate(ctx); err != nil {20 log.Fatal(err)21 }22 time.Sleep(5 * time.Second)23}24import (25func main() {26 ctx := context.Background()27 req := testcontainers.ContainerRequest{28 Cmd: []string{"echo", "hello world"},29 ExposedPorts: []string{"80/tcp"},30 WaitingFor: wait.ForLog("hello world"),31 }32 c, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{33 })34 if err != nil {35 log.Fatal(err)36 }37 if err := testcontainers.TestLogs(ctx, c, "hello world"); err != nil {38 log.Fatal(err)

Full Screen

Full Screen

TestLogger

Using AI Code Generation

copy

Full Screen

1import (2func TestLogger(t *testing.T) {3 ctx := context.Background()4 req := testcontainers.ContainerRequest{5 Cmd: []string{"echo", "hello world"},6 ExposedPorts: []string{"80/tcp"},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 start container: %v", err)13 }14 ip, err := c.Host(ctx)15 if err != nil {16 log.Fatalf("Could not get container IP: %v", err)17 }18 port, err := c.MappedPort(ctx, "80")19 if err != nil {20 log.Fatalf("Could not get mapped port: %v", err)21 }22 fmt.Printf("Container IP: %s, Port: %s", ip, port.Port())23 if err := c.Terminate(ctx); err != nil {24 log.Fatalf("Could not stop container: %v", err)25 }26}27import (28func TestLogger(t *testing.T) {29 ctx := context.Background()30 req := testcontainers.ContainerRequest{31 Cmd: []string{"echo", "hello world"},32 ExposedPorts: []string{"80/tcp"},33 WaitingFor: wait.ForLog("hello world"),34 }35 c, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{36 })37 if err != nil {38 log.Fatalf("Could not start container: %v", err)39 }

Full Screen

Full Screen

TestLogger

Using AI Code Generation

copy

Full Screen

1import (2func TestLogger(t *testing.T) {3 req := testcontainers.ContainerRequest{4 ExposedPorts: []string{"80/tcp"},5 WaitingFor: wait.ForLog("ready"),6 }7 ctx := context.Background()8 c, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{9 })10 if err != nil {11 t.Fatal(err)12 }13 defer c.Terminate(ctx)14 ip, err := c.Host(ctx)15 if err != nil {16 t.Fatal(err)17 }18 port, err := c.MappedPort(ctx, "80")19 if err != nil {20 t.Fatal(err)21 }22 if err != nil {23 t.Fatal(err)24 }25}26import (27func TestLogger(t *testing.T) {28 req := testcontainers.ContainerRequest{29 ExposedPorts: []string{"80/tcp"},30 WaitingFor: wait.ForLog("ready"),31 }32 ctx := context.Background()33 c, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{34 })35 if err != nil {36 t.Fatal(err)37 }38 defer c.Terminate(ctx)39 ip, err := c.Host(ctx)40 if err != nil {41 t.Fatal(err)42 }43 port, err := c.MappedPort(ctx, "80")44 if err != nil {45 t.Fatal(err)46 }

Full Screen

Full Screen

TestLogger

Using AI Code Generation

copy

Full Screen

1import (2func TestLogger(t *testing.T) {3 ctx := context.Background()4 req := testcontainers.ContainerRequest{5 Cmd: []string{"echo", "hello world"},6 }7 resp, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{8 })9 if err != nil {10 log.Fatalf("Could not start container: %v", err)11 }12 defer resp.Terminate(ctx)13 logFile, err := os.Create("test.log")14 if err != nil {15 log.Fatalf("Could not create log file: %v", err)16 }17 defer logFile.Close()18 log.SetOutput(logFile)19 resp.FollowOutput(ctx, testcontainers.NewLogConsumer(t))20}21import (22func main() {23 ctx := context.Background()24 cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())25 if err != nil {26 log.Fatalf("Could not connect to Docker: %v", err)27 }28 logFile, err := os.Create("test.log")29 if err != nil {30 log.Fatalf("Could not create log file: %v", err)31 }32 defer logFile.Close()33 log.SetOutput(logFile)34 out, err := cli.ContainerLogs(ctx, "b1c4b4f0dc1b", types.ContainerLogsOptions{35 })36 if err != nil {37 log.Fatalf("Could not get logs from container: %v

Full Screen

Full Screen

TestLogger

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 ctx := context.Background()4 req := testcontainers.ContainerRequest{5 ExposedPorts: []string{"27017/tcp"},6 WaitingFor: wait.ForLog("waiting for connections on port"),7 }8 container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{9 })10 if err != nil {11 log.Fatal(err)12 }13 defer container.Terminate(ctx)14 mappedPort, err := container.MappedPort(ctx, "27017")15 if err != nil {16 log.Fatal(err)17 }18 fmt.Println(mappedPort.Int())19}20import (21func main() {22 ctx := context.Background()23 req := testcontainers.ContainerRequest{24 ExposedPorts: []string{"27017/tcp"},25 WaitingFor: wait.ForLog("waiting for connections on port"),26 }27 container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{28 })29 if err != nil {30 log.Fatal(err)31 }32 defer container.Terminate(ctx)33 mappedPort, err := container.MappedPort(ctx, "27017")34 if err != nil {35 log.Fatal(err)36 }37 fmt.Println(mappedPort.Int())38}39import (40func main() {41 ctx := context.Background()42 req := testcontainers.ContainerRequest{43 ExposedPorts: []string{"27017/tcp"},44 WaitingFor: wait.ForLog("waiting for

Full Screen

Full Screen

TestLogger

Using AI Code Generation

copy

Full Screen

1func TestLogger(t *testing.T) {2 ctx := context.Background()3 req := testcontainers.ContainerRequest{4 Cmd: []string{"echo", "hello world"},5 }6 resp, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{7 })8 if err != nil {9 t.Fatal(err)10 }11 defer resp.Terminate(ctx)12 logs, err := resp.Logs(ctx)13 if err != nil {14 t.Fatal(err)15 }16 fmt.Println(logs)17}18func TestLogger(t *testing.T) {19 ctx := context.Background()20 req := testcontainers.ContainerRequest{21 Cmd: []string{"echo", "hello world"},22 }23 resp, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{24 })25 if err != nil {26 t.Fatal(err)27 }28 defer resp.Terminate(ctx)29 logs, err := resp.Logs(ctx)30 if err != nil {31 t.Fatal(err)32 }33 fmt.Println(logs)34}35func TestLogger(t *testing.T) {36 ctx := context.Background()37 req := testcontainers.ContainerRequest{38 Cmd: []string{"echo", "hello world"},39 }40 resp, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{41 })42 if err != nil {43 t.Fatal(err)44 }45 defer resp.Terminate(ctx)46 logs, err := resp.Logs(ctx)47 if err != nil {48 t.Fatal(err)49 }50 fmt.Println(logs)51}

Full Screen

Full Screen

TestLogger

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 ctx := context.Background()4 req := testcontainers.ContainerRequest{5 ExposedPorts: []string{"8080/tcp"},6 WaitingFor: wait.ForHTTP("/ping").WithStartupTimeout(3 * time.Second),7 }8 ryukContainer, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{9 })10 if err != nil {11 log.Fatal(err)12 }13 defer ryukContainer.Terminate(ctx)14 ip, err := ryukContainer.Host(ctx)15 if err != nil {16 log.Fatal(err)17 }18 port, err := ryukContainer.MappedPort(ctx, "8080/tcp")19 if err != nil {20 log.Fatal(err)21 }22 fmt.Println("Ryuk is listening on", ip+":"+port.Port())23}24import (25func main() {26 ctx := context.Background()27 req := testcontainers.ContainerRequest{28 ExposedPorts: []string{"8080/tcp"},29 WaitingFor: wait.ForHTTP("/ping").WithStartupTimeout(3 * time.Second),30 }31 ryukContainer, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{32 })33 if err != nil {34 log.Fatal(err)35 }36 defer ryukContainer.Terminate(ctx)37 ip, err := ryukContainer.Host(ctx)38 if err != nil {39 log.Fatal(err)40 }41 port, err := ryukContainer.MappedPort(ctx, "8080/tcp")

Full Screen

Full Screen

TestLogger

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 logger := log.New(os.Stdout, "testcontainers", log.LstdFlags)4 if err != nil {5 logger.Fatal(err)6 }7 ctx := context.Background()8 req := testcontainers.ContainerRequest{9 Cmd: []string{"echo", "hello world"},10 ExposedPorts: []string{"80/tcp"},11 WaitingFor: wait.ForLog("hello world"),12 }13 c, err := client.CreateContainer(ctx, req)14 if err != nil {15 logger.Fatal(err)16 }17 defer c.Terminate(ctx)18 err = c.Start(ctx)19 if err != nil {20 logger.Fatal(err)21 }22 ip, err := c.Host(ctx)23 if err != nil {24 logger.Fatal(err)25 }26 port, err := c.MappedPort(ctx, "80")27 if err != nil {28 logger.Fatal(err)29 }30 fmt.Printf("Container %s is listening on port %s", ip, port.Port())31}32import (33func main() {34 logger := log.New(os.Stdout, "testcontainers", log.LstdFlags)35 if err != nil {36 logger.Fatal(err)37 }38 ctx := context.Background()39 req := testcontainers.ContainerRequest{40 Cmd: []string{"echo", "hello world"},41 ExposedPorts: []string{"80/tcp"},42 WaitingFor: wait.ForLog("

Full Screen

Full Screen

TestLogger

Using AI Code Generation

copy

Full Screen

1log := testcontainers.NewLogConsumer(t)2ctx := context.Background()3req := testcontainers.ContainerRequest{4ExposedPorts: []string{"6379/tcp"},5WaitingFor: wait.ForLog("Ready to accept connections"),6}7redisContainer, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{8})9require.NoError(t, err)10redisContainer.Start(ctx)11redisContainer.Terminate(ctx)12log := testcontainers.NewLogConsumer(t)13ctx := context.Background()14req := testcontainers.ContainerRequest{15ExposedPorts: []string{"6379/tcp"},16WaitingFor: wait.ForLog("Ready to accept connections"),17}18redisContainer, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{19})20require.NoError(t, err)21redisContainer.Start(ctx)22redisContainer.Terminate(ctx)23log := testcontainers.NewLogConsumer(t)24ctx := context.Background()25req := testcontainers.ContainerRequest{26ExposedPorts: []string{"6379/tcp

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