Browse Source

isolate router settings synthesis

Shelikhoo 4 years ago
parent
commit
39b3866774

+ 3 - 2
infra/conf/blackhole.go

@@ -3,6 +3,7 @@ package conf
 import (
 	"encoding/json"
 	"github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon"
+	"github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon/loader"
 
 	"github.com/golang/protobuf/proto"
 
@@ -43,8 +44,8 @@ func (v *BlackholeConfig) Build() (proto.Message, error) {
 	return config, nil
 }
 
-var configLoader = NewJSONConfigLoader(
-	ConfigCreatorCache{
+var configLoader = loader.NewJSONConfigLoader(
+	loader.ConfigCreatorCache{
 		"none": func() interface{} { return new(NoneResponse) },
 		"http": func() interface{} { return new(HTTPResponse) },
 	},

+ 4 - 3
infra/conf/blackhole_test.go

@@ -2,6 +2,7 @@ package conf_test
 
 import (
 	"github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon"
+	"github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon/testassist"
 	"testing"
 
 	"github.com/v2fly/v2ray-core/v4/common/serial"
@@ -14,21 +15,21 @@ func TestHTTPResponseJSON(t *testing.T) {
 		return new(BlackholeConfig)
 	}
 
-	runMultiTestCase(t, []TestCase{
+	testassist.RunMultiTestCase(t, []testassist.TestCase{
 		{
 			Input: `{
 				"response": {
 					"type": "http"
 				}
 			}`,
-			Parser: loadJSON(creator),
+			Parser: testassist.LoadJSON(creator),
 			Output: &blackhole.Config{
 				Response: serial.ToTypedMessage(&blackhole.HTTPResponse{}),
 			},
 		},
 		{
 			Input:  `{}`,
-			Parser: loadJSON(creator),
+			Parser: testassist.LoadJSON(creator),
 			Output: &blackhole.Config{},
 		},
 	})

+ 3 - 1
infra/conf/loader.go → infra/conf/cfgcommon/loader/loader.go

@@ -1,10 +1,12 @@
-package conf
+package loader
 
 import (
 	"encoding/json"
 	"strings"
 )
 
+//go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen
+
 type ConfigCreator func() interface{}
 
 type ConfigCreatorCache map[string]ConfigCreator

+ 3 - 3
infra/conf/general_test.go → infra/conf/cfgcommon/testassist/general.go

@@ -1,4 +1,4 @@
-package conf_test
+package testassist
 
 import (
 	"encoding/json"
@@ -10,7 +10,7 @@ import (
 	"github.com/v2fly/v2ray-core/v4/common"
 )
 
-func loadJSON(creator func() cfgcommon.Buildable) func(string) (proto.Message, error) {
+func LoadJSON(creator func() cfgcommon.Buildable) func(string) (proto.Message, error) {
 	return func(s string) (proto.Message, error) {
 		instance := creator()
 		if err := json.Unmarshal([]byte(s), instance); err != nil {
@@ -26,7 +26,7 @@ type TestCase struct {
 	Output proto.Message
 }
 
-func runMultiTestCase(t *testing.T, testCases []TestCase) {
+func RunMultiTestCase(t *testing.T, testCases []TestCase) {
 	for _, testCase := range testCases {
 		actual, err := testCase.Parser(testCase.Input)
 		common.Must(err)

+ 3 - 2
infra/conf/dns_proxy_test.go

@@ -2,6 +2,7 @@ package conf_test
 
 import (
 	"github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon"
+	"github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon/testassist"
 	"testing"
 
 	"github.com/v2fly/v2ray-core/v4/common/net"
@@ -14,14 +15,14 @@ func TestDnsProxyConfig(t *testing.T) {
 		return new(DNSOutboundConfig)
 	}
 
-	runMultiTestCase(t, []TestCase{
+	testassist.RunMultiTestCase(t, []testassist.TestCase{
 		{
 			Input: `{
 				"address": "8.8.8.8",
 				"port": 53,
 				"network": "tcp"
 			}`,
-			Parser: loadJSON(creator),
+			Parser: testassist.LoadJSON(creator),
 			Output: &dns.Config{
 				Server: &net.Endpoint{
 					Network: net.Network_TCP,

+ 2 - 1
infra/conf/dns_test.go

@@ -3,6 +3,7 @@ package conf_test
 import (
 	"encoding/json"
 	"errors"
+	"github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon/testassist"
 	"io/fs"
 	"os"
 	"path/filepath"
@@ -58,7 +59,7 @@ func TestDNSConfigParsing(t *testing.T) {
 		}
 	}
 
-	runMultiTestCase(t, []TestCase{
+	testassist.RunMultiTestCase(t, []testassist.TestCase{
 		{
 			Input: `{
 				"servers": [{

+ 3 - 2
infra/conf/dokodemo_test.go

@@ -2,6 +2,7 @@ package conf_test
 
 import (
 	"github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon"
+	"github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon/testassist"
 	"testing"
 
 	"github.com/v2fly/v2ray-core/v4/common/net"
@@ -14,7 +15,7 @@ func TestDokodemoConfig(t *testing.T) {
 		return new(DokodemoConfig)
 	}
 
-	runMultiTestCase(t, []TestCase{
+	testassist.RunMultiTestCase(t, []testassist.TestCase{
 		{
 			Input: `{
 				"address": "8.8.8.8",
@@ -24,7 +25,7 @@ func TestDokodemoConfig(t *testing.T) {
 				"followRedirect": true,
 				"userLevel": 1
 			}`,
-			Parser: loadJSON(creator),
+			Parser: testassist.LoadJSON(creator),
 			Output: &dokodemo.Config{
 				Address: &net.IPOrDomain{
 					Address: &net.IPOrDomain_Ip{

+ 0 - 33
infra/conf/duration.go

@@ -1,33 +0,0 @@
-package conf
-
-import (
-	"encoding/json"
-	"fmt"
-	"time"
-)
-
-type Duration int64
-
-func (d *Duration) MarshalJSON() ([]byte, error) {
-	dr := time.Duration(*d)
-	return json.Marshal(dr.String())
-}
-
-func (d *Duration) UnmarshalJSON(b []byte) error {
-	var v interface{}
-	if err := json.Unmarshal(b, &v); err != nil {
-		return err
-	}
-	switch value := v.(type) {
-	case string:
-		var err error
-		dr, err := time.ParseDuration(value)
-		if err != nil {
-			return err
-		}
-		*d = Duration(dr)
-		return nil
-	default:
-		return fmt.Errorf("invalid duration: %v", v)
-	}
-}

+ 0 - 33
infra/conf/duration_test.go

@@ -1,33 +0,0 @@
-package conf_test
-
-import (
-	"encoding/json"
-	"testing"
-	"time"
-
-	"github.com/v2fly/v2ray-core/v4/infra/conf"
-)
-
-type testWithDuration struct {
-	Duration conf.Duration
-}
-
-func TestDurationJSON(t *testing.T) {
-	expected := &testWithDuration{
-		Duration: conf.Duration(time.Hour),
-	}
-	data, err := json.Marshal(expected)
-	if err != nil {
-		t.Error(err)
-		return
-	}
-	actual := &testWithDuration{}
-	err = json.Unmarshal(data, &actual)
-	if err != nil {
-		t.Error(err)
-		return
-	}
-	if actual.Duration != expected.Duration {
-		t.Errorf("expected: %s, actual: %s", time.Duration(expected.Duration), time.Duration(actual.Duration))
-	}
-}

+ 3 - 2
infra/conf/freedom_test.go

@@ -2,6 +2,7 @@ package conf_test
 
 import (
 	"github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon"
+	"github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon/testassist"
 	"testing"
 
 	"github.com/v2fly/v2ray-core/v4/common/net"
@@ -15,7 +16,7 @@ func TestFreedomConfig(t *testing.T) {
 		return new(FreedomConfig)
 	}
 
-	runMultiTestCase(t, []TestCase{
+	testassist.RunMultiTestCase(t, []testassist.TestCase{
 		{
 			Input: `{
 				"domainStrategy": "AsIs",
@@ -23,7 +24,7 @@ func TestFreedomConfig(t *testing.T) {
 				"redirect": "127.0.0.1:3366",
 				"userLevel": 1
 			}`,
-			Parser: loadJSON(creator),
+			Parser: testassist.LoadJSON(creator),
 			Output: &freedom.Config{
 				DomainStrategy: freedom.Config_AS_IS,
 				Timeout:        10,

+ 3 - 2
infra/conf/http_test.go

@@ -2,6 +2,7 @@ package conf_test
 
 import (
 	"github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon"
+	"github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon/testassist"
 	"testing"
 
 	. "github.com/v2fly/v2ray-core/v4/infra/conf"
@@ -13,7 +14,7 @@ func TestHTTPServerConfig(t *testing.T) {
 		return new(HTTPServerConfig)
 	}
 
-	runMultiTestCase(t, []TestCase{
+	testassist.RunMultiTestCase(t, []testassist.TestCase{
 		{
 			Input: `{
 				"timeout": 10,
@@ -26,7 +27,7 @@ func TestHTTPServerConfig(t *testing.T) {
 				"allowTransparent": true,
 				"userLevel": 1
 			}`,
-			Parser: loadJSON(creator),
+			Parser: testassist.LoadJSON(creator),
 			Output: &http.ServerConfig{
 				Accounts: map[string]string{
 					"my-username": "my-password",

+ 2 - 1
infra/conf/observatory.go

@@ -7,6 +7,7 @@ import (
 	"github.com/v2fly/v2ray-core/v4/app/observatory/multiObservatory"
 	"github.com/v2fly/v2ray-core/v4/common/serial"
 	"github.com/v2fly/v2ray-core/v4/common/taggedfeatures"
+	"github.com/v2fly/v2ray-core/v4/infra/conf/synthetic/router"
 
 	"github.com/v2fly/v2ray-core/v4/app/observatory"
 	"github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon/duration"
@@ -25,7 +26,7 @@ func (o *ObservatoryConfig) Build() (proto.Message, error) {
 type BurstObservatoryConfig struct {
 	SubjectSelector []string `json:"subjectSelector"`
 	// health check settings
-	HealthCheck *healthCheckSettings `json:"pingConfig,omitempty"`
+	HealthCheck *router.HealthCheckSettings `json:"pingConfig,omitempty"`
 }
 
 func (b BurstObservatoryConfig) Build() (proto.Message, error) {

+ 4 - 3
infra/conf/reverse_test.go

@@ -2,6 +2,7 @@ package conf_test
 
 import (
 	"github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon"
+	"github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon/testassist"
 	"testing"
 
 	"github.com/v2fly/v2ray-core/v4/app/reverse"
@@ -13,7 +14,7 @@ func TestReverseConfig(t *testing.T) {
 		return new(conf.ReverseConfig)
 	}
 
-	runMultiTestCase(t, []TestCase{
+	testassist.RunMultiTestCase(t, []testassist.TestCase{
 		{
 			Input: `{
 				"bridges": [{
@@ -21,7 +22,7 @@ func TestReverseConfig(t *testing.T) {
 					"domain": "test.v2fly.org"
 				}]
 			}`,
-			Parser: loadJSON(creator),
+			Parser: testassist.LoadJSON(creator),
 			Output: &reverse.Config{
 				BridgeConfig: []*reverse.BridgeConfig{
 					{Tag: "test", Domain: "test.v2fly.org"},
@@ -35,7 +36,7 @@ func TestReverseConfig(t *testing.T) {
 					"domain": "test.v2fly.org"
 				}]
 			}`,
-			Parser: loadJSON(creator),
+			Parser: testassist.LoadJSON(creator),
 			Output: &reverse.Config{
 				PortalConfig: []*reverse.PortalConfig{
 					{Tag: "test", Domain: "test.v2fly.org"},

+ 3 - 2
infra/conf/shadowsocks_test.go

@@ -2,6 +2,7 @@ package conf_test
 
 import (
 	"github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon"
+	"github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon/testassist"
 	"testing"
 
 	"github.com/v2fly/v2ray-core/v4/common/net"
@@ -16,13 +17,13 @@ func TestShadowsocksServerConfigParsing(t *testing.T) {
 		return new(ShadowsocksServerConfig)
 	}
 
-	runMultiTestCase(t, []TestCase{
+	testassist.RunMultiTestCase(t, []testassist.TestCase{
 		{
 			Input: `{
 				"method": "aes-256-GCM",
 				"password": "v2ray-password"
 			}`,
-			Parser: loadJSON(creator),
+			Parser: testassist.LoadJSON(creator),
 			Output: &shadowsocks.ServerConfig{
 				User: &protocol.User{
 					Account: serial.ToTypedMessage(&shadowsocks.Account{

+ 5 - 4
infra/conf/socks_test.go

@@ -2,6 +2,7 @@ package conf_test
 
 import (
 	"github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon"
+	"github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon/testassist"
 	"testing"
 
 	"github.com/v2fly/v2ray-core/v4/common/net"
@@ -16,7 +17,7 @@ func TestSocksInboundConfig(t *testing.T) {
 		return new(SocksServerConfig)
 	}
 
-	runMultiTestCase(t, []TestCase{
+	testassist.RunMultiTestCase(t, []testassist.TestCase{
 		{
 			Input: `{
 				"auth": "password",
@@ -31,7 +32,7 @@ func TestSocksInboundConfig(t *testing.T) {
 				"timeout": 5,
 				"userLevel": 1
 			}`,
-			Parser: loadJSON(creator),
+			Parser: testassist.LoadJSON(creator),
 			Output: &socks.ServerConfig{
 				AuthType: socks.AuthType_PASSWORD,
 				Accounts: map[string]string{
@@ -55,7 +56,7 @@ func TestSocksOutboundConfig(t *testing.T) {
 		return new(SocksClientConfig)
 	}
 
-	runMultiTestCase(t, []TestCase{
+	testassist.RunMultiTestCase(t, []testassist.TestCase{
 		{
 			Input: `{
 				"servers": [{
@@ -66,7 +67,7 @@ func TestSocksOutboundConfig(t *testing.T) {
 					]
 				}]
 			}`,
-			Parser: loadJSON(creator),
+			Parser: testassist.LoadJSON(creator),
 			Output: &socks.ClientConfig{
 				Server: []*protocol.ServerEndpoint{
 					{

+ 4 - 2
infra/conf/router.go → infra/conf/synthetic/router/router.go

@@ -1,4 +1,6 @@
-package conf
+package router
+
+//go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen
 
 import (
 	"context"
@@ -50,7 +52,7 @@ func (r *BalancingRule) Build() (*router.BalancingRule, error) {
 	case strategyLeastLoad:
 		strategy = strategyLeastLoad
 	case strategyLeastPing:
-		strategy = "leastPing"
+		strategy = "leastping"
 	default:
 		return nil, newError("unknown balancing strategy: " + r.Strategy.Type)
 	}

+ 14 - 12
infra/conf/router_strategy.go → infra/conf/synthetic/router/router_strategy.go

@@ -1,8 +1,10 @@
-package conf
+package router
 
 import (
 	"github.com/golang/protobuf/proto"
 	"github.com/v2fly/v2ray-core/v4/app/observatory/burst"
+	"github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon/duration"
+	"github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon/loader"
 
 	"github.com/v2fly/v2ray-core/v4/app/router"
 )
@@ -14,7 +16,7 @@ const (
 )
 
 var (
-	strategyConfigLoader = NewJSONConfigLoader(ConfigCreatorCache{
+	strategyConfigLoader = loader.NewJSONConfigLoader(loader.ConfigCreatorCache{
 		strategyRandom:    func() interface{} { return new(strategyEmptyConfig) },
 		strategyLeastLoad: func() interface{} { return new(strategyLeastLoadConfig) },
 		strategyLeastPing: func() interface{} { return new(strategyLeastPingConfig) },
@@ -32,27 +34,27 @@ type strategyLeastLoadConfig struct {
 	// weight settings
 	Costs []*router.StrategyWeight `json:"costs,omitempty"`
 	// ping rtt baselines
-	Baselines []Duration `json:"baselines,omitempty"`
+	Baselines []duration.Duration `json:"baselines,omitempty"`
 	// expected nodes count to select
 	Expected int32 `json:"expected,omitempty"`
 	// max acceptable rtt, filter away high delay nodes. defalut 0
-	MaxRTT Duration `json:"maxRTT,omitempty"`
+	MaxRTT duration.Duration `json:"maxRTT,omitempty"`
 	// acceptable failure rate
 	Tolerance float64 `json:"tolerance,omitempty"`
 
 	ObserverTag string `json:"observerTag,omitempty"`
 }
 
-// healthCheckSettings holds settings for health Checker
-type healthCheckSettings struct {
-	Destination   string   `json:"destination"`
-	Connectivity  string   `json:"connectivity"`
-	Interval      Duration `json:"interval"`
-	SamplingCount int      `json:"sampling"`
-	Timeout       Duration `json:"timeout"`
+// HealthCheckSettings holds settings for health Checker
+type HealthCheckSettings struct {
+	Destination   string            `json:"destination"`
+	Connectivity  string            `json:"connectivity"`
+	Interval      duration.Duration `json:"interval"`
+	SamplingCount int               `json:"sampling"`
+	Timeout       duration.Duration `json:"timeout"`
 }
 
-func (h healthCheckSettings) Build() (proto.Message, error) {
+func (h HealthCheckSettings) Build() (proto.Message, error) {
 	return &burst.HealthPingConfig{
 		Destination:   h.Destination,
 		Connectivity:  h.Connectivity,

+ 9 - 4
infra/conf/router_test.go → infra/conf/synthetic/router/router_test.go

@@ -1,7 +1,9 @@
-package conf_test
+package router_test
 
 import (
 	"encoding/json"
+	"github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon/testassist"
+	router2 "github.com/v2fly/v2ray-core/v4/infra/conf/synthetic/router"
 	"testing"
 	"time"
 	_ "unsafe"
@@ -11,13 +13,16 @@ import (
 	"github.com/v2fly/v2ray-core/v4/app/router"
 	"github.com/v2fly/v2ray-core/v4/common/net"
 	"github.com/v2fly/v2ray-core/v4/common/serial"
-	. "github.com/v2fly/v2ray-core/v4/infra/conf"
+
+	// Geo loaders
+	_ "github.com/v2fly/v2ray-core/v4/infra/conf/geodata/memconservative"
+	_ "github.com/v2fly/v2ray-core/v4/infra/conf/geodata/standard"
 )
 
 func TestRouterConfig(t *testing.T) {
 	createParser := func() func(string) (proto.Message, error) {
 		return func(s string) (proto.Message, error) {
-			config := new(RouterConfig)
+			config := new(router2.RouterConfig)
 			if err := json.Unmarshal([]byte(s), config); err != nil {
 				return nil, err
 			}
@@ -25,7 +30,7 @@ func TestRouterConfig(t *testing.T) {
 		}
 	}
 
-	runMultiTestCase(t, []TestCase{
+	testassist.RunMultiTestCase(t, []testassist.TestCase{
 		{
 			Input: `{
 				"strategy": "rules",

+ 3 - 2
infra/conf/transport_internet.go

@@ -3,6 +3,7 @@ package conf
 import (
 	"encoding/base64"
 	"encoding/json"
+	"github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon/loader"
 	"strings"
 
 	"github.com/golang/protobuf/proto"
@@ -23,7 +24,7 @@ import (
 )
 
 var (
-	kcpHeaderLoader = NewJSONConfigLoader(ConfigCreatorCache{
+	kcpHeaderLoader = loader.NewJSONConfigLoader(loader.ConfigCreatorCache{
 		"none":         func() interface{} { return new(NoOpAuthenticator) },
 		"srtp":         func() interface{} { return new(SRTPAuthenticator) },
 		"utp":          func() interface{} { return new(UTPAuthenticator) },
@@ -32,7 +33,7 @@ var (
 		"wireguard":    func() interface{} { return new(WireguardAuthenticator) },
 	}, "type", "")
 
-	tcpHeaderLoader = NewJSONConfigLoader(ConfigCreatorCache{
+	tcpHeaderLoader = loader.NewJSONConfigLoader(loader.ConfigCreatorCache{
 		"none": func() interface{} { return new(NoOpConnectionAuthenticator) },
 		"http": func() interface{} { return new(Authenticator) },
 	}, "type", "")

+ 3 - 2
infra/conf/transport_test.go

@@ -2,6 +2,7 @@ package conf_test
 
 import (
 	"encoding/json"
+	"github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon/testassist"
 	"testing"
 
 	"github.com/golang/protobuf/proto"
@@ -31,7 +32,7 @@ func TestSocketConfig(t *testing.T) {
 		}
 	}
 
-	runMultiTestCase(t, []TestCase{
+	testassist.RunMultiTestCase(t, []testassist.TestCase{
 		{
 			Input: `{
 				"mark": 1,
@@ -57,7 +58,7 @@ func TestTransportConfig(t *testing.T) {
 		}
 	}
 
-	runMultiTestCase(t, []TestCase{
+	testassist.RunMultiTestCase(t, []testassist.TestCase{
 		{
 			Input: `{
 				"tcpSettings": {

+ 5 - 3
infra/conf/v2ray.go

@@ -2,6 +2,8 @@ package conf
 
 import (
 	"encoding/json"
+	"github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon/loader"
+	"github.com/v2fly/v2ray-core/v4/infra/conf/synthetic/router"
 	"strings"
 
 	core "github.com/v2fly/v2ray-core/v4"
@@ -13,7 +15,7 @@ import (
 )
 
 var (
-	inboundConfigLoader = NewJSONConfigLoader(ConfigCreatorCache{
+	inboundConfigLoader = loader.NewJSONConfigLoader(loader.ConfigCreatorCache{
 		"dokodemo-door": func() interface{} { return new(DokodemoConfig) },
 		"http":          func() interface{} { return new(HTTPServerConfig) },
 		"shadowsocks":   func() interface{} { return new(ShadowsocksServerConfig) },
@@ -23,7 +25,7 @@ var (
 		"trojan":        func() interface{} { return new(TrojanServerConfig) },
 	}, "protocol", "settings")
 
-	outboundConfigLoader = NewJSONConfigLoader(ConfigCreatorCache{
+	outboundConfigLoader = loader.NewJSONConfigLoader(loader.ConfigCreatorCache{
 		"blackhole":   func() interface{} { return new(BlackholeConfig) },
 		"freedom":     func() interface{} { return new(FreedomConfig) },
 		"http":        func() interface{} { return new(HTTPClientConfig) },
@@ -339,7 +341,7 @@ type Config struct {
 	OutboundDetours []OutboundDetourConfig `json:"outboundDetour"`
 
 	LogConfig        *LogConfig              `json:"log"`
-	RouterConfig     *RouterConfig           `json:"routing"`
+	RouterConfig     *router.RouterConfig    `json:"routing"`
 	DNSConfig        *DNSConfig              `json:"dns"`
 	InboundConfigs   []InboundDetourConfig   `json:"inbounds"`
 	OutboundConfigs  []OutboundDetourConfig  `json:"outbounds"`

+ 2 - 1
infra/conf/v2ray_test.go

@@ -2,6 +2,7 @@ package conf_test
 
 import (
 	"encoding/json"
+	"github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon/testassist"
 	"reflect"
 	"testing"
 
@@ -40,7 +41,7 @@ func TestV2RayConfig(t *testing.T) {
 		}
 	}
 
-	runMultiTestCase(t, []TestCase{
+	testassist.RunMultiTestCase(t, []testassist.TestCase{
 		{
 			Input: `{
 				"outbound": {

+ 5 - 4
infra/conf/vless_test.go

@@ -2,6 +2,7 @@ package conf_test
 
 import (
 	"github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon"
+	"github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon/testassist"
 	"testing"
 
 	"github.com/v2fly/v2ray-core/v4/common/net"
@@ -18,7 +19,7 @@ func TestVLessOutbound(t *testing.T) {
 		return new(VLessOutboundConfig)
 	}
 
-	runMultiTestCase(t, []TestCase{
+	testassist.RunMultiTestCase(t, []testassist.TestCase{
 		{
 			Input: `{
 				"vnext": [{
@@ -33,7 +34,7 @@ func TestVLessOutbound(t *testing.T) {
 					]
 				}]
 			}`,
-			Parser: loadJSON(creator),
+			Parser: testassist.LoadJSON(creator),
 			Output: &outbound.Config{
 				Vnext: []*protocol.ServerEndpoint{
 					{
@@ -64,7 +65,7 @@ func TestVLessInbound(t *testing.T) {
 		return new(VLessInboundConfig)
 	}
 
-	runMultiTestCase(t, []TestCase{
+	testassist.RunMultiTestCase(t, []testassist.TestCase{
 		{
 			Input: `{
 				"clients": [
@@ -90,7 +91,7 @@ func TestVLessInbound(t *testing.T) {
 					}
 				]
 			}`,
-			Parser: loadJSON(creator),
+			Parser: testassist.LoadJSON(creator),
 			Output: &inbound.Config{
 				Clients: []*protocol.User{
 					{

+ 5 - 4
infra/conf/vmess_test.go

@@ -2,6 +2,7 @@ package conf_test
 
 import (
 	"github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon"
+	"github.com/v2fly/v2ray-core/v4/infra/conf/cfgcommon/testassist"
 	"testing"
 
 	"github.com/v2fly/v2ray-core/v4/common/net"
@@ -18,7 +19,7 @@ func TestVMessOutbound(t *testing.T) {
 		return new(VMessOutboundConfig)
 	}
 
-	runMultiTestCase(t, []TestCase{
+	testassist.RunMultiTestCase(t, []testassist.TestCase{
 		{
 			Input: `{
 				"vnext": [{
@@ -33,7 +34,7 @@ func TestVMessOutbound(t *testing.T) {
 					]
 				}]
 			}`,
-			Parser: loadJSON(creator),
+			Parser: testassist.LoadJSON(creator),
 			Output: &outbound.Config{
 				Receiver: []*protocol.ServerEndpoint{
 					{
@@ -68,7 +69,7 @@ func TestVMessInbound(t *testing.T) {
 		return new(VMessInboundConfig)
 	}
 
-	runMultiTestCase(t, []TestCase{
+	testassist.RunMultiTestCase(t, []testassist.TestCase{
 		{
 			Input: `{
 				"clients": [
@@ -89,7 +90,7 @@ func TestVMessInbound(t *testing.T) {
 				},
 				"disableInsecureEncryption": true
 			}`,
-			Parser: loadJSON(creator),
+			Parser: testassist.LoadJSON(creator),
 			Output: &inbound.Config{
 				User: []*protocol.User{
 					{