From 322496c2863d5bc14b0a5e4af16690bf19073cae Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Sat, 6 Jun 2026 09:19:02 +0300 Subject: test(chown): add end-to-end coverage for chown/fchown/lchown/fchownat family chown/lchown/fchownat/fchown previously had no integration coverage: no scenario in cmd/ioworkload/ and no test in integrationtests/. All four are correctly classified (chown/lchown KindPathname args[0]; fchownat KindPathname args[1]; fchown KindFd args[0]; all FamilyFS, all UNCLASSIFIED ret) but nothing exercised them end-to-end. Add a chown-basic scenario that, on a temp file and a symlink the caller owns, issues raw chown(path,-1,-1), lchown(symlink,-1,-1), fchownat(AT_FDCWD,path, -1,-1,0) and fchown(fd,-1,-1). Owner/group -1/-1 means "leave both ids unchanged", which the kernel accepts without CAP_CHOWN, so the scenario is fully UNPRIVILEGED and nothing is actually modified. Raw syscalls are used so each distinct tracepoint fires rather than glibc redirecting chown to fchownat. TestChownBasic asserts enter_chown and enter_fchownat capture the regular file path (chownfile.txt), enter_lchown captures the symlink (chownlink), and enter_fchown fires (KindFd, no path). Mirrors the chmod coverage (scenario_chmod.go / chmod_test.go). Co-Authored-By: Claude Opus 4.8 --- integrationtests/chown_test.go | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 integrationtests/chown_test.go (limited to 'integrationtests') diff --git a/integrationtests/chown_test.go b/integrationtests/chown_test.go new file mode 100644 index 0000000..4ada1b6 --- /dev/null +++ b/integrationtests/chown_test.go @@ -0,0 +1,40 @@ +package integrationtests + +import "testing" + +// TestChownBasic verifies ior captures the chown ownership-change family +// end-to-end. chown, lchown and fchownat all take a real filesystem path +// (args[0], args[0] and args[1] respectively), so each must be path-classified +// (KindPathname) with the path captured: chown/fchownat on the regular file +// (chownfile.txt) and lchown on the symlink (chownlink). fchown operates on an +// open fd (KindFd) and carries no path, so we only assert the tracepoint fired. +// Every call uses owner/group -1/-1 ("no change"), so the scenario runs +// unprivileged (no CAP_CHOWN). Mirrors the chmod coverage (scenario_chown.go / +// chown_test.go). +func TestChownBasic(t *testing.T) { + runScenario(t, "chown-basic", []ExpectedEvent{ + { + PathContains: "chownfile.txt", + Tracepoint: "enter_chown", + Comm: "ioworkload", + MinCount: 1, + }, + { + PathContains: "chownlink", + Tracepoint: "enter_lchown", + Comm: "ioworkload", + MinCount: 1, + }, + { + PathContains: "chownfile.txt", + Tracepoint: "enter_fchownat", + Comm: "ioworkload", + MinCount: 1, + }, + { + Tracepoint: "enter_fchown", + Comm: "ioworkload", + MinCount: 1, + }, + }) +} -- cgit v1.2.3