Note: this series applies on top of the series reducing stack usage, https://lore.kernel.org/linux-kselftest/20220113165931.451305-1-dlatypov@goo... There's no real smenatic dependency between these, just potential for merge conflicts.
The current layout of the assertion macros is confusing.
Here's the call chain for KUNIT_EXPECT_EQ() and KUNIT_EXPECT_EQ_MSG() KUNIT_EXPECT_EQ => KUNIT_BINARY_EQ_ASSERTION => # note: not shared with the _MSG variant KUNIT_BINARY_EQ_MSG_ASSERTION => KUNIT_BASE_EQ_MSG_ASSERTION => KUNIT_BASE_BINARY_ASSERTION
KUNIT_EXPECT_EQ_MSG => KUNIT_BINARY_EQ_MSG_ASSERTION => KUNIT_BASE_EQ_MSG_ASSERTION => KUNIT_BASE_BINARY_ASSERTION
After this series KUNIT_EXPECT_EQ => KUNIT_EXPECT_EQ_MSG => KUNIT_BINARY_INT_ASSERTION => KUNIT_BASE_BINARY_ASSERTION
The current macro layout tries hard to reduce duplication, but comes at the cost of a lot of intermediates that can simply vanish.
The same call-chain again, but annotated with the info we add: KUNIT_EXPECT_EQ => specify we're an EXPECT, not an ASSERT KUNIT_BINARY_EQ_ASSERTION => specify we have a NULL msg KUNIT_BINARY_EQ_MSG_ASSERTION => specify we work with ints, not ptrs KUNIT_BASE_EQ_MSG_ASSERTION => specify that the op is '==' KUNIT_BASE_BINARY_ASSERTION
We can see that each level of the chain only specifes one parameter at a time. We've taken the concept of DRY too far.
The following is a full snippet of all the macros needed for KUNIT_EXPECT_EQ, showing that a bit of repetition is just fine: #define KUNIT_BINARY_INT_ASSERTION(test, \ assert_type, \ left, \ op, \ right, \ fmt, \ ...) \ KUNIT_BASE_BINARY_ASSERTION(test, \ kunit_binary_assert, \ KUNIT_INIT_BINARY_ASSERT_STRUCT, \ assert_type, \ left, op, right, \ fmt, \ ##__VA_ARGS__)
#define KUNIT_EXPECT_EQ(test, left, right) \ KUNIT_EXPECT_EQ_MSG(test, left, right, NULL)
#define KUNIT_EXPECT_EQ_MSG(test, left, right, fmt, ...) \ KUNIT_BINARY_INT_ASSERTION(test, \ KUNIT_EXPECTATION, \ left, ==, right, \ fmt, \ ##__VA_ARGS__)
as opposed to our current DRYer version
#define KUNIT_BASE_EQ_MSG_ASSERTION(test, \ assert_class, \ ASSERT_CLASS_INIT, \ assert_type, \ left, \ right, \ fmt, \ ...) \ KUNIT_BASE_BINARY_ASSERTION(test, \ assert_class, \ ASSERT_CLASS_INIT, \ assert_type, \ left, ==, right, \ fmt, \ ##__VA_ARGS__)
#define KUNIT_BINARY_EQ_MSG_ASSERTION(test, assert_type, left, right, fmt, ...)\ KUNIT_BASE_EQ_MSG_ASSERTION(test, \ kunit_binary_assert, \ KUNIT_INIT_BINARY_ASSERT_STRUCT, \ assert_type, \ left, \ right, \ fmt, \ ##__VA_ARGS__)
#define KUNIT_BINARY_EQ_ASSERTION(test, assert_type, left, right) \ KUNIT_BINARY_EQ_MSG_ASSERTION(test, \ assert_type, \ left, \ right, \ NULL) #define KUNIT_EXPECT_EQ(test, left, right) \ KUNIT_BINARY_EQ_ASSERTION(test, KUNIT_EXPECTATION, left, right)
#define KUNIT_EXPECT_EQ_MSG(test, left, right, fmt, ...) \ KUNIT_BINARY_EQ_MSG_ASSERTION(test, \ KUNIT_EXPECTATION, \ left, \ right, \ fmt, \ ##__VA_ARGS__)
Daniel Latypov (5): kunit: make KUNIT_EXPECT_EQ() use KUNIT_EXPECT_EQ_MSG(), etc. kunit: drop unused intermediate macros for ptr inequality checks kunit: reduce layering in string assertion macros kunit: decrease macro layering for integer asserts kunit: decrease macro layering for EQ/NE asserts
include/kunit/test.h | 660 ++++++++++--------------------------------- 1 file changed, 142 insertions(+), 518 deletions(-)