2 # Copyright 2021 Canonical Ltd.
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
8 # http://www.apache.org/licenses/LICENSE-2.0
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
16 # For those usages not covered by the Apache License, Version 2.0 please
17 # contact: legal@canonical.com
19 # To get in touch with the maintainers, please contact:
20 # osm-charmers@lists.launchpad.net
24 from typing
import NoReturn
27 from charm
import LcmCharm
29 from ops
.model
import ActiveStatus
, BlockedStatus
30 from ops
.testing
import Harness
33 class TestCharm(unittest
.TestCase
):
34 """Prometheus Charm unit tests."""
36 def setUp(self
) -> NoReturn
:
38 self
.image_info
= sys
.modules
["oci_image"].OCIImageResource().fetch()
39 self
.harness
= Harness(LcmCharm
)
40 self
.harness
.set_leader(is_leader
=True)
43 "vca_host": "192.168.0.13",
46 "vca_secret": "admin",
48 "vca_cacert": "cacert",
50 "vca_k8s_cloud": "k8scloud",
51 "database_commonkey": "commonkey",
54 self
.harness
.update_config(self
.config
)
56 def test_config_changed_no_relations(
59 """Test ingress resources without HTTP."""
61 self
.harness
.charm
.on
.config_changed
.emit()
64 self
.assertIsInstance(self
.harness
.charm
.unit
.status
, BlockedStatus
)
67 relation
in self
.harness
.charm
.unit
.status
.message
68 for relation
in ["mongodb", "kafka", "ro"]
72 def test_config_changed_non_leader(
75 """Test ingress resources without HTTP."""
76 self
.harness
.set_leader(is_leader
=False)
77 self
.harness
.charm
.on
.config_changed
.emit()
80 self
.assertIsInstance(self
.harness
.charm
.unit
.status
, ActiveStatus
)
82 def test_with_relations(
85 "Test with relations (internal)"
86 self
.initialize_kafka_relation()
87 self
.initialize_mongo_relation()
88 self
.initialize_ro_relation()
90 self
.assertNotIsInstance(self
.harness
.charm
.unit
.status
, BlockedStatus
)
92 def test_build_pod_spec(
96 "OSMLCM_GLOBAL_LOGLEVEL": self
.config
["log_level"],
97 "OSMLCM_DATABASE_COMMONKEY": self
.config
["database_commonkey"],
99 expected_config
.update(
101 f
"OSMLCM_{k.upper()}": v
102 for k
, v
in self
.config
.items()
103 if k
.startswith("vca_")
106 self
.harness
.charm
._check
_missing
_dependencies
= mock
.Mock()
107 pod_spec
= self
.harness
.charm
.build_pod_spec(
108 {"imageDetails": {"imagePath": "lcm-image"}}
110 actual_config
= pod_spec
["containers"][0]["envConfig"]
112 self
.assertDictContainsSubset(
116 for config_key
in actual_config
:
117 self
.assertNotIn("VCA_MODEL_CONFIG", config_key
)
119 def test_build_pod_spec_with_model_config(
122 self
.harness
.update_config(
124 "vca_model_config_agent_metadata_url": "string",
125 "vca_model_config_agent_stream": "string",
126 "vca_model_config_apt_ftp_proxy": "string",
127 "vca_model_config_apt_http_proxy": "string",
128 "vca_model_config_apt_https_proxy": "string",
129 "vca_model_config_apt_mirror": "string",
130 "vca_model_config_apt_no_proxy": "string",
131 "vca_model_config_automatically_retry_hooks": False,
132 "vca_model_config_backup_dir": "string",
133 "vca_model_config_cloudinit_userdata": "string",
134 "vca_model_config_container_image_metadata_url": "string",
135 "vca_model_config_container_image_stream": "string",
136 "vca_model_config_container_inherit_properties": "string",
137 "vca_model_config_container_networking_method": "string",
138 "vca_model_config_default_series": "string",
139 "vca_model_config_default_space": "string",
140 "vca_model_config_development": False,
141 "vca_model_config_disable_network_management": False,
142 "vca_model_config_egress_subnets": "string",
143 "vca_model_config_enable_os_refresh_update": False,
144 "vca_model_config_enable_os_upgrade": False,
145 "vca_model_config_fan_config": "string",
146 "vca_model_config_firewall_mode": "string",
147 "vca_model_config_ftp_proxy": "string",
148 "vca_model_config_http_proxy": "string",
149 "vca_model_config_https_proxy": "string",
150 "vca_model_config_ignore_machine_addresses": False,
151 "vca_model_config_image_metadata_url": "string",
152 "vca_model_config_image_stream": "string",
153 "vca_model_config_juju_ftp_proxy": "string",
154 "vca_model_config_juju_http_proxy": "string",
155 "vca_model_config_juju_https_proxy": "string",
156 "vca_model_config_juju_no_proxy": "string",
157 "vca_model_config_logforward_enabled": False,
158 "vca_model_config_logging_config": "string",
159 "vca_model_config_lxd_snap_channel": "string",
160 "vca_model_config_max_action_results_age": "string",
161 "vca_model_config_max_action_results_size": "string",
162 "vca_model_config_max_status_history_age": "string",
163 "vca_model_config_max_status_history_size": "string",
164 "vca_model_config_net_bond_reconfigure_delay": "string",
165 "vca_model_config_no_proxy": "string",
166 "vca_model_config_provisioner_harvest_mode": "string",
167 "vca_model_config_proxy_ssh": False,
168 "vca_model_config_snap_http_proxy": "string",
169 "vca_model_config_snap_https_proxy": "string",
170 "vca_model_config_snap_store_assertions": "string",
171 "vca_model_config_snap_store_proxy": "string",
172 "vca_model_config_snap_store_proxy_url": "string",
173 "vca_model_config_ssl_hostname_verification": False,
174 "vca_model_config_test_mode": False,
175 "vca_model_config_transmit_vendor_metrics": False,
176 "vca_model_config_update_status_hook_interval": "string",
180 f
"OSMLCM_{k.upper()}": v
181 for k
, v
in self
.config
.items()
182 if k
.startswith("vca_model_config_")
185 self
.harness
.charm
._check
_missing
_dependencies
= mock
.Mock()
186 pod_spec
= self
.harness
.charm
.build_pod_spec(
187 {"imageDetails": {"imagePath": "lcm-image"}}
189 actual_config
= pod_spec
["containers"][0]["envConfig"]
191 self
.assertDictContainsSubset(
196 def initialize_kafka_relation(self
):
197 kafka_relation_id
= self
.harness
.add_relation("kafka", "kafka")
198 self
.harness
.add_relation_unit(kafka_relation_id
, "kafka/0")
199 self
.harness
.update_relation_data(
200 kafka_relation_id
, "kafka/0", {"host": "kafka", "port": 9092}
203 def initialize_mongo_relation(self
):
204 mongodb_relation_id
= self
.harness
.add_relation("mongodb", "mongodb")
205 self
.harness
.add_relation_unit(mongodb_relation_id
, "mongodb/0")
206 self
.harness
.update_relation_data(
209 {"connection_string": "mongodb://mongo:27017"},
212 def initialize_ro_relation(self
):
213 http_relation_id
= self
.harness
.add_relation("ro", "ro")
214 self
.harness
.add_relation_unit(http_relation_id
, "ro")
215 self
.harness
.update_relation_data(
218 {"host": "ro", "port": 9090},
222 if __name__
== "__main__":
226 # class TestCharm(unittest.TestCase):
227 # """LCM Charm unit tests."""
229 # def setUp(self) -> NoReturn:
231 # self.harness = Harness(LcmCharm)
232 # self.harness.set_leader(is_leader=True)
233 # self.harness.begin()
235 # def test_on_start_without_relations(self) -> NoReturn:
236 # """Test installation without any relation."""
237 # self.harness.charm.on.start.emit()
240 # self.assertIsInstance(self.harness.charm.unit.status, BlockedStatus)
242 # # Verifying status message
243 # self.assertGreater(len(self.harness.charm.unit.status.message), 0)
245 # self.harness.charm.unit.status.message.startswith("Waiting for ")
247 # self.assertIn("kafka", self.harness.charm.unit.status.message)
248 # self.assertIn("mongodb", self.harness.charm.unit.status.message)
249 # self.assertIn("ro", self.harness.charm.unit.status.message)
250 # self.assertTrue(self.harness.charm.unit.status.message.endswith(" relations"))
252 # def test_on_start_with_relations(self) -> NoReturn:
253 # """Test deployment without keystone."""
254 # expected_result = {
259 # "imageDetails": self.harness.charm.image.fetch(),
260 # "imagePullPolicy": "Always",
264 # "containerPort": 9999,
269 # "ALLOW_ANONYMOUS_LOGIN": "yes",
270 # "OSMLCM_GLOBAL_LOGLEVEL": "INFO",
271 # "OSMLCM_RO_HOST": "ro",
272 # "OSMLCM_RO_PORT": 9090,
273 # "OSMLCM_RO_TENANT": "osm",
274 # "OSMLCM_MESSAGE_DRIVER": "kafka",
275 # "OSMLCM_MESSAGE_HOST": "kafka",
276 # "OSMLCM_MESSAGE_PORT": 9092,
277 # "OSMLCM_DATABASE_DRIVER": "mongo",
278 # "OSMLCM_DATABASE_URI": "mongodb://mongo:27017",
279 # "OSMLCM_DATABASE_COMMONKEY": "osm",
280 # "OSMLCM_STORAGE_DRIVER": "mongo",
281 # "OSMLCM_STORAGE_PATH": "/app/storage",
282 # "OSMLCM_STORAGE_COLLECTION": "files",
283 # "OSMLCM_STORAGE_URI": "mongodb://mongo:27017",
284 # "OSMLCM_VCA_HOST": "admin",
285 # "OSMLCM_VCA_PORT": 17070,
286 # "OSMLCM_VCA_USER": "admin",
287 # "OSMLCM_VCA_PUBKEY": "secret",
288 # "OSMLCM_VCA_SECRET": "secret",
289 # "OSMLCM_VCA_CACERT": "",
290 # "OSMLCM_VCA_CLOUD": "localhost",
291 # "OSMLCM_VCA_K8S_CLOUD": "k8scloud",
295 # "kubernetesResources": {"ingressResources": []},
298 # self.harness.charm.on.start.emit()
300 # # Check if kafka datastore is initialized
301 # self.assertIsNone(self.harness.charm.state.message_host)
302 # self.assertIsNone(self.harness.charm.state.message_port)
304 # # Check if mongodb datastore is initialized
305 # self.assertIsNone(self.harness.charm.state.database_uri)
307 # # Check if RO datastore is initialized
308 # self.assertIsNone(self.harness.charm.state.ro_host)
309 # self.assertIsNone(self.harness.charm.state.ro_port)
311 # # Initializing the kafka relation
312 # kafka_relation_id = self.harness.add_relation("kafka", "kafka")
313 # self.harness.add_relation_unit(kafka_relation_id, "kafka/0")
314 # self.harness.update_relation_data(
315 # kafka_relation_id, "kafka/0", {"host": "kafka", "port": 9092}
318 # # Initializing the mongo relation
319 # mongodb_relation_id = self.harness.add_relation("mongodb", "mongodb")
320 # self.harness.add_relation_unit(mongodb_relation_id, "mongodb/0")
321 # self.harness.update_relation_data(
322 # mongodb_relation_id,
324 # {"connection_string": "mongodb://mongo:27017"},
327 # # Initializing the RO relation
328 # ro_relation_id = self.harness.add_relation("ro", "ro")
329 # self.harness.add_relation_unit(ro_relation_id, "ro/0")
330 # self.harness.update_relation_data(
331 # ro_relation_id, "ro/0", {"host": "ro", "port": 9090}
334 # # Checking if kafka data is stored
335 # self.assertEqual(self.harness.charm.state.message_host, "kafka")
336 # self.assertEqual(self.harness.charm.state.message_port, 9092)
338 # # Checking if mongodb data is stored
339 # self.assertEqual(self.harness.charm.state.database_uri, "mongodb://mongo:27017")
341 # # Checking if RO data is stored
342 # self.assertEqual(self.harness.charm.state.ro_host, "ro")
343 # self.assertEqual(self.harness.charm.state.ro_port, 9090)
346 # self.assertNotIsInstance(self.harness.charm.unit.status, BlockedStatus)
348 # pod_spec, _ = self.harness.get_pod_spec()
350 # self.assertDictEqual(expected_result, pod_spec)
352 # def test_on_kafka_relation_unit_changed(self) -> NoReturn:
353 # """Test to see if kafka relation is updated."""
354 # self.harness.charm.on.start.emit()
356 # self.assertIsNone(self.harness.charm.state.message_host)
357 # self.assertIsNone(self.harness.charm.state.message_port)
359 # relation_id = self.harness.add_relation("kafka", "kafka")
360 # self.harness.add_relation_unit(relation_id, "kafka/0")
361 # self.harness.update_relation_data(
362 # relation_id, "kafka/0", {"host": "kafka", "port": 9092}
365 # self.assertEqual(self.harness.charm.state.message_host, "kafka")
366 # self.assertEqual(self.harness.charm.state.message_port, 9092)
369 # self.assertIsInstance(self.harness.charm.unit.status, BlockedStatus)
371 # # Verifying status message
372 # self.assertGreater(len(self.harness.charm.unit.status.message), 0)
374 # self.harness.charm.unit.status.message.startswith("Waiting for ")
376 # self.assertNotIn("kafka", self.harness.charm.unit.status.message)
377 # self.assertIn("mongodb", self.harness.charm.unit.status.message)
378 # self.assertIn("ro", self.harness.charm.unit.status.message)
379 # self.assertTrue(self.harness.charm.unit.status.message.endswith(" relations"))
381 # def test_on_mongodb_unit_relation_changed(self) -> NoReturn:
382 # """Test to see if mongodb relation is updated."""
383 # self.harness.charm.on.start.emit()
385 # self.assertIsNone(self.harness.charm.state.database_uri)
387 # relation_id = self.harness.add_relation("mongodb", "mongodb")
388 # self.harness.add_relation_unit(relation_id, "mongodb/0")
389 # self.harness.update_relation_data(
390 # relation_id, "mongodb/0", {"connection_string": "mongodb://mongo:27017"}
393 # self.assertEqual(self.harness.charm.state.database_uri, "mongodb://mongo:27017")
396 # self.assertIsInstance(self.harness.charm.unit.status, BlockedStatus)
398 # # Verifying status message
399 # self.assertGreater(len(self.harness.charm.unit.status.message), 0)
401 # self.harness.charm.unit.status.message.startswith("Waiting for ")
403 # self.assertIn("kafka", self.harness.charm.unit.status.message)
404 # self.assertNotIn("mongodb", self.harness.charm.unit.status.message)
405 # self.assertIn("ro", self.harness.charm.unit.status.message)
406 # self.assertTrue(self.harness.charm.unit.status.message.endswith(" relations"))
408 # def test_on_ro_unit_relation_changed(self) -> NoReturn:
409 # """Test to see if RO relation is updated."""
410 # self.harness.charm.on.start.emit()
412 # self.assertIsNone(self.harness.charm.state.ro_host)
413 # self.assertIsNone(self.harness.charm.state.ro_port)
415 # relation_id = self.harness.add_relation("ro", "ro")
416 # self.harness.add_relation_unit(relation_id, "ro/0")
417 # self.harness.update_relation_data(
418 # relation_id, "ro/0", {"host": "ro", "port": 9090}
421 # self.assertEqual(self.harness.charm.state.ro_host, "ro")
422 # self.assertEqual(self.harness.charm.state.ro_port, 9090)
425 # self.assertIsInstance(self.harness.charm.unit.status, BlockedStatus)
427 # # Verifying status message
428 # self.assertGreater(len(self.harness.charm.unit.status.message), 0)
430 # self.harness.charm.unit.status.message.startswith("Waiting for ")
432 # self.assertIn("kafka", self.harness.charm.unit.status.message)
433 # self.assertIn("mongodb", self.harness.charm.unit.status.message)
434 # self.assertNotIn("ro", self.harness.charm.unit.status.message)
435 # self.assertTrue(self.harness.charm.unit.status.message.endswith(" relations"))
438 # if __name__ == "__main__":