blob: 3bfd69c787028e323cef0ee4d45ea8b6a9ac09df [file] [log] [blame]
beierlm4d356652023-08-25 23:00:53 +02001#!/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
23import sys
24from typing import NoReturn
25import unittest
26from unittest.mock import patch
27
28from charm import GrafanaCharm
29from ops.model import ActiveStatus, BlockedStatus
30from ops.testing import Harness
31
32
33class TestCharm(unittest.TestCase):
34 """Prometheus Charm unit tests."""
35
36 def setUp(self) -> NoReturn:
37 """Test setup"""
38 self.image_info = sys.modules["oci_image"].OCIImageResource().fetch()
39 self.harness = Harness(GrafanaCharm)
40 self.harness.set_leader(is_leader=True)
41 self.harness.begin()
42 self.config = {
43 "max_file_size": 0,
44 "ingress_whitelist_source_range": "",
45 "tls_secret_name": "",
46 "site_url": "https://grafana.192.168.100.100.nip.io",
47 "cluster_issuer": "vault-issuer",
48 "osm_dashboards": True,
49 }
50 self.harness.update_config(self.config)
51
52 def test_config_changed(
53 self,
54 ) -> NoReturn:
55 """Test ingress resources without HTTP."""
56
57 self.harness.charm.on.config_changed.emit()
58
59 # Assertions
60 self.assertIsInstance(self.harness.charm.unit.status, BlockedStatus)
61 self.assertTrue("prometheus" in self.harness.charm.unit.status.message)
62
63 def test_config_changed_non_leader(
64 self,
65 ) -> NoReturn:
66 """Test ingress resources without HTTP."""
67 self.harness.set_leader(is_leader=False)
68 self.harness.charm.on.config_changed.emit()
69
70 # Assertions
71 self.assertIsInstance(self.harness.charm.unit.status, ActiveStatus)
72
73 @patch("opslib.osm.interfaces.grafana.GrafanaCluster.set_initial_password")
74 def test_with_db_relation_and_prometheus(self, _) -> NoReturn:
75 self.initialize_prometheus_relation()
76 self.initialize_mysql_relation()
77 self.assertIsInstance(self.harness.charm.unit.status, ActiveStatus)
78
79 @patch("opslib.osm.interfaces.grafana.GrafanaCluster.set_initial_password")
80 def test_with_db_config_and_prometheus(self, _) -> NoReturn:
81 self.initialize_prometheus_relation()
82 self.initialize_mysql_config()
83 self.assertIsInstance(self.harness.charm.unit.status, ActiveStatus)
84
85 def test_with_prometheus(
86 self,
87 ) -> NoReturn:
88 """Test to see if prometheus relation is updated."""
89 self.initialize_prometheus_relation()
90 # Verifying status
91 self.assertIsInstance(self.harness.charm.unit.status, BlockedStatus)
92
93 def test_with_db_config(self) -> NoReturn:
94 "Test with mysql config"
95 self.initialize_mysql_config()
96 # Verifying status
97 self.assertIsInstance(self.harness.charm.unit.status, BlockedStatus)
98
99 @patch("opslib.osm.interfaces.grafana.GrafanaCluster.set_initial_password")
100 def test_with_db_relations(self, _) -> NoReturn:
101 "Test with relations"
102 self.initialize_mysql_relation()
103 # Verifying status
104 self.assertIsInstance(self.harness.charm.unit.status, BlockedStatus)
105
106 def test_exception_db_relation_and_config(
107 self,
108 ) -> NoReturn:
109 "Test with relations and config. Must throw exception"
110 self.initialize_mysql_config()
111 self.initialize_mysql_relation()
112 # Verifying status
113 self.assertIsInstance(self.harness.charm.unit.status, BlockedStatus)
114
115 def initialize_prometheus_relation(self):
116 relation_id = self.harness.add_relation("prometheus", "prometheus")
117 self.harness.add_relation_unit(relation_id, "prometheus/0")
118 self.harness.update_relation_data(
119 relation_id,
120 "prometheus",
121 {"hostname": "prometheus", "port": 9090},
122 )
123
124 def initialize_mysql_config(self):
125 self.harness.update_config(
126 {"mysql_uri": "mysql://grafana:$grafanapw$@host:3606/db"}
127 )
128
129 def initialize_mysql_relation(self):
130 relation_id = self.harness.add_relation("db", "mysql")
131 self.harness.add_relation_unit(relation_id, "mysql/0")
132 self.harness.update_relation_data(
133 relation_id,
134 "mysql/0",
135 {
136 "host": "mysql",
137 "port": 3306,
138 "user": "mano",
139 "password": "manopw",
140 "root_password": "rootmanopw",
141 },
142 )
143
144
145if __name__ == "__main__":
146 unittest.main()
147
148# class TestCharm(unittest.TestCase):
149# """Grafana Charm unit tests."""
150
151# def setUp(self) -> NoReturn:
152# """Test setup"""
153# self.harness = Harness(GrafanaCharm)
154# self.harness.set_leader(is_leader=True)
155# self.harness.begin()
156
157# def test_on_start_without_relations(self) -> NoReturn:
158# """Test installation without any relation."""
159# self.harness.charm.on.start.emit()
160
161# # Verifying status
162# self.assertIsInstance(self.harness.charm.unit.status, BlockedStatus)
163
164# # Verifying status message
165# self.assertGreater(len(self.harness.charm.unit.status.message), 0)
166# self.assertTrue(
167# self.harness.charm.unit.status.message.startswith("Waiting for ")
168# )
169# self.assertIn("prometheus", self.harness.charm.unit.status.message)
170# self.assertTrue(self.harness.charm.unit.status.message.endswith(" relation"))
171
172# def test_on_start_with_relations_without_http(self) -> NoReturn:
173# """Test deployment."""
174# expected_result = {
175# "version": 3,
176# "containers": [
177# {
178# "name": "grafana",
179# "imageDetails": self.harness.charm.image.fetch(),
180# "imagePullPolicy": "Always",
181# "ports": [
182# {
183# "name": "grafana",
184# "containerPort": 3000,
185# "protocol": "TCP",
186# }
187# ],
188# "envConfig": {},
189# "volumeConfig": [
190# {
191# "name": "dashboards",
192# "mountPath": "/etc/grafana/provisioning/dashboards/",
193# "files": [
194# {
195# "path": "dashboard-osm.yml",
196# "content": (
197# "apiVersion: 1\n"
198# "providers:\n"
199# " - name: 'osm'\n"
200# " orgId: 1\n"
201# " folder: ''\n"
202# " type: file\n"
203# " options:\n"
204# " path: /etc/grafana/provisioning/dashboards/\n"
205# ),
206# },
207# ],
208# },
209# {
210# "name": "datasources",
211# "mountPath": "/etc/grafana/provisioning/datasources/",
212# "files": [
213# {
214# "path": "datasource-prometheus.yml",
215# "content": (
216# "datasources:\n"
217# " - access: proxy\n"
218# " editable: true\n"
219# " is_default: true\n"
220# " name: osm_prometheus\n"
221# " orgId: 1\n"
222# " type: prometheus\n"
223# " version: 1\n"
224# " url: http://prometheus:9090\n"
225# ),
226# },
227# ],
228# },
229# ],
230# "kubernetes": {
231# "readinessProbe": {
232# "httpGet": {
233# "path": "/api/health",
234# "port": 3000,
235# },
236# "initialDelaySeconds": 10,
237# "periodSeconds": 10,
238# "timeoutSeconds": 5,
239# "successThreshold": 1,
240# "failureThreshold": 3,
241# },
242# "livenessProbe": {
243# "httpGet": {
244# "path": "/api/health",
245# "port": 3000,
246# },
247# "initialDelaySeconds": 60,
248# "timeoutSeconds": 30,
249# "failureThreshold": 10,
250# },
251# },
252# },
253# ],
254# "kubernetesResources": {"ingressResources": []},
255# }
256
257# self.harness.charm.on.start.emit()
258
259# # Initializing the prometheus relation
260# relation_id = self.harness.add_relation("prometheus", "prometheus")
261# self.harness.add_relation_unit(relation_id, "prometheus/0")
262# self.harness.update_relation_data(
263# relation_id,
264# "prometheus",
265# {
266# "hostname": "prometheus",
267# "port": "9090",
268# },
269# )
270
271# # Verifying status
272# self.assertNotIsInstance(self.harness.charm.unit.status, BlockedStatus)
273
274# pod_spec, _ = self.harness.get_pod_spec()
275
276# self.assertDictEqual(expected_result, pod_spec)
277
278# def test_ingress_resources_with_http(self) -> NoReturn:
279# """Test ingress resources with HTTP."""
280# expected_result = {
281# "version": 3,
282# "containers": [
283# {
284# "name": "grafana",
285# "imageDetails": self.harness.charm.image.fetch(),
286# "imagePullPolicy": "Always",
287# "ports": [
288# {
289# "name": "grafana",
290# "containerPort": 3000,
291# "protocol": "TCP",
292# }
293# ],
294# "envConfig": {},
295# "volumeConfig": [
296# {
297# "name": "dashboards",
298# "mountPath": "/etc/grafana/provisioning/dashboards/",
299# "files": [
300# {
301# "path": "dashboard-osm.yml",
302# "content": (
303# "apiVersion: 1\n"
304# "providers:\n"
305# " - name: 'osm'\n"
306# " orgId: 1\n"
307# " folder: ''\n"
308# " type: file\n"
309# " options:\n"
310# " path: /etc/grafana/provisioning/dashboards/\n"
311# ),
312# },
313# ],
314# },
315# {
316# "name": "datasources",
317# "mountPath": "/etc/grafana/provisioning/datasources/",
318# "files": [
319# {
320# "path": "datasource-prometheus.yml",
321# "content": (
322# "datasources:\n"
323# " - access: proxy\n"
324# " editable: true\n"
325# " is_default: true\n"
326# " name: osm_prometheus\n"
327# " orgId: 1\n"
328# " type: prometheus\n"
329# " version: 1\n"
330# " url: http://prometheus:9090\n"
331# ),
332# },
333# ],
334# },
335# ],
336# "kubernetes": {
337# "readinessProbe": {
338# "httpGet": {
339# "path": "/api/health",
340# "port": 3000,
341# },
342# "initialDelaySeconds": 10,
343# "periodSeconds": 10,
344# "timeoutSeconds": 5,
345# "successThreshold": 1,
346# "failureThreshold": 3,
347# },
348# "livenessProbe": {
349# "httpGet": {
350# "path": "/api/health",
351# "port": 3000,
352# },
353# "initialDelaySeconds": 60,
354# "timeoutSeconds": 30,
355# "failureThreshold": 10,
356# },
357# },
358# },
359# ],
360# "kubernetesResources": {
361# "ingressResources": [
362# {
363# "name": "grafana-ingress",
364# "annotations": {
365# "nginx.ingress.kubernetes.io/proxy-body-size": "0",
366# "nginx.ingress.kubernetes.io/ssl-redirect": "false",
367# },
368# "spec": {
369# "rules": [
370# {
371# "host": "grafana",
372# "http": {
373# "paths": [
374# {
375# "path": "/",
376# "backend": {
377# "serviceName": "grafana",
378# "servicePort": 3000,
379# },
380# }
381# ]
382# },
383# }
384# ]
385# },
386# }
387# ],
388# },
389# }
390
391# self.harness.charm.on.start.emit()
392
393# # Initializing the prometheus relation
394# relation_id = self.harness.add_relation("prometheus", "prometheus")
395# self.harness.add_relation_unit(relation_id, "prometheus/0")
396# self.harness.update_relation_data(
397# relation_id,
398# "prometheus",
399# {
400# "hostname": "prometheus",
401# "port": "9090",
402# },
403# )
404
405# self.harness.update_config({"site_url": "http://grafana"})
406
407# pod_spec, _ = self.harness.get_pod_spec()
408
409# self.assertDictEqual(expected_result, pod_spec)
410
411# def test_ingress_resources_with_https(self) -> NoReturn:
412# """Test ingress resources with HTTPS."""
413# expected_result = {
414# "version": 3,
415# "containers": [
416# {
417# "name": "grafana",
418# "imageDetails": self.harness.charm.image.fetch(),
419# "imagePullPolicy": "Always",
420# "ports": [
421# {
422# "name": "grafana",
423# "containerPort": 3000,
424# "protocol": "TCP",
425# }
426# ],
427# "envConfig": {},
428# "volumeConfig": [
429# {
430# "name": "dashboards",
431# "mountPath": "/etc/grafana/provisioning/dashboards/",
432# "files": [
433# {
434# "path": "dashboard-osm.yml",
435# "content": (
436# "apiVersion: 1\n"
437# "providers:\n"
438# " - name: 'osm'\n"
439# " orgId: 1\n"
440# " folder: ''\n"
441# " type: file\n"
442# " options:\n"
443# " path: /etc/grafana/provisioning/dashboards/\n"
444# ),
445# },
446# ],
447# },
448# {
449# "name": "datasources",
450# "mountPath": "/etc/grafana/provisioning/datasources/",
451# "files": [
452# {
453# "path": "datasource-prometheus.yml",
454# "content": (
455# "datasources:\n"
456# " - access: proxy\n"
457# " editable: true\n"
458# " is_default: true\n"
459# " name: osm_prometheus\n"
460# " orgId: 1\n"
461# " type: prometheus\n"
462# " version: 1\n"
463# " url: http://prometheus:9090\n"
464# ),
465# },
466# ],
467# },
468# ],
469# "kubernetes": {
470# "readinessProbe": {
471# "httpGet": {
472# "path": "/api/health",
473# "port": 3000,
474# },
475# "initialDelaySeconds": 10,
476# "periodSeconds": 10,
477# "timeoutSeconds": 5,
478# "successThreshold": 1,
479# "failureThreshold": 3,
480# },
481# "livenessProbe": {
482# "httpGet": {
483# "path": "/api/health",
484# "port": 3000,
485# },
486# "initialDelaySeconds": 60,
487# "timeoutSeconds": 30,
488# "failureThreshold": 10,
489# },
490# },
491# },
492# ],
493# "kubernetesResources": {
494# "ingressResources": [
495# {
496# "name": "grafana-ingress",
497# "annotations": {
498# "nginx.ingress.kubernetes.io/proxy-body-size": "0",
499# },
500# "spec": {
501# "rules": [
502# {
503# "host": "grafana",
504# "http": {
505# "paths": [
506# {
507# "path": "/",
508# "backend": {
509# "serviceName": "grafana",
510# "servicePort": 3000,
511# },
512# }
513# ]
514# },
515# }
516# ],
517# "tls": [{"hosts": ["grafana"], "secretName": "grafana"}],
518# },
519# }
520# ],
521# },
522# }
523
524# self.harness.charm.on.start.emit()
525
526# # Initializing the prometheus relation
527# relation_id = self.harness.add_relation("prometheus", "prometheus")
528# self.harness.add_relation_unit(relation_id, "prometheus/0")
529# self.harness.update_relation_data(
530# relation_id,
531# "prometheus",
532# {
533# "hostname": "prometheus",
534# "port": "9090",
535# },
536# )
537
538# self.harness.update_config(
539# {"site_url": "https://grafana", "tls_secret_name": "grafana"}
540# )
541
542# pod_spec, _ = self.harness.get_pod_spec()
543
544# self.assertDictEqual(expected_result, pod_spec)
545
546# def test_ingress_resources_with_https_and_ingress_whitelist(self) -> NoReturn:
547# """Test ingress resources with HTTPS and ingress whitelist."""
548# expected_result = {
549# "version": 3,
550# "containers": [
551# {
552# "name": "grafana",
553# "imageDetails": self.harness.charm.image.fetch(),
554# "imagePullPolicy": "Always",
555# "ports": [
556# {
557# "name": "grafana",
558# "containerPort": 3000,
559# "protocol": "TCP",
560# }
561# ],
562# "envConfig": {},
563# "volumeConfig": [
564# {
565# "name": "dashboards",
566# "mountPath": "/etc/grafana/provisioning/dashboards/",
567# "files": [
568# {
569# "path": "dashboard-osm.yml",
570# "content": (
571# "apiVersion: 1\n"
572# "providers:\n"
573# " - name: 'osm'\n"
574# " orgId: 1\n"
575# " folder: ''\n"
576# " type: file\n"
577# " options:\n"
578# " path: /etc/grafana/provisioning/dashboards/\n"
579# ),
580# },
581# ],
582# },
583# {
584# "name": "datasources",
585# "mountPath": "/etc/grafana/provisioning/datasources/",
586# "files": [
587# {
588# "path": "datasource-prometheus.yml",
589# "content": (
590# "datasources:\n"
591# " - access: proxy\n"
592# " editable: true\n"
593# " is_default: true\n"
594# " name: osm_prometheus\n"
595# " orgId: 1\n"
596# " type: prometheus\n"
597# " version: 1\n"
598# " url: http://prometheus:9090\n"
599# ),
600# },
601# ],
602# },
603# ],
604# "kubernetes": {
605# "readinessProbe": {
606# "httpGet": {
607# "path": "/api/health",
608# "port": 3000,
609# },
610# "initialDelaySeconds": 10,
611# "periodSeconds": 10,
612# "timeoutSeconds": 5,
613# "successThreshold": 1,
614# "failureThreshold": 3,
615# },
616# "livenessProbe": {
617# "httpGet": {
618# "path": "/api/health",
619# "port": 3000,
620# },
621# "initialDelaySeconds": 60,
622# "timeoutSeconds": 30,
623# "failureThreshold": 10,
624# },
625# },
626# },
627# ],
628# "kubernetesResources": {
629# "ingressResources": [
630# {
631# "name": "grafana-ingress",
632# "annotations": {
633# "nginx.ingress.kubernetes.io/proxy-body-size": "0",
634# "nginx.ingress.kubernetes.io/whitelist-source-range": "0.0.0.0/0",
635# },
636# "spec": {
637# "rules": [
638# {
639# "host": "grafana",
640# "http": {
641# "paths": [
642# {
643# "path": "/",
644# "backend": {
645# "serviceName": "grafana",
646# "servicePort": 3000,
647# },
648# }
649# ]
650# },
651# }
652# ],
653# "tls": [{"hosts": ["grafana"], "secretName": "grafana"}],
654# },
655# }
656# ],
657# },
658# }
659
660# self.harness.charm.on.start.emit()
661
662# # Initializing the prometheus relation
663# relation_id = self.harness.add_relation("prometheus", "prometheus")
664# self.harness.add_relation_unit(relation_id, "prometheus/0")
665# self.harness.update_relation_data(
666# relation_id,
667# "prometheus",
668# {
669# "hostname": "prometheus",
670# "port": "9090",
671# },
672# )
673
674# self.harness.update_config(
675# {
676# "site_url": "https://grafana",
677# "tls_secret_name": "grafana",
678# "ingress_whitelist_source_range": "0.0.0.0/0",
679# }
680# )
681
682# pod_spec, _ = self.harness.get_pod_spec()
683
684# self.assertDictEqual(expected_result, pod_spec)
685
686# def test_on_prometheus_unit_relation_changed(self) -> NoReturn:
687# """Test to see if prometheus relation is updated."""
688# self.harness.charm.on.start.emit()
689
690# relation_id = self.harness.add_relation("prometheus", "prometheus")
691# self.harness.add_relation_unit(relation_id, "prometheus/0")
692# self.harness.update_relation_data(
693# relation_id,
694# "prometheus",
695# {"hostname": "prometheus", "port": 9090},
696# )
697
698# # Verifying status
699# self.assertNotIsInstance(self.harness.charm.unit.status, BlockedStatus)
700
701
702if __name__ == "__main__":
703 unittest.main()