Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add unit test cases, improve implement #1162

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 9 additions & 27 deletions bfe_balance/bal_slb/bal_rr.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,12 @@ import (
"math/rand"
"sort"
"sync"
)

import (
"github.com/baidu/go-lib/log"
"github.com/spaolacci/murmur3"
)

import (
"github.com/bfenetworks/bfe/bfe_balance/backend"
"github.com/bfenetworks/bfe/bfe_config/bfe_cluster_conf/cluster_table_conf"
"github.com/bfenetworks/bfe/bfe_debug"
"github.com/spaolacci/murmur3"
)

// implementation versions of weighted round-robin algorithm
Expand Down Expand Up @@ -322,47 +317,34 @@ func (brr *BalanceRR) leastConnsSimpleBalance() (*backend.BfeBackend, error) {
}

func leastConnsBalance(backs BackendList) (BackendList, error) {
var best *BackendRR
candidates := make(BackendList, 0, len(backs))

// select available candidates
singleBackend := true
for _, backendRR := range backs {
if !backendRR.backend.Avail() || backendRR.weight <= 0 {
continue
}

if best == nil {
best = backendRR
singleBackend = true
if len(candidates) == 0 {
candidates = append(candidates, backendRR) // init
continue
}

// compare backends
ret := compLCWeight(best, backendRR)
ret := compLCWeight(candidates[0], backendRR)
if ret > 0 {
best = backendRR
singleBackend = true
candidates = candidates[0:0] // reset
candidates = append(candidates, backendRR)
} else if ret == 0 {
singleBackend = false
if len(candidates) > 0 {
candidates = append(candidates, backendRR)
} else {
candidates = append(candidates, best, backendRR)
}

// more than one backend have same connections/weight
candidates = append(candidates, backendRR)
}
}

if best == nil {
if len(candidates) == 0 {
return nil, fmt.Errorf("rr_bal:all backend is down")
}

// single backend, return directly
if singleBackend {
return BackendList{best}, nil
}
// more than one backend have same connections/weight,
// return all the candidates
return candidates, nil
}
Expand Down
81 changes: 76 additions & 5 deletions bfe_balance/bal_slb/bal_rr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ import (
"math/rand"
"reflect"
"testing"
)

import (
"github.com/bfenetworks/bfe/bfe_balance/backend"
"github.com/bfenetworks/bfe/bfe_config/bfe_cluster_conf/cluster_table_conf"
"github.com/bfenetworks/bfe/bfe_util/json"
Expand Down Expand Up @@ -131,7 +129,7 @@ func processBalancLoopTwenty(t *testing.T, label string, algor int, key []byte,

func processSimpleBalance(t *testing.T, label string, algor int, key []byte, rr *BalanceRR, result []string) {
var l []string
loopCount := (300+200+100)+4
loopCount := (300 + 200 + 100) + 4

for i := 1; i < loopCount; i++ {
r, err := rr.Balance(algor, key)
Expand All @@ -156,7 +154,7 @@ func processSimpleBalance(t *testing.T, label string, algor int, key []byte, rr

func processSimpleBalance3(t *testing.T, label string, algor int, key []byte, rr *BalanceRR, result []string) {
var l []string
loopCount := (200+100)*3+4
loopCount := (200+100)*3 + 4

for i := 1; i < loopCount; i++ {
r, err := rr.Balance(algor, key)
Expand Down Expand Up @@ -218,7 +216,7 @@ func TestBalance(t *testing.T) {
rr.backends[0].backend.SetAvail(false)
// after scale up 100, the hash result changed
expectResult = []string{"b3", "b3", "b3", "b3", "b3", "b3", "b3", "b3", "b3"}
// expectResult = []string{"b2", "b2", "b2", "b2", "b2", "b2", "b2", "b2", "b2"}
// expectResult = []string{"b2", "b2", "b2", "b2", "b2", "b2", "b2", "b2", "b2"}
processBalance(t, "case 6", WrrSticky, []byte{1}, rr, expectResult)

// case 7, lcw balance
Expand Down Expand Up @@ -363,3 +361,76 @@ func TestSlowStart(t *testing.T) {
rr := prepareBalanceRR()
rr.SetSlowStart(30)
}

func Test_leastConnsBalance(t *testing.T) {
b0_0 := &BackendRR{backend: backend.NewBfeBackend(), weight: 0}
b0_1 := &BackendRR{backend: backend.NewBfeBackend(), weight: 0}

b1_1 := &BackendRR{backend: backend.NewBfeBackend(), weight: 1}

b2_1 := &BackendRR{backend: backend.NewBfeBackend(), weight: 2}
b2_2 := &BackendRR{backend: backend.NewBfeBackend(), weight: 2}
b2_3 := &BackendRR{backend: backend.NewBfeBackend(), weight: 2}

b3_1 := &BackendRR{backend: backend.NewBfeBackend(), weight: 3}
b3_3 := &BackendRR{backend: backend.NewBfeBackend(), weight: 3}

b0_0.backend.Name = "b0_0"
b0_1.backend.Name = "b0_1"
b1_1.backend.Name = "b1_1"
b2_1.backend.Name = "b2_1"
b2_2.backend.Name = "b2_2"
b2_3.backend.Name = "b2_3"
b3_1.backend.Name = "b3_1"
b3_3.backend.Name = "b3_3"

b0_1.backend.IncConnNum()
b1_1.backend.IncConnNum()
b2_1.backend.IncConnNum()

b2_2.backend.IncConnNum()
b2_2.backend.IncConnNum()

b2_3.backend.IncConnNum()
b2_3.backend.IncConnNum()
b2_3.backend.IncConnNum()

b3_1.backend.IncConnNum()

b3_3.backend.IncConnNum()
b3_3.backend.IncConnNum()
b3_3.backend.IncConnNum()

for _, cas := range []struct {
name string
backends BackendList
wantCandidates []string
wantErr bool
}{
{name: "all down", backends: BackendList{b0_0, b0_1}, wantCandidates: nil, wantErr: true},
{name: "all same", backends: BackendList{b1_1, b2_2, b3_3}, wantCandidates: []string{"b1_1", "b2_2", "b3_3"}, wantErr: false},
{name: "incr1", backends: BackendList{b2_1, b2_2, b2_3}, wantCandidates: []string{"b2_1"}, wantErr: false},
{name: "desc1", backends: BackendList{b2_3, b2_2, b2_1}, wantCandidates: []string{"b2_1"}, wantErr: false},
{name: "incr2", backends: BackendList{b3_1, b2_1, b1_1}, wantCandidates: []string{"b3_1"}, wantErr: false},
{name: "desc2", backends: BackendList{b1_1, b2_1, b3_1}, wantCandidates: []string{"b3_1"}, wantErr: false},
{name: "just one", backends: BackendList{b2_1}, wantCandidates: []string{"b2_1"}, wantErr: false},
} {
got, err := leastConnsBalance(cas.backends)

if !cas.wantErr && err != nil {
t.Errorf("%s: leastConnsBalance() error = %v", cas.name, err)
}
if cas.wantErr {
continue
}

gotList := []string{}
for _, one := range got {
gotList = append(gotList, one.backend.Name)
}

if !reflect.DeepEqual(gotList, cas.wantCandidates) {
t.Errorf("%s: want: %v, got: %v", cas.name, cas.wantCandidates, gotList)
}
}
}
Loading