From c61fb1f71a72d66960914877e8f0a24638c85324 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Tue, 9 Jun 2026 22:33:34 +0300 Subject: test(memory): add coverage for mlock/mlock2/munlock/mlockall/munlockall The memory-locking cluster (FamilyMemory) had no end-to-end integration coverage; mmap_test.go only exercised mmap/msync/mremap/munmap. These syscalls return UNCLASSIFIED, so enter-tracepoint presence is the right end-to-end check (mlock/mlock2/munlock are KindMem, mlockall/munlockall are KindNull). Add a mmap-memory-lock scenario that, on a single anonymous page (small enough to stay under RLIMIT_MEMLOCK), issues raw syscalls for mlock, munlock, mlock2(addr,len,0), mlockall(MCL_CURRENT) and munlockall so the exact sys_enter_ tracepoints fire. mlock/mlock2/mlockall tolerate EPERM/ENOMEM best-effort since the enter tracepoint fires before the error; munlock/munlockall always succeed and clean up. TestMmapMemoryLock asserts enter_mlock, enter_munlock, enter_mlock2, enter_mlockall and enter_munlockall each fire (MinCount>=1, Comm ioworkload). All five captured under sudo. Co-Authored-By: Claude Opus 4.8 --- integrationtests/mmap_test.go | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'integrationtests') diff --git a/integrationtests/mmap_test.go b/integrationtests/mmap_test.go index 74eb14e..ff3ad55 100644 --- a/integrationtests/mmap_test.go +++ b/integrationtests/mmap_test.go @@ -11,6 +11,11 @@ const ( var mmapTraceArgs = []string{"-trace-syscalls", "openat,write,close,mmap,msync,mremap,munmap"} +// mmapMemoryLockTraceArgs traces the memory-locking cluster. mlock/mlock2/ +// munlock are KindMem and mlockall/munlockall are KindNull; in all cases only +// the sys_enter_ tracepoint presence is asserted (return is UNCLASSIFIED). +var mmapMemoryLockTraceArgs = []string{"-trace-syscalls", "mlock,mlock2,munlock,mlockall,munlockall"} + func TestMmapBasic(t *testing.T) { runScenarioResultWithIorArgs(t, "mmap-basic", []ExpectedEvent{ { @@ -78,6 +83,41 @@ func TestMmapMremapMunmap(t *testing.T) { }, 0) } +// TestMmapMemoryLock asserts the memory-locking cluster fires its enter +// tracepoints end-to-end. mlock/mlock2/munlock (KindMem) and mlockall/ +// munlockall (KindNull) all return UNCLASSIFIED, so enter-presence is the +// correct check. mlock/mlock2/mlockall may hit EPERM/ENOMEM under a low +// RLIMIT_MEMLOCK, but the sys_enter_ tracepoint fires regardless. +func TestMmapMemoryLock(t *testing.T) { + runScenarioResultWithIorArgs(t, "mmap-memory-lock", []ExpectedEvent{ + { + Tracepoint: "enter_mlock", + Comm: "ioworkload", + MinCount: 1, + }, + { + Tracepoint: "enter_munlock", + Comm: "ioworkload", + MinCount: 1, + }, + { + Tracepoint: "enter_mlock2", + Comm: "ioworkload", + MinCount: 1, + }, + { + Tracepoint: "enter_mlockall", + Comm: "ioworkload", + MinCount: 1, + }, + { + Tracepoint: "enter_munlockall", + Comm: "ioworkload", + MinCount: 1, + }, + }, mmapMemoryLockTraceArgs) +} + func TestMmapMremapMunmapAddressSpaceBytesInParquet(t *testing.T) { h := newTestHarness(t) h.WorkloadEnv = []string{mmapWorkloadStartupEnv} -- cgit v1.2.3