diff options
| author | Brenda J. Butler <bjb@mojatatu.com> | 2018-02-14 14:09:23 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2018-02-15 15:38:33 -0500 |
| commit | a13fedbe56fef141aff7d584eba2a08daaf613cc (patch) | |
| tree | 97bff2cb9e944aed67e134bf7af1747119d72e07 /tools/testing/selftests/tc-testing/plugin-lib/nsPlugin.py | |
| parent | f6926e85eee9be08d05170af3a2266b8d7f9cdef (diff) | |
tools: tc-testing: nsPlugin
Move the functionality of creating a namespace before the test suite
and destroying it afterwards to a plugin.
Signed-off-by: Brenda J. Butler <bjb@mojatatu.com>
Acked-by: Lucas Bates <lucasb@mojatatu.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'tools/testing/selftests/tc-testing/plugin-lib/nsPlugin.py')
| -rw-r--r-- | tools/testing/selftests/tc-testing/plugin-lib/nsPlugin.py | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/tools/testing/selftests/tc-testing/plugin-lib/nsPlugin.py b/tools/testing/selftests/tc-testing/plugin-lib/nsPlugin.py new file mode 100644 index 000000000000..a194b1af2b30 --- /dev/null +++ b/tools/testing/selftests/tc-testing/plugin-lib/nsPlugin.py | |||
| @@ -0,0 +1,141 @@ | |||
| 1 | import os | ||
| 2 | import signal | ||
| 3 | from string import Template | ||
| 4 | import subprocess | ||
| 5 | import time | ||
| 6 | from TdcPlugin import TdcPlugin | ||
| 7 | |||
| 8 | from tdc_config import * | ||
| 9 | |||
| 10 | class SubPlugin(TdcPlugin): | ||
| 11 | def __init__(self): | ||
| 12 | self.sub_class = 'ns/SubPlugin' | ||
| 13 | super().__init__() | ||
| 14 | |||
| 15 | def pre_suite(self, testcount, testidlist): | ||
| 16 | '''run commands before test_runner goes into a test loop''' | ||
| 17 | super().pre_suite(testcount, testidlist) | ||
| 18 | |||
| 19 | if self.args.namespace: | ||
| 20 | self._ns_create() | ||
| 21 | |||
| 22 | def post_suite(self, index): | ||
| 23 | '''run commands after test_runner goes into a test loop''' | ||
| 24 | super().post_suite(index) | ||
| 25 | if self.args.verbose: | ||
| 26 | print('{}.post_suite'.format(self.sub_class)) | ||
| 27 | |||
| 28 | if self.args.namespace: | ||
| 29 | self._ns_destroy() | ||
| 30 | |||
| 31 | def add_args(self, parser): | ||
| 32 | super().add_args(parser) | ||
| 33 | self.argparser_group = self.argparser.add_argument_group( | ||
| 34 | 'netns', | ||
| 35 | 'options for nsPlugin(run commands in net namespace)') | ||
| 36 | self.argparser_group.add_argument( | ||
| 37 | '-n', '--namespace', action='store_true', | ||
| 38 | help='Run commands in namespace') | ||
| 39 | return self.argparser | ||
| 40 | |||
| 41 | def adjust_command(self, stage, command): | ||
| 42 | super().adjust_command(stage, command) | ||
| 43 | cmdform = 'list' | ||
| 44 | cmdlist = list() | ||
| 45 | |||
| 46 | if not self.args.namespace: | ||
| 47 | return command | ||
| 48 | |||
| 49 | if self.args.verbose: | ||
| 50 | print('{}.adjust_command'.format(self.sub_class)) | ||
| 51 | |||
| 52 | if not isinstance(command, list): | ||
| 53 | cmdform = 'str' | ||
| 54 | cmdlist = command.split() | ||
| 55 | else: | ||
| 56 | cmdlist = command | ||
| 57 | if stage == 'setup' or stage == 'execute' or stage == 'verify' or stage == 'teardown': | ||
| 58 | if self.args.verbose: | ||
| 59 | print('adjust_command: stage is {}; inserting netns stuff in command [{}] list [{}]'.format(stage, command, cmdlist)) | ||
| 60 | cmdlist.insert(0, self.args.NAMES['NS']) | ||
| 61 | cmdlist.insert(0, 'exec') | ||
| 62 | cmdlist.insert(0, 'netns') | ||
| 63 | cmdlist.insert(0, 'ip') | ||
| 64 | else: | ||
| 65 | pass | ||
| 66 | |||
| 67 | if cmdform == 'str': | ||
| 68 | command = ' '.join(cmdlist) | ||
| 69 | else: | ||
| 70 | command = cmdlist | ||
| 71 | |||
| 72 | if self.args.verbose: | ||
| 73 | print('adjust_command: return command [{}]'.format(command)) | ||
| 74 | return command | ||
| 75 | |||
| 76 | def _ns_create(self): | ||
| 77 | ''' | ||
| 78 | Create the network namespace in which the tests will be run and set up | ||
| 79 | the required network devices for it. | ||
| 80 | ''' | ||
| 81 | if self.args.namespace: | ||
| 82 | cmd = 'ip netns add {}'.format(self.args.NAMES['NS']) | ||
| 83 | self._exec_cmd('pre', cmd) | ||
| 84 | cmd = 'ip link add $DEV0 type veth peer name $DEV1' | ||
| 85 | self._exec_cmd('pre', cmd) | ||
| 86 | cmd = 'ip link set $DEV1 netns {}'.format(self.args.NAMES['NS']) | ||
| 87 | self._exec_cmd('pre', cmd) | ||
| 88 | cmd = 'ip link set $DEV0 up' | ||
| 89 | self._exec_cmd('pre', cmd) | ||
| 90 | cmd = 'ip -n {} link set $DEV1 up'.format(self.args.NAMES['NS']) | ||
| 91 | self._exec_cmd('pre', cmd) | ||
| 92 | if self.args.device: | ||
| 93 | cmd = 'ip link set $DEV2 netns {}'.format(self.args.NAMES['NS']) | ||
| 94 | self._exec_cmd('pre', cmd) | ||
| 95 | cmd = 'ip -n {} link set $DEV2 up'.format(self.args.NAMES['NS']) | ||
| 96 | self._exec_cmd('pre', cmd) | ||
| 97 | |||
| 98 | def _ns_destroy(self): | ||
| 99 | ''' | ||
| 100 | Destroy the network namespace for testing (and any associated network | ||
| 101 | devices as well) | ||
| 102 | ''' | ||
| 103 | if self.args.namespace: | ||
| 104 | cmd = 'ip netns delete {}'.format(self.args.NAMES['NS']) | ||
| 105 | self._exec_cmd('post', cmd) | ||
| 106 | |||
| 107 | def _exec_cmd(self, stage, command): | ||
| 108 | ''' | ||
| 109 | Perform any required modifications on an executable command, then run | ||
| 110 | it in a subprocess and return the results. | ||
| 111 | ''' | ||
| 112 | if '$' in command: | ||
| 113 | command = self._replace_keywords(command) | ||
| 114 | |||
| 115 | self.adjust_command(stage, command) | ||
| 116 | if self.args.verbose: | ||
| 117 | print('_exec_cmd: command "{}"'.format(command)) | ||
| 118 | proc = subprocess.Popen(command, | ||
| 119 | shell=True, | ||
| 120 | stdout=subprocess.PIPE, | ||
| 121 | stderr=subprocess.PIPE, | ||
| 122 | env=ENVIR) | ||
| 123 | (rawout, serr) = proc.communicate() | ||
| 124 | |||
| 125 | if proc.returncode != 0 and len(serr) > 0: | ||
| 126 | foutput = serr.decode("utf-8") | ||
| 127 | else: | ||
| 128 | foutput = rawout.decode("utf-8") | ||
| 129 | |||
| 130 | proc.stdout.close() | ||
| 131 | proc.stderr.close() | ||
| 132 | return proc, foutput | ||
| 133 | |||
| 134 | def _replace_keywords(self, cmd): | ||
| 135 | """ | ||
| 136 | For a given executable command, substitute any known | ||
| 137 | variables contained within NAMES with the correct values | ||
| 138 | """ | ||
| 139 | tcmd = Template(cmd) | ||
| 140 | subcmd = tcmd.safe_substitute(self.args.NAMES) | ||
| 141 | return subcmd | ||
