Skip to content

Commit edd456e

Browse files
committed
[SRVKP-7207] verify olmskiprange path
1 parent f10d43a commit edd456e

File tree

6 files changed

+264
-2
lines changed

6 files changed

+264
-2
lines changed

pkg/oc/oc.go

Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"encoding/json"
55
"fmt"
66
"log"
7+
"os"
78
"slices"
89
"strings"
910
"time"
@@ -169,3 +170,218 @@ func CopySecret(secretName string, sourceNamespace string, destNamespace string)
169170
cmd.MustSucceed("bash", "-c", fmt.Sprintf(`echo '%s' | kubectl apply -n %s -f -`, cmdOutput, destNamespace))
170171
log.Printf("Successfully copied secret %s from %s to %s", secretName, sourceNamespace, destNamespace)
171172
}
173+
174+
func FetchOlmSkipRange() (map[string]string, error) {
175+
skipRangesJson := cmd.MustSucceed("bash", "-c", `oc get packagemanifests openshift-pipelines-operator-rh -n openshift-marketplace -o json | jq -r '.status.channels[].currentCSVDesc.annotations["olm.skipRange"]'`).Stdout()
176+
skipRanges := strings.Split(strings.TrimSpace(skipRangesJson), "\n")
177+
channelsJson := cmd.MustSucceed("bash", "-c", `oc get packagemanifests openshift-pipelines-operator-rh -n openshift-marketplace -o json | jq -r '.status.channels[].name'`).Stdout()
178+
channels := strings.Split(strings.TrimSpace(channelsJson), "\n")
179+
180+
if len(channels) != len(skipRanges) {
181+
return nil, fmt.Errorf("mismatch between number of channels (%d) and skipRanges (%d)", len(channels), len(skipRanges))
182+
}
183+
184+
channelSkipRangeMap := make(map[string]string)
185+
for i, channel := range channels {
186+
if skipRanges[i] != "null" && skipRanges[i] != "" {
187+
channelSkipRangeMap[channel] = skipRanges[i]
188+
}
189+
}
190+
191+
if len(channelSkipRangeMap) == 0 {
192+
return nil, fmt.Errorf("no valid OLM Skip Ranges found")
193+
}
194+
return channelSkipRangeMap, nil
195+
}
196+
197+
func GetOlmSkipRange(upgradeType, fieldName, fileName string) {
198+
skipRangeMap, err := FetchOlmSkipRange()
199+
if err != nil {
200+
log.Printf("Error fetching OLM Skip Range: %v", err)
201+
return
202+
}
203+
file, err := os.OpenFile(config.Path(fileName), os.O_RDWR, 0644)
204+
if err != nil {
205+
log.Printf("Error opening file %s: %v", fileName, err)
206+
return
207+
}
208+
defer file.Close()
209+
var existingData map[string]interface{}
210+
if err := json.NewDecoder(file).Decode(&existingData); err != nil {
211+
log.Printf("Error decoding existing data from file %s: %v", fileName, err)
212+
return
213+
}
214+
switch upgradeType {
215+
case "pre-upgrade":
216+
existingData["pre-upgrade-olm-skip-range"] = skipRangeMap
217+
log.Printf("Pre-upgrade OLM Skip Range is stored as: %+v", skipRangeMap)
218+
case "post-upgrade":
219+
existingData["post-upgrade-olm-skip-range"] = skipRangeMap
220+
log.Printf("Post-upgrade OLM Skip Range is stored as: %+v", skipRangeMap)
221+
}
222+
if _, err := file.Seek(0, 0); err != nil {
223+
log.Printf("Error seeking file %s: %v", fileName, err)
224+
return
225+
}
226+
encoder := json.NewEncoder(file)
227+
encoder.SetIndent("", " ") // Pretty-print the JSON output
228+
if err := encoder.Encode(existingData); err != nil {
229+
log.Printf("Error writing updated data to file %s: %v", fileName, err)
230+
return
231+
}
232+
log.Printf("OLM Skip Range for '%s' has been saved to file %s", fieldName, fileName)
233+
}
234+
235+
func ValidateOlmSkipRange() {
236+
skipRangeMap, err := FetchOlmSkipRange()
237+
if err != nil {
238+
log.Printf("Error fetching OLM Skip Range: %v", err)
239+
return
240+
}
241+
242+
ospVersion := os.Getenv("OSP_VERSION")
243+
log.Printf("Validating OSP_VERSION: %s", ospVersion)
244+
found := false
245+
246+
if ospVersion == "5.0.5" {
247+
log.Printf("Detected nightly build (OSP_VERSION=5.0.5), validating only skipRange, not channel name")
248+
for channel, skipRange := range skipRangeMap {
249+
if channel == "latest" {
250+
log.Printf("Skipping 'latest' channel as requested")
251+
continue
252+
}
253+
skipRangeContainsVersion := strings.Contains(skipRange, ospVersion)
254+
log.Printf("Channel: %s, SkipRange: %s", channel, skipRange)
255+
log.Printf(" - SkipRange contains OSP_VERSION '%s': %v", ospVersion, skipRangeContainsVersion)
256+
257+
if skipRangeContainsVersion {
258+
log.Printf("Success: OSP_VERSION '%s' found in skipRange for channel '%s': '%s'", ospVersion, channel, skipRange)
259+
found = true
260+
break
261+
}
262+
}
263+
} else {
264+
log.Printf("Regular release build, validating both channel name and skipRange")
265+
for channel, skipRange := range skipRangeMap {
266+
if channel == "latest" {
267+
log.Printf("Skipping 'latest' channel as requested")
268+
continue
269+
}
270+
channelContainsVersion := strings.Contains(channel, ospVersion)
271+
skipRangeContainsVersion := strings.Contains(skipRange, ospVersion)
272+
log.Printf("Channel: %s, SkipRange: %s", channel, skipRange)
273+
log.Printf(" - Channel contains OSP_VERSION '%s': %v", ospVersion, channelContainsVersion)
274+
log.Printf(" - SkipRange contains OSP_VERSION '%s': %v", ospVersion, skipRangeContainsVersion)
275+
if channelContainsVersion && skipRangeContainsVersion {
276+
log.Printf("Success: OSP_VERSION '%s' found in both channel '%s' and its skipRange '%s'", ospVersion, channel, skipRange)
277+
found = true
278+
break
279+
}
280+
}
281+
}
282+
283+
if !found {
284+
log.Printf("Available channels and their skipRanges:")
285+
for channel, skipRange := range skipRangeMap {
286+
if channel != "latest" {
287+
log.Printf(" - Channel: %s, SkipRange: %s", channel, skipRange)
288+
}
289+
}
290+
291+
if ospVersion == "5.0.5" {
292+
testsuit.T.Fail(fmt.Errorf("Error: OSP_VERSION '%s' not found in skipRange for any non-latest channel", ospVersion))
293+
} else {
294+
testsuit.T.Fail(fmt.Errorf("Error: OSP_VERSION '%s' not found in both channel name and skipRange for any non-latest channel", ospVersion))
295+
}
296+
}
297+
}
298+
299+
func ValidateOlmSkipRangeDiff(fileName string, preUpgradeSkipRange string, postUpgradeSkipRange string) {
300+
file, err := os.Open(config.Path(fileName))
301+
if err != nil {
302+
log.Printf("Error opening file %s: %v", fileName, err)
303+
testsuit.T.Fail(fmt.Errorf("Error opening file %s: %v", fileName, err))
304+
return
305+
}
306+
defer file.Close()
307+
var skipRangeData map[string]interface{}
308+
decoder := json.NewDecoder(file)
309+
if err := decoder.Decode(&skipRangeData); err != nil {
310+
log.Printf("Error decoding JSON from file %s: %v", fileName, err)
311+
testsuit.T.Fail(fmt.Errorf("Error decoding JSON from file %s: %v", fileName, err))
312+
return
313+
}
314+
preUpgradeData, preExists := skipRangeData[preUpgradeSkipRange]
315+
postUpgradeData, postExists := skipRangeData[postUpgradeSkipRange]
316+
if !preExists || !postExists {
317+
log.Printf("Error: One of the skip ranges is missing. Pre-Upgrade exists: %v, Post-Upgrade exists: %v", preExists, postExists)
318+
testsuit.T.Fail(fmt.Errorf("One of the skip ranges is missing. Pre-Upgrade exists: %v, Post-Upgrade exists: %v", preExists, postExists))
319+
return
320+
}
321+
322+
preUpgradeMap, ok1 := preUpgradeData.(map[string]interface{})
323+
postUpgradeMap, ok2 := postUpgradeData.(map[string]interface{})
324+
325+
if !ok1 || !ok2 {
326+
log.Printf("Error: Skip range data is not in expected map format")
327+
testsuit.T.Fail(fmt.Errorf("Skip range data is not in expected map format"))
328+
return
329+
}
330+
331+
log.Printf("Pre-Upgrade Skip Range: %+v", preUpgradeMap)
332+
log.Printf("Post-Upgrade Skip Range: %+v", postUpgradeMap)
333+
334+
// Validate that all pre-upgrade channels (except 'latest') are preserved in post-upgrade
335+
// Ignore 'latest' channel in post-upgrade data completely
336+
validationErrors := []string{}
337+
338+
log.Printf("Validating that all pre-upgrade channels are preserved in post-upgrade (ignoring 'latest' channel)")
339+
340+
// Check each channel from pre-upgrade data
341+
for preChannel, preSkipRange := range preUpgradeMap {
342+
// Skip 'latest' channel from pre-upgrade validation
343+
if preChannel == "latest" {
344+
log.Printf("Skipping 'latest' channel from pre-upgrade data as requested")
345+
continue
346+
}
347+
348+
// Check if this pre-upgrade channel exists in post-upgrade with same skipRange
349+
if postSkipRange, exists := postUpgradeMap[preChannel]; exists {
350+
if preSkipRange == postSkipRange {
351+
log.Printf("✅ Success: Channel '%s' preserved with skipRange: %v", preChannel, preSkipRange)
352+
} else {
353+
validationErrors = append(validationErrors, fmt.Sprintf("Channel '%s' skipRange changed from '%v' to '%v' (should remain unchanged)", preChannel, preSkipRange, postSkipRange))
354+
}
355+
} else {
356+
validationErrors = append(validationErrors, fmt.Sprintf("Pre-upgrade channel '%s' is missing in post-upgrade data", preChannel))
357+
}
358+
}
359+
360+
// Log additional channels in post-upgrade (for information only, not validation errors)
361+
log.Printf("Additional channels found in post-upgrade data:")
362+
for postChannel, postSkipRange := range postUpgradeMap {
363+
// Skip channels that were in pre-upgrade (already validated above)
364+
if _, existedInPre := preUpgradeMap[postChannel]; existedInPre {
365+
continue
366+
}
367+
368+
// Skip 'latest' channel as requested
369+
if postChannel == "latest" {
370+
log.Printf(" - Ignoring 'latest' channel in post-upgrade as requested")
371+
continue
372+
}
373+
374+
log.Printf(" - New channel '%s' with skipRange: %v", postChannel, postSkipRange)
375+
}
376+
377+
// Report results
378+
if len(validationErrors) > 0 {
379+
log.Printf("❌ OLM Skip Range validation failed with errors:")
380+
for _, err := range validationErrors {
381+
log.Printf(" - %s", err)
382+
}
383+
testsuit.T.Fail(fmt.Errorf("OLM Skip Range validation failed: %v", strings.Join(validationErrors, "; ")))
384+
} else {
385+
log.Printf("✅ Success: OLM Skip Range validation passed - all expected changes detected correctly")
386+
}
387+
}

specs/operator/post-upgrade.spec

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,4 +83,15 @@ Importance: Critical
8383
Steps:
8484
* Switch to project "releasetest-upgrade-s2i"
8585
* Get tags of the imagestream "golang" from namespace "openshift" and store to variable "golang-tags"
86-
* Start and verify pipeline "s2i-go-pipeline" with param "VERSION" with values stored in variable "golang-tags" with workspace "name=source,claimName=shared-pvc"
86+
* Start and verify pipeline "s2i-go-pipeline" with param "VERSION" with values stored in variable "golang-tags" with workspace "name=source,claimName=shared-pvc"
87+
88+
## Validate olm skiprange post upgrade: PIPELINES-19-TC06
89+
Tags: post-upgrade, olm
90+
Component: Pipelines
91+
Level: Integration
92+
Type: Functional
93+
Importance: Critical
94+
95+
Steps:
96+
* Get olm-skip-range "post-upgrade" and save to field "post-upgrade-olm-skip-range" in file "testdata/olm/skiprange.json"
97+
* Validate the fields "pre-upgrade-olm-skip-range" and "post-upgrade-olm-skip-range" are same in file "testdata/olm/skiprange.json"

specs/operator/pre-upgrade.spec

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,4 +126,14 @@ Steps:
126126
|S.NO|resource_dir |
127127
|----|------------------------------------------------------|
128128
|1 |testdata/ecosystem/pipelines/s2i-go.yaml|
129-
|2 |testdata/pvc/pvc.yaml |
129+
|2 |testdata/pvc/pvc.yaml |
130+
131+
## Validate olm skiprange pre upgrade: PIPELINES-18-TC06
132+
Tags: pre-upgrade, olm
133+
Component: Pipelines
134+
Level: Integration
135+
Type: Functional
136+
Importance: Critical
137+
138+
Steps:
139+
* Get olm-skip-range "pre-upgrade" and save to field "pre-upgrade-olm-skip-range" in file "testdata/olm/skiprange.json"

specs/versions.spec

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,12 @@ Steps:
3030
* Check "tkn-pac" version
3131
* Check "opc" client version
3232
* Check "opc" server version
33+
34+
## Check OperatorVersion in OlmSkipRange : PIPELINES-22-TC03
35+
Tags: e2e, sanity, olm
36+
Component: Operator
37+
Level: Integration
38+
Type: Functional
39+
Importance: High
40+
Steps:
41+
* Validate OperatorVersion in OlmSkipRange

steps/olm/operator.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,3 +194,15 @@ var _ = gauge.Step("Store Cosign public key in file", func() {
194194
var _ = gauge.Step("Verify <binary> version from the pipelinerun logs", func(binary string) {
195195
pipelines.CheckLogVersion(store.Clients(), binary, store.Namespace())
196196
})
197+
198+
var _ = gauge.Step("Get olm-skip-range <upgradeType> and save to field <fieldName> in file <fileName>", func(upgradeType string, fieldName string, filename string) {
199+
oc.GetOlmSkipRange(upgradeType, fieldName, filename)
200+
})
201+
202+
var _ = gauge.Step("Validate the fields <preUpgradeSkipRange> and <postUpgradeSkipRange> are same in file <fileName>", func(preUpgradeSkipRange string, postUpgradeSkipRange string, fileName string) {
203+
oc.ValidateOlmSkipRangeDiff(fileName, preUpgradeSkipRange, postUpgradeSkipRange)
204+
})
205+
206+
var _ = gauge.Step("Validate OperatorVersion in OlmSkipRange", func() {
207+
oc.ValidateOlmSkipRange()
208+
})

testdata/olm/skiprange.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"post-upgrade-olm-skip-range": {},
3+
"pre-upgrade-olm-skip-range": {}
4+
}

0 commit comments

Comments
 (0)