Skip to content

Commit 83d5e55

Browse files
authored
fix(localstack): more reliable legacy tag detection (#2936)
* fix(localstack): more reliable tag version detection * fix(localstack): refactor isLegacyMode and isVersion2
1 parent 09dd613 commit 83d5e55

File tree

2 files changed

+70
-28
lines changed

2 files changed

+70
-28
lines changed

modules/localstack/localstack.go

Lines changed: 15 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package localstack
33
import (
44
"context"
55
"fmt"
6+
"slices"
67
"strings"
78
"time"
89

@@ -20,42 +21,30 @@ const (
2021
localstackHostEnvVar = "LOCALSTACK_HOST"
2122
)
2223

23-
func isLegacyMode(image string) bool {
24-
parts := strings.Split(image, ":")
25-
version := parts[len(parts)-1]
26-
27-
if version == "latest" {
28-
return false
29-
}
30-
31-
if !strings.HasPrefix(version, "v") {
32-
version = "v" + version
33-
}
34-
35-
if semver.IsValid(version) {
36-
return semver.Compare(version, "v0.11") < 0 // version < v0.11
37-
}
38-
39-
return true
24+
var recentVersionTags = []string{
25+
"latest",
26+
"s3",
27+
"s3-latest",
28+
"stable",
4029
}
4130

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

46-
if version == "latest" {
35+
if pos := strings.LastIndexByte(version, '-'); pos >= 0 {
36+
version = version[0:pos]
37+
}
38+
39+
if slices.Contains(recentVersionTags, version) {
4740
return true
4841
}
4942

5043
if !strings.HasPrefix(version, "v") {
5144
version = "v" + version
5245
}
5346

54-
if semver.IsValid(version) {
55-
return semver.Compare(version, "v2.0") > 0 // version >= v2.0
56-
}
57-
58-
return true
47+
return semver.IsValid(version) && semver.Compare(version, minVersion) >= 0
5948
}
6049

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

103-
if isLegacyMode(localStackReq.Image) {
92+
if !isMinimumVersion(localStackReq.Image, "v0.11") {
10493
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)
10594
}
10695

10796
envVar := hostnameExternalEnvVar
108-
if isVersion2(localStackReq.Image) {
97+
if isMinimumVersion(localStackReq.Image, "v2") {
10998
envVar = localstackHostEnvVar
11099
}
111100

modules/localstack/localstack_test.go

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,24 +82,77 @@ func TestConfigureDockerHost(t *testing.T) {
8282
}
8383
}
8484

85-
func TestIsLegacyMode(t *testing.T) {
85+
func TestIsLegacyVersion(t *testing.T) {
8686
tests := []struct {
8787
version string
8888
want bool
8989
}{
9090
{"foo", true},
9191
{"latest", false},
92+
{"latest-amd64", false},
93+
{"s3-latest", false},
94+
{"s3-latest-amd64", false},
95+
{"stable", false},
96+
{"stable-amd64", false},
9297
{"0.10.0", true},
98+
{"0.10.0-amd64", true},
9399
{"0.10.999", true},
100+
{"0.10.999-amd64", true},
94101
{"0.11", false},
102+
{"0.11-amd64", false},
95103
{"0.11.2", false},
104+
{"0.11.2-amd64", false},
96105
{"0.12", false},
106+
{"0.12-amd64", false},
107+
{"1", false},
108+
{"1-amd64", false},
97109
{"1.0", false},
110+
{"1.0-amd64", false},
98111
}
99112

100113
for _, tt := range tests {
101114
t.Run(tt.version, func(t *testing.T) {
102-
got := isLegacyMode("localstack/localstack:" + tt.version)
115+
got := !isMinimumVersion("localstack/localstack:"+tt.version, "v0.11")
116+
require.Equal(t, tt.want, got, "runInLegacyMode() = %v, want %v", got, tt.want)
117+
})
118+
}
119+
}
120+
121+
func TestIsMinimumVersion2(t *testing.T) {
122+
tests := []struct {
123+
version string
124+
want bool
125+
}{
126+
{"foo", false},
127+
{"latest", true},
128+
{"latest-amd64", true},
129+
{"s3-latest", true},
130+
{"s3-latest-amd64", true},
131+
{"stable", true},
132+
{"stable-amd64", true},
133+
{"1", false},
134+
{"1-amd64", false},
135+
{"1.12", false},
136+
{"1.12-amd64", false},
137+
{"1.12.2", false},
138+
{"1.12.2-amd64", false},
139+
{"2", true},
140+
{"2-amd64", true},
141+
{"2.0", true},
142+
{"2.0-amd64", true},
143+
{"2.0.0", true},
144+
{"2.0.0-amd64", true},
145+
{"2.0.1", true},
146+
{"2.0.1-amd64", true},
147+
{"2.1", true},
148+
{"2.1-amd64", true},
149+
{"3", true},
150+
{"3-amd64", true},
151+
}
152+
153+
for _, tt := range tests {
154+
t.Run(tt.version, func(t *testing.T) {
155+
got := isMinimumVersion("localstack/localstack:"+tt.version, "v2")
103156
require.Equal(t, tt.want, got, "runInLegacyMode() = %v, want %v", got, tt.want)
104157
})
105158
}

0 commit comments

Comments
 (0)