mirror of
https://github.com/v2fly/v2ray-core.git
synced 2024-06-03 06:30:42 +00:00
2c5a714903
* generate .pb.go * health checker conf * check logic * implement ping * fix check interval * improve check results * health check on add outbounds * fix tests * fix ping handler * fix min rtt < 0 * random alive * fix check all on add outbounds * least load strategy * conf codes optimize * improve least load strategy * improve health check on AddOutboundHandler * cleanup results with scheduler code optimize * health ping timeout default 5s * remove config of health ping round round 1 seems to be good enough * fix TestSimpleBalancer * add TestLeastLoadBalancer * add todos * lint and test fix * balancer fallback * api health stats command * add hc cmd to perform health checks * rename 'health stats' cmd to hci * many code optimizations * fix typo * select none if no match for baselines only config > prev 'select 1' behavior can achieved by baselines+expected=1 * add LeastLoadStrategy tests * don't select alive on no match, go to fallback * api hci refactor * more detailed info * ready for future new strategies * apply lint style * refactor: strategies don't need ref of balancer * change check interval unit to seconds > to reduce influence caused by what is described by new added FIXME * fix test * RouterService->RoutingService * Revert "generate .pb.go" This reverts commit 0e6fa1be889470d0ad9692f7279da45c030e1919. * make checks distributed > but `api hc` is the exception * BalancingStrategy interface optimize * fix random selects unchecked * upgrade cmd hci to bi & rename hc to bc * bi shows all balancers, while hci shows only heath-check-enabled ones * shows more info * fix test * api bi sort output * update according to review * remove checks on add outbound * refactor: move health checker inside to strategy * enables rounds setting for health ping * restore the random behavior, no ping, no pick alive > if future strategy based on HealthPing, just embed it like what LeastLoad does * apply lint style * code optimize * fix typo * update desc of bc bi * ping with head code optimize * force rouds to 1 if checks not distributed * leatload: select by standard deviations * health ping refactor * continuously applying results * config is easier to understand * checker interfaces simplifying * add maxRTT config to filter away high delay nodes * apply lint * cost for leastload * api bo to override balancer selecting * fix health ping statistics & fix test * check connectivity if ping fail * add tolerance setting & more detailed bi output * fix connectivity check * optimize bi output * should not put results when network is down * fixes @_@ * mux optimize * remove pause option of selecting overriding > it causes data racing * update bo desc * fix potential racing * simplify locking * switch sync.Mutex to avoid potential racing * add more tests * code optimize * code optimize * fix connectivity check when url not set
178 lines
4.8 KiB
Go
178 lines
4.8 KiB
Go
package router
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestSelectLeastLoad(t *testing.T) {
|
|
settings := &StrategyLeastLoadConfig{
|
|
HealthCheck: &HealthPingConfig{
|
|
SamplingCount: 10,
|
|
},
|
|
Expected: 1,
|
|
MaxRTT: int64(time.Millisecond * time.Duration(800)),
|
|
}
|
|
strategy := NewLeastLoadStrategy(settings, nil)
|
|
// std 40
|
|
strategy.PutResult("a", time.Millisecond*time.Duration(60))
|
|
strategy.PutResult("a", time.Millisecond*time.Duration(140))
|
|
strategy.PutResult("a", time.Millisecond*time.Duration(60))
|
|
strategy.PutResult("a", time.Millisecond*time.Duration(140))
|
|
// std 60
|
|
strategy.PutResult("b", time.Millisecond*time.Duration(40))
|
|
strategy.PutResult("b", time.Millisecond*time.Duration(160))
|
|
strategy.PutResult("b", time.Millisecond*time.Duration(40))
|
|
strategy.PutResult("b", time.Millisecond*time.Duration(160))
|
|
// std 0, but >MaxRTT
|
|
strategy.PutResult("c", time.Millisecond*time.Duration(1000))
|
|
strategy.PutResult("c", time.Millisecond*time.Duration(1000))
|
|
strategy.PutResult("c", time.Millisecond*time.Duration(1000))
|
|
strategy.PutResult("c", time.Millisecond*time.Duration(1000))
|
|
expected := "a"
|
|
actual := strategy.SelectAndPick([]string{"a", "b", "c", "untested"})
|
|
if actual != expected {
|
|
t.Errorf("expected: %v, actual: %v", expected, actual)
|
|
}
|
|
}
|
|
|
|
func TestSelectLeastLoadWithCost(t *testing.T) {
|
|
settings := &StrategyLeastLoadConfig{
|
|
HealthCheck: &HealthPingConfig{
|
|
SamplingCount: 10,
|
|
},
|
|
Costs: []*StrategyWeight{
|
|
{Match: "a", Value: 9},
|
|
},
|
|
Expected: 1,
|
|
}
|
|
strategy := NewLeastLoadStrategy(settings, nil)
|
|
// std 40, std+c 120
|
|
strategy.PutResult("a", time.Millisecond*time.Duration(60))
|
|
strategy.PutResult("a", time.Millisecond*time.Duration(140))
|
|
strategy.PutResult("a", time.Millisecond*time.Duration(60))
|
|
strategy.PutResult("a", time.Millisecond*time.Duration(140))
|
|
// std 60
|
|
strategy.PutResult("b", time.Millisecond*time.Duration(40))
|
|
strategy.PutResult("b", time.Millisecond*time.Duration(160))
|
|
strategy.PutResult("b", time.Millisecond*time.Duration(40))
|
|
strategy.PutResult("b", time.Millisecond*time.Duration(160))
|
|
expected := "b"
|
|
actual := strategy.SelectAndPick([]string{"a", "b", "untested"})
|
|
if actual != expected {
|
|
t.Errorf("expected: %v, actual: %v", expected, actual)
|
|
}
|
|
}
|
|
|
|
func TestSelectLeastExpected(t *testing.T) {
|
|
strategy := &LeastLoadStrategy{
|
|
settings: &StrategyLeastLoadConfig{
|
|
Baselines: nil,
|
|
Expected: 3,
|
|
},
|
|
}
|
|
nodes := []*node{
|
|
{Tag: "a", applied: 100},
|
|
{Tag: "b", applied: 200},
|
|
{Tag: "c", applied: 300},
|
|
{Tag: "d", applied: 350},
|
|
}
|
|
expected := 3
|
|
ns := strategy.selectLeastLoad(nodes)
|
|
if len(ns) != expected {
|
|
t.Errorf("expected: %v, actual: %v", expected, len(ns))
|
|
}
|
|
}
|
|
func TestSelectLeastExpected2(t *testing.T) {
|
|
strategy := &LeastLoadStrategy{
|
|
settings: &StrategyLeastLoadConfig{
|
|
Baselines: nil,
|
|
Expected: 3,
|
|
},
|
|
}
|
|
nodes := []*node{
|
|
{Tag: "a", applied: 100},
|
|
{Tag: "b", applied: 200},
|
|
}
|
|
expected := 2
|
|
ns := strategy.selectLeastLoad(nodes)
|
|
if len(ns) != expected {
|
|
t.Errorf("expected: %v, actual: %v", expected, len(ns))
|
|
}
|
|
}
|
|
func TestSelectLeastExpectedAndBaselines(t *testing.T) {
|
|
strategy := &LeastLoadStrategy{
|
|
settings: &StrategyLeastLoadConfig{
|
|
Baselines: []int64{200, 300, 400},
|
|
Expected: 3,
|
|
},
|
|
}
|
|
nodes := []*node{
|
|
{Tag: "a", applied: 100},
|
|
{Tag: "b", applied: 200},
|
|
{Tag: "c", applied: 250},
|
|
{Tag: "d", applied: 300},
|
|
{Tag: "e", applied: 310},
|
|
}
|
|
expected := 4
|
|
ns := strategy.selectLeastLoad(nodes)
|
|
if len(ns) != expected {
|
|
t.Errorf("expected: %v, actual: %v", expected, len(ns))
|
|
}
|
|
}
|
|
func TestSelectLeastExpectedAndBaselines2(t *testing.T) {
|
|
strategy := &LeastLoadStrategy{
|
|
settings: &StrategyLeastLoadConfig{
|
|
Baselines: []int64{200, 300, 400},
|
|
Expected: 3,
|
|
},
|
|
}
|
|
nodes := []*node{
|
|
{Tag: "a", applied: 500},
|
|
{Tag: "b", applied: 600},
|
|
{Tag: "c", applied: 700},
|
|
{Tag: "d", applied: 800},
|
|
{Tag: "e", applied: 900},
|
|
}
|
|
expected := 3
|
|
ns := strategy.selectLeastLoad(nodes)
|
|
if len(ns) != expected {
|
|
t.Errorf("expected: %v, actual: %v", expected, len(ns))
|
|
}
|
|
}
|
|
func TestSelectLeastLoadBaselines(t *testing.T) {
|
|
strategy := &LeastLoadStrategy{
|
|
settings: &StrategyLeastLoadConfig{
|
|
Baselines: []int64{200, 400, 600},
|
|
Expected: 0,
|
|
},
|
|
}
|
|
nodes := []*node{
|
|
{Tag: "a", applied: 100},
|
|
{Tag: "b", applied: 200},
|
|
{Tag: "c", applied: 300},
|
|
}
|
|
expected := 2
|
|
ns := strategy.selectLeastLoad(nodes)
|
|
if len(ns) != expected {
|
|
t.Errorf("expected: %v, actual: %v", expected, len(ns))
|
|
}
|
|
}
|
|
func TestSelectLeastLoadBaselinesNoQualified(t *testing.T) {
|
|
strategy := &LeastLoadStrategy{
|
|
settings: &StrategyLeastLoadConfig{
|
|
Baselines: []int64{200, 400, 600},
|
|
Expected: 0,
|
|
},
|
|
}
|
|
nodes := []*node{
|
|
{Tag: "a", applied: 800},
|
|
{Tag: "b", applied: 1000},
|
|
}
|
|
expected := 0
|
|
ns := strategy.selectLeastLoad(nodes)
|
|
if len(ns) != expected {
|
|
t.Errorf("expected: %v, actual: %v", expected, len(ns))
|
|
}
|
|
}
|