mirror of
https://github.com/grafana/grafana.git
synced 2024-12-01 13:09:22 -06:00
3ca00f90b5
This commit adds contact point testing to ngalerts via a new API endpoint. This endpoint accepts JSON containing a list of receiver configurations which are validated and then tested with a notification for a test alert. The endpoint returns JSON for each receiver with a status and error message. It accepts a configurable timeout via the Request-Timeout header (in seconds) up to a maximum of 30 seconds.
141 lines
3.9 KiB
Go
141 lines
3.9 KiB
Go
package api
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/grafana/grafana/pkg/services/ngalert/notifier"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestContextWithTimeoutFromRequest(t *testing.T) {
|
|
t.Run("assert context has default timeout when header is absent", func(t *testing.T) {
|
|
req, err := http.NewRequest(http.MethodGet, "https://grafana.net", nil)
|
|
require.NoError(t, err)
|
|
|
|
now := time.Now()
|
|
ctx := context.Background()
|
|
ctx, cancelFunc, err := contextWithTimeoutFromRequest(
|
|
ctx,
|
|
req,
|
|
15*time.Second,
|
|
30*time.Second)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, cancelFunc)
|
|
require.NotNil(t, ctx)
|
|
|
|
deadline, ok := ctx.Deadline()
|
|
require.True(t, ok)
|
|
require.True(t, deadline.After(now))
|
|
require.Less(t, deadline.Sub(now).Seconds(), 30.0)
|
|
require.GreaterOrEqual(t, deadline.Sub(now).Seconds(), 15.0)
|
|
})
|
|
|
|
t.Run("assert context has timeout in request header", func(t *testing.T) {
|
|
req, err := http.NewRequest(http.MethodGet, "https://grafana.net", nil)
|
|
require.NoError(t, err)
|
|
req.Header.Set("Request-Timeout", "5")
|
|
|
|
now := time.Now()
|
|
ctx := context.Background()
|
|
ctx, cancelFunc, err := contextWithTimeoutFromRequest(
|
|
ctx,
|
|
req,
|
|
15*time.Second,
|
|
30*time.Second)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, cancelFunc)
|
|
require.NotNil(t, ctx)
|
|
|
|
deadline, ok := ctx.Deadline()
|
|
require.True(t, ok)
|
|
require.True(t, deadline.After(now))
|
|
require.Less(t, deadline.Sub(now).Seconds(), 15.0)
|
|
require.GreaterOrEqual(t, deadline.Sub(now).Seconds(), 5.0)
|
|
})
|
|
|
|
t.Run("assert timeout in request header cannot exceed max timeout", func(t *testing.T) {
|
|
req, err := http.NewRequest(http.MethodGet, "https://grafana.net", nil)
|
|
require.NoError(t, err)
|
|
req.Header.Set("Request-Timeout", "60")
|
|
|
|
ctx := context.Background()
|
|
ctx, cancelFunc, err := contextWithTimeoutFromRequest(
|
|
ctx,
|
|
req,
|
|
15*time.Second,
|
|
30*time.Second)
|
|
require.Error(t, err, "exceeded maximum timeout")
|
|
require.Nil(t, cancelFunc)
|
|
require.Nil(t, ctx)
|
|
})
|
|
}
|
|
|
|
func TestStatusForTestReceivers(t *testing.T) {
|
|
t.Run("assert HTTP 400 Status Bad Request for no receivers", func(t *testing.T) {
|
|
require.Equal(t, http.StatusBadRequest, statusForTestReceivers([]notifier.TestReceiverResult{}))
|
|
})
|
|
|
|
t.Run("assert HTTP 400 Bad Request when all invalid receivers", func(t *testing.T) {
|
|
require.Equal(t, http.StatusBadRequest, statusForTestReceivers([]notifier.TestReceiverResult{{
|
|
Name: "test1",
|
|
Configs: []notifier.TestReceiverConfigResult{{
|
|
Name: "test1",
|
|
UID: "uid1",
|
|
Status: "failed",
|
|
Error: notifier.InvalidReceiverError{},
|
|
}},
|
|
}, {
|
|
Name: "test2",
|
|
Configs: []notifier.TestReceiverConfigResult{{
|
|
Name: "test2",
|
|
UID: "uid2",
|
|
Status: "failed",
|
|
Error: notifier.InvalidReceiverError{},
|
|
}},
|
|
}}))
|
|
})
|
|
|
|
t.Run("assert HTTP 408 Request Timeout when all receivers timed out", func(t *testing.T) {
|
|
require.Equal(t, http.StatusRequestTimeout, statusForTestReceivers([]notifier.TestReceiverResult{{
|
|
Name: "test1",
|
|
Configs: []notifier.TestReceiverConfigResult{{
|
|
Name: "test1",
|
|
UID: "uid1",
|
|
Status: "failed",
|
|
Error: notifier.ReceiverTimeoutError{},
|
|
}},
|
|
}, {
|
|
Name: "test2",
|
|
Configs: []notifier.TestReceiverConfigResult{{
|
|
Name: "test2",
|
|
UID: "uid2",
|
|
Status: "failed",
|
|
Error: notifier.ReceiverTimeoutError{},
|
|
}},
|
|
}}))
|
|
})
|
|
|
|
t.Run("assert 207 Multi Status for different errors", func(t *testing.T) {
|
|
require.Equal(t, http.StatusMultiStatus, statusForTestReceivers([]notifier.TestReceiverResult{{
|
|
Name: "test1",
|
|
Configs: []notifier.TestReceiverConfigResult{{
|
|
Name: "test1",
|
|
UID: "uid1",
|
|
Status: "failed",
|
|
Error: notifier.InvalidReceiverError{},
|
|
}},
|
|
}, {
|
|
Name: "test2",
|
|
Configs: []notifier.TestReceiverConfigResult{{
|
|
Name: "test2",
|
|
UID: "uid2",
|
|
Status: "failed",
|
|
Error: notifier.ReceiverTimeoutError{},
|
|
}},
|
|
}}))
|
|
})
|
|
}
|