Esempio n. 1
0
func TestNextCost(t *testing.T) {
	pool := NewPool("test", newTestConfig())
	defer pool.Shutdown()

	backend0 := testutils.NewBackend(0, false)
	defer backend0.Shutdown()

	backend1 := testutils.NewBackend(0, false)
	defer backend1.Shutdown()

	pool.AddServer(backend0.Address(), NewServer(backend0.Address()))
	pool.AddServer(backend1.Address(), NewServer(backend1.Address()))
	time.Sleep(50 * time.Millisecond)

	for _, server := range pool.Servers {
		if server.Address == backend0.Address() {
			// leaving a request open for this effect
			// will add to test times
			server.Metrics.RequestStart()
		}
	}

	if pool.Next().Address != backend1.Address() {
		t.Errorf("should return server with least cost")
	}
}
Esempio n. 2
0
func TestParseAndSet(t *testing.T) {
	status := NewServerStatus()

	backend := testutils.NewBackend(0, false)
	defer backend.Shutdown()

	client := &http.Client{}
	req, _ := http.NewRequest("GET", backend.URL()+"/healthz", nil)

	backend.SetStatus(http.StatusOK, "DEGRADED")
	res, _ := client.Do(req)

	status.ParseAndSet(res)
	if status.Current != StatusDegraded {
		t.Errorf("should set status to degraded from header")
	}

	backend.SetStatus(http.StatusOK, "MAINTENANCE")
	res, _ = client.Do(req)

	status.ParseAndSet(res)
	if status.Current != StatusMaintenance {
		t.Errorf("should set status to maintenance from header")
	}
}
Esempio n. 3
0
func TestRoundTripServerError(t *testing.T) {
	backend := testutils.NewBackend(0, false)
	backend.SetResponse(http.StatusInternalServerError, "No shit, Sherlock!")
	defer backend.Shutdown()

	server := NewServer(backend.Address())
	req, _ := http.NewRequest("GET", backend.URL(), nil)

	resErrCh := make(chan ResponseError)
	go server.RoundTrip(req, resErrCh)

	resErr := <-resErrCh
	if resErr.Error != nil {
		// transport must not care about server's response
		// as long as there are no connection errors
		t.Errorf("should report no error")
	}

	body, _ := ioutil.ReadAll(resErr.Response.Body)
	if string(body) != "No shit, Sherlock!" {
		t.Errorf("should return server's response")
	}

	return
}
Esempio n. 4
0
func TestRunChecks(t *testing.T) {
	conf := newTestConfig()

	pool := NewPool("test", conf)
	defer pool.Shutdown()

	backend := testutils.NewBackend(0, false)
	defer backend.Shutdown()

	backend.SetStatus(http.StatusOK, "MAINTENANCE")
	pool.AddServer(backend.Address(), NewServer(backend.Address()))

	time.Sleep(50 * time.Millisecond)
	if pool.Servers[backend.Address()].Status.Current != StatusMaintenance {
		t.Errorf("should poll for server health")
	}

	conf = PoolConfig{
		HealthzEvery:   2 * time.Second,
		HealthzTimeout: 1 * time.Second,
	}
	pool.Reconfigure(conf)
	time.Sleep(50 * time.Millisecond)

	backend.SetStatus(http.StatusOK, "OK")
	if pool.Servers[backend.Address()].Status.Current != StatusMaintenance {
		t.Errorf("should update check interval")
	}
}
Esempio n. 5
0
func TestCheckStatusTimeout(t *testing.T) {
	backend := testutils.NewBackend(100, false)
	defer backend.Shutdown()

	server := NewServer(backend.Address())
	server.CheckStatus(10 * time.Millisecond)
	if server.Status.Current != StatusCritical {
		t.Errorf("should set status to critical on timeout")
	}
}
Esempio n. 6
0
func TestHandleResponseHeaders(t *testing.T) {
	backend := testutils.NewBackend(0, false)
	defer backend.Shutdown()

	server := NewServer(backend.Address())
	logRecord, _ := testutils.NewTestHAProxyLogRecord(backend.URL() + "/healthz")
	server.Handle(logRecord, 100*time.Millisecond)

	if logRecord.GetResponseHeaders()["Server-Status"][0] != "OK" {
		t.Errorf("should copy response headers")
	}
}
Esempio n. 7
0
func TestNextMaintenance(t *testing.T) {
	pool := NewPool("test", newTestConfig())
	defer pool.Shutdown()

	backend0 := testutils.NewBackend(0, false)
	defer backend0.Shutdown()

	backend1 := testutils.NewBackend(0, false)
	defer backend0.Shutdown()

	backend0.SetStatus(http.StatusOK, "MAINTENANCE")
	backend1.SetStatus(http.StatusOK, "MAINTENANCE")

	pool.AddServer(backend0.Address(), NewServer(backend0.Address()))
	pool.AddServer(backend1.Address(), NewServer(backend1.Address()))
	time.Sleep(50 * time.Millisecond)

	if pool.Next() != nil {
		t.Errorf("should never return server under maintenance")
	}
}
Esempio n. 8
0
func TestHandleXForwardedFor(t *testing.T) {
	backend := testutils.NewBackend(0, false)
	defer backend.Shutdown()

	server := NewServer(backend.Address())
	logRecord, _ := testutils.NewTestHAProxyLogRecord(backend.URL())
	server.Handle(logRecord, 100*time.Millisecond)

	elm := backend.Handler.Recorded.Front()
	rec := elm.Value.(testutils.RequestAndTime).R
	if rec.Header["X-Forwarded-For"] == nil {
		t.Errorf("should set x-forwarded-for")
	}
}
Esempio n. 9
0
func TestHandleResponse(t *testing.T) {
	backend := testutils.NewBackend(0, false)
	backend.SetResponse(http.StatusOK, "The eagle has landed.")
	defer backend.Shutdown()

	server := NewServer(backend.Address())
	logRecord, rr := testutils.NewTestHAProxyLogRecord(backend.URL())
	server.Handle(logRecord, 100*time.Millisecond)

	if logRecord.GetResponseStatusCode() != http.StatusOK {
		t.Errorf("should set status code")
	}
	body, _ := ioutil.ReadAll(rr.Body)
	if string(body) != "The eagle has landed." {
		t.Errorf("should set response body")
	}
}
Esempio n. 10
0
func TestHandleTimeout(t *testing.T) {
	backend := testutils.NewBackend(100, false)
	backend.SetResponse(http.StatusOK, "Ba-ba-ba-ba-ba-na-na!")
	defer backend.Shutdown()

	server := NewServer(backend.Address())
	logRecord, rr := testutils.NewTestHAProxyLogRecord(backend.URL())
	server.Handle(logRecord, 10*time.Millisecond)

	if logRecord.GetResponseStatusCode() != http.StatusGatewayTimeout ||
		rr.Code != http.StatusGatewayTimeout {
		t.Errorf("should report status code 502")
	}

	body, _ := ioutil.ReadAll(rr.Body)
	if string(body) != "Gateway Timeout\n" {
		t.Errorf("should report 'Gateway Timeout'")
	}
}
Esempio n. 11
0
func TestRoundTripServerOk(t *testing.T) {
	backend := testutils.NewBackend(0, false)
	defer backend.Shutdown()

	server := NewServer(backend.Address())
	req, _ := http.NewRequest("GET", backend.URL(), nil)

	resErrCh := make(chan ResponseError)
	go server.RoundTrip(req, resErrCh)

	resErr := <-resErrCh
	if resErr.Error != nil {
		t.Errorf("should report no error")
	}

	body, _ := ioutil.ReadAll(resErr.Response.Body)
	if string(body) != "testutils backend" {
		t.Errorf("should return server's response")
	}

	return
}
Esempio n. 12
0
func TestHandle(t *testing.T) {
	pool := NewPool("test", newTestConfig())
	defer pool.Shutdown()

	backend := testutils.NewBackend(0, false)
	defer backend.Shutdown()

	backend.SetResponse(http.StatusOK, "Mickey Mouse!")

	pool.AddServer(backend.Address(), NewServer(backend.Address()))
	time.Sleep(50 * time.Millisecond)

	logRecord, rr := testutils.NewTestHAProxyLogRecord(backend.URL())
	pool.Handle(logRecord)

	body, _ := ioutil.ReadAll(rr.Body)
	if logRecord.GetResponseStatusCode() != http.StatusOK || rr.Code != http.StatusOK ||
		string(body) != "Mickey Mouse!" {
		t.Errorf("should forward requests to backend")
		t.Errorf("%d | %d | %s", logRecord.GetResponseStatusCode, rr.Code, string(body))
	}
}
Esempio n. 13
0
func TestCheckStatus(t *testing.T) {
	backend := testutils.NewBackend(0, false)
	defer backend.Shutdown()

	server := NewServer(backend.Address())
	backend.SetStatus(http.StatusInternalServerError, "UNKNOWN")
	server.CheckStatus(100 * time.Millisecond)
	if server.Status.Current != StatusUnknown {
		t.Errorf("should set status to unknown")
	}

	backend.SetStatus(http.StatusOK, "MainTENANCE")
	server.CheckStatus(100 * time.Millisecond)
	if server.Status.Current != StatusMaintenance {
		t.Errorf("should set status to maintenance")
	}

	backend.SetStatus(http.StatusOK, "DEGRADED")
	server.CheckStatus(100 * time.Millisecond)
	if server.Status.Current != StatusDegraded {
		t.Errorf("should parse response headers on 200s")
	}
}