Refactoring Prometheus Charm to use Operator Framework
[osm/devops.git] / installers / charm / prometheus / tests / test_charm.py
1 #!/usr/bin/env python3
2 # Copyright 2020 Canonical Ltd.
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License"); you may
5 # not use this file except in compliance with the License. You may obtain
6 # a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 # License for the specific language governing permissions and limitations
14 # under the License.
15 #
16 # For those usages not covered by the Apache License, Version 2.0 please
17 # contact: legal@canonical.com
18 #
19 # To get in touch with the maintainers, please contact:
20 # osm-charmers@lists.launchpad.net
21 ##
22
23 from typing import NoReturn
24 import unittest
25
26 from ops.model import BlockedStatus
27 from ops.testing import Harness
28
29 from charm import PrometheusCharm
30
31
32 class TestCharm(unittest.TestCase):
33 """Prometheus Charm unit tests."""
34
35 def setUp(self) -> NoReturn:
36 """Test setup"""
37 self.harness = Harness(PrometheusCharm)
38 self.harness.set_leader(is_leader=True)
39 self.harness.begin()
40
41 def test_ingress_resources_without_http(self) -> NoReturn:
42 """Test ingress resources without HTTP."""
43 expected_result = {
44 "version": 3,
45 "containers": [
46 {
47 "name": "prometheus",
48 "imageDetails": self.harness.charm.image.fetch(),
49 "imagePullPolicy": "Always",
50 "ports": [
51 {
52 "name": "prometheus",
53 "containerPort": 9090,
54 "protocol": "TCP",
55 }
56 ],
57 "envConfig": {},
58 "volumeConfig": [
59 {
60 "name": "config",
61 "mountPath": "/etc/prometheus",
62 "files": [
63 {
64 "path": "prometheus.yml",
65 "content": (
66 "global:"
67 " scrape_interval: 15s"
68 " evaluation_interval: 15s"
69 "alerting:"
70 " alertmanagers:"
71 " - static_configs:"
72 " - targets:"
73 "rule_files:"
74 "scrape_configs:"
75 " - job_name: 'prometheus'"
76 " static_configs:"
77 " - targets: [{}]".format("")
78 ),
79 }
80 ],
81 }
82 ],
83 "command": [
84 "sh",
85 "-c",
86 "/bin/prometheus",
87 "--config.file=/etc/prometheus/prometheus.yml",
88 "--storage.tsdb.path=/prometheus",
89 "--web.console.libraries=/usr/share/prometheus/console_libraries",
90 "--web.console.templates=/usr/share/prometheus/consoles",
91 "--web.route-prefix={}".format("/"),
92 "--web.external-url=http://localhost:{}{}".format(9090, "/"),
93 ],
94 "kubernetes": {
95 "readinessProbe": {
96 "httpGet": {
97 "path": "/-/ready",
98 "port": 9090,
99 },
100 "initialDelaySeconds": 10,
101 "timeoutSeconds": 30,
102 },
103 "livenessProbe": {
104 "httpGet": {
105 "path": "/-/healthy",
106 "port": 9090,
107 },
108 "initialDelaySeconds": 30,
109 "periodSeconds": 30,
110 },
111 },
112 }
113 ],
114 "kubernetesResources": {"ingressResources": []},
115 }
116
117 self.harness.charm.on.start.emit()
118
119 # Verifying status
120 self.assertNotIsInstance(self.harness.charm.unit.status, BlockedStatus)
121
122 pod_spec, _ = self.harness.get_pod_spec()
123
124 self.assertDictEqual(expected_result, pod_spec)
125
126 def test_ingress_resources_with_http(self) -> NoReturn:
127 """Test ingress resources with HTTP."""
128 expected_result = {
129 "version": 3,
130 "containers": [
131 {
132 "name": "prometheus",
133 "imageDetails": self.harness.charm.image.fetch(),
134 "imagePullPolicy": "Always",
135 "ports": [
136 {
137 "name": "prometheus",
138 "containerPort": 9090,
139 "protocol": "TCP",
140 }
141 ],
142 "envConfig": {},
143 "volumeConfig": [
144 {
145 "name": "config",
146 "mountPath": "/etc/prometheus",
147 "files": [
148 {
149 "path": "prometheus.yml",
150 "content": (
151 "global:"
152 " scrape_interval: 15s"
153 " evaluation_interval: 15s"
154 "alerting:"
155 " alertmanagers:"
156 " - static_configs:"
157 " - targets:"
158 "rule_files:"
159 "scrape_configs:"
160 " - job_name: 'prometheus'"
161 " static_configs:"
162 " - targets: [{}]".format("")
163 ),
164 }
165 ],
166 }
167 ],
168 "command": [
169 "sh",
170 "-c",
171 "/bin/prometheus",
172 "--config.file=/etc/prometheus/prometheus.yml",
173 "--storage.tsdb.path=/prometheus",
174 "--web.console.libraries=/usr/share/prometheus/console_libraries",
175 "--web.console.templates=/usr/share/prometheus/consoles",
176 "--web.route-prefix={}".format("/"),
177 "--web.external-url=http://localhost:{}{}".format(9090, "/"),
178 ],
179 "kubernetes": {
180 "readinessProbe": {
181 "httpGet": {
182 "path": "/-/ready",
183 "port": 9090,
184 },
185 "initialDelaySeconds": 10,
186 "timeoutSeconds": 30,
187 },
188 "livenessProbe": {
189 "httpGet": {
190 "path": "/-/healthy",
191 "port": 9090,
192 },
193 "initialDelaySeconds": 30,
194 "periodSeconds": 30,
195 },
196 },
197 }
198 ],
199 "kubernetesResources": {
200 "ingressResources": [
201 {
202 "name": "prometheus-ingress",
203 "annotations": {
204 "nginx.ingress.kubernetes.io/proxy-body-size": "0",
205 "nginx.ingress.kubernetes.io/ssl-redirect": "false",
206 },
207 "spec": {
208 "rules": [
209 {
210 "host": "prometheus",
211 "http": {
212 "paths": [
213 {
214 "path": "/",
215 "backend": {
216 "serviceName": "prometheus",
217 "servicePort": 9090,
218 },
219 }
220 ]
221 },
222 }
223 ]
224 },
225 }
226 ],
227 },
228 }
229
230 self.harness.charm.on.start.emit()
231
232 self.harness.update_config({"site_url": "http://prometheus"})
233
234 pod_spec, _ = self.harness.get_pod_spec()
235
236 self.assertDictEqual(expected_result, pod_spec)
237
238 def test_ingress_resources_with_https(self) -> NoReturn:
239 """Test ingress resources with HTTPS."""
240 expected_result = {
241 "version": 3,
242 "containers": [
243 {
244 "name": "prometheus",
245 "imageDetails": self.harness.charm.image.fetch(),
246 "imagePullPolicy": "Always",
247 "ports": [
248 {
249 "name": "prometheus",
250 "containerPort": 9090,
251 "protocol": "TCP",
252 }
253 ],
254 "envConfig": {},
255 "volumeConfig": [
256 {
257 "name": "config",
258 "mountPath": "/etc/prometheus",
259 "files": [
260 {
261 "path": "prometheus.yml",
262 "content": (
263 "global:"
264 " scrape_interval: 15s"
265 " evaluation_interval: 15s"
266 "alerting:"
267 " alertmanagers:"
268 " - static_configs:"
269 " - targets:"
270 "rule_files:"
271 "scrape_configs:"
272 " - job_name: 'prometheus'"
273 " static_configs:"
274 " - targets: [{}]".format("")
275 ),
276 }
277 ],
278 }
279 ],
280 "command": [
281 "sh",
282 "-c",
283 "/bin/prometheus",
284 "--config.file=/etc/prometheus/prometheus.yml",
285 "--storage.tsdb.path=/prometheus",
286 "--web.console.libraries=/usr/share/prometheus/console_libraries",
287 "--web.console.templates=/usr/share/prometheus/consoles",
288 "--web.route-prefix={}".format("/"),
289 "--web.external-url=http://localhost:{}{}".format(9090, "/"),
290 ],
291 "kubernetes": {
292 "readinessProbe": {
293 "httpGet": {
294 "path": "/-/ready",
295 "port": 9090,
296 },
297 "initialDelaySeconds": 10,
298 "timeoutSeconds": 30,
299 },
300 "livenessProbe": {
301 "httpGet": {
302 "path": "/-/healthy",
303 "port": 9090,
304 },
305 "initialDelaySeconds": 30,
306 "periodSeconds": 30,
307 },
308 },
309 }
310 ],
311 "kubernetesResources": {
312 "ingressResources": [
313 {
314 "name": "prometheus-ingress",
315 "annotations": {
316 "nginx.ingress.kubernetes.io/proxy-body-size": "0",
317 },
318 "spec": {
319 "rules": [
320 {
321 "host": "prometheus",
322 "http": {
323 "paths": [
324 {
325 "path": "/",
326 "backend": {
327 "serviceName": "prometheus",
328 "servicePort": 9090,
329 },
330 }
331 ]
332 },
333 }
334 ],
335 "tls": [
336 {"hosts": ["prometheus"], "secretName": "prometheus"}
337 ],
338 },
339 }
340 ],
341 },
342 }
343
344 self.harness.charm.on.start.emit()
345
346 self.harness.update_config(
347 {"site_url": "https://prometheus", "tls_secret_name": "prometheus"}
348 )
349
350 pod_spec, _ = self.harness.get_pod_spec()
351
352 self.assertDictEqual(expected_result, pod_spec)
353
354 def test_ingress_resources_with_https_and_ingress_whitelist(self) -> NoReturn:
355 """Test ingress resources with HTTPS and ingress whitelist."""
356 expected_result = {
357 "version": 3,
358 "containers": [
359 {
360 "name": "prometheus",
361 "imageDetails": self.harness.charm.image.fetch(),
362 "imagePullPolicy": "Always",
363 "ports": [
364 {
365 "name": "prometheus",
366 "containerPort": 9090,
367 "protocol": "TCP",
368 }
369 ],
370 "envConfig": {},
371 "volumeConfig": [
372 {
373 "name": "config",
374 "mountPath": "/etc/prometheus",
375 "files": [
376 {
377 "path": "prometheus.yml",
378 "content": (
379 "global:"
380 " scrape_interval: 15s"
381 " evaluation_interval: 15s"
382 "alerting:"
383 " alertmanagers:"
384 " - static_configs:"
385 " - targets:"
386 "rule_files:"
387 "scrape_configs:"
388 " - job_name: 'prometheus'"
389 " static_configs:"
390 " - targets: [{}]".format("")
391 ),
392 }
393 ],
394 }
395 ],
396 "command": [
397 "sh",
398 "-c",
399 "/bin/prometheus",
400 "--config.file=/etc/prometheus/prometheus.yml",
401 "--storage.tsdb.path=/prometheus",
402 "--web.console.libraries=/usr/share/prometheus/console_libraries",
403 "--web.console.templates=/usr/share/prometheus/consoles",
404 "--web.route-prefix={}".format("/"),
405 "--web.external-url=http://localhost:{}{}".format(9090, "/"),
406 ],
407 "kubernetes": {
408 "readinessProbe": {
409 "httpGet": {
410 "path": "/-/ready",
411 "port": 9090,
412 },
413 "initialDelaySeconds": 10,
414 "timeoutSeconds": 30,
415 },
416 "livenessProbe": {
417 "httpGet": {
418 "path": "/-/healthy",
419 "port": 9090,
420 },
421 "initialDelaySeconds": 30,
422 "periodSeconds": 30,
423 },
424 },
425 }
426 ],
427 "kubernetesResources": {
428 "ingressResources": [
429 {
430 "name": "prometheus-ingress",
431 "annotations": {
432 "nginx.ingress.kubernetes.io/proxy-body-size": "0",
433 "nginx.ingress.kubernetes.io/whitelist-source-range": "0.0.0.0/0",
434 },
435 "spec": {
436 "rules": [
437 {
438 "host": "prometheus",
439 "http": {
440 "paths": [
441 {
442 "path": "/",
443 "backend": {
444 "serviceName": "prometheus",
445 "servicePort": 9090,
446 },
447 }
448 ]
449 },
450 }
451 ],
452 "tls": [
453 {"hosts": ["prometheus"], "secretName": "prometheus"}
454 ],
455 },
456 }
457 ],
458 },
459 }
460
461 self.harness.charm.on.start.emit()
462
463 self.harness.update_config(
464 {
465 "site_url": "https://prometheus",
466 "tls_secret_name": "prometheus",
467 "ingress_whitelist_source_range": "0.0.0.0/0",
468 }
469 )
470
471 pod_spec, _ = self.harness.get_pod_spec()
472
473 self.assertDictEqual(expected_result, pod_spec)
474
475 def test_publish_prometheus_info(self) -> NoReturn:
476 """Test to see if prometheus relation is updated."""
477 expected_result = {
478 "host": "prometheus",
479 "port": "9090",
480 }
481
482 self.harness.charm.on.start.emit()
483
484 relation_id = self.harness.add_relation("prometheus", "mon")
485 self.harness.add_relation_unit(relation_id, "mon/0")
486 relation_data = self.harness.get_relation_data(relation_id, "prometheus")
487
488 self.assertDictEqual(expected_result, relation_data)
489
490
491 if __name__ == "__main__":
492 unittest.main()