diff --git a/Makefile b/Makefile index 5fa2e8f7eef..2b270f210d6 100644 --- a/Makefile +++ b/Makefile @@ -91,18 +91,18 @@ run-local-shift: rc e2e-local: values_file = test/e2e/e2e-values.yaml e2e-local: rc - ./scripts/build_local.sh - ./scripts/run_e2e_local.sh + . ./scripts/build_local.sh + . ./scripts/run_e2e_local.sh e2e-local-shift: values_file = test/e2e/e2e-values.yaml e2e-local-shift: rc - ./scripts/build_local_shift.sh - ./scripts/run_e2e_local.sh + . ./scripts/build_local_shift.sh + . ./scripts/run_e2e_local.sh e2e-local-docker: values_file = test/e2e/e2e-values.yaml e2e-local-docker: rc - ./scripts/build_local.sh - ./scripts/run_e2e_docker.sh + . ./scripts/build_local.sh + . ./scripts/run_e2e_docker.sh DEP := $(GOPATH)/bin/dep $(DEP): diff --git a/e2e-local-build.Dockerfile b/e2e-local-build.Dockerfile deleted file mode 100644 index b0dace36072..00000000000 --- a/e2e-local-build.Dockerfile +++ /dev/null @@ -1,13 +0,0 @@ -FROM golang:1.10 as builder -WORKDIR /go/src/github.com/operator-framework/operator-lifecycle-manager -COPY . . -RUN make build-coverage && cp bin/alm /bin/alm && cp bin/catalog /bin/catalog && bin/servicebroker /bin/servicebroker - -FROM alpine:latest -WORKDIR / -COPY --from=builder /go/src/github.com/operator-framework/operator-lifecycle-manager/bin/alm /bin/alm -COPY --from=builder /go/src/github.com/operator-framework/operator-lifecycle-manager/bin/catalog /bin/catalog -COPY --from=builder /go/src/github.com/operator-framework/operator-lifecycle-manager/bin/servicebroker /bin/servicebroker -COPY catalog_resources /var/catalog_resources - -CMD ["/bin/alm", "-h"] diff --git a/e2e-local-run.Dockerfile b/e2e-local-run.Dockerfile index c5d1165e9dc..67753009af4 100644 --- a/e2e-local-run.Dockerfile +++ b/e2e-local-run.Dockerfile @@ -4,6 +4,6 @@ RUN apt-get update RUN apt-get install -y jq COPY pkg pkg COPY vendor vendor -COPY e2e e2e +COPY test/e2e test/e2e RUN go test -c -o /bin/e2e ./test/e2e/... CMD ["./test/e2e/e2e.sh"] diff --git a/e2e.Dockerfile b/e2e.Dockerfile new file mode 100644 index 00000000000..f5aa22087f3 --- /dev/null +++ b/e2e.Dockerfile @@ -0,0 +1,40 @@ +FROM golang:1.10 as builder +LABEL builder=true +WORKDIR /go/src/github.com/operator-framework/operator-lifecycle-manager +RUN curl -L https://github.com/stedolan/jq/releases/download/jq-1.5/jq-linux64 -o /bin/jq +RUN chmod +x /bin/jq +COPY . . +RUN make build-coverage +RUN go test -c -o /bin/e2e ./test/e2e/... + +FROM alpine:latest as olm +LABEL olm=true +WORKDIR / +COPY --from=builder /go/src/github.com/operator-framework/operator-lifecycle-manager/bin/alm /bin/alm +EXPOSE 8080 +CMD ["/bin/alm"] + +FROM alpine:latest as catalog +LABEL catalog=true +WORKDIR / +COPY --from=builder /go/src/github.com/operator-framework/operator-lifecycle-manager/bin/catalog /bin/catalog +EXPOSE 8080 +CMD ["/bin/catalog"] + +FROM alpine:latest as broker +LABEL broker=true +WORKDIR / +COPY --from=builder /go/src/github.com/operator-framework/operator-lifecycle-manager/bin/servicebroker /bin/servicebroker +EXPOSE 8080 +EXPOSE 8005 +CMD ["/bin/servicebroker"] + +FROM golang:1.10 +LABEL e2e=true +RUN mkdir -p /var/e2e +WORKDIR /var/e2e +COPY --from=builder /bin/e2e /bin/e2e +COPY --from=builder /bin/jq /bin/jq +COPY ./test/e2e/e2e.sh /var/e2e/e2e.sh +COPY ./test/e2e/tap.jq /var/e2e/tap.jq +CMD ["/bin/e2e"] diff --git a/scripts/build_local.sh b/scripts/build_local.sh index ac428f265ca..8974a269ee0 100755 --- a/scripts/build_local.sh +++ b/scripts/build_local.sh @@ -8,8 +8,8 @@ set -e minikube start --extra-config=apiserver.Authorization.Mode=RBAC || { echo 'Cannot start minikube.'; exit 1; } eval $(minikube docker-env) || { echo 'Cannot switch to minikube docker'; exit 1; } kubectl config use-context minikube -docker build \ - -t quay.io/coreos/catalog:local \ - -t quay.io/coreos/olm:local \ - -t quay.io/coreos/olm-service-broker:local \ - -f e2e-local-build.Dockerfile . +docker build -f e2e.Dockerfile . +docker tag $(docker images --filter 'label=broker=true' --format '{{.CreatedAt}}\t{{.ID}}' | sort -nr | head -n 1 | cut -f2) quay.io/coreos/olm-service-broker:local +docker tag $(docker images --filter 'label=catalog=true' --format '{{.CreatedAt}}\t{{.ID}}' | sort -nr | head -n 1 | cut -f2) quay.io/coreos/catalog:local +docker tag $(docker images --filter 'label=e2e=true' --format '{{.CreatedAt}}\t{{.ID}}' | sort -nr | head -n 1 | cut -f2) quay.io/coreos/olm-e2e:local +docker tag $(docker images --filter 'label=olm=true' --format '{{.CreatedAt}}\t{{.ID}}' | sort -nr | head -n 1 | cut -f2) quay.io/coreos/olm:local diff --git a/scripts/run_e2e_docker.sh b/scripts/run_e2e_docker.sh index dc2ddb90652..ad36bff8934 100755 --- a/scripts/run_e2e_docker.sh +++ b/scripts/run_e2e_docker.sh @@ -38,20 +38,10 @@ trap cleanupAndExit SIGINT SIGTERM EXIT ./scripts/install_local.sh ${namespace} test/e2e/resources mkdir -p test/e2e/test-resources - -pushd test/e2e/chart/templates -filenames=$(ls *.yaml) -popd - -for f in ${filenames} -do - echo "Processing $f file..." - helm template --set namespace=${namespace} -f test/e2e/e2e-values.yaml -x templates/${f} test/e2e/chart > test/e2e/test-resources/${f} -done +helm template --set namespace=${namespace} -f test/e2e/e2e-values.yaml test/e2e/chart --output-dir test/e2e/test-resources eval $(minikube docker-env) || { echo 'Cannot switch to minikube docker'; exit 1; } -docker build --no-cache -t quay.io/coreos/alm-e2e:local -f e2e-local-run.Dockerfile . -kubectl apply -f test/e2e/test-resources +kubectl apply -f test/e2e/test-resources/alm-e2e/templates until kubectl -n ${namespace} logs job/e2e | grep -v "ContainerCreating"; do echo "waiting for job to run" && sleep 1; done kubectl -n ${namespace} logs job/e2e -f diff --git a/scripts/run_e2e_local.sh b/scripts/run_e2e_local.sh index 6ece7574a3e..47bcd0637ce 100755 --- a/scripts/run_e2e_local.sh +++ b/scripts/run_e2e_local.sh @@ -37,6 +37,5 @@ trap cleanupAndExit SIGINT SIGTERM EXIT ./scripts/install_local.sh ${namespace} test/e2e/resources - # run tests KUBECONFIG=~/.kube/config NAMESPACE=${namespace} go test -v ./test/e2e/... ${1/[[:alnum:]-]*/-run ${1}} diff --git a/test/e2e/csv_e2e_test.go b/test/e2e/csv_e2e_test.go index edca1901593..3d944e916f5 100644 --- a/test/e2e/csv_e2e_test.go +++ b/test/e2e/csv_e2e_test.go @@ -30,28 +30,26 @@ type cleanupFunc func() var immediateDeleteGracePeriod int64 = 0 -func buildCSVCleanupFunc(c opClient.Interface, csv v1alpha1.ClusterServiceVersion) cleanupFunc { +func buildCSVCleanupFunc(t *testing.T, c opClient.Interface, csv v1alpha1.ClusterServiceVersion, deleteCRDs bool) cleanupFunc { return func() { - err := c.DeleteCustomResource(apis.GroupName, v1alpha1.GroupVersion, testNamespace, v1alpha1.ClusterServiceVersionKind, csv.GetName()) - if err != nil { - fmt.Println(err) + require.NoError(t, c.DeleteCustomResource(apis.GroupName, v1alpha1.GroupVersion, testNamespace, v1alpha1.ClusterServiceVersionKind, csv.GetName())) + if deleteCRDs { + for _, crd := range csv.Spec.CustomResourceDefinitions.Owned { + require.NoError(t, c.DeleteCustomResourceDefinition(crd.Name, &metav1.DeleteOptions{})) + } } } } -func createCSV(c opClient.Interface, csv v1alpha1.ClusterServiceVersion) (cleanupFunc, error) { +func createCSV(t *testing.T, c opClient.Interface, csv v1alpha1.ClusterServiceVersion, cleanupCRDs bool) (cleanupFunc, error) { csv.Kind = v1alpha1.ClusterServiceVersionKind csv.APIVersion = v1alpha1.SchemeGroupVersion.String() csv.Namespace = testNamespace csvUnst, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&csv) - if err != nil { - return nil, err - } + require.NoError(t, err) err = c.CreateCustomResource(&unstructured.Unstructured{Object: csvUnst}) - if err != nil { - return nil, err - } - return buildCSVCleanupFunc(c, csv), nil + require.NoError(t, err) + return buildCSVCleanupFunc(t, c, csv, cleanupCRDs), nil } @@ -139,11 +137,14 @@ func fetchCSV(t *testing.T, c opClient.Interface, name string, checker csvCondit func waitForDeploymentToDelete(t *testing.T, c opClient.Interface, name string) error { return wait.Poll(pollInterval, pollDuration, func() (bool, error) { + t.Logf("waiting for deployment %s to delete", name) _, err := c.GetDeployment(testNamespace, name) if errors.IsNotFound(err) { + t.Logf("deleted %s", name) return true, nil } if err != nil { + t.Logf("err trying to delete %s: %s", name, err) return false, err } return false, nil @@ -213,7 +214,7 @@ func TestCreateCSVWithUnmetRequirements(t *testing.T) { }, } - cleanupCSV, err := createCSV(c, csv) + cleanupCSV, err := createCSV(t, c, csv, false) require.NoError(t, err) defer cleanupCSV() @@ -290,7 +291,7 @@ func TestCreateCSVRequirementsMet(t *testing.T) { require.NoError(t, err) defer cleanupCRD() - cleanupCSV, err := createCSV(c, csv) + cleanupCSV, err := createCSV(t, c, csv, true) require.NoError(t, err) defer cleanupCSV() @@ -388,9 +389,9 @@ func TestUpdateCSVSameDeploymentName(t *testing.T) { require.NoError(t, err) defer cleanupCRD() - cleanupCSV, err := createCSV(c, csv) + // don't need to cleanup this CSV, it will be deleted by the upgrade process + _, err = createCSV(t, c, csv, true) require.NoError(t, err) - defer cleanupCSV() // Wait for current CSV to succeed _, err = fetchCSV(t, c, csv.Name, csvSucceededChecker) @@ -465,7 +466,7 @@ func TestUpdateCSVSameDeploymentName(t *testing.T) { }, } - cleanupNewCSV, err := createCSV(c, csvNew) + cleanupNewCSV, err := createCSV(t, c, csvNew, true) require.NoError(t, err) defer cleanupNewCSV() @@ -562,9 +563,9 @@ func TestUpdateCSVDifferentDeploymentName(t *testing.T) { require.NoError(t, err) defer cleanupCRD() - cleanupCSV, err := createCSV(c, csv) + // don't need to clean up this CSV, it will be deleted by the upgrade process + _, err = createCSV(t, c, csv, true) require.NoError(t, err) - defer cleanupCSV() // Wait for current CSV to succeed _, err = fetchCSV(t, c, csv.Name, csvSucceededChecker) @@ -615,7 +616,7 @@ func TestUpdateCSVDifferentDeploymentName(t *testing.T) { }, } - cleanupNewCSV, err := createCSV(c, csvNew) + cleanupNewCSV, err := createCSV(t, c, csvNew) require.NoError(t, err) defer cleanupNewCSV() diff --git a/test/e2e/e2e-values-shift.yaml b/test/e2e/e2e-values-shift.yaml new file mode 100644 index 00000000000..28c87000afa --- /dev/null +++ b/test/e2e/e2e-values-shift.yaml @@ -0,0 +1,33 @@ +alm: + replicaCount: 1 + image: + ref: quay.io/coreos/olm:local + pullPolicy: IfNotPresent + service: + internalPort: 8080 + commandArgs: -test.coverprofile=/tmp/coverage/alm-coverage.cov + +catalog: + replicaCount: 1 + image: + ref: quay.io/coreos/catalog:local + pullPolicy: IfNotPresent + service: + internalPort: 8080 + commandArgs: -test.coverprofile=/tmp/catalog-coverage.cov + +servicebroker: + replicaCount: 1 + image: + ref: quay.io/coreos/olm-service-broker:local + pullPolicy: IfNotPresent + service: + internalPort: 8080 + brokerPort: 8005 + commandArgs: -test.coverprofile=/tmp/service-broker-coverage.cov + +e2e: + image: + ref: quay.io/coreos/olm-e2e:local + +job_name: e2e diff --git a/test/e2e/e2e-values.yaml b/test/e2e/e2e-values.yaml index 5a78b000aa6..58f86429ee7 100644 --- a/test/e2e/e2e-values.yaml +++ b/test/e2e/e2e-values.yaml @@ -16,18 +16,8 @@ catalog: internalPort: 8080 commandArgs: -test.coverprofile=/tmp/catalog-coverage.cov -servicebroker: - replicaCount: 1 - image: - ref: quay.io/coreos/alm-service-broker:local - pullPolicy: IfNotPresent - service: - internalPort: 8080 - brokerPort: 8005 - commandArgs: -test.coverprofile=/tmp/service-broker-coverage.cov - e2e: image: - ref: quay.io/coreos/alm-e2e:local + ref: quay.io/coreos/olm-e2e:local job_name: e2e diff --git a/test/e2e/subscription_e2e_test.go b/test/e2e/subscription_e2e_test.go index 4bf00498055..b4e13afd1a6 100644 --- a/test/e2e/subscription_e2e_test.go +++ b/test/e2e/subscription_e2e_test.go @@ -78,8 +78,19 @@ var ( Kind: csvv1alpha1.ClusterServiceVersionKind, APIVersion: csvv1alpha1.GroupVersion, } + + strategy = install.StrategyDetailsDeployment{ + DeploymentSpecs: []install.StrategyDeploymentSpec{ + { + Name: genName("dep-"), + Spec: newNginxDeployment(genName("nginx-")), + }, + }, + } + strategyRaw, _ = json.Marshal(strategy) installStrategy = csvv1alpha1.NamedInstallStrategy{ - StrategyName: install.InstallStrategyNameDeployment, + StrategyName: install.InstallStrategyNameDeployment, + StrategySpecRaw: strategyRaw, } outdatedCSV = csvv1alpha1.ClusterServiceVersion{ TypeMeta: csvType, @@ -207,9 +218,7 @@ func initCatalog(t *testing.T, c opClient.Interface) error { // create CatalogSource custom resource pointing to ConfigMap dummyCatalogSource.SetNamespace(testNamespace) csUnst, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&dummyCatalogSource) - if err != nil { - return err - } + require.NoError(t, err) err = c.CreateCustomResource(&unstructured.Unstructured{Object: csUnst}) if err != nil && !k8serrors.IsAlreadyExists(err) { return err @@ -245,9 +254,7 @@ func createSubscription(t *testing.T, c opClient.Interface, channel string, name func fetchSubscription(t *testing.T, c opClient.Interface, name string) (*subscriptionv1alpha1.Subscription, error) { var sub *subscriptionv1alpha1.Subscription unstrSub, err := waitForAndFetchCustomResource(t, c, subscriptionv1alpha1.GroupVersion, subscriptionv1alpha1.SubscriptionKind, name) - if err != nil { - return nil, err - } + require.NoError(t, err) err = runtime.DefaultUnstructuredConverter.FromUnstructured(unstrSub.Object, &sub) return sub, err } @@ -255,9 +262,7 @@ func fetchSubscription(t *testing.T, c opClient.Interface, name string) (*subscr func checkForCSV(t *testing.T, c opClient.Interface, name string) (*csvv1alpha1.ClusterServiceVersion, error) { var csv *csvv1alpha1.ClusterServiceVersion unstrCSV, err := waitForAndFetchCustomResource(t, c, csvv1alpha1.GroupVersion, csvv1alpha1.ClusterServiceVersionKind, name) - if err != nil { - return nil, err - } + require.NoError(t, err) err = runtime.DefaultUnstructuredConverter.FromUnstructured(unstrCSV.Object, &csv) return csv, err } @@ -265,11 +270,9 @@ func checkForCSV(t *testing.T, c opClient.Interface, name string) (*csvv1alpha1. func checkForInstallPlan(t *testing.T, c opClient.Interface, owner ownerutil.Owner) (*v1alpha1.InstallPlan, error) { var installPlan *v1alpha1.InstallPlan installPlans, err := waitForAndFetchChildren(t, c, v1alpha1.GroupVersion, v1alpha1.InstallPlanKind, owner, 1) - if err != nil { - return nil, err - } + require.NoError(t, err) err = runtime.DefaultUnstructuredConverter.FromUnstructured(installPlans[0].Object, &installPlan) - return installPlan, nil + return installPlan, err } // I. Creating a new subscription @@ -291,7 +294,7 @@ func TestCreateNewSubscription(t *testing.T) { // Deleting subscription / installplan doesn't clean up the CSV cleanupCustomResource(t, c, csvv1alpha1.GroupVersion, - csvv1alpha1.ClusterServiceVersionKind, csv.GetName()) + csvv1alpha1.ClusterServiceVersionKind, csv.GetName())() } // I. Creating a new subscription @@ -299,10 +302,9 @@ func TestCreateNewSubscription(t *testing.T) { // version func TestCreateNewSubscriptionAgain(t *testing.T) { c := newKubeClient(t) - require.NoError(t, initCatalog(t, c)) - csvCleanup, err := createCSV(c, stableCSV) + csvCleanup, err := createCSV(t, c, stableCSV) require.NoError(t, err) defer csvCleanup() @@ -319,16 +321,16 @@ func TestCreateNewSubscriptionAgain(t *testing.T) { // Deleting subscription / installplan doesn't clean up the CSV cleanupCustomResource(t, c, csvv1alpha1.GroupVersion, - csvv1alpha1.ClusterServiceVersionKind, csv.GetName()) + csvv1alpha1.ClusterServiceVersionKind, csv.GetName())() } // If installPlanApproval is set to manual, the installplans created should be created with approval: manual -func TestCreateSubscriptionManualApproval(t *testing.T) { +func TestCreateNewSubscriptionManualApproval(t *testing.T) { c := newKubeClient(t) require.NoError(t, initCatalog(t, c)) - subscriptionCleanup := createSubscription(t, c, alphaChannel, "manual-subscription", v1alpha1.ApprovalManual) + subscriptionCleanup := createSubscription(t, c, stableChannel, "manual-subscription", v1alpha1.ApprovalManual) defer subscriptionCleanup() subscription, err := fetchSubscription(t, c, "manual-subscription") @@ -340,4 +342,5 @@ func TestCreateSubscriptionManualApproval(t *testing.T) { require.NotNil(t, installPlan) require.Equal(t, v1alpha1.ApprovalManual, installPlan.Spec.Approval) + require.Equal(t, v1alpha1.InstallPlanPhaseRequiresApproval, installPlan.Status.Phase) } diff --git a/test/e2e/util_test.go b/test/e2e/util_test.go index 8988c0090c5..57cfcc92da8 100644 --- a/test/e2e/util_test.go +++ b/test/e2e/util_test.go @@ -124,16 +124,11 @@ func waitForAndFetchChildren(t *testing.T, c opClient.Interface, version string, owned := 0 for _, obj := range crList.Items { - t.Log(obj.GetName()) - t.Log(obj.GetOwnerReferences()) - t.Log(owner) - t.Log(owner.GetUID()) if ownerutil.IsOwnedBy(obj, owner) { owned += 1 res = append(res, obj) } } - t.Log(owned) // waiting for count number of objects to exist if owned != count { @@ -147,7 +142,7 @@ func waitForAndFetchChildren(t *testing.T, c opClient.Interface, version string, func cleanupCustomResource(t *testing.T, c opClient.Interface, group, kind, name string) cleanupFunc { return func() { - t.Log("deleting %s %s", kind, name) + t.Logf("deleting %s %s", kind, name) require.NoError(t, c.DeleteCustomResource(apis.GroupName, group, testNamespace, kind, name)) } }