You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/modules/ROOT/pages/testing.adoc
+70-25Lines changed: 70 additions & 25 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,7 +1,3 @@
1
-
ifndef::backend-pdf[]
2
-
:examplesdir: example$
3
-
endif::[]
4
-
5
1
= Tutorial: Writing Commodore Component Tests
6
2
7
3
This tutorial covers the topic of writing tests for your new or existing Commodore Component.
@@ -10,8 +6,10 @@ If not, see link:index.adoc[Writing your First Commodore Component].
10
6
11
7
Currently, we can test components with two approaches:
12
8
13
-
. Unit tests with Go. Easy to understand and write if you are already a Go developer.
14
-
. Policy tests with Conftest. Uses the https://www.openpolicyagent.org/docs/latest/policy-language/[Rego] syntax from https://www.openpolicyagent.org/[OpenPolicyAgent].
9
+
. Unit tests with Go.
10
+
Easy to understand and write if you are already a Go developer.
11
+
. Policy tests with Conftest.
12
+
Uses the https://www.openpolicyagent.org/docs/latest/policy-language/[Rego] syntax from https://www.openpolicyagent.org/[OpenPolicyAgent].
15
13
16
14
It is up to you to decide which test framework you want to use.
17
15
Some tests are simpler to do in Go, some are simpler in Rego.
@@ -24,7 +22,6 @@ NOTE: The policy tests run with the Conftest tool, but for the purpose of this t
24
22
NOTE: This tutorial *was written on a Linux system*.
25
23
26
24
. `Go` version 1.15, developer environment with Go modules enabled.
27
-
. `make` version 4
28
25
. `docker` version 19
29
26
30
27
== Setting up test infrastructure with Go
@@ -54,7 +51,44 @@ If you have `component-somename`, then leave out `component-`.
. `recommended_labels` is an object that verifies that `.metadata.labels` contain the desired label keys.
116
-
. `warn_labels[msg]` is a Rule. If all expressions in the brackets match (including `msg`), this Rule is considered `true`.
117
-
. Since the prefix of the rule is `warn_`, it will only print a Warning message if there is an object that matches the rule. With `deny_`, it would fail the test.
152
+
. `warn_labels[msg]` is a Rule.
153
+
If all expressions in the brackets match (including `msg`), this Rule is considered `true`.
154
+
. Since the prefix of the rule is `warn_`, it will only print a Warning message if there is an object that matches the rule.
155
+
With `deny_`, it would fail the test.
118
156
119
157
IMPORTANT: Rego (like Datalog and its ancestor Prolog) is declarative.
120
158
The lines within a rule are not evaluated imperatively.
121
159
It is important to keep that in mind when writing rules, as it can cause many headaches.
122
160
123
161
Let's translate the example to English:
124
162
125
-
. In `recommended_labels`, we will test whether the Kubernetes object (named `input`) contains "app.kubernetes.io/managed-by" in the `.metadata.labels` dictionary. We ignore the actual value here. Since `recommended_labels` is not a rule, it's not yet used.
163
+
. In `recommended_labels`, we will test whether the Kubernetes object (named `input`) contains "app.kubernetes.io/managed-by" in the `.metadata.labels` dictionary.
164
+
We ignore the actual value here.
165
+
Since `recommended_labels` is not a rule, it's not yet used.
126
166
. When conftest matches an Object against the rule `warn_labels`, all expressions in the rule have to evaluate `True`.
127
167
. If we pass a CRD, the result of the rule is `False` because of `input.kind != "CustomResourceDefinition"`, thus the rule does not match, and the test passes.
128
168
. If we pass a `Deployment`, we have at least `input.kind != "CustomResourceDefinition"` that equals to `True`, but remember, all expressions have to be evaluated.
129
-
. The other expression, `not recommended_labels` checks if the object is missing the desired labels. If the given Deployment has the labels, it will fail the rule and pass the test. A Deployment that doesn't have the labels would match the rule, and thus fail the test.
130
-
. By now the rule would already match with a Deployment without the labels, and thus fail the test, but we want to give a reason why. As the final expression, we will assign the `msg` variable a human readable message why the rule matches. Remember, this line can also be the first one since the execution order is determined by Rego and not line by line.
169
+
. The other expression, `not recommended_labels` checks if the object is missing the desired labels.
170
+
If the given Deployment has the labels, it will fail the rule and pass the test.
171
+
A Deployment that doesn't have the labels would match the rule, and thus fail the test.
172
+
. By now the rule would already match with a Deployment without the labels, and thus fail the test, but we want to give a reason why.
173
+
As the final expression, we will assign the `msg` variable a human readable message why the rule matches.
174
+
Remember, this line can also be the first one since the execution order is determined by Rego and not line by line.
131
175
132
176
If we now also pass a `Namespace` or `Service` objects, the same rules can be applied, since all these objects share the common property `.metadata.labels`.
133
177
@@ -149,8 +193,7 @@ The expression `not input.metadata.name = "syn-espejo"` is equivalent, but we wa
149
193
Running the policies could look like this:
150
194
[source,bash]
151
195
----
152
-
$ make test_conftest
153
-
===> Running Conftest policies
196
+
$ DOCKER_CMD --volume "${PWD}/tests/policies:/policy" openpolicyagent/conftest:latest test --policy /policy $(find . -type f -wholename "./compiled/${COMPONENT_NAME}/*.yaml")
154
197
WARN - ./compiled/espejo/espejo/05_rbac.yaml - ClusterRole/syn-espejo has not recommended labels
155
198
WARN - ./compiled/espejo/espejo/05_rbac.yaml - ServiceAccount/espejo has not recommended labels
156
199
WARN - ./compiled/espejo/espejo/05_rbac.yaml - ClusterRoleBinding/syn-espejo has not recommended labels
@@ -161,11 +204,13 @@ WARN - ./compiled/espejo/espejo/01_namespace.yaml - Namespace/syn-espejo has not
161
204
162
205
== Run all tests
163
206
164
-
At the time of writing, this is done simply with `make test`.
165
-
This is also applicable in any CI/CD pipelines, such as GitHub Actions.
207
+
You could declare all the test commands in the `Makefile`.
208
+
Have a look at https://github.com/projectsyn/component-espejo/blob/master/Makefile[Component-Espejo] for an example.
209
+
This should also help running tests in any CI/CD pipelines, such as GitHub Actions.
166
210
167
211
== Conclusion
168
212
169
213
I hope this guide has shown how we can test our component without having to compile a whole catalog and applying it to a cluster.
170
214
171
-
At the moment, we are limited to only have tests against a single compilation (e.g. the default parameters). Later on, we want to enable testing different parameter sets.
215
+
At the moment, we are limited to only have tests against a single compilation (e.g. the default parameters).
216
+
Later on, we want to enable testing different parameter sets.
0 commit comments