4 # Copyright 2016 RIFT.IO Inc
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
10 # http://www.apache.org/licenses/LICENSE-2.0
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
32 gi.require_version('RwDtsToyTaskletYang', '1.0')
33 gi.require_version('RwManifestYang', '1.0')
34 gi.require_version('RwVcsYang', '1.0')
36 import gi.repository.RwManifestYang as rwmanifest
37 import gi.repository.RwVcsYang as rwvcs
38 import gi.repository.RwDtsToyTaskletYang as toyyang
39 import gi.repository.RwYang as RwYang
40 import rift.auto.session
46 if sys.version_info < (3, 4, 4):
47 asyncio.ensure_future = asyncio.async
49 class LaunchPad(rift.test.dts.AbstractDTSTest):
51 DTS GI interface unittests
53 Note: Each tests uses a list of asyncio.Events for staging through the
54 test. These are required here because we are bring up each coroutine
55 ("tasklet") at the same time and are not implementing any re-try
56 mechanisms. For instance, this is used in numerous tests to make sure that
57 a publisher is up and ready before the subscriber sends queries. Such
58 event lists should not be used in production software.
62 1. Creates an asyncio loop
63 2. Triggers the hook configure_test
65 def scheduler_tick(self, *args):
66 self.call_soon(self.stop)
69 # Init params: loop & timers
70 self.loop = asyncio.new_event_loop()
72 self.loop.scheduler_tick = types.MethodType(scheduler_tick, self.loop)
74 self.asyncio_timer = None
75 self.stop_timer = None
76 self.__class__.id_cnt += 1
77 self.configure_test(self.loop, self.__class__.id_cnt)
80 def configure_schema(cls):
81 schema = RwYang.Model.load_and_merge_schema(rwvcs.get_schema(), 'librwcal_yang_gen.so', 'Rwcal')
82 cls.model = RwYang.Model.create_libncx()
83 cls.model.load_schema_ypbc(schema)
84 xml = cls.manifest.to_xml_v2(cls.model, 1)
85 xml = re.sub('rw-manifest:', '', xml)
86 xml = re.sub('<manifest xmlns:rw-manifest="http://riftio.com/ns/riftware-1.0/rw-manifest">', '<?xml version="1.0" ?>\n<manifest xmlns="http://riftio.com/ns/riftware-1.0/rw-manifest" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://riftio.com/ns/riftware-1.0/rw-manifest ./rw-manifest.xsd">', xml)
87 xml = '\n'.join(xml.split('\n')[1:])
88 with open('lptestmanifest.xml', 'w') as f:
95 def configure_manifest(cls):
96 manifest = rwmanifest.Manifest()
97 manifest.bootstrap_phase = rwmanifest.BootstrapPhase.from_dict({
99 "northbound_listing": [ "cli_launchpad_schema_listing.txt" ]
102 "plugin_name": "rwinit-c"
111 "bootstrap_time": 30,
112 "console_severity": 4
116 "ip_addr": "127.0.0.1",
120 "master_ip": "127.0.0.1",
121 "unique_ports": False,
130 "component_name": "msgbroker",
134 "component_name": "dtsrouter",
141 # "cert": "/net/mahi/localdisk/kelayath/ws/coreha/etc/ssl/current.cert",
142 # "key": "/net/mahi/localdisk/kelayath/ws/coreha/etc/ssl/current.key"
145 manifest.init_phase = rwmanifest.InitPhase.from_dict({
148 "vm_ip_address = '127.0.0.1'",
149 "rw_component_name = 'vm-launchpad'",
151 "component_type = 'rwvm'",
153 "component_name": "$python(rw_component_name)",
154 "instance_id": "$python(instance_id)",
155 "component_type": "$python(rw_component_type)"
169 "collapse_each_rwvm": False,
170 "collapse_each_rwprocess": False
174 manifest.inventory = rwmanifest.Inventory.from_dict({
177 "component_name": "master",
178 "component_type": "RWCOLLECTION",
180 "collection_type": "rwcolony",
185 "name": "Start vm-launchpad for master",
187 "python_variable": ["vm_ip_address = '127.0.0.1'"],
188 "component_name": "vm-launchpad",
198 "component_name": "vm-launchpad",
199 "component_type": "RWVM",
207 "name": "Start the master",
209 "component_name": "master",
210 "recovery_action": "RESTART",
215 # "name": "Start the RW.CLI",
217 # "component_name": "RW.CLI",
218 # "recovery_action": "RESTART",
219 # "config_ready": True
223 "name": "Start the RW.Proc_1.Restconf",
225 "component_name": "RW.Proc_1.Restconf",
226 "recovery_action": "RESTART",
231 # "name": "Start the RW.Proc_2.RestPortForward",
233 # "component_name": "RW.Proc_2.RestPortForward",
234 # "recovery_action": "RESTART",
235 # "config_ready": True
239 "name": "Start the RW.Proc_3.CalProxy",
241 "component_name": "RW.Proc_3.CalProxy",
242 "recovery_action": "RESTART",
247 "name": "Start the RW.Proc_4.nfvi-metrics-monitor",
249 "component_name": "RW.Proc_4.nfvi-metrics-monitor",
250 "recovery_action": "RESTART",
255 "name": "Start the RW.Proc_5.network-services-manager",
257 "component_name": "RW.Proc_5.network-services-manager",
258 "recovery_action": "RESTART",
263 "name": "Start the RW.Proc_6.virtual-network-function-manager",
265 "component_name": "RW.Proc_6.virtual-network-function-manager",
266 "recovery_action": "RESTART",
271 "name": "Start the RW.Proc_7.virtual-network-service",
273 "component_name": "RW.Proc_7.virtual-network-service",
274 "recovery_action": "RESTART",
279 "name": "Start the RW.Proc_8.nfvi-metrics-monitor",
281 "component_name": "RW.Proc_8.nfvi-metrics-monitor",
282 "recovery_action": "RESTART",
287 "name": "Start the RW.MC.UI",
289 "component_name": "RW.MC.UI",
290 "recovery_action": "RESTART",
295 # "name": "Start the RW.COMPOSER.UI",
297 # "component_name": "RW.COMPOSER.UI",
298 # "config_ready": True
302 "name": "Start the RW.Proc_10.launchpad",
304 "component_name": "RW.Proc_10.launchpad",
305 "recovery_action": "RESTART",
310 "name": "Start the RW.Proc_11.Resource-Manager",
312 "component_name": "RW.Proc_11.Resource-Manager",
313 "recovery_action": "RESTART",
318 "name": "Start the RW.uAgent",
320 "python_variable": ["cmdargs_str = '--confd-proto AF_INET --confd-ip 127.0.0.1'"],
321 "component_name": "RW.uAgent",
322 "recovery_action": "RESTART",
327 "name": "Start the logd",
329 "component_name": "logd",
330 "recovery_action": "RESTART",
340 # "component_name": "RW.CLI",
341 # "component_type": "PROC",
343 # "exe_path": "./usr/bin/rwcli",
344 # "args": "--netconf_host 127.0.0.1 --netconf_port 2022 --schema_listing cli_launchpad_schema_listing.txt",
348 "component_name": "RW.Proc_1.Restconf",
349 "component_type": "RWPROC",
352 "name": "Start RW.Restconf for RW.Proc_1.Restconf",
353 "component_name": "RW.Restconf",
354 "recovery_action": "RESTART",
360 "component_name": "RW.Restconf",
361 "component_type": "RWTASKLET",
363 "plugin_directory": "./usr/lib/rift/plugins/restconf",
364 "plugin_name": "restconf"
368 # "component_name": "RW.Proc_2.RestPortForward",
369 # "component_type": "RWPROC",
372 # "name": "Start RW.RestPortForward for RW.Proc_2.RestPortForward",
373 # "component_name": "RW.RestPortForward",
374 # "recovery_action": "RESTART",
375 # "config_ready": True
380 # "component_name": "RW.RestPortForward",
381 # "component_type": "RWTASKLET",
383 # "plugin_directory": "./usr/lib/rift/plugins/restportforward",
384 # "plugin_name": "restportforward"
388 "component_name": "RW.Proc_3.CalProxy",
389 "component_type": "RWPROC",
392 "name": "Start RW.CalProxy for RW.Proc_3.CalProxy",
393 "component_name": "RW.CalProxy",
394 "recovery_action": "RESTART",
400 "component_name": "RW.CalProxy",
401 "component_type": "RWTASKLET",
403 "plugin_directory": "./usr/lib/rift/plugins/rwcalproxytasklet",
404 "plugin_name": "rwcalproxytasklet"
408 "component_name": "RW.Proc_4.nfvi-metrics-monitor",
409 "component_type": "RWPROC",
412 "name": "Start nfvi-metrics-monitor for RW.Proc_4.nfvi-metrics-monitor",
413 "component_name": "nfvi-metrics-monitor",
414 "recovery_action": "RESTART",
420 "component_name": "nfvi-metrics-monitor",
421 "component_type": "RWTASKLET",
423 "plugin_directory": "./usr/lib/rift/plugins/rwmonitor",
424 "plugin_name": "rwmonitor"
428 "component_name": "RW.Proc_5.network-services-manager",
429 "component_type": "RWPROC",
432 "name": "Start network-services-manager for RW.Proc_5.network-services-manager",
433 "component_name": "network-services-manager",
434 "recovery_action": "RESTART",
440 "component_name": "network-services-manager",
441 "component_type": "RWTASKLET",
443 "plugin_directory": "./usr/lib/rift/plugins/rwnsmtasklet",
444 "plugin_name": "rwnsmtasklet"
448 "component_name": "RW.Proc_6.virtual-network-function-manager",
449 "component_type": "RWPROC",
452 "name": "Start virtual-network-function-manager for RW.Proc_6.virtual-network-function-manager",
453 "component_name": "virtual-network-function-manager",
454 "recovery_action": "RESTART",
460 "component_name": "virtual-network-function-manager",
461 "component_type": "RWTASKLET",
463 "plugin_directory": "./usr/lib/rift/plugins/rwvnfmtasklet",
464 "plugin_name": "rwvnfmtasklet"
468 "component_name": "RW.Proc_7.virtual-network-service",
469 "component_type": "RWPROC",
472 "name": "Start virtual-network-service for RW.Proc_7.virtual-network-service",
473 "component_name": "virtual-network-service",
474 "recovery_action": "RESTART",
480 "component_name": "virtual-network-service",
481 "component_type": "RWTASKLET",
483 "plugin_directory": "./usr/lib/rift/plugins/rwvnstasklet",
484 "plugin_name": "rwvnstasklet"
488 "component_name": "RW.Proc_8.nfvi-metrics-monitor",
489 "component_type": "RWPROC",
492 "name": "Start nfvi-metrics-monitor for RW.Proc_8.nfvi-metrics-monitor",
493 "component_name": "nfvi-metrics-monitor",
494 "recovery_action": "RESTART",
500 "component_name": "RW.MC.UI",
501 "component_type": "PROC",
503 "exe_path": "./usr/share/rw.ui/skyquake/scripts/launch_ui.sh",
507 "component_name": "RW.COMPOSER.UI",
508 "component_type": "PROC",
510 "exe_path": "./usr/share/composer/scripts/launch_composer.sh",
514 "component_name": "RW.Proc_9.Configuration-Manager",
515 "component_type": "RWPROC",
518 "name": "Start Configuration-Manager for RW.Proc_9.Configuration-Manager",
519 "component_name": "Configuration-Manager",
520 "recovery_action": "RESTART",
526 "component_name": "Configuration-Manager",
527 "component_type": "RWTASKLET",
529 "plugin_directory": "./usr/lib/rift/plugins/rwconmantasklet",
530 "plugin_name": "rwconmantasklet"
534 "component_name": "RW.Proc_10.launchpad",
535 "component_type": "RWPROC",
538 "name": "Start launchpad for RW.Proc_10.launchpad",
539 "component_name": "launchpad",
540 "recovery_action": "RESTART",
546 "component_name": "launchpad",
547 "component_type": "RWTASKLET",
549 "plugin_directory": "./usr/lib/rift/plugins/rwlaunchpad",
550 "plugin_name": "rwlaunchpad"
554 "component_name": "RW.Proc_11.Resource-Manager",
555 "component_type": "RWPROC",
558 "name": "Start Resource-Manager for RW.Proc_11.Resource-Manager",
559 "component_name": "Resource-Manager",
560 "recovery_action": "RESTART",
566 "component_name": "Resource-Manager",
567 "component_type": "RWTASKLET",
569 "plugin_directory": "./usr/lib/rift/plugins/rwresmgrtasklet",
570 "plugin_name": "rwresmgrtasklet"
574 "component_name": "RW.uAgent",
575 "component_type": "RWTASKLET",
577 "plugin_directory": "./usr/lib/rift/plugins/rwuagent-c",
578 "plugin_name": "rwuagent-c"
582 "component_name": "logd",
583 "component_type": "RWTASKLET",
585 "plugin_directory": "./usr/lib/rift/plugins/rwlogd-c",
586 "plugin_name": "rwlogd-c"
590 "component_name": "msgbroker",
591 "component_type": "RWTASKLET",
593 "plugin_directory": "./usr/lib/rift/plugins/rwmsgbroker-c",
594 "plugin_name": "rwmsgbroker-c"
598 "component_name": "dtsrouter",
599 "component_type": "RWTASKLET",
601 "plugin_directory": "./usr/lib/rift/plugins/rwdtsrouter-c",
602 "plugin_name": "rwdtsrouter-c"
610 tasklist = { 'reaperd',
613 for proc in psutil.process_iter():
614 if proc.name() in tasklist:
615 print("killing", proc.name())
619 print(proc.name(), "no longer exists")
624 class LaunchPadTest(LaunchPad):
626 DTS GI interface unittests
628 Note: Each tests uses a list of asyncio.Events for staging through the
629 test. These are required here because we are bring up each coroutine
630 ("tasklet") at the same time and are not implementing any re-try
631 mechanisms. For instance, this is used in numerous tests to make sure that
632 a publisher is up and ready before the subscriber sends queries. Such
633 event lists should not be used in production software.
637 res_iter = yield from self.dts_mgmt.query_read('/rw-base:vcs/rw-base:info', flags=0)
639 info_result = yield from i
640 components = info_result.result.components.component_info
642 for component in components:
643 recvd_list[component.component_name] = (component.instance_id,
644 component.rwcomponent_parent,
645 component.component_type,
650 def issue_vcrash(self, component_type):
651 # critical_components = {'msgbroker', 'dtsrouter'}
652 critical_components = {'msgbroker', 'dtsrouter', 'RW.uAgent'}
653 comp_inventory = yield from self.inventory()
654 for component in comp_inventory:
655 if ((comp_inventory[component])[2] == component_type):
656 inst = (comp_inventory[component])[0]
657 if (component in critical_components):
658 print(component, 'Marked as CRITICAL - Not restarting')
660 print('Crashing ', component_type,component)
661 vcrash_input = rwvcs.VCrashInput(instance_name=component+'-'+str(inst))
662 query_iter = yield from self.dts_mgmt.query_rpc( xpath="/rw-vcs:vcrash",
663 flags=0, msg=vcrash_input)
664 yield from asyncio.sleep(1, loop=self.loop)
665 restarted_inventory = yield from self.inventory()
666 self.assertTrue(restarted_inventory[component][3] != 'TO_RECOVER')
668 def test_launch_pad(self):
670 Verify the launchpad setup functions
671 The test will progress through stages defined by the events list:
672 0: mission_control setup is brought up
673 2: Tasklet/PROC/VM restarts tested to confirm recovery is proper
676 print("{{{{{{{{{{{{{{{{{{{{STARTING - mano recovery test")
677 # confd_host="127.0.0.1"
679 events = [asyncio.Event(loop=self.loop) for _ in range(2)]
684 tinfo = self.new_tinfo('sub')
685 self.dts_mgmt = rift.tasklets.DTS(tinfo, self.schema, self.loop)
687 # Sleep for DTS registrations to complete
688 print('.........................................................')
689 print('........SLEEPING 80 seconds for system to come up........')
690 yield from asyncio.sleep(80, loop=self.loop)
691 print('........RESUMING........')
694 def issue_vstop(component,inst,flag=0):
695 vstop_input = rwvcs.VStopInput(instance_name=component+'-'+(str(inst)))
696 query_iter = yield from self.dts_mgmt.query_rpc( xpath="/rw-vcs:vstop",
697 flags=flag, msg=vstop_input)
698 yield from asyncio.sleep(1, loop=self.loop)
703 def issue_vstart(component, parent, recover=False):
704 vstart_input = rwvcs.VStartInput()
705 vstart_input.component_name = component
706 vstart_input.parent_instance = parent
707 vstart_input.recover = recover
708 query_iter = yield from self.dts_mgmt.query_rpc( xpath="/rw-vcs:vstart",
709 flags=0, msg=vstart_input)
710 yield from asyncio.sleep(1, loop=self.loop)
713 def issue_start_stop(comp_inventory, component_type):
714 # critical_components = {'msgbroker', 'dtsrouter'}
715 critical_components = {'msgbroker', 'dtsrouter', 'RW.uAgent'}
716 for component in comp_inventory:
717 if ((comp_inventory[component])[2] == component_type):
718 inst = (comp_inventory[component])[0]
719 parent = (comp_inventory[component])[1]
720 if (component in critical_components):
721 print(component, 'Marked as CRITICAL - Not restarting')
723 print('Stopping ', component_type,component)
724 yield from issue_vstop(component,inst)
725 restarted_inventory = yield from self.inventory()
726 # self.assertEqual(restarted_inventory[component][3],'TO_RECOVER')
727 print('Starting ',component_type,component)
728 yield from issue_vstart(component, parent, recover=True)
729 restarted_inventory = yield from self.inventory()
730 self.assertTrue(restarted_inventory[component][3] != 'TO_RECOVER')
732 yield from asyncio.sleep(20, loop=self.loop)
733 comp_inventory = yield from self.inventory()
734 yield from issue_start_stop(comp_inventory, 'RWTASKLET')
735 # yield from issue_start_stop(comp_inventory, 'RWPROC')
736 # yield from self.issue_vcrash('RWTASKLET')
738 yield from asyncio.sleep(20, loop=self.loop)
739 restarted_inventory = yield from self.inventory()
740 # critical_components = {'msgbroker', 'dtsrouter', 'RW.uAgent'}
741 for comp in comp_inventory:
742 self.assertEqual(str(comp_inventory[comp]), str(restarted_inventory[comp]))
743 # if (comp not in critical_components):
744 # inst = (comp_inventory[comp])[0]
745 # yield from issue_vstop(comp,inst)
749 asyncio.ensure_future(sub(), loop=self.loop)
750 self.run_until(events[1].is_set, timeout=260)
754 plugin_dir = os.path.join(os.environ["RIFT_INSTALL"], "usr/lib/rift/plugins")
755 if 'DTS_TEST_PUB_DIR' not in os.environ:
756 os.environ['DTS_TEST_PUB_DIR'] = os.path.join(plugin_dir, 'dtstestpub')
758 if 'RIFT_NO_SUDO_REAPER' not in os.environ:
759 os.environ['RIFT_NO_SUDO_REAPER'] = '1'
761 if 'MESSAGE_BROKER_DIR' not in os.environ:
762 os.environ['MESSAGE_BROKER_DIR'] = os.path.join(plugin_dir, 'rwmsgbroker-c')
764 if 'ROUTER_DIR' not in os.environ:
765 os.environ['ROUTER_DIR'] = os.path.join(plugin_dir, 'rwdtsrouter-c')
767 if 'RW_VAR_RIFT' not in os.environ:
768 os.environ['RW_VAR_RIFT'] = '1'
770 if 'INSTALLDIR' in os.environ:
771 os.chdir(os.environ.get('INSTALLDIR'))
773 # if 'RWMSG_BROKER_SHUNT' not in os.environ:
774 # os.environ['RWMSG_BROKER_SHUNT'] = '1'
776 if 'TEST_ENVIRON' not in os.environ:
777 os.environ['TEST_ENVIRON'] = '1'
779 if 'RW_MANIFEST' not in os.environ:
780 os.environ['RW_MANIFEST'] = os.path.join(install_dir, 'lptestmanifest.xml')
782 parser = argparse.ArgumentParser()
783 parser.add_argument('-v', '--verbose', action='store_true')
784 args, _ = parser.parse_known_args()
787 runner = xmlrunner.XMLTestRunner(output=os.environ["RIFT_MODULE_TEST"])
788 unittest.main(testRunner=runner)
790 if __name__ == '__main__':