Repository: redhat-developer/service-binding-operator
Pull request #519 (2020-06-22 17:24:52)

Add notes to debug e2e tests
### Motivation

Adding some notes would be helpful for developers.

### Changes

new docs in markdown format.

### Testing

NA



openshift-ci-robot: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by:
To complete the [pull request process](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process), please assign **baijum**
You can assign the PR to them by writing `/assign @baijum` in a comment when ready.

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=redhat-developer%2Fservice-binding-operator).

<details open>
Needs approval from an approver in each of these files:

- **[OWNERS](https://github.com/redhat-developer/service-binding-operator/blob/master/OWNERS)**

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":["baijum"]} -->
openshift-ci-robot: @baijum: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
ci/prow/4.5-e2e | 753d7e645848ed6751132eeaacb87173f69a176b | [link](https://prow.svc.ci.openshift.org/view/gcs/origin-ci-test/pr-logs/pull/redhat-developer_service-binding-operator/519/pull-ci-redhat-developer-service-binding-operator-master-4.5-e2e/1275117572638904320) | `/test 4.5-e2e`

[Full PR test history](https://prow.svc.ci.openshift.org/pr-history?org=redhat-developer&repo=service-binding-operator&pr=519). [Your PR dashboard](https://prow.svc.ci.openshift.org/pr?query=is:pr+state:open+author:baijum). Please help us cut down on flakes by [linking to](https://github.com/kubernetes/community/blob/master/contributors/devel/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/redhat-developer/service-binding-operator/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
openshift-ci-robot: @baijum: The following tests **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
ci/prow/4.5-e2e | 753d7e645848ed6751132eeaacb87173f69a176b | [link](https://prow.svc.ci.openshift.org/view/gcs/origin-ci-test/pr-logs/pull/redhat-developer_service-binding-operator/519/pull-ci-redhat-developer-service-binding-operator-master-4.5-e2e/1275117572638904320) | `/test 4.5-e2e`
ci/prow/e2e | 753d7e645848ed6751132eeaacb87173f69a176b | [link](https://prow.svc.ci.openshift.org/view/gcs/origin-ci-test/pr-logs/pull/redhat-developer_service-binding-operator/519/pull-ci-redhat-developer-service-binding-operator-master-e2e/1275117572802482176) | `/test e2e`

[Full PR test history](https://prow.svc.ci.openshift.org/pr-history?org=redhat-developer&repo=service-binding-operator&pr=519). [Your PR dashboard](https://prow.svc.ci.openshift.org/pr?query=is:pr+state:open+author:baijum). Please help us cut down on flakes by [linking to](https://github.com/kubernetes/community/blob/master/contributors/devel/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/redhat-developer/service-binding-operator/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
openshift-ci-robot: @baijum: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
ci/prow/4.5-e2e | fd047cdadf420ce9cab1b8abe3a09afdf1aa61a8 | [link](https://prow.svc.ci.openshift.org/view/gcs/origin-ci-test/pr-logs/pull/redhat-developer_service-binding-operator/519/pull-ci-redhat-developer-service-binding-operator-master-4.5-e2e/1279959362126745600) | `/test 4.5-e2e`

[Full PR test history](https://prow.svc.ci.openshift.org/pr-history?org=redhat-developer&repo=service-binding-operator&pr=519). [Your PR dashboard](https://prow.svc.ci.openshift.org/pr?query=is:pr+state:open+author:baijum). Please help us cut down on flakes by [linking to](https://github.com/kubernetes/community/blob/master/contributors/devel/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/redhat-developer/service-binding-operator/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
baijum: /test 4.5-e2e
openshift-ci-robot: @baijum: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
ci/prow/4.5-e2e | fd047cdadf420ce9cab1b8abe3a09afdf1aa61a8 | [link](https://prow.svc.ci.openshift.org/view/gcs/origin-ci-test/pr-logs/pull/redhat-developer_service-binding-operator/519/pull-ci-redhat-developer-service-binding-operator-master-4.5-e2e/1279998391077572608) | `/test 4.5-e2e`

[Full PR test history](https://prow.svc.ci.openshift.org/pr-history?org=redhat-developer&repo=service-binding-operator&pr=519). [Your PR dashboard](https://prow.svc.ci.openshift.org/pr?query=is:pr+state:open+author:baijum). Please help us cut down on flakes by [linking to](https://github.com/kubernetes/community/blob/master/contributors/devel/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/redhat-developer/service-binding-operator/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
baijum: /test 4.5-e2e

Patch:
diff --git a/README.md b/README.md
index 00649cb6..47333fb3 100644
--- a/README.md
+++ b/README.md
@@ -96,6 +96,8 @@ The following example scenarios are available:
 
 [Binding an Imported app in one namespace with an In-cluster Managed PostgreSQL Database in another namespace](examples/nodejs_postgresql_namespaces/README.md)
 
+[Binding an Imported app to a Route/Ingress][examples/route_k8s_resource/README.md]
+
 ## Community, discussion, contribution, and support
 
 The Service Binding community meets weekly on Thursdays at 11:15 AM UTC via [Google Meet](https://meet.google.com/jti-pujt-zqs).
diff --git a/docs/ci.md b/docs/ci.md
new file mode 100644
index 00000000..61199b7b
--- /dev/null
+++ b/docs/ci.md
@@ -0,0 +1,134 @@
+# Continuous Integration
+
+Service binding operator primarily uses [OpenShift CI][openshift-ci] for
+continuous integration.  The Openshift CI is built using
+[CI-Operator][ci-operator].  The Service Binding Operator specific configuration
+is located here:
+https://github.com/openshift/release/tree/master/ci-operator/config/redhat-developer/service-binding-operator
+
+As part of the continuous integration, there are several jobs configured to run
+against pull requests in GitHub.  The CI jobs are triggered whenever there is a
+new pull request from the team members.  It is also triggered when there is a
+new commit in the current pull request.  If a non-member creates the pull
+request, there should be a comment with text as `/ok-to-test` from any member to
+run the CI job.
+
+Here is a high-level schematic diagram of the CI pipeline for an end-to-end
+test:
+
+```
++--------+     +--------+     +--------+
+|        |     |        |     |        |
+|  root  +---->+  src   +---->+  bin   |
+|        |     |        |     |        |
++--------+     +--------+     +---+----+
+                                   |
+    ,------------------------------'
+    |
+    v
++---+----+     +--------+
+|        |     |        |
+| images +---->+ tests  |
+|        |     |        |
++--------+     +--------+
+```
+
+For lint and unit test, the schematic diagram is as follows:
+
+```
++--------+     +--------+     +----------------+
+|        |     |        |     |                |
+|  root  +---->+  src   +---->+ lint/unit test |
+|        |     |        |     |                |
++--------+     +--------+     +----------------+
+```
+
+
+All the steps mentioned below are taking place inside a temporary work
+namespace.  When you click on the job details from your pull request, you can
+see the name of the work namespace in the dashboard UI.  The name starts with
+`ci-op-`.  The images created goes into this temporary work namespace.  At the
+end of every image build, the [work namespace name has set as an environment
+variable][namespace] called `OPENSHIFT_BUILD_NAMESPACE`.  This environment
+variable is used to refer the image URLs inside the configuration files.
+
+## root
+
+As part of the CI pipeline, the first step is to create the `root` image.  In
+fact, `root` is a tag created for the pipeline image.  This image contains all
+the tools including but not limited to Go compiler, git, kubectl, oc, and
+Operator SDK.
+
+The `root` image tag is created using this Dockerfile:
+`openshift-ci/Dockerfile.tools`.
+
+## src
+
+This step clones the pull request branch with the latest changes.  The cloning
+is taking place inside a container created from the `root` image.  As a result
+of this step, an image named `src` is going to be created.
+
+If your pull request depends on any package installed through `yum install`
+inside the `root` image, those changes should be sent through a different PR and
+merged first.  As you can see from the above diagrams, the `src` image gets
+built after the `root` image, whereas the pull request branch gets merged in the
+`src` image.
+
+## bin
+
+This step runs the `build` Makefile target.  This step is taking place
+inside a container created from the `src` image created in the
+previous step.
+
+The `make build` produces an operator binary image available under `./out`
+directory.  As a result of this step, a container image named `bin` is going to
+be created.
+
+## tests
+
+### lint
+
+The lint runs the [GolangCI Lint][golangci], [YAML Lint][yaml-lint], and
+[Operator Courier][operator-courier].  GolangCI is a Go program, whereas the
+other two are Python based.  So, Python 3 is a prerequisite to run lint.
+
+The GolangCI Lint program runs multiple Go lint tools against the repository.
+GolangCI Lint runs lint concurrently and completes execution in a few seconds.
+As of now, there is no configuration provided to run GolangCI Lint.
+
+The YAML Lint tools validate all the YAML configuration files.  It
+excludes the `vendor` directory while running.  There is a
+configuration file at the top-level directory of the source code:
+`.yamllint`.
+
+### unit
+
+The `unit` target runs the unit tests.  Some of the tests make use of mock
+objects. The unit tests don't require a dedicated OpenShift cluster, unlike
+end-to-end tests. It runs `test-unit` Makefile target.
+
+### e2e
+
+The `e2e` run an end-to-end test against an operator running inside the CI
+cluster pod but connected to a freshly created temporary Openshift 4 cluster.
+It makes use of the `--up-local` option provided by the Operator SDK testing
+tool.  It runs `test-e2e` Makefile target.
+
+## Debugging e2e test
+
+1. Login to https://api.ci.openshift.org
+2. Copy login command from top-right corner
+3. Note down the namespace from log.  As mentioned before, when you click on the
+   job details from your pull request, you can see the name of the work
+   namespace in the dashboard UI.  The name starts with `ci-op-`.
+4. Now you can check each container log or rsh into shell.
+5. In the container named `setup` in `e2e` pod, you will get kubeconfig for the
+   temporary cluster.  You can use it to access the temporary cluster and
+   perform further debugging.
+
+[openshift-ci]: https://github.com/openshift/release
+[ci-operator]: https://github.com/openshift/release/tree/master/ci-operator
+[golangci]: https://github.com/golangci/golangci-lint
+[yaml-lint]: https://github.com/adrienverge/yamllint
+[operator-courier]: https://github.com/operator-framework/operator-courier
+[namespace]: https://docs.okd.io/latest/dev_guide/builds/build_output.html#output-image-environment-variables
diff --git a/pkg/apis/apps/v1alpha1/servicebindingrequest_types.go b/pkg/apis/apps/v1alpha1/servicebindingrequest_types.go
index 321ae486..472c4c7b 100644
--- a/pkg/apis/apps/v1alpha1/servicebindingrequest_types.go
+++ b/pkg/apis/apps/v1alpha1/servicebindingrequest_types.go
@@ -112,3 +112,14 @@ type ServiceBindingRequestList struct {
 func init() {
 	SchemeBuilder.Register(&ServiceBindingRequest{}, &ServiceBindingRequestList{})
 }
+
+func (sbr ServiceBindingRequest) AsOwnerReference() metav1.OwnerReference {
+	var ownerRefController bool = true
+	return metav1.OwnerReference{
+		Name:       sbr.Name,
+		UID:        sbr.UID,
+		Kind:       sbr.Kind,
+		APIVersion: sbr.APIVersion,
+		Controller: &ownerRefController,
+	}
+}
diff --git a/pkg/controller/servicebindingrequest/secret.go b/pkg/controller/servicebindingrequest/secret.go
index 22eba8ac..f05af5c7 100644
--- a/pkg/controller/servicebindingrequest/secret.go
+++ b/pkg/controller/servicebindingrequest/secret.go
@@ -27,12 +27,13 @@ func (s *secret) buildResourceClient() dynamic.ResourceInterface {
 
 // createOrUpdate will take informed payload and either create a new secret or update an existing
 // one. It can return error when Kubernetes client does.
-func (s *secret) createOrUpdate(payload map[string][]byte) (*unstructured.Unstructured, error) {
+func (s *secret) createOrUpdate(payload map[string][]byte, ownerReference metav1.OwnerReference) (*unstructured.Unstructured, error) {
 	logger := s.logger.WithValues("Namespace", s.ns, "Name", s.name)
 	secretObj := &corev1.Secret{
 		ObjectMeta: metav1.ObjectMeta{
-			Namespace: s.ns,
-			Name:      s.name,
+			Namespace:       s.ns,
+			Name:            s.name,
+			OwnerReferences: []metav1.OwnerReference{ownerReference},
 		},
 		Data: payload,
 	}
@@ -59,12 +60,6 @@ func (s *secret) createOrUpdate(payload map[string][]byte) (*unstructured.Unstru
 	return u, nil
 }
 
-// commit will store informed data as a secret, commit it against the API server. It can forward
-// errors from custom environment parser component, or from the API server itself.
-func (s *secret) commit(payload map[string][]byte) (*unstructured.Unstructured, error) {
-	return s.createOrUpdate(payload)
-}
-
 // get an unstructured object from the secret handled by this component. It can return errors in case
 // the API server does.
 func (s *secret) get() (*unstructured.Unstructured, bool, error) {
@@ -76,16 +71,6 @@ func (s *secret) get() (*unstructured.Unstructured, bool, error) {
 	return u, u != nil, nil
 }
 
-// delete the secret represented by this component. It can return error when the API server does.
-func (s *secret) delete() error {
-	resourceClient := s.buildResourceClient()
-	err := resourceClient.Delete(s.name, &metav1.DeleteOptions{})
-	if err != nil && !errors.IsNotFound(err) {
-		return err
-	}
-	return nil
-}
-
 // newSecret instantiate a new Secret.
 func newSecret(
 	client dynamic.Interface,
diff --git a/pkg/controller/servicebindingrequest/servicebinder.go b/pkg/controller/servicebindingrequest/servicebinder.go
index f3e767f1..03e3aa32 100644
--- a/pkg/controller/servicebindingrequest/servicebinder.go
+++ b/pkg/controller/servicebindingrequest/servicebinder.go
@@ -152,12 +152,6 @@ func (b *serviceBinder) unbind() (reconcile.Result, error) {
 		return requeueError(err)
 	}
 
-	logger.Info("Deleting intermediary secret")
-	if err := b.secret.delete(); err != nil {
-		logger.Error(err, "On deleting intermediary secret.")
-		return requeueError(err)
-	}
-
 	logger.Debug("Removing resource finalizers...")
 	b.sbr.SetFinalizers(removeStringSlice(b.sbr.GetFinalizers(), finalizer))
 	if _, err := b.updateServiceBindingRequest(b.sbr); err != nil {
@@ -247,7 +241,8 @@ func (b *serviceBinder) bind() (reconcile.Result, error) {
 	sbrStatus := b.sbr.Status.DeepCopy()
 
 	b.logger.Info("Saving data on intermediary secret...")
-	secretObj, err := b.secret.commit(b.envVars)
+
+	secretObj, err := b.secret.createOrUpdate(b.envVars, b.sbr.AsOwnerReference())
 	if err != nil {
 		b.logger.Error(err, "On saving secret data..")
 		return b.onError(err, b.sbr, sbrStatus, nil)


Test patch:
diff --git a/pkg/controller/servicebindingrequest/secret_test.go b/pkg/controller/servicebindingrequest/secret_test.go
index 8f579eb0..ba7c4934 100644
--- a/pkg/controller/servicebindingrequest/secret_test.go
+++ b/pkg/controller/servicebindingrequest/secret_test.go
@@ -4,14 +4,26 @@ import (
 	"testing"
 
 	"github.com/stretchr/testify/assert"
+	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
 
 	"github.com/redhat-developer/service-binding-operator/test/mocks"
 )
 
+var ownerRefController bool = true
+var secretOwnerReference = v1.OwnerReference{
+	Name:       "binding-request",
+	UID:        "c77ca1ae-72d0-4fdd-809f-58fdd37facf3",
+	Kind:       "ServiceBindingRequest",
+	APIVersion: "apps.openshift.io/v1alpha1",
+	Controller: &ownerRefController,
+}
+
 func assertSecretNamespacedName(t *testing.T, u *unstructured.Unstructured, ns, name string) {
 	assert.Equal(t, ns, u.GetNamespace())
 	assert.Equal(t, name, u.GetName())
+	ownerReference := u.GetOwnerReferences()
+	assert.Equal(t, secretOwnerReference, ownerReference[0])
 }
 
 func TestSecretNew(t *testing.T) {
@@ -29,18 +41,7 @@ func TestSecretNew(t *testing.T) {
 	)
 
 	t.Run("createOrUpdate", func(t *testing.T) {
-		u, err := s.createOrUpdate(data)
-		assert.NoError(t, err)
-		assertSecretNamespacedName(t, u, ns, name)
-	})
-
-	t.Run("Delete", func(t *testing.T) {
-		err := s.delete()
-		assert.NoError(t, err)
-	})
-
-	t.Run("Commit", func(t *testing.T) {
-		u, err := s.commit(data)
+		u, err := s.createOrUpdate(data, secretOwnerReference)
 		assert.NoError(t, err)
 		assertSecretNamespacedName(t, u, ns, name)
 	})