release: version 1.1.2 - Add error callback mechanism and comprehensive test suite
Some checks failed
Build RPM Package / Build RPM Packages (CentOS 7, Rocky 8/9/10) (push) Has been cancelled
Some checks failed
Build RPM Package / Build RPM Packages (CentOS 7, Rocky 8/9/10) (push) Has been cancelled
Features: - Add ErrorCallback type for UNIX socket connection error reporting - Add WithErrorCallback option for UnixSocketWriter configuration - Add BuilderImpl.WithErrorCallback() for propagating callbacks - Add consecutive failure tracking in processQueue Testing (50+ new tests): - Add integration tests for full pipeline (capture → tlsparse → fingerprint → output) - Add tests for FileWriter.rotate() and Reopen() log rotation - Add tests for cleanupExpiredFlows() and cleanupLoop() in TLS parser - Add tests for extractSNIFromPayload() and extractJA4Hash() helpers - Add tests for config load error paths (invalid YAML, permission denied) - Add tests for capture.Run() error conditions - Add tests for signal handling documentation Documentation: - Update architecture.yml with new fields (LogLevel, TLSClientHello extensions) - Update architecture.yml with Close() methods for Capture and Parser interfaces - Update RPM spec changelog Cleanup: - Remove empty internal/api/ directory Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
@ -133,3 +133,122 @@ func buildMinimalClientHelloForTest() []byte {
|
||||
|
||||
return record
|
||||
}
|
||||
|
||||
// TestExtractJA4Hash tests the extractJA4Hash helper function
|
||||
func TestExtractJA4Hash(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
ja4 string
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "standard_ja4_format",
|
||||
ja4: "t13d1516h2_8daaf6152771_02cb136f2775",
|
||||
want: "8daaf6152771_02cb136f2775",
|
||||
},
|
||||
{
|
||||
name: "ja4_with_single_underscore",
|
||||
ja4: "t12d1234h1_abcdef123456",
|
||||
want: "abcdef123456",
|
||||
},
|
||||
{
|
||||
name: "ja4_no_underscore_returns_empty",
|
||||
ja4: "t13d1516h2",
|
||||
want: "",
|
||||
},
|
||||
{
|
||||
name: "empty_ja4_returns_empty",
|
||||
ja4: "",
|
||||
want: "",
|
||||
},
|
||||
{
|
||||
name: "underscore_at_start",
|
||||
ja4: "_hash1_hash2",
|
||||
want: "hash1_hash2",
|
||||
},
|
||||
{
|
||||
name: "multiple_underscores_returns_after_first",
|
||||
ja4: "base_part1_part2_part3",
|
||||
want: "part1_part2_part3",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := extractJA4Hash(tt.ja4)
|
||||
if got != tt.want {
|
||||
t.Errorf("extractJA4Hash(%q) = %q, want %q", tt.ja4, got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestFromClientHello_NilPayload tests error handling for nil payload
|
||||
func TestFromClientHello_NilPayload(t *testing.T) {
|
||||
engine := NewEngine()
|
||||
ch := api.TLSClientHello{
|
||||
Payload: nil,
|
||||
}
|
||||
|
||||
_, err := engine.FromClientHello(ch)
|
||||
|
||||
if err == nil {
|
||||
t.Error("FromClientHello() with nil payload should return error")
|
||||
}
|
||||
if err.Error() != "empty ClientHello payload" {
|
||||
t.Errorf("FromClientHello() error = %v, want 'empty ClientHello payload'", err)
|
||||
}
|
||||
}
|
||||
|
||||
// TestFromClientHello_JA3Hash tests that JA3Hash is correctly populated
|
||||
func TestFromClientHello_JA3Hash(t *testing.T) {
|
||||
clientHello := buildMinimalClientHelloForTest()
|
||||
|
||||
ch := api.TLSClientHello{
|
||||
Payload: clientHello,
|
||||
}
|
||||
|
||||
engine := NewEngine()
|
||||
fp, err := engine.FromClientHello(ch)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("FromClientHello() error = %v", err)
|
||||
}
|
||||
|
||||
// JA3Hash should be populated (MD5 hash of JA3 string)
|
||||
if fp.JA3Hash == "" {
|
||||
t.Error("JA3Hash should be populated")
|
||||
}
|
||||
|
||||
// JA3 should also be populated
|
||||
if fp.JA3 == "" {
|
||||
t.Error("JA3 should be populated")
|
||||
}
|
||||
}
|
||||
|
||||
// TestFromClientHello_EmptyJA4Hash tests behavior when JA4 has no underscore
|
||||
func TestFromClientHello_EmptyJA4Hash(t *testing.T) {
|
||||
// This test verifies that even if JA4 format changes, the code handles it gracefully
|
||||
engine := NewEngine()
|
||||
|
||||
// Use a valid ClientHello - the library should produce a proper JA4
|
||||
clientHello := buildMinimalClientHelloForTest()
|
||||
|
||||
ch := api.TLSClientHello{
|
||||
Payload: clientHello,
|
||||
}
|
||||
|
||||
fp, err := engine.FromClientHello(ch)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("FromClientHello() error = %v", err)
|
||||
}
|
||||
|
||||
// JA4 should always be populated
|
||||
if fp.JA4 == "" {
|
||||
t.Error("JA4 should be populated")
|
||||
}
|
||||
|
||||
// JA4Hash may be empty if the JA4 format doesn't include underscores
|
||||
// This is acceptable behavior
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user