func TestCallPrimaryUnreachableWithHealthChecks(t *testing.T) {
	var alreadyRetried bool
	httpClient := NewTestHttpClient(func(req *http.Request) (*http.Response, error) {
		if req.Host == "primary1.foo" {
			if !alreadyRetried {
				if req.URL.Path == "/healthcheck" {
					return buildResponse(http.StatusOK, ""), nil
				}
				alreadyRetried = true
			}
			return nil, errors.New("Unreachable")
		}
		if req.Host == "secondary1.foo" {
			if req.URL.Path == "/healthcheck" {
				return buildResponse(http.StatusOK, ""), nil
			}
			return &http.Response{
				StatusCode: http.StatusOK,
				Body:       ioutil.NopCloser(bytes.NewBufferString("OK")),
				Header:     make(http.Header),
			}, nil
		}
		return nil, errors.New("Unreachable")
	})
	client, err := NewHTTPClient(
		SetHttpClient(httpClient),
		SetAPIKey("my-awesome-api-key"),
		SetURLs("http://primary1.foo", "http://secondary1.foo"),
		SetReadPreference(PrimaryPreferred),
		SetMaxRetries(0),
		SetTopologyDiscovery(false),
		SetHealthChecks(true),
	)
	require.NoError(t, err)
	resp, err := client.callPrimary("GET", "/test", nil)
	require.Error(t, err, "The requests should fail")
	require.True(t, len(resp) == 0, "The response should be empty")
}
Having 2 nodes with the primary being unreachable, and there is no
"discovery" option enabled, the request fails.
Healthchecks (enabled here) does not change primary.
package client
import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"net/url"
	"os"
	"strings"
	"testing"
	"time"
	"github.com/stretchr/testify/require"
	"github.com/bbva/qed/balloon"
	"github.com/bbva/qed/crypto/hashing"
	"github.com/bbva/qed/log"
	"github.com/bbva/qed/testutils/spec"
	"github.com/pkg/errors"
	"github.com/bbva/qed/protocol"
	"github.com/stretchr/testify/assert"
)
func TestMain(m *testing.M) {
	log.SetDefault(log.New(&log.LoggerOptions{
		IncludeLocation: true,
		Level:           log.Off,
	}))
	os.Exit(m.Run())
}
func setupServer(input []byte) (string, func()) {
	mux := http.NewServeMux()
	server := httptest.NewServer(mux)
	mux.HandleFunc("/info/shards", infoHandler(server.URL))
	mux.HandleFunc("/events", defaultHandler(input))
	mux.HandleFunc("/events/bulk", defaultHandler(input))
	mux.HandleFunc("/proofs/membership", defaultHandler(input))
	mux.HandleFunc("/proofs/incremental", defaultHandler(input))
	mux.HandleFunc("/proofs/digest-membership", defaultHandler(input))
	mux.HandleFunc("/healthcheck", defaultHandler(nil))
	return server.URL, func() {
		server.Close()
	}
}
func setupClient(t *testing.T, urls []string) *HTTPClient {
	httpClient := http.DefaultClient
	client, err := NewHTTPClient(
		SetHttpClient(httpClient),
		SetAPIKey("my-awesome-api-key"),
		SetURLs(urls[0], urls[1:]...),
		SetRequestRetrier(NewNoRequestRetrier(httpClient)),
		SetReadPreference(Primary),
		SetMaxRetries(0),
		SetTopologyDiscovery(false),
		SetHealthChecks(false),
		SetHasherFunction(hashing.NewSha256Hasher),
	)
	if err != nil {
		t.Fatal(errors.Wrap(err, "Cannot create http client: "))
	}
	return client
}
func TestCallPrimaryWorking(t *testing.T) {
	var numRequests int
	httpClient := NewTestHttpClient(func(req *http.Request) (*http.Response, error) {
		numRequests++
		return &http.Response{
			StatusCode: http.StatusOK,
			Body:       ioutil.NopCloser(bytes.NewBufferString("OK")),
			Header:     make(http.Header),
		}, nil
	})
	client, err := NewHTTPClient(
		SetHttpClient(httpClient),
		SetAPIKey("my-awesome-api-key"),
		SetURLs("http://primary.foo"),
		SetReadPreference(PrimaryPreferred),
		SetMaxRetries(1),
		SetTopologyDiscovery(false),
		SetHealthChecks(false),
	)
	require.NoError(t, err)
	resp, err := client.callPrimary("GET", "/test", nil)
	require.NoError(t, err, "The requests should not fail")
	require.True(t, len(resp) > 0, "The response should not be empty")
	require.Equal(t, 1, numRequests, "The number of requests should match")
}
func TestCallPrimaryFails(t *testing.T) {
	var numRequests int
	httpClient := NewTestHttpClient(func(req *http.Request) (*http.Response, error) {
		numRequests++
		return &http.Response{
			StatusCode: http.StatusInternalServerError,
			Body:       ioutil.NopCloser(bytes.NewBufferString("Internal server error")),
			Header:     make(http.Header),
		}, nil
	})
	client, err := NewHTTPClient(
		SetHttpClient(httpClient),
		SetAPIKey("my-awesome-api-key"),
		SetURLs("http://primary.foo", "http://secondary1.foo"),
		SetReadPreference(PrimaryPreferred),
		SetMaxRetries(1),
		SetTopologyDiscovery(false),
		SetHealthChecks(false),
	)
	require.NoError(t, err)
	resp, err := client.callPrimary("GET", "/test", nil)
	require.Error(t, err, "The requests should fail")
	require.True(t, len(resp) == 0, "The response should be empty")
	require.Equal(t, 2, numRequests, "The number of requests should match")
}
func TestCallPrimaryUnreachable(t *testing.T) {
	var numRequests int
	httpClient := NewTestHttpClient(func(req *http.Request) (*http.Response, error) {
		numRequests++
		return nil, errors.New("Unreachable")
	})
	client, err := NewHTTPClient(
		SetHttpClient(httpClient),
		SetAPIKey("my-awesome-api-key"),
		SetURLs("http://primary.foo", "http://secondary1.foo"),
		SetReadPreference(PrimaryPreferred),
		SetMaxRetries(0),
		SetTopologyDiscovery(false),
		SetHealthChecks(false),
	)
	require.NoError(t, err)
	resp, err := client.callPrimary("GET", "/test", nil)
	require.Error(t, err, "The requests should fail")
	require.True(t, len(resp) == 0, "The response should be empty")
	require.Equal(t, 1, numRequests, "The number of requests should match")
}