#!/usr/bin/env python3 # Copyright 2020 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 PrometheusCharm class TestCharm(unittest.TestCase): """Prometheus Charm unit tests.""" def setUp(self) -> NoReturn: """Test setup""" self.harness = Harness(PrometheusCharm) self.harness.set_leader(is_leader=True) self.harness.begin() def test_ingress_resources_without_http(self) -> NoReturn: """Test ingress resources without HTTP.""" expected_result = { "version": 3, "containers": [ { "name": "prometheus", "imageDetails": self.harness.charm.image.fetch(), "imagePullPolicy": "Always", "ports": [ { "name": "prometheus", "containerPort": 9090, "protocol": "TCP", } ], "envConfig": {}, "volumeConfig": [ { "name": "config", "mountPath": "/etc/prometheus", "files": [ { "path": "prometheus.yml", "content": ( "global:\n" " scrape_interval: 15s\n" " evaluation_interval: 15s\n" "alerting:\n" " alertmanagers:\n" " - static_configs:\n" " - targets:\n" "rule_files:\n" "scrape_configs:\n" " - job_name: 'prometheus'\n" " static_configs:\n" " - targets: [{}]\n".format("") ), } ], } ], "command": [ "/bin/prometheus", "--config.file=/etc/prometheus/prometheus.yml", "--storage.tsdb.path=/prometheus", "--web.console.libraries=/usr/share/prometheus/console_libraries", "--web.console.templates=/usr/share/prometheus/consoles", "--web.route-prefix={}".format("/"), "--web.external-url=http://localhost:{}{}".format(9090, "/"), ], "kubernetes": { "readinessProbe": { "httpGet": { "path": "/-/ready", "port": 9090, }, "initialDelaySeconds": 10, "timeoutSeconds": 30, }, "livenessProbe": { "httpGet": { "path": "/-/healthy", "port": 9090, }, "initialDelaySeconds": 30, "periodSeconds": 30, }, }, } ], "kubernetesResources": {"ingressResources": []}, } self.harness.charm.on.start.emit() # 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", "imageDetails": self.harness.charm.image.fetch(), "imagePullPolicy": "Always", "ports": [ { "name": "prometheus", "containerPort": 9090, "protocol": "TCP", } ], "envConfig": {}, "volumeConfig": [ { "name": "config", "mountPath": "/etc/prometheus", "files": [ { "path": "prometheus.yml", "content": ( "global:\n" " scrape_interval: 15s\n" " evaluation_interval: 15s\n" "alerting:\n" " alertmanagers:\n" " - static_configs:\n" " - targets:\n" "rule_files:\n" "scrape_configs:\n" " - job_name: 'prometheus'\n" " static_configs:\n" " - targets: [{}]\n".format("") ), } ], } ], "command": [ "/bin/prometheus", "--config.file=/etc/prometheus/prometheus.yml", "--storage.tsdb.path=/prometheus", "--web.console.libraries=/usr/share/prometheus/console_libraries", "--web.console.templates=/usr/share/prometheus/consoles", "--web.route-prefix={}".format("/"), "--web.external-url=http://localhost:{}{}".format(9090, "/"), ], "kubernetes": { "readinessProbe": { "httpGet": { "path": "/-/ready", "port": 9090, }, "initialDelaySeconds": 10, "timeoutSeconds": 30, }, "livenessProbe": { "httpGet": { "path": "/-/healthy", "port": 9090, }, "initialDelaySeconds": 30, "periodSeconds": 30, }, }, } ], "kubernetesResources": { "ingressResources": [ { "name": "prometheus-ingress", "annotations": { "nginx.ingress.kubernetes.io/proxy-body-size": "0", "nginx.ingress.kubernetes.io/ssl-redirect": "false", }, "spec": { "rules": [ { "host": "prometheus", "http": { "paths": [ { "path": "/", "backend": { "serviceName": "prometheus", "servicePort": 9090, }, } ] }, } ] }, } ], }, } self.harness.charm.on.start.emit() self.harness.update_config({"site_url": "http://prometheus"}) 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", "imageDetails": self.harness.charm.image.fetch(), "imagePullPolicy": "Always", "ports": [ { "name": "prometheus", "containerPort": 9090, "protocol": "TCP", } ], "envConfig": {}, "volumeConfig": [ { "name": "config", "mountPath": "/etc/prometheus", "files": [ { "path": "prometheus.yml", "content": ( "global:\n" " scrape_interval: 15s\n" " evaluation_interval: 15s\n" "alerting:\n" " alertmanagers:\n" " - static_configs:\n" " - targets:\n" "rule_files:\n" "scrape_configs:\n" " - job_name: 'prometheus'\n" " static_configs:\n" " - targets: [{}]\n".format("") ), } ], } ], "command": [ "/bin/prometheus", "--config.file=/etc/prometheus/prometheus.yml", "--storage.tsdb.path=/prometheus", "--web.console.libraries=/usr/share/prometheus/console_libraries", "--web.console.templates=/usr/share/prometheus/consoles", "--web.route-prefix={}".format("/"), "--web.external-url=http://localhost:{}{}".format(9090, "/"), ], "kubernetes": { "readinessProbe": { "httpGet": { "path": "/-/ready", "port": 9090, }, "initialDelaySeconds": 10, "timeoutSeconds": 30, }, "livenessProbe": { "httpGet": { "path": "/-/healthy", "port": 9090, }, "initialDelaySeconds": 30, "periodSeconds": 30, }, }, } ], "kubernetesResources": { "ingressResources": [ { "name": "prometheus-ingress", "annotations": { "nginx.ingress.kubernetes.io/proxy-body-size": "0", }, "spec": { "rules": [ { "host": "prometheus", "http": { "paths": [ { "path": "/", "backend": { "serviceName": "prometheus", "servicePort": 9090, }, } ] }, } ], "tls": [ {"hosts": ["prometheus"], "secretName": "prometheus"} ], }, } ], }, } self.harness.charm.on.start.emit() self.harness.update_config( {"site_url": "https://prometheus", "tls_secret_name": "prometheus"} ) 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", "imageDetails": self.harness.charm.image.fetch(), "imagePullPolicy": "Always", "ports": [ { "name": "prometheus", "containerPort": 9090, "protocol": "TCP", } ], "envConfig": {}, "volumeConfig": [ { "name": "config", "mountPath": "/etc/prometheus", "files": [ { "path": "prometheus.yml", "content": ( "global:\n" " scrape_interval: 15s\n" " evaluation_interval: 15s\n" "alerting:\n" " alertmanagers:\n" " - static_configs:\n" " - targets:\n" "rule_files:\n" "scrape_configs:\n" " - job_name: 'prometheus'\n" " static_configs:\n" " - targets: [{}]\n".format("") ), } ], } ], "command": [ "/bin/prometheus", "--config.file=/etc/prometheus/prometheus.yml", "--storage.tsdb.path=/prometheus", "--web.console.libraries=/usr/share/prometheus/console_libraries", "--web.console.templates=/usr/share/prometheus/consoles", "--web.route-prefix={}".format("/"), "--web.external-url=http://localhost:{}{}".format(9090, "/"), ], "kubernetes": { "readinessProbe": { "httpGet": { "path": "/-/ready", "port": 9090, }, "initialDelaySeconds": 10, "timeoutSeconds": 30, }, "livenessProbe": { "httpGet": { "path": "/-/healthy", "port": 9090, }, "initialDelaySeconds": 30, "periodSeconds": 30, }, }, } ], "kubernetesResources": { "ingressResources": [ { "name": "prometheus-ingress", "annotations": { "nginx.ingress.kubernetes.io/proxy-body-size": "0", "nginx.ingress.kubernetes.io/whitelist-source-range": "0.0.0.0/0", }, "spec": { "rules": [ { "host": "prometheus", "http": { "paths": [ { "path": "/", "backend": { "serviceName": "prometheus", "servicePort": 9090, }, } ] }, } ], "tls": [ {"hosts": ["prometheus"], "secretName": "prometheus"} ], }, } ], }, } self.harness.charm.on.start.emit() self.harness.update_config( { "site_url": "https://prometheus", "tls_secret_name": "prometheus", "ingress_whitelist_source_range": "0.0.0.0/0", } ) pod_spec, _ = self.harness.get_pod_spec() self.assertDictEqual(expected_result, pod_spec) def test_publish_prometheus_info(self) -> NoReturn: """Test to see if prometheus relation is updated.""" expected_result = { "host": "prometheus", "port": "9090", } self.harness.charm.on.start.emit() relation_id = self.harness.add_relation("prometheus", "mon") self.harness.add_relation_unit(relation_id, "mon/0") relation_data = self.harness.get_relation_data(relation_id, "prometheus") self.assertDictEqual(expected_result, relation_data) if __name__ == "__main__": unittest.main()