mirror of https://github.com/grafana/grafana
Merge pull request #14883 from sharkpc0813/14701-fix-alert-context
fix that alert context and result handle context do not use the same derived context.pull/15082/head
commit
711f9bc034
@ -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