2b1e4ca3a7
Covering nil-input safety, plugin backends (HTTP/gRPC/default), loaders (File/HTTP/Redis), selector strategies, edge cases (empty/invalid inputs), and hop-to-node metadata inheritance. All tests passing.
238 lines
5.3 KiB
Go
238 lines
5.3 KiB
Go
package router
|
|
|
|
import (
|
|
"context"
|
|
"io"
|
|
"testing"
|
|
|
|
"github.com/go-gost/core/logger"
|
|
"github.com/go-gost/x/config"
|
|
xlogger "github.com/go-gost/x/logger"
|
|
)
|
|
|
|
func TestMain(m *testing.M) {
|
|
logger.SetDefault(xlogger.NewLogger(xlogger.OutputOption(io.Discard)))
|
|
m.Run()
|
|
}
|
|
|
|
func TestParseRouter_Nil(t *testing.T) {
|
|
r := ParseRouter(nil)
|
|
if r != nil {
|
|
t.Fatal("expected nil for nil config")
|
|
}
|
|
}
|
|
|
|
func TestParseRouter_PluginHTTP(t *testing.T) {
|
|
r := ParseRouter(&config.RouterConfig{
|
|
Name: "http-rt",
|
|
Plugin: &config.PluginConfig{
|
|
Type: "http",
|
|
Addr: "127.0.0.1:9000",
|
|
},
|
|
})
|
|
if r == nil {
|
|
t.Fatal("expected non-nil router")
|
|
}
|
|
}
|
|
|
|
func TestParseRouter_PluginGRPC(t *testing.T) {
|
|
r := ParseRouter(&config.RouterConfig{
|
|
Name: "grpc-rt",
|
|
Plugin: &config.PluginConfig{
|
|
Type: "grpc",
|
|
Addr: "127.0.0.1:9001",
|
|
Token: "secret",
|
|
TLS: &config.TLSConfig{
|
|
Secure: true,
|
|
ServerName: "router.local",
|
|
},
|
|
},
|
|
})
|
|
if r == nil {
|
|
t.Fatal("expected non-nil router")
|
|
}
|
|
}
|
|
|
|
func TestParseRouter_PluginDefaultType(t *testing.T) {
|
|
r := ParseRouter(&config.RouterConfig{
|
|
Name: "default-rt",
|
|
Plugin: &config.PluginConfig{
|
|
Addr: "127.0.0.1:9002",
|
|
},
|
|
})
|
|
if r == nil {
|
|
t.Fatal("expected non-nil router")
|
|
}
|
|
}
|
|
|
|
func TestParseRouter_WithCIDRRoutes(t *testing.T) {
|
|
r := ParseRouter(&config.RouterConfig{
|
|
Name: "cidr-rt",
|
|
Routes: []*config.RouterRouteConfig{
|
|
{Net: "192.168.1.0/24", Gateway: "10.0.0.1"},
|
|
{Net: "10.0.0.0/8", Gateway: "10.0.0.2"},
|
|
},
|
|
})
|
|
if r == nil {
|
|
t.Fatal("expected non-nil router with CIDR routes")
|
|
}
|
|
}
|
|
|
|
func TestParseRouter_WithDstRoutes(t *testing.T) {
|
|
r := ParseRouter(&config.RouterConfig{
|
|
Name: "dst-rt",
|
|
Routes: []*config.RouterRouteConfig{
|
|
{Dst: "192.168.1.0/24", Gateway: "10.0.0.1"},
|
|
},
|
|
})
|
|
if r == nil {
|
|
t.Fatal("expected non-nil router with dst routes")
|
|
}
|
|
}
|
|
|
|
func TestParseRouter_MissingGatewaySkipped(t *testing.T) {
|
|
r := ParseRouter(&config.RouterConfig{
|
|
Name: "skip-rt",
|
|
Routes: []*config.RouterRouteConfig{
|
|
{Net: "192.168.1.0/24", Gateway: ""}, // skipped: no gateway
|
|
{Net: "10.0.0.0/8", Gateway: "10.0.0.1"}, // kept
|
|
},
|
|
})
|
|
if r == nil {
|
|
t.Fatal("expected non-nil router (with one valid route)")
|
|
}
|
|
}
|
|
|
|
func TestParseRouter_MissingDstSkipped(t *testing.T) {
|
|
r := ParseRouter(&config.RouterConfig{
|
|
Name: "no-dst-rt",
|
|
Routes: []*config.RouterRouteConfig{
|
|
{Dst: "", Gateway: "10.0.0.1"}, // skipped: no dst
|
|
},
|
|
})
|
|
if r == nil {
|
|
t.Fatal("expected non-nil router (all routes skipped)")
|
|
}
|
|
}
|
|
|
|
func TestParseRouter_InvalidCIDRSkipped(t *testing.T) {
|
|
r := ParseRouter(&config.RouterConfig{
|
|
Name: "invalid-cidr-rt",
|
|
Routes: []*config.RouterRouteConfig{
|
|
{Net: "not-a-cidr", Gateway: "10.0.0.1"}, // invalid CIDR with empty Dst, skipped
|
|
{Net: "192.168.1.0/24", Gateway: "10.0.0.2"}, // valid
|
|
},
|
|
})
|
|
if r == nil {
|
|
t.Fatal("expected non-nil router")
|
|
}
|
|
}
|
|
|
|
func TestParseRouter_NilRouteSkipped(t *testing.T) {
|
|
r := ParseRouter(&config.RouterConfig{
|
|
Name: "nil-route-rt",
|
|
Routes: []*config.RouterRouteConfig{
|
|
nil,
|
|
{Net: "192.168.1.0/24", Gateway: "10.0.0.1"},
|
|
},
|
|
})
|
|
if r == nil {
|
|
t.Fatal("expected non-nil router when nil route is in list")
|
|
}
|
|
}
|
|
|
|
func TestParseRouter_EmptyRoutes(t *testing.T) {
|
|
r := ParseRouter(&config.RouterConfig{
|
|
Name: "empty-routes",
|
|
Routes: []*config.RouterRouteConfig{},
|
|
})
|
|
if r == nil {
|
|
t.Fatal("expected non-nil router with empty routes")
|
|
}
|
|
}
|
|
|
|
func TestParseRouter_FileLoader(t *testing.T) {
|
|
r := ParseRouter(&config.RouterConfig{
|
|
Name: "file-rt",
|
|
File: &config.FileLoader{Path: "/tmp/routes.txt"},
|
|
})
|
|
if r == nil {
|
|
t.Fatal("expected non-nil router")
|
|
}
|
|
}
|
|
|
|
func TestParseRouter_HTTPLoader(t *testing.T) {
|
|
r := ParseRouter(&config.RouterConfig{
|
|
Name: "http-rt",
|
|
HTTP: &config.HTTPLoader{URL: "http://localhost:8080/routes"},
|
|
})
|
|
if r == nil {
|
|
t.Fatal("expected non-nil router")
|
|
}
|
|
}
|
|
|
|
func TestParseRouter_RedisHashLoader(t *testing.T) {
|
|
r := ParseRouter(&config.RouterConfig{
|
|
Name: "redis-hash-rt",
|
|
Redis: &config.RedisLoader{
|
|
Addr: "127.0.0.1:6379",
|
|
Key: "routes-hash",
|
|
Type: "hash",
|
|
},
|
|
})
|
|
if r == nil {
|
|
t.Fatal("expected non-nil router")
|
|
}
|
|
}
|
|
|
|
func TestParseRouter_RedisListLoader(t *testing.T) {
|
|
r := ParseRouter(&config.RouterConfig{
|
|
Name: "redis-list-rt",
|
|
Redis: &config.RedisLoader{
|
|
Addr: "127.0.0.1:6379",
|
|
Key: "routes-list",
|
|
Type: "list",
|
|
},
|
|
})
|
|
if r == nil {
|
|
t.Fatal("expected non-nil router")
|
|
}
|
|
}
|
|
|
|
func TestParseRouter_RedisSetLoader(t *testing.T) {
|
|
r := ParseRouter(&config.RouterConfig{
|
|
Name: "redis-set-rt",
|
|
Redis: &config.RedisLoader{
|
|
Addr: "127.0.0.1:6379",
|
|
Key: "routes-set",
|
|
Type: "set",
|
|
},
|
|
})
|
|
if r == nil {
|
|
t.Fatal("expected non-nil router")
|
|
}
|
|
}
|
|
|
|
func TestParseRouter_DstSyncedFromNet(t *testing.T) {
|
|
// When Dst is empty but Net is provided, Net is converted to Dst
|
|
r := ParseRouter(&config.RouterConfig{
|
|
Name: "net-to-dst-rt",
|
|
Routes: []*config.RouterRouteConfig{
|
|
{Net: "192.168.1.0/24", Gateway: "10.0.0.1"},
|
|
},
|
|
})
|
|
if r == nil {
|
|
t.Fatal("expected non-nil router")
|
|
}
|
|
route := r.GetRoute(context.Background(), "192.168.1.5")
|
|
if route == nil {
|
|
t.Fatal("expected non-nil route for IP in CIDR range")
|
|
}
|
|
if route.Dst != "192.168.1.0/24" {
|
|
t.Fatalf("Dst = %q, want %q", route.Dst, "192.168.1.0/24")
|
|
}
|
|
if route.Gateway != "10.0.0.1" {
|
|
t.Fatalf("Gateway = %q, want %q", route.Gateway, "10.0.0.1")
|
|
}
|
|
}
|