#!/usr/bin/env python3 # Copyright 2021 Canonical Ltd. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # # For those usages not covered by the Apache License, Version 2.0 please # contact: legal@canonical.com # # To get in touch with the maintainers, please contact: # osm-charmers@lists.launchpad.net ## from typing import NoReturn import unittest from ops.model import BlockedStatus from ops.testing import Harness from charm import PrometheusMongodbExporterCharm class TestCharm(unittest.TestCase): """Prometheus Mongodb Exporter Charm unit tests.""" def setUp(self) -> NoReturn: """Test setup""" self.harness = Harness(PrometheusMongodbExporterCharm) self.harness.set_leader(is_leader=True) self.harness.begin() def test_on_start_without_relations(self) -> NoReturn: """Test installation without any relation.""" self.harness.charm.on.start.emit() # Verifying status self.assertIsInstance(self.harness.charm.unit.status, BlockedStatus) # Verifying status message self.assertGreater(len(self.harness.charm.unit.status.message), 0) self.assertTrue( self.harness.charm.unit.status.message.startswith("Waiting for ") ) self.assertIn("mongodb", self.harness.charm.unit.status.message) self.assertTrue(self.harness.charm.unit.status.message.endswith(" relation")) def test_on_start_with_relations_without_http(self) -> NoReturn: """Test deployment.""" expected_result = { "version": 3, "containers": [ { "name": "prometheus-mongodb-exporter", "imageDetails": self.harness.charm.image.fetch(), "imagePullPolicy": "Always", "ports": [ { "name": "prometheus-mongodb-exporter", "containerPort": 9216, "protocol": "TCP", } ], "envConfig": {}, "command": [ "mongodb_exporter_linux_amd64/mongodb_exporter", "--mongodbdsn=mongodb://mongo", ], "kubernetes": { "readinessProbe": { "httpGet": { "path": "/api/health", "port": 9216, }, "initialDelaySeconds": 10, "periodSeconds": 10, "timeoutSeconds": 5, "successThreshold": 1, "failureThreshold": 3, }, "livenessProbe": { "httpGet": { "path": "/api/health", "port": 9216, }, "initialDelaySeconds": 60, "timeoutSeconds": 30, "failureThreshold": 10, }, }, }, ], "kubernetesResources": {"ingressResources": []}, } self.harness.charm.on.start.emit() # Initializing the mongodb relation relation_id = self.harness.add_relation("mongodb", "mongodb") self.harness.add_relation_unit(relation_id, "mongodb/0") self.harness.update_relation_data( relation_id, "mongodb/0", { "connection_string": "mongodb://mongo", }, ) # Verifying status self.assertNotIsInstance(self.harness.charm.unit.status, BlockedStatus) pod_spec, _ = self.harness.get_pod_spec() self.assertDictEqual(expected_result, pod_spec) def test_ingress_resources_with_http(self) -> NoReturn: """Test ingress resources with HTTP.""" expected_result = { "version": 3, "containers": [ { "name": "prometheus-mongodb-exporter", "imageDetails": self.harness.charm.image.fetch(), "imagePullPolicy": "Always", "ports": [ { "name": "prometheus-mongodb-exporter", "containerPort": 9216, "protocol": "TCP", } ], "envConfig": {}, "command": [ "mongodb_exporter_linux_amd64/mongodb_exporter", "--mongodbdsn=mongodb://mongo", ], "kubernetes": { "readinessProbe": { "httpGet": { "path": "/api/health", "port": 9216, }, "initialDelaySeconds": 10, "periodSeconds": 10, "timeoutSeconds": 5, "successThreshold": 1, "failureThreshold": 3, }, "livenessProbe": { "httpGet": { "path": "/api/health", "port": 9216, }, "initialDelaySeconds": 60, "timeoutSeconds": 30, "failureThreshold": 10, }, }, }, ], "kubernetesResources": { "ingressResources": [ { "name": "prometheus-mongodb-exporter-ingress", "annotations": { "nginx.ingress.kubernetes.io/ssl-redirect": "false", }, "spec": { "rules": [ { "host": "prometheus-mongodb-exporter", "http": { "paths": [ { "path": "/", "backend": { "serviceName": "prometheus-mongodb-exporter", "servicePort": 9216, }, } ] }, } ] }, } ], }, } self.harness.charm.on.start.emit() # Initializing the mongodb relation relation_id = self.harness.add_relation("mongodb", "mongodb") self.harness.add_relation_unit(relation_id, "mongodb/0") self.harness.update_relation_data( relation_id, "mongodb/0", { "connection_string": "mongodb://mongo", }, ) self.harness.update_config({"site_url": "http://prometheus-mongodb-exporter"}) pod_spec, _ = self.harness.get_pod_spec() self.assertDictEqual(expected_result, pod_spec) def test_ingress_resources_with_https(self) -> NoReturn: """Test ingress resources with HTTPS.""" expected_result = { "version": 3, "containers": [ { "name": "prometheus-mongodb-exporter", "imageDetails": self.harness.charm.image.fetch(), "imagePullPolicy": "Always", "ports": [ { "name": "prometheus-mongodb-exporter", "containerPort": 9216, "protocol": "TCP", } ], "envConfig": {}, "command": [ "mongodb_exporter_linux_amd64/mongodb_exporter", "--mongodbdsn=mongodb://mongo", ], "kubernetes": { "readinessProbe": { "httpGet": { "path": "/api/health", "port": 9216, }, "initialDelaySeconds": 10, "periodSeconds": 10, "timeoutSeconds": 5, "successThreshold": 1, "failureThreshold": 3, }, "livenessProbe": { "httpGet": { "path": "/api/health", "port": 9216, }, "initialDelaySeconds": 60, "timeoutSeconds": 30, "failureThreshold": 10, }, }, }, ], "kubernetesResources": { "ingressResources": [ { "name": "prometheus-mongodb-exporter-ingress", "annotations": {}, "spec": { "rules": [ { "host": "prometheus-mongodb-exporter", "http": { "paths": [ { "path": "/", "backend": { "serviceName": "prometheus-mongodb-exporter", "servicePort": 9216, }, } ] }, } ], "tls": [ { "hosts": ["prometheus-mongodb-exporter"], "secretName": "prometheus-mongodb-exporter", } ], }, } ], }, } self.harness.charm.on.start.emit() # Initializing the mongodb relation relation_id = self.harness.add_relation("mongodb", "mongodb") self.harness.add_relation_unit(relation_id, "mongodb/0") self.harness.update_relation_data( relation_id, "mongodb/0", { "connection_string": "mongodb://mongo", }, ) self.harness.update_config( { "site_url": "https://prometheus-mongodb-exporter", "tls_secret_name": "prometheus-mongodb-exporter", } ) pod_spec, _ = self.harness.get_pod_spec() self.assertDictEqual(expected_result, pod_spec) def test_ingress_resources_with_https_and_ingress_whitelist(self) -> NoReturn: """Test ingress resources with HTTPS and ingress whitelist.""" expected_result = { "version": 3, "containers": [ { "name": "prometheus-mongodb-exporter", "imageDetails": self.harness.charm.image.fetch(), "imagePullPolicy": "Always", "ports": [ { "name": "prometheus-mongodb-exporter", "containerPort": 9216, "protocol": "TCP", } ], "envConfig": {}, "command": [ "mongodb_exporter_linux_amd64/mongodb_exporter", "--mongodbdsn=mongodb://mongo", ], "kubernetes": { "readinessProbe": { "httpGet": { "path": "/api/health", "port": 9216, }, "initialDelaySeconds": 10, "periodSeconds": 10, "timeoutSeconds": 5, "successThreshold": 1, "failureThreshold": 3, }, "livenessProbe": { "httpGet": { "path": "/api/health", "port": 9216, }, "initialDelaySeconds": 60, "timeoutSeconds": 30, "failureThreshold": 10, }, }, }, ], "kubernetesResources": { "ingressResources": [ { "name": "prometheus-mongodb-exporter-ingress", "annotations": { "nginx.ingress.kubernetes.io/whitelist-source-range": "0.0.0.0/0", }, "spec": { "rules": [ { "host": "prometheus-mongodb-exporter", "http": { "paths": [ { "path": "/", "backend": { "serviceName": "prometheus-mongodb-exporter", "servicePort": 9216, }, } ] }, } ], "tls": [ { "hosts": ["prometheus-mongodb-exporter"], "secretName": "prometheus-mongodb-exporter", } ], }, } ], }, } self.harness.charm.on.start.emit() # Initializing the mongodb relation relation_id = self.harness.add_relation("mongodb", "mongodb") self.harness.add_relation_unit(relation_id, "mongodb/0") self.harness.update_relation_data( relation_id, "mongodb/0", { "connection_string": "mongodb://mongo", }, ) self.harness.update_config( { "site_url": "https://prometheus-mongodb-exporter", "tls_secret_name": "prometheus-mongodb-exporter", "ingress_whitelist_source_range": "0.0.0.0/0", } ) pod_spec, _ = self.harness.get_pod_spec() self.assertDictEqual(expected_result, pod_spec) def test_on_mongodb_unit_relation_changed(self) -> NoReturn: """Test to see if mongodb relation is updated.""" self.harness.charm.on.start.emit() # Initializing the mongodb relation relation_id = self.harness.add_relation("mongodb", "mongodb") self.harness.add_relation_unit(relation_id, "mongodb/0") self.harness.update_relation_data( relation_id, "mongodb/0", { "connection_string": "mongodb://mongo", }, ) # Verifying status self.assertNotIsInstance(self.harness.charm.unit.status, BlockedStatus) def test_publish_target_info(self) -> NoReturn: """Test to see if target relation is updated.""" expected_result = { "hostname": "prometheus-mongodb-exporter", "port": "9216", } self.harness.charm.on.start.emit() relation_id = self.harness.add_relation("prometheus-target", "prometheus") self.harness.add_relation_unit(relation_id, "prometheus/0") relation_data = self.harness.get_relation_data( relation_id, "prometheus-mongodb-exporter/0" ) self.assertDictEqual(expected_result, relation_data) def test_publish_dashboard_info(self) -> NoReturn: """Test to see if dashboard relation is updated.""" self.harness.charm.on.start.emit() relation_id = self.harness.add_relation("grafana-dashboard", "grafana") self.harness.add_relation_unit(relation_id, "grafana/0") relation_data = self.harness.get_relation_data( relation_id, "prometheus-mongodb-exporter/0" ) self.assertTrue("dashboard" in relation_data) self.assertTrue(len(relation_data["dashboard"]) > 0) if __name__ == "__main__": unittest.main()