4c6b0cba14819604d34578d1461e7ee9ae9009d5
[osm/devops.git] / installers / charm / lcm / tests / test_pod_spec.py
1 #!/usr/bin/env python3
2 # Copyright 2020 Canonical Ltd.
3 #
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
23 from pydantic import ValidationError
24 from typing import NoReturn
25 import unittest
26
27 import pod_spec
28
29
30 class TestPodSpec(unittest.TestCase):
31 """Pod spec unit tests."""
32
33 def test_make_pod_ports(self) -> NoReturn:
34 """Testing make pod ports."""
35 port = 9999
36
37 expected_result = [
38 {
39 "name": "lcm",
40 "containerPort": port,
41 "protocol": "TCP",
42 }
43 ]
44
45 pod_ports = pod_spec._make_pod_ports(9999)
46
47 self.assertListEqual(expected_result, pod_ports)
48
49 def test_make_pod_envconfig_without_vca_apiproxy(self) -> NoReturn:
50 """Teting make pod envconfig without vca_apiproxy configuration."""
51 config = {
52 "database_commonkey": "commonkey",
53 "log_level": "INFO",
54 "vca_host": "vca",
55 "vca_port": 1212,
56 "vca_user": "vca_user",
57 "vca_pubkey": "vca_pubkey",
58 "vca_password": "vca_password",
59 "vca_cacert": "vca_cacert",
60 "vca_cloud": "vca_cloud",
61 "vca_k8s_cloud": "vca_k8s_cloud",
62 }
63 relation_state = {
64 "message_host": "kafka",
65 "message_port": 2181,
66 "database_uri": "mongodb://mongo",
67 "ro_host": "ro",
68 "ro_port": 9090,
69 }
70
71 expected_result = {
72 "ALLOW_ANONYMOUS_LOGIN": "yes",
73 "OSMLCM_GLOBAL_LOGLEVEL": config["log_level"],
74 "OSMLCM_RO_HOST": relation_state["ro_host"],
75 "OSMLCM_RO_PORT": relation_state["ro_port"],
76 "OSMLCM_RO_TENANT": "osm",
77 "OSMLCM_MESSAGE_DRIVER": "kafka",
78 "OSMLCM_MESSAGE_HOST": relation_state["message_host"],
79 "OSMLCM_MESSAGE_PORT": relation_state["message_port"],
80 "OSMLCM_DATABASE_DRIVER": "mongo",
81 "OSMLCM_DATABASE_URI": relation_state["database_uri"],
82 "OSMLCM_DATABASE_COMMONKEY": config["database_commonkey"],
83 "OSMLCM_STORAGE_DRIVER": "mongo",
84 "OSMLCM_STORAGE_PATH": "/app/storage",
85 "OSMLCM_STORAGE_COLLECTION": "files",
86 "OSMLCM_STORAGE_URI": relation_state["database_uri"],
87 "OSMLCM_VCA_HOST": config["vca_host"],
88 "OSMLCM_VCA_PORT": config["vca_port"],
89 "OSMLCM_VCA_USER": config["vca_user"],
90 "OSMLCM_VCA_PUBKEY": config["vca_pubkey"],
91 "OSMLCM_VCA_SECRET": config["vca_password"],
92 "OSMLCM_VCA_CACERT": config["vca_cacert"],
93 "OSMLCM_VCA_CLOUD": config["vca_cloud"],
94 "OSMLCM_VCA_K8S_CLOUD": config["vca_k8s_cloud"],
95 }
96
97 pod_envconfig = pod_spec._make_pod_envconfig(config, relation_state)
98
99 self.assertDictEqual(expected_result, pod_envconfig)
100
101 def test_make_pod_envconfig_with_vca_apiproxy(self) -> NoReturn:
102 """Teting make pod envconfig with vca_apiproxy configuration."""
103 config = {
104 "database_commonkey": "commonkey",
105 "log_level": "INFO",
106 "vca_host": "vca",
107 "vca_port": 1212,
108 "vca_user": "vca_user",
109 "vca_pubkey": "vca_pubkey",
110 "vca_password": "vca_password",
111 "vca_cacert": "vca_cacert",
112 "vca_cloud": "vca_cloud",
113 "vca_k8s_cloud": "vca_k8s_cloud",
114 "vca_apiproxy": "vca_apiproxy",
115 }
116 relation_state = {
117 "message_host": "kafka",
118 "message_port": 2181,
119 "database_uri": "mongodb://mongo",
120 "ro_host": "ro",
121 "ro_port": 9090,
122 }
123
124 expected_result = {
125 "ALLOW_ANONYMOUS_LOGIN": "yes",
126 "OSMLCM_GLOBAL_LOGLEVEL": config["log_level"],
127 "OSMLCM_RO_HOST": relation_state["ro_host"],
128 "OSMLCM_RO_PORT": relation_state["ro_port"],
129 "OSMLCM_RO_TENANT": "osm",
130 "OSMLCM_MESSAGE_DRIVER": "kafka",
131 "OSMLCM_MESSAGE_HOST": relation_state["message_host"],
132 "OSMLCM_MESSAGE_PORT": relation_state["message_port"],
133 "OSMLCM_DATABASE_DRIVER": "mongo",
134 "OSMLCM_DATABASE_URI": relation_state["database_uri"],
135 "OSMLCM_DATABASE_COMMONKEY": config["database_commonkey"],
136 "OSMLCM_STORAGE_DRIVER": "mongo",
137 "OSMLCM_STORAGE_PATH": "/app/storage",
138 "OSMLCM_STORAGE_COLLECTION": "files",
139 "OSMLCM_STORAGE_URI": relation_state["database_uri"],
140 "OSMLCM_VCA_HOST": config["vca_host"],
141 "OSMLCM_VCA_PORT": config["vca_port"],
142 "OSMLCM_VCA_USER": config["vca_user"],
143 "OSMLCM_VCA_PUBKEY": config["vca_pubkey"],
144 "OSMLCM_VCA_SECRET": config["vca_password"],
145 "OSMLCM_VCA_CACERT": config["vca_cacert"],
146 "OSMLCM_VCA_CLOUD": config["vca_cloud"],
147 "OSMLCM_VCA_K8S_CLOUD": config["vca_k8s_cloud"],
148 "OSMLCM_VCA_APIPROXY": config["vca_apiproxy"],
149 }
150
151 pod_envconfig = pod_spec._make_pod_envconfig(config, relation_state)
152
153 self.assertDictEqual(expected_result, pod_envconfig)
154
155 def test_make_startup_probe(self) -> NoReturn:
156 """Testing make startup probe."""
157 expected_result = {
158 "exec": {"command": ["/usr/bin/pgrep python3"]},
159 "initialDelaySeconds": 60,
160 "timeoutSeconds": 5,
161 }
162
163 startup_probe = pod_spec._make_startup_probe()
164
165 self.assertDictEqual(expected_result, startup_probe)
166
167 def test_make_readiness_probe(self) -> NoReturn:
168 """Testing make readiness probe."""
169 port = 9999
170
171 expected_result = {
172 "httpGet": {
173 "path": "/osm/",
174 "port": port,
175 },
176 "initialDelaySeconds": 45,
177 "timeoutSeconds": 5,
178 }
179
180 readiness_probe = pod_spec._make_readiness_probe(port)
181
182 self.assertDictEqual(expected_result, readiness_probe)
183
184 def test_make_liveness_probe(self) -> NoReturn:
185 """Testing make liveness probe."""
186 port = 9999
187
188 expected_result = {
189 "httpGet": {
190 "path": "/osm/",
191 "port": port,
192 },
193 "initialDelaySeconds": 45,
194 "timeoutSeconds": 5,
195 }
196
197 liveness_probe = pod_spec._make_liveness_probe(port)
198
199 self.assertDictEqual(expected_result, liveness_probe)
200
201 def test_make_pod_spec(self) -> NoReturn:
202 """Testing make pod spec."""
203 image_info = {"upstream-source": "opensourcemano/lcm:8"}
204 config = {
205 "database_commonkey": "commonkey",
206 "log_level": "INFO",
207 "vca_host": "vca",
208 "vca_port": 1212,
209 "vca_user": "vca_user",
210 "vca_pubkey": "vca_pubkey",
211 "vca_password": "vca_password",
212 "vca_cacert": "vca_cacert",
213 "vca_cloud": "vca_cloud",
214 "vca_k8s_cloud": "vca_k8s_cloud",
215 "vca_apiproxy": "vca_apiproxy",
216 }
217 relation_state = {
218 "message_host": "kafka",
219 "message_port": 2181,
220 "database_uri": "mongodb://mongo",
221 "ro_host": "ro",
222 "ro_port": 9090,
223 }
224 app_name = "lcm"
225 port = 9999
226
227 expected_result = {
228 "version": 3,
229 "containers": [
230 {
231 "name": app_name,
232 "imageDetails": image_info,
233 "imagePullPolicy": "Always",
234 "ports": [
235 {
236 "name": app_name,
237 "containerPort": port,
238 "protocol": "TCP",
239 }
240 ],
241 "envConfig": {
242 "ALLOW_ANONYMOUS_LOGIN": "yes",
243 "OSMLCM_GLOBAL_LOGLEVEL": config["log_level"],
244 "OSMLCM_RO_HOST": relation_state["ro_host"],
245 "OSMLCM_RO_PORT": relation_state["ro_port"],
246 "OSMLCM_RO_TENANT": "osm",
247 "OSMLCM_MESSAGE_DRIVER": "kafka",
248 "OSMLCM_MESSAGE_HOST": relation_state["message_host"],
249 "OSMLCM_MESSAGE_PORT": relation_state["message_port"],
250 "OSMLCM_DATABASE_DRIVER": "mongo",
251 "OSMLCM_DATABASE_URI": relation_state["database_uri"],
252 "OSMLCM_DATABASE_COMMONKEY": config["database_commonkey"],
253 "OSMLCM_STORAGE_DRIVER": "mongo",
254 "OSMLCM_STORAGE_PATH": "/app/storage",
255 "OSMLCM_STORAGE_COLLECTION": "files",
256 "OSMLCM_STORAGE_URI": relation_state["database_uri"],
257 "OSMLCM_VCA_HOST": config["vca_host"],
258 "OSMLCM_VCA_PORT": config["vca_port"],
259 "OSMLCM_VCA_USER": config["vca_user"],
260 "OSMLCM_VCA_PUBKEY": config["vca_pubkey"],
261 "OSMLCM_VCA_SECRET": config["vca_password"],
262 "OSMLCM_VCA_CACERT": config["vca_cacert"],
263 "OSMLCM_VCA_CLOUD": config["vca_cloud"],
264 "OSMLCM_VCA_K8S_CLOUD": config["vca_k8s_cloud"],
265 "OSMLCM_VCA_APIPROXY": config["vca_apiproxy"],
266 },
267 }
268 ],
269 "kubernetesResources": {"ingressResources": []},
270 }
271
272 spec = pod_spec.make_pod_spec(
273 image_info, config, relation_state, app_name, port
274 )
275
276 self.assertDictEqual(expected_result, spec)
277
278 def test_make_pod_spec_with_vca_apiproxy(self) -> NoReturn:
279 """Testing make pod spec with vca_apiproxy."""
280 image_info = {"upstream-source": "opensourcemano/lcm:8"}
281 config = {
282 "database_commonkey": "commonkey",
283 "log_level": "INFO",
284 "vca_host": "vca",
285 "vca_port": 1212,
286 "vca_user": "vca_user",
287 "vca_pubkey": "vca_pubkey",
288 "vca_password": "vca_password",
289 "vca_cacert": "vca_cacert",
290 "vca_cloud": "vca_cloud",
291 "vca_k8s_cloud": "vca_k8s_cloud",
292 }
293 relation_state = {
294 "message_host": "kafka",
295 "message_port": 2181,
296 "database_uri": "mongodb://mongo",
297 "ro_host": "ro",
298 "ro_port": 9090,
299 }
300 app_name = "lcm"
301 port = 9999
302
303 expected_result = {
304 "version": 3,
305 "containers": [
306 {
307 "name": app_name,
308 "imageDetails": image_info,
309 "imagePullPolicy": "Always",
310 "ports": [
311 {
312 "name": app_name,
313 "containerPort": port,
314 "protocol": "TCP",
315 }
316 ],
317 "envConfig": {
318 "ALLOW_ANONYMOUS_LOGIN": "yes",
319 "OSMLCM_GLOBAL_LOGLEVEL": config["log_level"],
320 "OSMLCM_RO_HOST": relation_state["ro_host"],
321 "OSMLCM_RO_PORT": relation_state["ro_port"],
322 "OSMLCM_RO_TENANT": "osm",
323 "OSMLCM_MESSAGE_DRIVER": "kafka",
324 "OSMLCM_MESSAGE_HOST": relation_state["message_host"],
325 "OSMLCM_MESSAGE_PORT": relation_state["message_port"],
326 "OSMLCM_DATABASE_DRIVER": "mongo",
327 "OSMLCM_DATABASE_URI": relation_state["database_uri"],
328 "OSMLCM_DATABASE_COMMONKEY": config["database_commonkey"],
329 "OSMLCM_STORAGE_DRIVER": "mongo",
330 "OSMLCM_STORAGE_PATH": "/app/storage",
331 "OSMLCM_STORAGE_COLLECTION": "files",
332 "OSMLCM_STORAGE_URI": relation_state["database_uri"],
333 "OSMLCM_VCA_HOST": config["vca_host"],
334 "OSMLCM_VCA_PORT": config["vca_port"],
335 "OSMLCM_VCA_USER": config["vca_user"],
336 "OSMLCM_VCA_PUBKEY": config["vca_pubkey"],
337 "OSMLCM_VCA_SECRET": config["vca_password"],
338 "OSMLCM_VCA_CACERT": config["vca_cacert"],
339 "OSMLCM_VCA_CLOUD": config["vca_cloud"],
340 "OSMLCM_VCA_K8S_CLOUD": config["vca_k8s_cloud"],
341 },
342 }
343 ],
344 "kubernetesResources": {"ingressResources": []},
345 }
346
347 spec = pod_spec.make_pod_spec(
348 image_info, config, relation_state, app_name, port
349 )
350
351 self.assertDictEqual(expected_result, spec)
352
353 def test_make_pod_spec_without_image_info(self) -> NoReturn:
354 """Testing make pod spec without image_info."""
355 image_info = None
356 config = {
357 "database_commonkey": "commonkey",
358 "log_level": "INFO",
359 "vca_host": "vca",
360 "vca_port": 1212,
361 "vca_user": "vca_user",
362 "vca_pubkey": "vca_pubkey",
363 "vca_password": "vca_password",
364 "vca_cacert": "vca_cacert",
365 "vca_cloud": "vca_cloud",
366 "vca_k8s_cloud": "vca_k8s_cloud",
367 "vca_apiproxy": "vca_apiproxy",
368 }
369 relation_state = {
370 "message_host": "kafka",
371 "message_port": 2181,
372 "database_uri": "mongodb://mongo",
373 "ro_host": "ro",
374 "ro_port": 9090,
375 }
376 app_name = "lcm"
377 port = 9999
378
379 spec = pod_spec.make_pod_spec(
380 image_info, config, relation_state, app_name, port
381 )
382
383 self.assertIsNone(spec)
384
385 def test_make_pod_spec_without_config(self) -> NoReturn:
386 """Testing make pod spec without config."""
387 image_info = {"upstream-source": "opensourcemano/lcm:8"}
388 config = {}
389 relation_state = {
390 "message_host": "kafka",
391 "message_port": 2181,
392 "database_uri": "mongodb://mongo",
393 "ro_host": "ro",
394 "ro_port": 9090,
395 }
396 app_name = "lcm"
397 port = 9999
398
399 with self.assertRaises(ValidationError):
400 pod_spec.make_pod_spec(image_info, config, relation_state, app_name, port)
401
402 def test_make_pod_spec_without_relation_state(self) -> NoReturn:
403 """Testing make pod spec without relation_state."""
404 image_info = {"upstream-source": "opensourcemano/lcm:8"}
405 config = {
406 "database_commonkey": "commonkey",
407 "log_level": "INFO",
408 "vca_host": "vca",
409 "vca_port": 1212,
410 "vca_user": "vca_user",
411 "vca_pubkey": "vca_pubkey",
412 "vca_password": "vca_password",
413 "vca_cacert": "vca_cacert",
414 "vca_cloud": "vca_cloud",
415 "vca_k8s_cloud": "vca_k8s_cloud",
416 "vca_apiproxy": "vca_apiproxy",
417 }
418 relation_state = {}
419 app_name = "lcm"
420 port = 9999
421
422 with self.assertRaises(ValidationError):
423 pod_spec.make_pod_spec(image_info, config, relation_state, app_name, port)
424
425
426 if __name__ == "__main__":
427 unittest.main()