Skip to content

Commit c9749f9

Browse files
authored
fix TestClusterExtensionInstallReResolvesWhenNewCataloge2e test (#1008)
Signed-off-by: yashoza19 <[email protected]>
1 parent 422a740 commit c9749f9

File tree

11 files changed

+143
-108
lines changed

11 files changed

+143
-108
lines changed

Makefile

+11-7
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,11 @@ E2E_REGISTRY_NAME := docker-registry
129129
E2E_REGISTRY_NAMESPACE := operator-controller-e2e
130130

131131
export REG_PKG_NAME := registry-operator
132-
export REGISTRY_ROOT := $(E2E_REGISTRY_NAME).$(E2E_REGISTRY_NAMESPACE).svc:5000
133-
export CATALOG_IMG := $(REGISTRY_ROOT)/e2e/test-catalog:e2e
132+
export LOCAL_REGISTRY_HOST := $(E2E_REGISTRY_NAME).$(E2E_REGISTRY_NAMESPACE).svc:5000
133+
export CLUSTER_REGISTRY_HOST := localhost:30000
134+
export E2E_TEST_CATALOG_V1 := e2e/test-catalog:v1
135+
export E2E_TEST_CATALOG_V2 := e2e/test-catalog:v2
136+
export CATALOG_IMG := $(LOCAL_REGISTRY_HOST)/$(E2E_TEST_CATALOG_V1)
134137
.PHONY: test-ext-dev-e2e
135138
test-ext-dev-e2e: $(OPERATOR_SDK) $(KUSTOMIZE) $(KIND) #HELP Run extension create, upgrade and delete tests.
136139
test/extension-developer-e2e/setup.sh $(OPERATOR_SDK) $(CONTAINER_RUNTIME) $(KUSTOMIZE) $(KIND) $(KIND_CLUSTER_NAME) $(E2E_REGISTRY_NAMESPACE)
@@ -148,7 +151,8 @@ image-registry: ## Setup in-cluster image registry
148151
./test/tools/image-registry.sh $(E2E_REGISTRY_NAMESPACE) $(E2E_REGISTRY_NAME)
149152

150153
build-push-e2e-catalog: ## Build the testdata catalog used for e2e tests and push it to the image registry
151-
./test/tools/build-push-e2e-catalog.sh $(E2E_REGISTRY_NAMESPACE) $(CATALOG_IMG)
154+
./test/tools/build-push-e2e-catalog.sh $(E2E_REGISTRY_NAMESPACE) $(LOCAL_REGISTRY_HOST)/$(E2E_TEST_CATALOG_V1)
155+
./test/tools/build-push-e2e-catalog.sh $(E2E_REGISTRY_NAMESPACE) $(LOCAL_REGISTRY_HOST)/$(E2E_TEST_CATALOG_V2)
152156

153157
# When running the e2e suite, you can set the ARTIFACT_PATH variable to the absolute path
154158
# of the directory for the operator-controller e2e tests to store the artifacts, which
@@ -209,10 +213,10 @@ kind-clean: $(KIND) #EXHELP Delete the kind cluster.
209213
$(KIND) delete cluster --name $(KIND_CLUSTER_NAME)
210214

211215
registry-load-bundles: ## Load selected e2e testdata container images created in kind-load-bundles into registry
212-
testdata/bundles/registry-v1/build-push-e2e-bundle.sh ${E2E_REGISTRY_NAMESPACE} $(REGISTRY_ROOT)/bundles/registry-v1/prometheus-operator:v1.0.0 prometheus-operator.v1.0.0 prometheus-operator.v1.0.0
213-
testdata/bundles/registry-v1/build-push-e2e-bundle.sh ${E2E_REGISTRY_NAMESPACE} $(REGISTRY_ROOT)/bundles/registry-v1/prometheus-operator:v1.0.1 prometheus-operator.v1.0.1 prometheus-operator.v1.0.0
214-
testdata/bundles/registry-v1/build-push-e2e-bundle.sh ${E2E_REGISTRY_NAMESPACE} $(REGISTRY_ROOT)/bundles/registry-v1/prometheus-operator:v1.2.0 prometheus-operator.v1.2.0 prometheus-operator.v1.0.0
215-
testdata/bundles/registry-v1/build-push-e2e-bundle.sh ${E2E_REGISTRY_NAMESPACE} $(REGISTRY_ROOT)/bundles/registry-v1/prometheus-operator:v2.0.0 prometheus-operator.v2.0.0 prometheus-operator.v1.0.0
216+
testdata/bundles/registry-v1/build-push-e2e-bundle.sh ${E2E_REGISTRY_NAMESPACE} $(LOCAL_REGISTRY_HOST)/bundles/registry-v1/prometheus-operator:v1.0.0 prometheus-operator.v1.0.0 prometheus-operator.v1.0.0
217+
testdata/bundles/registry-v1/build-push-e2e-bundle.sh ${E2E_REGISTRY_NAMESPACE} $(LOCAL_REGISTRY_HOST)/bundles/registry-v1/prometheus-operator:v1.0.1 prometheus-operator.v1.0.1 prometheus-operator.v1.0.0
218+
testdata/bundles/registry-v1/build-push-e2e-bundle.sh ${E2E_REGISTRY_NAMESPACE} $(LOCAL_REGISTRY_HOST)/bundles/registry-v1/prometheus-operator:v1.2.0 prometheus-operator.v1.2.0 prometheus-operator.v1.0.0
219+
testdata/bundles/registry-v1/build-push-e2e-bundle.sh ${E2E_REGISTRY_NAMESPACE} $(LOCAL_REGISTRY_HOST)/bundles/registry-v1/prometheus-operator:v2.0.0 prometheus-operator.v2.0.0 prometheus-operator.v1.0.0
216220

217221
#SECTION Build
218222

test/e2e/cluster_extension_install_test.go

+80-70
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"testing"
1111
"time"
1212

13+
"github.com/google/go-containerregistry/pkg/crane"
1314
"github.com/stretchr/testify/assert"
1415
"github.com/stretchr/testify/require"
1516
"gopkg.in/yaml.v2"
@@ -94,7 +95,7 @@ func TestClusterExtensionInstallRegistry(t *testing.T) {
9495
assert.Equal(ct, metav1.ConditionTrue, cond.Status)
9596
assert.Equal(ct, ocv1alpha1.ReasonSuccess, cond.Reason)
9697
assert.Contains(ct, cond.Message, "resolved to")
97-
assert.Equal(ct, &ocv1alpha1.BundleMetadata{Name: "prometheus-operator.2.0.0", Version: "2.0.0"}, clusterExtension.Status.ResolvedBundle)
98+
assert.Equal(ct, &ocv1alpha1.BundleMetadata{Name: "prometheus-operator.1.2.0", Version: "1.2.0"}, clusterExtension.Status.ResolvedBundle)
9899
}, pollDuration, pollInterval)
99100

100101
t.Log("By eventually reporting a successful unpacked")
@@ -123,75 +124,6 @@ func TestClusterExtensionInstallRegistry(t *testing.T) {
123124
}, pollDuration, pollInterval)
124125
}
125126

126-
func TestClusterExtensionInstallReResolvesWhenNewCatalog(t *testing.T) {
127-
t.Log("When a cluster extension is installed from a catalog")
128-
t.Log("It resolves again when a new catalog is available")
129-
130-
clusterExtension, extensionCatalog := testInit(t)
131-
defer testCleanup(t, extensionCatalog, clusterExtension)
132-
defer getArtifactsOutput(t)
133-
134-
pkgName := "prometheus"
135-
clusterExtension.Spec = ocv1alpha1.ClusterExtensionSpec{
136-
PackageName: pkgName,
137-
InstallNamespace: "default",
138-
ServiceAccount: ocv1alpha1.ServiceAccountReference{
139-
Name: "default",
140-
},
141-
}
142-
143-
t.Log("By deleting the catalog first")
144-
require.NoError(t, c.Delete(context.Background(), extensionCatalog))
145-
require.EventuallyWithT(t, func(ct *assert.CollectT) {
146-
err := c.Get(context.Background(), types.NamespacedName{Name: extensionCatalog.Name}, &catalogd.ClusterCatalog{})
147-
assert.True(ct, errors.IsNotFound(err))
148-
}, pollDuration, pollInterval)
149-
150-
t.Log("By creating the ClusterExtension resource")
151-
require.NoError(t, c.Create(context.Background(), clusterExtension))
152-
153-
// TODO: this isn't a good precondition because a missing package results in
154-
// exponential backoff retries. So we can't be sure that the re-reconcile is a result of
155-
// the catalog becoming available because it could also be a retry of the initial failed
156-
// resolution.
157-
t.Log("By failing to find ClusterExtension during resolution")
158-
require.EventuallyWithT(t, func(ct *assert.CollectT) {
159-
assert.NoError(ct, c.Get(context.Background(), types.NamespacedName{Name: clusterExtension.Name}, clusterExtension))
160-
cond := apimeta.FindStatusCondition(clusterExtension.Status.Conditions, ocv1alpha1.TypeResolved)
161-
if !assert.NotNil(ct, cond) {
162-
return
163-
}
164-
assert.Equal(ct, metav1.ConditionFalse, cond.Status)
165-
assert.Equal(ct, ocv1alpha1.ReasonResolutionFailed, cond.Reason)
166-
assert.Contains(ct, cond.Message, fmt.Sprintf("no package %q found", pkgName))
167-
}, pollDuration, pollInterval)
168-
169-
t.Log("By creating an ClusterExtension catalog with the desired package")
170-
var err error
171-
extensionCatalog, err = createTestCatalog(context.Background(), testCatalogName, os.Getenv(testCatalogRefEnvVar))
172-
require.NoError(t, err)
173-
require.EventuallyWithT(t, func(ct *assert.CollectT) {
174-
assert.NoError(ct, c.Get(context.Background(), types.NamespacedName{Name: extensionCatalog.Name}, extensionCatalog))
175-
cond := apimeta.FindStatusCondition(extensionCatalog.Status.Conditions, catalogd.TypeUnpacked)
176-
if !assert.NotNil(ct, cond) {
177-
return
178-
}
179-
assert.Equal(ct, metav1.ConditionTrue, cond.Status)
180-
assert.Equal(ct, catalogd.ReasonUnpackSuccessful, cond.Reason)
181-
}, pollDuration, pollInterval)
182-
183-
t.Log("By eventually resolving the package successfully")
184-
require.EventuallyWithT(t, func(ct *assert.CollectT) {
185-
assert.NoError(ct, c.Get(context.Background(), types.NamespacedName{Name: clusterExtension.Name}, clusterExtension))
186-
cond := apimeta.FindStatusCondition(clusterExtension.Status.Conditions, ocv1alpha1.TypeResolved)
187-
if !assert.NotNil(ct, cond) {
188-
return
189-
}
190-
assert.Equal(ct, metav1.ConditionTrue, cond.Status)
191-
assert.Equal(ct, ocv1alpha1.ReasonSuccess, cond.Reason)
192-
}, pollDuration, pollInterval)
193-
}
194-
195127
func TestClusterExtensionBlockInstallNonSuccessorVersion(t *testing.T) {
196128
t.Log("When a cluster extension is installed from a catalog")
197129
t.Log("When resolving upgrade edges")
@@ -337,6 +269,84 @@ func TestClusterExtensionInstallSuccessorVersion(t *testing.T) {
337269
}, pollDuration, pollInterval)
338270
}
339271

272+
func TestClusterExtensionInstallReResolvesWhenNewCatalog(t *testing.T) {
273+
t.Log("When a cluster extension is installed from a catalog")
274+
t.Log("It resolves again when a new catalog is available")
275+
276+
// Tag the image with the new tag
277+
var err error
278+
v1Image := fmt.Sprintf("%s/%s", os.Getenv("CLUSTER_REGISTRY_HOST"), os.Getenv("E2E_TEST_CATALOG_V1"))
279+
err = crane.Tag(v1Image, latestImageTag, crane.Insecure)
280+
require.NoError(t, err)
281+
282+
// create a test-catalog with latest image tag
283+
latestCatalogImage := fmt.Sprintf("%s/e2e/test-catalog:latest", os.Getenv("LOCAL_REGISTRY_HOST"))
284+
extensionCatalog, err := createTestCatalog(context.Background(), testCatalogName, latestCatalogImage)
285+
require.NoError(t, err)
286+
clusterExtensionName := fmt.Sprintf("clusterextension-%s", rand.String(8))
287+
clusterExtension := &ocv1alpha1.ClusterExtension{
288+
ObjectMeta: metav1.ObjectMeta{
289+
Name: clusterExtensionName,
290+
},
291+
}
292+
defer testCleanup(t, extensionCatalog, clusterExtension)
293+
defer getArtifactsOutput(t)
294+
295+
clusterExtension.Spec = ocv1alpha1.ClusterExtensionSpec{
296+
PackageName: "prometheus",
297+
InstallNamespace: "default",
298+
ServiceAccount: ocv1alpha1.ServiceAccountReference{
299+
Name: "default",
300+
},
301+
}
302+
t.Log("It resolves the specified package with correct bundle path")
303+
t.Log("By creating the ClusterExtension resource")
304+
require.NoError(t, c.Create(context.Background(), clusterExtension))
305+
306+
t.Log("By reporting a successful resolution and bundle path")
307+
require.EventuallyWithT(t, func(ct *assert.CollectT) {
308+
assert.NoError(ct, c.Get(context.Background(), types.NamespacedName{Name: clusterExtension.Name}, clusterExtension))
309+
assert.Len(ct, clusterExtension.Status.Conditions, len(conditionsets.ConditionTypes))
310+
cond := apimeta.FindStatusCondition(clusterExtension.Status.Conditions, ocv1alpha1.TypeResolved)
311+
if !assert.NotNil(ct, cond) {
312+
return
313+
}
314+
assert.Equal(ct, metav1.ConditionTrue, cond.Status)
315+
assert.Equal(ct, ocv1alpha1.ReasonSuccess, cond.Reason)
316+
assert.Contains(ct, cond.Message, "resolved to")
317+
assert.Equal(ct, &ocv1alpha1.BundleMetadata{Name: "prometheus-operator.1.2.0", Version: "1.2.0"}, clusterExtension.Status.ResolvedBundle)
318+
}, pollDuration, pollInterval)
319+
320+
// update tag on test-catalog image with v2 image
321+
t.Log("By updating the catalog tag to point to the v2 catalog")
322+
v2Image := fmt.Sprintf("%s/%s", os.Getenv("CLUSTER_REGISTRY_HOST"), os.Getenv("E2E_TEST_CATALOG_V2"))
323+
err = crane.Tag(v2Image, latestImageTag, crane.Insecure)
324+
require.NoError(t, err)
325+
require.EventuallyWithT(t, func(ct *assert.CollectT) {
326+
assert.NoError(ct, c.Get(context.Background(), types.NamespacedName{Name: extensionCatalog.Name}, extensionCatalog))
327+
cond := apimeta.FindStatusCondition(extensionCatalog.Status.Conditions, catalogd.TypeUnpacked)
328+
if !assert.NotNil(ct, cond) {
329+
return
330+
}
331+
assert.Equal(ct, metav1.ConditionTrue, cond.Status)
332+
assert.Equal(ct, catalogd.ReasonUnpackSuccessful, cond.Reason)
333+
}, pollDuration, pollInterval)
334+
335+
t.Log("By eventually reporting a successful resolution and bundle path")
336+
require.EventuallyWithT(t, func(ct *assert.CollectT) {
337+
assert.NoError(ct, c.Get(context.Background(), types.NamespacedName{Name: clusterExtension.Name}, clusterExtension))
338+
assert.Len(ct, clusterExtension.Status.Conditions, len(conditionsets.ConditionTypes))
339+
cond := apimeta.FindStatusCondition(clusterExtension.Status.Conditions, ocv1alpha1.TypeResolved)
340+
if !assert.NotNil(ct, cond) {
341+
return
342+
}
343+
assert.Equal(ct, metav1.ConditionTrue, cond.Status)
344+
assert.Equal(ct, ocv1alpha1.ReasonSuccess, cond.Reason)
345+
assert.Contains(ct, cond.Message, "resolved to")
346+
assert.Equal(ct, &ocv1alpha1.BundleMetadata{Name: "prometheus-operator.2.0.0", Version: "2.0.0"}, clusterExtension.Status.ResolvedBundle)
347+
}, pollDuration, pollInterval)
348+
}
349+
340350
// getArtifactsOutput gets all the artifacts from the test run and saves them to the artifact path.
341351
// Currently it saves:
342352
// - clusterextensions

test/e2e/e2e_suite_test.go

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"os"
66
"testing"
7+
"time"
78

89
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
910
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
@@ -24,6 +25,7 @@ var (
2425
const (
2526
testCatalogRefEnvVar = "CATALOG_IMG"
2627
testCatalogName = "test-catalog"
28+
latestImageTag = "latest"
2729
)
2830

2931
func TestMain(m *testing.M) {
@@ -50,6 +52,7 @@ func createTestCatalog(ctx context.Context, name string, imageRef string) (*cata
5052
Image: &catalogd.ImageSource{
5153
Ref: imageRef,
5254
InsecureSkipTLSVerify: true,
55+
PollInterval: &metav1.Duration{Duration: time.Second},
5356
},
5457
},
5558
},

test/extension-developer-e2e/setup.sh

+4-4
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ a KinD cluster with the name specified in the arguments.
1313
The following environment variables are required for configuring this script:
1414
- \$CATALOG_IMG - the tag for the catalog image that contains the registry+v1 bundle.
1515
- \$REG_PKG_NAME - the name of the package for the extension that uses the registry+v1 bundle format.
16-
- \$REGISTRY_ROOT - hostname:port of the local docker-registry
16+
- \$LOCAL_REGISTRY_HOST - hostname:port of the local docker-registry
1717
setup.sh also takes 5 arguments.
1818
1919
Usage:
@@ -42,8 +42,8 @@ if [[ -z "${REG_PKG_NAME}" ]]; then
4242
exit 1
4343
fi
4444

45-
if [[ -z "${REGISTRY_ROOT}" ]]; then
46-
echo "\$REGISTRY_ROOT is required to be set"
45+
if [[ -z "${LOCAL_REGISTRY_HOST}" ]]; then
46+
echo "\$LOCAL_REGISTRY_HOST is required to be set"
4747
echo "${help}"
4848
exit 1
4949
fi
@@ -69,7 +69,7 @@ kcluster_name=$5
6969
namespace=$6
7070

7171
reg_img="${DOMAIN}/registry:v0.0.1"
72-
reg_bundle_img="${REGISTRY_ROOT}/bundles/registry-v1/registry-bundle:v0.0.1"
72+
reg_bundle_img="${LOCAL_REGISTRY_HOST}/bundles/registry-v1/registry-bundle:v0.0.1"
7373

7474
catalog_img="${CATALOG_IMG}"
7575
reg_pkg_name="${REG_PKG_NAME}"

test/tools/build-push-e2e-catalog.sh

+15-14
Original file line numberDiff line numberDiff line change
@@ -21,45 +21,46 @@ if [[ "$#" -ne 2 ]]; then
2121
fi
2222

2323
namespace=$1
24-
tag=$2
24+
image=$2
25+
tag=${image##*:}
2526

26-
echo "${namespace}" "${tag}"
27+
echo "${namespace}" "${image}" "${tag}"
2728

28-
kubectl create configmap -n "${namespace}" --from-file=testdata/catalogs/test-catalog.Dockerfile operator-controller-e2e.dockerfile
29-
kubectl create configmap -n "${namespace}" --from-file=testdata/catalogs/test-catalog operator-controller-e2e.build-contents
29+
kubectl create configmap -n "${namespace}" --from-file=testdata/catalogs/test-catalog-${tag}.Dockerfile operator-controller-e2e-${tag}.dockerfile
30+
kubectl create configmap -n "${namespace}" --from-file=testdata/catalogs/test-catalog-${tag} operator-controller-e2e-${tag}.build-contents
3031

3132
kubectl apply -f - << EOF
3233
apiVersion: batch/v1
3334
kind: Job
3435
metadata:
35-
name: kaniko
36+
name: "kaniko-${tag}"
3637
namespace: "${namespace}"
3738
spec:
3839
template:
3940
spec:
4041
containers:
41-
- name: kaniko
42+
- name: kaniko-${tag}
4243
image: gcr.io/kaniko-project/executor:latest
43-
args: ["--dockerfile=/workspace/test-catalog.Dockerfile",
44+
args: ["--dockerfile=/workspace/test-catalog-${tag}.Dockerfile",
4445
"--context=/workspace/",
45-
"--destination=${tag}",
46+
"--destination=${image}",
4647
"--skip-tls-verify"]
4748
volumeMounts:
4849
- name: dockerfile
4950
mountPath: /workspace/
5051
- name: build-contents
51-
mountPath: /workspace/test-catalog/
52+
mountPath: /workspace/test-catalog-${tag}/
5253
restartPolicy: Never
5354
volumes:
5455
- name: dockerfile
5556
configMap:
56-
name: operator-controller-e2e.dockerfile
57+
name: operator-controller-e2e-${tag}.dockerfile
5758
items:
58-
- key: test-catalog.Dockerfile
59-
path: test-catalog.Dockerfile
59+
- key: test-catalog-${tag}.Dockerfile
60+
path: test-catalog-${tag}.Dockerfile
6061
- name: build-contents
6162
configMap:
62-
name: operator-controller-e2e.build-contents
63+
name: operator-controller-e2e-${tag}.build-contents
6364
EOF
6465

65-
kubectl wait --for=condition=Complete -n "${namespace}" jobs/kaniko --timeout=60s
66+
kubectl wait --for=condition=Complete -n "${namespace}" jobs/kaniko-${tag} --timeout=60s

testdata/catalogs/test-catalog.Dockerfile renamed to testdata/catalogs/test-catalog-v1.Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
FROM scratch
2-
ADD test-catalog /configs
2+
ADD test-catalog-v1 /configs
33

44
# Set DC-specific label for the location of the DC root directory
55
# in the image

testdata/catalogs/test-catalog/catalog.yaml renamed to testdata/catalogs/test-catalog-v1/catalog.yaml

-12
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ entries:
1818
replaces: prometheus-operator.1.0.0
1919
- name: prometheus-operator.1.2.0
2020
replaces: prometheus-operator.1.0.1
21-
- name: prometheus-operator.2.0.0
22-
replaces: prometheus-operator.1.2.0
2321
---
2422
schema: olm.bundle
2523
name: prometheus-operator.1.0.0
@@ -50,13 +48,3 @@ properties:
5048
value:
5149
packageName: prometheus
5250
version: 1.2.0
53-
---
54-
schema: olm.bundle
55-
name: prometheus-operator.2.0.0
56-
package: prometheus
57-
image: docker-registry.operator-controller-e2e.svc.cluster.local:5000/bundles/registry-v1/prometheus-operator:v2.0.0
58-
properties:
59-
- type: olm.package
60-
value:
61-
packageName: prometheus
62-
version: 2.0.0
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
FROM scratch
2+
ADD test-catalog-v2 /configs
3+
4+
# Set DC-specific label for the location of the DC root directory
5+
# in the image
6+
LABEL operators.operatorframework.io.index.configs.v1=/configs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/expected_all.json
2+
..*
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
---
2+
schema: olm.package
3+
name: prometheus
4+
defaultChannel: beta
5+
---
6+
schema: olm.channel
7+
name: beta
8+
package: prometheus
9+
entries:
10+
- name: prometheus-operator.2.0.0
11+
replaces: prometheus-operator.1.2.0
12+
---
13+
schema: olm.bundle
14+
name: prometheus-operator.2.0.0
15+
package: prometheus
16+
image: docker-registry.operator-controller-e2e.svc.cluster.local:5000/bundles/registry-v1/prometheus-operator:v2.0.0
17+
properties:
18+
- type: olm.package
19+
value:
20+
packageName: prometheus
21+
version: 2.0.0

0 commit comments

Comments
 (0)