github.com/v2fly/v2ray-core/v5@v5.16.2-0.20240507031116-8191faa6e095/app/router/router_test.go (about)

     1  package router_test
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	"github.com/golang/mock/gomock"
     8  
     9  	. "github.com/v2fly/v2ray-core/v5/app/router"
    10  	"github.com/v2fly/v2ray-core/v5/app/router/routercommon"
    11  	"github.com/v2fly/v2ray-core/v5/common"
    12  	"github.com/v2fly/v2ray-core/v5/common/net"
    13  	"github.com/v2fly/v2ray-core/v5/common/session"
    14  	"github.com/v2fly/v2ray-core/v5/features/outbound"
    15  	routing_session "github.com/v2fly/v2ray-core/v5/features/routing/session"
    16  	"github.com/v2fly/v2ray-core/v5/testing/mocks"
    17  )
    18  
    19  type mockOutboundManager struct {
    20  	outbound.Manager
    21  	outbound.HandlerSelector
    22  }
    23  
    24  func TestSimpleRouter(t *testing.T) {
    25  	config := &Config{
    26  		Rule: []*RoutingRule{
    27  			{
    28  				TargetTag: &RoutingRule_Tag{
    29  					Tag: "test",
    30  				},
    31  				Networks: []net.Network{net.Network_TCP},
    32  			},
    33  		},
    34  	}
    35  
    36  	mockCtl := gomock.NewController(t)
    37  	defer mockCtl.Finish()
    38  
    39  	mockDNS := mocks.NewDNSClient(mockCtl)
    40  	mockOhm := mocks.NewOutboundManager(mockCtl)
    41  	mockHs := mocks.NewOutboundHandlerSelector(mockCtl)
    42  
    43  	r := new(Router)
    44  	common.Must(r.Init(context.TODO(), config, mockDNS, &mockOutboundManager{
    45  		Manager:         mockOhm,
    46  		HandlerSelector: mockHs,
    47  	}, nil))
    48  
    49  	ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.DomainAddress("v2fly.org"), 80)})
    50  	route, err := r.PickRoute(routing_session.AsRoutingContext(ctx))
    51  	common.Must(err)
    52  	if tag := route.GetOutboundTag(); tag != "test" {
    53  		t.Error("expect tag 'test', bug actually ", tag)
    54  	}
    55  }
    56  
    57  func TestSimpleBalancer(t *testing.T) {
    58  	config := &Config{
    59  		Rule: []*RoutingRule{
    60  			{
    61  				TargetTag: &RoutingRule_BalancingTag{
    62  					BalancingTag: "balance",
    63  				},
    64  				Networks: []net.Network{net.Network_TCP},
    65  			},
    66  		},
    67  		BalancingRule: []*BalancingRule{
    68  			{
    69  				Tag:              "balance",
    70  				OutboundSelector: []string{"test-"},
    71  			},
    72  		},
    73  	}
    74  
    75  	mockCtl := gomock.NewController(t)
    76  	defer mockCtl.Finish()
    77  
    78  	mockDNS := mocks.NewDNSClient(mockCtl)
    79  	mockOhm := mocks.NewOutboundManager(mockCtl)
    80  	mockHs := mocks.NewOutboundHandlerSelector(mockCtl)
    81  
    82  	mockHs.EXPECT().Select(gomock.Eq([]string{"test-"})).Return([]string{"test"})
    83  
    84  	r := new(Router)
    85  	common.Must(r.Init(context.TODO(), config, mockDNS, &mockOutboundManager{
    86  		Manager:         mockOhm,
    87  		HandlerSelector: mockHs,
    88  	}, nil))
    89  
    90  	ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.DomainAddress("v2fly.org"), 80)})
    91  	route, err := r.PickRoute(routing_session.AsRoutingContext(ctx))
    92  	common.Must(err)
    93  	if tag := route.GetOutboundTag(); tag != "test" {
    94  		t.Error("expect tag 'test', bug actually ", tag)
    95  	}
    96  }
    97  
    98  /*
    99  
   100  Do not work right now: need a full client setup
   101  
   102  func TestLeastLoadBalancer(t *testing.T) {
   103  	config := &Config{
   104  		Rule: []*RoutingRule{
   105  			{
   106  				TargetTag: &RoutingRule_BalancingTag{
   107  					BalancingTag: "balance",
   108  				},
   109  				Networks: []net.Network{net.Network_TCP},
   110  			},
   111  		},
   112  		BalancingRule: []*BalancingRule{
   113  			{
   114  				Tag:              "balance",
   115  				OutboundSelector: []string{"test-"},
   116  				Strategy:         "leastLoad",
   117  				StrategySettings: serial.ToTypedMessage(&StrategyLeastLoadConfig{
   118  					Baselines:   nil,
   119  					Expected:    1,
   120  				}),
   121  			},
   122  		},
   123  	}
   124  
   125  	mockCtl := gomock.NewController(t)
   126  	defer mockCtl.Finish()
   127  
   128  	mockDNS := mocks.NewDNSClient(mockCtl)
   129  	mockOhm := mocks.NewOutboundManager(mockCtl)
   130  	mockHs := mocks.NewOutboundHandlerSelector(mockCtl)
   131  
   132  	mockHs.EXPECT().Select(gomock.Eq([]string{"test-"})).Return([]string{"test1"})
   133  
   134  	r := new(Router)
   135  	common.Must(r.Init(context.TODO(), config, mockDNS, &mockOutboundManager{
   136  		Manager:         mockOhm,
   137  		HandlerSelector: mockHs,
   138  	}, nil))
   139  	ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.DomainAddress("v2ray.com"), 80)})
   140  	route, err := r.PickRoute(routing_session.AsRoutingContext(ctx))
   141  	common.Must(err)
   142  	if tag := route.GetOutboundTag(); tag != "test1" {
   143  		t.Error("expect tag 'test1', bug actually ", tag)
   144  	}
   145  }*/
   146  
   147  func TestIPOnDemand(t *testing.T) {
   148  	config := &Config{
   149  		DomainStrategy: DomainStrategy_IpOnDemand,
   150  		Rule: []*RoutingRule{
   151  			{
   152  				TargetTag: &RoutingRule_Tag{
   153  					Tag: "test",
   154  				},
   155  				Cidr: []*routercommon.CIDR{
   156  					{
   157  						Ip:     []byte{192, 168, 0, 0},
   158  						Prefix: 16,
   159  					},
   160  				},
   161  			},
   162  		},
   163  	}
   164  
   165  	mockCtl := gomock.NewController(t)
   166  	defer mockCtl.Finish()
   167  
   168  	mockDNS := mocks.NewDNSClient(mockCtl)
   169  	mockDNS.EXPECT().LookupIP(gomock.Eq("v2fly.org")).Return([]net.IP{{192, 168, 0, 1}}, nil).AnyTimes()
   170  
   171  	r := new(Router)
   172  	common.Must(r.Init(context.TODO(), config, mockDNS, nil, nil))
   173  
   174  	ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.DomainAddress("v2fly.org"), 80)})
   175  	route, err := r.PickRoute(routing_session.AsRoutingContext(ctx))
   176  	common.Must(err)
   177  	if tag := route.GetOutboundTag(); tag != "test" {
   178  		t.Error("expect tag 'test', bug actually ", tag)
   179  	}
   180  }
   181  
   182  func TestIPIfNonMatchDomain(t *testing.T) {
   183  	config := &Config{
   184  		DomainStrategy: DomainStrategy_IpIfNonMatch,
   185  		Rule: []*RoutingRule{
   186  			{
   187  				TargetTag: &RoutingRule_Tag{
   188  					Tag: "test",
   189  				},
   190  				Cidr: []*routercommon.CIDR{
   191  					{
   192  						Ip:     []byte{192, 168, 0, 0},
   193  						Prefix: 16,
   194  					},
   195  				},
   196  			},
   197  		},
   198  	}
   199  
   200  	mockCtl := gomock.NewController(t)
   201  	defer mockCtl.Finish()
   202  
   203  	mockDNS := mocks.NewDNSClient(mockCtl)
   204  	mockDNS.EXPECT().LookupIP(gomock.Eq("v2fly.org")).Return([]net.IP{{192, 168, 0, 1}}, nil).AnyTimes()
   205  
   206  	r := new(Router)
   207  	common.Must(r.Init(context.TODO(), config, mockDNS, nil, nil))
   208  
   209  	ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.DomainAddress("v2fly.org"), 80)})
   210  	route, err := r.PickRoute(routing_session.AsRoutingContext(ctx))
   211  	common.Must(err)
   212  	if tag := route.GetOutboundTag(); tag != "test" {
   213  		t.Error("expect tag 'test', bug actually ", tag)
   214  	}
   215  }
   216  
   217  func TestIPIfNonMatchIP(t *testing.T) {
   218  	config := &Config{
   219  		DomainStrategy: DomainStrategy_IpIfNonMatch,
   220  		Rule: []*RoutingRule{
   221  			{
   222  				TargetTag: &RoutingRule_Tag{
   223  					Tag: "test",
   224  				},
   225  				Cidr: []*routercommon.CIDR{
   226  					{
   227  						Ip:     []byte{127, 0, 0, 0},
   228  						Prefix: 8,
   229  					},
   230  				},
   231  			},
   232  		},
   233  	}
   234  
   235  	mockCtl := gomock.NewController(t)
   236  	defer mockCtl.Finish()
   237  
   238  	mockDNS := mocks.NewDNSClient(mockCtl)
   239  
   240  	r := new(Router)
   241  	common.Must(r.Init(context.TODO(), config, mockDNS, nil, nil))
   242  
   243  	ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.LocalHostIP, 80)})
   244  	route, err := r.PickRoute(routing_session.AsRoutingContext(ctx))
   245  	common.Must(err)
   246  	if tag := route.GetOutboundTag(); tag != "test" {
   247  		t.Error("expect tag 'test', bug actually ", tag)
   248  	}
   249  }