influxdb/http/check_test.go

1486 lines
38 KiB
Go
Raw Normal View History

2019-07-25 10:30:25 +00:00
package http
import (
"bytes"
"context"
"encoding/json"
"fmt"
2021-10-12 21:55:07 +00:00
"io"
2019-07-25 10:30:25 +00:00
"net/http"
"net/http/httptest"
"path"
2019-07-25 10:30:25 +00:00
"testing"
feat(checks): add first pass at creating tasks from checks First pass at flux AST generation from check Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): format call expression Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): cleanup CheckDefinition Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): clean up threshold functions Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): clean up message function Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): misc fixes Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): remove dead code Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): move threshold flux generation to check pkg Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): move base ast generation to its own package Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): add comment for GenerateFluxAST Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> docs(notification/flux): add comments to each exported function Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> feat(notification/check): add tests for GenerateFlux Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> feat(notification/check): add task options to generated flux fix(notification/check): use flux compatible duration type test(notification/check): add task option to task definition test(http): use check Duration in checks http handlers feat(check): add TaskID to checks base fix(notification/check): hack around issue with formatting ast package wtih multiple files test(check): create task when check is created A lot of little changes had to happen as a result of this. This change was rather painful. feat(checks): add update and delete of task for check fix(notifications/check): hack around the alerts package not being available test(kv): temporarily skip check tests while we merge the pr above
2019-08-07 22:34:07 +00:00
"github.com/influxdata/flux/parser"
"github.com/influxdata/httprouter"
"github.com/influxdata/influxdb/v2"
pcontext "github.com/influxdata/influxdb/v2/context"
"github.com/influxdata/influxdb/v2/kit/platform"
"github.com/influxdata/influxdb/v2/kit/platform/errors"
kithttp "github.com/influxdata/influxdb/v2/kit/transport/http"
"github.com/influxdata/influxdb/v2/mock"
"github.com/influxdata/influxdb/v2/notification"
"github.com/influxdata/influxdb/v2/notification/check"
"github.com/influxdata/influxdb/v2/pkg/testttp"
"github.com/influxdata/influxdb/v2/query/fluxlang"
"github.com/influxdata/influxdb/v2/task/taskmodel"
influxTesting "github.com/influxdata/influxdb/v2/testing"
"go.uber.org/zap/zaptest"
2019-07-25 10:30:25 +00:00
)
// NewMockCheckBackend returns a CheckBackend with mock services.
func NewMockCheckBackend(t *testing.T) *CheckBackend {
2019-07-25 10:30:25 +00:00
return &CheckBackend{
log: zaptest.NewLogger(t),
2019-07-25 10:30:25 +00:00
CheckService: mock.NewCheckService(),
UserResourceMappingService: mock.NewUserResourceMappingService(),
LabelService: mock.NewLabelService(),
UserService: mock.NewUserService(),
OrganizationService: mock.NewOrganizationService(),
FluxLanguageService: fluxlang.DefaultService,
2019-07-25 10:30:25 +00:00
}
}
func TestService_handleGetChecks(t *testing.T) {
type fields struct {
CheckService influxdb.CheckService
LabelService influxdb.LabelService
}
type args struct {
queryParams map[string][]string
}
type wants struct {
statusCode int
contentType string
body string
}
fl1 := 100.32
fl2 := 200.64
fl4 := 100.1
fl5 := 3023.2
2019-07-25 10:30:25 +00:00
tests := []struct {
name string
fields fields
args args
wants wants
}{
{
name: "get all checks",
fields: fields{
&mock.CheckService{
FindChecksFn: func(ctx context.Context, filter influxdb.CheckFilter, opts ...influxdb.FindOptions) ([]influxdb.Check, int, error) {
return []influxdb.Check{
&check.Deadman{
Base: check.Base{
ID: influxTesting.MustIDBase16("0b501e7e557ab1ed"),
Name: "hello",
OrgID: influxTesting.MustIDBase16("50f7ba1150f7ba11"),
feat(checks): add first pass at creating tasks from checks First pass at flux AST generation from check Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): format call expression Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): cleanup CheckDefinition Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): clean up threshold functions Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): clean up message function Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): misc fixes Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): remove dead code Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): move threshold flux generation to check pkg Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): move base ast generation to its own package Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): add comment for GenerateFluxAST Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> docs(notification/flux): add comments to each exported function Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> feat(notification/check): add tests for GenerateFlux Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> feat(notification/check): add task options to generated flux fix(notification/check): use flux compatible duration type test(notification/check): add task option to task definition test(http): use check Duration in checks http handlers feat(check): add TaskID to checks base fix(notification/check): hack around issue with formatting ast package wtih multiple files test(check): create task when check is created A lot of little changes had to happen as a result of this. This change was rather painful. feat(checks): add update and delete of task for check fix(notifications/check): hack around the alerts package not being available test(kv): temporarily skip check tests while we merge the pr above
2019-08-07 22:34:07 +00:00
TaskID: 3,
2019-07-25 10:30:25 +00:00
},
Level: notification.Info,
},
&check.Threshold{
Base: check.Base{
ID: influxTesting.MustIDBase16("c0175f0077a77005"),
Name: "example",
OrgID: influxTesting.MustIDBase16("7e55e118dbabb1ed"),
feat(checks): add first pass at creating tasks from checks First pass at flux AST generation from check Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): format call expression Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): cleanup CheckDefinition Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): clean up threshold functions Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): clean up message function Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): misc fixes Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): remove dead code Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): move threshold flux generation to check pkg Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): move base ast generation to its own package Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): add comment for GenerateFluxAST Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> docs(notification/flux): add comments to each exported function Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> feat(notification/check): add tests for GenerateFlux Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> feat(notification/check): add task options to generated flux fix(notification/check): use flux compatible duration type test(notification/check): add task option to task definition test(http): use check Duration in checks http handlers feat(check): add TaskID to checks base fix(notification/check): hack around issue with formatting ast package wtih multiple files test(check): create task when check is created A lot of little changes had to happen as a result of this. This change was rather painful. feat(checks): add update and delete of task for check fix(notifications/check): hack around the alerts package not being available test(kv): temporarily skip check tests while we merge the pr above
2019-08-07 22:34:07 +00:00
TaskID: 3,
2019-07-25 10:30:25 +00:00
},
Thresholds: []check.ThresholdConfig{
&check.Greater{
Value: fl1,
ThresholdConfigBase: check.ThresholdConfigBase{Level: notification.Critical},
},
&check.Lesser{
Value: fl2,
ThresholdConfigBase: check.ThresholdConfigBase{Level: notification.Info},
},
&check.Range{Min: fl4, Max: fl5, Within: true},
2019-07-25 10:30:25 +00:00
},
},
}, 2, nil
},
},
&mock.LabelService{
FindResourceLabelsFn: func(ctx context.Context, f influxdb.LabelMappingFilter) ([]*influxdb.Label, error) {
labels := []*influxdb.Label{
{
ID: influxTesting.MustIDBase16("fc3dc670a4be9b9a"),
Name: "label",
Properties: map[string]string{
"color": "fff000",
},
},
}
return labels, nil
},
},
},
args: args{
map[string][]string{
"limit": {"1"},
},
},
wants: wants{
statusCode: http.StatusOK,
contentType: "application/json; charset=utf-8",
body: `
{
"links": {
"self": "/api/v2/checks?descending=false&limit=1&offset=0",
"next": "/api/v2/checks?descending=false&limit=1&offset=1"
},
"checks": [
{
"links": {
"self": "/api/v2/checks/0b501e7e557ab1ed",
"labels": "/api/v2/checks/0b501e7e557ab1ed/labels",
"query": "/api/v2/checks/0b501e7e557ab1ed/query",
2019-07-25 10:30:25 +00:00
"owners": "/api/v2/checks/0b501e7e557ab1ed/owners",
"members": "/api/v2/checks/0b501e7e557ab1ed/members"
},
2019-09-18 20:19:51 +00:00
"createdAt": "0001-01-01T00:00:00Z",
"updatedAt": "0001-01-01T00:00:00Z",
2019-07-25 10:30:25 +00:00
"id": "0b501e7e557ab1ed",
2019-09-18 20:19:51 +00:00
"orgID": "50f7ba1150f7ba11",
"name": "hello",
"level": "INFO",
"query": {
"builderConfig": {
"aggregateWindow": {
"fillValues": false,
2019-09-18 20:19:51 +00:00
"period": ""
},
"buckets": [],
"functions": [],
"tags": []
2019-09-18 20:19:51 +00:00
},
"editMode": "",
"name": "",
"text": ""
},
"reportZero": false,
"statusMessageTemplate": "",
"tags": null,
"taskID": "0000000000000003",
2019-09-18 20:19:51 +00:00
"type": "deadman",
2019-07-25 10:30:25 +00:00
"labels": [
{
"id": "fc3dc670a4be9b9a",
"name": "label",
"properties": {
"color": "fff000"
}
}
2019-09-18 20:19:51 +00:00
],
"status": "active",
"latestCompleted": "0001-01-01T00:00:00Z",
"latestScheduled": "0001-01-01T00:00:00Z"
2019-07-25 10:30:25 +00:00
},
{
"links": {
"self": "/api/v2/checks/c0175f0077a77005",
"labels": "/api/v2/checks/c0175f0077a77005/labels",
"members": "/api/v2/checks/c0175f0077a77005/members",
"owners": "/api/v2/checks/c0175f0077a77005/owners",
"query": "/api/v2/checks/c0175f0077a77005/query"
2019-07-25 10:30:25 +00:00
},
2019-09-18 20:19:51 +00:00
"createdAt": "0001-01-01T00:00:00Z",
"updatedAt": "0001-01-01T00:00:00Z",
2019-07-25 10:30:25 +00:00
"id": "c0175f0077a77005",
"orgID": "7e55e118dbabb1ed",
"name": "example",
2019-09-18 20:19:51 +00:00
"query": {
"builderConfig": {
"aggregateWindow": {
"fillValues": false,
2019-09-18 20:19:51 +00:00
"period": ""
},
"buckets": [],
"functions": [],
"tags": []
2019-09-18 20:19:51 +00:00
},
"editMode": "",
"name": "",
"text": ""
},
"statusMessageTemplate": "",
"tags": null,
"taskID": "0000000000000003",
2019-09-18 20:19:51 +00:00
"thresholds": [
{
"allValues": false,
"level": "CRIT",
"type": "greater",
"value": 100.32
},
{
"allValues": false,
"level": "INFO",
"type": "lesser",
"value": 200.64
},
{
"allValues": false,
"level": "UNKNOWN",
"max": 3023.2,
"min": 100.1,
"type": "range",
"within": true
}
],
"type": "threshold",
"labels": [
{
"id": "fc3dc670a4be9b9a",
"name": "label",
"properties": {
"color": "fff000"
}
}
],
"status": "active",
"latestCompleted": "0001-01-01T00:00:00Z",
"latestScheduled": "0001-01-01T00:00:00Z"
2019-09-18 20:19:51 +00:00
}
]
2019-07-25 10:30:25 +00:00
}
`,
},
},
{
name: "get all checks when there are none",
fields: fields{
&mock.CheckService{
FindChecksFn: func(ctx context.Context, filter influxdb.CheckFilter, opts ...influxdb.FindOptions) ([]influxdb.Check, int, error) {
return []influxdb.Check{}, 0, nil
},
},
&mock.LabelService{},
},
args: args{
map[string][]string{
"limit": {"1"},
},
},
wants: wants{
statusCode: http.StatusOK,
contentType: "application/json; charset=utf-8",
body: `
{
"links": {
"self": "/api/v2/checks?descending=false&limit=1&offset=0"
},
"checks": []
}`,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
checkBackend := NewMockCheckBackend(t)
2019-07-25 10:30:25 +00:00
checkBackend.CheckService = tt.fields.CheckService
checkBackend.LabelService = tt.fields.LabelService
2019-09-18 20:19:51 +00:00
checkBackend.TaskService = &mock.TaskService{
FindTaskByIDFn: func(ctx context.Context, id platform.ID) (*taskmodel.Task, error) {
return &taskmodel.Task{Status: "active"}, nil
2019-09-18 20:19:51 +00:00
},
}
h := NewCheckHandler(zaptest.NewLogger(t), checkBackend)
2019-07-25 10:30:25 +00:00
r := httptest.NewRequest("GET", "http://any.url", nil)
qp := r.URL.Query()
for k, vs := range tt.args.queryParams {
for _, v := range vs {
qp.Add(k, v)
}
}
r.URL.RawQuery = qp.Encode()
2019-10-21 18:11:08 +00:00
r = r.WithContext(pcontext.SetAuthorizer(r.Context(), &influxdb.Session{UserID: influxTesting.MustIDBase16("6f626f7274697321")}))
2019-07-25 10:30:25 +00:00
w := httptest.NewRecorder()
h.handleGetChecks(w, r)
res := w.Result()
content := res.Header.Get("Content-Type")
2021-10-12 21:55:07 +00:00
body, _ := io.ReadAll(res.Body)
2019-07-25 10:30:25 +00:00
if res.StatusCode != tt.wants.statusCode {
t.Errorf("%q. handleGetChecks() = %v, want %v", tt.name, res.StatusCode, tt.wants.statusCode)
}
if tt.wants.contentType != "" && content != tt.wants.contentType {
t.Errorf("%q. handleGetChecks() = %v, want %v", tt.name, content, tt.wants.contentType)
}
if eq, diff, err := jsonEqual(string(body), tt.wants.body); err != nil || tt.wants.body != "" && !eq {
2019-09-18 20:19:51 +00:00
t.Errorf("%v", err)
2019-07-25 10:30:25 +00:00
t.Errorf("%q. handleGetChecks() = ***%v***", tt.name, diff)
}
})
}
}
func mustDuration(d string) *notification.Duration {
feat(checks): add first pass at creating tasks from checks First pass at flux AST generation from check Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): format call expression Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): cleanup CheckDefinition Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): clean up threshold functions Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): clean up message function Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): misc fixes Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): remove dead code Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): move threshold flux generation to check pkg Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): move base ast generation to its own package Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): add comment for GenerateFluxAST Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> docs(notification/flux): add comments to each exported function Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> feat(notification/check): add tests for GenerateFlux Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> feat(notification/check): add task options to generated flux fix(notification/check): use flux compatible duration type test(notification/check): add task option to task definition test(http): use check Duration in checks http handlers feat(check): add TaskID to checks base fix(notification/check): hack around issue with formatting ast package wtih multiple files test(check): create task when check is created A lot of little changes had to happen as a result of this. This change was rather painful. feat(checks): add update and delete of task for check fix(notifications/check): hack around the alerts package not being available test(kv): temporarily skip check tests while we merge the pr above
2019-08-07 22:34:07 +00:00
dur, err := parser.ParseDuration(d)
if err != nil {
panic(err)
}
return (*notification.Duration)(dur)
feat(checks): add first pass at creating tasks from checks First pass at flux AST generation from check Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): format call expression Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): cleanup CheckDefinition Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): clean up threshold functions Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): clean up message function Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): misc fixes Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): remove dead code Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): move threshold flux generation to check pkg Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): move base ast generation to its own package Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): add comment for GenerateFluxAST Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> docs(notification/flux): add comments to each exported function Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> feat(notification/check): add tests for GenerateFlux Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> feat(notification/check): add task options to generated flux fix(notification/check): use flux compatible duration type test(notification/check): add task option to task definition test(http): use check Duration in checks http handlers feat(check): add TaskID to checks base fix(notification/check): hack around issue with formatting ast package wtih multiple files test(check): create task when check is created A lot of little changes had to happen as a result of this. This change was rather painful. feat(checks): add update and delete of task for check fix(notifications/check): hack around the alerts package not being available test(kv): temporarily skip check tests while we merge the pr above
2019-08-07 22:34:07 +00:00
}
2019-08-22 16:18:02 +00:00
func TestService_handleGetCheckQuery(t *testing.T) {
type fields struct {
CheckService influxdb.CheckService
}
var l float64 = 10
var u float64 = 40
type args struct {
id string
}
type wants struct {
statusCode int
contentType string
body string
}
tests := []struct {
name string
fields fields
args args
wants wants
}{
{
name: "get a check query by id",
fields: fields{
&mock.CheckService{
FindCheckByIDFn: func(ctx context.Context, id platform.ID) (influxdb.Check, error) {
2019-08-22 16:18:02 +00:00
if id == influxTesting.MustIDBase16("020f755c3c082000") {
return &check.Threshold{
Base: check.Base{
ID: influxTesting.MustIDBase16("020f755c3c082000"),
OrgID: influxTesting.MustIDBase16("020f755c3c082000"),
Name: "hello",
TaskID: 3,
Tags: []influxdb.Tag{
2019-08-22 16:18:02 +00:00
{Key: "aaa", Value: "vaaa"},
{Key: "bbb", Value: "vbbb"},
},
Every: mustDuration("1h"),
StatusMessageTemplate: "whoa! {check.yeah}",
Query: influxdb.DashboardQuery{
Text: `from(bucket: "foo") |> range(start: -1d, stop: now()) |> filter(fn: (r) => r._field == "usage_idle") |> aggregateWindow(every: 1m, fn: mean) |> yield()`,
2019-08-22 16:18:02 +00:00
},
},
Thresholds: []check.ThresholdConfig{
check.Greater{
ThresholdConfigBase: check.ThresholdConfigBase{
Level: notification.Ok,
},
Value: l,
},
check.Lesser{
ThresholdConfigBase: check.ThresholdConfigBase{
Level: notification.Info,
},
Value: u,
},
check.Range{
ThresholdConfigBase: check.ThresholdConfigBase{
Level: notification.Warn,
},
Min: l,
Max: u,
Within: true,
},
check.Range{
ThresholdConfigBase: check.ThresholdConfigBase{
Level: notification.Critical,
},
Min: l,
Max: u,
Within: true,
},
},
}, nil
}
return nil, fmt.Errorf("not found")
},
},
},
args: args{
id: "020f755c3c082000",
},
wants: wants{
statusCode: http.StatusOK,
contentType: "application/json; charset=utf-8",
body: "{\"flux\":" + formatFluxJson(t, `import "influxdata/influxdb/monitor"
import "influxdata/influxdb/v1"
data =
from(bucket: "foo")
|> range(start: -1h)
|> filter(fn: (r) => r._field == "usage_idle")
|> aggregateWindow(every: 1h, fn: mean, createEmpty: false)
option task = {name: "hello", every: 1h}
check = {_check_id: "020f755c3c082000", _check_name: "hello", _type: "threshold", tags: {aaa: "vaaa", bbb: "vbbb"}}
ok = (r) => r["usage_idle"] > 10.0
info = (r) => r["usage_idle"] < 40.0
warn = (r) => r["usage_idle"] < 40.0 and r["usage_idle"] > 10.0
crit = (r) => r["usage_idle"] < 40.0 and r["usage_idle"] > 10.0
messageFn = (r) => "whoa! {check.yeah}"
data
|> v1["fieldsAsCols"]()
|> monitor["check"](
data: check,
messageFn: messageFn,
ok: ok,
info: info,
warn: warn,
crit: crit,
)
`) + "}\n",
2019-08-22 16:18:02 +00:00
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
checkBackend := NewMockCheckBackend(t)
checkBackend.HTTPErrorHandler = kithttp.NewErrorHandler(zaptest.NewLogger(t))
2019-08-22 16:18:02 +00:00
checkBackend.CheckService = tt.fields.CheckService
2019-09-18 20:19:51 +00:00
checkBackend.TaskService = &mock.TaskService{
FindTaskByIDFn: func(ctx context.Context, id platform.ID) (*taskmodel.Task, error) {
return &taskmodel.Task{}, nil
2019-09-18 20:19:51 +00:00
},
}
2019-08-22 16:18:02 +00:00
testttp.
Get(t, path.Join(prefixChecks, tt.args.id, "/query")).
Do(NewCheckHandler(zaptest.NewLogger(t), checkBackend)).
ExpectStatus(tt.wants.statusCode).
Expect(func(resp *testttp.Resp) {
content := resp.Rec.Header().Get("Content-Type")
if tt.wants.contentType != "" && content != tt.wants.contentType {
t.Errorf("%q. handleGetCheckQuery() = %v, want %v", tt.name, content, tt.wants.contentType)
}
}).
ExpectBody(func(body *bytes.Buffer) {
if eq, diff, err := jsonEqual(body.String(), tt.wants.body); err != nil || tt.wants.body != "" && !eq {
if err != nil {
t.Errorf("jsonEqual error: %v", err)
}
t.Errorf("%q. handleGetChecks() = ***%v***", tt.name, diff)
}
})
2019-08-22 16:18:02 +00:00
})
}
}
func formatFluxJson(t *testing.T, script string) string {
formatted := influxTesting.FormatFluxString(t, script)
enc, err := json.Marshal(formatted)
if err != nil {
t.Fatalf("error marshalling flux: %v", err)
}
var bb bytes.Buffer
json.HTMLEscape(&bb, enc)
std := bb.String()
return std
}
2019-07-25 10:30:25 +00:00
func TestService_handleGetCheck(t *testing.T) {
type fields struct {
CheckService influxdb.CheckService
}
type args struct {
id string
}
type wants struct {
statusCode int
contentType string
body string
}
tests := []struct {
name string
fields fields
args args
wants wants
}{
{
name: "get a check by id",
fields: fields{
&mock.CheckService{
FindCheckByIDFn: func(ctx context.Context, id platform.ID) (influxdb.Check, error) {
2019-07-25 10:30:25 +00:00
if id == influxTesting.MustIDBase16("020f755c3c082000") {
return &check.Deadman{
Base: check.Base{
ID: influxTesting.MustIDBase16("020f755c3c082000"),
OrgID: influxTesting.MustIDBase16("020f755c3c082000"),
Name: "hello",
feat(checks): add first pass at creating tasks from checks First pass at flux AST generation from check Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): format call expression Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): cleanup CheckDefinition Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): clean up threshold functions Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): clean up message function Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): misc fixes Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): remove dead code Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): move threshold flux generation to check pkg Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): move base ast generation to its own package Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): add comment for GenerateFluxAST Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> docs(notification/flux): add comments to each exported function Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> feat(notification/check): add tests for GenerateFlux Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> feat(notification/check): add task options to generated flux fix(notification/check): use flux compatible duration type test(notification/check): add task option to task definition test(http): use check Duration in checks http handlers feat(check): add TaskID to checks base fix(notification/check): hack around issue with formatting ast package wtih multiple files test(check): create task when check is created A lot of little changes had to happen as a result of this. This change was rather painful. feat(checks): add update and delete of task for check fix(notifications/check): hack around the alerts package not being available test(kv): temporarily skip check tests while we merge the pr above
2019-08-07 22:34:07 +00:00
Every: mustDuration("3h"),
TaskID: 3,
2019-07-25 10:30:25 +00:00
},
Level: notification.Critical,
}, nil
}
return nil, fmt.Errorf("not found")
},
},
},
args: args{
id: "020f755c3c082000",
},
wants: wants{
statusCode: http.StatusOK,
contentType: "application/json; charset=utf-8",
body: `
{
"links": {
"self": "/api/v2/checks/020f755c3c082000",
"labels": "/api/v2/checks/020f755c3c082000/labels",
"members": "/api/v2/checks/020f755c3c082000/members",
"owners": "/api/v2/checks/020f755c3c082000/owners",
"query": "/api/v2/checks/020f755c3c082000/query"
2019-07-25 10:30:25 +00:00
},
"labels": [],
"level": "CRIT",
feat(checks): add first pass at creating tasks from checks First pass at flux AST generation from check Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): format call expression Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): cleanup CheckDefinition Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): clean up threshold functions Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): clean up message function Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): misc fixes Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): remove dead code Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): move threshold flux generation to check pkg Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): move base ast generation to its own package Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): add comment for GenerateFluxAST Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> docs(notification/flux): add comments to each exported function Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> feat(notification/check): add tests for GenerateFlux Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> feat(notification/check): add task options to generated flux fix(notification/check): use flux compatible duration type test(notification/check): add task option to task definition test(http): use check Duration in checks http handlers feat(check): add TaskID to checks base fix(notification/check): hack around issue with formatting ast package wtih multiple files test(check): create task when check is created A lot of little changes had to happen as a result of this. This change was rather painful. feat(checks): add update and delete of task for check fix(notifications/check): hack around the alerts package not being available test(kv): temporarily skip check tests while we merge the pr above
2019-08-07 22:34:07 +00:00
"every": "3h",
2019-07-25 10:30:25 +00:00
"createdAt": "0001-01-01T00:00:00Z",
"updatedAt": "0001-01-01T00:00:00Z",
"id": "020f755c3c082000",
"query": {
"builderConfig": {
"aggregateWindow": {
"fillValues": false,
"period": ""
2019-07-25 10:30:25 +00:00
},
"buckets": [],
"functions": [],
"tags": []
2019-07-25 10:30:25 +00:00
},
"editMode": "",
"name": "",
"text": ""
},
"reportZero": false,
"status": "active",
"statusMessageTemplate": "",
"tags": null,
"taskID": "0000000000000003",
2019-07-25 10:30:25 +00:00
"type": "deadman",
"orgID": "020f755c3c082000",
2019-09-18 20:19:51 +00:00
"name": "hello",
"status": "active",
"latestCompleted": "0001-01-01T00:00:00Z",
"latestScheduled": "0001-01-01T00:00:00Z"
2019-07-25 10:30:25 +00:00
}
`,
},
},
{
name: "not found",
fields: fields{
&mock.CheckService{
FindCheckByIDFn: func(ctx context.Context, id platform.ID) (influxdb.Check, error) {
return nil, &errors.Error{
Code: errors.ENotFound,
2019-07-25 10:30:25 +00:00
Msg: "check not found",
}
},
},
},
args: args{
id: "020f755c3c082000",
},
wants: wants{
statusCode: http.StatusNotFound,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
checkBackend := NewMockCheckBackend(t)
checkBackend.HTTPErrorHandler = kithttp.NewErrorHandler(zaptest.NewLogger(t))
2019-07-25 10:30:25 +00:00
checkBackend.CheckService = tt.fields.CheckService
2019-09-18 20:19:51 +00:00
checkBackend.TaskService = &mock.TaskService{
FindTaskByIDFn: func(ctx context.Context, id platform.ID) (*taskmodel.Task, error) {
return &taskmodel.Task{Status: "active"}, nil
2019-09-18 20:19:51 +00:00
},
}
h := NewCheckHandler(zaptest.NewLogger(t), checkBackend)
2019-07-25 10:30:25 +00:00
r := httptest.NewRequest("GET", "http://any.url", nil)
r = r.WithContext(context.WithValue(
context.Background(),
httprouter.ParamsKey,
httprouter.Params{
{
Key: "id",
Value: tt.args.id,
},
}))
w := httptest.NewRecorder()
h.handleGetCheck(w, r)
res := w.Result()
content := res.Header.Get("Content-Type")
2021-10-12 21:55:07 +00:00
body, _ := io.ReadAll(res.Body)
2019-07-25 10:30:25 +00:00
t.Logf(res.Header.Get("X-Influx-Error"))
if res.StatusCode != tt.wants.statusCode {
t.Errorf("%q. handleGetCheck() = %v, want %v", tt.name, res.StatusCode, tt.wants.statusCode)
}
if tt.wants.contentType != "" && content != tt.wants.contentType {
t.Errorf("%q. handleGetCheck() = %v, want %v", tt.name, content, tt.wants.contentType)
}
if tt.wants.body != "" {
if eq, diff, err := jsonEqual(string(body), tt.wants.body); err != nil {
t.Errorf("%q, handleGetCheck(). error unmarshalling json %v", tt.name, err)
2019-07-25 10:30:25 +00:00
} else if !eq {
t.Errorf("%q. handleGetCheck() = ***%s***", tt.name, diff)
}
}
})
}
}
func TestService_handlePostCheck(t *testing.T) {
type fields struct {
CheckService influxdb.CheckService
OrganizationService influxdb.OrganizationService
}
type args struct {
userID platform.ID
check influxdb.Check
2019-07-25 10:30:25 +00:00
}
type wants struct {
statusCode int
contentType string
body string
}
tests := []struct {
name string
fields fields
args args
wants wants
}{
{
name: "create a new check",
fields: fields{
CheckService: &mock.CheckService{
CreateCheckFn: func(ctx context.Context, c influxdb.CheckCreate, userID platform.ID) error {
2019-07-25 10:30:25 +00:00
c.SetID(influxTesting.MustIDBase16("020f755c3c082000"))
c.SetOwnerID(userID)
2019-07-25 10:30:25 +00:00
return nil
},
},
OrganizationService: &mock.OrganizationService{
FindOrganizationF: func(ctx context.Context, f influxdb.OrganizationFilter) (*influxdb.Organization, error) {
return &influxdb.Organization{ID: influxTesting.MustIDBase16("6f626f7274697320")}, nil
},
},
},
args: args{
userID: influxTesting.MustIDBase16("6f626f7274697321"),
2019-07-25 10:30:25 +00:00
check: &check.Deadman{
Base: check.Base{
Name: "hello",
OrgID: influxTesting.MustIDBase16("6f626f7274697320"),
OwnerID: influxTesting.MustIDBase16("6f626f7274697321"),
2019-07-25 10:30:25 +00:00
Description: "desc1",
StatusMessageTemplate: "msg1",
feat(checks): add first pass at creating tasks from checks First pass at flux AST generation from check Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): format call expression Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): cleanup CheckDefinition Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): clean up threshold functions Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): clean up message function Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): misc fixes Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): remove dead code Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): move threshold flux generation to check pkg Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): move base ast generation to its own package Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): add comment for GenerateFluxAST Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> docs(notification/flux): add comments to each exported function Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> feat(notification/check): add tests for GenerateFlux Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> feat(notification/check): add task options to generated flux fix(notification/check): use flux compatible duration type test(notification/check): add task option to task definition test(http): use check Duration in checks http handlers feat(check): add TaskID to checks base fix(notification/check): hack around issue with formatting ast package wtih multiple files test(check): create task when check is created A lot of little changes had to happen as a result of this. This change was rather painful. feat(checks): add update and delete of task for check fix(notifications/check): hack around the alerts package not being available test(kv): temporarily skip check tests while we merge the pr above
2019-08-07 22:34:07 +00:00
Every: mustDuration("5m"),
TaskID: 3,
Tags: []influxdb.Tag{
2019-07-25 10:30:25 +00:00
{Key: "k1", Value: "v1"},
{Key: "k2", Value: "v2"},
},
},
TimeSince: mustDuration("13s"),
2019-07-25 10:30:25 +00:00
ReportZero: true,
Level: notification.Warn,
},
},
wants: wants{
statusCode: http.StatusCreated,
contentType: "application/json; charset=utf-8",
body: `
{
"links": {
"self": "/api/v2/checks/020f755c3c082000",
"labels": "/api/v2/checks/020f755c3c082000/labels",
"members": "/api/v2/checks/020f755c3c082000/members",
"owners": "/api/v2/checks/020f755c3c082000/owners",
"query": "/api/v2/checks/020f755c3c082000/query"
2019-07-25 10:30:25 +00:00
},
"reportZero": true,
"statusMessageTemplate": "msg1",
"tags": [
{
"key": "k1",
"value": "v1"
},
{
"key": "k2",
"value": "v2"
}
],
"query": {
"builderConfig": {
"aggregateWindow": {
"fillValues": false,
2019-07-25 10:30:25 +00:00
"period": ""
},
"buckets": [],
"functions": [],
"tags": []
2019-07-25 10:30:25 +00:00
},
"editMode": "",
"name": "",
"text": ""
},
"taskID": "0000000000000003",
2019-07-25 10:30:25 +00:00
"type": "deadman",
"timeSince": "13s",
2019-07-25 10:30:25 +00:00
"createdAt": "0001-01-01T00:00:00Z",
"updatedAt": "0001-01-01T00:00:00Z",
"id": "020f755c3c082000",
"orgID": "6f626f7274697320",
"name": "hello",
"ownerID": "6f626f7274697321",
2019-07-25 10:30:25 +00:00
"description": "desc1",
feat(checks): add first pass at creating tasks from checks First pass at flux AST generation from check Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): format call expression Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): cleanup CheckDefinition Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): clean up threshold functions Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): clean up message function Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): misc fixes Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): remove dead code Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): move threshold flux generation to check pkg Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): move base ast generation to its own package Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): add comment for GenerateFluxAST Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> docs(notification/flux): add comments to each exported function Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> feat(notification/check): add tests for GenerateFlux Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> feat(notification/check): add task options to generated flux fix(notification/check): use flux compatible duration type test(notification/check): add task option to task definition test(http): use check Duration in checks http handlers feat(check): add TaskID to checks base fix(notification/check): hack around issue with formatting ast package wtih multiple files test(check): create task when check is created A lot of little changes had to happen as a result of this. This change was rather painful. feat(checks): add update and delete of task for check fix(notifications/check): hack around the alerts package not being available test(kv): temporarily skip check tests while we merge the pr above
2019-08-07 22:34:07 +00:00
"every": "5m",
2019-07-25 10:30:25 +00:00
"level": "WARN",
2019-09-18 20:19:51 +00:00
"labels": [],
"status": "active",
"latestCompleted": "0001-01-01T00:00:00Z",
"latestScheduled": "0001-01-01T00:00:00Z"
2019-07-25 10:30:25 +00:00
}
`,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
checkBackend := NewMockCheckBackend(t)
2019-07-25 10:30:25 +00:00
checkBackend.CheckService = tt.fields.CheckService
checkBackend.OrganizationService = tt.fields.OrganizationService
2019-09-18 20:19:51 +00:00
checkBackend.TaskService = &mock.TaskService{
FindTaskByIDFn: func(ctx context.Context, id platform.ID) (*taskmodel.Task, error) {
return &taskmodel.Task{Status: "active"}, nil
2019-09-18 20:19:51 +00:00
},
}
h := NewCheckHandler(zaptest.NewLogger(t), checkBackend)
2019-07-25 10:30:25 +00:00
b, err := json.Marshal(tt.args.check)
if err != nil {
t.Fatalf("failed to unmarshal check: %v", err)
}
r := httptest.NewRequest("GET", "http://any.url?org=30", bytes.NewReader(b))
w := httptest.NewRecorder()
r = r.WithContext(pcontext.SetAuthorizer(r.Context(), &influxdb.Session{UserID: tt.args.userID}))
2019-07-25 10:30:25 +00:00
h.handlePostCheck(w, r)
res := w.Result()
content := res.Header.Get("Content-Type")
2021-10-12 21:55:07 +00:00
body, _ := io.ReadAll(res.Body)
2019-07-25 10:30:25 +00:00
if res.StatusCode != tt.wants.statusCode {
t.Errorf("%q. handlePostCheck() = %v, want %v", tt.name, res.StatusCode, tt.wants.statusCode)
}
if tt.wants.contentType != "" && content != tt.wants.contentType {
t.Errorf("%q. handlePostCheck() = %v, want %v", tt.name, content, tt.wants.contentType)
}
if tt.wants.body != "" {
if eq, diff, err := jsonEqual(string(body), tt.wants.body); err != nil {
t.Errorf("%q, handlePostCheck(). error unmarshalling json %v", tt.name, err)
2019-07-25 10:30:25 +00:00
} else if !eq {
t.Errorf("%q. handlePostCheck() = ***%s***", tt.name, diff)
}
}
})
}
}
func TestService_handleDeleteCheck(t *testing.T) {
type fields struct {
CheckService influxdb.CheckService
}
type args struct {
id string
}
type wants struct {
statusCode int
contentType string
body string
}
tests := []struct {
name string
fields fields
args args
wants wants
}{
{
name: "remove a check by id",
fields: fields{
&mock.CheckService{
DeleteCheckFn: func(ctx context.Context, id platform.ID) error {
2019-07-25 10:30:25 +00:00
if id == influxTesting.MustIDBase16("020f755c3c082000") {
return nil
}
return fmt.Errorf("wrong id")
},
},
},
args: args{
id: "020f755c3c082000",
},
wants: wants{
statusCode: http.StatusNoContent,
},
},
{
name: "check not found",
fields: fields{
&mock.CheckService{
DeleteCheckFn: func(ctx context.Context, id platform.ID) error {
return &errors.Error{
Code: errors.ENotFound,
2019-07-25 10:30:25 +00:00
Msg: "check not found",
}
},
},
},
args: args{
id: "020f755c3c082000",
},
wants: wants{
statusCode: http.StatusNotFound,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
checkBackend := NewMockCheckBackend(t)
checkBackend.HTTPErrorHandler = kithttp.NewErrorHandler(zaptest.NewLogger(t))
2019-07-25 10:30:25 +00:00
checkBackend.CheckService = tt.fields.CheckService
2019-09-18 20:19:51 +00:00
checkBackend.TaskService = &mock.TaskService{
FindTaskByIDFn: func(ctx context.Context, id platform.ID) (*taskmodel.Task, error) {
return &taskmodel.Task{}, nil
2019-09-18 20:19:51 +00:00
},
}
h := NewCheckHandler(zaptest.NewLogger(t), checkBackend)
2019-07-25 10:30:25 +00:00
r := httptest.NewRequest("GET", "http://any.url", nil)
r = r.WithContext(context.WithValue(
context.Background(),
httprouter.ParamsKey,
httprouter.Params{
{
Key: "id",
Value: tt.args.id,
},
}))
w := httptest.NewRecorder()
h.handleDeleteCheck(w, r)
res := w.Result()
content := res.Header.Get("Content-Type")
2021-10-12 21:55:07 +00:00
body, _ := io.ReadAll(res.Body)
2019-07-25 10:30:25 +00:00
if res.StatusCode != tt.wants.statusCode {
t.Errorf("%q. handleDeleteCheck() = %v, want %v", tt.name, res.StatusCode, tt.wants.statusCode)
}
if tt.wants.contentType != "" && content != tt.wants.contentType {
t.Errorf("%q. handleDeleteCheck() = %v, want %v", tt.name, content, tt.wants.contentType)
}
if tt.wants.body != "" {
if eq, diff, err := jsonEqual(string(body), tt.wants.body); err != nil {
t.Errorf("%q, handleDeleteCheck(). error unmarshalling json %v", tt.name, err)
2019-07-25 10:30:25 +00:00
} else if !eq {
t.Errorf("%q. handleDeleteCheck() = ***%s***", tt.name, diff)
}
}
})
}
}
func TestService_handlePatchCheck(t *testing.T) {
type fields struct {
CheckService influxdb.CheckService
}
type args struct {
id string
name string
}
type wants struct {
statusCode int
contentType string
body string
}
tests := []struct {
name string
fields fields
args args
wants wants
}{
{
name: "update a check name",
2019-07-25 10:30:25 +00:00
fields: fields{
&mock.CheckService{
PatchCheckFn: func(ctx context.Context, id platform.ID, upd influxdb.CheckUpdate) (influxdb.Check, error) {
2019-07-25 10:30:25 +00:00
if id == influxTesting.MustIDBase16("020f755c3c082000") {
d := &check.Deadman{
Base: check.Base{
feat(checks): add first pass at creating tasks from checks First pass at flux AST generation from check Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): format call expression Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): cleanup CheckDefinition Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): clean up threshold functions Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): clean up message function Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): misc fixes Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): remove dead code Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): move threshold flux generation to check pkg Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): move base ast generation to its own package Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): add comment for GenerateFluxAST Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> docs(notification/flux): add comments to each exported function Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> feat(notification/check): add tests for GenerateFlux Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> feat(notification/check): add task options to generated flux fix(notification/check): use flux compatible duration type test(notification/check): add task option to task definition test(http): use check Duration in checks http handlers feat(check): add TaskID to checks base fix(notification/check): hack around issue with formatting ast package wtih multiple files test(check): create task when check is created A lot of little changes had to happen as a result of this. This change was rather painful. feat(checks): add update and delete of task for check fix(notifications/check): hack around the alerts package not being available test(kv): temporarily skip check tests while we merge the pr above
2019-08-07 22:34:07 +00:00
ID: influxTesting.MustIDBase16("020f755c3c082000"),
Name: "hello",
OrgID: influxTesting.MustIDBase16("020f755c3c082000"),
TaskID: 3,
2019-07-25 10:30:25 +00:00
},
Level: notification.Critical,
}
if upd.Name != nil {
d.Name = *upd.Name
}
return d, nil
}
return nil, fmt.Errorf("not found")
},
},
},
args: args{
id: "020f755c3c082000",
name: "example",
},
wants: wants{
statusCode: http.StatusOK,
contentType: "application/json; charset=utf-8",
body: `
{
"links": {
"self": "/api/v2/checks/020f755c3c082000",
"labels": "/api/v2/checks/020f755c3c082000/labels",
"members": "/api/v2/checks/020f755c3c082000/members",
"owners": "/api/v2/checks/020f755c3c082000/owners",
"query": "/api/v2/checks/020f755c3c082000/query"
2019-07-25 10:30:25 +00:00
},
"createdAt": "0001-01-01T00:00:00Z",
"updatedAt": "0001-01-01T00:00:00Z",
"id": "020f755c3c082000",
"orgID": "020f755c3c082000",
"level": "CRIT",
"name": "example",
"query": {
2019-09-18 20:19:51 +00:00
"builderConfig": {
"aggregateWindow": {
"fillValues": false,
2019-09-18 20:19:51 +00:00
"period": ""
},
"buckets": [],
"functions": [],
"tags": []
2019-09-18 20:19:51 +00:00
},
"editMode": "",
"name": "",
"text": ""
},
"reportZero": false,
"status": "active",
"statusMessageTemplate": "",
"tags": null,
"taskID": "0000000000000003",
2019-09-18 20:19:51 +00:00
"type": "deadman",
"labels": [],
"latestCompleted": "0001-01-01T00:00:00Z",
"latestScheduled": "0001-01-01T00:00:00Z"
2019-07-25 10:30:25 +00:00
}
`,
},
},
{
name: "check not found",
fields: fields{
&mock.CheckService{
PatchCheckFn: func(ctx context.Context, id platform.ID, upd influxdb.CheckUpdate) (influxdb.Check, error) {
return nil, &errors.Error{
Code: errors.ENotFound,
2019-07-25 10:30:25 +00:00
Msg: "check not found",
}
},
},
},
args: args{
id: "020f755c3c082000",
name: "hello",
},
wants: wants{
statusCode: http.StatusNotFound,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
checkBackend := NewMockCheckBackend(t)
checkBackend.HTTPErrorHandler = kithttp.NewErrorHandler(zaptest.NewLogger(t))
2019-07-25 10:30:25 +00:00
checkBackend.CheckService = tt.fields.CheckService
2019-09-18 20:19:51 +00:00
checkBackend.TaskService = &mock.TaskService{
FindTaskByIDFn: func(ctx context.Context, id platform.ID) (*taskmodel.Task, error) {
return &taskmodel.Task{Status: "active"}, nil
2019-09-18 20:19:51 +00:00
},
}
h := NewCheckHandler(zaptest.NewLogger(t), checkBackend)
2019-07-25 10:30:25 +00:00
upd := influxdb.CheckUpdate{}
if tt.args.name != "" {
upd.Name = &tt.args.name
}
b, err := json.Marshal(upd)
if err != nil {
t.Fatalf("failed to unmarshal check update: %v", err)
}
r := httptest.NewRequest("GET", "http://any.url", bytes.NewReader(b))
r = r.WithContext(context.WithValue(
context.Background(),
httprouter.ParamsKey,
httprouter.Params{
{
Key: "id",
Value: tt.args.id,
},
}))
w := httptest.NewRecorder()
h.handlePatchCheck(w, r)
res := w.Result()
content := res.Header.Get("Content-Type")
2021-10-12 21:55:07 +00:00
body, _ := io.ReadAll(res.Body)
2019-07-25 10:30:25 +00:00
if res.StatusCode != tt.wants.statusCode {
t.Errorf("%q. handlePatchCheck() = %v, want %v %v", tt.name, res.StatusCode, tt.wants.statusCode, w.Header())
}
if tt.wants.contentType != "" && content != tt.wants.contentType {
t.Errorf("%q. handlePatchCheck() = %v, want %v", tt.name, content, tt.wants.contentType)
}
if tt.wants.body != "" {
if eq, diff, err := jsonEqual(string(body), tt.wants.body); err != nil {
t.Errorf("%q, handlePatchCheck(). error unmarshalling json %v", tt.name, err)
2019-07-25 10:30:25 +00:00
} else if !eq {
t.Errorf("%q. handlePatchCheck() = ***%s***", tt.name, diff)
}
}
})
}
}
func TestService_handleUpdateCheck(t *testing.T) {
type fields struct {
CheckService influxdb.CheckService
}
type args struct {
id string
chk influxdb.Check
}
type wants struct {
statusCode int
contentType string
body string
}
tests := []struct {
name string
fields fields
args args
wants wants
}{
{
name: "update a check name",
2019-07-25 10:30:25 +00:00
fields: fields{
CheckService: &mock.CheckService{
UpdateCheckFn: func(ctx context.Context, id platform.ID, chk influxdb.CheckCreate) (influxdb.Check, error) {
2019-07-25 10:30:25 +00:00
if id == influxTesting.MustIDBase16("020f755c3c082000") {
d := &check.Deadman{
Base: check.Base{
ID: influxTesting.MustIDBase16("020f755c3c082000"),
Name: "hello",
OrgID: influxTesting.MustIDBase16("020f755c3c082000"),
feat(checks): add first pass at creating tasks from checks First pass at flux AST generation from check Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): format call expression Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): cleanup CheckDefinition Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): clean up threshold functions Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): clean up message function Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): misc fixes Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): remove dead code Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): move threshold flux generation to check pkg Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): move base ast generation to its own package Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> fix(notification/check): add comment for GenerateFluxAST Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> docs(notification/flux): add comments to each exported function Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> feat(notification/check): add tests for GenerateFlux Co-authored-by: Michael Desa <mjdesa@gmail.com> Co-authored-by: Deniz Kusefoglu <deniz@influxdata.com> feat(notification/check): add task options to generated flux fix(notification/check): use flux compatible duration type test(notification/check): add task option to task definition test(http): use check Duration in checks http handlers feat(check): add TaskID to checks base fix(notification/check): hack around issue with formatting ast package wtih multiple files test(check): create task when check is created A lot of little changes had to happen as a result of this. This change was rather painful. feat(checks): add update and delete of task for check fix(notifications/check): hack around the alerts package not being available test(kv): temporarily skip check tests while we merge the pr above
2019-08-07 22:34:07 +00:00
TaskID: 3,
Every: mustDuration("1m"),
2019-07-25 10:30:25 +00:00
},
}
2019-09-18 20:19:51 +00:00
d = chk.Check.(*check.Deadman)
2019-07-25 10:30:25 +00:00
d.SetID(influxTesting.MustIDBase16("020f755c3c082000"))
d.SetOrgID(influxTesting.MustIDBase16("020f755c3c082000"))
return d, nil
}
return nil, fmt.Errorf("not found")
},
},
},
args: args{
id: "020f755c3c082000",
chk: &check.Deadman{
Base: check.Base{
Name: "example",
TaskID: 3,
OwnerID: 42,
OrgID: influxTesting.MustIDBase16("020f755c3c082000"),
Every: mustDuration("1m"),
2019-07-25 10:30:25 +00:00
},
Level: notification.Critical,
},
},
wants: wants{
statusCode: http.StatusOK,
contentType: "application/json; charset=utf-8",
body: `
{
"links": {
"self": "/api/v2/checks/020f755c3c082000",
"labels": "/api/v2/checks/020f755c3c082000/labels",
"members": "/api/v2/checks/020f755c3c082000/members",
"owners": "/api/v2/checks/020f755c3c082000/owners",
"query": "/api/v2/checks/020f755c3c082000/query"
2019-07-25 10:30:25 +00:00
},
"createdAt": "0001-01-01T00:00:00Z",
"updatedAt": "0001-01-01T00:00:00Z",
"id": "020f755c3c082000",
"every": "1m",
2019-07-25 10:30:25 +00:00
"orgID": "020f755c3c082000",
"ownerID": "000000000000002a",
2019-07-25 10:30:25 +00:00
"level": "CRIT",
"name": "example",
"query": {
"builderConfig": {
"aggregateWindow": {
"fillValues": false,
2019-07-25 10:30:25 +00:00
"period": ""
},
"buckets": [],
"functions": [],
"tags": []
2019-07-25 10:30:25 +00:00
},
"editMode": "",
"name": "",
"text": ""
},
"reportZero": false,
"status": "active",
"statusMessageTemplate": "",
"tags": null,
"taskID": "0000000000000003",
2019-07-25 10:30:25 +00:00
"type": "deadman",
"labels": [],
"latestCompleted": "0001-01-01T00:00:00Z",
"latestScheduled": "0001-01-01T00:00:00Z"
2019-07-25 10:30:25 +00:00
}
`,
},
},
{
name: "check not found",
fields: fields{
CheckService: &mock.CheckService{
UpdateCheckFn: func(ctx context.Context, id platform.ID, chk influxdb.CheckCreate) (influxdb.Check, error) {
return nil, &errors.Error{
Code: errors.ENotFound,
2019-07-25 10:30:25 +00:00
Msg: "check not found",
}
},
},
},
args: args{
id: "020f755c3c082000",
chk: &check.Deadman{
Base: check.Base{
Name: "example",
OwnerID: 42,
OrgID: influxTesting.MustIDBase16("020f755c3c082000"),
Every: mustDuration("1m"),
2019-07-25 10:30:25 +00:00
},
},
},
wants: wants{
statusCode: http.StatusNotFound,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
checkBackend := NewMockCheckBackend(t)
checkBackend.HTTPErrorHandler = kithttp.NewErrorHandler(zaptest.NewLogger(t))
2019-07-25 10:30:25 +00:00
checkBackend.CheckService = tt.fields.CheckService
2019-09-18 20:19:51 +00:00
checkBackend.TaskService = &mock.TaskService{
FindTaskByIDFn: func(ctx context.Context, id platform.ID) (*taskmodel.Task, error) {
return &taskmodel.Task{Status: "active"}, nil
2019-09-18 20:19:51 +00:00
},
}
h := NewCheckHandler(zaptest.NewLogger(t), checkBackend)
2019-07-25 10:30:25 +00:00
b, err := json.Marshal(tt.args.chk)
if err != nil {
t.Fatalf("failed to unmarshal check update: %v", err)
}
r := httptest.NewRequest("GET", "http://any.url", bytes.NewReader(b))
r = r.WithContext(context.WithValue(
context.Background(),
httprouter.ParamsKey,
httprouter.Params{
{
Key: "id",
Value: tt.args.id,
},
}))
w := httptest.NewRecorder()
h.handlePutCheck(w, r)
res := w.Result()
content := res.Header.Get("Content-Type")
2021-10-12 21:55:07 +00:00
body, _ := io.ReadAll(res.Body)
2019-07-25 10:30:25 +00:00
if res.StatusCode != tt.wants.statusCode {
t.Errorf("%q. handlePutCheck() = %v, want %v %v %v", tt.name, res.StatusCode, tt.wants.statusCode, w.Header(), string(body))
2019-07-25 10:30:25 +00:00
}
if tt.wants.contentType != "" && content != tt.wants.contentType {
t.Errorf("%q. handlePutCheck() = %v, want %v", tt.name, content, tt.wants.contentType)
}
if tt.wants.body != "" {
if eq, diff, err := jsonEqual(string(body), tt.wants.body); err != nil {
t.Errorf("%q, handlePutCheck(). error unmarshalling json %v", tt.name, err)
2019-07-25 10:30:25 +00:00
} else if !eq {
t.Errorf("%q. handlePutCheck() = ***%s***", tt.name, diff)
}
}
})
}
}
func TestService_handlePostCheckMember(t *testing.T) {
type fields struct {
UserService influxdb.UserService
}
type args struct {
checkID string
user *influxdb.User
}
type wants struct {
statusCode int
contentType string
body string
}
tests := []struct {
name string
fields fields
args args
wants wants
}{
{
name: "add a check member",
fields: fields{
UserService: &mock.UserService{
FindUserByIDFn: func(ctx context.Context, id platform.ID) (*influxdb.User, error) {
2019-07-25 10:30:25 +00:00
return &influxdb.User{
ID: id,
Name: "name",
Status: influxdb.Active,
2019-07-25 10:30:25 +00:00
}, nil
},
},
},
args: args{
checkID: "020f755c3c082000",
user: &influxdb.User{
ID: influxTesting.MustIDBase16("6f626f7274697320"),
},
},
wants: wants{
statusCode: http.StatusCreated,
contentType: "application/json; charset=utf-8",
body: `
{
"links": {
"logs": "/api/v2/users/6f626f7274697320/logs",
"self": "/api/v2/users/6f626f7274697320"
},
"role": "member",
"id": "6f626f7274697320",
"name": "name",
"status": "active"
2019-07-25 10:30:25 +00:00
}
`,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
checkBackend := NewMockCheckBackend(t)
2019-07-25 10:30:25 +00:00
checkBackend.UserService = tt.fields.UserService
2019-09-18 20:19:51 +00:00
checkBackend.TaskService = &mock.TaskService{
FindTaskByIDFn: func(ctx context.Context, id platform.ID) (*taskmodel.Task, error) {
return &taskmodel.Task{}, nil
2019-09-18 20:19:51 +00:00
},
}
h := NewCheckHandler(zaptest.NewLogger(t), checkBackend)
2019-07-25 10:30:25 +00:00
b, err := json.Marshal(tt.args.user)
if err != nil {
t.Fatalf("failed to marshal user: %v", err)
}
path := fmt.Sprintf("/api/v2/checks/%s/members", tt.args.checkID)
r := httptest.NewRequest("POST", path, bytes.NewReader(b))
w := httptest.NewRecorder()
h.ServeHTTP(w, r)
res := w.Result()
content := res.Header.Get("Content-Type")
2021-10-12 21:55:07 +00:00
body, _ := io.ReadAll(res.Body)
2019-07-25 10:30:25 +00:00
if res.StatusCode != tt.wants.statusCode {
t.Errorf("%q. handlePostCheckMember() = %v, want %v", tt.name, res.StatusCode, tt.wants.statusCode)
}
if tt.wants.contentType != "" && content != tt.wants.contentType {
t.Errorf("%q. handlePostCheckMember() = %v, want %v", tt.name, content, tt.wants.contentType)
}
if eq, diff, err := jsonEqual(string(body), tt.wants.body); err != nil {
t.Errorf("%q, handlePostCheckMember(). error unmarshalling json %v", tt.name, err)
2019-07-25 10:30:25 +00:00
} else if tt.wants.body != "" && !eq {
t.Errorf("%q. handlePostCheckMember() = ***%s***", tt.name, diff)
}
})
}
}
func TestService_handlePostCheckOwner(t *testing.T) {
type fields struct {
UserService influxdb.UserService
}
type args struct {
checkID string
user *influxdb.User
}
type wants struct {
statusCode int
contentType string
body string
}
tests := []struct {
name string
fields fields
args args
wants wants
}{
{
name: "add a check owner",
fields: fields{
UserService: &mock.UserService{
FindUserByIDFn: func(ctx context.Context, id platform.ID) (*influxdb.User, error) {
2019-07-25 10:30:25 +00:00
return &influxdb.User{
ID: id,
Name: "name",
Status: influxdb.Active,
2019-07-25 10:30:25 +00:00
}, nil
},
},
},
args: args{
checkID: "020f755c3c082000",
user: &influxdb.User{
ID: influxTesting.MustIDBase16("6f626f7274697320"),
},
},
wants: wants{
statusCode: http.StatusCreated,
contentType: "application/json; charset=utf-8",
body: `
{
"links": {
"logs": "/api/v2/users/6f626f7274697320/logs",
"self": "/api/v2/users/6f626f7274697320"
},
"role": "owner",
"id": "6f626f7274697320",
"name": "name",
"status": "active"
2019-07-25 10:30:25 +00:00
}
`,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
checkBackend := NewMockCheckBackend(t)
2019-07-25 10:30:25 +00:00
checkBackend.UserService = tt.fields.UserService
h := NewCheckHandler(zaptest.NewLogger(t), checkBackend)
2019-07-25 10:30:25 +00:00
b, err := json.Marshal(tt.args.user)
if err != nil {
t.Fatalf("failed to marshal user: %v", err)
}
path := fmt.Sprintf("/api/v2/checks/%s/owners", tt.args.checkID)
r := httptest.NewRequest("POST", path, bytes.NewReader(b))
w := httptest.NewRecorder()
h.ServeHTTP(w, r)
res := w.Result()
content := res.Header.Get("Content-Type")
2021-10-12 21:55:07 +00:00
body, _ := io.ReadAll(res.Body)
2019-07-25 10:30:25 +00:00
if res.StatusCode != tt.wants.statusCode {
t.Errorf("%q. handlePostCheckOwner() = %v, want %v", tt.name, res.StatusCode, tt.wants.statusCode)
}
if tt.wants.contentType != "" && content != tt.wants.contentType {
t.Errorf("%q. handlePostCheckOwner() = %v, want %v", tt.name, content, tt.wants.contentType)
}
if eq, diff, err := jsonEqual(string(body), tt.wants.body); err != nil {
t.Errorf("%q, handlePostCheckOwner(). error unmarshalling json %v", tt.name, err)
2019-07-25 10:30:25 +00:00
} else if tt.wants.body != "" && !eq {
t.Errorf("%q. handlePostCheckOwner() = ***%s***", tt.name, diff)
}
})
}
}