Skip to content

Commit 0bc6f80

Browse files
author
Per Goncalves da Silva
committed
Add ParseFS failure unit tests
Signed-off-by: Per Goncalves da Silva <[email protected]>
1 parent b0a17be commit 0bc6f80

File tree

2 files changed

+100
-1
lines changed

2 files changed

+100
-1
lines changed

internal/rukpak/convert/registryv1.go

+14
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,14 @@ func RegistryV1ToHelmChart(ctx context.Context, rv1 fs.FS, installNamespace stri
6969
return chrt, nil
7070
}
7171

72+
// ParseFS converts the rv1 filesystem into a RegistryV1.
73+
// ParseFS expects the filesystem to conform to the registry+v1 format:
74+
// metadata/annotations.yaml
75+
// manifests/
76+
// - csv.yaml
77+
// - ...
78+
//
79+
// manifests directory does not contain subdirectories
7280
func ParseFS(ctx context.Context, rv1 fs.FS) (RegistryV1, error) {
7381
l := log.FromContext(ctx)
7482

@@ -84,6 +92,7 @@ func ParseFS(ctx context.Context, rv1 fs.FS) (RegistryV1, error) {
8492
reg.PackageName = annotationsFile.Annotations.PackageName
8593

8694
const manifestsDir = "manifests"
95+
foundCSV := false
8796
if err := fs.WalkDir(rv1, manifestsDir, func(path string, e fs.DirEntry, err error) error {
8897
if err != nil {
8998
return err
@@ -119,6 +128,7 @@ func ParseFS(ctx context.Context, rv1 fs.FS) (RegistryV1, error) {
119128
return err
120129
}
121130
reg.CSV = csv
131+
foundCSV = true
122132
default:
123133
reg.Others = append(reg.Others, *info.Object.(*unstructured.Unstructured))
124134
}
@@ -131,6 +141,10 @@ func ParseFS(ctx context.Context, rv1 fs.FS) (RegistryV1, error) {
131141
return reg, err
132142
}
133143

144+
if !foundCSV {
145+
return reg, fmt.Errorf("no ClusterServiceVersion found in %q", manifestsDir)
146+
}
147+
134148
if err := copyMetadataPropertiesToCSV(&reg.CSV, rv1); err != nil {
135149
return reg, err
136150
}

internal/rukpak/convert/registryv1_test.go

+86-1
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ package convert_test
33
import (
44
"context"
55
"fmt"
6-
"github.com/operator-framework/operator-controller/internal/rukpak/convert"
6+
"io/fs"
77
"os"
88
"strings"
99
"testing"
10+
"testing/fstest"
1011

1112
"github.com/stretchr/testify/require"
1213
appsv1 "k8s.io/api/apps/v1"
@@ -21,12 +22,17 @@ import (
2122

2223
"github.com/operator-framework/api/pkg/operators/v1alpha1"
2324
"github.com/operator-framework/operator-registry/alpha/property"
25+
26+
"github.com/operator-framework/operator-controller/internal/rukpak/convert"
2427
)
2528

2629
const (
2730
olmNamespaces = "olm.targetNamespaces"
2831
olmProperties = "olm.properties"
2932
installNamespace = "testInstallNamespace"
33+
34+
bundlePathAnnotations = "metadata/annotations.yaml"
35+
bundlePathCSV = "manifests/csv.yaml"
3036
)
3137

3238
func getCsvAndService() (v1alpha1.ClusterServiceVersion, corev1.Service) {
@@ -466,6 +472,48 @@ func TestRegistryV1SuiteReadBundleFileSystem(t *testing.T) {
466472
require.JSONEq(t, `[{"type":"from-csv-annotations-key","value":"from-csv-annotations-value"},{"type":"from-file-key","value":"from-file-value"}]`, chrt.Metadata.Annotations[olmProperties])
467473
}
468474

475+
func TestParseFSFails(t *testing.T) {
476+
for _, tt := range []struct {
477+
name string
478+
FS fs.FS
479+
}{
480+
{
481+
name: "bundle missing ClusterServiceVersion manifest",
482+
FS: removePaths(newBundleFS(), bundlePathCSV),
483+
}, {
484+
name: "bundle missing metadata/annotations.yaml",
485+
FS: removePaths(newBundleFS(), bundlePathAnnotations),
486+
}, {
487+
name: "bundle missing metadata/ directory",
488+
FS: removePaths(newBundleFS(), "metadata/"),
489+
}, {
490+
name: "bundle missing manifests/ directory",
491+
FS: removePaths(newBundleFS(), "manifests/"),
492+
},
493+
} {
494+
t.Run(tt.name, func(t *testing.T) {
495+
_, err := convert.ParseFS(context.Background(), tt.FS)
496+
require.Error(t, err)
497+
})
498+
}
499+
}
500+
501+
func TestRegistryV1SuiteReadBundleFileSystemFailsOnNoCSV(t *testing.T) {
502+
t.Log("convert.RegistryV1 Suite Convert")
503+
t.Log("It should generate objects successfully based on target namespaces")
504+
505+
t.Log("It should read the registry+v1 bundle filesystem correctly")
506+
t.Log("It should include metadata/properties.yaml and csv.metadata.annotations['olm.properties'] in chart metadata")
507+
fsys := os.DirFS("testdata/combine-properties-bundle")
508+
509+
chrt, err := convert.RegistryV1ToHelmChart(context.Background(), fsys, "", nil)
510+
require.NoError(t, err)
511+
require.NotNil(t, chrt)
512+
require.NotNil(t, chrt.Metadata)
513+
require.Contains(t, chrt.Metadata.Annotations, olmProperties)
514+
require.JSONEq(t, `[{"type":"from-csv-annotations-key","value":"from-csv-annotations-value"},{"type":"from-file-key","value":"from-file-value"}]`, chrt.Metadata.Annotations[olmProperties])
515+
}
516+
469517
func TestRegistryV1SuiteGenerateNoWebhooks(t *testing.T) {
470518
t.Log("convert.RegistryV1 Suite Convert")
471519
t.Log("It should generate objects successfully based on target namespaces")
@@ -543,3 +591,40 @@ func findObjectByName(name string, result []client.Object) client.Object {
543591
}
544592
return nil
545593
}
594+
595+
func newBundleFS() fstest.MapFS {
596+
annotationsYml := `
597+
annotations:
598+
operators.operatorframework.io.bundle.mediatype.v1: registry+v1
599+
operators.operatorframework.io.bundle.package.v1: test
600+
`
601+
602+
csvYml := `
603+
apiVersion: operators.operatorframework.io/v1alpha1
604+
kind: ClusterServiceVersion
605+
metadata:
606+
name: test.v1.0.0
607+
annotations:
608+
olm.properties: '[{"type":"from-csv-annotations-key", "value":"from-csv-annotations-value"}]'
609+
spec:
610+
installModes:
611+
- type: AllNamespaces
612+
supported: true
613+
`
614+
615+
return fstest.MapFS{
616+
bundlePathAnnotations: &fstest.MapFile{Data: []byte(strings.Trim(annotationsYml, "\n"))},
617+
bundlePathCSV: &fstest.MapFile{Data: []byte(strings.Trim(csvYml, "\n"))},
618+
}
619+
}
620+
621+
func removePaths(mapFs fstest.MapFS, paths ...string) fstest.MapFS {
622+
for k := range mapFs {
623+
for _, path := range paths {
624+
if strings.HasPrefix(k, path) {
625+
delete(mapFs, k)
626+
}
627+
}
628+
}
629+
return mapFs
630+
}

0 commit comments

Comments
 (0)