blob: 776b38454eff3921f8db1544fe85b1b74e7077d2 [file] [log] [blame]
sousaeduabe73212020-11-04 15:13:35 +00001#!/usr/bin/env python3
David Garcia49379ce2021-02-24 13:48:22 +01002# Copyright 2021 Canonical Ltd.
sousaeduabe73212020-11-04 15:13:35 +00003#
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
David Garcia49379ce2021-02-24 13:48:22 +010023import sys
sousaeduabe73212020-11-04 15:13:35 +000024from typing import NoReturn
25import unittest
sousaeduabe73212020-11-04 15:13:35 +000026
27from charm import LcmCharm
David Garciac753dc52021-03-17 15:28:47 +010028import mock
29from ops.model import ActiveStatus, BlockedStatus
30from ops.testing import Harness
sousaeduabe73212020-11-04 15:13:35 +000031
32
33class TestCharm(unittest.TestCase):
sousaedu0dc25b32021-08-30 16:33:33 +010034 """LCM Charm unit tests."""
sousaeduabe73212020-11-04 15:13:35 +000035
36 def setUp(self) -> NoReturn:
37 """Test setup"""
David Garcia49379ce2021-02-24 13:48:22 +010038 self.image_info = sys.modules["oci_image"].OCIImageResource().fetch()
sousaeduabe73212020-11-04 15:13:35 +000039 self.harness = Harness(LcmCharm)
40 self.harness.set_leader(is_leader=True)
41 self.harness.begin()
David Garcia49379ce2021-02-24 13:48:22 +010042 self.config = {
43 "vca_host": "192.168.0.13",
44 "vca_port": 17070,
45 "vca_user": "admin",
David Garciac753dc52021-03-17 15:28:47 +010046 "vca_secret": "admin",
David Garcia49379ce2021-02-24 13:48:22 +010047 "vca_pubkey": "key",
48 "vca_cacert": "cacert",
49 "vca_cloud": "cloud",
50 "vca_k8s_cloud": "k8scloud",
51 "database_commonkey": "commonkey",
sousaedu996a5602021-05-03 00:22:43 +020052 "mongodb_uri": "",
David Garcia49379ce2021-02-24 13:48:22 +010053 "log_level": "INFO",
sousaeduabe73212020-11-04 15:13:35 +000054 }
David Garcia49379ce2021-02-24 13:48:22 +010055 self.harness.update_config(self.config)
sousaeduabe73212020-11-04 15:13:35 +000056
David Garcia49379ce2021-02-24 13:48:22 +010057 def test_config_changed_no_relations(
58 self,
59 ) -> NoReturn:
60 """Test ingress resources without HTTP."""
sousaeduabe73212020-11-04 15:13:35 +000061
David Garcia49379ce2021-02-24 13:48:22 +010062 self.harness.charm.on.config_changed.emit()
sousaeduabe73212020-11-04 15:13:35 +000063
David Garcia49379ce2021-02-24 13:48:22 +010064 # Assertions
65 self.assertIsInstance(self.harness.charm.unit.status, BlockedStatus)
66 self.assertTrue(
67 all(
68 relation in self.harness.charm.unit.status.message
69 for relation in ["mongodb", "kafka", "ro"]
70 )
71 )
sousaeduabe73212020-11-04 15:13:35 +000072
David Garcia49379ce2021-02-24 13:48:22 +010073 def test_config_changed_non_leader(
74 self,
75 ) -> NoReturn:
76 """Test ingress resources without HTTP."""
77 self.harness.set_leader(is_leader=False)
78 self.harness.charm.on.config_changed.emit()
sousaeduabe73212020-11-04 15:13:35 +000079
David Garcia49379ce2021-02-24 13:48:22 +010080 # Assertions
81 self.assertIsInstance(self.harness.charm.unit.status, ActiveStatus)
82
sousaedu996a5602021-05-03 00:22:43 +020083 def test_with_relations_and_mongodb_config(
84 self,
85 ) -> NoReturn:
86 "Test with relations and mongodb config"
87 self.initialize_kafka_relation()
88 self.initialize_mongo_config()
89 self.initialize_ro_relation()
90 # Verifying status
91 self.assertNotIsInstance(self.harness.charm.unit.status, BlockedStatus)
92
David Garcia49379ce2021-02-24 13:48:22 +010093 def test_with_relations(
94 self,
95 ) -> NoReturn:
96 "Test with relations (internal)"
97 self.initialize_kafka_relation()
98 self.initialize_mongo_relation()
99 self.initialize_ro_relation()
100 # Verifying status
101 self.assertNotIsInstance(self.harness.charm.unit.status, BlockedStatus)
102
sousaedu996a5602021-05-03 00:22:43 +0200103 def test_exception_mongodb_relation_and_config(
104 self,
105 ) -> NoReturn:
106 "Test with all relations and config for mongodb. Must fail"
107 self.initialize_mongo_relation()
108 self.initialize_mongo_config()
109 # Verifying status
110 self.assertIsInstance(self.harness.charm.unit.status, BlockedStatus)
111
David Garcia141d9352021-09-08 17:48:40 +0200112 # def test_build_pod_spec(
113 # self,
114 # ) -> NoReturn:
115 # expected_config = {
116 # "OSMLCM_GLOBAL_LOGLEVEL": self.config["log_level"],
117 # "OSMLCM_DATABASE_COMMONKEY": self.config["database_commonkey"],
118 # }
119 # expected_config.update(
120 # {
121 # f"OSMLCM_{k.upper()}": v
122 # for k, v in self.config.items()
123 # if k.startswith("vca_")
124 # }
125 # )
126 # self.harness.charm._check_missing_dependencies = mock.Mock()
127 # pod_spec = self.harness.charm.build_pod_spec(
128 # {"imageDetails": {"imagePath": "lcm-image"}}
129 # )
130 # actual_config = pod_spec["containers"][0]["envConfig"]
David Garciac753dc52021-03-17 15:28:47 +0100131
David Garcia141d9352021-09-08 17:48:40 +0200132 # self.assertDictContainsSubset(
133 # expected_config,
134 # actual_config,
135 # )
136 # for config_key in actual_config:
137 # self.assertNotIn("VCA_MODEL_CONFIG", config_key)
David Garciac753dc52021-03-17 15:28:47 +0100138
139 def test_build_pod_spec_with_model_config(
140 self,
141 ) -> NoReturn:
142 self.harness.update_config(
143 {
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",
197 }
198 )
199 expected_config = {
200 f"OSMLCM_{k.upper()}": v
201 for k, v in self.config.items()
202 if k.startswith("vca_model_config_")
203 }
204
205 self.harness.charm._check_missing_dependencies = mock.Mock()
206 pod_spec = self.harness.charm.build_pod_spec(
207 {"imageDetails": {"imagePath": "lcm-image"}}
208 )
209 actual_config = pod_spec["containers"][0]["envConfig"]
210
211 self.assertDictContainsSubset(
212 expected_config,
213 actual_config,
214 )
215
David Garcia49379ce2021-02-24 13:48:22 +0100216 def initialize_kafka_relation(self):
sousaeduabe73212020-11-04 15:13:35 +0000217 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}
221 )
222
sousaedu996a5602021-05-03 00:22:43 +0200223 def initialize_mongo_config(self):
224 self.harness.update_config({"mongodb_uri": "mongodb://mongo:27017"})
225
David Garcia49379ce2021-02-24 13:48:22 +0100226 def initialize_mongo_relation(self):
sousaeduabe73212020-11-04 15:13:35 +0000227 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(
230 mongodb_relation_id,
231 "mongodb/0",
232 {"connection_string": "mongodb://mongo:27017"},
233 )
234
David Garcia49379ce2021-02-24 13:48:22 +0100235 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")
sousaeduabe73212020-11-04 15:13:35 +0000238 self.harness.update_relation_data(
David Garcia49379ce2021-02-24 13:48:22 +0100239 http_relation_id,
240 "ro",
241 {"host": "ro", "port": 9090},
sousaeduabe73212020-11-04 15:13:35 +0000242 )
243
sousaeduabe73212020-11-04 15:13:35 +0000244
245if __name__ == "__main__":
246 unittest.main()
David Garcia49379ce2021-02-24 13:48:22 +0100247
248
249# class TestCharm(unittest.TestCase):
250# """LCM Charm unit tests."""
251
252# def setUp(self) -> NoReturn:
253# """Test setup"""
254# self.harness = Harness(LcmCharm)
255# self.harness.set_leader(is_leader=True)
256# self.harness.begin()
257
258# def test_on_start_without_relations(self) -> NoReturn:
259# """Test installation without any relation."""
260# self.harness.charm.on.start.emit()
261
262# # Verifying status
263# self.assertIsInstance(self.harness.charm.unit.status, BlockedStatus)
264
265# # Verifying status message
266# self.assertGreater(len(self.harness.charm.unit.status.message), 0)
267# self.assertTrue(
268# self.harness.charm.unit.status.message.startswith("Waiting for ")
269# )
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"))
274
275# def test_on_start_with_relations(self) -> NoReturn:
276# """Test deployment without keystone."""
277# expected_result = {
278# "version": 3,
279# "containers": [
280# {
281# "name": "lcm",
282# "imageDetails": self.harness.charm.image.fetch(),
283# "imagePullPolicy": "Always",
284# "ports": [
285# {
286# "name": "lcm",
287# "containerPort": 9999,
288# "protocol": "TCP",
289# }
290# ],
291# "envConfig": {
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",
315# },
316# }
317# ],
318# "kubernetesResources": {"ingressResources": []},
319# }
320
321# self.harness.charm.on.start.emit()
322
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)
326
327# # Check if mongodb datastore is initialized
328# self.assertIsNone(self.harness.charm.state.database_uri)
329
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)
333
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}
339# )
340
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,
346# "mongodb/0",
347# {"connection_string": "mongodb://mongo:27017"},
348# )
349
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}
355# )
356
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)
360
361# # Checking if mongodb data is stored
362# self.assertEqual(self.harness.charm.state.database_uri, "mongodb://mongo:27017")
363
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)
367
368# # Verifying status
369# self.assertNotIsInstance(self.harness.charm.unit.status, BlockedStatus)
370
371# pod_spec, _ = self.harness.get_pod_spec()
372
373# self.assertDictEqual(expected_result, pod_spec)
374
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()
378
379# self.assertIsNone(self.harness.charm.state.message_host)
380# self.assertIsNone(self.harness.charm.state.message_port)
381
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}
386# )
387
388# self.assertEqual(self.harness.charm.state.message_host, "kafka")
389# self.assertEqual(self.harness.charm.state.message_port, 9092)
390
391# # Verifying status
392# self.assertIsInstance(self.harness.charm.unit.status, BlockedStatus)
393
394# # Verifying status message
395# self.assertGreater(len(self.harness.charm.unit.status.message), 0)
396# self.assertTrue(
397# self.harness.charm.unit.status.message.startswith("Waiting for ")
398# )
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"))
403
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()
407
408# self.assertIsNone(self.harness.charm.state.database_uri)
409
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"}
414# )
415
416# self.assertEqual(self.harness.charm.state.database_uri, "mongodb://mongo:27017")
417
418# # Verifying status
419# self.assertIsInstance(self.harness.charm.unit.status, BlockedStatus)
420
421# # Verifying status message
422# self.assertGreater(len(self.harness.charm.unit.status.message), 0)
423# self.assertTrue(
424# self.harness.charm.unit.status.message.startswith("Waiting for ")
425# )
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"))
430
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()
434
435# self.assertIsNone(self.harness.charm.state.ro_host)
436# self.assertIsNone(self.harness.charm.state.ro_port)
437
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}
442# )
443
444# self.assertEqual(self.harness.charm.state.ro_host, "ro")
445# self.assertEqual(self.harness.charm.state.ro_port, 9090)
446
447# # Verifying status
448# self.assertIsInstance(self.harness.charm.unit.status, BlockedStatus)
449
450# # Verifying status message
451# self.assertGreater(len(self.harness.charm.unit.status.message), 0)
452# self.assertTrue(
453# self.harness.charm.unit.status.message.startswith("Waiting for ")
454# )
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"))
459
460
461# if __name__ == "__main__":
462# unittest.main()