Some checks failed
Build RPM Package / Build RPM Packages (CentOS 7, Rocky 8/9/10) (push) Has been cancelled
- Correction race condition dans tlsparse avec mutex par ConnectionFlow - Fix fuite mémoire buffer HelloBuffer - Ajout rotation de fichiers logs (100MB, 3 backups) - Implémentation queue asynchrone avec reconnexion exponentielle (socket UNIX) - Validation BPF (caractères, longueur, parenthèses) - Augmentation snapLen pcap de 1600 à 65535 bytes - Permissions fichiers sécurisées (0600) - Ajout 46 tests unitaires (capture, output, logging) - Passage go test -race sans erreur Tests: go test -race ./... ✓ Build: go build ./... ✓ Lint: go vet ./... ✓ Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
234 lines
4.7 KiB
Go
234 lines
4.7 KiB
Go
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)
|
|
}
|
|
})
|
|
}
|
|
}
|