You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
211 lines
4.7 KiB
Go
211 lines
4.7 KiB
Go
package cluster
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"io"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"reflect"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func Test_AddressProviderString(t *testing.T) {
|
|
a := []string{"a", "b", "c"}
|
|
p := NewAddressProviderString(a)
|
|
b, err := p.Lookup()
|
|
if err != nil {
|
|
t.Fatalf("failed to lookup addresses: %s", err.Error())
|
|
}
|
|
if !reflect.DeepEqual(a, b) {
|
|
t.Fatalf("failed to get correct addresses")
|
|
}
|
|
}
|
|
|
|
func Test_NewBootstrapper(t *testing.T) {
|
|
bs := NewBootstrapper(nil, 1, nil)
|
|
if bs == nil {
|
|
t.Fatalf("failed to create a simple Bootstrapper")
|
|
}
|
|
}
|
|
|
|
func Test_BootstrapperBootDoneImmediately(t *testing.T) {
|
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
t.Fatalf("client made HTTP request")
|
|
}))
|
|
|
|
done := func() bool {
|
|
return true
|
|
}
|
|
p := NewAddressProviderString([]string{ts.URL})
|
|
bs := NewBootstrapper(p, 1, nil)
|
|
if err := bs.Boot("node1", "192.168.1.1:1234", done, 10*time.Second); err != nil {
|
|
t.Fatalf("failed to boot: %s", err)
|
|
}
|
|
}
|
|
|
|
func Test_BootstrapperBootTimeout(t *testing.T) {
|
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.WriteHeader(http.StatusServiceUnavailable)
|
|
}))
|
|
|
|
done := func() bool {
|
|
return false
|
|
}
|
|
p := NewAddressProviderString([]string{ts.URL})
|
|
bs := NewBootstrapper(p, 1, nil)
|
|
bs.Interval = time.Second
|
|
err := bs.Boot("node1", "192.168.1.1:1234", done, 5*time.Second)
|
|
if err == nil {
|
|
t.Fatalf("no error returned from timed-out boot")
|
|
}
|
|
if !errors.Is(err, ErrBootTimeout) {
|
|
t.Fatalf("wrong error returned")
|
|
}
|
|
}
|
|
|
|
func Test_BootstrapperBootSingleNotify(t *testing.T) {
|
|
tsNotified := false
|
|
var body map[string]string
|
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if r.URL.Path == "/join" {
|
|
w.WriteHeader(http.StatusServiceUnavailable)
|
|
return
|
|
}
|
|
|
|
tsNotified = true
|
|
b, err := io.ReadAll(r.Body)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
if err := json.Unmarshal(b, &body); err != nil {
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
return
|
|
}
|
|
}))
|
|
|
|
n := -1
|
|
done := func() bool {
|
|
n++
|
|
if n == 5 {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
p := NewAddressProviderString([]string{ts.URL})
|
|
bs := NewBootstrapper(p, 1, nil)
|
|
bs.Interval = time.Second
|
|
|
|
err := bs.Boot("node1", "192.168.1.1:1234", done, 60*time.Second)
|
|
if err != nil {
|
|
t.Fatalf("failed to boot: %s", err)
|
|
}
|
|
|
|
if tsNotified != true {
|
|
t.Fatalf("notify target not contacted")
|
|
}
|
|
|
|
if got, exp := body["id"], "node1"; got != exp {
|
|
t.Fatalf("wrong node ID supplied, exp %s, got %s", exp, got)
|
|
}
|
|
if got, exp := body["addr"], "192.168.1.1:1234"; got != exp {
|
|
t.Fatalf("wrong address supplied, exp %s, got %s", exp, got)
|
|
}
|
|
}
|
|
|
|
func Test_BootstrapperBootSingleNotifyAuth(t *testing.T) {
|
|
tsNotified := false
|
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
username, password, ok := r.BasicAuth()
|
|
if !ok {
|
|
t.Fatalf("request did not have Basic Auth credentials")
|
|
}
|
|
if username != "username1" || password != "password1" {
|
|
t.Fatalf("bad Basic Auth credentials received (%s, %s", username, password)
|
|
}
|
|
|
|
if r.URL.Path == "/join" {
|
|
w.WriteHeader(http.StatusServiceUnavailable)
|
|
return
|
|
}
|
|
tsNotified = true
|
|
}))
|
|
|
|
n := -1
|
|
done := func() bool {
|
|
n++
|
|
if n == 5 {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
p := NewAddressProviderString([]string{ts.URL})
|
|
bs := NewBootstrapper(p, 1, nil)
|
|
bs.SetBasicAuth("username1", "password1")
|
|
bs.Interval = time.Second
|
|
|
|
err := bs.Boot("node1", "192.168.1.1:1234", done, 60*time.Second)
|
|
if err != nil {
|
|
t.Fatalf("failed to boot: %s", err)
|
|
}
|
|
|
|
if tsNotified != true {
|
|
t.Fatalf("notify target not contacted")
|
|
}
|
|
}
|
|
|
|
func Test_BootstrapperBootMultiNotify(t *testing.T) {
|
|
ts1Join := false
|
|
ts1Notified := false
|
|
ts1 := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if r.URL.Path == "/join" {
|
|
ts1Join = true
|
|
w.WriteHeader(http.StatusServiceUnavailable)
|
|
return
|
|
}
|
|
ts1Notified = true
|
|
}))
|
|
|
|
ts2Join := false
|
|
ts2Notified := false
|
|
ts2 := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if r.URL.Path == "/join" {
|
|
ts2Join = true
|
|
w.WriteHeader(http.StatusServiceUnavailable)
|
|
return
|
|
}
|
|
ts2Notified = true
|
|
}))
|
|
|
|
n := -1
|
|
done := func() bool {
|
|
n++
|
|
if n == 5 {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
p := NewAddressProviderString([]string{ts1.URL, ts2.URL})
|
|
bs := NewBootstrapper(p, 2, nil)
|
|
bs.Interval = time.Second
|
|
|
|
err := bs.Boot("node1", "192.168.1.1:1234", done, 60*time.Second)
|
|
if err != nil {
|
|
t.Fatalf("failed to boot: %s", err)
|
|
}
|
|
|
|
if ts1Join != true || ts2Join != true {
|
|
t.Fatalf("all join targets not contacted")
|
|
}
|
|
|
|
if ts1Notified != true || ts2Notified != true {
|
|
t.Fatalf("all notify targets not contacted")
|
|
}
|
|
}
|