|
1 | 1 | package tests |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "context" |
| 5 | + "fmt" |
| 6 | + "os" |
| 7 | + "path/filepath" |
| 8 | + "strings" |
| 9 | + |
4 | 10 | . "github.com/onsi/ginkgo/v2" |
5 | 11 | . "github.com/onsi/gomega" |
6 | | - tsparams "github.com/redhat-best-practices-for-k8s/certsuite-qe/tests/platformalteration/parameters" |
| 12 | + corev1 "k8s.io/api/core/v1" |
| 13 | + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" |
7 | 14 |
|
8 | 15 | "github.com/redhat-best-practices-for-k8s/certsuite-qe/tests/globalhelper" |
9 | 16 | "github.com/redhat-best-practices-for-k8s/certsuite-qe/tests/globalparameters" |
| 17 | + tsparams "github.com/redhat-best-practices-for-k8s/certsuite-qe/tests/platformalteration/parameters" |
| 18 | +) |
| 19 | + |
| 20 | +const ( |
| 21 | + // rhcosVersionMapRelativePath is the path to the rhcos_version_map file relative to the certsuite repo root. |
| 22 | + rhcosVersionMapRelativePath = "tests/platform/operatingsystem/files/rhcos_version_map" |
10 | 23 | ) |
11 | 24 |
|
12 | 25 | var _ = Describe("platform-alteration-ocp-lifecycle", func() { |
@@ -40,12 +53,95 @@ var _ = Describe("platform-alteration-ocp-lifecycle", func() { |
40 | 53 | Skip("OCP version is not applicable for Kind cluster") |
41 | 54 | } |
42 | 55 |
|
| 56 | + By("Verify RHCOS versions exist in certsuite rhcos_version_map") |
| 57 | + err := verifyRHCOSVersionsInCertsuite() |
| 58 | + Expect(err).ToNot(HaveOccurred(), "RHCOS version validation failed") |
| 59 | + |
43 | 60 | By("Start platform-alteration-ocp-lifecycle test") |
44 | | - err := globalhelper.LaunchTests(tsparams.CertsuiteOCPLifecycleName, |
| 61 | + err = globalhelper.LaunchTests(tsparams.CertsuiteOCPLifecycleName, |
45 | 62 | globalhelper.ConvertSpecNameToFileName(CurrentSpecReport().FullText()), randomReportDir, randomCertsuiteConfigDir) |
46 | 63 | Expect(err).ToNot(HaveOccurred()) |
47 | 64 |
|
48 | 65 | err = globalhelper.ValidateIfReportsAreValid(tsparams.CertsuiteOCPLifecycleName, globalparameters.TestCasePassed, randomReportDir) |
49 | 66 | Expect(err).ToNot(HaveOccurred()) |
50 | 67 | }) |
51 | 68 | }) |
| 69 | + |
| 70 | +// verifyRHCOSVersionsInCertsuite verifies that the RHCOS version from each node's OSImage |
| 71 | +// exists in the certsuite rhcos_version_map file. |
| 72 | +func verifyRHCOSVersionsInCertsuite() error { |
| 73 | + // Get all nodes |
| 74 | + nodesList, err := globalhelper.GetAPIClient().Nodes().List(context.TODO(), metav1.ListOptions{}) |
| 75 | + if err != nil { |
| 76 | + return fmt.Errorf("failed to list nodes: %w", err) |
| 77 | + } |
| 78 | + |
| 79 | + // Get certsuite repo path from config |
| 80 | + certsuiteRepoPath := globalhelper.GetConfiguration().General.CertsuiteRepoPath |
| 81 | + if certsuiteRepoPath == "" { |
| 82 | + return fmt.Errorf("CERTSUITE_REPO_PATH is not configured") |
| 83 | + } |
| 84 | + |
| 85 | + // Path to rhcos_version_map file - split the relative path and join with certsuite repo path |
| 86 | + pathParts := strings.Split(rhcosVersionMapRelativePath, "/") |
| 87 | + pathComponents := append([]string{certsuiteRepoPath}, pathParts...) |
| 88 | + rhcosVersionMapPath := filepath.Join(pathComponents...) |
| 89 | + |
| 90 | + // Read the rhcos_version_map file |
| 91 | + rhcosVersionMapData, err := os.ReadFile(rhcosVersionMapPath) |
| 92 | + if err != nil { |
| 93 | + return fmt.Errorf("failed to read rhcos_version_map file at %s: %w", rhcosVersionMapPath, err) |
| 94 | + } |
| 95 | + |
| 96 | + return verifyRHCOSVersions(nodesList.Items, string(rhcosVersionMapData)) |
| 97 | +} |
| 98 | + |
| 99 | +// verifyRHCOSVersions is a parameterized function that verifies RHCOS versions from nodes |
| 100 | +// against the rhcos_version_map content. This function is designed to be testable. |
| 101 | +func verifyRHCOSVersions(nodes []corev1.Node, rhcosVersionMapContent string) error { |
| 102 | + const rhcosName = "Red Hat Enterprise Linux CoreOS" |
| 103 | + |
| 104 | + if len(nodes) == 0 { |
| 105 | + return fmt.Errorf("no nodes provided for verification") |
| 106 | + } |
| 107 | + |
| 108 | + if rhcosVersionMapContent == "" { |
| 109 | + return fmt.Errorf("rhcos_version_map content is empty") |
| 110 | + } |
| 111 | + |
| 112 | + // Check each node's RHCOS version |
| 113 | + for _, node := range nodes { |
| 114 | + osImage := node.Status.NodeInfo.OSImage |
| 115 | + |
| 116 | + // Extract RHCOS version from OSImage |
| 117 | + // e.g., "Red Hat Enterprise Linux CoreOS 410.84.202205031645-0 (Ootpa)" -> "410.84.202205031645-0" |
| 118 | + if !strings.Contains(osImage, rhcosName) { |
| 119 | + return fmt.Errorf("node %s has unexpected OS image format: %s (does not contain %s)", |
| 120 | + node.Name, osImage, rhcosName) |
| 121 | + } |
| 122 | + |
| 123 | + splitStr := strings.Split(osImage, rhcosName) |
| 124 | + if len(splitStr) < 2 { |
| 125 | + return fmt.Errorf("node %s has unexpected OS image format: %s (cannot split by %s)", |
| 126 | + node.Name, osImage, rhcosName) |
| 127 | + } |
| 128 | + |
| 129 | + longVersionSplit := strings.Split(strings.TrimSpace(splitStr[1]), " ") |
| 130 | + if len(longVersionSplit) == 0 || longVersionSplit[0] == "" { |
| 131 | + return fmt.Errorf("node %s has unexpected OS image format: %s (cannot extract version)", |
| 132 | + node.Name, osImage) |
| 133 | + } |
| 134 | + |
| 135 | + rhcosVersion := longVersionSplit[0] |
| 136 | + |
| 137 | + // Check if the version exists in the rhcos_version_map file |
| 138 | + if !strings.Contains(rhcosVersionMapContent, rhcosVersion) { |
| 139 | + return fmt.Errorf("RHCOS version %s from node %s not found in rhcos_version_map", |
| 140 | + rhcosVersion, node.Name) |
| 141 | + } |
| 142 | + |
| 143 | + fmt.Printf("✓ Node %s RHCOS version %s found in rhcos_version_map\n", node.Name, rhcosVersion) |
| 144 | + } |
| 145 | + |
| 146 | + return nil |
| 147 | +} |
0 commit comments