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 | ||