Merge branch 'selftests-net-page_poll-allocation-error-injection'
[linux-2.6-block.git] / tools / testing / selftests / net / lib / py / utils.py
CommitLineData
b86761ff
JK
1# SPDX-License-Identifier: GPL-2.0
2
3import json as _json
31611cea
JK
4import random
5import re
b86761ff 6import subprocess
31611cea
JK
7import time
8
b86761ff
JK
9
10class cmd:
1a20a9a0 11 def __init__(self, comm, shell=True, fail=True, ns=None, background=False, host=None):
b86761ff 12 if ns:
b86761ff
JK
13 comm = f'ip netns exec {ns} ' + comm
14
15 self.stdout = None
16 self.stderr = None
17 self.ret = None
18
19 self.comm = comm
1a20a9a0
JK
20 if host:
21 self.proc = host.cmd(comm)
22 else:
23 self.proc = subprocess.Popen(comm, shell=shell, stdout=subprocess.PIPE,
24 stderr=subprocess.PIPE)
b86761ff
JK
25 if not background:
26 self.process(terminate=False, fail=fail)
27
28 def process(self, terminate=True, fail=None):
29 if terminate:
30 self.proc.terminate()
1a20a9a0 31 stdout, stderr = self.proc.communicate(timeout=5)
b86761ff
JK
32 self.stdout = stdout.decode("utf-8")
33 self.stderr = stderr.decode("utf-8")
34 self.proc.stdout.close()
35 self.proc.stderr.close()
36 self.ret = self.proc.returncode
37
38 if self.proc.returncode != 0 and fail:
39 if len(stderr) > 0 and stderr[-1] == "\n":
40 stderr = stderr[:-1]
232d79aa
JK
41 raise Exception("Command failed: %s\nSTDOUT: %s\nSTDERR: %s" %
42 (self.proc.args, stdout, stderr))
b86761ff
JK
43
44
31611cea
JK
45class bkg(cmd):
46 def __init__(self, comm, shell=True, fail=True, ns=None, host=None,
47 exit_wait=False):
48 super().__init__(comm, background=True,
49 shell=shell, fail=fail, ns=ns, host=host)
50 self.terminate = not exit_wait
51
52 def __enter__(self):
53 return self
54
55 def __exit__(self, ex_type, ex_value, ex_tb):
56 return self.process(terminate=self.terminate)
57
58
32a4ca13
JK
59def tool(name, args, json=None, ns=None, host=None):
60 cmd_str = name + ' '
b86761ff 61 if json:
32a4ca13 62 cmd_str += '--json '
b86761ff 63 cmd_str += args
1a20a9a0 64 cmd_obj = cmd(cmd_str, ns=ns, host=host)
b86761ff
JK
65 if json:
66 return _json.loads(cmd_obj.stdout)
67 return cmd_obj
31611cea
JK
68
69
32a4ca13
JK
70def ip(args, json=None, ns=None, host=None):
71 if ns:
72 args = f'-netns {ns} ' + args
73 return tool('ip', args, json=json, host=host)
74
75
31611cea
JK
76def rand_port():
77 """
78 Get unprivileged port, for now just random, one day we may decide to check if used.
79 """
ee2512d6 80 return random.randint(10000, 65535)
31611cea
JK
81
82
83def wait_port_listen(port, proto="tcp", ns=None, host=None, sleep=0.005, deadline=5):
84 end = time.monotonic() + deadline
85
86 pattern = f":{port:04X} .* "
87 if proto == "tcp": # for tcp protocol additionally check the socket state
88 pattern += "0A"
89 pattern = re.compile(pattern)
90
91 while True:
92 data = cmd(f'cat /proc/net/{proto}*', ns=ns, host=host, shell=True).stdout
93 for row in data.split("\n"):
94 if pattern.search(row):
95 return
96 if time.monotonic() > end:
97 raise Exception("Waiting for port listen timed out")
98 time.sleep(sleep)