Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

unittests: add a testbench to check public/private kdoc comments

Add unit tests to check if the public/private and comments strip
is working properly.

Running it shows that, on several cases, public/private is not
doing what it is expected:

test_private:
TestPublicPrivate:
test balanced_inner_private: OK
test balanced_non_greddy_private: OK
test balanced_private: OK
test no private: OK
test unbalanced_inner_private: FAIL
test unbalanced_private: FAIL
test unbalanced_struct_group_tagged_with_private: FAIL
test unbalanced_two_struct_group_tagged_first_with_private: FAIL
test unbalanced_without_end_of_line: FAIL

Ran 9 tests

FAILED (failures=5)

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Message-ID: <144f4952e0cb74fe9c9adc117e9a21ec8aa1cc10.1773074166.git.mchehab+huawei@kernel.org>
Signed-off-by: Jonathan Corbet <corbet@lwn.net>
Message-ID: <c1574b5b67b0442de3fab570fe6de9bc28b17a75.1773770483.git.mchehab+huawei@kernel.org>

authored by

Mauro Carvalho Chehab and committed by
Jonathan Corbet
c6c23449 023aabb6

+331
+331
tools/unittests/test_private.py
··· 1 + #!/usr/bin/env python3 2 + 3 + """ 4 + Unit tests for struct/union member extractor class. 5 + """ 6 + 7 + 8 + import os 9 + import re 10 + import unittest 11 + import sys 12 + 13 + from unittest.mock import MagicMock 14 + 15 + SRC_DIR = os.path.dirname(os.path.realpath(__file__)) 16 + sys.path.insert(0, os.path.join(SRC_DIR, "../lib/python")) 17 + 18 + from kdoc.kdoc_parser import trim_private_members 19 + from unittest_helper import run_unittest 20 + 21 + # 22 + # List of tests. 23 + # 24 + # The code will dynamically generate one test for each key on this dictionary. 25 + # 26 + 27 + #: Tests to check if CTokenizer is handling properly public/private comments. 28 + TESTS_PRIVATE = { 29 + # 30 + # Simplest case: no private. Ensure that trimming won't affect struct 31 + # 32 + "no private": { 33 + "source": """ 34 + struct foo { 35 + int a; 36 + int b; 37 + int c; 38 + }; 39 + """, 40 + "trimmed": """ 41 + struct foo { 42 + int a; 43 + int b; 44 + int c; 45 + }; 46 + """, 47 + }, 48 + 49 + # 50 + # Play "by the books" by always having a public in place 51 + # 52 + 53 + "balanced_private": { 54 + "source": """ 55 + struct foo { 56 + int a; 57 + /* private: */ 58 + int b; 59 + /* public: */ 60 + int c; 61 + }; 62 + """, 63 + "trimmed": """ 64 + struct foo { 65 + int a; 66 + int c; 67 + }; 68 + """, 69 + }, 70 + 71 + "balanced_non_greddy_private": { 72 + "source": """ 73 + struct foo { 74 + int a; 75 + /* private: */ 76 + int b; 77 + /* public: */ 78 + int c; 79 + /* private: */ 80 + int d; 81 + /* public: */ 82 + int e; 83 + 84 + }; 85 + """, 86 + "trimmed": """ 87 + struct foo { 88 + int a; 89 + int c; 90 + int e; 91 + }; 92 + """, 93 + }, 94 + 95 + "balanced_inner_private": { 96 + "source": """ 97 + struct foo { 98 + struct { 99 + int a; 100 + /* private: ignore below */ 101 + int b; 102 + /* public: but this should not be ignored */ 103 + }; 104 + int b; 105 + }; 106 + """, 107 + "trimmed": """ 108 + struct foo { 109 + struct { 110 + int a; 111 + }; 112 + int b; 113 + }; 114 + """, 115 + }, 116 + 117 + # 118 + # Test what happens if there's no public after private place 119 + # 120 + 121 + "unbalanced_private": { 122 + "source": """ 123 + struct foo { 124 + int a; 125 + /* private: */ 126 + int b; 127 + int c; 128 + }; 129 + """, 130 + "trimmed": """ 131 + struct foo { 132 + int a; 133 + }; 134 + """, 135 + }, 136 + 137 + "unbalanced_inner_private": { 138 + "source": """ 139 + struct foo { 140 + struct { 141 + int a; 142 + /* private: ignore below */ 143 + int b; 144 + /* but this should not be ignored */ 145 + }; 146 + int b; 147 + }; 148 + """, 149 + "trimmed": """ 150 + struct foo { 151 + struct { 152 + int a; 153 + }; 154 + int b; 155 + }; 156 + """, 157 + }, 158 + 159 + "unbalanced_struct_group_tagged_with_private": { 160 + "source": """ 161 + struct page_pool_params { 162 + struct_group_tagged(page_pool_params_fast, fast, 163 + unsigned int order; 164 + unsigned int pool_size; 165 + int nid; 166 + struct device *dev; 167 + struct napi_struct *napi; 168 + enum dma_data_direction dma_dir; 169 + unsigned int max_len; 170 + unsigned int offset; 171 + }; 172 + struct_group_tagged(page_pool_params_slow, slow, 173 + struct net_device *netdev; 174 + unsigned int queue_idx; 175 + unsigned int flags; 176 + /* private: used by test code only */ 177 + void (*init_callback)(netmem_ref netmem, void *arg); 178 + void *init_arg; 179 + }; 180 + }; 181 + """, 182 + "trimmed": """ 183 + struct page_pool_params { 184 + struct_group_tagged(page_pool_params_fast, fast, 185 + unsigned int order; 186 + unsigned int pool_size; 187 + int nid; 188 + struct device *dev; 189 + struct napi_struct *napi; 190 + enum dma_data_direction dma_dir; 191 + unsigned int max_len; 192 + unsigned int offset; 193 + }; 194 + struct_group_tagged(page_pool_params_slow, slow, 195 + struct net_device *netdev; 196 + unsigned int queue_idx; 197 + unsigned int flags; 198 + }; 199 + }; 200 + """, 201 + }, 202 + 203 + "unbalanced_two_struct_group_tagged_first_with_private": { 204 + "source": """ 205 + struct page_pool_params { 206 + struct_group_tagged(page_pool_params_slow, slow, 207 + struct net_device *netdev; 208 + unsigned int queue_idx; 209 + unsigned int flags; 210 + /* private: used by test code only */ 211 + void (*init_callback)(netmem_ref netmem, void *arg); 212 + void *init_arg; 213 + }; 214 + struct_group_tagged(page_pool_params_fast, fast, 215 + unsigned int order; 216 + unsigned int pool_size; 217 + int nid; 218 + struct device *dev; 219 + struct napi_struct *napi; 220 + enum dma_data_direction dma_dir; 221 + unsigned int max_len; 222 + unsigned int offset; 223 + }; 224 + }; 225 + """, 226 + "trimmed": """ 227 + struct page_pool_params { 228 + struct_group_tagged(page_pool_params_slow, slow, 229 + struct net_device *netdev; 230 + unsigned int queue_idx; 231 + unsigned int flags; 232 + }; 233 + struct_group_tagged(page_pool_params_fast, fast, 234 + unsigned int order; 235 + unsigned int pool_size; 236 + int nid; 237 + struct device *dev; 238 + struct napi_struct *napi; 239 + enum dma_data_direction dma_dir; 240 + unsigned int max_len; 241 + unsigned int offset; 242 + }; 243 + }; 244 + """, 245 + }, 246 + "unbalanced_without_end_of_line": { 247 + "source": """ \ 248 + struct page_pool_params { \ 249 + struct_group_tagged(page_pool_params_slow, slow, \ 250 + struct net_device *netdev; \ 251 + unsigned int queue_idx; \ 252 + unsigned int flags; 253 + /* private: used by test code only */ 254 + void (*init_callback)(netmem_ref netmem, void *arg); \ 255 + void *init_arg; \ 256 + }; \ 257 + struct_group_tagged(page_pool_params_fast, fast, \ 258 + unsigned int order; \ 259 + unsigned int pool_size; \ 260 + int nid; \ 261 + struct device *dev; \ 262 + struct napi_struct *napi; \ 263 + enum dma_data_direction dma_dir; \ 264 + unsigned int max_len; \ 265 + unsigned int offset; \ 266 + }; \ 267 + }; 268 + """, 269 + "trimmed": """ 270 + struct page_pool_params { 271 + struct_group_tagged(page_pool_params_slow, slow, 272 + struct net_device *netdev; 273 + unsigned int queue_idx; 274 + unsigned int flags; 275 + }; 276 + struct_group_tagged(page_pool_params_fast, fast, 277 + unsigned int order; 278 + unsigned int pool_size; 279 + int nid; 280 + struct device *dev; 281 + struct napi_struct *napi; 282 + enum dma_data_direction dma_dir; 283 + unsigned int max_len; 284 + unsigned int offset; 285 + }; 286 + }; 287 + """, 288 + }, 289 + } 290 + 291 + 292 + class TestPublicPrivate(unittest.TestCase): 293 + """ 294 + Main test class. Populated dynamically at runtime. 295 + """ 296 + 297 + def setUp(self): 298 + self.maxDiff = None 299 + 300 + def add_test(cls, name, source, trimmed): 301 + """ 302 + Dynamically add a test to the class 303 + """ 304 + def test(cls): 305 + result = trim_private_members(source) 306 + 307 + result = re.sub(r"\s++", " ", result).strip() 308 + expected = re.sub(r"\s++", " ", trimmed).strip() 309 + 310 + msg = f"failed when parsing this source:\n" + source 311 + 312 + cls.assertEqual(result, expected, msg=msg) 313 + 314 + test.__name__ = f'test {name}' 315 + 316 + setattr(TestPublicPrivate, test.__name__, test) 317 + 318 + 319 + # 320 + # Populate TestPublicPrivate class 321 + # 322 + test_class = TestPublicPrivate() 323 + for name, test in TESTS_PRIVATE.items(): 324 + test_class.add_test(name, test["source"], test["trimmed"]) 325 + 326 + 327 + # 328 + # main 329 + # 330 + if __name__ == "__main__": 331 + run_unittest(__file__)