influxdb/annotations/transport/annotations_router_test.go

268 lines
6.8 KiB
Go

package transport
import (
"encoding/json"
"net/http"
"testing"
"time"
"github.com/golang/mock/gomock"
"github.com/influxdata/influxdb/v2"
influxdbtesting "github.com/influxdata/influxdb/v2/testing"
"github.com/stretchr/testify/require"
)
var (
testCreateAnnotation = influxdb.AnnotationCreate{
StreamTag: "sometag",
Summary: "testing the api",
Message: "stored annotation message",
Stickers: map[string]string{"val1": "sticker1", "val2": "sticker2"},
EndTime: &now,
StartTime: &now,
}
testEvent = influxdb.AnnotationEvent{
ID: *id,
AnnotationCreate: testCreateAnnotation,
}
testReadAnnotation1 = influxdb.ReadAnnotation{
ID: *influxdbtesting.IDPtr(1),
}
testReadAnnotation2 = influxdb.ReadAnnotation{
ID: *influxdbtesting.IDPtr(2),
}
testStoredAnnotation = influxdb.StoredAnnotation{
ID: *id,
OrgID: *orgID,
StreamID: *influxdbtesting.IDPtr(3),
StreamTag: "sometag",
Summary: "testing the api",
Message: "stored annotation message",
Stickers: map[string]string{"val1": "sticker1", "val2": "sticker2"},
Lower: now.Format(time.RFC3339),
Upper: now.Format(time.RFC3339),
}
testReadAnnotations = influxdb.ReadAnnotations{
"sometag": []influxdb.ReadAnnotation{
{
ID: testStoredAnnotation.ID,
Summary: testStoredAnnotation.Summary,
Message: testStoredAnnotation.Message,
Stickers: map[string]string{"val1": "sticker1", "val2": "sticker2"},
EndTime: testStoredAnnotation.Lower,
StartTime: testStoredAnnotation.Upper,
},
},
}
)
func TestAnnotationRouter(t *testing.T) {
t.Parallel()
t.Run("get annotations happy path", func(t *testing.T) {
ts, svc := newTestServer(t)
defer ts.Close()
req := newTestRequest(t, "GET", ts.URL+"/annotations", nil)
q := req.URL.Query()
q.Add("orgID", orgStr)
q.Add("endTime", now.Format(time.RFC3339))
q.Add("stickerIncludes[product]", "oss")
q.Add("stickerIncludes[env]", "dev")
q.Add("streamIncludes", "stream1")
q.Add("streamIncludes", "stream2")
req.URL.RawQuery = q.Encode()
want := []influxdb.AnnotationList{
{
StreamTag: "stream1",
Annotations: []influxdb.ReadAnnotation{testReadAnnotation1},
},
{
StreamTag: "stream2",
Annotations: []influxdb.ReadAnnotation{testReadAnnotation2},
},
}
svc.EXPECT().
ListAnnotations(gomock.Any(), *orgID, influxdb.AnnotationListFilter{
StickerIncludes: map[string]string{"product": "oss", "env": "dev"},
StreamIncludes: []string{"stream1", "stream2"},
BasicFilter: influxdb.BasicFilter{
StartTime: &time.Time{},
EndTime: &now,
},
}).
Return([]influxdb.StoredAnnotation{
{
ID: testReadAnnotation1.ID,
StreamTag: "stream1",
},
{
ID: testReadAnnotation2.ID,
StreamTag: "stream2",
},
}, nil)
res := doTestRequest(t, req, http.StatusOK, true)
got := []influxdb.AnnotationList{}
err := json.NewDecoder(res.Body).Decode(&got)
require.NoError(t, err)
require.ElementsMatch(t, want, got)
})
t.Run("create annotations happy path", func(t *testing.T) {
ts, svc := newTestServer(t)
defer ts.Close()
createAnnotations := []influxdb.AnnotationCreate{testCreateAnnotation}
req := newTestRequest(t, "POST", ts.URL+"/annotations", createAnnotations)
q := req.URL.Query()
q.Add("orgID", orgStr)
req.URL.RawQuery = q.Encode()
want := []influxdb.AnnotationEvent{testEvent}
svc.EXPECT().
CreateAnnotations(gomock.Any(), *orgID, createAnnotations).
Return(want, nil)
res := doTestRequest(t, req, http.StatusOK, true)
got := []influxdb.AnnotationEvent{}
err := json.NewDecoder(res.Body).Decode(&got)
require.NoError(t, err)
require.Equal(t, want, got)
})
t.Run("delete annotations happy path", func(t *testing.T) {
ts, svc := newTestServer(t)
defer ts.Close()
req := newTestRequest(t, "DELETE", ts.URL+"/annotations", nil)
q := req.URL.Query()
q.Add("orgID", orgStr)
q.Add("stream", "someTag")
q.Add("startTime", now.Format(time.RFC3339))
q.Add("endTime", later.Format(time.RFC3339))
req.URL.RawQuery = q.Encode()
svc.EXPECT().
DeleteAnnotations(gomock.Any(), *orgID, influxdb.AnnotationDeleteFilter{
StreamTag: "someTag",
StartTime: &now,
EndTime: &later,
Stickers: map[string]string{},
}).
Return(nil)
doTestRequest(t, req, http.StatusNoContent, false)
})
t.Run("get annotation happy path", func(t *testing.T) {
ts, svc := newTestServer(t)
defer ts.Close()
req := newTestRequest(t, "GET", ts.URL+"/annotations/"+idStr, nil)
svc.EXPECT().
GetAnnotation(gomock.Any(), *id).
Return(&testStoredAnnotation, nil)
res := doTestRequest(t, req, http.StatusOK, true)
got := &influxdb.AnnotationEvent{}
err := json.NewDecoder(res.Body).Decode(got)
require.NoError(t, err)
require.Equal(t, &testEvent, got)
})
t.Run("delete annotation happy path", func(t *testing.T) {
ts, svc := newTestServer(t)
defer ts.Close()
req := newTestRequest(t, "DELETE", ts.URL+"/annotations/"+idStr, nil)
svc.EXPECT().
DeleteAnnotation(gomock.Any(), *id).
Return(nil)
doTestRequest(t, req, http.StatusNoContent, false)
})
t.Run("update annotation happy path", func(t *testing.T) {
ts, svc := newTestServer(t)
defer ts.Close()
req := newTestRequest(t, "PUT", ts.URL+"/annotations/"+idStr, testCreateAnnotation)
svc.EXPECT().
UpdateAnnotation(gomock.Any(), *id, testCreateAnnotation).
Return(&testEvent, nil)
res := doTestRequest(t, req, http.StatusOK, true)
got := &influxdb.AnnotationEvent{}
err := json.NewDecoder(res.Body).Decode(got)
require.NoError(t, err)
require.Equal(t, &testEvent, got)
})
t.Run("invalid org ids return 400 when required", func(t *testing.T) {
methods := []string{"POST", "GET", "DELETE"}
for _, m := range methods {
t.Run(m, func(t *testing.T) {
ts, _ := newTestServer(t)
defer ts.Close()
req := newTestRequest(t, m, ts.URL+"/annotations", nil)
q := req.URL.Query()
q.Add("orgID", "badid")
req.URL.RawQuery = q.Encode()
doTestRequest(t, req, http.StatusBadRequest, false)
})
}
})
t.Run("invalid annotation ids return 400 when required", func(t *testing.T) {
methods := []string{"GET", "DELETE", "PUT"}
for _, m := range methods {
t.Run(m, func(t *testing.T) {
ts, _ := newTestServer(t)
defer ts.Close()
req := newTestRequest(t, m, ts.URL+"/annotations/badID", nil)
doTestRequest(t, req, http.StatusBadRequest, false)
})
}
})
}
func TestStoredAnnotationsToReadAnnotations(t *testing.T) {
t.Parallel()
got, err := storedAnnotationsToReadAnnotations([]influxdb.StoredAnnotation{testStoredAnnotation})
require.NoError(t, err)
require.Equal(t, got, testReadAnnotations)
}
func TestStoredAnnotationToEvent(t *testing.T) {
t.Parallel()
got, err := storedAnnotationToEvent(&testStoredAnnotation)
require.NoError(t, err)
require.Equal(t, got, &testEvent)
}