Add is_tor plumbing from collector->aggregator->frontend/cli
This commit is contained in:
@@ -83,10 +83,10 @@ func compiledEQ(status int32) *CompiledFilter {
|
||||
}
|
||||
|
||||
func TestMatchesFilterNil(t *testing.T) {
|
||||
if !MatchesFilter(Tuple4{Website: "x"}, nil) {
|
||||
if !MatchesFilter(Tuple5{Website: "x"}, nil) {
|
||||
t.Fatal("nil filter should match everything")
|
||||
}
|
||||
if !MatchesFilter(Tuple4{Website: "x"}, &CompiledFilter{}) {
|
||||
if !MatchesFilter(Tuple5{Website: "x"}, &CompiledFilter{}) {
|
||||
t.Fatal("empty compiled filter should match everything")
|
||||
}
|
||||
}
|
||||
@@ -94,10 +94,10 @@ func TestMatchesFilterNil(t *testing.T) {
|
||||
func TestMatchesFilterExactWebsite(t *testing.T) {
|
||||
w := "example.com"
|
||||
cf := CompileFilter(&pb.Filter{Website: &w})
|
||||
if !MatchesFilter(Tuple4{Website: "example.com"}, cf) {
|
||||
if !MatchesFilter(Tuple5{Website: "example.com"}, cf) {
|
||||
t.Fatal("expected match")
|
||||
}
|
||||
if MatchesFilter(Tuple4{Website: "other.com"}, cf) {
|
||||
if MatchesFilter(Tuple5{Website: "other.com"}, cf) {
|
||||
t.Fatal("expected no match")
|
||||
}
|
||||
}
|
||||
@@ -105,10 +105,10 @@ func TestMatchesFilterExactWebsite(t *testing.T) {
|
||||
func TestMatchesFilterWebsiteRegex(t *testing.T) {
|
||||
re := "gouda.*"
|
||||
cf := CompileFilter(&pb.Filter{WebsiteRegex: &re})
|
||||
if !MatchesFilter(Tuple4{Website: "gouda.example.com"}, cf) {
|
||||
if !MatchesFilter(Tuple5{Website: "gouda.example.com"}, cf) {
|
||||
t.Fatal("expected match")
|
||||
}
|
||||
if MatchesFilter(Tuple4{Website: "edam.example.com"}, cf) {
|
||||
if MatchesFilter(Tuple5{Website: "edam.example.com"}, cf) {
|
||||
t.Fatal("expected no match")
|
||||
}
|
||||
}
|
||||
@@ -116,10 +116,10 @@ func TestMatchesFilterWebsiteRegex(t *testing.T) {
|
||||
func TestMatchesFilterURIRegex(t *testing.T) {
|
||||
re := "^/api/.*"
|
||||
cf := CompileFilter(&pb.Filter{UriRegex: &re})
|
||||
if !MatchesFilter(Tuple4{URI: "/api/users"}, cf) {
|
||||
if !MatchesFilter(Tuple5{URI: "/api/users"}, cf) {
|
||||
t.Fatal("expected match")
|
||||
}
|
||||
if MatchesFilter(Tuple4{URI: "/health"}, cf) {
|
||||
if MatchesFilter(Tuple5{URI: "/health"}, cf) {
|
||||
t.Fatal("expected no match")
|
||||
}
|
||||
}
|
||||
@@ -127,17 +127,17 @@ func TestMatchesFilterURIRegex(t *testing.T) {
|
||||
func TestMatchesFilterInvalidRegexMatchesNothing(t *testing.T) {
|
||||
re := "[invalid"
|
||||
cf := CompileFilter(&pb.Filter{WebsiteRegex: &re})
|
||||
if MatchesFilter(Tuple4{Website: "anything"}, cf) {
|
||||
if MatchesFilter(Tuple5{Website: "anything"}, cf) {
|
||||
t.Fatal("invalid regex should match nothing")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMatchesFilterStatusEQ(t *testing.T) {
|
||||
cf := compiledEQ(200)
|
||||
if !MatchesFilter(Tuple4{Status: "200"}, cf) {
|
||||
if !MatchesFilter(Tuple5{Status: "200"}, cf) {
|
||||
t.Fatal("expected match")
|
||||
}
|
||||
if MatchesFilter(Tuple4{Status: "404"}, cf) {
|
||||
if MatchesFilter(Tuple5{Status: "404"}, cf) {
|
||||
t.Fatal("expected no match")
|
||||
}
|
||||
}
|
||||
@@ -145,10 +145,10 @@ func TestMatchesFilterStatusEQ(t *testing.T) {
|
||||
func TestMatchesFilterStatusNE(t *testing.T) {
|
||||
v := int32(200)
|
||||
cf := CompileFilter(&pb.Filter{HttpResponse: &v, StatusOp: pb.StatusOp_NE})
|
||||
if MatchesFilter(Tuple4{Status: "200"}, cf) {
|
||||
if MatchesFilter(Tuple5{Status: "200"}, cf) {
|
||||
t.Fatal("expected no match for 200 != 200")
|
||||
}
|
||||
if !MatchesFilter(Tuple4{Status: "404"}, cf) {
|
||||
if !MatchesFilter(Tuple5{Status: "404"}, cf) {
|
||||
t.Fatal("expected match for 404 != 200")
|
||||
}
|
||||
}
|
||||
@@ -156,13 +156,13 @@ func TestMatchesFilterStatusNE(t *testing.T) {
|
||||
func TestMatchesFilterStatusGE(t *testing.T) {
|
||||
v := int32(400)
|
||||
cf := CompileFilter(&pb.Filter{HttpResponse: &v, StatusOp: pb.StatusOp_GE})
|
||||
if !MatchesFilter(Tuple4{Status: "400"}, cf) {
|
||||
if !MatchesFilter(Tuple5{Status: "400"}, cf) {
|
||||
t.Fatal("expected match: 400 >= 400")
|
||||
}
|
||||
if !MatchesFilter(Tuple4{Status: "500"}, cf) {
|
||||
if !MatchesFilter(Tuple5{Status: "500"}, cf) {
|
||||
t.Fatal("expected match: 500 >= 400")
|
||||
}
|
||||
if MatchesFilter(Tuple4{Status: "200"}, cf) {
|
||||
if MatchesFilter(Tuple5{Status: "200"}, cf) {
|
||||
t.Fatal("expected no match: 200 >= 400")
|
||||
}
|
||||
}
|
||||
@@ -170,17 +170,17 @@ func TestMatchesFilterStatusGE(t *testing.T) {
|
||||
func TestMatchesFilterStatusLT(t *testing.T) {
|
||||
v := int32(400)
|
||||
cf := CompileFilter(&pb.Filter{HttpResponse: &v, StatusOp: pb.StatusOp_LT})
|
||||
if !MatchesFilter(Tuple4{Status: "200"}, cf) {
|
||||
if !MatchesFilter(Tuple5{Status: "200"}, cf) {
|
||||
t.Fatal("expected match: 200 < 400")
|
||||
}
|
||||
if MatchesFilter(Tuple4{Status: "400"}, cf) {
|
||||
if MatchesFilter(Tuple5{Status: "400"}, cf) {
|
||||
t.Fatal("expected no match: 400 < 400")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMatchesFilterStatusNonNumeric(t *testing.T) {
|
||||
cf := compiledEQ(200)
|
||||
if MatchesFilter(Tuple4{Status: "ok"}, cf) {
|
||||
if MatchesFilter(Tuple5{Status: "ok"}, cf) {
|
||||
t.Fatal("non-numeric status should not match")
|
||||
}
|
||||
}
|
||||
@@ -193,13 +193,67 @@ func TestMatchesFilterCombined(t *testing.T) {
|
||||
HttpResponse: &v,
|
||||
StatusOp: pb.StatusOp_EQ,
|
||||
})
|
||||
if !MatchesFilter(Tuple4{Website: "example.com", Status: "200"}, cf) {
|
||||
if !MatchesFilter(Tuple5{Website: "example.com", Status: "200"}, cf) {
|
||||
t.Fatal("expected match")
|
||||
}
|
||||
if MatchesFilter(Tuple4{Website: "other.com", Status: "200"}, cf) {
|
||||
if MatchesFilter(Tuple5{Website: "other.com", Status: "200"}, cf) {
|
||||
t.Fatal("expected no match: wrong website")
|
||||
}
|
||||
if MatchesFilter(Tuple4{Website: "example.com", Status: "404"}, cf) {
|
||||
if MatchesFilter(Tuple5{Website: "example.com", Status: "404"}, cf) {
|
||||
t.Fatal("expected no match: wrong status")
|
||||
}
|
||||
}
|
||||
|
||||
// --- IsTor label encoding and filtering ---
|
||||
|
||||
func TestEncodeLabelTupleRoundtripWithTor(t *testing.T) {
|
||||
for _, isTor := range []bool{false, true} {
|
||||
orig := Tuple5{Website: "a.com", Prefix: "1.2.3.0/24", URI: "/x", Status: "200", IsTor: isTor}
|
||||
got := LabelTuple(EncodeTuple(orig))
|
||||
if got != orig {
|
||||
t.Errorf("roundtrip mismatch: got %+v, want %+v", got, orig)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLabelTupleBackwardCompat(t *testing.T) {
|
||||
// Old 4-field label (no is_tor field) should decode with IsTor=false.
|
||||
label := "a.com\x001.2.3.0/24\x00/x\x00200"
|
||||
got := LabelTuple(label)
|
||||
if got.IsTor {
|
||||
t.Errorf("expected IsTor=false for old label, got true")
|
||||
}
|
||||
if got.Website != "a.com" || got.Status != "200" {
|
||||
t.Errorf("unexpected tuple: %+v", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMatchesFilterTorYes(t *testing.T) {
|
||||
cf := CompileFilter(&pb.Filter{Tor: pb.TorFilter_TOR_YES})
|
||||
if !MatchesFilter(Tuple5{IsTor: true}, cf) {
|
||||
t.Fatal("TOR_YES should match TOR tuple")
|
||||
}
|
||||
if MatchesFilter(Tuple5{IsTor: false}, cf) {
|
||||
t.Fatal("TOR_YES should not match non-TOR tuple")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMatchesFilterTorNo(t *testing.T) {
|
||||
cf := CompileFilter(&pb.Filter{Tor: pb.TorFilter_TOR_NO})
|
||||
if !MatchesFilter(Tuple5{IsTor: false}, cf) {
|
||||
t.Fatal("TOR_NO should match non-TOR tuple")
|
||||
}
|
||||
if MatchesFilter(Tuple5{IsTor: true}, cf) {
|
||||
t.Fatal("TOR_NO should not match TOR tuple")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMatchesFilterTorAny(t *testing.T) {
|
||||
cf := CompileFilter(&pb.Filter{Tor: pb.TorFilter_TOR_ANY})
|
||||
if !MatchesFilter(Tuple5{IsTor: true}, cf) {
|
||||
t.Fatal("TOR_ANY should match TOR tuple")
|
||||
}
|
||||
if !MatchesFilter(Tuple5{IsTor: false}, cf) {
|
||||
t.Fatal("TOR_ANY should match non-TOR tuple")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user