Skip to content

Commit 3908ca8

Browse files
committed
MGMT-24397: Add OCP test version builder & PoC
Add TestVersionBuilder for resolving test versions from data files instead of hardcoding them. These helpers let tests reference versions dynamically so they adapt when data files change via make generate.
1 parent babc11d commit 3908ca8

7 files changed

Lines changed: 210 additions & 30 deletions

File tree

hack/Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ generate-events:
3838
validate-swagger-file:
3939
./hack/generate.sh validate_swagger_file
4040

41+
generate-test-versions:
42+
./hack/generate.sh generate_test_versions
43+
4144
generate-configuration:
4245
./hack/generate.sh generate_configuration
4346

@@ -61,4 +64,4 @@ generate-go:
6164
# because the latter copies around files that need to be generated by the
6265
# former. Without doing it in this order, the `generate` target will not be
6366
# idempotent and would have to be executed twice to achieve the desired result.
64-
generate: generate-from-swagger generate-go generate-events generate-mocks generate-configuration generate-bundle
67+
generate: generate-from-swagger generate-go generate-events generate-mocks generate-configuration generate-test-versions generate-bundle

hack/generate.sh

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,44 @@ function generate_bundle() {
125125
operator-sdk bundle validate ${BUNDLE_OUTPUT_DIR}
126126
}
127127

128+
function generate_test_versions() {
129+
local data_file="${__root}/data/default_release_images.json"
130+
local output_file="${__root}/internal/common/test_versions_generated.go"
131+
132+
python3 -c '
133+
import json, re
134+
from collections import defaultdict
135+
136+
with open("'"${data_file}"'") as f:
137+
data = json.load(f)
138+
139+
arch_versions = defaultdict(set)
140+
for entry in data:
141+
version = re.sub(r"-multi$", "", entry["openshift_version"])
142+
parts = version.split(".")
143+
version = "%s.%s" % (parts[0], parts[1])
144+
arch_versions[entry["cpu_architecture"]].add(version)
145+
146+
def sort_key(v):
147+
return tuple(int(p) for p in v.split(".") if p.isdigit())
148+
149+
lines = []
150+
for arch in sorted(arch_versions):
151+
versions = sorted(arch_versions[arch], key=sort_key)
152+
quoted = ", ".join("\"%s\"" % v for v in versions)
153+
lines.append("\t\"%s\": {%s}," % (arch, quoted))
154+
155+
print("""// Code generated by hack/generate.sh generate_test_versions; DO NOT EDIT.
156+
package common
157+
158+
var testVersionsByArch = map[string][]string{
159+
%s
160+
}""" % "\n".join(lines))
161+
' > "$output_file"
162+
163+
gofmt -w "$output_file"
164+
}
165+
128166
function print_help() {
129167
echo "The available functions are:"
130168
compgen -A function | grep "^generate" | awk '{print "\t" $1}'

internal/common/test_configuration.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,14 @@ const TestDiskPath = "/dev/test-disk"
5252
const MinimalVersionForNmstatectl = "4.18"
5353

5454
var (
55-
OpenShiftVersion string = "4.6"
56-
ReleaseVersion = "4.6.0"
57-
ReleaseImageURL = "quay.io/openshift-release-dev/ocp-release:4.6.16-x86_64"
58-
RhcosImage = "rhcos_4.6.0"
59-
RhcosVersion = "version-46.123-0"
60-
SupportLevel = "beta"
61-
CPUArchitecture = DefaultCPUArchitecture
55+
DefaultTestVersion = TestVersion().Latest()
56+
OpenShiftVersion = DefaultTestVersion.Version()
57+
ReleaseVersion = DefaultTestVersion.ReleaseVersion()
58+
ReleaseImageURL = DefaultTestVersion.ReleaseImageURL()
59+
RhcosImage = "rhcos_" + DefaultTestVersion.Version() + ".0"
60+
RhcosVersion = "version-46.123-0"
61+
SupportLevel = "beta"
62+
CPUArchitecture = DefaultCPUArchitecture
6263
)
6364

6465
// Defaults to be used by all testing modules

internal/common/test_versions.go

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package common
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/hashicorp/go-version"
7+
)
8+
9+
type TestVersionBuilder struct {
10+
arch string
11+
oldest bool
12+
constraint func(string) bool
13+
}
14+
15+
func TestVersion() *TestVersionBuilder {
16+
return &TestVersionBuilder{arch: DefaultCPUArchitecture}
17+
}
18+
19+
func (b *TestVersionBuilder) ForArch(arch string) *TestVersionBuilder {
20+
b.arch = arch
21+
return b
22+
}
23+
24+
func (b *TestVersionBuilder) Latest() *TestVersionBuilder {
25+
b.oldest = false
26+
return b
27+
}
28+
29+
func (b *TestVersionBuilder) Oldest() *TestVersionBuilder {
30+
b.oldest = true
31+
return b
32+
}
33+
34+
func (b *TestVersionBuilder) LessThan(threshold string) *TestVersionBuilder {
35+
parsed := b.parseVersion(threshold)
36+
b.constraint = func(v string) bool {
37+
return b.parseVersion(v).LessThan(parsed)
38+
}
39+
return b
40+
}
41+
42+
func (b *TestVersionBuilder) GreaterThan(threshold string) *TestVersionBuilder {
43+
parsed := b.parseVersion(threshold)
44+
b.constraint = func(v string) bool {
45+
return b.parseVersion(v).GreaterThan(parsed)
46+
}
47+
return b
48+
}
49+
50+
func (b *TestVersionBuilder) Exact(target string) *TestVersionBuilder {
51+
parsed := b.parseVersion(target)
52+
b.constraint = func(v string) bool {
53+
return b.parseVersion(v).Equal(parsed)
54+
}
55+
return b
56+
}
57+
58+
func (b *TestVersionBuilder) TryVersion() (string, bool) {
59+
v := b.versions()
60+
if len(v) == 0 {
61+
return "", false
62+
}
63+
if b.oldest {
64+
return v[0], true
65+
}
66+
return v[len(v)-1], true
67+
}
68+
69+
func (b *TestVersionBuilder) Version() string {
70+
v, ok := b.TryVersion()
71+
if !ok {
72+
panic(fmt.Sprintf("no test version found for arch %q with active constraint", b.arch))
73+
}
74+
return v
75+
}
76+
77+
func (b *TestVersionBuilder) ReleaseVersion() string {
78+
return b.Version() + ".0"
79+
}
80+
81+
// Mirrors getReleaseImageReference in internal/releasesources/release_sources.go
82+
func (b *TestVersionBuilder) ReleaseImageURL() string {
83+
suffix := b.arch
84+
if suffix == ARM64CPUArchitecture {
85+
suffix = AARCH64CPUArchitecture
86+
}
87+
return fmt.Sprintf("quay.io/openshift-release-dev/ocp-release:%s-%s", b.ReleaseVersion(), suffix)
88+
}
89+
90+
func (b *TestVersionBuilder) versions() []string {
91+
all, ok := testVersionsByArch[b.arch]
92+
if !ok {
93+
return []string{}
94+
}
95+
if b.constraint == nil || len(all) == 0 {
96+
return all
97+
}
98+
var filtered []string
99+
for _, v := range all {
100+
if b.constraint(v) {
101+
filtered = append(filtered, v)
102+
}
103+
}
104+
return filtered
105+
}
106+
107+
func (b *TestVersionBuilder) parseVersion(v string) *version.Version {
108+
parsed, err := version.NewVersion(v)
109+
if err != nil {
110+
panic(fmt.Sprintf("invalid version %q: %v", v, err))
111+
}
112+
return parsed
113+
}

internal/common/test_versions_generated.go

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/releasesources/release_sources_test.go

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package releasesources
22

33
import (
4+
"fmt"
45
"testing"
56

67
"github.com/go-openapi/swag"
@@ -212,7 +213,7 @@ var _ = Describe("SyncReleaseImages", func() {
212213
It("Should cause an error with invalid release sources - invalid cpu architecture", func() {
213214
releaseSources := models.ReleaseSources{
214215
{
215-
OpenshiftVersion: swag.String("4.12"),
216+
OpenshiftVersion: swag.String(common.TestVersion().Version()),
216217
MultiCPUArchitectures: testSupportedMultiArchitectures,
217218
UpgradeChannels: []*models.UpgradeChannel{
218219
{
@@ -262,7 +263,7 @@ var _ = Describe("SyncReleaseImages", func() {
262263
It("Should cause an error with invalid release sources - invalid channel", func() {
263264
releaseSources := models.ReleaseSources{
264265
{
265-
OpenshiftVersion: swag.String("4.12"),
266+
OpenshiftVersion: swag.String(common.TestVersion().Version()),
266267
MultiCPUArchitectures: testSupportedMultiArchitectures,
267268
UpgradeChannels: []*models.UpgradeChannel{
268269
{
@@ -287,7 +288,7 @@ var _ = Describe("SyncReleaseImages", func() {
287288
It("Should cause an error with invalid release sources - invalid multi_cpu_architectures", func() {
288289
releaseSources := models.ReleaseSources{
289290
{
290-
OpenshiftVersion: swag.String("4.12"),
291+
OpenshiftVersion: swag.String(common.TestVersion().Version()),
291292
MultiCPUArchitectures: []string{"invalid arch"},
292293
UpgradeChannels: []*models.UpgradeChannel{
293294
{
@@ -398,7 +399,7 @@ var _ = Describe("SyncReleaseImages", func() {
398399
It("Should cause an error with invalid release sources - missing multi_cpu_architectures", func() {
399400
releaseSources := models.ReleaseSources{
400401
{
401-
OpenshiftVersion: swag.String("4.12"),
402+
OpenshiftVersion: swag.String(common.TestVersion().Version()),
402403
UpgradeChannels: []*models.UpgradeChannel{
403404
{
404405
CPUArchitecture: swag.String(common.X86CPUArchitecture),
@@ -422,7 +423,7 @@ var _ = Describe("SyncReleaseImages", func() {
422423
It("Should cause an error with invalid release sources - missing upgrade_channels", func() {
423424
releaseSources := models.ReleaseSources{
424425
{
425-
OpenshiftVersion: swag.String("4.12"),
426+
OpenshiftVersion: swag.String(common.TestVersion().Version()),
426427
MultiCPUArchitectures: testSupportedMultiArchitectures,
427428
},
428429
}
@@ -441,7 +442,7 @@ var _ = Describe("SyncReleaseImages", func() {
441442
It("Should cause an error with invalid release sources - missing cpu_architecture", func() {
442443
releaseSources := models.ReleaseSources{
443444
{
444-
OpenshiftVersion: swag.String("4.12"),
445+
OpenshiftVersion: swag.String(common.TestVersion().Version()),
445446
MultiCPUArchitectures: testSupportedMultiArchitectures,
446447
UpgradeChannels: []*models.UpgradeChannel{
447448
{
@@ -464,7 +465,7 @@ var _ = Describe("SyncReleaseImages", func() {
464465
It("Should cause an error with invalid release sources - missing channels", func() {
465466
releaseSources := models.ReleaseSources{
466467
{
467-
OpenshiftVersion: swag.String("4.12"),
468+
OpenshiftVersion: swag.String(common.TestVersion().Version()),
468469
MultiCPUArchitectures: testSupportedMultiArchitectures,
469470
UpgradeChannels: []*models.UpgradeChannel{
470471
{
@@ -560,11 +561,15 @@ var _ = Describe("SyncReleaseImages", func() {
560561
})
561562

562563
It("Should cause an error with missing required fields", func() {
564+
testVersion := common.TestVersion().Version()
565+
testFullVersion := testVersion + ".1"
566+
testURL := fmt.Sprintf("quay.io/openshift-release-dev/ocp-release:%s-x86_64", testFullVersion)
567+
563568
releaseImages := models.ReleaseImages{
564569
{
565-
Version: swag.String("4.11.1"),
570+
Version: swag.String(testFullVersion),
566571
CPUArchitecture: swag.String(common.X86CPUArchitecture),
567-
URL: swag.String("quay.io/openshift-release-dev/ocp-release:4.11.1-x86_64"),
572+
URL: swag.String(testURL),
568573
},
569574
}
570575
handler, err = newReleaseSourcesHandler(
@@ -579,9 +584,9 @@ var _ = Describe("SyncReleaseImages", func() {
579584

580585
releaseImages = models.ReleaseImages{
581586
{
582-
OpenshiftVersion: swag.String("4.11"),
587+
OpenshiftVersion: swag.String(testVersion),
583588
CPUArchitecture: swag.String(common.X86CPUArchitecture),
584-
URL: swag.String("quay.io/openshift-release-dev/ocp-release:4.11.1-x86_64"),
589+
URL: swag.String(testURL),
585590
},
586591
}
587592

@@ -597,9 +602,9 @@ var _ = Describe("SyncReleaseImages", func() {
597602

598603
releaseImages = models.ReleaseImages{
599604
{
600-
OpenshiftVersion: swag.String("4.11"),
601-
Version: swag.String("4.11.1"),
602-
URL: swag.String("quay.io/openshift-release-dev/ocp-release:4.11.1-x86_64"),
605+
OpenshiftVersion: swag.String(testVersion),
606+
Version: swag.String(testFullVersion),
607+
URL: swag.String(testURL),
603608
},
604609
}
605610

@@ -615,8 +620,8 @@ var _ = Describe("SyncReleaseImages", func() {
615620

616621
releaseImages = models.ReleaseImages{
617622
{
618-
OpenshiftVersion: swag.String("4.11"),
619-
Version: swag.String("4.11.1"),
623+
OpenshiftVersion: swag.String(testVersion),
624+
Version: swag.String(testFullVersion),
620625
CPUArchitecture: swag.String(common.X86CPUArchitecture),
621626
},
622627
}
@@ -663,12 +668,16 @@ var _ = Describe("SyncReleaseImages", func() {
663668
})
664669

665670
It("Should cause an error with invalid fields", func() {
671+
testVersion := common.TestVersion().Version()
672+
testFullVersion := testVersion + ".1"
673+
testURL := fmt.Sprintf("quay.io/openshift-release-dev/ocp-release:%s-x86_64", testFullVersion)
674+
666675
releaseImages := models.ReleaseImages{
667676
{
668-
OpenshiftVersion: swag.String("4.11"),
669-
Version: swag.String("4.11.1"),
677+
OpenshiftVersion: swag.String(testVersion),
678+
Version: swag.String(testFullVersion),
670679
CPUArchitecture: swag.String("invalidCPUArch"),
671-
URL: swag.String("quay.io/openshift-release-dev/ocp-release:4.11.1-x86_64"),
680+
URL: swag.String(testURL),
672681
},
673682
}
674683

subsystem/cluster_test.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,14 @@ var _ = Describe("Cluster with Platform", func() {
7474

7575
Context("vSphere", func() {
7676
It("vSphere cluster on OCP 4.13 - Success", func() {
77+
openShiftVersion, ok := common.TestVersion().Exact("4.13").TryVersion()
78+
if !ok {
79+
Skip("4.13 not available")
80+
}
7781
cluster, err := utils_test.TestContext.UserBMClient.Installer.V2RegisterCluster(ctx, &installer.V2RegisterClusterParams{
7882
NewClusterParams: &models.ClusterCreateParams{
7983
Name: swag.String("test-cluster"),
80-
OpenshiftVersion: swag.String("4.13"),
84+
OpenshiftVersion: swag.String(openShiftVersion),
8185
ControlPlaneCount: swag.Int64(common.MinMasterHostsNeededForInstallationInHaMode),
8286
PullSecret: swag.String(pullSecret),
8387
Platform: &models.Platform{Type: common.PlatformTypePtr(models.PlatformTypeVsphere)},
@@ -87,11 +91,15 @@ var _ = Describe("Cluster with Platform", func() {
8791
Expect(*cluster.GetPayload().Platform.Type).Should(Equal(models.PlatformTypeVsphere))
8892
})
8993

90-
It("vSphere cluster on OCP 4.13 with dual stack - Succeess", func() {
94+
It("vSphere cluster on OCP 4.13 with dual stack - Success", func() {
95+
openShiftVersion, ok := common.TestVersion().Exact("4.13").TryVersion()
96+
if !ok {
97+
Skip("4.13 not available")
98+
}
9199
_, err := utils_test.TestContext.UserBMClient.Installer.V2RegisterCluster(ctx, &installer.V2RegisterClusterParams{
92100
NewClusterParams: &models.ClusterCreateParams{
93101
Name: swag.String("test-cluster"),
94-
OpenshiftVersion: swag.String("4.13"),
102+
OpenshiftVersion: swag.String(openShiftVersion),
95103
ControlPlaneCount: swag.Int64(common.MinMasterHostsNeededForInstallationInHaMode),
96104
PullSecret: swag.String(pullSecret),
97105
Platform: &models.Platform{Type: common.PlatformTypePtr(models.PlatformTypeVsphere)},

0 commit comments

Comments
 (0)