Skip to content

Commit d4f0a13

Browse files
fix: skip healthcheck when nerdctl < 2.2.1
Signed-off-by: Swapnanil Gupta <swpnlg@amazon.com>
1 parent c9b3409 commit d4f0a13

File tree

5 files changed

+96
-1
lines changed

5 files changed

+96
-1
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ require (
88
)
99

1010
require (
11-
github.com/Masterminds/semver/v3 v3.3.1 // indirect
11+
github.com/Masterminds/semver/v3 v3.4.0 // indirect
1212
github.com/go-logr/logr v1.4.3 // indirect
1313
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
1414
github.com/google/go-cmp v0.7.0 // indirect

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
github.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4=
22
github.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
3+
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
4+
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
35
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
46
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
57
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=

option/option.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"fmt"
1010
"os"
1111
"os/exec"
12+
"regexp"
1213
"strings"
1314
)
1415

@@ -19,6 +20,11 @@ const (
1920
nerdctlVersion feature = iota
2021
)
2122

23+
var (
24+
nerdctlVersionRegex = regexp.MustCompile(`nerdctl\s+version\s+(\S+)`)
25+
finchNerdctlVersionRegex = regexp.MustCompile(`nerdctl:\s+Version:\s+(\S+)`)
26+
)
27+
2228
// Option customizes how tests are run.
2329
//
2430
// If a testing function needs special customizations other than the ones specified in Option,
@@ -127,3 +133,46 @@ func (o *Option) isNerdctlVersion(cmp func(string) bool) bool {
127133

128134
return cmp(version)
129135
}
136+
137+
// Subject returns the subject stored in the option.
138+
func (o *Option) Subject() []string {
139+
return o.subject
140+
}
141+
142+
// GetNerdctlVersion gets the nerdctl version from the subject. If the subject is neither "nerdctl" nor "finch", it will return an error.
143+
func (o *Option) GetNerdctlVersion() (string, error) {
144+
switch o.subject[0] {
145+
case "nerdctl":
146+
//nolint:gosec // G204 is not an issue because subject is fully controlled by the user.
147+
versionBytes, err := exec.Command(o.subject[0], "--version").Output()
148+
if err != nil {
149+
return "", fmt.Errorf("failed to run nerdctl --version: %w", err)
150+
}
151+
version, err := getNerdctlVersionMatch(nerdctlVersionRegex, string(versionBytes))
152+
if err != nil {
153+
return "", err
154+
}
155+
return version, nil
156+
case "finch":
157+
//nolint:gosec // G204 is not an issue because subject is fully controlled by the user.
158+
versionBytes, err := exec.Command(o.subject[0], "version").Output()
159+
if err != nil {
160+
return "", fmt.Errorf("failed to run nerdctl --version: %w", err)
161+
}
162+
version, err := getNerdctlVersionMatch(finchNerdctlVersionRegex, string(versionBytes))
163+
if err != nil {
164+
return "", err
165+
}
166+
return version, nil
167+
default:
168+
return "", fmt.Errorf("unsupported subject %s", o.subject[0])
169+
}
170+
}
171+
172+
func getNerdctlVersionMatch(nerdctlVersionRegexp *regexp.Regexp, versionOutput string) (string, error) {
173+
matches := nerdctlVersionRegexp.FindStringSubmatch(versionOutput)
174+
if len(matches) < 2 {
175+
return "", fmt.Errorf("failed to parse nerdctl version from: %s", versionOutput)
176+
}
177+
return matches[1], nil
178+
}

tests/health_check.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"github.com/runfinch/common-tests/command"
1616
"github.com/runfinch/common-tests/ffs"
1717
"github.com/runfinch/common-tests/option"
18+
"github.com/runfinch/common-tests/util"
1819
)
1920

2021
type testCase struct {
@@ -79,6 +80,9 @@ func HealthCheck(o *option.Option) {
7980

8081
func testCliHealthCheckFlags(o *option.Option) {
8182
ginkgo.Describe("test container healthcheck flags", func() {
83+
ginkgo.BeforeEach(func() {
84+
util.RequireNerdctlVersion(o, ">= 2.2.1")
85+
})
8286
ginkgo.BeforeEach(func() {
8387
command.RemoveAll(o)
8488
})
@@ -162,6 +166,9 @@ func testImageHealthCheckFlags(o *option.Option) {
162166
ginkgo.Describe("test image healthcheck flags", func() {
163167
var buildContext string
164168

169+
ginkgo.BeforeEach(func() {
170+
util.RequireNerdctlVersion(o, ">= 2.2.1")
171+
})
165172
ginkgo.BeforeEach(func() {
166173
buildContext = ffs.CreateBuildContext(fmt.Sprintf(`FROM %s
167174
HEALTHCHECK --interval=30s --timeout=10s CMD wget -q http://localhost:8080 || exit 1
@@ -229,6 +236,9 @@ func testImageHealthCheckFlags(o *option.Option) {
229236

230237
func testHealthCheckStatus(o *option.Option) {
231238
ginkgo.Describe("test automated container healthcheck status", func() {
239+
ginkgo.BeforeEach(func() {
240+
util.RequireNerdctlVersion(o, ">= 2.2.1")
241+
})
232242
ginkgo.BeforeEach(func() {
233243
command.RemoveAll(o)
234244
})
@@ -411,6 +421,9 @@ func testHealthCheckStatus(o *option.Option) {
411421

412422
func testHealthCheckStatusNegativeCases(o *option.Option) {
413423
ginkgo.Describe("test manual container healthcheck status", func() {
424+
ginkgo.BeforeEach(func() {
425+
util.RequireNerdctlVersion(o, ">= 2.2.1")
426+
})
414427
ginkgo.BeforeEach(func() {
415428
command.RemoveAll(o)
416429
})

util/version.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package util
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/Masterminds/semver/v3"
7+
"github.com/onsi/ginkgo/v2"
8+
"github.com/runfinch/common-tests/option"
9+
)
10+
11+
// RequireNerdctlVersion skips a test if the nerdctl version does not satisfy the constraint.
12+
func RequireNerdctlVersion(o *option.Option, constraint string) {
13+
c, err := semver.NewConstraint(constraint)
14+
if err != nil {
15+
ginkgo.Fail(fmt.Sprintf("failed to construct constraint from %s: %s", constraint, err.Error()))
16+
return
17+
}
18+
nerdctlVersion, err := o.GetNerdctlVersion()
19+
if err != nil {
20+
ginkgo.Fail(fmt.Sprintf("failed to get nerdctl version: %s", err.Error()))
21+
return
22+
}
23+
v, err := semver.NewVersion(nerdctlVersion)
24+
if err != nil {
25+
ginkgo.Fail(fmt.Sprintf("failed to construct semver from %s: %s", nerdctlVersion, err.Error()))
26+
return
27+
}
28+
if !c.Check(v) {
29+
ginkgo.Skip(fmt.Sprintf("nerdctl version %s does not satisfy constraint %s", v, constraint))
30+
}
31+
}

0 commit comments

Comments
 (0)