Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions pkg/payload/render_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package payload

import (
"bytes"
"fmt"
"os"
"path/filepath"
"strings"
"testing"

Expand All @@ -12,6 +15,7 @@ import (
"k8s.io/utils/ptr"

configv1 "github.com/openshift/api/config/v1"
"github.com/openshift/library-go/pkg/manifest"
)

func TestRenderManifest(t *testing.T) {
Expand Down Expand Up @@ -304,3 +308,78 @@ data:

return yaml
}
func Test_cvoManifests(t *testing.T) {
config := manifestRenderConfig{
ReleaseImage: "quay.io/cvo/release:latest",
ClusterProfile: "some-profile",
}

tests := []struct {
name string
dir string
}{
{
name: "install dir",
dir: filepath.Join("../../install"),
},
{
name: "bootstrap dir",
dir: filepath.Join("../../bootstrap"),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
files, err := os.ReadDir(tt.dir)
if err != nil {
t.Fatalf("failed to read directory: %v", err)
}

if len(files) == 0 {
t.Fatalf("no files found in %s", tt.dir)
}

var manifestsWithoutIncludeAnnotation []manifest.Manifest
const prefix = "include.release.openshift.io/"
for _, manifestFile := range files {
if manifestFile.IsDir() {
continue
}
filePath := filepath.Join(tt.dir, manifestFile.Name())
Comment on lines +332 to +347
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Top-level-only scan can miss manifests and under-report violations.

Line 332 reads only direct entries, and Line 344-Line 346 skips directories entirely. If manifests exist under nested folders, they are never validated, so this test can pass while missing unannotated payload manifests.

🔧 Suggested fix (recursive walk + manifest file filtering)
 import (
 	"bytes"
 	"fmt"
+	"io/fs"
 	"os"
 	"path/filepath"
 	"strings"
 	"testing"
@@
-			files, err := os.ReadDir(tt.dir)
+			var files []string
+			err := filepath.WalkDir(tt.dir, func(path string, d fs.DirEntry, err error) error {
+				if err != nil {
+					return err
+				}
+				if d.IsDir() {
+					return nil
+				}
+				ext := strings.ToLower(filepath.Ext(d.Name()))
+				if ext != ".yaml" && ext != ".yml" && ext != ".json" {
+					return nil
+				}
+				files = append(files, path)
+				return nil
+			})
 			if err != nil {
 				t.Fatalf("failed to read directory: %v", err)
 			}
@@
-			for _, manifestFile := range files {
-				if manifestFile.IsDir() {
-					continue
-				}
-				filePath := filepath.Join(tt.dir, manifestFile.Name())
+			for _, filePath := range files {
 				data, err := os.ReadFile(filePath)
 				if err != nil {
 					t.Fatalf("failed to read manifest file: %v", err)
 				}

As per coding guidelines, "**: -Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity."

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
files, err := os.ReadDir(tt.dir)
if err != nil {
t.Fatalf("failed to read directory: %v", err)
}
if len(files) == 0 {
t.Fatalf("no files found in %s", tt.dir)
}
var manifestsWithoutIncludeAnnotation []manifest.Manifest
const prefix = "include.release.openshift.io/"
for _, manifestFile := range files {
if manifestFile.IsDir() {
continue
}
filePath := filepath.Join(tt.dir, manifestFile.Name())
var files []string
err := filepath.WalkDir(tt.dir, func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if d.IsDir() {
return nil
}
ext := strings.ToLower(filepath.Ext(d.Name()))
if ext != ".yaml" && ext != ".yml" && ext != ".json" {
return nil
}
files = append(files, path)
return nil
})
if err != nil {
t.Fatalf("failed to read directory: %v", err)
}
if len(files) == 0 {
t.Fatalf("no files found in %s", tt.dir)
}
var manifestsWithoutIncludeAnnotation []manifest.Manifest
const prefix = "include.release.openshift.io/"
for _, filePath := range files {
data, err := os.ReadFile(filePath)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/payload/render_test.go` around lines 332 - 347, The test currently reads
only top-level entries from tt.dir using os.ReadDir and skips directories
(manifestFile.IsDir()), so nested manifests are missed; update the logic that
builds manifestsWithoutIncludeAnnotation to recursively walk tt.dir (e.g., using
filepath.WalkDir) and collect regular files (filtering for manifest file types
like .yaml/.yml/.json or using manifest.Parse) instead of skipping directories,
then open and validate each discovered file (use the same variable names:
tt.dir, manifestFile/filePath, manifestsWithoutIncludeAnnotation, and prefix) so
nested manifests are included in the validation.

data, err := os.ReadFile(filePath)
if err != nil {
t.Fatalf("failed to read manifest file: %v", err)
}
data, err = renderManifest(config, data)
if err != nil {
t.Fatalf("failed to render manifest: %v", err)
}
manifests, err := manifest.ParseManifests(bytes.NewReader(data))
if err != nil {
t.Fatalf("failed to load manifests: %v", err)
}

for _, m := range manifests {
m.OriginalFilename = filePath
var found bool
for k := range m.Obj.GetAnnotations() {
if strings.HasPrefix(k, prefix) {
found = true
break
}
}
if !found {
manifestsWithoutIncludeAnnotation = append(manifestsWithoutIncludeAnnotation, m)
}
}
}

if len(manifestsWithoutIncludeAnnotation) > 0 {
var messages []string
for _, m := range manifestsWithoutIncludeAnnotation {
messages = append(messages, fmt.Sprintf("%s/%s/%s/%s", m.OriginalFilename, m.GVK, m.Obj.GetName(), m.Obj.GetNamespace()))
}
t.Errorf("Those manifests have no annotation with prefix %q and will not be installed by CVO: %s", prefix, strings.Join(messages, ", "))
}
})
}
}