Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Part 1]Add unit tests for reconcile methods #250

Merged
merged 10 commits into from
May 4, 2021

Conversation

bhiravabhatla
Copy link
Contributor

@bhiravabhatla bhiravabhatla commented Apr 19, 2021

Signed-off-by: santosh [email protected]

Resolves #35

  • Add unit tests for configmap, daemonset, deployment reconcilers
  • Fix Patch calls for configmap, daemonset, deployment reconcilers

Raised #261 for service and service account reconcilers

@bhiravabhatla bhiravabhatla requested review from a team April 19, 2021 03:19
@bhiravabhatla
Copy link
Contributor Author

bhiravabhatla commented Apr 19, 2021

@jpkrohling - I am unable to test Patch call (updating existing configmap) with envtest.

		err = expectedConfigMaps(context.Background(), params(), []v1.ConfigMap{configMap()}, true)
		assert.NoError(t, err)

While running expectedConfigMaps with existing configmap, I am seeing below error returned.

failed to apply changes: the name of the object (test-collector based on URL) was undeterminable: name must be provided

While running on debug - i could see the control reaching the Patch statement -

if err := params.Client.Patch(ctx, updated, patch); err != nil {
			return fmt.Errorf("failed to apply changes: %w", err)
		}

And Patch is returning above error. Any clues what might be causing this. Current PR has this particular test commented.

@alolita
Copy link
Member

alolita commented Apr 22, 2021

@humivo @IrisTuntun can you take a look at this PR too for the Operator enhancements we're working on?

@bhiravabhatla
Copy link
Contributor Author

I would need help with above blocker. If this is resolved, I can add tests for all the other reconcilers similarly.

@bhiravabhatla
Copy link
Contributor Author

bhiravabhatla commented Apr 25, 2021

@jpkrohling - I guess there is a bug in Patch logic -

patch := client.MergeFrom(&params.Instance)

We are generating patch from Instance, (not sure why). If I generate the patch from existing configmap [ which should be the case, as we are pacthing configmap - not openTelemetryCollector CR ] , like below -

patch := client.MergeFrom(existing)

Patch Tests are passing. Below is the documentation of mergeFrom function - MergeFrom creates a Patch that patches using the merge-patch strategy with the given object as base.

// MergeFrom creates a Patch that patches using the merge-patch strategy with the given object as base.
// The difference between MergeFrom and StrategicMergeFrom lays in the handling of modified list fields.
// When using MergeFrom, existing lists will be completely replaced by new lists.
// When using StrategicMergeFrom, the list field's `patchStrategy` is respected if specified in the API type,
// e.g. the existing list is not replaced completely but rather merged with the new one using the list's `patchMergeKey`.
// See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/ for more details on
// the difference between merge-patch and strategic-merge-patch.
func MergeFrom(obj runtime.Object) Patch {
	return &mergeFromPatch{patchType: types.MergePatchType, createPatch: createMergePatch, from: obj}
}

Same is the case for all the patch calls ( configmap, daemonset, deployment , etc). Kindly confirm.

I ll update this thread after testing the operator using above fix

@bhiravabhatla
Copy link
Contributor Author

I ll update this thread after testing the operator using above fix

Works well. I could see deployment being patched if I manually edit the deployment. I am pushing the above change with this PR if its ok. @jpkrohling - Thoughts?

We were generating patches from params.Instance as base for configmap,deployments & daemonsets. Get the patch from existing resource instead.

Signed-off-by: santosh <[email protected]>
@jpkrohling
Copy link
Member

Sorry for taking so long to look into this, I'll review this today or, at the latest, tomorrow.

@IrisTuntun
Copy link
Contributor

Hi, I'm working on adding StatefulSet to reconcile and have a test added in this PR. The test works without changing the MergeFrom logic. I was wondering if my test strategy makes sense here.

Copy link
Member

@jpkrohling jpkrohling left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's looking great! Would you like to get this one merged first, before working on the next tests? This way, we don't get huge PRs in the queue.

pkg/collector/reconcile/configmap.go Show resolved Hide resolved

func TestDesiredConfigMap(t *testing.T) {
t.Run("should return expected config map", func(t *testing.T) {
expected := configMap("test-collector")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would skip the local configMap, and make explicit assertions about certain aspects of the returned config map, like checking the returned labels and the name, and possibly the config.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


func TestExpectedConfigMap(t *testing.T) {

cm := configMap("test-collector")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can call the desiredConfigMap here, as you are testing its correctness in another test.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

})
}

func daemonset(name string) v1.DaemonSet {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as the configmap: if you have a test for the desiredDaemonSet, this one here could probably be removed in favor of the official one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep makes sense.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as below

})
}

func deployment(name string) v1.Deployment {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto :-)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For delete test cases - I cant use desiredDaemonSet/desiredDeployment - As I would need to a resource with same labels as the one in Params but with different name.

i.e.

Lables should be

Labels: map[string]string{
"app.kubernetes.io/managed-by": "opentelemetry-operator",
"app.kubernetes.io/instance": fmt.Sprintf("%s.%s", params.Instance.Namespace, params().Instance.Name),
},

but name should be different than params.Instance.Name. Its not possible using desiredDaemonSet/desiredDeployment functions. So I would have to retain the daemonset and deployment helper functions.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think all you need for those cases is a deployment/daemonset with one or two labels (managed-by, I believe). This is what we have in the jaeger-operator:

https://github.com/jaegertracing/jaeger-operator/blob/4693d119aabb550a7a651315cbfce1833bb786fc/pkg/controller/jaeger/daemonset_test.go#L104-L114

The good thing about doing it like this is that we see exactly what has influence on the decision to remove the CR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In our case - we are actually creating the object. So would need the entire spec, only namespacedName and labels wont suffice. Basically have to move everything in daemonset function to actual test. Will do the same then

@bhiravabhatla
Copy link
Contributor Author

Would you like to get this one merged first, before working on the next tests?

Makes sense. I am half way through with service tests - I ll raise another PR for it.

@bhiravabhatla bhiravabhatla changed the title [WIP] Add unit tests for reconcile methods [Part 1]Add unit tests for reconcile methods May 2, 2021
@jpkrohling
Copy link
Member

Let me know once this is ready for another review.

@bhiravabhatla
Copy link
Contributor Author

Let me know once this is ready for another review.

Done. Also added one more test case each for daemonset and deployment to make sure we dont delete resources which are not owned by operator. Kindly review @jpkrohling

@bhiravabhatla
Copy link
Contributor Author

Would you like to get this one merged first, before working on the next tests?

Makes sense. I am half way through with service tests - I ll raise another PR for it.

Raised second PR for this. Could you also take a look at - #261 @jpkrohling

@jpkrohling
Copy link
Member

CodeQL seems stuck. Would you be able to do a "git commit --amend" and push it again?

@jpkrohling jpkrohling enabled auto-merge (squash) May 4, 2021 15:26
@jpkrohling jpkrohling merged commit 70d7920 into open-telemetry:main May 4, 2021
@bhiravabhatla bhiravabhatla deleted the reconcile_tests branch May 5, 2021 02:33
shree007 pushed a commit to shree007/opentelemetry-operator that referenced this pull request Dec 12, 2021
ItielOlenick pushed a commit to ItielOlenick/opentelemetry-operator that referenced this pull request May 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Tests for reconcilers
4 participants