1a13fedbeSBrenda J. Butlerimport os 2a13fedbeSBrenda J. Butlerimport signal 3a13fedbeSBrenda J. Butlerfrom string import Template 4a13fedbeSBrenda J. Butlerimport subprocess 5a13fedbeSBrenda J. Butlerimport time 6a13fedbeSBrenda J. Butlerfrom TdcPlugin import TdcPlugin 7a13fedbeSBrenda J. Butler 8a13fedbeSBrenda J. Butlerfrom tdc_config import * 9a13fedbeSBrenda J. Butler 10a13fedbeSBrenda J. Butlerclass SubPlugin(TdcPlugin): 11a13fedbeSBrenda J. Butler def __init__(self): 12a13fedbeSBrenda J. Butler self.sub_class = 'ns/SubPlugin' 13a13fedbeSBrenda J. Butler super().__init__() 14a13fedbeSBrenda J. Butler 15a13fedbeSBrenda J. Butler def pre_suite(self, testcount, testidlist): 16a13fedbeSBrenda J. Butler '''run commands before test_runner goes into a test loop''' 17a13fedbeSBrenda J. Butler super().pre_suite(testcount, testidlist) 18a13fedbeSBrenda J. Butler 19a13fedbeSBrenda J. Butler if self.args.namespace: 20a13fedbeSBrenda J. Butler self._ns_create() 21489ce2f4SLucas Bates else: 22489ce2f4SLucas Bates self._ports_create() 23a13fedbeSBrenda J. Butler 24a13fedbeSBrenda J. Butler def post_suite(self, index): 25a13fedbeSBrenda J. Butler '''run commands after test_runner goes into a test loop''' 26a13fedbeSBrenda J. Butler super().post_suite(index) 27a13fedbeSBrenda J. Butler if self.args.verbose: 28a13fedbeSBrenda J. Butler print('{}.post_suite'.format(self.sub_class)) 29a13fedbeSBrenda J. Butler 30a13fedbeSBrenda J. Butler if self.args.namespace: 31a13fedbeSBrenda J. Butler self._ns_destroy() 32489ce2f4SLucas Bates else: 33489ce2f4SLucas Bates self._ports_destroy() 34a13fedbeSBrenda J. Butler 35a13fedbeSBrenda J. Butler def add_args(self, parser): 36a13fedbeSBrenda J. Butler super().add_args(parser) 37a13fedbeSBrenda J. Butler self.argparser_group = self.argparser.add_argument_group( 38a13fedbeSBrenda J. Butler 'netns', 39a13fedbeSBrenda J. Butler 'options for nsPlugin(run commands in net namespace)') 40a13fedbeSBrenda J. Butler self.argparser_group.add_argument( 41489ce2f4SLucas Bates '-N', '--no-namespace', action='store_false', default=True, 42489ce2f4SLucas Bates dest='namespace', help='Don\'t run commands in namespace') 43a13fedbeSBrenda J. Butler return self.argparser 44a13fedbeSBrenda J. Butler 45a13fedbeSBrenda J. Butler def adjust_command(self, stage, command): 46a13fedbeSBrenda J. Butler super().adjust_command(stage, command) 47a13fedbeSBrenda J. Butler cmdform = 'list' 48a13fedbeSBrenda J. Butler cmdlist = list() 49a13fedbeSBrenda J. Butler 50a13fedbeSBrenda J. Butler if not self.args.namespace: 51a13fedbeSBrenda J. Butler return command 52a13fedbeSBrenda J. Butler 53a13fedbeSBrenda J. Butler if self.args.verbose: 54a13fedbeSBrenda J. Butler print('{}.adjust_command'.format(self.sub_class)) 55a13fedbeSBrenda J. Butler 56a13fedbeSBrenda J. Butler if not isinstance(command, list): 57a13fedbeSBrenda J. Butler cmdform = 'str' 58a13fedbeSBrenda J. Butler cmdlist = command.split() 59a13fedbeSBrenda J. Butler else: 60a13fedbeSBrenda J. Butler cmdlist = command 61a13fedbeSBrenda J. Butler if stage == 'setup' or stage == 'execute' or stage == 'verify' or stage == 'teardown': 62a13fedbeSBrenda J. Butler if self.args.verbose: 63a13fedbeSBrenda J. Butler print('adjust_command: stage is {}; inserting netns stuff in command [{}] list [{}]'.format(stage, command, cmdlist)) 64a13fedbeSBrenda J. Butler cmdlist.insert(0, self.args.NAMES['NS']) 65a13fedbeSBrenda J. Butler cmdlist.insert(0, 'exec') 66a13fedbeSBrenda J. Butler cmdlist.insert(0, 'netns') 67*02a3f0d5SDavide Caratti cmdlist.insert(0, self.args.NAMES['IP']) 68a13fedbeSBrenda J. Butler else: 69a13fedbeSBrenda J. Butler pass 70a13fedbeSBrenda J. Butler 71a13fedbeSBrenda J. Butler if cmdform == 'str': 72a13fedbeSBrenda J. Butler command = ' '.join(cmdlist) 73a13fedbeSBrenda J. Butler else: 74a13fedbeSBrenda J. Butler command = cmdlist 75a13fedbeSBrenda J. Butler 76a13fedbeSBrenda J. Butler if self.args.verbose: 77a13fedbeSBrenda J. Butler print('adjust_command: return command [{}]'.format(command)) 78a13fedbeSBrenda J. Butler return command 79a13fedbeSBrenda J. Butler 80489ce2f4SLucas Bates def _ports_create(self): 81*02a3f0d5SDavide Caratti cmd = '$IP link add $DEV0 type veth peer name $DEV1' 82489ce2f4SLucas Bates self._exec_cmd('pre', cmd) 83*02a3f0d5SDavide Caratti cmd = '$IP link set $DEV0 up' 84489ce2f4SLucas Bates self._exec_cmd('pre', cmd) 85489ce2f4SLucas Bates if not self.args.namespace: 86*02a3f0d5SDavide Caratti cmd = '$IP link set $DEV1 up' 87489ce2f4SLucas Bates self._exec_cmd('pre', cmd) 88489ce2f4SLucas Bates 89489ce2f4SLucas Bates def _ports_destroy(self): 90*02a3f0d5SDavide Caratti cmd = '$IP link del $DEV0' 91489ce2f4SLucas Bates self._exec_cmd('post', cmd) 92489ce2f4SLucas Bates 93a13fedbeSBrenda J. Butler def _ns_create(self): 94a13fedbeSBrenda J. Butler ''' 95a13fedbeSBrenda J. Butler Create the network namespace in which the tests will be run and set up 96a13fedbeSBrenda J. Butler the required network devices for it. 97a13fedbeSBrenda J. Butler ''' 98489ce2f4SLucas Bates self._ports_create() 99a13fedbeSBrenda J. Butler if self.args.namespace: 100*02a3f0d5SDavide Caratti cmd = '$IP netns add {}'.format(self.args.NAMES['NS']) 101a13fedbeSBrenda J. Butler self._exec_cmd('pre', cmd) 102*02a3f0d5SDavide Caratti cmd = '$IP link set $DEV1 netns {}'.format(self.args.NAMES['NS']) 103a13fedbeSBrenda J. Butler self._exec_cmd('pre', cmd) 104*02a3f0d5SDavide Caratti cmd = '$IP -n {} link set $DEV1 up'.format(self.args.NAMES['NS']) 105a13fedbeSBrenda J. Butler self._exec_cmd('pre', cmd) 106a13fedbeSBrenda J. Butler if self.args.device: 107*02a3f0d5SDavide Caratti cmd = '$IP link set $DEV2 netns {}'.format(self.args.NAMES['NS']) 108a13fedbeSBrenda J. Butler self._exec_cmd('pre', cmd) 109*02a3f0d5SDavide Caratti cmd = '$IP -n {} link set $DEV2 up'.format(self.args.NAMES['NS']) 110a13fedbeSBrenda J. Butler self._exec_cmd('pre', cmd) 111a13fedbeSBrenda J. Butler 112a13fedbeSBrenda J. Butler def _ns_destroy(self): 113a13fedbeSBrenda J. Butler ''' 114a13fedbeSBrenda J. Butler Destroy the network namespace for testing (and any associated network 115a13fedbeSBrenda J. Butler devices as well) 116a13fedbeSBrenda J. Butler ''' 117a13fedbeSBrenda J. Butler if self.args.namespace: 118*02a3f0d5SDavide Caratti cmd = '$IP netns delete {}'.format(self.args.NAMES['NS']) 119a13fedbeSBrenda J. Butler self._exec_cmd('post', cmd) 120a13fedbeSBrenda J. Butler 121a13fedbeSBrenda J. Butler def _exec_cmd(self, stage, command): 122a13fedbeSBrenda J. Butler ''' 123a13fedbeSBrenda J. Butler Perform any required modifications on an executable command, then run 124a13fedbeSBrenda J. Butler it in a subprocess and return the results. 125a13fedbeSBrenda J. Butler ''' 126a13fedbeSBrenda J. Butler if '$' in command: 127a13fedbeSBrenda J. Butler command = self._replace_keywords(command) 128a13fedbeSBrenda J. Butler 129a13fedbeSBrenda J. Butler self.adjust_command(stage, command) 130a13fedbeSBrenda J. Butler if self.args.verbose: 131a13fedbeSBrenda J. Butler print('_exec_cmd: command "{}"'.format(command)) 132a13fedbeSBrenda J. Butler proc = subprocess.Popen(command, 133a13fedbeSBrenda J. Butler shell=True, 134a13fedbeSBrenda J. Butler stdout=subprocess.PIPE, 135a13fedbeSBrenda J. Butler stderr=subprocess.PIPE, 136a13fedbeSBrenda J. Butler env=ENVIR) 137a13fedbeSBrenda J. Butler (rawout, serr) = proc.communicate() 138a13fedbeSBrenda J. Butler 139a13fedbeSBrenda J. Butler if proc.returncode != 0 and len(serr) > 0: 140a13fedbeSBrenda J. Butler foutput = serr.decode("utf-8") 141a13fedbeSBrenda J. Butler else: 142a13fedbeSBrenda J. Butler foutput = rawout.decode("utf-8") 143a13fedbeSBrenda J. Butler 144a13fedbeSBrenda J. Butler proc.stdout.close() 145a13fedbeSBrenda J. Butler proc.stderr.close() 146a13fedbeSBrenda J. Butler return proc, foutput 147a13fedbeSBrenda J. Butler 148a13fedbeSBrenda J. Butler def _replace_keywords(self, cmd): 149a13fedbeSBrenda J. Butler """ 150a13fedbeSBrenda J. Butler For a given executable command, substitute any known 151a13fedbeSBrenda J. Butler variables contained within NAMES with the correct values 152a13fedbeSBrenda J. Butler """ 153a13fedbeSBrenda J. Butler tcmd = Template(cmd) 154a13fedbeSBrenda J. Butler subcmd = tcmd.safe_substitute(self.args.NAMES) 155a13fedbeSBrenda J. Butler return subcmd 156