diff options
| author | Paul Buetow <paul@buetow.org> | 2026-02-21 11:51:01 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-02-21 11:51:01 +0200 |
| commit | 6c912a9d72ae2a43923c638538d320e6bf585952 (patch) | |
| tree | 727f66d158210e01abf8c18a83ef4db6066e0c1a /internal/generate/classify_test.go | |
| parent | 32136b8cb18944157ff1f361bc0755f6b627fd47 (diff) | |
Migrate make targets to mage
Amp-Thread-ID: https://ampcode.com/threads/T-019c7f4e-cc5f-76f1-aaf0-dd7cbaabbb18
Co-authored-by: Amp <amp@ampcode.com>
Diffstat (limited to 'internal/generate/classify_test.go')
| -rw-r--r-- | internal/generate/classify_test.go | 332 |
1 files changed, 332 insertions, 0 deletions
diff --git a/internal/generate/classify_test.go b/internal/generate/classify_test.go new file mode 100644 index 0000000..c94e359 --- /dev/null +++ b/internal/generate/classify_test.go @@ -0,0 +1,332 @@ +package generate + +import ( + "strings" + "testing" +) + +func classifyFromData(t *testing.T, data string) ClassificationResult { + t.Helper() + f := mustParseOne(t, data) + return ClassifyFormat(&f) +} + +func TestClassifyFdRead(t *testing.T) { + r := classifyFromData(t, FormatRead) + if r.Kind != KindFd { + t.Errorf("read: got kind %d, want KindFd", r.Kind) + } +} + +func TestClassifyFdClose(t *testing.T) { + r := classifyFromData(t, FormatClose) + if r.Kind != KindFd { + t.Errorf("close: got kind %d, want KindFd", r.Kind) + } +} + +func TestClassifyFdPread64(t *testing.T) { + r := classifyFromData(t, FormatPread64) + if r.Kind != KindFd { + t.Errorf("pread64: got kind %d, want KindFd", r.Kind) + } +} + +func TestClassifyFdWrite(t *testing.T) { + r := classifyFromData(t, FormatWrite) + if r.Kind != KindFd { + t.Errorf("write: got kind %d, want KindFd", r.Kind) + } +} + +func TestClassifyOpenOpenat(t *testing.T) { + r := classifyFromData(t, FormatOpenat) + if r.Kind != KindOpen { + t.Errorf("openat: got kind %d, want KindOpen", r.Kind) + } +} + +func TestClassifyOpenOpen(t *testing.T) { + r := classifyFromData(t, FormatOpen) + if r.Kind != KindOpen { + t.Errorf("open: got kind %d, want KindOpen", r.Kind) + } +} + +func TestClassifyOpenOpenat2(t *testing.T) { + r := classifyFromData(t, FormatOpenat2) + if r.Kind != KindOpen { + t.Errorf("openat2: got kind %d, want KindOpen", r.Kind) + } +} + +func TestClassifyPathnameCreat(t *testing.T) { + r := classifyFromData(t, FormatCreat) + if r.Kind != KindPathname { + t.Errorf("creat: got kind %d, want KindPathname", r.Kind) + } + if r.PathnameField != "pathname" { + t.Errorf("creat: PathnameField = %q, want pathname", r.PathnameField) + } +} + +func TestClassifyPathnameUnlink(t *testing.T) { + r := classifyFromData(t, FormatUnlink) + if r.Kind != KindPathname { + t.Errorf("unlink: got kind %d, want KindPathname", r.Kind) + } + if r.PathnameField != "pathname" { + t.Errorf("unlink: PathnameField = %q, want pathname", r.PathnameField) + } +} + +func TestClassifyNameRename(t *testing.T) { + r := classifyFromData(t, FormatRename) + if r.Kind != KindName { + t.Errorf("rename: got kind %d, want KindName", r.Kind) + } +} + +func TestClassifyNameLinkat(t *testing.T) { + r := classifyFromData(t, FormatLinkat) + if r.Kind != KindName { + t.Errorf("linkat: got kind %d, want KindName", r.Kind) + } +} + +func TestClassifyNameSymlink(t *testing.T) { + r := classifyFromData(t, FormatSymlink) + if r.Kind != KindName { + t.Errorf("symlink: got kind %d, want KindName", r.Kind) + } +} + +func TestClassifyFcntl(t *testing.T) { + r := classifyFromData(t, FormatFcntl) + if r.Kind != KindFcntl { + t.Errorf("fcntl: got kind %d, want KindFcntl", r.Kind) + } +} + +func TestClassifyDup(t *testing.T) { + r := classifyFromData(t, FormatDup) + if r.Kind != KindFd { + t.Errorf("dup: got kind %d, want KindFd", r.Kind) + } +} + +func TestClassifyDup2(t *testing.T) { + r := classifyFromData(t, FormatDup2) + if r.Kind != KindFd { + t.Errorf("dup2: got kind %d, want KindFd", r.Kind) + } +} + +func TestClassifyDup3(t *testing.T) { + r := classifyFromData(t, FormatDup3) + if r.Kind != KindDup3 { + t.Errorf("dup3: got kind %d, want KindDup3", r.Kind) + } +} + +func TestClassifyOpenByHandleAt(t *testing.T) { + r := classifyFromData(t, FormatOpenByHandleAt) + if r.Kind != KindOpenByHandleAt { + t.Errorf("open_by_handle_at: got kind %d, want KindOpenByHandleAt", r.Kind) + } +} + +func TestClassifyNullSync(t *testing.T) { + r := classifyFromData(t, FormatSync) + if r.Kind != KindNull { + t.Errorf("sync: got kind %d, want KindNull", r.Kind) + } +} + +func TestClassifyNullSyslog(t *testing.T) { + r := classifyFromData(t, FormatSyslog) + if r.Kind != KindNull { + t.Errorf("syslog: got kind %d, want KindNull", r.Kind) + } +} + +func TestClassifyNullIoUring(t *testing.T) { + r := classifyFromData(t, FormatIoUringEnter) + if r.Kind != KindNull { + t.Errorf("io_uring_enter: got kind %d, want KindNull", r.Kind) + } +} + +func TestClassifyRetExitRead(t *testing.T) { + r := classifyFromData(t, FormatExitRead) + if r.Kind != KindRet { + t.Errorf("exit_read: got kind %d, want KindRet", r.Kind) + } +} + +func TestClassifyRetExitWrite(t *testing.T) { + r := classifyFromData(t, FormatExitWrite) + if r.Kind != KindRet { + t.Errorf("exit_write: got kind %d, want KindRet", r.Kind) + } +} + +func TestClassifyRetExitOpenat(t *testing.T) { + r := classifyFromData(t, FormatExitOpenat) + if r.Kind != KindRet { + t.Errorf("exit_openat: got kind %d, want KindRet", r.Kind) + } +} + +func TestClassifyRetExitPread64(t *testing.T) { + r := classifyFromData(t, FormatExitPread64) + if r.Kind != KindRet { + t.Errorf("exit_pread64: got kind %d, want KindRet", r.Kind) + } +} + +func TestClassifyRetExitSymlink(t *testing.T) { + r := classifyFromData(t, FormatExitSymlink) + if r.Kind != KindRet { + t.Errorf("exit_symlink: got kind %d, want KindRet", r.Kind) + } +} + +// --- Ignore tests --- + +func TestIgnoreMknod(t *testing.T) { + r := classifyFromData(t, FormatMknod) + if r.Kind != KindNone { + t.Errorf("mknod: got kind %d, want KindNone (ignored)", r.Kind) + } +} + +func TestIgnoreExecve(t *testing.T) { + r := classifyFromData(t, FormatExecve) + if r.Kind != KindNone { + t.Errorf("execve: got kind %d, want KindNone (ignored)", r.Kind) + } +} + +func TestIgnoreAccept(t *testing.T) { + r := classifyFromData(t, FormatAccept) + if r.Kind != KindNone { + t.Errorf("accept: got kind %d, want KindNone (ignored)", r.Kind) + } +} + +func TestIgnoreSocket(t *testing.T) { + r := classifyFromData(t, FormatSocket) + if r.Kind != KindNone { + t.Errorf("socket: got kind %d, want KindNone (ignored)", r.Kind) + } +} + +func TestIgnoreKill(t *testing.T) { + r := classifyFromData(t, FormatKill) + if r.Kind != KindNone { + t.Errorf("kill: got kind %d, want KindNone (no matching type)", r.Kind) + } +} + +func TestShouldIgnorePatterns(t *testing.T) { + ignoreNames := []string{ + "sys_enter_mknod", "sys_enter_mknodat", + "sys_enter_execve", "sys_enter_execveat", + "sys_enter_accept", "sys_enter_accept4", + "sys_enter_listen", + "sys_enter_epoll_ctl", "sys_enter_epoll_pwait", + "sys_enter_recvfrom", "sys_enter_recvmsg", "sys_enter_recvmmsg", + "sys_enter_sendto", "sys_enter_sendmsg", "sys_enter_sendmmsg", + "sys_enter_socket", "sys_enter_socketpair", "sys_enter_getsockname", + "sys_enter_inotify_init", "sys_enter_inotify_add_watch", + "sys_enter_pidfd_open", "sys_enter_pidfd_getfd", + "sys_enter_bind", "sys_enter_setns", "sys_enter_shutdown", + "sys_enter_connect", "sys_enter_fanotify_init", "sys_enter_getpeername", + } + for _, name := range ignoreNames { + if !shouldIgnore(name) { + t.Errorf("shouldIgnore(%q) = false, want true", name) + } + } +} + +func TestShouldNotIgnore(t *testing.T) { + noIgnore := []string{ + "sys_enter_read", "sys_enter_write", "sys_enter_openat", + "sys_enter_close", "sys_enter_rename", "sys_enter_unlink", + "sys_exit_read", "sys_exit_openat", + } + for _, name := range noIgnore { + if shouldIgnore(name) { + t.Errorf("shouldIgnore(%q) = true, want false", name) + } + } +} + +// --- End-to-end classification with enter+exit pairs --- + +func TestClassifySyscallPairAccepted(t *testing.T) { + tests := []struct { + name string + enter string + exit string + enterKind TracepointKind + }{ + {"read", FormatRead, FormatExitRead, KindFd}, + {"openat", FormatOpenat, FormatExitOpenat, KindOpen}, + {"rename", FormatRename, FormatExitRename, KindName}, + {"close", FormatClose, FormatExitClose, KindFd}, + {"dup3", FormatDup3, FormatExitDup3, KindDup3}, + {"fcntl", FormatFcntl, FormatExitFcntl, KindFcntl}, + {"sync", FormatSync, FormatExitSync, KindNull}, + {"syslog", FormatSyslog, FormatExitSyslog, KindNull}, + {"open_by_handle_at", FormatOpenByHandleAt, FormatExitOpenByHandleAt, KindOpenByHandleAt}, + {"io_uring_enter", FormatIoUringEnter, FormatExitIoUringEnter, KindNull}, + {"pread64", FormatPread64, FormatExitPread64, KindFd}, + {"symlink", FormatSymlink, FormatExitSymlink, KindName}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + input := tt.enter + "\n" + tt.exit + output := GenerateTracepointsC(mustParseAll(t, input)) + if strings.Contains(output, "Ignoring") { + t.Errorf("syscall %s was ignored, expected accepted", tt.name) + } + }) + } +} + +func TestClassifySyscallPairIgnored(t *testing.T) { + tests := []struct { + name string + enter string + exit string + }{ + {"mknod", FormatMknod, FormatExitMknod}, + {"execve", FormatExecve, FormatExitExecve}, + {"accept", FormatAccept, FormatExitAccept}, + {"socket", FormatSocket, FormatExitSocket}, + {"kill", FormatKill, FormatExitKill}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + input := tt.enter + "\n" + tt.exit + output := GenerateTracepointsC(mustParseAll(t, input)) + if !strings.Contains(output, "Ignoring") { + t.Errorf("syscall %s was accepted, expected ignored", tt.name) + } + }) + } +} + +func mustParseAll(t *testing.T, data string) []Format { + t.Helper() + formats, err := ParseFormats(strings.NewReader(data)) + if err != nil { + t.Fatalf("ParseFormats failed: %v", err) + } + return formats +} |
