87d7bc5c2a0e60c331da12fa9190c914372f3a3f
[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:\n"
67 " scrape_interval: 15s\n"
68 " evaluation_interval: 15s\n"
69 "alerting:\n"
70 " alertmanagers:\n"
71 " - static_configs:\n"
72 " - targets:\n"
73 "rule_files:\n"
74 "scrape_configs:\n"
75 " - job_name: 'prometheus'\n"
76 " static_configs:\n"
77 " - targets: [{}]\n".format("")
78 ),
79 }
80 ],
81 }
82 ],
83 "command": [
84 "/bin/prometheus",
85 "--config.file=/etc/prometheus/prometheus.yml",
86 "--storage.tsdb.path=/prometheus",
87 "--web.console.libraries=/usr/share/prometheus/console_libraries",
88 "--web.console.templates=/usr/share/prometheus/consoles",
89 "--web.route-prefix={}".format("/"),
90 "--web.external-url=http://localhost:{}{}".format(9090, "/"),
91 ],
92 "kubernetes": {
93 "readinessProbe": {
94 "httpGet": {
95 "path": "/-/ready",
96 "port": 9090,
97 },
98 "initialDelaySeconds": 10,
99 "timeoutSeconds": 30,
100 },
101 "livenessProbe": {
102 "httpGet": {
103 "path": "/-/healthy",
104 "port": 9090,
105 },
106 "initialDelaySeconds": 30,
107 "periodSeconds": 30,
108 },
109 },
110 }
111 ],
112 "kubernetesResources": {"ingressResources": []},
113 }
114
115 self.harness.charm.on.start.emit()
116
117 # Verifying status
118 self.assertNotIsInstance(self.harness.charm.unit.status, BlockedStatus)
119
120 pod_spec, _ = self.harness.get_pod_spec()
121
122 self.assertDictEqual(expected_result, pod_spec)
123
124 def test_ingress_resources_with_http(self) -> NoReturn:
125 """Test ingress resources with HTTP."""
126 expected_result = {
127 "version": 3,
128 "containers": [
129 {
130 "name": "prometheus",
131 "imageDetails": self.harness.charm.image.fetch(),
132 "imagePullPolicy": "Always",
133 "ports": [
134 {
135 "name": "prometheus",
136 "containerPort": 9090,
137 "protocol": "TCP",
138 }
139 ],
140 "envConfig": {},
141 "volumeConfig": [
142 {
143 "name": "config",
144 "mountPath": "/etc/prometheus",
145 "files": [
146 {
147 "path": "prometheus.yml",
148 "content": (
149 "global:\n"
150 " scrape_interval: 15s\n"
151 " evaluation_interval: 15s\n"
152 "alerting:\n"
153 " alertmanagers:\n"
154 " - static_configs:\n"
155 " - targets:\n"
156 "rule_files:\n"
157 "scrape_configs:\n"
158 " - job_name: 'prometheus'\n"
159 " static_configs:\n"
160 " - targets: [{}]\n".format("")
161 ),
162 }
163 ],
164 }
165 ],
166 "command": [
167 "/bin/prometheus",
168 "--config.file=/etc/prometheus/prometheus.yml",
169 "--storage.tsdb.path=/prometheus",
170 "--web.console.libraries=/usr/share/prometheus/console_libraries",
171 "--web.console.templates=/usr/share/prometheus/consoles",
172 "--web.route-prefix={}".format("/"),
173 "--web.external-url=http://localhost:{}{}".format(9090, "/"),
174 ],
175 "kubernetes": {
176 "readinessProbe": {
177 "httpGet": {
178 "path": "/-/ready",
179 "port": 9090,
180 },
181 "initialDelaySeconds": 10,
182 "timeoutSeconds": 30,
183 },
184 "livenessProbe": {
185 "httpGet": {
186 "path": "/-/healthy",
187 "port": 9090,
188 },
189 "initialDelaySeconds": 30,
190 "periodSeconds": 30,
191 },
192 },
193 }
194 ],
195 "kubernetesResources": {
196 "ingressResources": [
197 {
198 "name": "prometheus-ingress",
199 "annotations": {
200 "nginx.ingress.kubernetes.io/proxy-body-size": "0",
201 "nginx.ingress.kubernetes.io/ssl-redirect": "false",
202 },
203 "spec": {
204 "rules": [
205 {
206 "host": "prometheus",
207 "http": {
208 "paths": [
209 {
210 "path": "/",
211 "backend": {
212 "serviceName": "prometheus",
213 "servicePort": 9090,
214 },
215 }
216 ]
217 },
218 }
219 ]
220 },
221 }
222 ],
223 },
224 }
225
226 self.harness.charm.on.start.emit()
227
228 self.harness.update_config({"site_url": "http://prometheus"})
229
230 pod_spec, _ = self.harness.get_pod_spec()
231
232 self.assertDictEqual(expected_result, pod_spec)
233
234 def test_ingress_resources_with_https(self) -> NoReturn:
235 """Test ingress resources with HTTPS."""
236 expected_result = {
237 "version": 3,
238 "containers": [
239 {
240 "name": "prometheus",
241 "imageDetails": self.harness.charm.image.fetch(),
242 "imagePullPolicy": "Always",
243 "ports": [
244 {
245 "name": "prometheus",
246 "containerPort": 9090,
247 "protocol": "TCP",
248 }
249 ],
250 "envConfig": {},
251 "volumeConfig": [
252 {
253 "name": "config",
254 "mountPath": "/etc/prometheus",
255 "files": [
256 {
257 "path": "prometheus.yml",
258 "content": (
259 "global:\n"
260 " scrape_interval: 15s\n"
261 " evaluation_interval: 15s\n"
262 "alerting:\n"
263 " alertmanagers:\n"
264 " - static_configs:\n"
265 " - targets:\n"
266 "rule_files:\n"
267 "scrape_configs:\n"
268 " - job_name: 'prometheus'\n"
269 " static_configs:\n"
270 " - targets: [{}]\n".format("")
271 ),
272 }
273 ],
274 }
275 ],
276 "command": [
277 "/bin/prometheus",
278 "--config.file=/etc/prometheus/prometheus.yml",
279 "--storage.tsdb.path=/prometheus",
280 "--web.console.libraries=/usr/share/prometheus/console_libraries",
281 "--web.console.templates=/usr/share/prometheus/consoles",
282 "--web.route-prefix={}".format("/"),
283 "--web.external-url=http://localhost:{}{}".format(9090, "/"),
284 ],
285 "kubernetes": {
286 "readinessProbe": {
287 "httpGet": {
288 "path": "/-/ready",
289 "port": 9090,
290 },
291 "initialDelaySeconds": 10,
292 "timeoutSeconds": 30,
293 },
294 "livenessProbe": {
295 "httpGet": {
296 "path": "/-/healthy",
297 "port": 9090,
298 },
299 "initialDelaySeconds": 30,
300 "periodSeconds": 30,
301 },
302 },
303 }
304 ],
305 "kubernetesResources": {
306 "ingressResources": [
307 {
308 "name": "prometheus-ingress",
309 "annotations": {
310 "nginx.ingress.kubernetes.io/proxy-body-size": "0",
311 },
312 "spec": {
313 "rules": [
314 {
315 "host": "prometheus",
316 "http": {
317 "paths": [
318 {
319 "path": "/",
320 "backend": {
321 "serviceName": "prometheus",
322 "servicePort": 9090,
323 },
324 }
325 ]
326 },
327 }
328 ],
329 "tls": [
330 {"hosts": ["prometheus"], "secretName": "prometheus"}
331 ],
332 },
333 }
334 ],
335 },
336 }
337
338 self.harness.charm.on.start.emit()
339
340 self.harness.update_config(
341 {"site_url": "https://prometheus", "tls_secret_name": "prometheus"}
342 )
343
344 pod_spec, _ = self.harness.get_pod_spec()
345
346 self.assertDictEqual(expected_result, pod_spec)
347
348 def test_ingress_resources_with_https_and_ingress_whitelist(self) -> NoReturn:
349 """Test ingress resources with HTTPS and ingress whitelist."""
350 expected_result = {
351 "version": 3,
352 "containers": [
353 {
354 "name": "prometheus",
355 "imageDetails": self.harness.charm.image.fetch(),
356 "imagePullPolicy": "Always",
357 "ports": [
358 {
359 "name": "prometheus",
360 "containerPort": 9090,
361 "protocol": "TCP",
362 }
363 ],
364 "envConfig": {},
365 "volumeConfig": [
366 {
367 "name": "config",
368 "mountPath": "/etc/prometheus",
369 "files": [
370 {
371 "path": "prometheus.yml",
372 "content": (
373 "global:\n"
374 " scrape_interval: 15s\n"
375 " evaluation_interval: 15s\n"
376 "alerting:\n"
377 " alertmanagers:\n"
378 " - static_configs:\n"
379 " - targets:\n"
380 "rule_files:\n"
381 "scrape_configs:\n"
382 " - job_name: 'prometheus'\n"
383 " static_configs:\n"
384 " - targets: [{}]\n".format("")
385 ),
386 }
387 ],
388 }
389 ],
390 "command": [
391 "/bin/prometheus",
392 "--config.file=/etc/prometheus/prometheus.yml",
393 "--storage.tsdb.path=/prometheus",
394 "--web.console.libraries=/usr/share/prometheus/console_libraries",
395 "--web.console.templates=/usr/share/prometheus/consoles",
396 "--web.route-prefix={}".format("/"),
397 "--web.external-url=http://localhost:{}{}".format(9090, "/"),
398 ],
399 "kubernetes": {
400 "readinessProbe": {
401 "httpGet": {
402 "path": "/-/ready",
403 "port": 9090,
404 },
405 "initialDelaySeconds": 10,
406 "timeoutSeconds": 30,
407 },
408 "livenessProbe": {
409 "httpGet": {
410 "path": "/-/healthy",
411 "port": 9090,
412 },
413 "initialDelaySeconds": 30,
414 "periodSeconds": 30,
415 },
416 },
417 }
418 ],
419 "kubernetesResources": {
420 "ingressResources": [
421 {
422 "name": "prometheus-ingress",
423 "annotations": {
424 "nginx.ingress.kubernetes.io/proxy-body-size": "0",
425 "nginx.ingress.kubernetes.io/whitelist-source-range": "0.0.0.0/0",
426 },
427 "spec": {
428 "rules": [
429 {
430 "host": "prometheus",
431 "http": {
432 "paths": [
433 {
434 "path": "/",
435 "backend": {
436 "serviceName": "prometheus",
437 "servicePort": 9090,
438 },
439 }
440 ]
441 },
442 }
443 ],
444 "tls": [
445 {"hosts": ["prometheus"], "secretName": "prometheus"}
446 ],
447 },
448 }
449 ],
450 },
451 }
452
453 self.harness.charm.on.start.emit()
454
455 self.harness.update_config(
456 {
457 "site_url": "https://prometheus",
458 "tls_secret_name": "prometheus",
459 "ingress_whitelist_source_range": "0.0.0.0/0",
460 }
461 )
462
463 pod_spec, _ = self.harness.get_pod_spec()
464
465 self.assertDictEqual(expected_result, pod_spec)
466
467 def test_publish_prometheus_info(self) -> NoReturn:
468 """Test to see if prometheus relation is updated."""
469 expected_result = {
470 "host": "prometheus",
471 "port": "9090",
472 }
473
474 self.harness.charm.on.start.emit()
475
476 relation_id = self.harness.add_relation("prometheus", "mon")
477 self.harness.add_relation_unit(relation_id, "mon/0")
478 relation_data = self.harness.get_relation_data(relation_id, "prometheus")
479
480 self.assertDictEqual(expected_result, relation_data)
481
482
483 if __name__ == "__main__":
484 unittest.main()