Files
karma/proxy_test.go
Łukasz Mierzwa b6dd993c2b Add support for proxying user connection to Alertmanager
Fixes #190.

With this feature unsee can be configured to proxy requests to selected Alertmanager instances, if it's enabled unsee silence form will send a request via unsee rather than directly. This allows users to manage silences in environments where they have access to unsee but not to Alertmanager. Only silences endpoints on Alertmanager API are proxied.
2018-01-03 16:17:58 -08:00

122 lines
3.4 KiB
Go

package main
import (
"net/http"
"net/http/httptest"
"testing"
"time"
"github.com/cloudflare/unsee/internal/alertmanager"
httpmock "gopkg.in/jarcoal/httpmock.v1"
)
// httptest.NewRecorder() doesn't implement http.CloseNotifier
type closeNotifyingRecorder struct {
*httptest.ResponseRecorder
closed chan bool
}
func newCloseNotifyingRecorder() *closeNotifyingRecorder {
return &closeNotifyingRecorder{
httptest.NewRecorder(),
make(chan bool, 1),
}
}
func (c *closeNotifyingRecorder) close() {
c.closed <- true
}
func (c *closeNotifyingRecorder) CloseNotify() <-chan bool {
return c.closed
}
type proxyTest struct {
method string
localPath string
upstreamURI string
code int
response string
}
var proxyTests = []proxyTest{
// valid alertmanager and methods
proxyTest{
method: "POST",
localPath: "/proxy/alertmanager/dummy/api/v1/silences",
upstreamURI: "http://localhost:9093/api/v1/silences",
code: 200,
response: "{\"status\":\"success\",\"data\":{\"silenceId\":\"d8a61ca8-ee2e-4076-999f-276f1e986bf3\"}}",
},
proxyTest{
method: "DELETE",
localPath: "/proxy/alertmanager/dummy/api/v1/silence/d8a61ca8-ee2e-4076-999f-276f1e986bf3",
upstreamURI: "http://localhost:9093/api/v1/silence/d8a61ca8-ee2e-4076-999f-276f1e986bf3",
code: 200,
response: "{\"status\":\"success\"}",
},
// invalid alertmanager name
proxyTest{
method: "POST",
localPath: "/proxy/alertmanager/INVALID/api/v1/silences",
upstreamURI: "",
code: 404,
response: "404 page not found",
},
proxyTest{
method: "DELETE",
localPath: "/proxy/alertmanager/INVALID/api/v1/silence/d8a61ca8-ee2e-4076-999f-276f1e986bf3",
upstreamURI: "http://localhost:9093/api/v1/silence/d8a61ca8-ee2e-4076-999f-276f1e986bf3",
code: 404,
response: "404 page not found",
},
// valid alertmanager name, but invalid method
proxyTest{
method: "GET",
localPath: "/proxy/alertmanager/dummy/api/v1/silences",
upstreamURI: "",
code: 404,
response: "404 page not found",
},
proxyTest{
method: "GET",
localPath: "/proxy/alertmanager/dummy/api/v1/silence/d8a61ca8-ee2e-4076-999f-276f1e986bf3",
upstreamURI: "http://localhost:9093/api/v1/silence/d8a61ca8-ee2e-4076-999f-276f1e986bf3",
code: 404,
response: "404 page not found",
},
}
func TestProxy(t *testing.T) {
r := ginTestEngine()
setupRouterProxyHandlers(r, &alertmanager.Alertmanager{
URI: "http://localhost:9093",
Timeout: time.Second * 5,
Name: "dummy",
ProxyRequests: true,
})
httpmock.Activate()
defer httpmock.DeactivateAndReset()
for _, testCase := range proxyTests {
httpmock.Reset()
if testCase.upstreamURI != "" {
httpmock.RegisterResponder(testCase.method, testCase.upstreamURI, httpmock.NewStringResponder(testCase.code, testCase.response))
}
req, _ := http.NewRequest(testCase.method, testCase.localPath, nil)
resp := newCloseNotifyingRecorder()
r.ServeHTTP(resp, req)
if resp.Code != testCase.code {
t.Errorf("%s %s proxied to %s returned status %d while %d was expected",
testCase.method, testCase.localPath, testCase.upstreamURI, resp.Code, testCase.code)
}
body := resp.Body.String()
if body != testCase.response {
t.Errorf("%s %s proxied to %s returned content '%s' while '%s' was expected",
testCase.method, testCase.localPath, testCase.upstreamURI, body, testCase.response)
}
}
}