1
0
Fork 0
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.

165 lines
4.0 KiB
Go

package http
import (
"net/http"
"net/http/httptest"
"net/url"
"testing"
)
func TestClient_QueryWhenAllAvailable(t *testing.T) {
node1 := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
writer.WriteHeader(http.StatusOK)
}))
defer node1.Close()
node2 := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
writer.WriteHeader(http.StatusOK)
}))
defer node2.Close()
httpClient := http.DefaultClient
u1, _ := url.Parse(node1.URL)
u2, _ := url.Parse(node2.URL)
client := NewClient(httpClient, []string{u1.Host, u2.Host})
res, err := client.Query(url.URL{
Path: "/",
})
defer res.Body.Close()
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if client.currentHost != 0 {
t.Errorf("expected to only forward requests to the first host")
}
if res.StatusCode != http.StatusOK {
t.Errorf("unexpected status code, expected '200' got '%d'", res.StatusCode)
}
}
func TestClient_QueryWhenSomeAreAvailable(t *testing.T) {
node1 := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
writer.WriteHeader(http.StatusOK)
}))
node2 := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
writer.WriteHeader(http.StatusOK)
}))
defer node2.Close()
httpClient := http.DefaultClient
// Shutting down one of the hosts making it unavailable
node1.Close()
u1, _ := url.Parse(node1.URL)
u2, _ := url.Parse(node2.URL)
client := NewClient(httpClient, []string{u1.Host, u2.Host})
res, err := client.Query(url.URL{
Path: "/",
})
defer res.Body.Close()
// If the request succeeds after changing hosts, it should be reflected in the returned error
// as HostChangedError
if err == nil {
t.Errorf("expected HostChangedError got nil instead")
}
hcer, ok := err.(*HostChangedError)
if !ok {
t.Errorf("unexpected error occurred: %v", err)
}
if hcer.NewHost != u2.Host {
t.Errorf("unexpected responding host")
}
if client.currentHost != 1 {
t.Errorf("expected to move on to the following host")
}
if res.StatusCode != http.StatusOK {
t.Errorf("unexpected status code, expected '200' got '%d'", res.StatusCode)
}
}
func TestClient_QueryWhenAllUnavailable(t *testing.T) {
node1 := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
writer.WriteHeader(http.StatusOK)
}))
node2 := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
writer.WriteHeader(http.StatusOK)
}))
httpClient := http.DefaultClient
u1, _ := url.Parse(node1.URL)
u2, _ := url.Parse(node2.URL)
// Shutting down both nodes, both of them now are unavailable
node1.Close()
node2.Close()
client := NewClient(httpClient, []string{u1.Host, u2.Host})
_, err := client.Query(url.URL{
Path: "/",
})
if err != ErrNoAvailableHost {
t.Errorf("Expected %v, got: %v", ErrNoAvailableHost, err)
}
}
func TestClient_BasicAuthIsForwarded(t *testing.T) {
mockAuth := func(request *http.Request) bool {
user, pass, ok := request.BasicAuth()
if ok {
if user == "john" && pass == "doe" {
return true
}
}
return false
}
node1 := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
if mockAuth(request) {
writer.WriteHeader(http.StatusOK)
return
}
writer.WriteHeader(http.StatusUnauthorized)
}))
defer node1.Close()
node2 := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
if mockAuth(request) {
writer.WriteHeader(http.StatusOK)
return
}
writer.WriteHeader(http.StatusUnauthorized)
}))
defer node2.Close()
httpClient := http.DefaultClient
u1, _ := url.Parse(node1.URL)
u2, _ := url.Parse(node2.URL)
client := NewClient(httpClient, []string{u1.Host, u2.Host}, WithBasicAuth("john:wrongpassword"))
res, err := client.Query(url.URL{
Path: "/",
})
if err != nil {
t.Errorf("unexpected error")
}
if res.StatusCode != http.StatusUnauthorized {
t.Errorf("expected unauthorized status")
}
}