1 # Copyright 2020 Canonical Ltd.
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
7 # http://www.apache.org/licenses/LICENSE-2.0
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.
17 from n2vc
.utils
import Dict
, N2VCDeploymentStatus
18 from n2vc
.n2vc_conn
import N2VCConnector
19 from unittest
.mock
import MagicMock
22 kubeconfig
= """apiVersion: v1
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
53 cluster: microk8s-cluster
56 current-context: microk8s
62 token: clhkRExRem5Xd1dCdnFEVXdvRGtDRGE5b1F3WnNrZk5qeHFCOU10bHBZRT0K
66 async def AsyncMockFunc():
67 await asyncio
.sleep(1)
70 class AsyncMock(MagicMock
):
71 async def __call__(self
, *args
, **kwargs
):
72 return super(AsyncMock
, self
).__call
__(*args
, **kwargs
)
75 class FakeN2VC(MagicMock
):
76 last_written_values
= None
78 async def write_app_status_to_db(
81 status
: N2VCDeploymentStatus
,
86 self
.last_written_values
= Dict(
88 "n2vc_status": status
,
89 "message": detailed_status
,
90 "vca_status": vca_status
,
91 "entity": entity_type
,
95 osm_status
= N2VCConnector
.osm_status
98 class FakeMachine(MagicMock
):
100 dns_name
= "FAKE ENDPOINT"
101 model_name
= "FAKE MODEL"
102 entity_type
= "machine"
103 safe_data
= {"instance-id": "myid"}
105 async def destroy(self
, force
):
109 class FakeManualMachine(MagicMock
):
111 dns_name
= "FAKE ENDPOINT"
112 model_name
= "FAKE MODEL"
113 entity_type
= "machine"
114 safe_data
= {"instance-id": "manual:myid"}
116 async def destroy(self
, force
):
120 class FakeWatcher(AsyncMock
):
122 delta_to_return
= None
124 async def Next(self
):
125 return Dict({"deltas": self
.delta_to_return
})
128 class FakeConnection(MagicMock
):
133 class FakeAction(MagicMock
):
139 def __init__(self
, applications
: dict = {}):
140 self
._applications
= applications
143 def applications(self
):
144 return self
._applications
147 class FakeUnit(MagicMock
):
148 async def is_leader_from_status(self
):
151 async def run_action(self
, action_name
):
155 class FakeApplication(AsyncMock
):
156 async def set_config(self
, config
):
159 async def add_unit(self
, to
):
162 async def get_actions(self
):
163 return ["existing_action"]
165 async def get_config(self
):
166 return ["app_config"]
168 units
= [FakeUnit(), FakeUnit()]
172 def __init__(self
, content
: str = ""):
173 self
.content
= content
175 def read(self
, size
: int = -1):
179 class FakeFileWrapper
:
180 def __init__(self
, content
: str = ""):
181 self
.file = FakeFile(content
=content
)
186 def __exit__(self
, type, value
, traceback
):
190 FAKE_DELTA_MACHINE_PENDING
= Dict(
192 "deltas": ["machine", "change", {}],
197 "instance-id": "juju-1b5808-2",
198 "agent-status": {"current": "pending", "message": "", "version": ""},
199 "instance-status": {"current": "running", "message": "Running"},
203 FAKE_DELTA_MACHINE_STARTED
= Dict(
205 "deltas": ["machine", "change", {}],
210 "instance-id": "juju-1b5808-2",
211 "agent-status": {"current": "started", "message": "", "version": ""},
212 "instance-status": {"current": "running", "message": "Running"},
217 FAKE_DELTA_UNIT_PENDING
= Dict(
219 "deltas": ["unit", "change", {}],
224 "application": "git",
226 "workload-status": {"current": "waiting", "message": ""},
227 "agent-status": {"current": "idle", "message": ""},
232 FAKE_DELTA_UNIT_STARTED
= Dict(
234 "deltas": ["unit", "change", {}],
239 "application": "git",
241 "workload-status": {"current": "active", "message": ""},
242 "agent-status": {"current": "idle", "message": ""},
247 FAKE_DELTA_APPLICATION_MAINTENANCE
= Dict(
249 "deltas": ["application", "change", {}],
250 "entity": "application",
255 "current": "maintenance",
256 "message": "installing charm software",
262 FAKE_DELTA_APPLICATION_ACTIVE
= Dict(
264 "deltas": ["application", "change", {}],
265 "entity": "application",
267 "data": {"name": "git", "status": {"current": "active", "message": "Ready!"}},
271 FAKE_DELTA_ACTION_COMPLETED
= Dict(
273 "deltas": ["action", "change", {}],
277 "model-uuid": "af19cdd4-374a-4d9f-86b1-bfed7b1b5808",
281 "status": "completed",
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"}
301 "message": "Running",
303 "vca_status": "running",
304 "n2vc_status": N2VCDeploymentStatus
.PENDING
,
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"}
319 "db": Dict({"written": False, "data": None}),
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"}
335 "message": "Running",
337 "vca_status": "running",
338 "n2vc_status": N2VCDeploymentStatus
.COMPLETED
,
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"}
353 "db": Dict({"written": False, "data": None}),
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"}
371 "vca_status": "waiting",
372 "n2vc_status": N2VCDeploymentStatus
.RUNNING
,
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"}
387 "db": Dict({"written": False, "data": None}),
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"}
405 "vca_status": "active",
406 "n2vc_status": N2VCDeploymentStatus
.COMPLETED
,
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"}
421 "db": Dict({"written": False, "data": None}),
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(
431 "status": "maintenance",
432 "message": "installing charm software",
433 "vca_status": "maintenance",
441 "message": "installing charm software",
442 "entity": "application",
443 "vca_status": "maintenance",
444 "n2vc_status": N2VCDeploymentStatus
.RUNNING
,
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(
458 "status": "maintenance",
459 "message": "installing charm software",
460 "vca_status": "maintenance",
463 "db": Dict({"written": False, "data": None}),
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"}
480 "entity": "application",
481 "vca_status": "active",
482 "n2vc_status": N2VCDeploymentStatus
.COMPLETED
,
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"}
497 "db": Dict({"written": False, "data": None}),
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(
507 "status": "completed",
508 "message": "completed",
509 "vca_status": "completed",
517 "message": "completed",
519 "vca_status": "completed",
520 "n2vc_status": N2VCDeploymentStatus
.COMPLETED
,
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(
534 "status": "completed",
535 "message": "completed",
536 "vca_status": "completed",
539 "db": Dict({"written": False, "data": None}),