Feature-9904: Enhancing NG-UI to enable Juju operational view dashboard
[osm/N2VC.git] / n2vc / tests / unit / utils.py
1 # Copyright 2020 Canonical Ltd.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 import asyncio
16
17 from n2vc.utils import Dict, N2VCDeploymentStatus
18 from n2vc.n2vc_conn import N2VCConnector
19 from unittest.mock import MagicMock
20
21
22 kubeconfig = """apiVersion: v1
23 clusters:
24 - cluster:
25 certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1\
26 JSURBVENDQWVtZ0F3SUJBZ0lKQUxjMk9xVUpwcnVCTUEwR0NTcUdTSWIzRFFFQk\
27 N3VUFNQmN4RlRBVEJnTlYKQkFNTURERXdMakUxTWk0eE9ETXVNVEFlRncweU1EQ\
28 TVNVEV4TkRJeU16VmFGdzB6TURBNU1Ea3hOREl5TXpWYQpNQmN4RlRBVEJnTlZC\
29 QU1NRERFd0xqRTFNaTR4T0RNdU1UQ0NBU0l3RFFZSktvWklodmNOQVFFQkJRQUR\
30 nZ0VQCkFEQ0NBUW9DZ2dFQkFNV0tyQkdxWlJRT0VONDExR2RESmY2ckZWRDcvMU\
31 xHNlZMWjNhd1BRdHBhRTRxdVdyNisKWjExTWwra2kwVEU1cGZFV3dKenVUZXlCU\
32 XVkUEpnYm1QTjF1VWROdGRiNlpocHEzeC9oT0hCMVJLNC9iSlNFUgpiZ0dITmN6\
33 MzR6SHRaZ1dwb2NPTXpPOW9oRUdhMTZUaDhmQWVxYU1CQTJRaklmeUFlaVp3VHJ\
34 nZ3BrY2dBMUlOCjBvQkdqSURnSGVoSU5tbGZOOURkQ3hNN1FNTmtSbzRXdE13bF\
35 JSRWZ4QnFiVkNpZGFjbVhhb1VPUjJPeFVmQWEKN1orSUU1TmN5ZFQ1TGovazdwd\
36 XZCVkdIa0JQWnE0TmlBa3R4aXd5NVB5R29GTk9mT0NrV2I2VnBzVzNhTlNJeAo4\
37 aXBITkc3enV3elc1TGQ5TkhQYWpRckZwdFZBSHpJNWNhRUNBd0VBQWFOUU1FNHd\
38 IUVlEVlIwT0JCWUVGQ1dVCkFaTXNaeE13L1k1OGlXMGZJWVAzcDdTYk1COEdBMV\
39 VkSXdRWU1CYUFGQ1dVQVpNc1p4TXcvWTU4aVcwZklZUDMKcDdTYk1Bd0dBMVVkR\
40 XdRRk1BTUJBZjh3RFFZSktvWklodmNOQVFFTEJRQURnZ0VCQUJaMlYxMWowRzhh\
41 Z1Z6Twp2YWtKTGt4UGZ0UE1NMFFOaVRzZmV6RzlicnBkdEVLSjFyalFCblNXYTN\
42 WbThWRGZTYkhLQUNXaGh0OEhzcXhtCmNzdVQyOWUyaGZBNHVIOUxMdy9MVG5EdE\
43 tJSjZ6aWFzaTM5RGh3UGwwaExuamJRMjk4VVo5TGovVlpnZGlqemIKWnVPdHlpT\
44 nVOS0E2Nmd0dGxXcWZRQ2hkbnJ5MlZUbjBjblR5dU9UalByYWdOdXJMdlVwL3Nl\
45 eURhZmsxNXJ4egozcmlYZldiQnRhUUk1dnM0ekFKU2xneUg2RnpiZStoTUhlUzF\
46 mM2ppb3dJV0lRR2NNbHpGT1RpMm1xWFRybEJYCnh1WmpLZlpOcndjQVNGbk9qYV\
47 BWeFQ1ODJ4WWhtTm8wR3J2MlZEck51bDlSYkgvK3lNS2J5NEhkOFRvVThMU2kKY\
48 3Uxajh3cz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
49 server: https://192.168.0.22:16443
50 name: microk8s-cluster
51 contexts:
52 - context:
53 cluster: microk8s-cluster
54 user: admin
55 name: microk8s
56 current-context: microk8s
57 kind: Config
58 preferences: {}
59 users:
60 - name: admin
61 user:
62 token: clhkRExRem5Xd1dCdnFEVXdvRGtDRGE5b1F3WnNrZk5qeHFCOU10bHBZRT0K
63 """
64
65
66 async def AsyncMockFunc():
67 await asyncio.sleep(1)
68
69
70 class AsyncMock(MagicMock):
71 async def __call__(self, *args, **kwargs):
72 return super(AsyncMock, self).__call__(*args, **kwargs)
73
74
75 class FakeN2VC(MagicMock):
76 last_written_values = None
77
78 async def write_app_status_to_db(
79 self,
80 db_dict: dict,
81 status: N2VCDeploymentStatus,
82 detailed_status: str,
83 vca_status: str,
84 entity_type: str,
85 ):
86 self.last_written_values = Dict(
87 {
88 "n2vc_status": status,
89 "message": detailed_status,
90 "vca_status": vca_status,
91 "entity": entity_type,
92 }
93 )
94
95 osm_status = N2VCConnector.osm_status
96
97
98 class FakeMachine(MagicMock):
99 entity_id = "2"
100 dns_name = "FAKE ENDPOINT"
101 model_name = "FAKE MODEL"
102 entity_type = "machine"
103 safe_data = {"instance-id": "myid"}
104
105 async def destroy(self, force):
106 pass
107
108
109 class FakeManualMachine(MagicMock):
110 entity_id = "2"
111 dns_name = "FAKE ENDPOINT"
112 model_name = "FAKE MODEL"
113 entity_type = "machine"
114 safe_data = {"instance-id": "manual:myid"}
115
116 async def destroy(self, force):
117 pass
118
119
120 class FakeWatcher(AsyncMock):
121
122 delta_to_return = None
123
124 async def Next(self):
125 return Dict({"deltas": self.delta_to_return})
126
127
128 class FakeConnection(MagicMock):
129 endpoint = None
130 is_open = False
131
132
133 class FakeAction(MagicMock):
134 entity_id = "id"
135 status = "ready"
136
137
138 class FakeModel:
139 def __init__(self, applications: dict = {}):
140 self._applications = applications
141
142 @property
143 def applications(self):
144 return self._applications
145
146
147 class FakeUnit(MagicMock):
148 async def is_leader_from_status(self):
149 return True
150
151 async def run_action(self, action_name):
152 return FakeAction()
153
154
155 class FakeApplication(AsyncMock):
156 async def set_config(self, config):
157 pass
158
159 async def add_unit(self, to):
160 pass
161
162 async def get_actions(self):
163 return ["existing_action"]
164
165 async def get_config(self):
166 return ["app_config"]
167
168 units = [FakeUnit(), FakeUnit()]
169
170
171 class FakeFile:
172 def __init__(self, content: str = ""):
173 self.content = content
174
175 def read(self, size: int = -1):
176 return self.content
177
178
179 class FakeFileWrapper:
180 def __init__(self, content: str = ""):
181 self.file = FakeFile(content=content)
182
183 def __enter__(self):
184 return self.file
185
186 def __exit__(self, type, value, traceback):
187 pass
188
189
190 FAKE_DELTA_MACHINE_PENDING = Dict(
191 {
192 "deltas": ["machine", "change", {}],
193 "entity": "machine",
194 "type": "change",
195 "data": {
196 "id": "2",
197 "instance-id": "juju-1b5808-2",
198 "agent-status": {"current": "pending", "message": "", "version": ""},
199 "instance-status": {"current": "running", "message": "Running"},
200 },
201 }
202 )
203 FAKE_DELTA_MACHINE_STARTED = Dict(
204 {
205 "deltas": ["machine", "change", {}],
206 "entity": "machine",
207 "type": "change",
208 "data": {
209 "id": "2",
210 "instance-id": "juju-1b5808-2",
211 "agent-status": {"current": "started", "message": "", "version": ""},
212 "instance-status": {"current": "running", "message": "Running"},
213 },
214 }
215 )
216
217 FAKE_DELTA_UNIT_PENDING = Dict(
218 {
219 "deltas": ["unit", "change", {}],
220 "entity": "unit",
221 "type": "change",
222 "data": {
223 "name": "git/0",
224 "application": "git",
225 "machine-id": "6",
226 "workload-status": {"current": "waiting", "message": ""},
227 "agent-status": {"current": "idle", "message": ""},
228 },
229 }
230 )
231
232 FAKE_DELTA_UNIT_STARTED = Dict(
233 {
234 "deltas": ["unit", "change", {}],
235 "entity": "unit",
236 "type": "change",
237 "data": {
238 "name": "git/0",
239 "application": "git",
240 "machine-id": "6",
241 "workload-status": {"current": "active", "message": ""},
242 "agent-status": {"current": "idle", "message": ""},
243 },
244 }
245 )
246
247 FAKE_DELTA_APPLICATION_MAINTENANCE = Dict(
248 {
249 "deltas": ["application", "change", {}],
250 "entity": "application",
251 "type": "change",
252 "data": {
253 "name": "git",
254 "status": {
255 "current": "maintenance",
256 "message": "installing charm software",
257 },
258 },
259 }
260 )
261
262 FAKE_DELTA_APPLICATION_ACTIVE = Dict(
263 {
264 "deltas": ["application", "change", {}],
265 "entity": "application",
266 "type": "change",
267 "data": {"name": "git", "status": {"current": "active", "message": "Ready!"}},
268 }
269 )
270
271 FAKE_DELTA_ACTION_COMPLETED = Dict(
272 {
273 "deltas": ["action", "change", {}],
274 "entity": "action",
275 "type": "change",
276 "data": {
277 "model-uuid": "af19cdd4-374a-4d9f-86b1-bfed7b1b5808",
278 "id": "1",
279 "receiver": "git/0",
280 "name": "add-repo",
281 "status": "completed",
282 "message": "",
283 },
284 }
285 )
286
287 Deltas = [
288 Dict(
289 {
290 "entity": Dict({"id": "2", "type": "machine"}),
291 "filter": Dict({"entity_id": "2", "entity_type": "machine"}),
292 "delta": FAKE_DELTA_MACHINE_PENDING,
293 "entity_status": Dict(
294 {"status": "pending", "message": "Running", "vca_status": "running"}
295 ),
296 "db": Dict(
297 {
298 "written": True,
299 "data": Dict(
300 {
301 "message": "Running",
302 "entity": "machine",
303 "vca_status": "running",
304 "n2vc_status": N2VCDeploymentStatus.PENDING,
305 }
306 ),
307 }
308 ),
309 }
310 ),
311 Dict(
312 {
313 "entity": Dict({"id": "2", "type": "machine"}),
314 "filter": Dict({"entity_id": "1", "entity_type": "machine"}),
315 "delta": FAKE_DELTA_MACHINE_PENDING,
316 "entity_status": Dict(
317 {"status": "pending", "message": "Running", "vca_status": "running"}
318 ),
319 "db": Dict({"written": False, "data": None}),
320 }
321 ),
322 Dict(
323 {
324 "entity": Dict({"id": "2", "type": "machine"}),
325 "filter": Dict({"entity_id": "2", "entity_type": "machine"}),
326 "delta": FAKE_DELTA_MACHINE_STARTED,
327 "entity_status": Dict(
328 {"status": "started", "message": "Running", "vca_status": "running"}
329 ),
330 "db": Dict(
331 {
332 "written": True,
333 "data": Dict(
334 {
335 "message": "Running",
336 "entity": "machine",
337 "vca_status": "running",
338 "n2vc_status": N2VCDeploymentStatus.COMPLETED,
339 }
340 ),
341 }
342 ),
343 }
344 ),
345 Dict(
346 {
347 "entity": Dict({"id": "2", "type": "machine"}),
348 "filter": Dict({"entity_id": "1", "entity_type": "machine"}),
349 "delta": FAKE_DELTA_MACHINE_STARTED,
350 "entity_status": Dict(
351 {"status": "started", "message": "Running", "vca_status": "running"}
352 ),
353 "db": Dict({"written": False, "data": None}),
354 }
355 ),
356 Dict(
357 {
358 "entity": Dict({"id": "git/0", "type": "unit"}),
359 "filter": Dict({"entity_id": "git", "entity_type": "application"}),
360 "delta": FAKE_DELTA_UNIT_PENDING,
361 "entity_status": Dict(
362 {"status": "waiting", "message": "", "vca_status": "waiting"}
363 ),
364 "db": Dict(
365 {
366 "written": True,
367 "data": Dict(
368 {
369 "message": "",
370 "entity": "unit",
371 "vca_status": "waiting",
372 "n2vc_status": N2VCDeploymentStatus.RUNNING,
373 }
374 ),
375 }
376 ),
377 }
378 ),
379 Dict(
380 {
381 "entity": Dict({"id": "git/0", "type": "unit"}),
382 "filter": Dict({"entity_id": "2", "entity_type": "machine"}),
383 "delta": FAKE_DELTA_UNIT_PENDING,
384 "entity_status": Dict(
385 {"status": "waiting", "message": "", "vca_status": "waiting"}
386 ),
387 "db": Dict({"written": False, "data": None}),
388 }
389 ),
390 Dict(
391 {
392 "entity": Dict({"id": "git/0", "type": "unit"}),
393 "filter": Dict({"entity_id": "git", "entity_type": "application"}),
394 "delta": FAKE_DELTA_UNIT_STARTED,
395 "entity_status": Dict(
396 {"status": "active", "message": "", "vca_status": "active"}
397 ),
398 "db": Dict(
399 {
400 "written": True,
401 "data": Dict(
402 {
403 "message": "",
404 "entity": "unit",
405 "vca_status": "active",
406 "n2vc_status": N2VCDeploymentStatus.COMPLETED,
407 }
408 ),
409 }
410 ),
411 }
412 ),
413 Dict(
414 {
415 "entity": Dict({"id": "git/0", "type": "unit"}),
416 "filter": Dict({"entity_id": "1", "entity_type": "action"}),
417 "delta": FAKE_DELTA_UNIT_STARTED,
418 "entity_status": Dict(
419 {"status": "active", "message": "", "vca_status": "active"}
420 ),
421 "db": Dict({"written": False, "data": None}),
422 }
423 ),
424 Dict(
425 {
426 "entity": Dict({"id": "git", "type": "application"}),
427 "filter": Dict({"entity_id": "git", "entity_type": "application"}),
428 "delta": FAKE_DELTA_APPLICATION_MAINTENANCE,
429 "entity_status": Dict(
430 {
431 "status": "maintenance",
432 "message": "installing charm software",
433 "vca_status": "maintenance",
434 }
435 ),
436 "db": Dict(
437 {
438 "written": True,
439 "data": Dict(
440 {
441 "message": "installing charm software",
442 "entity": "application",
443 "vca_status": "maintenance",
444 "n2vc_status": N2VCDeploymentStatus.RUNNING,
445 }
446 ),
447 }
448 ),
449 }
450 ),
451 Dict(
452 {
453 "entity": Dict({"id": "git", "type": "application"}),
454 "filter": Dict({"entity_id": "2", "entity_type": "machine"}),
455 "delta": FAKE_DELTA_APPLICATION_MAINTENANCE,
456 "entity_status": Dict(
457 {
458 "status": "maintenance",
459 "message": "installing charm software",
460 "vca_status": "maintenance",
461 }
462 ),
463 "db": Dict({"written": False, "data": None}),
464 }
465 ),
466 Dict(
467 {
468 "entity": Dict({"id": "git", "type": "application"}),
469 "filter": Dict({"entity_id": "git", "entity_type": "application"}),
470 "delta": FAKE_DELTA_APPLICATION_ACTIVE,
471 "entity_status": Dict(
472 {"status": "active", "message": "Ready!", "vca_status": "active"}
473 ),
474 "db": Dict(
475 {
476 "written": True,
477 "data": Dict(
478 {
479 "message": "Ready!",
480 "entity": "application",
481 "vca_status": "active",
482 "n2vc_status": N2VCDeploymentStatus.COMPLETED,
483 }
484 ),
485 }
486 ),
487 }
488 ),
489 Dict(
490 {
491 "entity": Dict({"id": "git", "type": "application"}),
492 "filter": Dict({"entity_id": "1", "entity_type": "action"}),
493 "delta": FAKE_DELTA_APPLICATION_ACTIVE,
494 "entity_status": Dict(
495 {"status": "active", "message": "Ready!", "vca_status": "active"}
496 ),
497 "db": Dict({"written": False, "data": None}),
498 }
499 ),
500 Dict(
501 {
502 "entity": Dict({"id": "1", "type": "action"}),
503 "filter": Dict({"entity_id": "1", "entity_type": "action"}),
504 "delta": FAKE_DELTA_ACTION_COMPLETED,
505 "entity_status": Dict(
506 {
507 "status": "completed",
508 "message": "completed",
509 "vca_status": "completed",
510 }
511 ),
512 "db": Dict(
513 {
514 "written": True,
515 "data": Dict(
516 {
517 "message": "completed",
518 "entity": "action",
519 "vca_status": "completed",
520 "n2vc_status": N2VCDeploymentStatus.COMPLETED,
521 }
522 ),
523 }
524 ),
525 }
526 ),
527 Dict(
528 {
529 "entity": Dict({"id": "git", "type": "action"}),
530 "filter": Dict({"entity_id": "1", "entity_type": "machine"}),
531 "delta": FAKE_DELTA_ACTION_COMPLETED,
532 "entity_status": Dict(
533 {
534 "status": "completed",
535 "message": "completed",
536 "vca_status": "completed",
537 }
538 ),
539 "db": Dict({"written": False, "data": None}),
540 }
541 ),
542 ]