mirror of
https://github.com/kemko/reproxy.git
synced 2026-01-01 15:55:49 +03:00
unittest, typos
This commit is contained in:
committed by
Umputun
parent
973d6c9a14
commit
7bbb7073ba
@@ -151,7 +151,7 @@ func (s *Service) Match(srv, src string) (string, MatchType, bool) {
|
||||
|
||||
// ScheduleHealthCheck starts background loop with health-check
|
||||
func (s *Service) ScheduleHealthCheck(ctx context.Context, interval time.Duration) {
|
||||
log.Printf("health-check scheduled every %s seconds", interval)
|
||||
log.Printf("health-check scheduled every %s", interval)
|
||||
|
||||
go func() {
|
||||
hloop:
|
||||
@@ -163,6 +163,7 @@ func (s *Service) ScheduleHealthCheck(ctx context.Context, interval time.Duratio
|
||||
cres := CheckHealth(s.Mappers())
|
||||
s.lock.RUnlock()
|
||||
|
||||
// alive services would be picked up first
|
||||
sort.SliceStable(cres.mappers, func(i, j int) bool {
|
||||
return cres.mappers[j].dead
|
||||
})
|
||||
|
||||
@@ -3,6 +3,10 @@ package discovery
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"testing"
|
||||
@@ -223,3 +227,53 @@ func TestService_extendRule(t *testing.T) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestService_ScheduleHealthCheck(t *testing.T) {
|
||||
randomPort := rand.Intn(10000) + 40000
|
||||
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte("OK"))
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
ts2 := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte("OK"))
|
||||
}))
|
||||
defer ts2.Close()
|
||||
|
||||
wantMappers := []URLMapper{
|
||||
{SrcMatch: *regexp.MustCompile("/api/svc3/xyz"), Dst: "http://127.0.0.3:8080/blah3/xyz", ProviderID: PIDocker, PingURL: ts.URL},
|
||||
{SrcMatch: *regexp.MustCompile("/api/svc3/xyz"), Dst: "http://127.0.0.3:8080/blah3/xyz", ProviderID: PIDocker, PingURL: fmt.Sprintf("127.0.0.1:%d", randomPort)},
|
||||
{SrcMatch: *regexp.MustCompile("/api/svc3/xyz"), Dst: "http://127.0.0.3:8080/blah3/xyz", ProviderID: PIDocker, PingURL: ts2.URL},
|
||||
}
|
||||
|
||||
p := &ProviderMock{
|
||||
EventsFunc: func(ctx context.Context) <-chan ProviderID {
|
||||
res := make(chan ProviderID, 1)
|
||||
res <- PIFile
|
||||
return res
|
||||
},
|
||||
ListFunc: func() ([]URLMapper, error) {
|
||||
return wantMappers, nil
|
||||
},
|
||||
}
|
||||
|
||||
svc := NewService([]Provider{p}, time.Millisecond*10)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
|
||||
defer cancel()
|
||||
|
||||
err := svc.Run(ctx)
|
||||
require.Error(t, err)
|
||||
assert.Equal(t, context.DeadlineExceeded, err)
|
||||
mappers := svc.Mappers()
|
||||
assert.Equal(t, 3, len(mappers))
|
||||
assert.Equal(t, wantMappers, mappers)
|
||||
|
||||
svc.ScheduleHealthCheck(context.Background(), time.Microsecond*2)
|
||||
time.Sleep(time.Millisecond * 10)
|
||||
|
||||
mappers = svc.Mappers()
|
||||
assert.Equal(t, false, mappers[0].dead)
|
||||
assert.Equal(t, false, mappers[1].dead)
|
||||
assert.Equal(t, true, mappers[2].dead)
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// CheckResult is result of health-check
|
||||
type CheckResult struct {
|
||||
Ok bool
|
||||
Valid int
|
||||
@@ -17,6 +18,7 @@ type CheckResult struct {
|
||||
mappers []URLMapper
|
||||
}
|
||||
|
||||
// CheckHealth starts health-check for service's mappers
|
||||
func CheckHealth(mappers []URLMapper) CheckResult {
|
||||
const concurrent = 8
|
||||
sema := make(chan struct{}, concurrent) // limit health check to 8 concurrent calls
|
||||
|
||||
@@ -1 +1,86 @@
|
||||
package discovery
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_ping(t *testing.T) {
|
||||
port := rand.Intn(10000) + 40000
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte("OK"))
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
ts2 := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(500)
|
||||
}))
|
||||
defer ts2.Close()
|
||||
|
||||
type args struct {
|
||||
m URLMapper
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want string
|
||||
wantErr bool
|
||||
}{
|
||||
{name: "test server, expected OK", args: args{m: URLMapper{PingURL: ts.URL}}, want: "", wantErr: false},
|
||||
{name: "random port, expected error", args: args{m: URLMapper{PingURL: fmt.Sprintf("127.0.0.1:%d", port)}}, want: "", wantErr: true},
|
||||
{name: "error code != 200", args: args{m: URLMapper{PingURL: ts2.URL}}, want: "", wantErr: true},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
_, err := ping(tt.args.m)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("ping() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckHealth(t *testing.T) {
|
||||
port := rand.Intn(10000) + 40000
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte("OK"))
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
ts2 := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte("OK"))
|
||||
}))
|
||||
defer ts2.Close()
|
||||
|
||||
type args struct {
|
||||
mappers []URLMapper
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want CheckResult
|
||||
}{
|
||||
{name: "case 1", args: args{mappers: []URLMapper{{PingURL: ts.URL}, {PingURL: ts2.URL}, {PingURL: fmt.Sprintf("127.0.0.1:%d", port)}}},
|
||||
want: CheckResult{Ok: false, Total: 3, Valid: 2, mappers: []URLMapper{{PingURL: ts.URL, dead: false}, {PingURL: ts2.URL, dead: false},
|
||||
{PingURL: fmt.Sprintf("127.0.0.1:%d", port), dead: true}}}},
|
||||
{name: "case 2", args: args{mappers: []URLMapper{{PingURL: ts.URL}, {PingURL: ts2.URL}}},
|
||||
want: CheckResult{Ok: true, Total: 2, Valid: 2, mappers: []URLMapper{{PingURL: ts.URL, dead: false}, {PingURL: ts2.URL, dead: false}}}},
|
||||
{name: "case 3", args: args{mappers: []URLMapper{{PingURL: ts.URL, MatchType: MTStatic}, {PingURL: ts2.URL}}},
|
||||
want: CheckResult{Ok: true, Total: 1, Valid: 1, mappers: []URLMapper{{PingURL: ts.URL, dead: false}, {PingURL: ts2.URL, dead: false}}}},
|
||||
{name: "case 4", args: args{mappers: []URLMapper{{}, {PingURL: ts2.URL}}},
|
||||
want: CheckResult{Ok: true, Total: 2, Valid: 1, mappers: []URLMapper{{PingURL: ts.URL, dead: false}, {PingURL: ts2.URL, dead: true}}}},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := CheckHealth(tt.args.mappers)
|
||||
got.Errs = got.Errs[:0]
|
||||
if got.Ok != tt.want.Ok || got.Total != tt.want.Total || got.Valid != tt.want.Valid {
|
||||
t.Errorf("CheckHealth() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user