diff --git a/data/default_os_images.json b/data/default_os_images.json index 58b7c1a9e1da..9a94d093057a 100644 --- a/data/default_os_images.json +++ b/data/default_os_images.json @@ -281,4 +281,4 @@ "url": "https://mirror.openshift.com/pub/openshift-v4/s390x/dependencies/rhcos/pre-release/4.22.0-ec.5/rhcos-4.22.0-ec.5-s390x-live-iso.s390x.iso", "version": "9.6.20251023-0" } -] \ No newline at end of file +] diff --git a/data/default_release_images.json b/data/default_release_images.json index 54a3bf94b650..ec282e25533b 100644 --- a/data/default_release_images.json +++ b/data/default_release_images.json @@ -363,4 +363,4 @@ "support_level": "beta", "version": "5.0.0-ec.1-multi" } -] \ No newline at end of file +] diff --git a/hack/Makefile b/hack/Makefile index bb347cd47689..5298683f12cd 100644 --- a/hack/Makefile +++ b/hack/Makefile @@ -38,6 +38,9 @@ generate-events: validate-swagger-file: ./hack/generate.sh validate_swagger_file +generate-test-versions: + ./hack/generate.sh generate_test_versions + generate-configuration: ./hack/generate.sh generate_configuration @@ -61,4 +64,4 @@ generate-go: # because the latter copies around files that need to be generated by the # former. Without doing it in this order, the `generate` target will not be # idempotent and would have to be executed twice to achieve the desired result. -generate: generate-from-swagger generate-go generate-events generate-mocks generate-configuration generate-bundle +generate: generate-from-swagger generate-go generate-events generate-mocks generate-configuration generate-test-versions generate-bundle diff --git a/hack/generate.sh b/hack/generate.sh index c2550e677a18..ec46f2aff286 100755 --- a/hack/generate.sh +++ b/hack/generate.sh @@ -125,6 +125,44 @@ function generate_bundle() { operator-sdk bundle validate ${BUNDLE_OUTPUT_DIR} } +function generate_test_versions() { + local data_file="${__root}/data/default_release_images.json" + local output_file="${__root}/internal/common/test_versions_generated.go" + + python3 -c ' +import json, re +from collections import defaultdict + +with open("'"${data_file}"'") as f: + data = json.load(f) + +arch_versions = defaultdict(set) +for entry in data: + version = re.sub(r"-multi$", "", entry["openshift_version"]) + parts = version.split(".") + version = "%s.%s" % (parts[0], parts[1]) + arch_versions[entry["cpu_architecture"]].add(version) + +def sort_key(v): + return tuple(int(p) for p in v.split(".") if p.isdigit()) + +lines = [] +for arch in sorted(arch_versions): + versions = sorted(arch_versions[arch], key=sort_key) + quoted = ", ".join("\"%s\"" % v for v in versions) + lines.append("\t\"%s\": {%s}," % (arch, quoted)) + +print("""// Code generated by hack/generate.sh generate_test_versions; DO NOT EDIT. +package common + +var testVersionsByArch = map[string][]string{ +%s +}""" % "\n".join(lines)) +' > "$output_file" + + gofmt -w "$output_file" +} + function print_help() { echo "The available functions are:" compgen -A function | grep "^generate" | awk '{print "\t" $1}' diff --git a/internal/bminventory/inventory_test.go b/internal/bminventory/inventory_test.go index 2ddd3dc4ec80..4a1464c6d85b 100644 --- a/internal/bminventory/inventory_test.go +++ b/internal/bminventory/inventory_test.go @@ -5209,6 +5209,17 @@ var _ = Describe("cluster", func() { }) Context("Multiple VIPs forbidden in update for pre-4.12", func() { + var pre412Version string + + BeforeEach(func() { + v, ok := common.TestVersion().LessThan("4.12").Latest().TryVersion() + if !ok { + Skip("no test version available below 4.12") + } + pre412Version = v + Expect(db.Model(&common.Cluster{}).Where("id = ?", clusterID).Update("openshift_version", pre412Version).Error).ShouldNot(HaveOccurred()) + }) + It("2 APIVips and 2 IngressVips", func() { apiVip := "8.8.8.7" ingressVip := "8.8.8.1" @@ -5223,7 +5234,7 @@ var _ = Describe("cluster", func() { }, }) - verifyApiErrorString(reply, http.StatusBadRequest, "dual-stack VIPs are not supported in OpenShift 4.6") + verifyApiErrorString(reply, http.StatusBadRequest, "dual-stack VIPs are not supported in OpenShift "+pre412Version) }) It("2 APIVips and 1 IngressVips", func() { @@ -5240,7 +5251,7 @@ var _ = Describe("cluster", func() { }, }) - verifyApiErrorString(reply, http.StatusBadRequest, "dual-stack VIPs are not supported in OpenShift 4.6") + verifyApiErrorString(reply, http.StatusBadRequest, "dual-stack VIPs are not supported in OpenShift "+pre412Version) }) It("1 APIVip and 2 IngressVips", func() { @@ -5257,7 +5268,7 @@ var _ = Describe("cluster", func() { }, }) - verifyApiErrorString(reply, http.StatusBadRequest, "dual-stack VIPs are not supported in OpenShift 4.6") + verifyApiErrorString(reply, http.StatusBadRequest, "dual-stack VIPs are not supported in OpenShift "+pre412Version) }) }) }) @@ -5355,6 +5366,7 @@ var _ = Describe("cluster", func() { ID: &clusterID, APIVips: []*models.APIVip{{IP: "10.11.12.13"}}, IngressVips: []*models.IngressVip{{IP: "10.11.20.50"}}, + CPUArchitecture: common.DefaultCPUArchitecture, OpenshiftVersion: common.TestDefaultConfig.OpenShiftVersion, Status: swag.String(models.ClusterStatusReady), }} @@ -5363,6 +5375,7 @@ var _ = Describe("cluster", func() { ID: &clusterID, APIVips: []*models.APIVip{{IP: "10.11.12.13"}}, IngressVips: []*models.IngressVip{{IP: "10.11.20.50"}}, + CPUArchitecture: common.DefaultCPUArchitecture, OpenshiftVersion: common.TestDefaultConfig.OpenShiftVersion, Status: swag.String(models.ClusterStatusInstalling), }, @@ -15102,8 +15115,8 @@ var _ = Describe("RegisterCluster", func() { Expect(result.Platform.None).Should(BeNil()) Expect(result.Platform.Baremetal).Should(BeNil()) - Expect(result.Platform.Vsphere.DeprecatedAPIVIP).Should(Equal(apiVip)) - Expect(result.Platform.Vsphere.DeprecatedIngressVIP).Should(Equal(ingressVip)) + Expect(result.Platform.Vsphere.APIVIPs).Should(ContainElement(apiVip)) + Expect(result.Platform.Vsphere.IngressVIPs).Should(ContainElement(ingressVip)) }) }) @@ -17815,6 +17828,7 @@ var _ = Describe("AMS subscriptions", func() { err := db.Create(&common.Cluster{Cluster: models.Cluster{ ID: &clusterID, OpenshiftVersion: common.TestDefaultConfig.OpenShiftVersion, + CPUArchitecture: common.DefaultCPUArchitecture, Status: swag.String(models.ClusterStatusReady), }}).Error Expect(err).ShouldNot(HaveOccurred()) diff --git a/internal/common/test_configuration.go b/internal/common/test_configuration.go index 776366653ba4..491c1d4e6908 100644 --- a/internal/common/test_configuration.go +++ b/internal/common/test_configuration.go @@ -52,13 +52,14 @@ const TestDiskPath = "/dev/test-disk" const MinimalVersionForNmstatectl = "4.18" var ( - OpenShiftVersion string = "4.6" - ReleaseVersion = "4.6.0" - ReleaseImageURL = "quay.io/openshift-release-dev/ocp-release:4.6.16-x86_64" - RhcosImage = "rhcos_4.6.0" - RhcosVersion = "version-46.123-0" - SupportLevel = "beta" - CPUArchitecture = DefaultCPUArchitecture + DefaultTestVersion = TestVersion().Latest() + OpenShiftVersion = DefaultTestVersion.Version() + ReleaseVersion = DefaultTestVersion.ReleaseVersion() + ReleaseImageURL = DefaultTestVersion.ReleaseImageURL() + RhcosImage = DefaultTestVersion.RhcosImage() + RhcosVersion = DefaultTestVersion.RhcosVersion() + SupportLevel = "beta" + CPUArchitecture = DefaultCPUArchitecture ) // Defaults to be used by all testing modules diff --git a/internal/common/test_versions.go b/internal/common/test_versions.go new file mode 100644 index 000000000000..12df26c2c569 --- /dev/null +++ b/internal/common/test_versions.go @@ -0,0 +1,126 @@ +package common + +import ( + "fmt" + "strings" + + "github.com/hashicorp/go-version" +) + +type TestVersionBuilder struct { + arch string + oldest bool + constraint func(string) bool + versionsByArch map[string][]string +} + +func TestVersion() *TestVersionBuilder { + return &TestVersionBuilder{ + arch: DefaultCPUArchitecture, + versionsByArch: testVersionsByArch, + } +} + +func (b *TestVersionBuilder) ForArch(arch string) *TestVersionBuilder { + b.arch = arch + return b +} + +func (b *TestVersionBuilder) Latest() *TestVersionBuilder { + b.oldest = false + return b +} + +func (b *TestVersionBuilder) Oldest() *TestVersionBuilder { + b.oldest = true + return b +} + +func (b *TestVersionBuilder) LessThan(threshold string) *TestVersionBuilder { + parsed := b.parseVersion(threshold) + b.constraint = func(v string) bool { + return b.parseVersion(v).LessThan(parsed) + } + return b +} + +func (b *TestVersionBuilder) GreaterThan(threshold string) *TestVersionBuilder { + parsed := b.parseVersion(threshold) + b.constraint = func(v string) bool { + return b.parseVersion(v).GreaterThan(parsed) + } + return b +} + +func (b *TestVersionBuilder) Exact(target string) *TestVersionBuilder { + parsed := b.parseVersion(target) + b.constraint = func(v string) bool { + return b.parseVersion(v).Equal(parsed) + } + return b +} + +func (b *TestVersionBuilder) TryVersion() (string, bool) { + v := b.versions() + if len(v) == 0 { + return "", false + } + if b.oldest { + return v[0], true + } + return v[len(v)-1], true +} + +func (b *TestVersionBuilder) Version() string { + v, ok := b.TryVersion() + if !ok { + panic(fmt.Sprintf("no test version found for arch %q with active constraint", b.arch)) + } + return v +} + +func (b *TestVersionBuilder) ReleaseVersion() string { + return b.Version() + ".0" +} + +// Mirrors getReleaseImageReference in internal/releasesources/release_sources.go +func (b *TestVersionBuilder) ReleaseImageURL() string { + suffix := b.arch + if suffix == ARM64CPUArchitecture { + suffix = AARCH64CPUArchitecture + } + return fmt.Sprintf("quay.io/openshift-release-dev/ocp-release:%s-%s", b.ReleaseVersion(), suffix) +} + +func (b *TestVersionBuilder) RhcosImage() string { + return fmt.Sprintf("rhcos_%s", b.ReleaseVersion()) +} + +func (b *TestVersionBuilder) RhcosVersion() string { + return fmt.Sprintf("version-%s.123-0", strings.ReplaceAll(b.Version(), ".", "")) +} + +func (b *TestVersionBuilder) versions() []string { + all, ok := testVersionsByArch[b.arch] + if !ok { + return []string{} + } + if b.constraint == nil || len(all) == 0 { + return all + } + var filtered []string + for _, v := range all { + if b.constraint(v) { + filtered = append(filtered, v) + } + } + return filtered +} + +func (b *TestVersionBuilder) parseVersion(v string) *version.Version { + parsed, err := version.NewVersion(v) + if err != nil { + panic(fmt.Sprintf("invalid version %q: %v", v, err)) + } + return parsed +} diff --git a/internal/common/test_versions_generated.go b/internal/common/test_versions_generated.go new file mode 100644 index 000000000000..4adc73a5cba9 --- /dev/null +++ b/internal/common/test_versions_generated.go @@ -0,0 +1,8 @@ +// Code generated by hack/generate.sh generate_test_versions; DO NOT EDIT. +package common + +var testVersionsByArch = map[string][]string{ + "arm64": {"4.10", "4.11", "4.13", "4.14", "4.16", "4.17", "4.18", "4.19", "4.20", "4.21", "4.22", "5.0"}, + "multi": {"4.11", "4.13", "4.14", "4.16", "4.17", "4.18", "4.19", "4.20", "4.21", "4.22", "5.0"}, + "x86_64": {"4.9", "4.10", "4.11", "4.13", "4.14", "4.16", "4.17", "4.18", "4.19", "4.20", "4.21", "4.22", "5.0"}, +} diff --git a/internal/common/test_versions_test.go b/internal/common/test_versions_test.go new file mode 100644 index 000000000000..cb5afe3ef91c --- /dev/null +++ b/internal/common/test_versions_test.go @@ -0,0 +1,331 @@ +package common + +import ( + . "github.com/onsi/ginkgo" + . "github.com/onsi/ginkgo/extensions/table" + . "github.com/onsi/gomega" +) + +func withVersions(versions map[string][]string, fn func()) { + original := testVersionsByArch + testVersionsByArch = versions + defer func() { testVersionsByArch = original }() + fn() +} + +var _ = Describe("TestVersionBuilder", func() { + Describe("Version selection with defaults", func() { + It("returns the latest x86_64 version by default", func() { + withVersions(map[string][]string{ + X86CPUArchitecture: {"4.14", "4.15", "4.16"}, + }, func() { + Expect(TestVersion().Version()).To(Equal("4.16")) + }) + }) + + It("returns the oldest version when Oldest is called", func() { + withVersions(map[string][]string{ + X86CPUArchitecture: {"4.14", "4.15", "4.16"}, + }, func() { + Expect(TestVersion().Oldest().Version()).To(Equal("4.14")) + }) + }) + + It("returns the latest version when Latest is called after Oldest", func() { + withVersions(map[string][]string{ + X86CPUArchitecture: {"4.14", "4.15", "4.16"}, + }, func() { + Expect(TestVersion().Oldest().Latest().Version()).To(Equal("4.16")) + }) + }) + }) + + Describe("Architecture selection", func() { + It("selects versions for the requested architecture", func() { + withVersions(map[string][]string{ + X86CPUArchitecture: {"4.14", "4.15"}, + ARM64CPUArchitecture: {"4.16", "4.17"}, + }, func() { + Expect(TestVersion().ForArch(ARM64CPUArchitecture).Version()).To(Equal("4.17")) + }) + }) + + It("panics when the architecture has no versions", func() { + withVersions(map[string][]string{ + X86CPUArchitecture: {"4.14"}, + }, func() { + Expect(func() { + TestVersion().ForArch("s390x").Version() + }).To(Panic()) + }) + }) + }) + + Describe("TryVersion", func() { + It("returns false when no versions exist for the architecture", func() { + withVersions(map[string][]string{}, func() { + v, ok := TestVersion().TryVersion() + Expect(ok).To(BeFalse()) + Expect(v).To(BeEmpty()) + }) + }) + + It("returns false when constraint filters out all versions", func() { + withVersions(map[string][]string{ + X86CPUArchitecture: {"4.14"}, + }, func() { + v, ok := TestVersion().GreaterThan("5.0").TryVersion() + Expect(ok).To(BeFalse()) + Expect(v).To(BeEmpty()) + }) + }) + + It("returns the matching version on success", func() { + withVersions(map[string][]string{ + X86CPUArchitecture: {"4.14", "4.15"}, + }, func() { + v, ok := TestVersion().TryVersion() + Expect(ok).To(BeTrue()) + Expect(v).To(Equal("4.15")) + }) + }) + }) + + Describe("Constraints", func() { + BeforeEach(func() {}) + + Describe("LessThan", func() { + It("filters to versions below the threshold", func() { + withVersions(map[string][]string{ + X86CPUArchitecture: {"4.14", "4.15", "4.16", "4.17"}, + }, func() { + Expect(TestVersion().LessThan("4.16").Version()).To(Equal("4.15")) + Expect(TestVersion().LessThan("4.16").Oldest().Version()).To(Equal("4.14")) + }) + }) + + It("returns nothing when all versions are at or above the threshold", func() { + withVersions(map[string][]string{ + X86CPUArchitecture: {"4.16", "4.17"}, + }, func() { + _, ok := TestVersion().LessThan("4.16").TryVersion() + Expect(ok).To(BeFalse()) + }) + }) + }) + + Describe("GreaterThan", func() { + It("filters to versions above the threshold", func() { + withVersions(map[string][]string{ + X86CPUArchitecture: {"4.14", "4.15", "4.16", "4.17"}, + }, func() { + Expect(TestVersion().GreaterThan("4.15").Version()).To(Equal("4.17")) + Expect(TestVersion().GreaterThan("4.15").Oldest().Version()).To(Equal("4.16")) + }) + }) + + It("returns nothing when all versions are at or below the threshold", func() { + withVersions(map[string][]string{ + X86CPUArchitecture: {"4.14", "4.15"}, + }, func() { + _, ok := TestVersion().GreaterThan("4.15").TryVersion() + Expect(ok).To(BeFalse()) + }) + }) + }) + + Describe("Exact", func() { + It("matches the exact version", func() { + withVersions(map[string][]string{ + X86CPUArchitecture: {"4.14", "4.15", "4.16"}, + }, func() { + Expect(TestVersion().Exact("4.15").Version()).To(Equal("4.15")) + }) + }) + + It("returns nothing when the version is not present", func() { + withVersions(map[string][]string{ + X86CPUArchitecture: {"4.14", "4.16"}, + }, func() { + _, ok := TestVersion().Exact("4.15").TryVersion() + Expect(ok).To(BeFalse()) + }) + }) + }) + + Describe("constraint with single version", func() { + It("returns the only version when it matches", func() { + withVersions(map[string][]string{ + X86CPUArchitecture: {"4.15"}, + }, func() { + Expect(TestVersion().LessThan("5.0").Version()).To(Equal("4.15")) + }) + }) + + It("returns nothing when the single version does not match", func() { + withVersions(map[string][]string{ + X86CPUArchitecture: {"4.15"}, + }, func() { + _, ok := TestVersion().GreaterThan("5.0").TryVersion() + Expect(ok).To(BeFalse()) + }) + }) + }) + + Describe("constraint replaces previous constraint", func() { + It("uses the last constraint set", func() { + withVersions(map[string][]string{ + X86CPUArchitecture: {"4.14", "4.15", "4.16", "4.17"}, + }, func() { + v := TestVersion().LessThan("4.15").GreaterThan("4.15").Version() + Expect(v).To(Equal("4.17")) + }) + }) + }) + + Describe("no constraint returns all versions", func() { + It("returns latest without any constraint", func() { + withVersions(map[string][]string{ + X86CPUArchitecture: {"4.14", "4.15", "4.16"}, + }, func() { + Expect(TestVersion().Version()).To(Equal("4.16")) + Expect(TestVersion().Oldest().Version()).To(Equal("4.14")) + }) + }) + }) + }) + + Describe("Constraint with cross-major versions", func() { + It("compares across major version boundaries", func() { + withVersions(map[string][]string{ + X86CPUArchitecture: {"4.16", "4.17", "5.0", "5.1"}, + }, func() { + Expect(TestVersion().GreaterThan("4.17").Oldest().Version()).To(Equal("5.0")) + Expect(TestVersion().LessThan("5.0").Version()).To(Equal("4.17")) + }) + }) + }) + + Describe("ReleaseVersion", func() { + It("appends .0 to the selected version", func() { + withVersions(map[string][]string{ + X86CPUArchitecture: {"4.16"}, + }, func() { + Expect(TestVersion().ReleaseVersion()).To(Equal("4.16.0")) + }) + }) + }) + + Describe("ReleaseImageURL", func() { + It("builds the correct URL for x86_64", func() { + withVersions(map[string][]string{ + X86CPUArchitecture: {"4.16"}, + }, func() { + url := TestVersion().ReleaseImageURL() + Expect(url).To(Equal("quay.io/openshift-release-dev/ocp-release:4.16.0-x86_64")) + }) + }) + + It("uses aarch64 suffix for arm64 architecture", func() { + withVersions(map[string][]string{ + ARM64CPUArchitecture: {"4.16"}, + }, func() { + url := TestVersion().ForArch(ARM64CPUArchitecture).ReleaseImageURL() + Expect(url).To(Equal("quay.io/openshift-release-dev/ocp-release:4.16.0-aarch64")) + }) + }) + + It("uses the arch name directly for multi", func() { + withVersions(map[string][]string{ + MultiCPUArchitecture: {"4.16"}, + }, func() { + url := TestVersion().ForArch(MultiCPUArchitecture).ReleaseImageURL() + Expect(url).To(Equal("quay.io/openshift-release-dev/ocp-release:4.16.0-multi")) + }) + }) + }) + + Describe("parseVersion panics on invalid input", func() { + It("panics for an unparseable version string", func() { + withVersions(map[string][]string{ + X86CPUArchitecture: {"4.16"}, + }, func() { + Expect(func() { + TestVersion().LessThan("not.a" + ".version.$$") + }).To(Panic()) + }) + }) + + It("panics when Version is called and constraint uses invalid version", func() { + withVersions(map[string][]string{ + X86CPUArchitecture: {"4.16"}, + }, func() { + Expect(func() { + TestVersion().Exact("%%%").Version() + }).To(Panic()) + }) + }) + }) + + Describe("Edge cases", func() { + It("handles empty version list for a known architecture", func() { + withVersions(map[string][]string{ + X86CPUArchitecture: {}, + }, func() { + _, ok := TestVersion().TryVersion() + Expect(ok).To(BeFalse()) + }) + }) + + It("constraint on empty list returns nothing", func() { + withVersions(map[string][]string{ + X86CPUArchitecture: {}, + }, func() { + _, ok := TestVersion().LessThan("5.0").TryVersion() + Expect(ok).To(BeFalse()) + }) + }) + + It("Oldest and Latest on a single-element list return the same version", func() { + withVersions(map[string][]string{ + X86CPUArchitecture: {"4.16"}, + }, func() { + Expect(TestVersion().Oldest().Version()).To(Equal("4.16")) + Expect(TestVersion().Latest().Version()).To(Equal("4.16")) + }) + }) + }) + + DescribeTable("constraint + arch combinations", + func(arch string, constraint func(*TestVersionBuilder) *TestVersionBuilder, expected string) { + withVersions(map[string][]string{ + X86CPUArchitecture: {"4.14", "4.15", "4.16"}, + ARM64CPUArchitecture: {"4.15", "4.16", "4.17"}, + MultiCPUArchitecture: {"4.16", "4.17", "4.18"}, + }, func() { + v := constraint(TestVersion().ForArch(arch)).Version() + Expect(v).To(Equal(expected)) + }) + }, + Entry("x86_64 less than 4.16", + X86CPUArchitecture, + func(b *TestVersionBuilder) *TestVersionBuilder { return b.LessThan("4.16") }, + "4.15", + ), + Entry("arm64 greater than 4.15", + ARM64CPUArchitecture, + func(b *TestVersionBuilder) *TestVersionBuilder { return b.GreaterThan("4.15") }, + "4.17", + ), + Entry("multi exact 4.17", + MultiCPUArchitecture, + func(b *TestVersionBuilder) *TestVersionBuilder { return b.Exact("4.17") }, + "4.17", + ), + Entry("arm64 oldest greater than 4.15", + ARM64CPUArchitecture, + func(b *TestVersionBuilder) *TestVersionBuilder { return b.GreaterThan("4.15").Oldest() }, + "4.16", + ), + ) +}) diff --git a/internal/host/hostcommands/install_cmd_test.go b/internal/host/hostcommands/install_cmd_test.go index 6ec5f57bcc21..ab9f81373618 100644 --- a/internal/host/hostcommands/install_cmd_test.go +++ b/internal/host/hostcommands/install_cmd_test.go @@ -173,7 +173,7 @@ var _ = Describe("installcmd", func() { mockImages(1) installCmdSteps, stepErr = installCmd.GetSteps(ctx, &host) postvalidation(false, false, installCmdSteps[0], stepErr, models.HostRoleMaster) - validateInstallCommand(installCmd, installCmdSteps[0], models.HostRoleMaster, infraEnvId, clusterId, *host.ID, common.TestDiskId, nil, common.MinMasterHostsNeededForInstallationInHaMode, false, common.TestDefaultConfig.OpenShiftVersion, true) + validateInstallCommand(installCmd, installCmdSteps[0], models.HostRoleMaster, infraEnvId, clusterId, *host.ID, common.TestDiskId, nil, common.MinMasterHostsNeededForInstallationInHaMode, true, common.TestDefaultConfig.OpenShiftVersion, true) hostFromDb := hostutil.GetHostFromDB(*host.ID, infraEnvId, db) Expect(hostFromDb.InstallerVersion).Should(Equal(DefaultInstructionConfig.InstallerImage)) }) @@ -186,13 +186,13 @@ var _ = Describe("installcmd", func() { mockImages(3) installCmdSteps, stepErr = installCmd.GetSteps(ctx, &host) postvalidation(false, false, installCmdSteps[0], stepErr, models.HostRoleMaster) - validateInstallCommand(installCmd, installCmdSteps[0], models.HostRoleMaster, infraEnvId, clusterId, *host.ID, common.TestDiskId, nil, common.MinMasterHostsNeededForInstallationInHaMode, false, common.TestDefaultConfig.OpenShiftVersion, true) + validateInstallCommand(installCmd, installCmdSteps[0], models.HostRoleMaster, infraEnvId, clusterId, *host.ID, common.TestDiskId, nil, common.MinMasterHostsNeededForInstallationInHaMode, true, common.TestDefaultConfig.OpenShiftVersion, true) installCmdSteps, stepErr = installCmd.GetSteps(ctx, &host2) postvalidation(false, false, installCmdSteps[0], stepErr, models.HostRoleMaster) - validateInstallCommand(installCmd, installCmdSteps[0], models.HostRoleMaster, infraEnvId, clusterId, *host2.ID, common.TestDiskId, nil, common.MinMasterHostsNeededForInstallationInHaMode, false, common.TestDefaultConfig.OpenShiftVersion, true) + validateInstallCommand(installCmd, installCmdSteps[0], models.HostRoleMaster, infraEnvId, clusterId, *host2.ID, common.TestDiskId, nil, common.MinMasterHostsNeededForInstallationInHaMode, true, common.TestDefaultConfig.OpenShiftVersion, true) installCmdSteps, stepErr = installCmd.GetSteps(ctx, &host3) postvalidation(false, false, installCmdSteps[0], stepErr, models.HostRoleBootstrap) - validateInstallCommand(installCmd, installCmdSteps[0], models.HostRoleBootstrap, infraEnvId, clusterId, *host3.ID, common.TestDiskId, nil, common.MinMasterHostsNeededForInstallationInHaMode, false, common.TestDefaultConfig.OpenShiftVersion, true) + validateInstallCommand(installCmd, installCmdSteps[0], models.HostRoleBootstrap, infraEnvId, clusterId, *host3.ID, common.TestDiskId, nil, common.MinMasterHostsNeededForInstallationInHaMode, true, common.TestDefaultConfig.OpenShiftVersion, true) }) It("invalid_inventory", func() { host.Inventory = "blah" @@ -288,7 +288,7 @@ var _ = Describe("installcmd", func() { prepareGetStep(sdb) installCmdSteps, stepErr = installCmd.GetSteps(ctx, &host) postvalidation(false, false, installCmdSteps[0], stepErr, models.HostRoleMaster) - validateInstallCommand(installCmd, installCmdSteps[0], models.HostRoleMaster, infraEnvId, clusterId, *host.ID, sdb.ID, getBootableDiskNames(disks), common.MinMasterHostsNeededForInstallationInHaMode, false, common.TestDefaultConfig.OpenShiftVersion, true) + validateInstallCommand(installCmd, installCmdSteps[0], models.HostRoleMaster, infraEnvId, clusterId, *host.ID, sdb.ID, getBootableDiskNames(disks), common.MinMasterHostsNeededForInstallationInHaMode, true, common.TestDefaultConfig.OpenShiftVersion, true) hostFromDb := hostutil.GetHostFromDB(*host.ID, infraEnvId, db) Expect(hostFromDb.InstallerVersion).Should(Equal(DefaultInstructionConfig.InstallerImage)) verifyDiskFormatCommand(installCmdSteps[0], sda.ID, true) @@ -310,7 +310,7 @@ var _ = Describe("installcmd", func() { prepareGetStep(sddd) installCmdSteps, stepErr = installCmd.GetSteps(ctx, &host) postvalidation(false, false, installCmdSteps[0], stepErr, models.HostRoleMaster) - validateInstallCommand(installCmd, installCmdSteps[0], models.HostRoleMaster, infraEnvId, clusterId, *host.ID, sddd.ID, getBootableDiskNames(disks), common.MinMasterHostsNeededForInstallationInHaMode, false, common.TestDefaultConfig.OpenShiftVersion, true) + validateInstallCommand(installCmd, installCmdSteps[0], models.HostRoleMaster, infraEnvId, clusterId, *host.ID, sddd.ID, getBootableDiskNames(disks), common.MinMasterHostsNeededForInstallationInHaMode, true, common.TestDefaultConfig.OpenShiftVersion, true) hostFromDb := hostutil.GetHostFromDB(*host.ID, infraEnvId, db) Expect(hostFromDb.InstallerVersion).Should(Equal(DefaultInstructionConfig.InstallerImage)) verifyDiskFormatCommand(installCmdSteps[0], sda.ID, true) @@ -333,7 +333,7 @@ var _ = Describe("installcmd", func() { prepareGetStep(sddd) installCmdSteps, stepErr = installCmd.GetSteps(ctx, &host) postvalidation(false, false, installCmdSteps[0], stepErr, models.HostRoleMaster) - validateInstallCommand(installCmd, installCmdSteps[0], models.HostRoleMaster, infraEnvId, clusterId, *host.ID, sddd.ID, getBootableDiskNames(disks), common.MinMasterHostsNeededForInstallationInHaMode, false, common.TestDefaultConfig.OpenShiftVersion, true) + validateInstallCommand(installCmd, installCmdSteps[0], models.HostRoleMaster, infraEnvId, clusterId, *host.ID, sddd.ID, getBootableDiskNames(disks), common.MinMasterHostsNeededForInstallationInHaMode, true, common.TestDefaultConfig.OpenShiftVersion, true) hostFromDb := hostutil.GetHostFromDB(*host.ID, infraEnvId, db) Expect(hostFromDb.InstallerVersion).Should(Equal(DefaultInstructionConfig.InstallerImage)) verifyDiskFormatCommand(installCmdSteps[0], sda.ID, true) @@ -380,7 +380,7 @@ var _ = Describe("installcmd", func() { prepareGetStep(sdb) installCmdSteps, stepErr = installCmd.GetSteps(ctx, &host) postvalidation(false, false, installCmdSteps[0], stepErr, models.HostRoleMaster) - validateInstallCommand(installCmd, installCmdSteps[0], models.HostRoleMaster, infraEnvId, clusterId, *host.ID, sdb.ID, []string{sda.ID, sdc.ID}, common.MinMasterHostsNeededForInstallationInHaMode, false, common.TestDefaultConfig.OpenShiftVersion, true) + validateInstallCommand(installCmd, installCmdSteps[0], models.HostRoleMaster, infraEnvId, clusterId, *host.ID, sdb.ID, []string{sda.ID, sdc.ID}, common.MinMasterHostsNeededForInstallationInHaMode, true, common.TestDefaultConfig.OpenShiftVersion, true) hostFromDb := hostutil.GetHostFromDB(*host.ID, infraEnvId, db) Expect(hostFromDb.InstallerVersion).Should(Equal(DefaultInstructionConfig.InstallerImage)) verifyDiskFormatCommand(installCmdSteps[0], sda.ID, true) diff --git a/internal/releasesources/release_sources_test.go b/internal/releasesources/release_sources_test.go index c9e73fec9f38..ebd41ecd6edb 100644 --- a/internal/releasesources/release_sources_test.go +++ b/internal/releasesources/release_sources_test.go @@ -1,6 +1,7 @@ package releasesources import ( + "fmt" "testing" "github.com/go-openapi/swag" @@ -212,7 +213,7 @@ var _ = Describe("SyncReleaseImages", func() { It("Should cause an error with invalid release sources - invalid cpu architecture", func() { releaseSources := models.ReleaseSources{ { - OpenshiftVersion: swag.String("4.12"), + OpenshiftVersion: swag.String(common.TestVersion().Version()), MultiCPUArchitectures: testSupportedMultiArchitectures, UpgradeChannels: []*models.UpgradeChannel{ { @@ -262,7 +263,7 @@ var _ = Describe("SyncReleaseImages", func() { It("Should cause an error with invalid release sources - invalid channel", func() { releaseSources := models.ReleaseSources{ { - OpenshiftVersion: swag.String("4.12"), + OpenshiftVersion: swag.String(common.TestVersion().Version()), MultiCPUArchitectures: testSupportedMultiArchitectures, UpgradeChannels: []*models.UpgradeChannel{ { @@ -287,7 +288,7 @@ var _ = Describe("SyncReleaseImages", func() { It("Should cause an error with invalid release sources - invalid multi_cpu_architectures", func() { releaseSources := models.ReleaseSources{ { - OpenshiftVersion: swag.String("4.12"), + OpenshiftVersion: swag.String(common.TestVersion().Version()), MultiCPUArchitectures: []string{"invalid arch"}, UpgradeChannels: []*models.UpgradeChannel{ { @@ -398,7 +399,7 @@ var _ = Describe("SyncReleaseImages", func() { It("Should cause an error with invalid release sources - missing multi_cpu_architectures", func() { releaseSources := models.ReleaseSources{ { - OpenshiftVersion: swag.String("4.12"), + OpenshiftVersion: swag.String(common.TestVersion().Version()), UpgradeChannels: []*models.UpgradeChannel{ { CPUArchitecture: swag.String(common.X86CPUArchitecture), @@ -422,7 +423,7 @@ var _ = Describe("SyncReleaseImages", func() { It("Should cause an error with invalid release sources - missing upgrade_channels", func() { releaseSources := models.ReleaseSources{ { - OpenshiftVersion: swag.String("4.12"), + OpenshiftVersion: swag.String(common.TestVersion().Version()), MultiCPUArchitectures: testSupportedMultiArchitectures, }, } @@ -441,7 +442,7 @@ var _ = Describe("SyncReleaseImages", func() { It("Should cause an error with invalid release sources - missing cpu_architecture", func() { releaseSources := models.ReleaseSources{ { - OpenshiftVersion: swag.String("4.12"), + OpenshiftVersion: swag.String(common.TestVersion().Version()), MultiCPUArchitectures: testSupportedMultiArchitectures, UpgradeChannels: []*models.UpgradeChannel{ { @@ -464,7 +465,7 @@ var _ = Describe("SyncReleaseImages", func() { It("Should cause an error with invalid release sources - missing channels", func() { releaseSources := models.ReleaseSources{ { - OpenshiftVersion: swag.String("4.12"), + OpenshiftVersion: swag.String(common.TestVersion().Version()), MultiCPUArchitectures: testSupportedMultiArchitectures, UpgradeChannels: []*models.UpgradeChannel{ { @@ -560,11 +561,16 @@ var _ = Describe("SyncReleaseImages", func() { }) It("Should cause an error with missing required fields", func() { + testVersion := common.TestVersion() + openshiftVersion := testVersion.Version() + testReleaseVersion := testVersion.ReleaseVersion() + testURL := testVersion.ReleaseImageURL() + releaseImages := models.ReleaseImages{ { - Version: swag.String("4.11.1"), + Version: swag.String(testReleaseVersion), CPUArchitecture: swag.String(common.X86CPUArchitecture), - URL: swag.String("quay.io/openshift-release-dev/ocp-release:4.11.1-x86_64"), + URL: swag.String(testURL), }, } handler, err = newReleaseSourcesHandler( @@ -579,9 +585,9 @@ var _ = Describe("SyncReleaseImages", func() { releaseImages = models.ReleaseImages{ { - OpenshiftVersion: swag.String("4.11"), + OpenshiftVersion: swag.String(openshiftVersion), CPUArchitecture: swag.String(common.X86CPUArchitecture), - URL: swag.String("quay.io/openshift-release-dev/ocp-release:4.11.1-x86_64"), + URL: swag.String(testURL), }, } @@ -597,9 +603,9 @@ var _ = Describe("SyncReleaseImages", func() { releaseImages = models.ReleaseImages{ { - OpenshiftVersion: swag.String("4.11"), - Version: swag.String("4.11.1"), - URL: swag.String("quay.io/openshift-release-dev/ocp-release:4.11.1-x86_64"), + OpenshiftVersion: swag.String(openshiftVersion), + Version: swag.String(testReleaseVersion), + URL: swag.String(testURL), }, } @@ -615,8 +621,8 @@ var _ = Describe("SyncReleaseImages", func() { releaseImages = models.ReleaseImages{ { - OpenshiftVersion: swag.String("4.11"), - Version: swag.String("4.11.1"), + OpenshiftVersion: swag.String(openshiftVersion), + Version: swag.String(testReleaseVersion), CPUArchitecture: swag.String(common.X86CPUArchitecture), }, } @@ -663,12 +669,16 @@ var _ = Describe("SyncReleaseImages", func() { }) It("Should cause an error with invalid fields", func() { + testVersion := common.TestVersion().Version() + testFullVersion := testVersion + ".1" + testURL := fmt.Sprintf("quay.io/openshift-release-dev/ocp-release:%s-x86_64", testFullVersion) + releaseImages := models.ReleaseImages{ { - OpenshiftVersion: swag.String("4.11"), - Version: swag.String("4.11.1"), + OpenshiftVersion: swag.String(testVersion), + Version: swag.String(testFullVersion), CPUArchitecture: swag.String("invalidCPUArch"), - URL: swag.String("quay.io/openshift-release-dev/ocp-release:4.11.1-x86_64"), + URL: swag.String(testURL), }, } diff --git a/subsystem/cluster_test.go b/subsystem/cluster_test.go index 8744e5fd32a5..9c7333782054 100644 --- a/subsystem/cluster_test.go +++ b/subsystem/cluster_test.go @@ -74,10 +74,14 @@ var _ = Describe("Cluster with Platform", func() { Context("vSphere", func() { It("vSphere cluster on OCP 4.13 - Success", func() { + openShiftVersion, ok := common.TestVersion().Exact("4.13").TryVersion() + if !ok { + Skip("4.13 not available") + } cluster, err := utils_test.TestContext.UserBMClient.Installer.V2RegisterCluster(ctx, &installer.V2RegisterClusterParams{ NewClusterParams: &models.ClusterCreateParams{ Name: swag.String("test-cluster"), - OpenshiftVersion: swag.String("4.13"), + OpenshiftVersion: swag.String(openShiftVersion), ControlPlaneCount: swag.Int64(common.MinMasterHostsNeededForInstallationInHaMode), PullSecret: swag.String(pullSecret), Platform: &models.Platform{Type: common.PlatformTypePtr(models.PlatformTypeVsphere)}, @@ -87,11 +91,15 @@ var _ = Describe("Cluster with Platform", func() { Expect(*cluster.GetPayload().Platform.Type).Should(Equal(models.PlatformTypeVsphere)) }) - It("vSphere cluster on OCP 4.13 with dual stack - Succeess", func() { + It("vSphere cluster on OCP 4.13 with dual stack - Success", func() { + openShiftVersion, ok := common.TestVersion().Exact("4.13").TryVersion() + if !ok { + Skip("4.13 not available") + } _, err := utils_test.TestContext.UserBMClient.Installer.V2RegisterCluster(ctx, &installer.V2RegisterClusterParams{ NewClusterParams: &models.ClusterCreateParams{ Name: swag.String("test-cluster"), - OpenshiftVersion: swag.String("4.13"), + OpenshiftVersion: swag.String(openShiftVersion), ControlPlaneCount: swag.Int64(common.MinMasterHostsNeededForInstallationInHaMode), PullSecret: swag.String(pullSecret), Platform: &models.Platform{Type: common.PlatformTypePtr(models.PlatformTypeVsphere)},