mirror of
https://github.com/torvalds/linux.git
synced 2026-05-27 08:33:17 +02:00
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>
This commit is contained in:
parent
023aabb6cc
commit
c6c23449b3
331
tools/unittests/test_private.py
Executable file
331
tools/unittests/test_private.py
Executable file
|
|
@ -0,0 +1,331 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
Unit tests for struct/union member extractor class.
|
||||
"""
|
||||
|
||||
|
||||
import os
|
||||
import re
|
||||
import unittest
|
||||
import sys
|
||||
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
SRC_DIR = os.path.dirname(os.path.realpath(__file__))
|
||||
sys.path.insert(0, os.path.join(SRC_DIR, "../lib/python"))
|
||||
|
||||
from kdoc.kdoc_parser import trim_private_members
|
||||
from unittest_helper import run_unittest
|
||||
|
||||
#
|
||||
# List of tests.
|
||||
#
|
||||
# The code will dynamically generate one test for each key on this dictionary.
|
||||
#
|
||||
|
||||
#: Tests to check if CTokenizer is handling properly public/private comments.
|
||||
TESTS_PRIVATE = {
|
||||
#
|
||||
# Simplest case: no private. Ensure that trimming won't affect struct
|
||||
#
|
||||
"no private": {
|
||||
"source": """
|
||||
struct foo {
|
||||
int a;
|
||||
int b;
|
||||
int c;
|
||||
};
|
||||
""",
|
||||
"trimmed": """
|
||||
struct foo {
|
||||
int a;
|
||||
int b;
|
||||
int c;
|
||||
};
|
||||
""",
|
||||
},
|
||||
|
||||
#
|
||||
# Play "by the books" by always having a public in place
|
||||
#
|
||||
|
||||
"balanced_private": {
|
||||
"source": """
|
||||
struct foo {
|
||||
int a;
|
||||
/* private: */
|
||||
int b;
|
||||
/* public: */
|
||||
int c;
|
||||
};
|
||||
""",
|
||||
"trimmed": """
|
||||
struct foo {
|
||||
int a;
|
||||
int c;
|
||||
};
|
||||
""",
|
||||
},
|
||||
|
||||
"balanced_non_greddy_private": {
|
||||
"source": """
|
||||
struct foo {
|
||||
int a;
|
||||
/* private: */
|
||||
int b;
|
||||
/* public: */
|
||||
int c;
|
||||
/* private: */
|
||||
int d;
|
||||
/* public: */
|
||||
int e;
|
||||
|
||||
};
|
||||
""",
|
||||
"trimmed": """
|
||||
struct foo {
|
||||
int a;
|
||||
int c;
|
||||
int e;
|
||||
};
|
||||
""",
|
||||
},
|
||||
|
||||
"balanced_inner_private": {
|
||||
"source": """
|
||||
struct foo {
|
||||
struct {
|
||||
int a;
|
||||
/* private: ignore below */
|
||||
int b;
|
||||
/* public: but this should not be ignored */
|
||||
};
|
||||
int b;
|
||||
};
|
||||
""",
|
||||
"trimmed": """
|
||||
struct foo {
|
||||
struct {
|
||||
int a;
|
||||
};
|
||||
int b;
|
||||
};
|
||||
""",
|
||||
},
|
||||
|
||||
#
|
||||
# Test what happens if there's no public after private place
|
||||
#
|
||||
|
||||
"unbalanced_private": {
|
||||
"source": """
|
||||
struct foo {
|
||||
int a;
|
||||
/* private: */
|
||||
int b;
|
||||
int c;
|
||||
};
|
||||
""",
|
||||
"trimmed": """
|
||||
struct foo {
|
||||
int a;
|
||||
};
|
||||
""",
|
||||
},
|
||||
|
||||
"unbalanced_inner_private": {
|
||||
"source": """
|
||||
struct foo {
|
||||
struct {
|
||||
int a;
|
||||
/* private: ignore below */
|
||||
int b;
|
||||
/* but this should not be ignored */
|
||||
};
|
||||
int b;
|
||||
};
|
||||
""",
|
||||
"trimmed": """
|
||||
struct foo {
|
||||
struct {
|
||||
int a;
|
||||
};
|
||||
int b;
|
||||
};
|
||||
""",
|
||||
},
|
||||
|
||||
"unbalanced_struct_group_tagged_with_private": {
|
||||
"source": """
|
||||
struct page_pool_params {
|
||||
struct_group_tagged(page_pool_params_fast, fast,
|
||||
unsigned int order;
|
||||
unsigned int pool_size;
|
||||
int nid;
|
||||
struct device *dev;
|
||||
struct napi_struct *napi;
|
||||
enum dma_data_direction dma_dir;
|
||||
unsigned int max_len;
|
||||
unsigned int offset;
|
||||
};
|
||||
struct_group_tagged(page_pool_params_slow, slow,
|
||||
struct net_device *netdev;
|
||||
unsigned int queue_idx;
|
||||
unsigned int flags;
|
||||
/* private: used by test code only */
|
||||
void (*init_callback)(netmem_ref netmem, void *arg);
|
||||
void *init_arg;
|
||||
};
|
||||
};
|
||||
""",
|
||||
"trimmed": """
|
||||
struct page_pool_params {
|
||||
struct_group_tagged(page_pool_params_fast, fast,
|
||||
unsigned int order;
|
||||
unsigned int pool_size;
|
||||
int nid;
|
||||
struct device *dev;
|
||||
struct napi_struct *napi;
|
||||
enum dma_data_direction dma_dir;
|
||||
unsigned int max_len;
|
||||
unsigned int offset;
|
||||
};
|
||||
struct_group_tagged(page_pool_params_slow, slow,
|
||||
struct net_device *netdev;
|
||||
unsigned int queue_idx;
|
||||
unsigned int flags;
|
||||
};
|
||||
};
|
||||
""",
|
||||
},
|
||||
|
||||
"unbalanced_two_struct_group_tagged_first_with_private": {
|
||||
"source": """
|
||||
struct page_pool_params {
|
||||
struct_group_tagged(page_pool_params_slow, slow,
|
||||
struct net_device *netdev;
|
||||
unsigned int queue_idx;
|
||||
unsigned int flags;
|
||||
/* private: used by test code only */
|
||||
void (*init_callback)(netmem_ref netmem, void *arg);
|
||||
void *init_arg;
|
||||
};
|
||||
struct_group_tagged(page_pool_params_fast, fast,
|
||||
unsigned int order;
|
||||
unsigned int pool_size;
|
||||
int nid;
|
||||
struct device *dev;
|
||||
struct napi_struct *napi;
|
||||
enum dma_data_direction dma_dir;
|
||||
unsigned int max_len;
|
||||
unsigned int offset;
|
||||
};
|
||||
};
|
||||
""",
|
||||
"trimmed": """
|
||||
struct page_pool_params {
|
||||
struct_group_tagged(page_pool_params_slow, slow,
|
||||
struct net_device *netdev;
|
||||
unsigned int queue_idx;
|
||||
unsigned int flags;
|
||||
};
|
||||
struct_group_tagged(page_pool_params_fast, fast,
|
||||
unsigned int order;
|
||||
unsigned int pool_size;
|
||||
int nid;
|
||||
struct device *dev;
|
||||
struct napi_struct *napi;
|
||||
enum dma_data_direction dma_dir;
|
||||
unsigned int max_len;
|
||||
unsigned int offset;
|
||||
};
|
||||
};
|
||||
""",
|
||||
},
|
||||
"unbalanced_without_end_of_line": {
|
||||
"source": """ \
|
||||
struct page_pool_params { \
|
||||
struct_group_tagged(page_pool_params_slow, slow, \
|
||||
struct net_device *netdev; \
|
||||
unsigned int queue_idx; \
|
||||
unsigned int flags;
|
||||
/* private: used by test code only */
|
||||
void (*init_callback)(netmem_ref netmem, void *arg); \
|
||||
void *init_arg; \
|
||||
}; \
|
||||
struct_group_tagged(page_pool_params_fast, fast, \
|
||||
unsigned int order; \
|
||||
unsigned int pool_size; \
|
||||
int nid; \
|
||||
struct device *dev; \
|
||||
struct napi_struct *napi; \
|
||||
enum dma_data_direction dma_dir; \
|
||||
unsigned int max_len; \
|
||||
unsigned int offset; \
|
||||
}; \
|
||||
};
|
||||
""",
|
||||
"trimmed": """
|
||||
struct page_pool_params {
|
||||
struct_group_tagged(page_pool_params_slow, slow,
|
||||
struct net_device *netdev;
|
||||
unsigned int queue_idx;
|
||||
unsigned int flags;
|
||||
};
|
||||
struct_group_tagged(page_pool_params_fast, fast,
|
||||
unsigned int order;
|
||||
unsigned int pool_size;
|
||||
int nid;
|
||||
struct device *dev;
|
||||
struct napi_struct *napi;
|
||||
enum dma_data_direction dma_dir;
|
||||
unsigned int max_len;
|
||||
unsigned int offset;
|
||||
};
|
||||
};
|
||||
""",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
class TestPublicPrivate(unittest.TestCase):
|
||||
"""
|
||||
Main test class. Populated dynamically at runtime.
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
self.maxDiff = None
|
||||
|
||||
def add_test(cls, name, source, trimmed):
|
||||
"""
|
||||
Dynamically add a test to the class
|
||||
"""
|
||||
def test(cls):
|
||||
result = trim_private_members(source)
|
||||
|
||||
result = re.sub(r"\s++", " ", result).strip()
|
||||
expected = re.sub(r"\s++", " ", trimmed).strip()
|
||||
|
||||
msg = f"failed when parsing this source:\n" + source
|
||||
|
||||
cls.assertEqual(result, expected, msg=msg)
|
||||
|
||||
test.__name__ = f'test {name}'
|
||||
|
||||
setattr(TestPublicPrivate, test.__name__, test)
|
||||
|
||||
|
||||
#
|
||||
# Populate TestPublicPrivate class
|
||||
#
|
||||
test_class = TestPublicPrivate()
|
||||
for name, test in TESTS_PRIVATE.items():
|
||||
test_class.add_test(name, test["source"], test["trimmed"])
|
||||
|
||||
|
||||
#
|
||||
# main
|
||||
#
|
||||
if __name__ == "__main__":
|
||||
run_unittest(__file__)
|
||||
Loading…
Reference in New Issue
Block a user