Skip to content

Commit

Permalink
fix(localstack): more reliable legacy tag detection (#2936)
Browse files Browse the repository at this point in the history
* fix(localstack): more reliable tag version detection

* fix(localstack): refactor isLegacyMode and isVersion2
  • Loading branch information
NathanBaulch authored Jan 14, 2025
1 parent 09dd613 commit 83d5e55
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 28 deletions.
41 changes: 15 additions & 26 deletions modules/localstack/localstack.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package localstack
import (
"context"
"fmt"
"slices"
"strings"
"time"

Expand All @@ -20,42 +21,30 @@ const (
localstackHostEnvVar = "LOCALSTACK_HOST"
)

func isLegacyMode(image string) bool {
parts := strings.Split(image, ":")
version := parts[len(parts)-1]

if version == "latest" {
return false
}

if !strings.HasPrefix(version, "v") {
version = "v" + version
}

if semver.IsValid(version) {
return semver.Compare(version, "v0.11") < 0 // version < v0.11
}

return true
var recentVersionTags = []string{
"latest",
"s3",
"s3-latest",
"stable",
}

func isVersion2(image string) bool {
func isMinimumVersion(image string, minVersion string) bool {
parts := strings.Split(image, ":")
version := parts[len(parts)-1]

if version == "latest" {
if pos := strings.LastIndexByte(version, '-'); pos >= 0 {
version = version[0:pos]
}

if slices.Contains(recentVersionTags, version) {
return true
}

if !strings.HasPrefix(version, "v") {
version = "v" + version
}

if semver.IsValid(version) {
return semver.Compare(version, "v2.0") > 0 // version >= v2.0
}

return true
return semver.IsValid(version) && semver.Compare(version, minVersion) >= 0
}

// WithNetwork creates a network with the given name and attaches the container to it, setting the network alias
Expand Down Expand Up @@ -100,12 +89,12 @@ func Run(ctx context.Context, img string, opts ...testcontainers.ContainerCustom
}
}

if isLegacyMode(localStackReq.Image) {
if !isMinimumVersion(localStackReq.Image, "v0.11") {
return nil, fmt.Errorf("version=%s. Testcontainers for Go does not support running LocalStack in legacy mode. Please use a version >= 0.11.0", localStackReq.Image)
}

envVar := hostnameExternalEnvVar
if isVersion2(localStackReq.Image) {
if isMinimumVersion(localStackReq.Image, "v2") {
envVar = localstackHostEnvVar
}

Expand Down
57 changes: 55 additions & 2 deletions modules/localstack/localstack_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,24 +82,77 @@ func TestConfigureDockerHost(t *testing.T) {
}
}

func TestIsLegacyMode(t *testing.T) {
func TestIsLegacyVersion(t *testing.T) {
tests := []struct {
version string
want bool
}{
{"foo", true},
{"latest", false},
{"latest-amd64", false},
{"s3-latest", false},
{"s3-latest-amd64", false},
{"stable", false},
{"stable-amd64", false},
{"0.10.0", true},
{"0.10.0-amd64", true},
{"0.10.999", true},
{"0.10.999-amd64", true},
{"0.11", false},
{"0.11-amd64", false},
{"0.11.2", false},
{"0.11.2-amd64", false},
{"0.12", false},
{"0.12-amd64", false},
{"1", false},
{"1-amd64", false},
{"1.0", false},
{"1.0-amd64", false},
}

for _, tt := range tests {
t.Run(tt.version, func(t *testing.T) {
got := isLegacyMode("localstack/localstack:" + tt.version)
got := !isMinimumVersion("localstack/localstack:"+tt.version, "v0.11")
require.Equal(t, tt.want, got, "runInLegacyMode() = %v, want %v", got, tt.want)
})
}
}

func TestIsMinimumVersion2(t *testing.T) {
tests := []struct {
version string
want bool
}{
{"foo", false},
{"latest", true},
{"latest-amd64", true},
{"s3-latest", true},
{"s3-latest-amd64", true},
{"stable", true},
{"stable-amd64", true},
{"1", false},
{"1-amd64", false},
{"1.12", false},
{"1.12-amd64", false},
{"1.12.2", false},
{"1.12.2-amd64", false},
{"2", true},
{"2-amd64", true},
{"2.0", true},
{"2.0-amd64", true},
{"2.0.0", true},
{"2.0.0-amd64", true},
{"2.0.1", true},
{"2.0.1-amd64", true},
{"2.1", true},
{"2.1-amd64", true},
{"3", true},
{"3-amd64", true},
}

for _, tt := range tests {
t.Run(tt.version, func(t *testing.T) {
got := isMinimumVersion("localstack/localstack:"+tt.version, "v2")
require.Equal(t, tt.want, got, "runInLegacyMode() = %v, want %v", got, tt.want)
})
}
Expand Down

0 comments on commit 83d5e55

Please sign in to comment.