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 """LCM 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",
55 self
.harness
.update_config(self
.config
)
57 def test_config_changed_no_relations(
60 """Test ingress resources without HTTP."""
62 self
.harness
.charm
.on
.config_changed
.emit()
65 self
.assertIsInstance(self
.harness
.charm
.unit
.status
, BlockedStatus
)
68 relation
in self
.harness
.charm
.unit
.status
.message
69 for relation
in ["mongodb", "kafka", "ro"]
73 def test_config_changed_non_leader(
76 """Test ingress resources without HTTP."""
77 self
.harness
.set_leader(is_leader
=False)
78 self
.harness
.charm
.on
.config_changed
.emit()
81 self
.assertIsInstance(self
.harness
.charm
.unit
.status
, ActiveStatus
)
83 def test_with_relations_and_mongodb_config(
86 "Test with relations and mongodb config"
87 self
.initialize_kafka_relation()
88 self
.initialize_mongo_config()
89 self
.initialize_ro_relation()
91 self
.assertNotIsInstance(self
.harness
.charm
.unit
.status
, BlockedStatus
)
93 def test_with_relations(
96 "Test with relations (internal)"
97 self
.initialize_kafka_relation()
98 self
.initialize_mongo_relation()
99 self
.initialize_ro_relation()
101 self
.assertNotIsInstance(self
.harness
.charm
.unit
.status
, BlockedStatus
)
103 def test_exception_mongodb_relation_and_config(
106 "Test with all relations and config for mongodb. Must fail"
107 self
.initialize_mongo_relation()
108 self
.initialize_mongo_config()
110 self
.assertIsInstance(self
.harness
.charm
.unit
.status
, BlockedStatus
)
112 # def test_build_pod_spec(
115 # expected_config = {
116 # "OSMLCM_GLOBAL_LOGLEVEL": self.config["log_level"],
117 # "OSMLCM_DATABASE_COMMONKEY": self.config["database_commonkey"],
119 # expected_config.update(
121 # f"OSMLCM_{k.upper()}": v
122 # for k, v in self.config.items()
123 # if k.startswith("vca_")
126 # self.harness.charm._check_missing_dependencies = mock.Mock()
127 # pod_spec = self.harness.charm.build_pod_spec(
128 # {"imageDetails": {"imagePath": "lcm-image"}}
130 # actual_config = pod_spec["containers"][0]["envConfig"]
132 # self.assertDictContainsSubset(
136 # for config_key in actual_config:
137 # self.assertNotIn("VCA_MODEL_CONFIG", config_key)
139 def test_build_pod_spec_with_model_config(
142 self
.harness
.update_config(
144 "vca_model_config_agent_metadata_url": "string",
145 "vca_model_config_agent_stream": "string",
146 "vca_model_config_apt_ftp_proxy": "string",
147 "vca_model_config_apt_http_proxy": "string",
148 "vca_model_config_apt_https_proxy": "string",
149 "vca_model_config_apt_mirror": "string",
150 "vca_model_config_apt_no_proxy": "string",
151 "vca_model_config_automatically_retry_hooks": False,
152 "vca_model_config_backup_dir": "string",
153 "vca_model_config_cloudinit_userdata": "string",
154 "vca_model_config_container_image_metadata_url": "string",
155 "vca_model_config_container_image_stream": "string",
156 "vca_model_config_container_inherit_properties": "string",
157 "vca_model_config_container_networking_method": "string",
158 "vca_model_config_default_series": "string",
159 "vca_model_config_default_space": "string",
160 "vca_model_config_development": False,
161 "vca_model_config_disable_network_management": False,
162 "vca_model_config_egress_subnets": "string",
163 "vca_model_config_enable_os_refresh_update": False,
164 "vca_model_config_enable_os_upgrade": False,
165 "vca_model_config_fan_config": "string",
166 "vca_model_config_firewall_mode": "string",
167 "vca_model_config_ftp_proxy": "string",
168 "vca_model_config_http_proxy": "string",
169 "vca_model_config_https_proxy": "string",
170 "vca_model_config_ignore_machine_addresses": False,
171 "vca_model_config_image_metadata_url": "string",
172 "vca_model_config_image_stream": "string",
173 "vca_model_config_juju_ftp_proxy": "string",
174 "vca_model_config_juju_http_proxy": "string",
175 "vca_model_config_juju_https_proxy": "string",
176 "vca_model_config_juju_no_proxy": "string",
177 "vca_model_config_logforward_enabled": False,
178 "vca_model_config_logging_config": "string",
179 "vca_model_config_lxd_snap_channel": "string",
180 "vca_model_config_max_action_results_age": "string",
181 "vca_model_config_max_action_results_size": "string",
182 "vca_model_config_max_status_history_age": "string",
183 "vca_model_config_max_status_history_size": "string",
184 "vca_model_config_net_bond_reconfigure_delay": "string",
185 "vca_model_config_no_proxy": "string",
186 "vca_model_config_provisioner_harvest_mode": "string",
187 "vca_model_config_proxy_ssh": False,
188 "vca_model_config_snap_http_proxy": "string",
189 "vca_model_config_snap_https_proxy": "string",
190 "vca_model_config_snap_store_assertions": "string",
191 "vca_model_config_snap_store_proxy": "string",
192 "vca_model_config_snap_store_proxy_url": "string",
193 "vca_model_config_ssl_hostname_verification": False,
194 "vca_model_config_test_mode": False,
195 "vca_model_config_transmit_vendor_metrics": False,
196 "vca_model_config_update_status_hook_interval": "string",
200 f
"OSMLCM_{k.upper()}": v
201 for k
, v
in self
.config
.items()
202 if k
.startswith("vca_model_config_")
205 self
.harness
.charm
._check
_missing
_dependencies
= mock
.Mock()
206 pod_spec
= self
.harness
.charm
.build_pod_spec(
207 {"imageDetails": {"imagePath": "lcm-image"}}
209 actual_config
= pod_spec
["containers"][0]["envConfig"]
211 self
.assertDictContainsSubset(
216 def initialize_kafka_relation(self
):
217 kafka_relation_id
= self
.harness
.add_relation("kafka", "kafka")
218 self
.harness
.add_relation_unit(kafka_relation_id
, "kafka/0")
219 self
.harness
.update_relation_data(
220 kafka_relation_id
, "kafka/0", {"host": "kafka", "port": 9092}
223 def initialize_mongo_config(self
):
224 self
.harness
.update_config({"mongodb_uri": "mongodb://mongo:27017"})
226 def initialize_mongo_relation(self
):
227 mongodb_relation_id
= self
.harness
.add_relation("mongodb", "mongodb")
228 self
.harness
.add_relation_unit(mongodb_relation_id
, "mongodb/0")
229 self
.harness
.update_relation_data(
232 {"connection_string": "mongodb://mongo:27017"},
235 def initialize_ro_relation(self
):
236 http_relation_id
= self
.harness
.add_relation("ro", "ro")
237 self
.harness
.add_relation_unit(http_relation_id
, "ro")
238 self
.harness
.update_relation_data(
241 {"host": "ro", "port": 9090},
245 if __name__
== "__main__":
249 # class TestCharm(unittest.TestCase):
250 # """LCM Charm unit tests."""
252 # def setUp(self) -> NoReturn:
254 # self.harness = Harness(LcmCharm)
255 # self.harness.set_leader(is_leader=True)
256 # self.harness.begin()
258 # def test_on_start_without_relations(self) -> NoReturn:
259 # """Test installation without any relation."""
260 # self.harness.charm.on.start.emit()
263 # self.assertIsInstance(self.harness.charm.unit.status, BlockedStatus)
265 # # Verifying status message
266 # self.assertGreater(len(self.harness.charm.unit.status.message), 0)
268 # self.harness.charm.unit.status.message.startswith("Waiting for ")
270 # self.assertIn("kafka", self.harness.charm.unit.status.message)
271 # self.assertIn("mongodb", self.harness.charm.unit.status.message)
272 # self.assertIn("ro", self.harness.charm.unit.status.message)
273 # self.assertTrue(self.harness.charm.unit.status.message.endswith(" relations"))
275 # def test_on_start_with_relations(self) -> NoReturn:
276 # """Test deployment without keystone."""
277 # expected_result = {
282 # "imageDetails": self.harness.charm.image.fetch(),
283 # "imagePullPolicy": "Always",
287 # "containerPort": 9999,
292 # "ALLOW_ANONYMOUS_LOGIN": "yes",
293 # "OSMLCM_GLOBAL_LOGLEVEL": "INFO",
294 # "OSMLCM_RO_HOST": "ro",
295 # "OSMLCM_RO_PORT": 9090,
296 # "OSMLCM_RO_TENANT": "osm",
297 # "OSMLCM_MESSAGE_DRIVER": "kafka",
298 # "OSMLCM_MESSAGE_HOST": "kafka",
299 # "OSMLCM_MESSAGE_PORT": 9092,
300 # "OSMLCM_DATABASE_DRIVER": "mongo",
301 # "OSMLCM_DATABASE_URI": "mongodb://mongo:27017",
302 # "OSMLCM_DATABASE_COMMONKEY": "osm",
303 # "OSMLCM_STORAGE_DRIVER": "mongo",
304 # "OSMLCM_STORAGE_PATH": "/app/storage",
305 # "OSMLCM_STORAGE_COLLECTION": "files",
306 # "OSMLCM_STORAGE_URI": "mongodb://mongo:27017",
307 # "OSMLCM_VCA_HOST": "admin",
308 # "OSMLCM_VCA_PORT": 17070,
309 # "OSMLCM_VCA_USER": "admin",
310 # "OSMLCM_VCA_PUBKEY": "secret",
311 # "OSMLCM_VCA_SECRET": "secret",
312 # "OSMLCM_VCA_CACERT": "",
313 # "OSMLCM_VCA_CLOUD": "localhost",
314 # "OSMLCM_VCA_K8S_CLOUD": "k8scloud",
318 # "kubernetesResources": {"ingressResources": []},
321 # self.harness.charm.on.start.emit()
323 # # Check if kafka datastore is initialized
324 # self.assertIsNone(self.harness.charm.state.message_host)
325 # self.assertIsNone(self.harness.charm.state.message_port)
327 # # Check if mongodb datastore is initialized
328 # self.assertIsNone(self.harness.charm.state.database_uri)
330 # # Check if RO datastore is initialized
331 # self.assertIsNone(self.harness.charm.state.ro_host)
332 # self.assertIsNone(self.harness.charm.state.ro_port)
334 # # Initializing the kafka relation
335 # kafka_relation_id = self.harness.add_relation("kafka", "kafka")
336 # self.harness.add_relation_unit(kafka_relation_id, "kafka/0")
337 # self.harness.update_relation_data(
338 # kafka_relation_id, "kafka/0", {"host": "kafka", "port": 9092}
341 # # Initializing the mongo relation
342 # mongodb_relation_id = self.harness.add_relation("mongodb", "mongodb")
343 # self.harness.add_relation_unit(mongodb_relation_id, "mongodb/0")
344 # self.harness.update_relation_data(
345 # mongodb_relation_id,
347 # {"connection_string": "mongodb://mongo:27017"},
350 # # Initializing the RO relation
351 # ro_relation_id = self.harness.add_relation("ro", "ro")
352 # self.harness.add_relation_unit(ro_relation_id, "ro/0")
353 # self.harness.update_relation_data(
354 # ro_relation_id, "ro/0", {"host": "ro", "port": 9090}
357 # # Checking if kafka data is stored
358 # self.assertEqual(self.harness.charm.state.message_host, "kafka")
359 # self.assertEqual(self.harness.charm.state.message_port, 9092)
361 # # Checking if mongodb data is stored
362 # self.assertEqual(self.harness.charm.state.database_uri, "mongodb://mongo:27017")
364 # # Checking if RO data is stored
365 # self.assertEqual(self.harness.charm.state.ro_host, "ro")
366 # self.assertEqual(self.harness.charm.state.ro_port, 9090)
369 # self.assertNotIsInstance(self.harness.charm.unit.status, BlockedStatus)
371 # pod_spec, _ = self.harness.get_pod_spec()
373 # self.assertDictEqual(expected_result, pod_spec)
375 # def test_on_kafka_relation_unit_changed(self) -> NoReturn:
376 # """Test to see if kafka relation is updated."""
377 # self.harness.charm.on.start.emit()
379 # self.assertIsNone(self.harness.charm.state.message_host)
380 # self.assertIsNone(self.harness.charm.state.message_port)
382 # relation_id = self.harness.add_relation("kafka", "kafka")
383 # self.harness.add_relation_unit(relation_id, "kafka/0")
384 # self.harness.update_relation_data(
385 # relation_id, "kafka/0", {"host": "kafka", "port": 9092}
388 # self.assertEqual(self.harness.charm.state.message_host, "kafka")
389 # self.assertEqual(self.harness.charm.state.message_port, 9092)
392 # self.assertIsInstance(self.harness.charm.unit.status, BlockedStatus)
394 # # Verifying status message
395 # self.assertGreater(len(self.harness.charm.unit.status.message), 0)
397 # self.harness.charm.unit.status.message.startswith("Waiting for ")
399 # self.assertNotIn("kafka", self.harness.charm.unit.status.message)
400 # self.assertIn("mongodb", self.harness.charm.unit.status.message)
401 # self.assertIn("ro", self.harness.charm.unit.status.message)
402 # self.assertTrue(self.harness.charm.unit.status.message.endswith(" relations"))
404 # def test_on_mongodb_unit_relation_changed(self) -> NoReturn:
405 # """Test to see if mongodb relation is updated."""
406 # self.harness.charm.on.start.emit()
408 # self.assertIsNone(self.harness.charm.state.database_uri)
410 # relation_id = self.harness.add_relation("mongodb", "mongodb")
411 # self.harness.add_relation_unit(relation_id, "mongodb/0")
412 # self.harness.update_relation_data(
413 # relation_id, "mongodb/0", {"connection_string": "mongodb://mongo:27017"}
416 # self.assertEqual(self.harness.charm.state.database_uri, "mongodb://mongo:27017")
419 # self.assertIsInstance(self.harness.charm.unit.status, BlockedStatus)
421 # # Verifying status message
422 # self.assertGreater(len(self.harness.charm.unit.status.message), 0)
424 # self.harness.charm.unit.status.message.startswith("Waiting for ")
426 # self.assertIn("kafka", self.harness.charm.unit.status.message)
427 # self.assertNotIn("mongodb", self.harness.charm.unit.status.message)
428 # self.assertIn("ro", self.harness.charm.unit.status.message)
429 # self.assertTrue(self.harness.charm.unit.status.message.endswith(" relations"))
431 # def test_on_ro_unit_relation_changed(self) -> NoReturn:
432 # """Test to see if RO relation is updated."""
433 # self.harness.charm.on.start.emit()
435 # self.assertIsNone(self.harness.charm.state.ro_host)
436 # self.assertIsNone(self.harness.charm.state.ro_port)
438 # relation_id = self.harness.add_relation("ro", "ro")
439 # self.harness.add_relation_unit(relation_id, "ro/0")
440 # self.harness.update_relation_data(
441 # relation_id, "ro/0", {"host": "ro", "port": 9090}
444 # self.assertEqual(self.harness.charm.state.ro_host, "ro")
445 # self.assertEqual(self.harness.charm.state.ro_port, 9090)
448 # self.assertIsInstance(self.harness.charm.unit.status, BlockedStatus)
450 # # Verifying status message
451 # self.assertGreater(len(self.harness.charm.unit.status.message), 0)
453 # self.harness.charm.unit.status.message.startswith("Waiting for ")
455 # self.assertIn("kafka", self.harness.charm.unit.status.message)
456 # self.assertIn("mongodb", self.harness.charm.unit.status.message)
457 # self.assertNotIn("ro", self.harness.charm.unit.status.message)
458 # self.assertTrue(self.harness.charm.unit.status.message.endswith(" relations"))
461 # if __name__ == "__main__":