summaryrefslogtreecommitdiff
path: root/internal/flamegraph
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-02-21 21:56:36 +0200
committerPaul Buetow <paul@buetow.org>2026-02-21 21:56:36 +0200
commit311b827599251d8d68526293815e8d4dcba632c8 (patch)
tree589d01f5653f966c3b2cc786911b8cc02a3237c9 /internal/flamegraph
parent36f216c757eea7db82cf04aeae592956199b9f76 (diff)
Add negative tests for all internal unit tests (task 348)
- internal/types: Fix StringValue panic with no null terminator, add negative tests for serialization, Equals, and StringValue edge cases - internal/file: Add negative tests for empty name, unknown flags, SetFlags/AddFlags, Dup, empty OldnameNewname and Pathname - internal/flamegraph: Add negative tests for StringByName unknown field, Counter.ValueByName panic, merge empty, deserialize invalid data, serialize/deserialize round-trip - internal/generate/format: Add negative tests for empty input, ID errors, malformed fields, empty declarations - internal/generate/typesgo: Add negative tests for snakeToCamel edge cases, unknown types, invalid member/define parsing, no-import case - internal/generate/tracepointsgo: Add negative tests for malformed SEC, no SEC lines - internal/generate/codegen: Add negative tests for unknown event kind, invalid syscall grouping, missing exit tracepoint - internal/generate/classify: Add negative tests for empty external fields, non-fd types Amp-Thread-ID: https://ampcode.com/threads/T-019c81bf-3d5c-7216-b1b6-890db1374414 Co-authored-by: Amp <amp@ampcode.com>
Diffstat (limited to 'internal/flamegraph')
-rw-r--r--internal/flamegraph/iordata_test.go156
1 files changed, 156 insertions, 0 deletions
diff --git a/internal/flamegraph/iordata_test.go b/internal/flamegraph/iordata_test.go
index 9957f9e..f499e5f 100644
--- a/internal/flamegraph/iordata_test.go
+++ b/internal/flamegraph/iordata_test.go
@@ -1,6 +1,7 @@
package flamegraph
import (
+ "bytes"
"ior/internal/types"
"syscall"
"testing"
@@ -109,6 +110,161 @@ func TestMerge(t *testing.T) {
// })
}
+func TestStringByNameUnknownField(t *testing.T) {
+ ir := IterRecord{
+ Path: "/tmp/test",
+ TraceID: types.SYS_ENTER_OPENAT,
+ Comm: "testComm",
+ Pid: 1234,
+ Tid: 5678,
+ Flags: flagsType(syscall.O_RDONLY),
+ Cnt: Counter{Count: 1},
+ }
+
+ _, err := ir.StringByName("nonexistent")
+ if err == nil {
+ t.Error("Expected error for unknown field name, got nil")
+ }
+}
+
+func TestStringByNameValidFields(t *testing.T) {
+ ir := IterRecord{
+ Path: "/tmp/test",
+ TraceID: types.SYS_ENTER_OPENAT,
+ Comm: "testComm",
+ Pid: 1234,
+ Tid: 5678,
+ Flags: flagsType(syscall.O_RDONLY),
+ Cnt: Counter{Count: 1},
+ }
+
+ validFields := []string{"path", "comm", "tracepoint", "pid", "tid", "flags"}
+ for _, name := range validFields {
+ t.Run(name, func(t *testing.T) {
+ val, err := ir.StringByName(name)
+ if err != nil {
+ t.Errorf("Expected no error for field %q, got %v", name, err)
+ }
+ if val == "" {
+ t.Errorf("Expected non-empty string for field %q", name)
+ }
+ })
+ }
+}
+
+func TestCounterValueByNamePanic(t *testing.T) {
+ c := Counter{Count: 1, Duration: 100, DurationToPrev: 10, Bytes: 64}
+
+ defer func() {
+ if r := recover(); r == nil {
+ t.Error("Expected panic for unknown counter name, got none")
+ }
+ }()
+
+ c.ValueByName("nonexistent")
+}
+
+func TestMergeEmpty(t *testing.T) {
+ traceId := types.SYS_ENTER_OPENAT
+ roFlag := flagsType(syscall.O_RDONLY)
+
+ iod := iorData{paths: pathMap{
+ "path1": {traceId: {"comm1": {100: {1000: {roFlag: Counter{
+ Count: 10,
+ Duration: 1000,
+ DurationToPrev: 100,
+ Bytes: 64,
+ }}}}}},
+ }}
+
+ empty := newIorData()
+ merged := iod.merge(empty)
+
+ if len(merged.paths) != 1 {
+ t.Errorf("Expected 1 path, got %d", len(merged.paths))
+ }
+ cnt := merged.paths["path1"][traceId]["comm1"][100][1000][roFlag]
+ if cnt.Count != 10 || cnt.Duration != 1000 || cnt.DurationToPrev != 100 || cnt.Bytes != 64 {
+ t.Errorf("Expected original counter preserved, got %v", cnt)
+ }
+}
+
+func TestAddZeroCounter(t *testing.T) {
+ iod := newIorData()
+ path := pathType("testPath")
+ traceId := types.SYS_ENTER_OPENAT
+ comm := commType("testComm")
+ pid := pidType(1234)
+ tid := tidType(5678)
+ flags := flagsType(syscall.O_RDONLY)
+ zero := Counter{}
+
+ iod.add(path, traceId, comm, pid, tid, flags, zero)
+
+ cnt, ok := iod.paths[path][traceId][comm][pid][tid][flags]
+ if !ok {
+ t.Fatal("Expected entry to exist for zero counter")
+ }
+ if cnt != zero {
+ t.Errorf("Expected zero counter %v, got %v", zero, cnt)
+ }
+}
+
+func TestSerializeDeserializeRoundTrip(t *testing.T) {
+ traceId := types.SYS_ENTER_OPENAT
+ rdwrFlag := flagsType(syscall.O_RDWR)
+ roFlag := flagsType(syscall.O_RDONLY)
+
+ original := iorData{paths: pathMap{
+ "path1": {traceId: {"comm1": {100: {1000: {rdwrFlag: Counter{
+ Count: 10,
+ Duration: 1000,
+ DurationToPrev: 100,
+ Bytes: 64,
+ }}}}}},
+ "path2": {traceId: {"comm2": {200: {2000: {roFlag: Counter{
+ Count: 20,
+ Duration: 2000,
+ DurationToPrev: 200,
+ Bytes: 128,
+ }}}}}},
+ }}
+
+ data, err := original.serialize()
+ if err != nil {
+ t.Fatalf("serialize failed: %v", err)
+ }
+
+ restored := newIorData()
+ if err := restored.deserialize(bytes.NewBuffer(data)); err != nil {
+ t.Fatalf("deserialize failed: %v", err)
+ }
+
+ if len(restored.paths) != len(original.paths) {
+ t.Fatalf("Expected %d paths, got %d", len(original.paths), len(restored.paths))
+ }
+
+ cnt1 := restored.paths["path1"][traceId]["comm1"][100][1000][rdwrFlag]
+ if cnt1.Count != 10 || cnt1.Duration != 1000 || cnt1.DurationToPrev != 100 || cnt1.Bytes != 64 {
+ t.Errorf("path1 counter mismatch: %v", cnt1)
+ }
+
+ cnt2 := restored.paths["path2"][traceId]["comm2"][200][2000][roFlag]
+ if cnt2.Count != 20 || cnt2.Duration != 2000 || cnt2.DurationToPrev != 200 || cnt2.Bytes != 128 {
+ t.Errorf("path2 counter mismatch: %v", cnt2)
+ }
+}
+
+func TestDeserializeInvalidData(t *testing.T) {
+ iod := newIorData()
+ var buf bytes.Buffer
+ buf.WriteString("this is not valid gob data")
+ err := iod.deserialize(&buf)
+ if err == nil {
+ t.Error("Expected error when deserializing invalid data, got nil")
+ }
+}
+
func bothArraysHaveSameElements(a, b []string) bool {
if len(a) != len(b) {
return false