From f150875d4c6901a6feb076a2bb17c8b209ec85fd Mon Sep 17 00:00:00 2001 From: Jordan Pittier Date: Tue, 9 Jan 2024 13:09:11 +0100 Subject: [PATCH] GenericContainer: in case of error: return a reference to the failed container This way, the caller has an opportunity to clean things up and call Destroy on the failed container. --- generic.go | 3 ++- generic_test.go | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/generic.go b/generic.go index bd5f34c8e7..05747774c5 100644 --- a/generic.go +++ b/generic.go @@ -74,7 +74,8 @@ func GenericContainer(ctx context.Context, req GenericContainerRequest) (Contain c, err = provider.CreateContainer(ctx, req.ContainerRequest) } if err != nil { - return nil, fmt.Errorf("%w: failed to create container", err) + // At this point `c` might not be nil. Give the caller an opportunity to call Destroy on the container. + return c, fmt.Errorf("%w: failed to create container", err) } if req.Started && !c.IsRunning() { diff --git a/generic_test.go b/generic_test.go index 77faa919c2..cb38e29faf 100644 --- a/generic_test.go +++ b/generic_test.go @@ -4,6 +4,7 @@ import ( "context" "errors" "testing" + "time" "github.com/stretchr/testify/require" @@ -96,3 +97,23 @@ func TestGenericReusableContainer(t *testing.T) { }) } } + +func TestGenericContainerShouldReturnRefOnError(t *testing.T) { + // In this test, we are going to cancel the context to exit the `wait.Strategy`. + // We want to make sure that the GenericContainer call will still return a reference to the + // created container, so that we can Destroy it. + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) + defer cancel() + + c, err := GenericContainer(ctx, GenericContainerRequest{ + ProviderType: providerType, + ContainerRequest: ContainerRequest{ + Image: nginxAlpineImage, + WaitingFor: wait.ForLog("this string should not be present in the logs"), + }, + Started: true, + }) + require.Error(t, err) + require.NotNil(t, c) + terminateContainerOnEnd(t, context.Background(), c) +}