Skip to content

Commit

Permalink
tests: use PRNG to generate data for tests
Browse files Browse the repository at this point in the history
This replaces the multiples of a prime sequence used for the per-CPU
helper tests with a slightly more self-documenting PRNG interface in
both the test kernel module and Python test scaffolding. It will be used
more in upcoming tests.

Signed-off-by: Omar Sandoval <[email protected]>
  • Loading branch information
osandov committed Feb 22, 2023
1 parent 38b090e commit dc38822
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 19 deletions.
12 changes: 12 additions & 0 deletions tests/linux_kernel/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,18 @@ def setUpClass(cls):
)


# PRNG used by the test kernel module.
def prng32(seed):
seed = seed.encode("ascii")
assert len(seed) == 4
x = int.from_bytes(seed, "big")
while True:
x ^= (x << 13) & 0xFFFFFFFF
x ^= x >> 17
x ^= (x << 5) & 0xFFFFFFFF
yield x


def wait_until(fn, *args, **kwds):
TIMEOUT = 5
deadline = time.monotonic() + TIMEOUT
Expand Down
9 changes: 3 additions & 6 deletions tests/linux_kernel/helpers/test_percpu.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from drgn.helpers.linux.percpu import per_cpu, per_cpu_ptr
from tests.linux_kernel import (
LinuxKernelTestCase,
prng32,
skip_unless_have_test_kmod,
smp_enabled,
)
Expand All @@ -25,18 +26,14 @@ def test_per_cpu(self):

@skip_unless_have_test_kmod
def test_per_cpu_module_static(self):
expected = prime = self.prog["drgn_test_percpu_static_prime"]
for cpu in for_each_possible_cpu(self.prog):
expected *= prime
for cpu, expected in zip(for_each_possible_cpu(self.prog), prng32("PCPU")):
self.assertEqual(
per_cpu(self.prog["drgn_test_percpu_static"], cpu), expected
)

@skip_unless_have_test_kmod
def test_per_cpu_module_dynamic(self):
expected = prime = self.prog["drgn_test_percpu_dynamic_prime"]
for cpu in for_each_possible_cpu(self.prog):
expected *= prime
for cpu, expected in zip(for_each_possible_cpu(self.prog), prng32("pcpu")):
self.assertEqual(
per_cpu_ptr(self.prog["drgn_test_percpu_dynamic"], cpu)[0], expected
)
40 changes: 27 additions & 13 deletions tests/linux_kernel/kmod/drgn_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,23 @@
#define HAVE_XARRAY 0
#endif

// Convert a 4-character string to a seed for drgn_test_prng32().
static inline u32 drgn_test_prng32_seed(const char *s)
{
BUG_ON(strlen(s) != 4);
return ((u32)s[0] << 24) | ((u32)s[1] << 16) | ((u32)s[2] << 8) | (u32)s[3];
}

// x must not be 0; the return value is never 0.
static u32 drgn_test_prng32(u32 x)
{
// Xorshift RNG with a period of 2^32 - 1.
x ^= x << 13;
x ^= x >> 17;
x ^= x << 5;
return x;
}

// list

LIST_HEAD(drgn_test_empty_list);
Expand Down Expand Up @@ -156,27 +173,24 @@ static void drgn_test_mm_exit(void)

// percpu

DEFINE_PER_CPU(unsigned int, drgn_test_percpu_static);
const unsigned int drgn_test_percpu_static_prime = 0xa45dcfc3U;
unsigned int __percpu *drgn_test_percpu_dynamic;
const unsigned int drgn_test_percpu_dynamic_prime = 0x6d80a613U;
DEFINE_PER_CPU(u32, drgn_test_percpu_static);
u32 __percpu *drgn_test_percpu_dynamic;

static int drgn_test_percpu_init(void)
{
int cpu;
unsigned int static_prime = drgn_test_percpu_static_prime;
unsigned int dynamic_prime = drgn_test_percpu_dynamic_prime;
u32 static_seed = drgn_test_prng32_seed("PCPU");
u32 dynamic_seed = drgn_test_prng32_seed("pcpu");

drgn_test_percpu_dynamic = alloc_percpu(unsigned int);
drgn_test_percpu_dynamic = alloc_percpu(u32);
if (!drgn_test_percpu_dynamic)
return -ENOMEM;
// Initialize the per-cpu variables to powers of a random prime number
// which are extremely unlikely to appear anywhere else.
// Initialize the per-cpu variables with a PRNG sequence.
for_each_possible_cpu(cpu) {
static_prime *= drgn_test_percpu_static_prime;
per_cpu(drgn_test_percpu_static, cpu) = static_prime;
dynamic_prime *= drgn_test_percpu_dynamic_prime;
*per_cpu_ptr(drgn_test_percpu_dynamic, cpu) = dynamic_prime;
static_seed = drgn_test_prng32(static_seed);
per_cpu(drgn_test_percpu_static, cpu) = static_seed;
dynamic_seed = drgn_test_prng32(dynamic_seed);
*per_cpu_ptr(drgn_test_percpu_dynamic, cpu) = dynamic_seed;
}
return 0;
}
Expand Down

0 comments on commit dc38822

Please sign in to comment.