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
165 lines
4.0 KiB
Go
3 years ago
|
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")
|
||
|
}
|
||
|
}
|