package capture import ( "testing" ) func TestValidateBPFFilter(t *testing.T) { tests := []struct { name string filter string wantErr bool }{ { name: "empty filter", filter: "", wantErr: false, }, { name: "valid simple filter", filter: "tcp port 443", wantErr: false, }, { name: "valid complex filter", filter: "(tcp port 443) or (tcp port 8443)", wantErr: false, }, { name: "filter with special chars", filter: "tcp port 443 and host 192.168.1.1", wantErr: false, }, { name: "too long filter", filter: string(make([]byte, MaxBPFFilterLength+1)), wantErr: true, }, { name: "unbalanced parentheses - extra open", filter: "(tcp port 443", wantErr: true, }, { name: "unbalanced parentheses - extra close", filter: "tcp port 443)", wantErr: true, }, { name: "invalid characters - semicolon", filter: "tcp port 443; rm -rf /", wantErr: true, }, { name: "invalid characters - backtick", filter: "tcp port `whoami`", wantErr: true, }, { name: "invalid characters - dollar", filter: "tcp port $HOME", wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { err := validateBPFFilter(tt.filter) if (err != nil) != tt.wantErr { t.Errorf("validateBPFFilter() error = %v, wantErr %v", err, tt.wantErr) } }) } } func TestBuildBPFForPorts(t *testing.T) { tests := []struct { name string ports []uint16 want string }{ { name: "no ports", ports: []uint16{}, want: "tcp", }, { name: "single port", ports: []uint16{443}, want: "(tcp port 443)", }, { name: "multiple ports", ports: []uint16{443, 8443, 9443}, want: "(tcp port 443) or (tcp port 8443) or (tcp port 9443)", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := buildBPFForPorts(tt.ports) if got != tt.want { t.Errorf("buildBPFForPorts() = %v, want %v", got, tt.want) } }) } } func TestJoinString(t *testing.T) { tests := []struct { name string parts []string sep string want string }{ { name: "empty slice", parts: []string{}, sep: ") or (", want: "", }, { name: "single element", parts: []string{"tcp port 443"}, sep: ") or (", want: "tcp port 443", }, { name: "multiple elements", parts: []string{"tcp port 443", "tcp port 8443"}, sep: ") or (", want: "tcp port 443) or (tcp port 8443", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := joinString(tt.parts, tt.sep) if got != tt.want { t.Errorf("joinString() = %v, want %v", got, tt.want) } }) } } func TestNewCapture(t *testing.T) { c := New() if c == nil { t.Fatal("New() returned nil") } if c.snapLen != DefaultSnapLen { t.Errorf("snapLen = %d, want %d", c.snapLen, DefaultSnapLen) } if c.promisc != DefaultPromiscuous { t.Errorf("promisc = %v, want %v", c.promisc, DefaultPromiscuous) } } func TestNewWithSnapLen(t *testing.T) { tests := []struct { name string snapLen int wantSnapLen int }{ { name: "valid snapLen", snapLen: 2048, wantSnapLen: 2048, }, { name: "zero snapLen uses default", snapLen: 0, wantSnapLen: DefaultSnapLen, }, { name: "negative snapLen uses default", snapLen: -100, wantSnapLen: DefaultSnapLen, }, { name: "too large snapLen uses default", snapLen: 100000, wantSnapLen: DefaultSnapLen, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { c := NewWithSnapLen(tt.snapLen) if c == nil { t.Fatal("NewWithSnapLen() returned nil") } if c.snapLen != tt.wantSnapLen { t.Errorf("snapLen = %d, want %d", c.snapLen, tt.wantSnapLen) } }) } } func TestCaptureImpl_Close(t *testing.T) { c := New() if c == nil { t.Fatal("New() returned nil") } // Close should not panic on fresh instance if err := c.Close(); err != nil { t.Errorf("Close() error = %v", err) } // Multiple closes should be safe if err := c.Close(); err != nil { t.Errorf("Close() second call error = %v", err) } } func TestValidateBPFFilter_BalancedParentheses(t *testing.T) { // Test various balanced parentheses scenarios validFilters := []string{ "(tcp port 443)", "((tcp port 443))", "(tcp port 443) or (tcp port 8443)", "((tcp port 443) or (tcp port 8443))", "(tcp port 443 and host 1.2.3.4) or (tcp port 8443)", } for _, filter := range validFilters { t.Run(filter, func(t *testing.T) { if err := validateBPFFilter(filter); err != nil { t.Errorf("validateBPFFilter(%q) unexpected error = %v", filter, err) } }) } }