feat: machine mode, PEM-only certs, ECH support, multi-instance config, batch ops, xbctl
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestValidateCustomRouteRules(t *testing.T) {
|
||||
available := map[string]struct{}{"direct": {}, "block": {}, "warp": {}, "proxy": {}}
|
||||
tests := []struct {
|
||||
name string
|
||||
rules []CustomRouteRule
|
||||
kernel string
|
||||
wantErr string
|
||||
}{
|
||||
{
|
||||
name: "valid route target",
|
||||
rules: []CustomRouteRule{{
|
||||
Match: RouteMatch{DomainSuffixes: []string{"example.com"}, Ports: []string{"443"}, Networks: []string{"tcp"}},
|
||||
Action: RouteAction{Type: "route", Target: "warp"},
|
||||
}},
|
||||
kernel: "singbox",
|
||||
},
|
||||
{
|
||||
name: "missing match",
|
||||
rules: []CustomRouteRule{{Action: RouteAction{Type: "direct"}}},
|
||||
kernel: "singbox",
|
||||
wantErr: "custom_route_rules[0].match is required",
|
||||
},
|
||||
{
|
||||
name: "unknown target",
|
||||
rules: []CustomRouteRule{{Match: RouteMatch{DomainSuffixes: []string{"example.com"}}, Action: RouteAction{Type: "route", Target: "missing"}}},
|
||||
kernel: "singbox",
|
||||
wantErr: `custom_route_rules[0].action.target references unknown outbound "missing"`,
|
||||
},
|
||||
{
|
||||
name: "route target required",
|
||||
rules: []CustomRouteRule{{Match: RouteMatch{DomainSuffixes: []string{"example.com"}}, Action: RouteAction{Type: "route"}}},
|
||||
kernel: "singbox",
|
||||
wantErr: "custom_route_rules[0].action.target is required when action.type is route",
|
||||
},
|
||||
{
|
||||
name: "direct target forbidden",
|
||||
rules: []CustomRouteRule{{Match: RouteMatch{DomainSuffixes: []string{"example.com"}}, Action: RouteAction{Type: "direct", Target: "warp"}}},
|
||||
kernel: "singbox",
|
||||
wantErr: "custom_route_rules[0].action.target is only allowed when action.type is route",
|
||||
},
|
||||
{
|
||||
name: "unsupported action",
|
||||
rules: []CustomRouteRule{{Match: RouteMatch{DomainSuffixes: []string{"example.com"}}, Action: RouteAction{Type: "dns"}}},
|
||||
kernel: "singbox",
|
||||
wantErr: `custom_route_rules[0].action.type "dns" is not supported by kernel "singbox"`,
|
||||
},
|
||||
{
|
||||
name: "invalid port range",
|
||||
rules: []CustomRouteRule{{Match: RouteMatch{Ports: []string{"2000-1000"}}, Action: RouteAction{Type: "direct"}}},
|
||||
kernel: "singbox",
|
||||
wantErr: `custom_route_rules[0].match.ports contains invalid port range "2000-1000"`,
|
||||
},
|
||||
{
|
||||
name: "invalid network",
|
||||
rules: []CustomRouteRule{{Match: RouteMatch{Networks: []string{"icmp"}}, Action: RouteAction{Type: "direct"}}},
|
||||
kernel: "singbox",
|
||||
wantErr: `custom_route_rules[0].match.networks contains unsupported network "icmp"`,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
err := ValidateCustomRouteRules(tc.rules, tc.kernel, available)
|
||||
if tc.wantErr == "" && err != nil {
|
||||
t.Fatalf("expected no error, got %v", err)
|
||||
}
|
||||
if tc.wantErr != "" {
|
||||
if err == nil {
|
||||
t.Fatal("expected error, got nil")
|
||||
}
|
||||
if !strings.Contains(err.Error(), tc.wantErr) {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user