Path: blob/main/pkg/integrations/v2/app_agent_receiver/handler_test.go
5333 views
package app_agent_receiver12import (3"bytes"4"context"5"errors"6"net/http"7"net/http/httptest"8"testing"910"github.com/go-kit/log"11"github.com/stretchr/testify/require"1213"github.com/prometheus/client_golang/prometheus"14)1516const PAYLOAD = `17{18"traces": {19"resourceSpans": []20},21"logs": [],22"exceptions": [],23"measurements": [],24"meta": {}25}26`2728type TestExporter struct {29name string30broken bool31payloads []Payload32}3334func (te *TestExporter) Name() string {35return te.name36}3738func (te *TestExporter) Export(ctx context.Context, payload Payload) error {39if te.broken {40return errors.New("this exporter is broken")41}42te.payloads = append(te.payloads, payload)43return nil44}4546func TestMultipleExportersAllSucceed(t *testing.T) {47req, err := http.NewRequest("POST", "/collect", bytes.NewBuffer([]byte(PAYLOAD)))4849reg := prometheus.NewRegistry()5051require.NoError(t, err)5253exporter1 := TestExporter{54name: "exporter1",55broken: false,56payloads: []Payload{},57}58exporter2 := TestExporter{59name: "exporter2",60broken: false,61payloads: []Payload{},62}6364conf := &Config{}6566fr := NewAppAgentReceiverHandler(conf, []appAgentReceiverExporter{&exporter1, &exporter2}, reg)67handler := fr.HTTPHandler(log.NewNopLogger())6869rr := httptest.NewRecorder()7071handler.ServeHTTP(rr, req)7273require.Equal(t, http.StatusAccepted, rr.Result().StatusCode)7475require.Len(t, exporter1.payloads, 1)76require.Len(t, exporter2.payloads, 1)77}7879func TestMultipleExportersOneFails(t *testing.T) {80req, err := http.NewRequest("POST", "/collect", bytes.NewBuffer([]byte(PAYLOAD)))8182require.NoError(t, err)8384reg := prometheus.NewRegistry()8586exporter1 := TestExporter{87name: "exporter1",88broken: true,89payloads: []Payload{},90}91exporter2 := TestExporter{92name: "exporter2",93broken: false,94payloads: []Payload{},95}9697conf := &Config{}9899fr := NewAppAgentReceiverHandler(conf, []appAgentReceiverExporter{&exporter1, &exporter2}, reg)100handler := fr.HTTPHandler(log.NewNopLogger())101102rr := httptest.NewRecorder()103104handler.ServeHTTP(rr, req)105106metrics, err := reg.Gather()107require.NoError(t, err)108109metric := metrics[0]110require.Equal(t, "app_agent_receiver_exporter_errors_total", *metric.Name)111require.Len(t, metric.Metric, 1)112require.Equal(t, 1.0, *metric.Metric[0].Counter.Value)113require.Len(t, metric.Metric[0].Label, 1)114require.Equal(t, *metric.Metric[0].Label[0].Value, "exporter1")115require.Len(t, metrics, 1)116require.Equal(t, http.StatusAccepted, rr.Result().StatusCode)117require.Len(t, exporter1.payloads, 0)118require.Len(t, exporter2.payloads, 1)119}120121func TestMultipleExportersAllFail(t *testing.T) {122req, err := http.NewRequest("POST", "/collect", bytes.NewBuffer([]byte(PAYLOAD)))123124reg := prometheus.NewRegistry()125126require.NoError(t, err)127128exporter1 := TestExporter{129name: "exporter1",130broken: true,131payloads: []Payload{},132}133exporter2 := TestExporter{134name: "exporter2",135broken: true,136payloads: []Payload{},137}138139conf := &Config{}140141fr := NewAppAgentReceiverHandler(conf, []appAgentReceiverExporter{&exporter1, &exporter2}, reg)142handler := fr.HTTPHandler(log.NewNopLogger())143144rr := httptest.NewRecorder()145146handler.ServeHTTP(rr, req)147148metrics, err := reg.Gather()149require.NoError(t, err)150151require.Len(t, metrics, 1)152metric := metrics[0]153154require.Equal(t, "app_agent_receiver_exporter_errors_total", *metric.Name)155require.Len(t, metric.Metric, 2)156require.Equal(t, 1.0, *metric.Metric[0].Counter.Value)157require.Equal(t, 1.0, *metric.Metric[1].Counter.Value)158require.Len(t, metric.Metric[0].Label, 1)159require.Len(t, metric.Metric[1].Label, 1)160require.Equal(t, *metric.Metric[0].Label[0].Value, "exporter1")161require.Equal(t, *metric.Metric[1].Label[0].Value, "exporter2")162require.Equal(t, http.StatusAccepted, rr.Result().StatusCode)163require.Len(t, exporter1.payloads, 0)164require.Len(t, exporter2.payloads, 0)165}166167func TestNoContentLengthLimitSet(t *testing.T) {168req, err := http.NewRequest("POST", "/collect", bytes.NewBuffer([]byte(PAYLOAD)))169require.NoError(t, err)170reg := prometheus.NewRegistry()171172conf := &Config{}173174req.ContentLength = 89348593894175176fr := NewAppAgentReceiverHandler(conf, []appAgentReceiverExporter{}, reg)177handler := fr.HTTPHandler(nil)178179rr := httptest.NewRecorder()180181handler.ServeHTTP(rr, req)182183require.Equal(t, http.StatusAccepted, rr.Result().StatusCode)184}185186func TestLargePayload(t *testing.T) {187req, err := http.NewRequest("POST", "/collect", bytes.NewBuffer([]byte(PAYLOAD)))188require.NoError(t, err)189reg := prometheus.NewRegistry()190191conf := &Config{192Server: ServerConfig{193MaxAllowedPayloadSize: 10,194},195}196197fr := NewAppAgentReceiverHandler(conf, []appAgentReceiverExporter{}, reg)198handler := fr.HTTPHandler(nil)199200rr := httptest.NewRecorder()201202handler.ServeHTTP(rr, req)203require.Equal(t, http.StatusRequestEntityTooLarge, rr.Result().StatusCode)204}205206func TestAPIKeyRequiredButNotProvided(t *testing.T) {207req, err := http.NewRequest("POST", "/collect", bytes.NewBuffer([]byte(PAYLOAD)))208209if err != nil {210t.Fatal(err)211}212213conf := &Config{214Server: ServerConfig{215APIKey: "foo",216},217}218219fr := NewAppAgentReceiverHandler(conf, nil, prometheus.NewRegistry())220handler := fr.HTTPHandler(nil)221222rr := httptest.NewRecorder()223224handler.ServeHTTP(rr, req)225require.Equal(t, http.StatusUnauthorized, rr.Result().StatusCode)226}227228func TestAPIKeyWrong(t *testing.T) {229req, err := http.NewRequest("POST", "/collect", bytes.NewBuffer([]byte(PAYLOAD)))230req.Header.Set("x-api-key", "bar")231232if err != nil {233t.Fatal(err)234}235236conf := &Config{237Server: ServerConfig{238APIKey: "foo",239},240}241242fr := NewAppAgentReceiverHandler(conf, nil, prometheus.NewRegistry())243handler := fr.HTTPHandler(nil)244245rr := httptest.NewRecorder()246247handler.ServeHTTP(rr, req)248require.Equal(t, http.StatusUnauthorized, rr.Result().StatusCode)249}250251func TestAPIKeyCorrect(t *testing.T) {252req, err := http.NewRequest("POST", "/collect", bytes.NewBuffer([]byte(PAYLOAD)))253req.Header.Set("x-api-key", "foo")254255if err != nil {256t.Fatal(err)257}258259conf := &Config{260Server: ServerConfig{261APIKey: "foo",262},263}264265fr := NewAppAgentReceiverHandler(conf, nil, prometheus.NewRegistry())266handler := fr.HTTPHandler(nil)267268rr := httptest.NewRecorder()269270handler.ServeHTTP(rr, req)271require.Equal(t, http.StatusAccepted, rr.Result().StatusCode)272}273274func TestRateLimiterNoReject(t *testing.T) {275req, err := http.NewRequest("POST", "/collect", bytes.NewBuffer([]byte(PAYLOAD)))276277if err != nil {278t.Fatal(err)279}280281conf := &Config{282Server: ServerConfig{283RateLimiting: RateLimitingConfig{284Burstiness: 10,285RPS: 10,286Enabled: true,287},288},289}290291fr := NewAppAgentReceiverHandler(conf, nil, prometheus.NewRegistry())292handler := fr.HTTPHandler(nil)293294rr := httptest.NewRecorder()295296handler.ServeHTTP(rr, req)297require.Equal(t, http.StatusAccepted, rr.Result().StatusCode)298}299300func TestRateLimiterReject(t *testing.T) {301conf := &Config{302Server: ServerConfig{303RateLimiting: RateLimitingConfig{304Burstiness: 2,305RPS: 1,306Enabled: true,307},308},309}310311fr := NewAppAgentReceiverHandler(conf, nil, prometheus.NewRegistry())312handler := fr.HTTPHandler(nil)313314makeRequest := func() *httptest.ResponseRecorder {315req, err := http.NewRequest("POST", "/collect", bytes.NewBuffer([]byte(PAYLOAD)))316require.NoError(t, err)317rr := httptest.NewRecorder()318handler.ServeHTTP(rr, req)319return rr320}321322r1 := makeRequest()323r2 := makeRequest()324r3 := makeRequest()325326require.Equal(t, http.StatusAccepted, r1.Result().StatusCode)327require.Equal(t, http.StatusAccepted, r2.Result().StatusCode)328require.Equal(t, http.StatusTooManyRequests, r3.Result().StatusCode)329}330331func TestRateLimiterDisabled(t *testing.T) {332req, err := http.NewRequest("POST", "/collect", bytes.NewBuffer([]byte(PAYLOAD)))333334if err != nil {335t.Fatal(err)336}337338conf := &Config{339Server: ServerConfig{340RateLimiting: RateLimitingConfig{341Burstiness: 0,342RPS: 0,343Enabled: false,344},345},346}347348fr := NewAppAgentReceiverHandler(conf, nil, prometheus.NewRegistry())349handler := fr.HTTPHandler(nil)350351rr := httptest.NewRecorder()352353handler.ServeHTTP(rr, req)354require.Equal(t, http.StatusAccepted, rr.Result().StatusCode)355}356357358