Skip to content

Commit

Permalink
Test all loadtest algorithms in healthy_endpoints_test.go
Browse files Browse the repository at this point in the history
Signed-off-by: Roman Zavodskikh <[email protected]>
  • Loading branch information
Roman Zavodskikh committed Mar 14, 2024
1 parent fd0f608 commit a5369e0
Showing 1 changed file with 120 additions and 102 deletions.
222 changes: 120 additions & 102 deletions proxy/healthy_endpoints_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,38 +29,42 @@ func defaultEndpointRegistry() *routing.EndpointRegistry {
}

func TestPHCWithoutRequests(t *testing.T) {
services := []*httptest.Server{}
for i := 0; i < 3; i++ {
service := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
}))
services = append(services, service)
defer service.Close()
for _, algorithm := range []string{"random", "consistentHash", "roundRobin", "powerOfRandomNChoices"} {
t.Run(algorithm, func(t *testing.T) {
services := []*httptest.Server{}
for i := 0; i < 3; i++ {
service := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
}))
services = append(services, service)
defer service.Close()
}
endpointRegistry := defaultEndpointRegistry()

doc := fmt.Sprintf(`* -> consistentHashKey("${request.header.ConsistentHashKey}") -> <%s, "%s", "%s", "%s">`, algorithm, services[0].URL, services[1].URL, services[2].URL)
tp, err := newTestProxyWithParams(doc, Params{
EnablePassiveHealthCheck: true,
EndpointRegistry: endpointRegistry,
})
if err != nil {
t.Fatal(err)
}
defer tp.close()

ps := httptest.NewServer(tp.proxy)
defer ps.Close()

rsp, err := ps.Client().Get(ps.URL)
if err != nil {
t.Fatal(err)
}
assert.Equal(t, http.StatusOK, rsp.StatusCode)
rsp.Body.Close()

time.Sleep(10 * period)
/* this test is needed to check PHC will not crash without requests sent during period at all */
})
}
endpointRegistry := defaultEndpointRegistry()

doc := fmt.Sprintf(`* -> <random, "%s", "%s", "%s">`, services[0].URL, services[1].URL, services[2].URL)
tp, err := newTestProxyWithParams(doc, Params{
EnablePassiveHealthCheck: true,
EndpointRegistry: endpointRegistry,
})
if err != nil {
t.Fatal(err)
}
defer tp.close()

ps := httptest.NewServer(tp.proxy)
defer ps.Close()

rsp, err := ps.Client().Get(ps.URL)
if err != nil {
t.Fatal(err)
}
assert.Equal(t, http.StatusOK, rsp.StatusCode)
rsp.Body.Close()

time.Sleep(10 * period)
/* this test is needed to check PHC will not crash without requests sent during period at all */
}

func TestPHCForSingleHealthyEndpoint(t *testing.T) {
Expand Down Expand Up @@ -99,42 +103,46 @@ func TestPHCForSingleHealthyEndpoint(t *testing.T) {
}

func TestPHCForMultipleHealthyEndpoints(t *testing.T) {
services := []*httptest.Server{}
for i := 0; i < 3; i++ {
service := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
}))
services = append(services, service)
defer service.Close()
for _, algorithm := range []string{"random", "consistentHash", "roundRobin", "powerOfRandomNChoices"} {
t.Run(algorithm, func(t *testing.T) {
services := []*httptest.Server{}
for i := 0; i < 3; i++ {
service := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
}))
services = append(services, service)
defer service.Close()
}
endpointRegistry := defaultEndpointRegistry()

doc := fmt.Sprintf(`* -> consistentHashKey("${request.header.ConsistentHashKey}") -> <%s, "%s", "%s", "%s">`, algorithm, services[0].URL, services[1].URL, services[2].URL)
tp, err := newTestProxyWithParams(doc, Params{
EnablePassiveHealthCheck: true,
EndpointRegistry: endpointRegistry,
})
if err != nil {
t.Fatal(err)
}
defer tp.close()

ps := httptest.NewServer(tp.proxy)
defer ps.Close()

failedReqs := 0
for i := 0; i < nRequests; i++ {
rsp, err := ps.Client().Get(ps.URL)
if err != nil {
t.Fatal(err)
}

if rsp.StatusCode != http.StatusOK {
failedReqs++
}
rsp.Body.Close()
}
assert.Equal(t, 0, failedReqs)
})
}
endpointRegistry := defaultEndpointRegistry()

doc := fmt.Sprintf(`* -> <random, "%s", "%s", "%s">`, services[0].URL, services[1].URL, services[2].URL)
tp, err := newTestProxyWithParams(doc, Params{
EnablePassiveHealthCheck: true,
EndpointRegistry: endpointRegistry,
})
if err != nil {
t.Fatal(err)
}
defer tp.close()

ps := httptest.NewServer(tp.proxy)
defer ps.Close()

failedReqs := 0
for i := 0; i < nRequests; i++ {
rsp, err := ps.Client().Get(ps.URL)
if err != nil {
t.Fatal(err)
}

if rsp.StatusCode != http.StatusOK {
failedReqs++
}
rsp.Body.Close()
}
assert.Equal(t, 0, failedReqs)
}

type roundTripperUnhealthyHost struct {
Expand Down Expand Up @@ -165,41 +173,51 @@ func newRoundTripperUnhealthyHost(o *RoundTripperUnhealthyHostOptions) func(r ht
}

func TestPHCForMultipleHealthyAndOneUnhealthyEndpoints(t *testing.T) {
services := []*httptest.Server{}
for i := 0; i < 3; i++ {
service := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
}))
services = append(services, service)
defer service.Close()
}
endpointRegistry := defaultEndpointRegistry()

doc := fmt.Sprintf(`* -> <random, "%s", "%s", "%s">`, services[0].URL, services[1].URL, services[2].URL)
tp, err := newTestProxyWithParams(doc, Params{
EnablePassiveHealthCheck: true,
EndpointRegistry: endpointRegistry,
CustomHttpRoundTripperWrap: newRoundTripperUnhealthyHost(&RoundTripperUnhealthyHostOptions{Host: services[0].URL[7:], Probability: rtFailureProbability}),
})
if err != nil {
t.Fatal(err)
}
defer tp.close()

ps := httptest.NewServer(tp.proxy)
defer ps.Close()

failedReqs := 0
for i := 0; i < nRequests; i++ {
rsp, err := ps.Client().Get(ps.URL)
if err != nil {
t.Fatal(err)
}

if rsp.StatusCode != http.StatusOK {
failedReqs++
}
rsp.Body.Close()
for _, algorithm := range []string{"random", "consistentHash", "roundRobin", "powerOfRandomNChoices"} {
t.Run(algorithm, func(t *testing.T) {
services := []*httptest.Server{}
for i := 0; i < 3; i++ {
service := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
}))
services = append(services, service)
defer service.Close()
}
endpointRegistry := defaultEndpointRegistry()

doc := fmt.Sprintf(`* -> consistentHashKey("${request.header.ConsistentHashKey}") -> <%s, "%s", "%s", "%s">`, algorithm, services[0].URL, services[1].URL, services[2].URL)
tp, err := newTestProxyWithParams(doc, Params{
EnablePassiveHealthCheck: true,
EndpointRegistry: endpointRegistry,
CustomHttpRoundTripperWrap: newRoundTripperUnhealthyHost(&RoundTripperUnhealthyHostOptions{Host: services[0].URL[7:], Probability: rtFailureProbability}),
})
if err != nil {
t.Fatal(err)
}
defer tp.close()

ps := httptest.NewServer(tp.proxy)
defer ps.Close()

failedReqs := 0
for i := 0; i < nRequests; i++ {
req, err := http.NewRequest("GET", ps.URL, nil)
if err != nil {
t.Fatal(err)
}
req.Header.Add("ConsistentHashKey", fmt.Sprintf("%+v", i))

rsp, err := ps.Client().Do(req)
if err != nil {
t.Fatal(err)
}

if rsp.StatusCode != http.StatusOK {
failedReqs++
}
rsp.Body.Close()
}
assert.InDelta(t, 0.33*rtFailureProbability*(1.0-rtFailureProbability)*float64(nRequests), failedReqs, 0.1*float64(nRequests))
})
}
assert.InDelta(t, 0.33*rtFailureProbability*(1.0-rtFailureProbability)*float64(nRequests), failedReqs, 0.1*float64(nRequests))
}

0 comments on commit a5369e0

Please sign in to comment.