Skip to content

Commit eb0f4e4

Browse files
author
Per Goncalves da Silva
committed
Update NewBundleFS test utility
Signed-off-by: Per Goncalves da Silva <[email protected]>
1 parent 55d9dfb commit eb0f4e4

File tree

5 files changed

+279
-68
lines changed

5 files changed

+279
-68
lines changed

internal/operator-controller/applier/boxcutter_test.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,15 @@ import (
2424
"sigs.k8s.io/controller-runtime/pkg/client"
2525
"sigs.k8s.io/controller-runtime/pkg/client/fake"
2626

27+
"github.com/operator-framework/api/pkg/operators/v1alpha1"
28+
2729
ocv1 "github.com/operator-framework/operator-controller/api/v1"
2830
"github.com/operator-framework/operator-controller/internal/operator-controller/applier"
2931
"github.com/operator-framework/operator-controller/internal/operator-controller/controllers"
3032
"github.com/operator-framework/operator-controller/internal/operator-controller/labels"
3133
"github.com/operator-framework/operator-controller/internal/operator-controller/rukpak/bundle"
3234
"github.com/operator-framework/operator-controller/internal/operator-controller/rukpak/render"
33-
testutils "github.com/operator-framework/operator-controller/internal/operator-controller/rukpak/util/testing"
35+
. "github.com/operator-framework/operator-controller/internal/operator-controller/rukpak/util/testing"
3436
)
3537

3638
func Test_RegistryV1BundleRenderer_Render_Success(t *testing.T) {
@@ -52,7 +54,10 @@ func Test_RegistryV1BundleRenderer_Render_Success(t *testing.T) {
5254
},
5355
},
5456
}
55-
bundleFS := testutils.NewBundleFS()
57+
58+
bundleFS := NewBundleFS(
59+
WithPackageName("some-package"),
60+
WithCSV(MakeCSV(WithInstallModeSupportFor(v1alpha1.InstallModeTypeAllNamespaces))))
5661

5762
objs, err := r.Render(bundleFS, &ocv1.ClusterExtension{
5863
Spec: ocv1.ClusterExtensionSpec{
@@ -74,7 +79,9 @@ func Test_RegistryV1BundleRenderer_Render_Failure(t *testing.T) {
7479
},
7580
},
7681
}
77-
bundleFS := testutils.NewBundleFS()
82+
bundleFS := NewBundleFS(
83+
WithPackageName("some-package"),
84+
WithCSV(MakeCSV(WithInstallModeSupportFor(v1alpha1.InstallModeTypeAllNamespaces))))
7885

7986
objs, err := r.Render(bundleFS, &ocv1.ClusterExtension{
8087
Spec: ocv1.ClusterExtensionSpec{

internal/operator-controller/rukpak/bundle/source/source.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ type BundleSource interface {
2424
GetBundle() (bundle.RegistryV1, error)
2525
}
2626

27+
type RegistryV1Properties struct {
28+
Properties []property.Property `json:"properties"`
29+
}
30+
2731
// identitySource is a bundle source that returns itself
2832
type identitySource bundle.RegistryV1
2933

@@ -158,11 +162,7 @@ func copyMetadataPropertiesToCSV(csv *v1alpha1.ClusterServiceVersion, fsys fs.FS
158162

159163
// Otherwise, we need to parse the properties.yaml file and
160164
// append its properties into the CSV annotation.
161-
type registryV1Properties struct {
162-
Properties []property.Property `json:"properties"`
163-
}
164-
165-
var metadataProperties registryV1Properties
165+
var metadataProperties RegistryV1Properties
166166
if err := yaml.Unmarshal(metadataPropertiesJSON, &metadataProperties); err != nil {
167167
return fmt.Errorf("failed to unmarshal metadata/properties.yaml: %w", err)
168168
}

internal/operator-controller/rukpak/bundle/source/source_test.go

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@ package source_test
22

33
import (
44
"io/fs"
5-
"strings"
65
"testing"
7-
"testing/fstest"
86

97
"github.com/stretchr/testify/require"
8+
corev1 "k8s.io/api/core/v1"
9+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10+
"k8s.io/utils/ptr"
11+
12+
"github.com/operator-framework/api/pkg/operators/v1alpha1"
1013

1114
"github.com/operator-framework/operator-controller/internal/operator-controller/rukpak/bundle"
1215
"github.com/operator-framework/operator-controller/internal/operator-controller/rukpak/bundle/source"
@@ -27,7 +30,19 @@ func Test_FromBundle_Success(t *testing.T) {
2730
}
2831

2932
func Test_FromFS_Success(t *testing.T) {
30-
rv1, err := source.FromFS(NewBundleFS()).GetBundle()
33+
bundleFS := NewBundleFS(
34+
WithPackageName("test"),
35+
WithBundleProperty("from-file-key", "from-file-value"),
36+
WithBundleResource("csv.yaml", ptr.To(MakeCSV(
37+
WithName("test.v1.0.0"),
38+
WithAnnotations(map[string]string{
39+
"olm.properties": `[{"type":"from-csv-annotations-key", "value":"from-csv-annotations-value"}]`,
40+
}),
41+
WithInstallModeSupportFor(v1alpha1.InstallModeTypeAllNamespaces)),
42+
)),
43+
)
44+
45+
rv1, err := source.FromFS(bundleFS).GetBundle()
3146
require.NoError(t, err)
3247

3348
t.Log("Check package name is correctly taken from metadata/annotations.yaml")
@@ -44,16 +59,34 @@ func Test_FromFS_Fails(t *testing.T) {
4459
}{
4560
{
4661
name: "bundle missing ClusterServiceVersion manifest",
47-
FS: removePaths(NewBundleFS(), BundlePathCSV),
62+
FS: NewBundleFS(
63+
WithPackageName("test"),
64+
WithBundleProperty("foo", "bar"),
65+
WithBundleResource("service.yaml", &corev1.Service{
66+
TypeMeta: metav1.TypeMeta{
67+
Kind: "Service",
68+
APIVersion: corev1.SchemeGroupVersion.String(),
69+
},
70+
}),
71+
),
4872
}, {
4973
name: "bundle missing metadata/annotations.yaml",
50-
FS: removePaths(NewBundleFS(), BundlePathAnnotations),
74+
FS: NewBundleFS(
75+
WithBundleProperty("foo", "bar"),
76+
WithBundleResource("csv.yaml", ptr.To(MakeCSV())),
77+
),
5178
}, {
52-
name: "bundle missing metadata/ directory",
53-
FS: removePaths(NewBundleFS(), "metadata/"),
79+
name: "metadata/annotations.yaml missing package name annotation",
80+
FS: NewBundleFS(
81+
WithBundleProperty("foo", "bar"),
82+
WithBundleResource("csv.yaml", ptr.To(MakeCSV())),
83+
),
5484
}, {
55-
name: "bundle missing manifests/ directory",
56-
FS: removePaths(NewBundleFS(), "manifests/"),
85+
name: "bundle missing manifests directory",
86+
FS: NewBundleFS(
87+
WithPackageName("test"),
88+
WithBundleProperty("foo", "bar"),
89+
),
5790
},
5891
} {
5992
t.Run(tt.name, func(t *testing.T) {
@@ -62,14 +95,3 @@ func Test_FromFS_Fails(t *testing.T) {
6295
})
6396
}
6497
}
65-
66-
func removePaths(mapFs fstest.MapFS, paths ...string) fstest.MapFS {
67-
for k := range mapFs {
68-
for _, path := range paths {
69-
if strings.HasPrefix(k, path) {
70-
delete(mapFs, k)
71-
}
72-
}
73-
}
74-
return mapFs
75-
}

internal/operator-controller/rukpak/util/testing/bundlefs.go

Lines changed: 117 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -8,57 +8,134 @@ import (
88

99
"sigs.k8s.io/controller-runtime/pkg/client"
1010
"sigs.k8s.io/yaml"
11+
12+
"github.com/operator-framework/api/pkg/operators/v1alpha1"
13+
"github.com/operator-framework/operator-registry/alpha/property"
14+
15+
"github.com/operator-framework/operator-controller/internal/operator-controller/rukpak/bundle/source"
16+
registry "github.com/operator-framework/operator-controller/internal/operator-controller/rukpak/operator-registry"
1117
)
1218

1319
const (
1420
BundlePathAnnotations = "metadata/annotations.yaml"
1521
BundlePathProperties = "metadata/properties.yaml"
1622
BundlePathManifests = "manifests"
17-
BundlePathCSV = BundlePathManifests + "/csv.yaml"
1823
)
1924

20-
func NewBundleFS() fstest.MapFS {
21-
annotationsYml := `
22-
annotations:
23-
operators.operatorframework.io.bundle.mediatype.v1: registry+v1
24-
operators.operatorframework.io.bundle.package.v1: test
25-
`
26-
27-
propertiesYml := `
28-
properties:
29-
- type: "from-file-key"
30-
value: "from-file-value"
31-
`
32-
33-
csvYml := `
34-
apiVersion: operators.operatorframework.io/v1alpha1
35-
kind: ClusterServiceVersion
36-
metadata:
37-
name: test.v1.0.0
38-
annotations:
39-
olm.properties: '[{"type":"from-csv-annotations-key", "value":"from-csv-annotations-value"}]'
40-
spec:
41-
installModes:
42-
- type: AllNamespaces
43-
supported: true
44-
`
45-
46-
return fstest.MapFS{
47-
BundlePathAnnotations: &fstest.MapFile{Data: []byte(strings.Trim(annotationsYml, "\n"))},
48-
BundlePathProperties: &fstest.MapFile{Data: []byte(strings.Trim(propertiesYml, "\n"))},
49-
BundlePathCSV: &fstest.MapFile{Data: []byte(strings.Trim(csvYml, "\n"))},
25+
type bundleData struct {
26+
annotations *registry.Annotations
27+
properties []property.Property
28+
resources map[string]client.Object
29+
}
30+
31+
type BundleFSOption func(*bundleData)
32+
33+
// WithPackageName is an option for NewBundleFS used to set the package name annotation in the
34+
// bundle filesystem metadata/annotations.yaml file
35+
func WithPackageName(packageName string) BundleFSOption {
36+
return func(data *bundleData) {
37+
if data.annotations == nil {
38+
data.annotations = &registry.Annotations{}
39+
}
40+
data.annotations.PackageName = packageName
41+
}
42+
}
43+
44+
// WithChannels is an option for NewBundleFS used to set the channels annotation in the
45+
// bundle filesystem metadata/annotations.yaml file
46+
func WithChannels(channels ...string) BundleFSOption {
47+
return func(data *bundleData) {
48+
if data.annotations == nil {
49+
data.annotations = &registry.Annotations{}
50+
}
51+
data.annotations.Channels = strings.Join(channels, ",")
52+
}
53+
}
54+
55+
// WithDefaultChannel is an option for NewBundleFS used to set the channel annotation in the
56+
// bundle filesystem metadata/annotations.yaml file
57+
func WithDefaultChannel(channel string) BundleFSOption {
58+
return func(data *bundleData) {
59+
if data.annotations == nil {
60+
data.annotations = &registry.Annotations{}
61+
}
62+
data.annotations.DefaultChannelName = channel
63+
}
64+
}
65+
66+
// WithBundleProperty is an options for NewBundleFS used to add a property to the list of properties
67+
// in the bundle filesystem metadata/properties.yaml file
68+
func WithBundleProperty(propertyType string, value string) BundleFSOption {
69+
return func(data *bundleData) {
70+
data.properties = append(data.properties, property.Property{
71+
Type: propertyType,
72+
Value: []byte(`"` + value + `"`),
73+
})
5074
}
5175
}
5276

53-
func AddManifest(bundleFS fstest.MapFS, obj client.Object) error {
54-
gvk := obj.GetObjectKind().GroupVersionKind()
55-
manifestName := fmt.Sprintf("%s%s_%s_%s%s.yaml", gvk.Group, gvk.Version, gvk.Kind, obj.GetNamespace(), obj.GetName())
56-
bytes, err := yaml.Marshal(obj)
57-
if err != nil {
58-
return err
77+
// WithBundleResource is an option for NewBundleFS use to add the yaml representation of resource to the
78+
// path manifests/<resourceName>.yaml on the bundles filesystem
79+
func WithBundleResource(resourceName string, resource client.Object) BundleFSOption {
80+
return func(data *bundleData) {
81+
if data.resources == nil {
82+
data.resources = make(map[string]client.Object)
83+
}
84+
data.resources[resourceName] = resource
5985
}
60-
bundleFS[filepath.Join(BundlePathManifests, manifestName)] = &fstest.MapFile{
61-
Data: bytes,
86+
}
87+
88+
// WithCSV is an optiona for NewBundleFS used to add the yaml representation of csv to the
89+
// path manifests/csv.yaml on the bundle filesystem
90+
func WithCSV(csv v1alpha1.ClusterServiceVersion) BundleFSOption {
91+
return func(data *bundleData) {
92+
if data.resources == nil {
93+
data.resources = make(map[string]client.Object)
94+
}
95+
data.resources["csv.yaml"] = &csv
6296
}
63-
return nil
97+
}
98+
99+
// NewBundleFS creates a registry+v1 bundle filesystem with the applied options
100+
// By default, an empty registry+v1 bundle filesystem will be returned
101+
func NewBundleFS(opts ...BundleFSOption) fstest.MapFS {
102+
bundleData := &bundleData{}
103+
for _, applyOpt := range opts {
104+
applyOpt(bundleData)
105+
}
106+
bundleFS := fstest.MapFS{}
107+
108+
// Add annotations metadata
109+
if bundleData.annotations != nil {
110+
annotationsYml, err := yaml.Marshal(registry.AnnotationsFile{
111+
Annotations: *bundleData.annotations,
112+
})
113+
if err != nil {
114+
panic(fmt.Errorf("error building bundle fs: %w", err))
115+
}
116+
bundleFS[BundlePathAnnotations] = &fstest.MapFile{Data: annotationsYml}
117+
}
118+
119+
// Add property metadata
120+
if len(bundleData.properties) > 0 {
121+
propertiesYml, err := yaml.Marshal(source.RegistryV1Properties{
122+
Properties: bundleData.properties,
123+
})
124+
if err != nil {
125+
panic(fmt.Errorf("error building bundle fs: %w", err))
126+
}
127+
bundleFS[BundlePathProperties] = &fstest.MapFile{Data: propertiesYml}
128+
}
129+
130+
// Add resources
131+
for name, obj := range bundleData.resources {
132+
resourcePath := filepath.Join(BundlePathManifests, name)
133+
resourceYml, err := yaml.Marshal(obj)
134+
if err != nil {
135+
panic(fmt.Errorf("error building bundle fs: %w", err))
136+
}
137+
bundleFS[resourcePath] = &fstest.MapFile{Data: resourceYml}
138+
}
139+
140+
return bundleFS
64141
}

0 commit comments

Comments
 (0)