From 1eb1dd41048e2c3441c6e9564e7e8dba864c2ee4 Mon Sep 17 00:00:00 2001 From: Markus Graf Date: Wed, 25 Mar 2026 12:16:20 +0100 Subject: [PATCH] test(01-02): add failing tests for capture package - TestListInterfaces: verifies net.Interfaces() returns at least 1 interface - TestListInterfacesFormat: verifies interface Name is non-empty - TestIsPermissionError: table-driven positive cases for perm error detection - TestIsPermissionErrorNegative: non-perm errors not flagged - TestPermissionErrorMsg: verifies sudo + interface name + Linux setcap hint --- capture/capture_test.go | 94 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 capture/capture_test.go diff --git a/capture/capture_test.go b/capture/capture_test.go new file mode 100644 index 0000000..459d881 --- /dev/null +++ b/capture/capture_test.go @@ -0,0 +1,94 @@ +package capture + +import ( + "errors" + "runtime" + "strings" + "testing" +) + +// TestListInterfaces verifies that net.Interfaces() returns at least one interface. +// The loopback interface (lo on Linux, lo0 on macOS) always exists. +func TestListInterfaces(t *testing.T) { + ifaces, err := ListInterfaces() + if err != nil { + t.Fatalf("ListInterfaces() error: %v", err) + } + if len(ifaces) == 0 { + t.Fatal("ListInterfaces() returned 0 interfaces; expected at least 1 (loopback)") + } + t.Logf("Found %d interfaces", len(ifaces)) +} + +// TestListInterfacesFormat verifies that each returned interface has a non-empty Name. +func TestListInterfacesFormat(t *testing.T) { + ifaces, err := ListInterfaces() + if err != nil { + t.Fatalf("ListInterfaces() error: %v", err) + } + for i, iface := range ifaces { + if iface.Name == "" { + t.Errorf("Interface[%d] has empty Name", i) + } + } +} + +// TestIsPermissionError checks positive cases for isPermissionError. +func TestIsPermissionError(t *testing.T) { + positives := []string{ + "permission denied", + "Permission Denied", + "PERMISSION DENIED", + "operation not permitted", + "Operation Not Permitted", + "pcap_create: foo", + "pcap_create: operation not permitted", + } + for _, msg := range positives { + err := errors.New(msg) + if !isPermissionError(err) { + t.Errorf("isPermissionError(%q) = false; want true", msg) + } + } +} + +// TestIsPermissionErrorNegative checks that non-permission errors are not flagged. +func TestIsPermissionErrorNegative(t *testing.T) { + negatives := []string{ + "interface not found", + "no such device", + "network is unreachable", + "device busy", + } + for _, msg := range negatives { + err := errors.New(msg) + if isPermissionError(err) { + t.Errorf("isPermissionError(%q) = true; want false", msg) + } + } +} + +// TestPermissionErrorMsg verifies the platform-specific error message. +func TestPermissionErrorMsg(t *testing.T) { + iface := "eth0" + err := permissionErrorMsg(iface) + if err == nil { + t.Fatal("permissionErrorMsg() returned nil; want an error") + } + msg := err.Error() + + // All platforms should mention sudo and the interface name. + if !strings.Contains(msg, "sudo") { + t.Errorf("permissionErrorMsg(%q) message missing 'sudo': %s", iface, msg) + } + if !strings.Contains(msg, iface) { + t.Errorf("permissionErrorMsg(%q) message missing interface name: %s", iface, msg) + } + + // Linux-specific: must mention setcap. + if runtime.GOOS == "linux" { + if !strings.Contains(msg, "setcap cap_net_raw+ep") { + t.Errorf("permissionErrorMsg on linux missing 'setcap cap_net_raw+ep': %s", msg) + } + } +}