github.com/xmplusdev/xmcore@v1.8.11-0.20240412132628-5518b55526af/infra/conf/router_test.go (about)

     1  package conf_test
     2  
     3  import (
     4  	"encoding/json"
     5  	"os"
     6  	"path/filepath"
     7  	"testing"
     8  	"time"
     9  	_ "unsafe"
    10  
    11  	"github.com/xmplusdev/xmcore/app/router"
    12  	"github.com/xmplusdev/xmcore/common"
    13  	"github.com/xmplusdev/xmcore/common/net"
    14  	"github.com/xmplusdev/xmcore/common/platform"
    15  	"github.com/xmplusdev/xmcore/common/platform/filesystem"
    16  	"github.com/xmplusdev/xmcore/common/serial"
    17  	. "github.com/xmplusdev/xmcore/infra/conf"
    18  	"google.golang.org/protobuf/proto"
    19  )
    20  
    21  func init() {
    22  	wd, err := os.Getwd()
    23  	common.Must(err)
    24  
    25  	if _, err := os.Stat(platform.GetAssetLocation("geoip.dat")); err != nil && os.IsNotExist(err) {
    26  		common.Must(filesystem.CopyFile(platform.GetAssetLocation("geoip.dat"), filepath.Join(wd, "..", "..", "resources", "geoip.dat")))
    27  	}
    28  
    29  	os.Setenv("xray.location.asset", wd)
    30  }
    31  
    32  func TestToCidrList(t *testing.T) {
    33  	t.Log(os.Getenv("xray.location.asset"))
    34  
    35  	common.Must(filesystem.CopyFile(platform.GetAssetLocation("geoiptestrouter.dat"), "geoip.dat"))
    36  
    37  	ips := StringList([]string{
    38  		"geoip:us",
    39  		"geoip:cn",
    40  		"geoip:!cn",
    41  		"ext:geoiptestrouter.dat:!cn",
    42  		"ext:geoiptestrouter.dat:ca",
    43  		"ext-ip:geoiptestrouter.dat:!cn",
    44  		"ext-ip:geoiptestrouter.dat:!ca",
    45  	})
    46  
    47  	_, err := ToCidrList(ips)
    48  	if err != nil {
    49  		t.Fatalf("Failed to parse geoip list, got %s", err)
    50  	}
    51  }
    52  
    53  func TestRouterConfig(t *testing.T) {
    54  	createParser := func() func(string) (proto.Message, error) {
    55  		return func(s string) (proto.Message, error) {
    56  			config := new(RouterConfig)
    57  			if err := json.Unmarshal([]byte(s), config); err != nil {
    58  				return nil, err
    59  			}
    60  			return config.Build()
    61  		}
    62  	}
    63  
    64  	runMultiTestCase(t, []TestCase{
    65  		{
    66  			Input: `{
    67  				"strategy": "rules",
    68  				"settings": {
    69  					"domainStrategy": "AsIs",
    70  					"rules": [
    71  						{
    72  							"type": "field",
    73  							"domain": [
    74  								"baidu.com",
    75  								"qq.com"
    76  							],
    77  							"outboundTag": "direct"
    78  						},
    79  						{
    80  							"type": "field",
    81  							"ip": [
    82  								"10.0.0.0/8",
    83  								"::1/128"
    84  							],
    85  							"outboundTag": "test"
    86  						},{
    87  							"type": "field",
    88  							"port": "53, 443, 1000-2000",
    89  							"outboundTag": "test"
    90  						},{
    91  							"type": "field",
    92  							"port": 123,
    93  							"outboundTag": "test"
    94  						}
    95  					]
    96  				},
    97  				"balancers": [
    98  					{
    99  						"tag": "b1",
   100  						"selector": ["test"]
   101  					},
   102  					{
   103  						"tag": "b2",
   104  						"selector": ["test"],
   105  						"strategy": {
   106  							"type": "leastload",
   107  							"settings": {
   108  								"healthCheck": {
   109  									"interval": "5m0s",
   110  									"sampling": 2,
   111  									"timeout": "5s",
   112  									"destination": "dest",
   113  									"connectivity": "conn"
   114  								},
   115  								"costs": [
   116  									{
   117  										"regexp": true,
   118  										"match": "\\d+(\\.\\d+)",
   119  										"value": 5
   120  									}
   121  								],
   122  								"baselines": ["400ms", "600ms"],
   123  								"expected": 6,
   124  								"maxRTT": "1000ms",
   125  								"tolerance": 0.5
   126  							}
   127  						},
   128  						"fallbackTag": "fall"
   129  					}
   130  				]
   131  			}`,
   132  			Parser: createParser(),
   133  			Output: &router.Config{
   134  				DomainStrategy: router.Config_AsIs,
   135  				BalancingRule: []*router.BalancingRule{
   136  					{
   137  						Tag:              "b1",
   138  						OutboundSelector: []string{"test"},
   139  						Strategy:         "random",
   140  					},
   141  					{
   142  						Tag:              "b2",
   143  						OutboundSelector: []string{"test"},
   144  						Strategy:         "leastload",
   145  						StrategySettings: serial.ToTypedMessage(&router.StrategyLeastLoadConfig{
   146  							Costs: []*router.StrategyWeight{
   147  								{
   148  									Regexp: true,
   149  									Match:  "\\d+(\\.\\d+)",
   150  									Value:  5,
   151  								},
   152  							},
   153  							Baselines: []int64{
   154  								int64(time.Duration(400) * time.Millisecond),
   155  								int64(time.Duration(600) * time.Millisecond),
   156  							},
   157  							Expected:  6,
   158  							MaxRTT:    int64(time.Duration(1000) * time.Millisecond),
   159  							Tolerance: 0.5,
   160  						}),
   161  						FallbackTag: "fall",
   162  					},
   163  				},
   164  				Rule: []*router.RoutingRule{
   165  					{
   166  						Domain: []*router.Domain{
   167  							{
   168  								Type:  router.Domain_Plain,
   169  								Value: "baidu.com",
   170  							},
   171  							{
   172  								Type:  router.Domain_Plain,
   173  								Value: "qq.com",
   174  							},
   175  						},
   176  						TargetTag: &router.RoutingRule_Tag{
   177  							Tag: "direct",
   178  						},
   179  					},
   180  					{
   181  						Geoip: []*router.GeoIP{
   182  							{
   183  								Cidr: []*router.CIDR{
   184  									{
   185  										Ip:     []byte{10, 0, 0, 0},
   186  										Prefix: 8,
   187  									},
   188  									{
   189  										Ip:     []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
   190  										Prefix: 128,
   191  									},
   192  								},
   193  							},
   194  						},
   195  						TargetTag: &router.RoutingRule_Tag{
   196  							Tag: "test",
   197  						},
   198  					},
   199  					{
   200  						PortList: &net.PortList{
   201  							Range: []*net.PortRange{
   202  								{From: 53, To: 53},
   203  								{From: 443, To: 443},
   204  								{From: 1000, To: 2000},
   205  							},
   206  						},
   207  						TargetTag: &router.RoutingRule_Tag{
   208  							Tag: "test",
   209  						},
   210  					},
   211  					{
   212  						PortList: &net.PortList{
   213  							Range: []*net.PortRange{
   214  								{From: 123, To: 123},
   215  							},
   216  						},
   217  						TargetTag: &router.RoutingRule_Tag{
   218  							Tag: "test",
   219  						},
   220  					},
   221  				},
   222  			},
   223  		},
   224  		{
   225  			Input: `{
   226  				"strategy": "rules",
   227  				"settings": {
   228  					"domainStrategy": "IPIfNonMatch",
   229  					"rules": [
   230  						{
   231  							"type": "field",
   232  							"domain": [
   233  								"baidu.com",
   234  								"qq.com"
   235  							],
   236  							"outboundTag": "direct"
   237  						},
   238  						{
   239  							"type": "field",
   240  							"ip": [
   241  								"10.0.0.0/8",
   242  								"::1/128"
   243  							],
   244  							"outboundTag": "test"
   245  						}
   246  					]
   247  				}
   248  			}`,
   249  			Parser: createParser(),
   250  			Output: &router.Config{
   251  				DomainStrategy: router.Config_IpIfNonMatch,
   252  				Rule: []*router.RoutingRule{
   253  					{
   254  						Domain: []*router.Domain{
   255  							{
   256  								Type:  router.Domain_Plain,
   257  								Value: "baidu.com",
   258  							},
   259  							{
   260  								Type:  router.Domain_Plain,
   261  								Value: "qq.com",
   262  							},
   263  						},
   264  						TargetTag: &router.RoutingRule_Tag{
   265  							Tag: "direct",
   266  						},
   267  					},
   268  					{
   269  						Geoip: []*router.GeoIP{
   270  							{
   271  								Cidr: []*router.CIDR{
   272  									{
   273  										Ip:     []byte{10, 0, 0, 0},
   274  										Prefix: 8,
   275  									},
   276  									{
   277  										Ip:     []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
   278  										Prefix: 128,
   279  									},
   280  								},
   281  							},
   282  						},
   283  						TargetTag: &router.RoutingRule_Tag{
   284  							Tag: "test",
   285  						},
   286  					},
   287  				},
   288  			},
   289  		},
   290  		{
   291  			Input: `{
   292  				"domainStrategy": "AsIs",
   293  				"rules": [
   294  					{
   295  						"type": "field",
   296  						"domain": [
   297  							"baidu.com",
   298  							"qq.com"
   299  						],
   300  						"outboundTag": "direct"
   301  					},
   302  					{
   303  						"type": "field",
   304  						"ip": [
   305  							"10.0.0.0/8",
   306  							"::1/128"
   307  						],
   308  						"outboundTag": "test"
   309  					}
   310  				]
   311  			}`,
   312  			Parser: createParser(),
   313  			Output: &router.Config{
   314  				DomainStrategy: router.Config_AsIs,
   315  				Rule: []*router.RoutingRule{
   316  					{
   317  						Domain: []*router.Domain{
   318  							{
   319  								Type:  router.Domain_Plain,
   320  								Value: "baidu.com",
   321  							},
   322  							{
   323  								Type:  router.Domain_Plain,
   324  								Value: "qq.com",
   325  							},
   326  						},
   327  						TargetTag: &router.RoutingRule_Tag{
   328  							Tag: "direct",
   329  						},
   330  					},
   331  					{
   332  						Geoip: []*router.GeoIP{
   333  							{
   334  								Cidr: []*router.CIDR{
   335  									{
   336  										Ip:     []byte{10, 0, 0, 0},
   337  										Prefix: 8,
   338  									},
   339  									{
   340  										Ip:     []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
   341  										Prefix: 128,
   342  									},
   343  								},
   344  							},
   345  						},
   346  						TargetTag: &router.RoutingRule_Tag{
   347  							Tag: "test",
   348  						},
   349  					},
   350  				},
   351  			},
   352  		},
   353  	})
   354  }