mirror of https://github.com/grafana/grafana
parent
35013a28cd
commit
364154d81f
@ -0,0 +1,148 @@ |
|||||||
|
// +build integration
|
||||||
|
|
||||||
|
package alerting |
||||||
|
|
||||||
|
import ( |
||||||
|
"context" |
||||||
|
"errors" |
||||||
|
"net" |
||||||
|
"net/http" |
||||||
|
"net/http/httptest" |
||||||
|
"testing" |
||||||
|
"time" |
||||||
|
|
||||||
|
. "github.com/smartystreets/goconvey/convey" |
||||||
|
) |
||||||
|
|
||||||
|
func TestEngineTimeouts(t *testing.T) { |
||||||
|
Convey("Alerting engine timeout tests", t, func() { |
||||||
|
engine := NewEngine() |
||||||
|
engine.resultHandler = &FakeResultHandler{} |
||||||
|
job := &Job{Running: true, Rule: &Rule{}} |
||||||
|
|
||||||
|
Convey("Should trigger as many retries as needed", func() { |
||||||
|
Convey("pended alert for datasource -> result handler should be worked", func() { |
||||||
|
// reduce alert timeout to test quickly
|
||||||
|
originAlertTimeout := alertTimeout |
||||||
|
alertTimeout = 2 * time.Second |
||||||
|
transportTimeoutInterval := 2 * time.Second |
||||||
|
serverBusySleepDuration := 1 * time.Second |
||||||
|
|
||||||
|
evalHandler := NewFakeCommonTimeoutHandler(transportTimeoutInterval, serverBusySleepDuration) |
||||||
|
resultHandler := NewFakeCommonTimeoutHandler(transportTimeoutInterval, serverBusySleepDuration) |
||||||
|
engine.evalHandler = evalHandler |
||||||
|
engine.resultHandler = resultHandler |
||||||
|
|
||||||
|
engine.processJobWithRetry(context.TODO(), job) |
||||||
|
|
||||||
|
So(evalHandler.EvalSucceed, ShouldEqual, true) |
||||||
|
So(resultHandler.ResultHandleSucceed, ShouldEqual, true) |
||||||
|
|
||||||
|
// initialize for other tests.
|
||||||
|
alertTimeout = originAlertTimeout |
||||||
|
engine.resultHandler = &FakeResultHandler{} |
||||||
|
}) |
||||||
|
}) |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
type FakeCommonTimeoutHandler struct { |
||||||
|
TransportTimeoutDuration time.Duration |
||||||
|
ServerBusySleepDuration time.Duration |
||||||
|
EvalSucceed bool |
||||||
|
ResultHandleSucceed bool |
||||||
|
} |
||||||
|
|
||||||
|
func NewFakeCommonTimeoutHandler(transportTimeoutDuration time.Duration, serverBusySleepDuration time.Duration) *FakeCommonTimeoutHandler { |
||||||
|
return &FakeCommonTimeoutHandler{ |
||||||
|
TransportTimeoutDuration: transportTimeoutDuration, |
||||||
|
ServerBusySleepDuration: serverBusySleepDuration, |
||||||
|
EvalSucceed: false, |
||||||
|
ResultHandleSucceed: false, |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func (handler *FakeCommonTimeoutHandler) Eval(evalContext *EvalContext) { |
||||||
|
// 1. prepare mock server
|
||||||
|
path := "/evaltimeout" |
||||||
|
srv := runBusyServer(path, handler.ServerBusySleepDuration) |
||||||
|
defer srv.Close() |
||||||
|
|
||||||
|
// 2. send requests
|
||||||
|
url := srv.URL + path |
||||||
|
res, err := sendRequest(evalContext.Ctx, url, handler.TransportTimeoutDuration) |
||||||
|
if res != nil { |
||||||
|
defer res.Body.Close() |
||||||
|
} |
||||||
|
|
||||||
|
if err != nil { |
||||||
|
evalContext.Error = errors.New("Fake evaluation timeout test failure") |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
if res.StatusCode == 200 { |
||||||
|
handler.EvalSucceed = true |
||||||
|
} |
||||||
|
|
||||||
|
evalContext.Error = errors.New("Fake evaluation timeout test failure; wrong response") |
||||||
|
} |
||||||
|
|
||||||
|
func (handler *FakeCommonTimeoutHandler) Handle(evalContext *EvalContext) error { |
||||||
|
// 1. prepare mock server
|
||||||
|
path := "/resulthandle" |
||||||
|
srv := runBusyServer(path, handler.ServerBusySleepDuration) |
||||||
|
defer srv.Close() |
||||||
|
|
||||||
|
// 2. send requests
|
||||||
|
url := srv.URL + path |
||||||
|
res, err := sendRequest(evalContext.Ctx, url, handler.TransportTimeoutDuration) |
||||||
|
if res != nil { |
||||||
|
defer res.Body.Close() |
||||||
|
} |
||||||
|
|
||||||
|
if err != nil { |
||||||
|
evalContext.Error = errors.New("Fake result handle timeout test failure") |
||||||
|
return evalContext.Error |
||||||
|
} |
||||||
|
|
||||||
|
if res.StatusCode == 200 { |
||||||
|
handler.ResultHandleSucceed = true |
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
evalContext.Error = errors.New("Fake result handle timeout test failure; wrong response") |
||||||
|
|
||||||
|
return evalContext.Error |
||||||
|
} |
||||||
|
|
||||||
|
func runBusyServer(path string, serverBusySleepDuration time.Duration) *httptest.Server { |
||||||
|
mux := http.NewServeMux() |
||||||
|
server := httptest.NewServer(mux) |
||||||
|
|
||||||
|
mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { |
||||||
|
time.Sleep(serverBusySleepDuration) |
||||||
|
}) |
||||||
|
|
||||||
|
return server |
||||||
|
} |
||||||
|
|
||||||
|
func sendRequest(context context.Context, url string, transportTimeoutInterval time.Duration) (resp *http.Response, err error) { |
||||||
|
req, err := http.NewRequest("GET", url, nil) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
|
||||||
|
req = req.WithContext(context) |
||||||
|
|
||||||
|
transport := http.Transport{ |
||||||
|
Dial: (&net.Dialer{ |
||||||
|
Timeout: transportTimeoutInterval, |
||||||
|
KeepAlive: transportTimeoutInterval, |
||||||
|
}).Dial, |
||||||
|
} |
||||||
|
client := http.Client{ |
||||||
|
Transport: &transport, |
||||||
|
} |
||||||
|
|
||||||
|
return client.Do(req) |
||||||
|
} |
||||||
Loading…
Reference in new issue