1 # SPDX-License-Identifier: GPL-2.0 2 # Copyright (c) 2020 SUSE LLC. 3 4 import collections 5 import functools 6 import json 7 import os 8 import socket 9 import subprocess 10 import unittest 11 12 13 # Add the source tree of bpftool and /usr/loca 14 cur_dir = os.path.dirname(os.path.realpath(__f 15 bpftool_dir = os.path.abspath(os.path.join(cur 16 "to 17 os.environ["PATH"] = bpftool_dir + ":/usr/loca 18 19 20 class IfaceNotFoundError(Exception): 21 pass 22 23 24 class UnprivilegedUserError(Exception): 25 pass 26 27 28 def _bpftool(args, json=True): 29 _args = ["bpftool"] 30 if json: 31 _args.append("-j") 32 _args.extend(args) 33 34 return subprocess.check_output(_args) 35 36 37 def bpftool(args): 38 return _bpftool(args, json=False).decode(" 39 40 41 def bpftool_json(args): 42 res = _bpftool(args) 43 return json.loads(res) 44 45 46 def get_default_iface(): 47 for iface in socket.if_nameindex(): 48 if iface[1] != "lo": 49 return iface[1] 50 raise IfaceNotFoundError("Could not find a 51 52 53 def default_iface(f): 54 @functools.wraps(f) 55 def wrapper(*args, **kwargs): 56 iface = get_default_iface() 57 return f(*args, iface, **kwargs) 58 return wrapper 59 60 DMESG_EMITTING_HELPERS = [ 61 "bpf_probe_write_user", 62 "bpf_trace_printk", 63 "bpf_trace_vprintk", 64 ] 65 66 class TestBpftool(unittest.TestCase): 67 @classmethod 68 def setUpClass(cls): 69 if os.getuid() != 0: 70 raise UnprivilegedUserError( 71 "This test suite needs root pr 72 73 @default_iface 74 def test_feature_dev_json(self, iface): 75 unexpected_helpers = DMESG_EMITTING_HE 76 expected_keys = [ 77 "syscall_config", 78 "program_types", 79 "map_types", 80 "helpers", 81 "misc", 82 ] 83 84 res = bpftool_json(["feature", "probe" 85 # Check if the result has all expected 86 self.assertCountEqual(res.keys(), expe 87 # Check if unexpected helpers are not 88 # result. 89 for helpers in res["helpers"].values() 90 for unexpected_helper in unexpecte 91 self.assertNotIn(unexpected_he 92 93 def test_feature_kernel(self): 94 test_cases = [ 95 bpftool_json(["feature", "probe", 96 bpftool_json(["feature", "probe"]) 97 bpftool_json(["feature"]), 98 ] 99 unexpected_helpers = DMESG_EMITTING_HE 100 expected_keys = [ 101 "syscall_config", 102 "system_config", 103 "program_types", 104 "map_types", 105 "helpers", 106 "misc", 107 ] 108 109 for tc in test_cases: 110 # Check if the result has all expe 111 self.assertCountEqual(tc.keys(), e 112 # Check if unexpected helpers are 113 # result. 114 for helpers in tc["helpers"].value 115 for unexpected_helper in unexp 116 self.assertNotIn(unexpecte 117 118 def test_feature_kernel_full(self): 119 test_cases = [ 120 bpftool_json(["feature", "probe", 121 bpftool_json(["feature", "probe", 122 ] 123 expected_helpers = DMESG_EMITTING_HELP 124 125 for tc in test_cases: 126 # Check if expected helpers are in 127 # helpers list for any program typ 128 # that they will be included in al 129 # subset of programs. It depends o 130 # configuration. 131 found_helpers = False 132 133 for helpers in tc["helpers"].value 134 if all(expected_helper in help 135 for expected_helper in 136 found_helpers = True 137 break 138 139 self.assertTrue(found_helpers) 140 141 def test_feature_kernel_full_vs_not_full(s 142 full_res = bpftool_json(["feature", "p 143 not_full_res = bpftool_json(["feature" 144 not_full_set = set() 145 full_set = set() 146 147 for helpers in full_res["helpers"].val 148 for helper in helpers: 149 full_set.add(helper) 150 151 for helpers in not_full_res["helpers"] 152 for helper in helpers: 153 not_full_set.add(helper) 154 155 self.assertCountEqual(full_set - not_f 156 set(DMESG_EMITTI 157 self.assertCountEqual(not_full_set - f 158 159 def test_feature_macros(self): 160 expected_patterns = [ 161 r"/\*\*\* System call availability 162 r"#define HAVE_BPF_SYSCALL", 163 r"/\*\*\* eBPF program types \*\*\ 164 r"#define HAVE.*PROG_TYPE", 165 r"/\*\*\* eBPF map types \*\*\*/", 166 r"#define HAVE.*MAP_TYPE", 167 r"/\*\*\* eBPF helper functions \* 168 r"#define HAVE.*HELPER", 169 r"/\*\*\* eBPF misc features \*\*\ 170 ] 171 172 res = bpftool(["feature", "probe", "ma 173 for pattern in expected_patterns: 174 self.assertRegex(res, pattern)
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.