mirror of
https://github.com/hackdiaz-dev/free-turn-proxy.git
synced 2026-10-12 09:41:53 +02:00
131 lines
3.7 KiB
Go
131 lines
3.7 KiB
Go
package multi
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"testing"
|
|
|
|
"github.com/samosvalishe/free-turn-proxy/internal/provider"
|
|
)
|
|
|
|
// fakeProvider записывает streamID, с которыми его звали, и кодирует свой индекс
|
|
// в выданных Credentials - чтобы проверить и маршрут, и значение.
|
|
type fakeProvider struct {
|
|
idx int
|
|
backoff int64
|
|
gotCreds []int
|
|
gotHandle []int
|
|
gotReset []int
|
|
gotDrop []int
|
|
authResult bool
|
|
}
|
|
|
|
func (f *fakeProvider) GetCredentials(_ context.Context, streamID int) (provider.Credentials, error) {
|
|
f.gotCreds = append(f.gotCreds, streamID)
|
|
return provider.Credentials{User: fmt.Sprintf("p%d-s%d", f.idx, streamID)}, nil
|
|
}
|
|
func (f *fakeProvider) IsAuthError(error) bool { return f.authResult }
|
|
func (f *fakeProvider) HandleAuthError(s int) bool { f.gotHandle = append(f.gotHandle, s); return true }
|
|
func (f *fakeProvider) ResetErrors(s int) { f.gotReset = append(f.gotReset, s) }
|
|
func (f *fakeProvider) DropCredentials(s int) { f.gotDrop = append(f.gotDrop, s) }
|
|
func (f *fakeProvider) BackoffUntilUnix() int64 { return f.backoff }
|
|
func (f *fakeProvider) Name() string { return fmt.Sprintf("fake%d", f.idx) }
|
|
|
|
func newFakes(n int) ([]provider.Provider, []*fakeProvider) {
|
|
ps := make([]provider.Provider, n)
|
|
fs := make([]*fakeProvider, n)
|
|
for i := range ps {
|
|
f := &fakeProvider{idx: i}
|
|
ps[i], fs[i] = f, f
|
|
}
|
|
return ps, fs
|
|
}
|
|
|
|
func TestNewPanicsOnEmpty(t *testing.T) {
|
|
defer func() {
|
|
if recover() == nil {
|
|
t.Fatal("expected panic on empty providers")
|
|
}
|
|
}()
|
|
New(nil)
|
|
}
|
|
|
|
func TestGetCredentialsRoundRobin(t *testing.T) {
|
|
ps, fs := newFakes(3)
|
|
m := New(ps)
|
|
|
|
// 3 провайдера x 10 стримов = 30 глобальных streamID.
|
|
for sid := 1; sid <= 30; sid++ {
|
|
creds, err := m.GetCredentials(context.Background(), sid)
|
|
if err != nil {
|
|
t.Fatalf("streamID %d: %v", sid, err)
|
|
}
|
|
wantIdx := (sid - 1) % 3
|
|
wantInner := ((sid - 1) / 3) + 1
|
|
want := fmt.Sprintf("p%d-s%d", wantIdx, wantInner)
|
|
if creds.User != want {
|
|
t.Fatalf("streamID %d: got %q, want %q", sid, creds.User, want)
|
|
}
|
|
}
|
|
|
|
// Каждый провайдер получил ровно innerID 1..10.
|
|
for i, f := range fs {
|
|
if len(f.gotCreds) != 10 {
|
|
t.Fatalf("provider %d got %d calls, want 10", i, len(f.gotCreds))
|
|
}
|
|
for j, inner := range f.gotCreds {
|
|
if inner != j+1 {
|
|
t.Fatalf("provider %d call %d: innerID %d, want %d", i, j, inner, j+1)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestHandleAndResetRouting(t *testing.T) {
|
|
ps, fs := newFakes(2)
|
|
m := New(ps)
|
|
|
|
// streamID 5: idx=(5-1)%2=0, inner=(5-1)/2+1=3.
|
|
m.HandleAuthError(5)
|
|
m.ResetErrors(5)
|
|
if len(fs[0].gotHandle) != 1 || fs[0].gotHandle[0] != 3 {
|
|
t.Fatalf("HandleAuthError routed wrong: %v", fs[0].gotHandle)
|
|
}
|
|
if len(fs[0].gotReset) != 1 || fs[0].gotReset[0] != 3 {
|
|
t.Fatalf("ResetErrors routed wrong: %v", fs[0].gotReset)
|
|
}
|
|
m.DropCredentials(5)
|
|
if len(fs[0].gotDrop) != 1 || fs[0].gotDrop[0] != 3 {
|
|
t.Fatalf("DropCredentials routed wrong: %v", fs[0].gotDrop)
|
|
}
|
|
if len(fs[1].gotHandle) != 0 {
|
|
t.Fatalf("provider 1 should not be touched: %v", fs[1].gotHandle)
|
|
}
|
|
}
|
|
|
|
func TestBackoffUntilUnixMax(t *testing.T) {
|
|
ps, fs := newFakes(3)
|
|
fs[0].backoff = 100
|
|
fs[1].backoff = 500
|
|
fs[2].backoff = 300
|
|
if got := New(ps).BackoffUntilUnix(); got != 500 {
|
|
t.Fatalf("BackoffUntilUnix = %d, want 500 (max)", got)
|
|
}
|
|
}
|
|
|
|
func TestIsAuthErrorDelegatesToFirst(t *testing.T) {
|
|
ps, fs := newFakes(2)
|
|
fs[0].authResult = true
|
|
if !New(ps).IsAuthError(errors.New("x")) {
|
|
t.Fatal("IsAuthError should delegate to providers[0]")
|
|
}
|
|
}
|
|
|
|
func TestName(t *testing.T) {
|
|
ps, _ := newFakes(4)
|
|
if got := New(ps).Name(); got != "multi(4)" {
|
|
t.Fatalf("Name = %q, want multi(4)", got)
|
|
}
|
|
}
|