The Linux Kernel Mailing List
 help / color / mirror / Atom feed
* [PATCH] lib/uuid_kunit: add tests for the four random UUID/GUID generators
@ 2026-05-14 17:22 Stepan Ionichev
  2026-05-15 10:51 ` Andy Shevchenko
  0 siblings, 1 reply; 2+ messages in thread
From: Stepan Ionichev @ 2026-05-14 17:22 UTC (permalink / raw)
  To: andriy.shevchenko
  Cc: akpm, gregkh, brendan.higgins, david, raemoar63, linux-kselftest,
	kunit-dev, linux-kernel, sozdayvek

uuid_kunit currently exercises only guid_parse() and uuid_parse() (plus
their invalid-input paths). The four random generators exported from
lib/uuid.c -- generate_random_uuid(), generate_random_guid(),
uuid_gen() and guid_gen() -- have no direct kunit coverage.

Random output cannot be compared against a fixed expected value, but
RFC 4122 section 4.4 specifies two invariants that any version-4
random UUID/GUID must satisfy:

  - version 4 in the high nibble of the version byte
    (byte 6 in the wire uuid_t layout, byte 7 in the byte-swapped
    guid_t layout);
  - variant DCE 1.1 (binary 10x) in the high bits of byte 8.

Add four test cases that invoke each generator several times and
verify these bit patterns hold. The same checks catch a regression
in either the mask/OR sequence in the generators or the layout
constants. Run the loop a handful of times to cover the small but
non-zero chance that an unmasked random byte happens to satisfy
the version/variant pattern by accident on a single call.

Signed-off-by: Stepan Ionichev <sozdayvek@gmail.com>
---
 lib/tests/uuid_kunit.c | 60 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/lib/tests/uuid_kunit.c b/lib/tests/uuid_kunit.c
index de71b2649..a800a80e6 100644
--- a/lib/tests/uuid_kunit.c
+++ b/lib/tests/uuid_kunit.c
@@ -86,11 +86,71 @@ static void uuid_test_uuid_invalid(struct kunit *test)
 	}
 }
 
+/*
+ * RFC 4122 section 4.4 says random UUIDs/GUIDs (version 4) must have:
+ *   - version 4 in the high nibble of the version byte,
+ *   - variant DCE 1.1 (binary 10x) in the high bits of byte 8.
+ *
+ * The version byte is byte 6 in the "wire" uuid_t layout and byte 7 in
+ * the byte-swapped guid_t layout.
+ */
+static void uuid_test_uuid_gen(struct kunit *test)
+{
+	unsigned int i;
+	uuid_t u;
+
+	for (i = 0; i < 8; i++) {
+		uuid_gen(&u);
+		KUNIT_EXPECT_EQ(test, u.b[6] & 0xf0, 0x40);
+		KUNIT_EXPECT_EQ(test, u.b[8] & 0xc0, 0x80);
+	}
+}
+
+static void uuid_test_guid_gen(struct kunit *test)
+{
+	unsigned int i;
+	guid_t g;
+
+	for (i = 0; i < 8; i++) {
+		guid_gen(&g);
+		KUNIT_EXPECT_EQ(test, g.b[7] & 0xf0, 0x40);
+		KUNIT_EXPECT_EQ(test, g.b[8] & 0xc0, 0x80);
+	}
+}
+
+static void uuid_test_generate_random_uuid(struct kunit *test)
+{
+	unsigned char buf[16];
+	unsigned int i;
+
+	for (i = 0; i < 8; i++) {
+		generate_random_uuid(buf);
+		KUNIT_EXPECT_EQ(test, buf[6] & 0xf0, 0x40);
+		KUNIT_EXPECT_EQ(test, buf[8] & 0xc0, 0x80);
+	}
+}
+
+static void uuid_test_generate_random_guid(struct kunit *test)
+{
+	unsigned char buf[16];
+	unsigned int i;
+
+	for (i = 0; i < 8; i++) {
+		generate_random_guid(buf);
+		KUNIT_EXPECT_EQ(test, buf[7] & 0xf0, 0x40);
+		KUNIT_EXPECT_EQ(test, buf[8] & 0xc0, 0x80);
+	}
+}
+
 static struct kunit_case uuid_test_cases[] = {
 	KUNIT_CASE(uuid_test_guid_valid),
 	KUNIT_CASE(uuid_test_uuid_valid),
 	KUNIT_CASE(uuid_test_guid_invalid),
 	KUNIT_CASE(uuid_test_uuid_invalid),
+	KUNIT_CASE(uuid_test_uuid_gen),
+	KUNIT_CASE(uuid_test_guid_gen),
+	KUNIT_CASE(uuid_test_generate_random_uuid),
+	KUNIT_CASE(uuid_test_generate_random_guid),
 	{},
 };
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] lib/uuid_kunit: add tests for the four random UUID/GUID generators
  2026-05-14 17:22 [PATCH] lib/uuid_kunit: add tests for the four random UUID/GUID generators Stepan Ionichev
@ 2026-05-15 10:51 ` Andy Shevchenko
  0 siblings, 0 replies; 2+ messages in thread
From: Andy Shevchenko @ 2026-05-15 10:51 UTC (permalink / raw)
  To: Stepan Ionichev
  Cc: akpm, gregkh, brendan.higgins, david, raemoar63, linux-kselftest,
	kunit-dev, linux-kernel

On Thu, May 14, 2026 at 10:22:41PM +0500, Stepan Ionichev wrote:
> uuid_kunit currently exercises only guid_parse() and uuid_parse() (plus
> their invalid-input paths). The four random generators exported from
> lib/uuid.c -- generate_random_uuid(), generate_random_guid(),
> uuid_gen() and guid_gen() -- have no direct kunit coverage.
> 
> Random output cannot be compared against a fixed expected value, but
> RFC 4122 section 4.4 specifies two invariants that any version-4
> random UUID/GUID must satisfy:
> 
>   - version 4 in the high nibble of the version byte
>     (byte 6 in the wire uuid_t layout, byte 7 in the byte-swapped
>     guid_t layout);
>   - variant DCE 1.1 (binary 10x) in the high bits of byte 8.
> 
> Add four test cases that invoke each generator several times and
> verify these bit patterns hold. The same checks catch a regression
> in either the mask/OR sequence in the generators or the layout
> constants. Run the loop a handful of times to cover the small but
> non-zero chance that an unmasked random byte happens to satisfy
> the version/variant pattern by accident on a single call.

Test cases are always good, although here I'm not sure we are so picky about
following this RFC. Whatever, feel free to add
Acked-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

...

> +static void uuid_test_uuid_gen(struct kunit *test)
> +{
> +	unsigned int i;
> +	uuid_t u;

> +	for (i = 0; i < 8; i++) {

Can be

	for (unsigned int i = 0; i < 8; i++) {

> +		uuid_gen(&u);
> +		KUNIT_EXPECT_EQ(test, u.b[6] & 0xf0, 0x40);
> +		KUNIT_EXPECT_EQ(test, u.b[8] & 0xc0, 0x80);
> +	}
> +}

Same for the rest.

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-05-15 10:51 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-14 17:22 [PATCH] lib/uuid_kunit: add tests for the four random UUID/GUID generators Stepan Ionichev
2026-05-15 10:51 ` Andy Shevchenko

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox