mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 08:38:45 +02:00 
			
		
		
		
	lib: packing: add KUnit tests adapted from selftests
Add 24 simple KUnit tests for the lib/packing.c pack() and unpack() APIs. The first 16 tests exercise all combinations of quirks with a simple magic number value on a 16-byte buffer. The remaining 8 tests cover non-multiple-of-4 buffer sizes. These tests were originally written by Vladimir as simple selftest functions. I adapted them to KUnit, refactoring them into a table driven approach. This will aid in adding additional tests in the future. Co-developed-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: Jacob Keller <jacob.e.keller@intel.com> Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com> Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com> Tested-by: Vladimir Oltean <vladimir.oltean@nxp.com> Link: https://patch.msgid.link/20241002-packing-kunit-tests-and-split-pack-unpack-v2-6-8373e551eae3@intel.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
		
							parent
							
								
									28aec9ca29
								
							
						
					
					
						commit
						e9502ea6db
					
				
					 4 changed files with 272 additions and 0 deletions
				
			
		|  | @ -17471,6 +17471,7 @@ S:	Supported | ||||||
| F:	Documentation/core-api/packing.rst | F:	Documentation/core-api/packing.rst | ||||||
| F:	include/linux/packing.h | F:	include/linux/packing.h | ||||||
| F:	lib/packing.c | F:	lib/packing.c | ||||||
|  | F:	lib/packing_test.c | ||||||
| 
 | 
 | ||||||
| PADATA PARALLEL EXECUTION MECHANISM | PADATA PARALLEL EXECUTION MECHANISM | ||||||
| M:	Steffen Klassert <steffen.klassert@secunet.com> | M:	Steffen Klassert <steffen.klassert@secunet.com> | ||||||
|  |  | ||||||
							
								
								
									
										12
									
								
								lib/Kconfig
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								lib/Kconfig
									
									
									
									
									
								
							|  | @ -40,6 +40,18 @@ config PACKING | ||||||
| 
 | 
 | ||||||
| 	  When in doubt, say N. | 	  When in doubt, say N. | ||||||
| 
 | 
 | ||||||
|  | config PACKING_KUNIT_TEST | ||||||
|  | 	tristate "KUnit tests for packing library" if !KUNIT_ALL_TESTS | ||||||
|  | 	depends on PACKING && KUNIT | ||||||
|  | 	default KUNIT_ALL_TESTS | ||||||
|  | 	help | ||||||
|  | 	  This builds KUnit tests for the packing library. | ||||||
|  | 
 | ||||||
|  | 	  For more information on KUnit and unit tests in general, | ||||||
|  | 	  please refer to the KUnit documentation in Documentation/dev-tools/kunit/. | ||||||
|  | 
 | ||||||
|  | 	  When in doubt, say N. | ||||||
|  | 
 | ||||||
| config BITREVERSE | config BITREVERSE | ||||||
| 	tristate | 	tristate | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -154,6 +154,7 @@ obj-$(CONFIG_DEBUG_OBJECTS) += debugobjects.o | ||||||
| obj-$(CONFIG_BITREVERSE) += bitrev.o | obj-$(CONFIG_BITREVERSE) += bitrev.o | ||||||
| obj-$(CONFIG_LINEAR_RANGES) += linear_ranges.o | obj-$(CONFIG_LINEAR_RANGES) += linear_ranges.o | ||||||
| obj-$(CONFIG_PACKING)	+= packing.o | obj-$(CONFIG_PACKING)	+= packing.o | ||||||
|  | obj-$(CONFIG_PACKING_KUNIT_TEST) += packing_test.o | ||||||
| obj-$(CONFIG_CRC_CCITT)	+= crc-ccitt.o | obj-$(CONFIG_CRC_CCITT)	+= crc-ccitt.o | ||||||
| obj-$(CONFIG_CRC16)	+= crc16.o | obj-$(CONFIG_CRC16)	+= crc16.o | ||||||
| obj-$(CONFIG_CRC_T10DIF)+= crc-t10dif.o | obj-$(CONFIG_CRC_T10DIF)+= crc-t10dif.o | ||||||
|  |  | ||||||
							
								
								
									
										258
									
								
								lib/packing_test.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										258
									
								
								lib/packing_test.c
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,258 @@ | ||||||
|  | // SPDX-License-Identifier: GPL-2.0
 | ||||||
|  | /* Copyright (c) 2024, Vladimir Oltean <olteanv@gmail.com>
 | ||||||
|  |  * Copyright (c) 2024, Intel Corporation. | ||||||
|  |  */ | ||||||
|  | #include <kunit/test.h> | ||||||
|  | #include <linux/packing.h> | ||||||
|  | 
 | ||||||
|  | struct packing_test_case { | ||||||
|  | 	const char *desc; | ||||||
|  | 	const u8 *pbuf; | ||||||
|  | 	size_t pbuf_size; | ||||||
|  | 	u64 uval; | ||||||
|  | 	size_t start_bit; | ||||||
|  | 	size_t end_bit; | ||||||
|  | 	u8 quirks; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | #define NO_QUIRKS	0 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * PBUF - Initialize .pbuf and .pbuf_size | ||||||
|  |  * @array: elements of constant physical buffer | ||||||
|  |  * | ||||||
|  |  * Initializes the .pbuf and .pbuf_size fields of a struct packing_test_case | ||||||
|  |  * with a constant array of the specified elements. | ||||||
|  |  */ | ||||||
|  | #define PBUF(array...)					\ | ||||||
|  | 	.pbuf = (const u8[]){ array },			\ | ||||||
|  | 	.pbuf_size = sizeof((const u8 []){ array }) | ||||||
|  | 
 | ||||||
|  | static const struct packing_test_case cases[] = { | ||||||
|  | 	/* These tests pack and unpack a magic 64-bit value
 | ||||||
|  | 	 * (0xcafedeadbeefcafe) at a fixed logical offset (32) within an | ||||||
|  | 	 * otherwise zero array of 128 bits (16 bytes). They test all possible | ||||||
|  | 	 * bit layouts of the 128 bit buffer. | ||||||
|  | 	 */ | ||||||
|  | 	{ | ||||||
|  | 		.desc = "no quirks, 16 bytes", | ||||||
|  | 		PBUF(0x00, 0x00, 0x00, 0x00, 0xca, 0xfe, 0xde, 0xad, | ||||||
|  | 		     0xbe, 0xef, 0xca, 0xfe, 0x00, 0x00, 0x00, 0x00), | ||||||
|  | 		.uval = 0xcafedeadbeefcafe, | ||||||
|  | 		.start_bit = 95, | ||||||
|  | 		.end_bit = 32, | ||||||
|  | 		.quirks = NO_QUIRKS, | ||||||
|  | 	}, | ||||||
|  | 	{ | ||||||
|  | 		.desc = "lsw32 first, 16 bytes", | ||||||
|  | 		PBUF(0x00, 0x00, 0x00, 0x00, 0xbe, 0xef, 0xca, 0xfe, | ||||||
|  | 		     0xca, 0xfe, 0xde, 0xad, 0x00, 0x00, 0x00, 0x00), | ||||||
|  | 		.uval = 0xcafedeadbeefcafe, | ||||||
|  | 		.start_bit = 95, | ||||||
|  | 		.end_bit = 32, | ||||||
|  | 		.quirks = QUIRK_LSW32_IS_FIRST, | ||||||
|  | 	}, | ||||||
|  | 	{ | ||||||
|  | 		.desc = "little endian words, 16 bytes", | ||||||
|  | 		PBUF(0x00, 0x00, 0x00, 0x00, 0xad, 0xde, 0xfe, 0xca, | ||||||
|  | 		     0xfe, 0xca, 0xef, 0xbe, 0x00, 0x00, 0x00, 0x00), | ||||||
|  | 		.uval = 0xcafedeadbeefcafe, | ||||||
|  | 		.start_bit = 95, | ||||||
|  | 		.end_bit = 32, | ||||||
|  | 		.quirks = QUIRK_LITTLE_ENDIAN, | ||||||
|  | 	}, | ||||||
|  | 	{ | ||||||
|  | 		.desc = "lsw32 first + little endian words, 16 bytes", | ||||||
|  | 		PBUF(0x00, 0x00, 0x00, 0x00, 0xfe, 0xca, 0xef, 0xbe, | ||||||
|  | 		     0xad, 0xde, 0xfe, 0xca, 0x00, 0x00, 0x00, 0x00), | ||||||
|  | 		.uval = 0xcafedeadbeefcafe, | ||||||
|  | 		.start_bit = 95, | ||||||
|  | 		.end_bit = 32, | ||||||
|  | 		.quirks = QUIRK_LSW32_IS_FIRST | QUIRK_LITTLE_ENDIAN, | ||||||
|  | 	}, | ||||||
|  | 	{ | ||||||
|  | 		.desc = "msb right, 16 bytes", | ||||||
|  | 		PBUF(0x00, 0x00, 0x00, 0x00, 0x53, 0x7f, 0x7b, 0xb5, | ||||||
|  | 		     0x7d, 0xf7, 0x53, 0x7f, 0x00, 0x00, 0x00, 0x00), | ||||||
|  | 		.uval = 0xcafedeadbeefcafe, | ||||||
|  | 		.start_bit = 95, | ||||||
|  | 		.end_bit = 32, | ||||||
|  | 		.quirks = QUIRK_MSB_ON_THE_RIGHT, | ||||||
|  | 	}, | ||||||
|  | 	{ | ||||||
|  | 		.desc = "msb right + lsw32 first, 16 bytes", | ||||||
|  | 		PBUF(0x00, 0x00, 0x00, 0x00, 0x7d, 0xf7, 0x53, 0x7f, | ||||||
|  | 		     0x53, 0x7f, 0x7b, 0xb5, 0x00, 0x00, 0x00, 0x00), | ||||||
|  | 		.uval = 0xcafedeadbeefcafe, | ||||||
|  | 		.start_bit = 95, | ||||||
|  | 		.end_bit = 32, | ||||||
|  | 		.quirks = QUIRK_MSB_ON_THE_RIGHT | QUIRK_LSW32_IS_FIRST, | ||||||
|  | 	}, | ||||||
|  | 	{ | ||||||
|  | 		.desc = "msb right + little endian words, 16 bytes", | ||||||
|  | 		PBUF(0x00, 0x00, 0x00, 0x00, 0xb5, 0x7b, 0x7f, 0x53, | ||||||
|  | 		     0x7f, 0x53, 0xf7, 0x7d, 0x00, 0x00, 0x00, 0x00), | ||||||
|  | 		.uval = 0xcafedeadbeefcafe, | ||||||
|  | 		.start_bit = 95, | ||||||
|  | 		.end_bit = 32, | ||||||
|  | 		.quirks = QUIRK_MSB_ON_THE_RIGHT | QUIRK_LITTLE_ENDIAN, | ||||||
|  | 	}, | ||||||
|  | 	{ | ||||||
|  | 		.desc = "msb right + lsw32 first + little endian words, 16 bytes", | ||||||
|  | 		PBUF(0x00, 0x00, 0x00, 0x00, 0x7f, 0x53, 0xf7, 0x7d, | ||||||
|  | 		     0xb5, 0x7b, 0x7f, 0x53, 0x00, 0x00, 0x00, 0x00), | ||||||
|  | 		.uval = 0xcafedeadbeefcafe, | ||||||
|  | 		.start_bit = 95, | ||||||
|  | 		.end_bit = 32, | ||||||
|  | 		.quirks = QUIRK_MSB_ON_THE_RIGHT | QUIRK_LSW32_IS_FIRST | QUIRK_LITTLE_ENDIAN, | ||||||
|  | 	}, | ||||||
|  | 	/* These tests pack and unpack a magic 64-bit value
 | ||||||
|  | 	 * (0xcafedeadbeefcafe) at a fixed logical offset (32) within an | ||||||
|  | 	 * otherwise zero array of varying size from 18 bytes to 24 bytes. | ||||||
|  | 	 */ | ||||||
|  | 	{ | ||||||
|  | 		.desc = "no quirks, 18 bytes", | ||||||
|  | 		PBUF(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xfe, | ||||||
|  | 		     0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x00, 0x00, | ||||||
|  | 		     0x00, 0x00), | ||||||
|  | 		.uval = 0xcafedeadbeefcafe, | ||||||
|  | 		.start_bit = 95, | ||||||
|  | 		.end_bit = 32, | ||||||
|  | 		.quirks = NO_QUIRKS, | ||||||
|  | 	}, | ||||||
|  | 	{ | ||||||
|  | 		.desc = "no quirks, 19 bytes", | ||||||
|  | 		PBUF(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, | ||||||
|  | 		     0xfe, 0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x00, | ||||||
|  | 		     0x00, 0x00, 0x00), | ||||||
|  | 		.uval = 0xcafedeadbeefcafe, | ||||||
|  | 		.start_bit = 95, | ||||||
|  | 		.end_bit = 32, | ||||||
|  | 		.quirks = NO_QUIRKS, | ||||||
|  | 	}, | ||||||
|  | 	{ | ||||||
|  | 		.desc = "no quirks, 20 bytes", | ||||||
|  | 		PBUF(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||||
|  | 		     0xca, 0xfe, 0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, | ||||||
|  | 		     0x00, 0x00, 0x00, 0x00), | ||||||
|  | 		.uval = 0xcafedeadbeefcafe, | ||||||
|  | 		.start_bit = 95, | ||||||
|  | 		.end_bit = 32, | ||||||
|  | 		.quirks = NO_QUIRKS, | ||||||
|  | 	}, | ||||||
|  | 	{ | ||||||
|  | 		.desc = "no quirks, 22 bytes", | ||||||
|  | 		PBUF(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||||
|  | 		     0x00, 0x00, 0xca, 0xfe, 0xde, 0xad, 0xbe, 0xef, | ||||||
|  | 		     0xca, 0xfe, 0x00, 0x00, 0x00, 0x00), | ||||||
|  | 		.uval = 0xcafedeadbeefcafe, | ||||||
|  | 		.start_bit = 95, | ||||||
|  | 		.end_bit = 32, | ||||||
|  | 		.quirks = NO_QUIRKS, | ||||||
|  | 	}, | ||||||
|  | 	{ | ||||||
|  | 		.desc = "no quirks, 24 bytes", | ||||||
|  | 		PBUF(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||||
|  | 		     0x00, 0x00, 0x00, 0x00, 0xca, 0xfe, 0xde, 0xad, | ||||||
|  | 		     0xbe, 0xef, 0xca, 0xfe, 0x00, 0x00, 0x00, 0x00), | ||||||
|  | 		.uval = 0xcafedeadbeefcafe, | ||||||
|  | 		.start_bit = 95, | ||||||
|  | 		.end_bit = 32, | ||||||
|  | 		.quirks = NO_QUIRKS, | ||||||
|  | 	}, | ||||||
|  | 	{ | ||||||
|  | 		.desc = "lsw32 first + little endian words, 18 bytes", | ||||||
|  | 		PBUF(0x00, 0x00, 0x00, 0x00, 0xfe, 0xca, 0xef, 0xbe, | ||||||
|  | 		     0xad, 0xde, 0xfe, 0xca, 0x00, 0x00, 0x00, 0x00, | ||||||
|  | 		     0x00, 0x00), | ||||||
|  | 		.uval = 0xcafedeadbeefcafe, | ||||||
|  | 		.start_bit = 95, | ||||||
|  | 		.end_bit = 32, | ||||||
|  | 		.quirks = QUIRK_LSW32_IS_FIRST | QUIRK_LITTLE_ENDIAN, | ||||||
|  | 	}, | ||||||
|  | 	{ | ||||||
|  | 		.desc = "lsw32 first + little endian words, 19 bytes", | ||||||
|  | 		PBUF(0x00, 0x00, 0x00, 0x00, 0xfe, 0xca, 0xef, 0xbe, | ||||||
|  | 		     0xad, 0xde, 0xfe, 0xca, 0x00, 0x00, 0x00, 0x00, | ||||||
|  | 		     0x00, 0x00, 0x00), | ||||||
|  | 		.uval = 0xcafedeadbeefcafe, | ||||||
|  | 		.start_bit = 95, | ||||||
|  | 		.end_bit = 32, | ||||||
|  | 		.quirks = QUIRK_LSW32_IS_FIRST | QUIRK_LITTLE_ENDIAN, | ||||||
|  | 	}, | ||||||
|  | 	{ | ||||||
|  | 		.desc = "lsw32 first + little endian words, 20 bytes", | ||||||
|  | 		PBUF(0x00, 0x00, 0x00, 0x00, 0xfe, 0xca, 0xef, 0xbe, | ||||||
|  | 		     0xad, 0xde, 0xfe, 0xca, 0x00, 0x00, 0x00, 0x00, | ||||||
|  | 		     0x00, 0x00, 0x00, 0x00), | ||||||
|  | 		.uval = 0xcafedeadbeefcafe, | ||||||
|  | 		.start_bit = 95, | ||||||
|  | 		.end_bit = 32, | ||||||
|  | 		.quirks = QUIRK_LSW32_IS_FIRST | QUIRK_LITTLE_ENDIAN, | ||||||
|  | 	}, | ||||||
|  | 	{ | ||||||
|  | 		.desc = "lsw32 first + little endian words, 22 bytes", | ||||||
|  | 		PBUF(0x00, 0x00, 0x00, 0x00, 0xfe, 0xca, 0xef, 0xbe, | ||||||
|  | 		     0xad, 0xde, 0xfe, 0xca, 0x00, 0x00, 0x00, 0x00, | ||||||
|  | 		     0x00, 0x00, 0x00, 0x00, 0x00, 0x00), | ||||||
|  | 		.uval = 0xcafedeadbeefcafe, | ||||||
|  | 		.start_bit = 95, | ||||||
|  | 		.end_bit = 32, | ||||||
|  | 		.quirks = QUIRK_LSW32_IS_FIRST | QUIRK_LITTLE_ENDIAN, | ||||||
|  | 	}, | ||||||
|  | 	{ | ||||||
|  | 		.desc = "lsw32 first + little endian words, 24 bytes", | ||||||
|  | 		PBUF(0x00, 0x00, 0x00, 0x00, 0xfe, 0xca, 0xef, 0xbe, | ||||||
|  | 		     0xad, 0xde, 0xfe, 0xca, 0x00, 0x00, 0x00, 0x00, | ||||||
|  | 		     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), | ||||||
|  | 		.uval = 0xcafedeadbeefcafe, | ||||||
|  | 		.start_bit = 95, | ||||||
|  | 		.end_bit = 32, | ||||||
|  | 		.quirks = QUIRK_LSW32_IS_FIRST | QUIRK_LITTLE_ENDIAN, | ||||||
|  | 	}, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | KUNIT_ARRAY_PARAM_DESC(packing, cases, desc); | ||||||
|  | 
 | ||||||
|  | static void packing_test_pack(struct kunit *test) | ||||||
|  | { | ||||||
|  | 	const struct packing_test_case *params = test->param_value; | ||||||
|  | 	u8 *pbuf; | ||||||
|  | 	int err; | ||||||
|  | 
 | ||||||
|  | 	pbuf = kunit_kzalloc(test, params->pbuf_size, GFP_KERNEL); | ||||||
|  | 
 | ||||||
|  | 	err = pack(pbuf, params->uval, params->start_bit, params->end_bit, | ||||||
|  | 		   params->pbuf_size, params->quirks); | ||||||
|  | 
 | ||||||
|  | 	KUNIT_EXPECT_EQ_MSG(test, err, 0, "pack() returned %pe\n", ERR_PTR(err)); | ||||||
|  | 	KUNIT_EXPECT_MEMEQ(test, pbuf, params->pbuf, params->pbuf_size); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void packing_test_unpack(struct kunit *test) | ||||||
|  | { | ||||||
|  | 	const struct packing_test_case *params = test->param_value; | ||||||
|  | 	u64 uval; | ||||||
|  | 	int err; | ||||||
|  | 
 | ||||||
|  | 	err = unpack(params->pbuf, &uval, params->start_bit, params->end_bit, | ||||||
|  | 		     params->pbuf_size, params->quirks); | ||||||
|  | 	KUNIT_EXPECT_EQ_MSG(test, err, 0, "unpack() returned %pe\n", ERR_PTR(err)); | ||||||
|  | 	KUNIT_EXPECT_EQ(test, uval, params->uval); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static struct kunit_case packing_test_cases[] = { | ||||||
|  | 	KUNIT_CASE_PARAM(packing_test_pack, packing_gen_params), | ||||||
|  | 	KUNIT_CASE_PARAM(packing_test_unpack, packing_gen_params), | ||||||
|  | 	{}, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static struct kunit_suite packing_test_suite = { | ||||||
|  | 	.name = "packing", | ||||||
|  | 	.test_cases = packing_test_cases, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | kunit_test_suite(packing_test_suite); | ||||||
|  | 
 | ||||||
|  | MODULE_LICENSE("GPL"); | ||||||
|  | MODULE_DESCRIPTION("KUnit tests for packing library"); | ||||||
		Loading…
	
		Reference in a new issue
	
	 Jacob Keller
						Jacob Keller