diff --git a/notifier/notifier.go b/notifier/notifier.go index b896d53a4..e9af00a4c 100644 --- a/notifier/notifier.go +++ b/notifier/notifier.go @@ -77,12 +77,18 @@ type Options struct { QueueCapacity int ExternalLabels model.LabelSet RelabelConfigs []*config.RelabelConfig + // Used for sending HTTP requests to the Alertmanager. + Do func(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) } // New constructs a new Notifier. func New(o *Options) *Notifier { ctx, cancel := context.WithCancel(context.Background()) + if o.Do == nil { + o.Do = ctxhttp.Do + } + return &Notifier{ queue: make(model.Alerts, 0, o.QueueCapacity), ctx: ctx, @@ -351,7 +357,12 @@ func (n *Notifier) sendAll(alerts ...*model.Alert) bool { } func (n *Notifier) sendOne(ctx context.Context, c *http.Client, url string, b []byte) error { - resp, err := ctxhttp.Post(ctx, c, url, contentTypeJSON, bytes.NewReader(b)) + req, err := http.NewRequest("POST", url, bytes.NewReader(b)) + if err != nil { + return err + } + req.Header.Set("Content-Type", contentTypeJSON) + resp, err := n.opts.Do(ctx, c, req) if err != nil { return err } diff --git a/notifier/notifier_test.go b/notifier/notifier_test.go index 65c49a3fa..3587a1a8a 100644 --- a/notifier/notifier_test.go +++ b/notifier/notifier_test.go @@ -16,12 +16,15 @@ package notifier import ( "encoding/json" "fmt" + "io/ioutil" "net/http" "net/http/httptest" "reflect" "testing" "time" + "golang.org/x/net/context" + "github.com/prometheus/common/model" "github.com/prometheus/prometheus/config" ) @@ -191,6 +194,37 @@ func TestHandlerSendAll(t *testing.T) { } } +func TestCustomDo(t *testing.T) { + const testURL = "http://testurl.com/" + const testBody = "testbody" + + var received bool + h := New(&Options{ + Do: func(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) { + received = true + body, err := ioutil.ReadAll(req.Body) + if err != nil { + t.Fatalf("Unable to read request body: %v", err) + } + if string(body) != testBody { + t.Fatalf("Unexpected body; want %v, got %v", testBody, string(body)) + } + if req.URL.String() != testURL { + t.Fatalf("Unexpected URL; want %v, got %v", testURL, req.URL.String()) + } + return &http.Response{ + Body: ioutil.NopCloser(nil), + }, nil + }, + }) + + h.sendOne(context.Background(), nil, testURL, []byte(testBody)) + + if !received { + t.Fatal("Expected to receive an alert, but didn't") + } +} + func TestExternalLabels(t *testing.T) { h := New(&Options{ QueueCapacity: 3 * maxBatchSize,