Skip to content

Commit 4f025c4

Browse files
fix(tests): skip upgrade tests if not upgrading between two consecutive Kong versions (#5327) (#5365)
(cherry picked from commit 614c6c0) Co-authored-by: Grzegorz Burzyński <czeslavo@gmail.com>
1 parent 622c990 commit 4f025c4

File tree

3 files changed

+97
-2
lines changed

3 files changed

+97
-2
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ require (
100100
github.com/chai2010/gettext-go v1.0.2 // indirect
101101
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
102102
github.com/docker/distribution v2.8.2+incompatible // indirect
103-
github.com/docker/docker v24.0.6+incompatible // indirect
103+
github.com/docker/docker v24.0.6+incompatible
104104
github.com/docker/go-connections v0.4.0 // indirect
105105
github.com/docker/go-units v0.5.0 // indirect
106106
github.com/emicklei/go-restful/v3 v3.10.2 // indirect

test/e2e/upgrade_test.go

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,14 @@ package e2e
55
import (
66
"context"
77
"fmt"
8+
"os"
9+
"regexp"
10+
"strings"
811
"testing"
12+
"time"
913

14+
"github.com/docker/docker/api/types"
15+
"github.com/docker/docker/client"
1016
"github.com/kong/go-kong/kong"
1117
"github.com/kong/kubernetes-testing-framework/pkg/environments"
1218
"github.com/samber/lo"
@@ -15,6 +21,7 @@ import (
1521
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1622

1723
"github.com/kong/kubernetes-ingress-controller/v2/test/internal/helpers"
24+
"github.com/kong/kubernetes-ingress-controller/v2/test/internal/testenv"
1825
)
1926

2027
const (
@@ -103,12 +110,14 @@ func testManifestsUpgrade(
103110
oldManifest, err := httpClient.Get(testParams.fromManifestURL)
104111
require.NoError(t, err)
105112
defer oldManifest.Body.Close()
113+
oldManifestPath := dumpToTempFile(t, oldManifest.Body)
114+
115+
skipIfNotTwoConsecutiveKongMinorVersions(t, oldManifestPath, testParams.toManifestPath)
106116

107117
t.Log("configuring upgrade manifests test")
108118
ctx, env := setupE2ETest(t)
109119

110120
t.Logf("deploying previous kong manifests: %s", testParams.fromManifestURL)
111-
oldManifestPath := dumpToTempFile(t, oldManifest.Body)
112121
ManifestDeploy{
113122
Path: oldManifestPath,
114123
SkipTestPatches: true,
@@ -154,3 +163,80 @@ func testManifestsUpgrade(
154163

155164
verifyIngressWithEchoBackendsPath(ctx, t, env, numberOfEchoBackends, newPath)
156165
}
166+
167+
// skipIfNotTwoConsecutiveKongMinorVersions skips the test if the old and new Kong versions are not two consecutive
168+
// minor versions. This is necessary because Kong in DB-mode doesn't support skipping minor versions when upgrading.
169+
// See the Gateway upgrade guide for details: https://docs.konghq.com/gateway/latest/upgrade/.
170+
func skipIfNotTwoConsecutiveKongMinorVersions(
171+
t *testing.T,
172+
oldManifestPath string,
173+
newManifestPath string,
174+
) {
175+
oldKongVersion := extractKongVersionFromManifest(t, oldManifestPath)
176+
177+
var newKongVersion kong.Version
178+
if targetKongImage := testenv.KongImageTag(); targetKongImage != "" {
179+
// If the target Kong image is specified via environment variable, use it...
180+
newKongVersion = extractKongVersionFromDockerImage(t, targetKongImage)
181+
} else {
182+
// ...otherwise, use the version used in the new manifest.
183+
newKongVersion = extractKongVersionFromManifest(t, newManifestPath)
184+
}
185+
186+
if oldKongVersion.Major() != newKongVersion.Major() ||
187+
oldKongVersion.Minor()+1 != newKongVersion.Minor() {
188+
t.Skipf("skipping upgrade test because the old and new Kong versions are not two consecutive minor versions: %s and %s",
189+
oldKongVersion, newKongVersion)
190+
}
191+
}
192+
193+
var kongVersionRegex = regexp.MustCompile(`image: (kong:.*)`)
194+
195+
// extractKongVersionFromManifest extracts the Kong version from the manifest.
196+
func extractKongVersionFromManifest(t *testing.T, manifestPath string) kong.Version {
197+
manifest, err := os.ReadFile(manifestPath)
198+
require.NoError(t, err)
199+
200+
res := kongVersionRegex.FindStringSubmatch(string(manifest))
201+
require.NotEmpty(t, res)
202+
203+
version := res[1]
204+
return extractKongVersionFromDockerImage(t, version)
205+
}
206+
207+
// extractKongVersionFromDockerImage extracts the Kong version from the docker image by inspecting the image's env vars
208+
// for the KONG_VERSION env var.
209+
func extractKongVersionFromDockerImage(t *testing.T, image string) kong.Version {
210+
dockerc, err := client.NewClientWithOpts(client.FromEnv)
211+
require.NoError(t, err)
212+
213+
ctx := context.Background()
214+
215+
t.Logf("pulling docker image %s to inspect it", image)
216+
_, err = dockerc.ImagePull(ctx, image, types.ImagePullOptions{})
217+
require.NoError(t, err)
218+
219+
t.Logf("inspecting docker image %s", image)
220+
var imageDetails types.ImageInspect
221+
// Retry because the image may not be available immediately after pulling it.
222+
require.Eventually(t, func() bool {
223+
var err error
224+
imageDetails, _, err = dockerc.ImageInspectWithRaw(ctx, image)
225+
if err != nil {
226+
t.Logf("failed to inspect docker image %s: %s", image, err)
227+
return false
228+
}
229+
return true
230+
}, time.Minute, time.Second)
231+
232+
kongVersionEnv, ok := lo.Find(imageDetails.Config.Env, func(s string) bool {
233+
return strings.HasPrefix(s, "KONG_VERSION=")
234+
})
235+
require.True(t, ok, "KONG_VERSION env var not found in image %s", image)
236+
237+
version, err := kong.ParseSemanticVersion(strings.TrimPrefix(kongVersionEnv, "KONG_VERSION="))
238+
require.NoError(t, err)
239+
t.Logf("parsed Kong version %s from docker image %s", version, image)
240+
241+
return version
242+
}

test/internal/testenv/testenv.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package testenv
22

33
import (
4+
"fmt"
45
"os"
56
"time"
67
)
@@ -40,6 +41,14 @@ func KongTag() string {
4041
return os.Getenv("TEST_KONG_TAG")
4142
}
4243

44+
// KongImageTag is the combined Kong image and tag if both are set, or empty string if not.
45+
func KongImageTag() string {
46+
if KongImage() != "" && KongTag() != "" {
47+
return fmt.Sprintf("%s:%s", KongImage(), KongTag())
48+
}
49+
return ""
50+
}
51+
4352
// KongEffectiveVersion is the effective semver of kong gateway.
4453
// When testing against "nightly" image of kong gateway, we need to set the effective version for parsing semver in chart templates.
4554
func KongEffectiveVersion() string {

0 commit comments

Comments
 (0)