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/format_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/format_test.go')
| -rw-r--r-- | internal/generate/format_test.go | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/internal/generate/format_test.go b/internal/generate/format_test.go new file mode 100644 index 0000000..f8f078b --- /dev/null +++ b/internal/generate/format_test.go @@ -0,0 +1,174 @@ +package generate + +import ( + "strings" + "testing" +) + +func mustParseOne(t *testing.T, data string) Format { + t.Helper() + formats, err := ParseFormats(strings.NewReader(data)) + if err != nil { + t.Fatalf("ParseFormats failed: %v", err) + } + if len(formats) != 1 { + t.Fatalf("expected 1 format, got %d", len(formats)) + } + return formats[0] +} + +func TestParseFormatOpenat(t *testing.T) { + f := mustParseOne(t, FormatOpenat) + + if f.Name != "sys_enter_openat" { + t.Errorf("name = %q, want sys_enter_openat", f.Name) + } + if f.ID != 784 { + t.Errorf("ID = %d, want 784", f.ID) + } + if len(f.InternalFields) != 4 { + t.Errorf("internal fields = %d, want 4", len(f.InternalFields)) + } + if len(f.ExternalFields) != 5 { + t.Errorf("external fields = %d, want 5", len(f.ExternalFields)) + } + if f.ExternalFields[0].Name != "__syscall_nr" { + t.Errorf("first external field = %q, want __syscall_nr", f.ExternalFields[0].Name) + } + if f.ExternalFields[2].Type != "const char *" { + t.Errorf("filename type = %q, want 'const char *'", f.ExternalFields[2].Type) + } + if f.ExternalFields[2].Name != "filename" { + t.Errorf("field 2 name = %q, want filename", f.ExternalFields[2].Name) + } +} + +func TestParseFormatExitRead(t *testing.T) { + f := mustParseOne(t, FormatExitRead) + + if f.Name != "sys_exit_read" { + t.Errorf("name = %q, want sys_exit_read", f.Name) + } + if f.ID != 843 { + t.Errorf("ID = %d, want 843", f.ID) + } + if len(f.ExternalFields) != 2 { + t.Errorf("external fields = %d, want 2", len(f.ExternalFields)) + } + if f.ExternalFields[1].Type != "long" { + t.Errorf("ret type = %q, want long", f.ExternalFields[1].Type) + } + if f.ExternalFields[1].Name != "ret" { + t.Errorf("ret name = %q, want ret", f.ExternalFields[1].Name) + } + if !f.ExternalFields[1].Signed { + t.Error("ret should be signed") + } +} + +func TestParseFormatSync(t *testing.T) { + f := mustParseOne(t, FormatSync) + + if f.Name != "sys_enter_sync" { + t.Errorf("name = %q, want sys_enter_sync", f.Name) + } + if f.ID != 1027 { + t.Errorf("ID = %d, want 1027", f.ID) + } + if len(f.ExternalFields) != 1 { + t.Errorf("external fields = %d, want 1 (__syscall_nr only)", len(f.ExternalFields)) + } +} + +func TestParseMultiSection(t *testing.T) { + input := FormatRead + "\n" + FormatExitRead + formats, err := ParseFormats(strings.NewReader(input)) + if err != nil { + t.Fatalf("ParseFormats failed: %v", err) + } + if len(formats) != 2 { + t.Fatalf("expected 2 formats, got %d", len(formats)) + } + if formats[0].Name != "sys_enter_read" { + t.Errorf("first = %q", formats[0].Name) + } + if formats[1].Name != "sys_exit_read" { + t.Errorf("second = %q", formats[1].Name) + } +} + +func TestParseFieldDetails(t *testing.T) { + f := mustParseOne(t, FormatOpenat) + + // common_type: internal field + ct := f.InternalFields[0] + if ct.Name != "common_type" || ct.Type != "unsigned short" || ct.Offset != 0 || ct.Size != 2 || ct.Signed { + t.Errorf("common_type = %+v", ct) + } + + // dfd: first non-syscall_nr external field + dfd := f.ExternalFields[1] + if dfd.Name != "dfd" || dfd.Type != "int" || dfd.Offset != 16 || dfd.Size != 8 { + t.Errorf("dfd = %+v", dfd) + } +} + +func TestFieldNumber(t *testing.T) { + f := mustParseOne(t, FormatOpenat) + + if n := f.FieldNumber("filename"); n != 1 { + t.Errorf("FieldNumber(filename) = %d, want 1", n) + } + if n := f.FieldNumber("flags"); n != 2 { + t.Errorf("FieldNumber(flags) = %d, want 2", n) + } + if n := f.FieldNumber("dfd"); n != 0 { + t.Errorf("FieldNumber(dfd) = %d, want 0", n) + } + if n := f.FieldNumber("nonexistent"); n != -1 { + t.Errorf("FieldNumber(nonexistent) = %d, want -1", n) + } +} + +func TestFieldNumberFcntl(t *testing.T) { + f := mustParseOne(t, FormatFcntl) + + if n := f.FieldNumber("fd"); n != 0 { + t.Errorf("FieldNumber(fd) = %d, want 0", n) + } + if n := f.FieldNumber("cmd"); n != 1 { + t.Errorf("FieldNumber(cmd) = %d, want 1", n) + } + if n := f.FieldNumber("arg"); n != 2 { + t.Errorf("FieldNumber(arg) = %d, want 2", n) + } +} + +func TestFieldNumberRename(t *testing.T) { + f := mustParseOne(t, FormatRename) + + if n := f.FieldNumber("oldname"); n != 0 { + t.Errorf("FieldNumber(oldname) = %d, want 0", n) + } + if n := f.FieldNumber("newname"); n != 1 { + t.Errorf("FieldNumber(newname) = %d, want 1", n) + } +} + +func TestFieldNumberLinkat(t *testing.T) { + f := mustParseOne(t, FormatLinkat) + + if n := f.FieldNumber("oldname"); n != 1 { + t.Errorf("FieldNumber(oldname) = %d, want 1", n) + } + if n := f.FieldNumber("newname"); n != 3 { + t.Errorf("FieldNumber(newname) = %d, want 3", n) + } +} + +func TestParseFormatError(t *testing.T) { + _, err := ParseFormats(strings.NewReader("field:broken")) + if err == nil { + t.Error("expected error for field without name") + } +} |
