Adding scraping relation to Mongodb Exporter
[osm/devops.git] / installers / charm / mongodb-exporter / tests / test_charm.py
1 #!/usr/bin/env python3
2 # Copyright 2021 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 MongodbExporterCharm
30
31
32 class TestCharm(unittest.TestCase):
33 """Mongodb Exporter Charm unit tests."""
34
35 def setUp(self) -> NoReturn:
36 """Test setup"""
37 self.harness = Harness(MongodbExporterCharm)
38 self.harness.set_leader(is_leader=True)
39 self.harness.begin()
40
41 def test_on_start_without_relations(self) -> NoReturn:
42 """Test installation without any relation."""
43 self.harness.charm.on.start.emit()
44
45 # Verifying status
46 self.assertIsInstance(self.harness.charm.unit.status, BlockedStatus)
47
48 # Verifying status message
49 self.assertGreater(len(self.harness.charm.unit.status.message), 0)
50 self.assertTrue(
51 self.harness.charm.unit.status.message.startswith("Waiting for ")
52 )
53 self.assertIn("mongodb", self.harness.charm.unit.status.message)
54 self.assertTrue(self.harness.charm.unit.status.message.endswith(" relation"))
55
56 def test_on_start_with_relations_without_http(self) -> NoReturn:
57 """Test deployment."""
58 expected_result = {
59 "version": 3,
60 "containers": [
61 {
62 "name": "mongodb-exporter",
63 "imageDetails": self.harness.charm.image.fetch(),
64 "imagePullPolicy": "Always",
65 "ports": [
66 {
67 "name": "mongo-exporter",
68 "containerPort": 9216,
69 "protocol": "TCP",
70 }
71 ],
72 "envConfig": {
73 "MONGODB_URI": "mongodb://mongo",
74 },
75 "kubernetes": {
76 "readinessProbe": {
77 "httpGet": {
78 "path": "/api/health",
79 "port": 9216,
80 },
81 "initialDelaySeconds": 10,
82 "periodSeconds": 10,
83 "timeoutSeconds": 5,
84 "successThreshold": 1,
85 "failureThreshold": 3,
86 },
87 "livenessProbe": {
88 "httpGet": {
89 "path": "/api/health",
90 "port": 9216,
91 },
92 "initialDelaySeconds": 60,
93 "timeoutSeconds": 30,
94 "failureThreshold": 10,
95 },
96 },
97 },
98 ],
99 "kubernetesResources": {"ingressResources": []},
100 }
101
102 self.harness.charm.on.start.emit()
103
104 # Initializing the mongodb relation
105 relation_id = self.harness.add_relation("mongodb", "mongodb")
106 self.harness.add_relation_unit(relation_id, "mongodb/0")
107 self.harness.update_relation_data(
108 relation_id,
109 "mongodb/0",
110 {
111 "connection_string": "mongodb://mongo",
112 },
113 )
114
115 # Verifying status
116 self.assertNotIsInstance(self.harness.charm.unit.status, BlockedStatus)
117
118 pod_spec, _ = self.harness.get_pod_spec()
119
120 self.assertDictEqual(expected_result, pod_spec)
121
122 def test_ingress_resources_with_http(self) -> NoReturn:
123 """Test ingress resources with HTTP."""
124 expected_result = {
125 "version": 3,
126 "containers": [
127 {
128 "name": "mongodb-exporter",
129 "imageDetails": self.harness.charm.image.fetch(),
130 "imagePullPolicy": "Always",
131 "ports": [
132 {
133 "name": "mongo-exporter",
134 "containerPort": 9216,
135 "protocol": "TCP",
136 }
137 ],
138 "envConfig": {
139 "MONGODB_URI": "mongodb://mongo",
140 },
141 "kubernetes": {
142 "readinessProbe": {
143 "httpGet": {
144 "path": "/api/health",
145 "port": 9216,
146 },
147 "initialDelaySeconds": 10,
148 "periodSeconds": 10,
149 "timeoutSeconds": 5,
150 "successThreshold": 1,
151 "failureThreshold": 3,
152 },
153 "livenessProbe": {
154 "httpGet": {
155 "path": "/api/health",
156 "port": 9216,
157 },
158 "initialDelaySeconds": 60,
159 "timeoutSeconds": 30,
160 "failureThreshold": 10,
161 },
162 },
163 },
164 ],
165 "kubernetesResources": {
166 "ingressResources": [
167 {
168 "name": "mongodb-exporter-ingress",
169 "annotations": {
170 "nginx.ingress.kubernetes.io/ssl-redirect": "false",
171 },
172 "spec": {
173 "rules": [
174 {
175 "host": "mongodb-exporter",
176 "http": {
177 "paths": [
178 {
179 "path": "/",
180 "backend": {
181 "serviceName": "mongodb-exporter",
182 "servicePort": 9216,
183 },
184 }
185 ]
186 },
187 }
188 ]
189 },
190 }
191 ],
192 },
193 }
194
195 self.harness.charm.on.start.emit()
196
197 # Initializing the mongodb relation
198 relation_id = self.harness.add_relation("mongodb", "mongodb")
199 self.harness.add_relation_unit(relation_id, "mongodb/0")
200 self.harness.update_relation_data(
201 relation_id,
202 "mongodb/0",
203 {
204 "connection_string": "mongodb://mongo",
205 },
206 )
207
208 self.harness.update_config({"site_url": "http://mongodb-exporter"})
209
210 pod_spec, _ = self.harness.get_pod_spec()
211
212 self.assertDictEqual(expected_result, pod_spec)
213
214 def test_ingress_resources_with_https(self) -> NoReturn:
215 """Test ingress resources with HTTPS."""
216 expected_result = {
217 "version": 3,
218 "containers": [
219 {
220 "name": "mongodb-exporter",
221 "imageDetails": self.harness.charm.image.fetch(),
222 "imagePullPolicy": "Always",
223 "ports": [
224 {
225 "name": "mongo-exporter",
226 "containerPort": 9216,
227 "protocol": "TCP",
228 }
229 ],
230 "envConfig": {
231 "MONGODB_URI": "mongodb://mongo",
232 },
233 "kubernetes": {
234 "readinessProbe": {
235 "httpGet": {
236 "path": "/api/health",
237 "port": 9216,
238 },
239 "initialDelaySeconds": 10,
240 "periodSeconds": 10,
241 "timeoutSeconds": 5,
242 "successThreshold": 1,
243 "failureThreshold": 3,
244 },
245 "livenessProbe": {
246 "httpGet": {
247 "path": "/api/health",
248 "port": 9216,
249 },
250 "initialDelaySeconds": 60,
251 "timeoutSeconds": 30,
252 "failureThreshold": 10,
253 },
254 },
255 },
256 ],
257 "kubernetesResources": {
258 "ingressResources": [
259 {
260 "name": "mongodb-exporter-ingress",
261 "annotations": {},
262 "spec": {
263 "rules": [
264 {
265 "host": "mongodb-exporter",
266 "http": {
267 "paths": [
268 {
269 "path": "/",
270 "backend": {
271 "serviceName": "mongodb-exporter",
272 "servicePort": 9216,
273 },
274 }
275 ]
276 },
277 }
278 ],
279 "tls": [
280 {
281 "hosts": ["mongodb-exporter"],
282 "secretName": "mongodb-exporter",
283 }
284 ],
285 },
286 }
287 ],
288 },
289 }
290
291 self.harness.charm.on.start.emit()
292
293 # Initializing the mongodb relation
294 relation_id = self.harness.add_relation("mongodb", "mongodb")
295 self.harness.add_relation_unit(relation_id, "mongodb/0")
296 self.harness.update_relation_data(
297 relation_id,
298 "mongodb/0",
299 {
300 "connection_string": "mongodb://mongo",
301 },
302 )
303
304 self.harness.update_config(
305 {
306 "site_url": "https://mongodb-exporter",
307 "tls_secret_name": "mongodb-exporter",
308 }
309 )
310
311 pod_spec, _ = self.harness.get_pod_spec()
312
313 self.assertDictEqual(expected_result, pod_spec)
314
315 def test_ingress_resources_with_https_and_ingress_whitelist(self) -> NoReturn:
316 """Test ingress resources with HTTPS and ingress whitelist."""
317 expected_result = {
318 "version": 3,
319 "containers": [
320 {
321 "name": "mongodb-exporter",
322 "imageDetails": self.harness.charm.image.fetch(),
323 "imagePullPolicy": "Always",
324 "ports": [
325 {
326 "name": "mongo-exporter",
327 "containerPort": 9216,
328 "protocol": "TCP",
329 }
330 ],
331 "envConfig": {
332 "MONGODB_URI": "mongodb://mongo",
333 },
334 "kubernetes": {
335 "readinessProbe": {
336 "httpGet": {
337 "path": "/api/health",
338 "port": 9216,
339 },
340 "initialDelaySeconds": 10,
341 "periodSeconds": 10,
342 "timeoutSeconds": 5,
343 "successThreshold": 1,
344 "failureThreshold": 3,
345 },
346 "livenessProbe": {
347 "httpGet": {
348 "path": "/api/health",
349 "port": 9216,
350 },
351 "initialDelaySeconds": 60,
352 "timeoutSeconds": 30,
353 "failureThreshold": 10,
354 },
355 },
356 },
357 ],
358 "kubernetesResources": {
359 "ingressResources": [
360 {
361 "name": "mongodb-exporter-ingress",
362 "annotations": {
363 "nginx.ingress.kubernetes.io/whitelist-source-range": "0.0.0.0/0",
364 },
365 "spec": {
366 "rules": [
367 {
368 "host": "mongodb-exporter",
369 "http": {
370 "paths": [
371 {
372 "path": "/",
373 "backend": {
374 "serviceName": "mongodb-exporter",
375 "servicePort": 9216,
376 },
377 }
378 ]
379 },
380 }
381 ],
382 "tls": [
383 {
384 "hosts": ["mongodb-exporter"],
385 "secretName": "mongodb-exporter",
386 }
387 ],
388 },
389 }
390 ],
391 },
392 }
393
394 self.harness.charm.on.start.emit()
395
396 # Initializing the mongodb relation
397 relation_id = self.harness.add_relation("mongodb", "mongodb")
398 self.harness.add_relation_unit(relation_id, "mongodb/0")
399 self.harness.update_relation_data(
400 relation_id,
401 "mongodb/0",
402 {
403 "connection_string": "mongodb://mongo",
404 },
405 )
406
407 self.harness.update_config(
408 {
409 "site_url": "https://mongodb-exporter",
410 "tls_secret_name": "mongodb-exporter",
411 "ingress_whitelist_source_range": "0.0.0.0/0",
412 }
413 )
414
415 pod_spec, _ = self.harness.get_pod_spec()
416
417 self.assertDictEqual(expected_result, pod_spec)
418
419 def test_on_mongodb_unit_relation_changed(self) -> NoReturn:
420 """Test to see if mongodb relation is updated."""
421 self.harness.charm.on.start.emit()
422
423 # Initializing the mongodb relation
424 relation_id = self.harness.add_relation("mongodb", "mongodb")
425 self.harness.add_relation_unit(relation_id, "mongodb/0")
426 self.harness.update_relation_data(
427 relation_id,
428 "mongodb/0",
429 {
430 "connection_string": "mongodb://mongo",
431 },
432 )
433
434 # Verifying status
435 self.assertNotIsInstance(self.harness.charm.unit.status, BlockedStatus)
436
437 def test_publish_scrape_info(self) -> NoReturn:
438 """Test to see if scrape relation is updated."""
439 expected_result = {
440 "hostname": "mongodb-exporter",
441 "port": "9216",
442 "metrics_path": "/metrics",
443 "scrape_interval": "30s",
444 "scrape_timeout": "15s",
445 }
446
447 self.harness.charm.on.start.emit()
448
449 relation_id = self.harness.add_relation("prometheus-scrape", "prometheus")
450 self.harness.add_relation_unit(relation_id, "prometheus/0")
451 relation_data = self.harness.get_relation_data(
452 relation_id, "mongodb-exporter/0"
453 )
454
455 self.assertDictEqual(expected_result, relation_data)
456
457 def test_publish_scrape_info_with_site_url(self) -> NoReturn:
458 """Test to see if target relation is updated."""
459 expected_result = {
460 "hostname": "mongodb-exporter-osm",
461 "port": "80",
462 "metrics_path": "/metrics",
463 "scrape_interval": "30s",
464 "scrape_timeout": "15s",
465 }
466
467 self.harness.charm.on.start.emit()
468
469 self.harness.update_config({"site_url": "http://mongodb-exporter-osm"})
470
471 relation_id = self.harness.add_relation("prometheus-scrape", "prometheus")
472 self.harness.add_relation_unit(relation_id, "prometheus/0")
473 relation_data = self.harness.get_relation_data(
474 relation_id, "mongodb-exporter/0"
475 )
476
477 self.assertDictEqual(expected_result, relation_data)
478
479 def test_publish_dashboard_info(self) -> NoReturn:
480 """Test to see if dashboard relation is updated."""
481 self.harness.charm.on.start.emit()
482
483 relation_id = self.harness.add_relation("grafana-dashboard", "grafana")
484 self.harness.add_relation_unit(relation_id, "grafana/0")
485 relation_data = self.harness.get_relation_data(
486 relation_id, "mongodb-exporter/0"
487 )
488
489 self.assertEqual("osm-mongodb", relation_data["name"])
490 self.assertTrue("dashboard" in relation_data)
491 self.assertTrue(len(relation_data["dashboard"]) > 0)
492
493
494 if __name__ == "__main__":
495 unittest.main()