2018-11-21 03:21:37 +00:00
|
|
|
package http
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"context"
|
|
|
|
"encoding/json"
|
2019-02-20 17:04:46 +00:00
|
|
|
"errors"
|
2019-01-25 23:17:30 +00:00
|
|
|
"fmt"
|
2022-04-13 20:24:27 +00:00
|
|
|
"io"
|
2018-11-21 03:21:37 +00:00
|
|
|
"net/http"
|
|
|
|
"net/http/httptest"
|
2019-01-25 23:17:30 +00:00
|
|
|
"strings"
|
2018-11-21 03:21:37 +00:00
|
|
|
"testing"
|
2019-02-15 18:44:27 +00:00
|
|
|
"time"
|
2018-11-21 03:21:37 +00:00
|
|
|
|
2019-12-04 23:10:23 +00:00
|
|
|
"github.com/influxdata/httprouter"
|
2020-04-03 17:39:20 +00:00
|
|
|
"github.com/influxdata/influxdb/v2"
|
2020-09-02 17:50:26 +00:00
|
|
|
"github.com/influxdata/influxdb/v2/authorization"
|
2020-04-03 17:39:20 +00:00
|
|
|
pcontext "github.com/influxdata/influxdb/v2/context"
|
2021-01-29 16:50:57 +00:00
|
|
|
_ "github.com/influxdata/influxdb/v2/fluxinit/static"
|
2021-04-07 18:42:55 +00:00
|
|
|
"github.com/influxdata/influxdb/v2/kit/platform"
|
|
|
|
errors2 "github.com/influxdata/influxdb/v2/kit/platform/errors"
|
2020-04-03 17:39:20 +00:00
|
|
|
kithttp "github.com/influxdata/influxdb/v2/kit/transport/http"
|
2020-09-02 17:50:26 +00:00
|
|
|
"github.com/influxdata/influxdb/v2/label"
|
2020-04-03 17:39:20 +00:00
|
|
|
"github.com/influxdata/influxdb/v2/mock"
|
2021-04-07 18:42:55 +00:00
|
|
|
"github.com/influxdata/influxdb/v2/task/taskmodel"
|
2020-09-02 17:50:26 +00:00
|
|
|
"github.com/influxdata/influxdb/v2/tenant"
|
2020-04-03 17:39:20 +00:00
|
|
|
influxdbtesting "github.com/influxdata/influxdb/v2/testing"
|
2019-02-09 01:34:44 +00:00
|
|
|
"go.uber.org/zap"
|
2019-02-07 01:34:54 +00:00
|
|
|
"go.uber.org/zap/zaptest"
|
2018-11-21 03:21:37 +00:00
|
|
|
)
|
|
|
|
|
2019-01-16 15:33:49 +00:00
|
|
|
// NewMockTaskBackend returns a TaskBackend with mock services.
|
2019-02-07 01:34:54 +00:00
|
|
|
func NewMockTaskBackend(t *testing.T) *TaskBackend {
|
2019-12-28 00:58:57 +00:00
|
|
|
t.Helper()
|
2021-08-31 20:43:45 +00:00
|
|
|
store := influxdbtesting.NewTestInmemStore(t)
|
refactor(kv): delete deprecated kv service code
This includes removal of a lot of kv.Service responsibilities. However,
it does not finish the re-wiring. It removes documents, telegrafs,
notification rules + endpoints, checks, orgs, users, buckets, passwords,
urms, labels and authorizations. There are some oustanding pieces that
are needed to get kv service compiling (dashboard service urm
dependency). Then all the call sites for kv service need updating and
the new implementations of telegraf and notification rules + endpoints
needed installing (along with any necessary migrations).
2020-10-20 13:25:36 +00:00
|
|
|
tenantService := tenant.NewService(tenant.NewStore(store))
|
|
|
|
|
2019-01-16 15:33:49 +00:00
|
|
|
return &TaskBackend{
|
2019-12-04 23:10:23 +00:00
|
|
|
log: zaptest.NewLogger(t).With(zap.String("handler", "task")),
|
2019-01-18 16:10:14 +00:00
|
|
|
|
2020-05-28 18:42:38 +00:00
|
|
|
AlgoWProxy: &NoopProxyHandler{},
|
2019-01-16 15:33:49 +00:00
|
|
|
AuthorizationService: mock.NewAuthorizationService(),
|
|
|
|
TaskService: &mock.TaskService{},
|
|
|
|
OrganizationService: &mock.OrganizationService{
|
2021-03-30 18:10:02 +00:00
|
|
|
FindOrganizationByIDF: func(ctx context.Context, id platform.ID) (*influxdb.Organization, error) {
|
2020-02-24 19:41:21 +00:00
|
|
|
return &influxdb.Organization{ID: id, Name: "test"}, nil
|
2019-01-16 15:33:49 +00:00
|
|
|
},
|
2020-02-24 19:41:21 +00:00
|
|
|
FindOrganizationF: func(ctx context.Context, filter influxdb.OrganizationFilter) (*influxdb.Organization, error) {
|
|
|
|
org := &influxdb.Organization{}
|
2019-01-16 15:33:49 +00:00
|
|
|
if filter.Name != nil {
|
2019-04-17 20:30:22 +00:00
|
|
|
if *filter.Name == "non-existent-org" {
|
2021-03-30 18:10:02 +00:00
|
|
|
return nil, &errors2.Error{
|
2019-02-20 17:04:46 +00:00
|
|
|
Err: errors.New("org not found or unauthorized"),
|
|
|
|
Msg: "org " + *filter.Name + " not found or unauthorized",
|
2021-03-30 18:10:02 +00:00
|
|
|
Code: errors2.ENotFound,
|
2019-02-20 17:04:46 +00:00
|
|
|
}
|
|
|
|
}
|
2019-01-16 15:33:49 +00:00
|
|
|
org.Name = *filter.Name
|
|
|
|
}
|
|
|
|
if filter.ID != nil {
|
|
|
|
org.ID = *filter.ID
|
|
|
|
}
|
|
|
|
|
|
|
|
return org, nil
|
|
|
|
},
|
2019-01-18 16:10:14 +00:00
|
|
|
},
|
refactor(kv): delete deprecated kv service code
This includes removal of a lot of kv.Service responsibilities. However,
it does not finish the re-wiring. It removes documents, telegrafs,
notification rules + endpoints, checks, orgs, users, buckets, passwords,
urms, labels and authorizations. There are some oustanding pieces that
are needed to get kv service compiling (dashboard service urm
dependency). Then all the call sites for kv service need updating and
the new implementations of telegraf and notification rules + endpoints
needed installing (along with any necessary migrations).
2020-10-20 13:25:36 +00:00
|
|
|
UserResourceMappingService: tenantService,
|
2019-01-16 15:33:49 +00:00
|
|
|
LabelService: mock.NewLabelService(),
|
|
|
|
UserService: mock.NewUserService(),
|
2019-01-18 16:10:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-21 03:21:37 +00:00
|
|
|
func TestTaskHandler_handleGetTasks(t *testing.T) {
|
|
|
|
type fields struct {
|
2021-04-07 18:42:55 +00:00
|
|
|
taskService taskmodel.TaskService
|
2020-02-24 19:41:21 +00:00
|
|
|
labelService influxdb.LabelService
|
2018-11-21 03:21:37 +00:00
|
|
|
}
|
|
|
|
type wants struct {
|
|
|
|
statusCode int
|
|
|
|
contentType string
|
|
|
|
body string
|
|
|
|
}
|
|
|
|
|
|
|
|
tests := []struct {
|
2019-02-20 17:04:46 +00:00
|
|
|
name string
|
|
|
|
getParams string
|
|
|
|
fields fields
|
|
|
|
wants wants
|
2018-11-21 03:21:37 +00:00
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "get tasks",
|
|
|
|
fields: fields{
|
|
|
|
taskService: &mock.TaskService{
|
2021-04-07 18:42:55 +00:00
|
|
|
FindTasksFn: func(ctx context.Context, f taskmodel.TaskFilter) ([]*taskmodel.Task, int, error) {
|
|
|
|
tasks := []*taskmodel.Task{
|
2018-11-21 03:21:37 +00:00
|
|
|
{
|
2020-08-26 16:26:32 +00:00
|
|
|
ID: 1,
|
|
|
|
Name: "task1",
|
|
|
|
Description: "A little Task",
|
|
|
|
OrganizationID: 1,
|
|
|
|
OwnerID: 1,
|
|
|
|
Organization: "test",
|
2018-11-21 03:21:37 +00:00
|
|
|
},
|
|
|
|
{
|
2020-08-26 16:26:32 +00:00
|
|
|
ID: 2,
|
|
|
|
Name: "task2",
|
|
|
|
OrganizationID: 2,
|
|
|
|
OwnerID: 2,
|
|
|
|
Organization: "test",
|
2018-11-21 03:21:37 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
return tasks, len(tasks), nil
|
|
|
|
},
|
|
|
|
},
|
2019-01-02 19:17:28 +00:00
|
|
|
labelService: &mock.LabelService{
|
2020-02-24 19:41:21 +00:00
|
|
|
FindResourceLabelsFn: func(ctx context.Context, f influxdb.LabelMappingFilter) ([]*influxdb.Label, error) {
|
|
|
|
labels := []*influxdb.Label{
|
2019-01-02 19:17:28 +00:00
|
|
|
{
|
2020-02-24 19:41:21 +00:00
|
|
|
ID: influxdbtesting.MustIDBase16("fc3dc670a4be9b9a"),
|
2019-01-18 19:03:36 +00:00
|
|
|
Name: "label",
|
2019-01-02 19:17:28 +00:00
|
|
|
Properties: map[string]string{
|
|
|
|
"color": "fff000",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
return labels, nil
|
|
|
|
},
|
|
|
|
},
|
2018-11-21 03:21:37 +00:00
|
|
|
},
|
|
|
|
wants: wants{
|
|
|
|
statusCode: http.StatusOK,
|
|
|
|
contentType: "application/json; charset=utf-8",
|
|
|
|
body: `
|
|
|
|
{
|
|
|
|
"links": {
|
2019-03-06 04:57:50 +00:00
|
|
|
"self": "/api/v2/tasks?limit=100"
|
2018-11-21 03:21:37 +00:00
|
|
|
},
|
|
|
|
"tasks": [
|
|
|
|
{
|
|
|
|
"links": {
|
|
|
|
"self": "/api/v2/tasks/0000000000000001",
|
|
|
|
"owners": "/api/v2/tasks/0000000000000001/owners",
|
|
|
|
"members": "/api/v2/tasks/0000000000000001/members",
|
2019-01-02 19:17:28 +00:00
|
|
|
"labels": "/api/v2/tasks/0000000000000001/labels",
|
2018-11-21 03:21:37 +00:00
|
|
|
"runs": "/api/v2/tasks/0000000000000001/runs",
|
|
|
|
"logs": "/api/v2/tasks/0000000000000001/logs"
|
|
|
|
},
|
|
|
|
"id": "0000000000000001",
|
|
|
|
"name": "task1",
|
2019-05-08 18:16:20 +00:00
|
|
|
"description": "A little Task",
|
|
|
|
"labels": [
|
2019-01-02 19:17:28 +00:00
|
|
|
{
|
2019-01-18 19:03:36 +00:00
|
|
|
"id": "fc3dc670a4be9b9a",
|
2019-01-02 19:17:28 +00:00
|
|
|
"name": "label",
|
|
|
|
"properties": {
|
|
|
|
"color": "fff000"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
],
|
2019-01-14 18:53:17 +00:00
|
|
|
"orgID": "0000000000000001",
|
2019-08-16 00:31:52 +00:00
|
|
|
"ownerID": "0000000000000001",
|
2019-01-18 16:10:14 +00:00
|
|
|
"org": "test",
|
2018-11-21 03:21:37 +00:00
|
|
|
"status": "",
|
2019-01-24 23:05:24 +00:00
|
|
|
"flux": ""
|
2018-11-21 03:21:37 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
"links": {
|
|
|
|
"self": "/api/v2/tasks/0000000000000002",
|
|
|
|
"owners": "/api/v2/tasks/0000000000000002/owners",
|
|
|
|
"members": "/api/v2/tasks/0000000000000002/members",
|
2019-01-02 19:17:28 +00:00
|
|
|
"labels": "/api/v2/tasks/0000000000000002/labels",
|
2018-11-21 03:21:37 +00:00
|
|
|
"runs": "/api/v2/tasks/0000000000000002/runs",
|
|
|
|
"logs": "/api/v2/tasks/0000000000000002/logs"
|
|
|
|
},
|
|
|
|
"id": "0000000000000002",
|
|
|
|
"name": "task2",
|
2019-01-02 19:17:28 +00:00
|
|
|
"labels": [
|
|
|
|
{
|
2019-01-18 19:03:36 +00:00
|
|
|
"id": "fc3dc670a4be9b9a",
|
2019-01-02 19:17:28 +00:00
|
|
|
"name": "label",
|
|
|
|
"properties": {
|
|
|
|
"color": "fff000"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
],
|
2019-01-18 16:10:14 +00:00
|
|
|
"orgID": "0000000000000002",
|
2019-08-16 00:31:52 +00:00
|
|
|
"ownerID": "0000000000000002",
|
2019-01-18 16:10:14 +00:00
|
|
|
"org": "test",
|
2018-11-21 03:21:37 +00:00
|
|
|
"status": "",
|
2019-01-24 23:05:24 +00:00
|
|
|
"flux": ""
|
2018-11-21 03:21:37 +00:00
|
|
|
}
|
|
|
|
]
|
2019-03-06 04:57:50 +00:00
|
|
|
}`,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "get tasks by after and limit",
|
|
|
|
getParams: "after=0000000000000001&limit=1",
|
|
|
|
fields: fields{
|
|
|
|
taskService: &mock.TaskService{
|
2021-04-07 18:42:55 +00:00
|
|
|
FindTasksFn: func(ctx context.Context, f taskmodel.TaskFilter) ([]*taskmodel.Task, int, error) {
|
|
|
|
tasks := []*taskmodel.Task{
|
2019-03-06 04:57:50 +00:00
|
|
|
{
|
2020-08-26 16:26:32 +00:00
|
|
|
ID: 2,
|
|
|
|
Name: "task2",
|
|
|
|
OrganizationID: 2,
|
|
|
|
OwnerID: 2,
|
|
|
|
Organization: "test",
|
2019-03-06 04:57:50 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
return tasks, len(tasks), nil
|
|
|
|
},
|
|
|
|
},
|
|
|
|
labelService: &mock.LabelService{
|
2020-02-24 19:41:21 +00:00
|
|
|
FindResourceLabelsFn: func(ctx context.Context, f influxdb.LabelMappingFilter) ([]*influxdb.Label, error) {
|
|
|
|
labels := []*influxdb.Label{
|
2019-03-06 04:57:50 +00:00
|
|
|
{
|
2020-02-24 19:41:21 +00:00
|
|
|
ID: influxdbtesting.MustIDBase16("fc3dc670a4be9b9a"),
|
2019-03-06 04:57:50 +00:00
|
|
|
Name: "label",
|
|
|
|
Properties: map[string]string{
|
|
|
|
"color": "fff000",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
return labels, nil
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
wants: wants{
|
|
|
|
statusCode: http.StatusOK,
|
|
|
|
contentType: "application/json; charset=utf-8",
|
|
|
|
body: `
|
|
|
|
{
|
|
|
|
"links": {
|
|
|
|
"self": "/api/v2/tasks?after=0000000000000001&limit=1",
|
|
|
|
"next": "/api/v2/tasks?after=0000000000000002&limit=1"
|
|
|
|
},
|
|
|
|
"tasks": [
|
|
|
|
{
|
|
|
|
"links": {
|
|
|
|
"self": "/api/v2/tasks/0000000000000002",
|
|
|
|
"owners": "/api/v2/tasks/0000000000000002/owners",
|
|
|
|
"members": "/api/v2/tasks/0000000000000002/members",
|
|
|
|
"labels": "/api/v2/tasks/0000000000000002/labels",
|
|
|
|
"runs": "/api/v2/tasks/0000000000000002/runs",
|
|
|
|
"logs": "/api/v2/tasks/0000000000000002/logs"
|
|
|
|
},
|
|
|
|
"id": "0000000000000002",
|
|
|
|
"name": "task2",
|
|
|
|
"labels": [
|
|
|
|
{
|
|
|
|
"id": "fc3dc670a4be9b9a",
|
|
|
|
"name": "label",
|
|
|
|
"properties": {
|
|
|
|
"color": "fff000"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
],
|
2019-08-16 00:31:52 +00:00
|
|
|
"orgID": "0000000000000002",
|
|
|
|
"ownerID": "0000000000000002",
|
2019-03-06 04:57:50 +00:00
|
|
|
"org": "test",
|
|
|
|
"status": "",
|
|
|
|
"flux": ""
|
|
|
|
}
|
|
|
|
]
|
2019-02-20 17:04:46 +00:00
|
|
|
}`,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "get tasks by org name",
|
|
|
|
getParams: "org=test2",
|
|
|
|
fields: fields{
|
|
|
|
taskService: &mock.TaskService{
|
2021-04-07 18:42:55 +00:00
|
|
|
FindTasksFn: func(ctx context.Context, f taskmodel.TaskFilter) ([]*taskmodel.Task, int, error) {
|
|
|
|
tasks := []*taskmodel.Task{
|
2019-02-20 17:04:46 +00:00
|
|
|
{
|
2020-08-26 16:26:32 +00:00
|
|
|
ID: 2,
|
|
|
|
Name: "task2",
|
|
|
|
OrganizationID: 2,
|
|
|
|
OwnerID: 2,
|
|
|
|
Organization: "test2",
|
2019-02-20 17:04:46 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
return tasks, len(tasks), nil
|
|
|
|
},
|
|
|
|
},
|
|
|
|
labelService: &mock.LabelService{
|
2020-02-24 19:41:21 +00:00
|
|
|
FindResourceLabelsFn: func(ctx context.Context, f influxdb.LabelMappingFilter) ([]*influxdb.Label, error) {
|
|
|
|
labels := []*influxdb.Label{
|
2019-02-20 17:04:46 +00:00
|
|
|
{
|
2020-02-24 19:41:21 +00:00
|
|
|
ID: influxdbtesting.MustIDBase16("fc3dc670a4be9b9a"),
|
2019-02-20 17:04:46 +00:00
|
|
|
Name: "label",
|
|
|
|
Properties: map[string]string{
|
|
|
|
"color": "fff000",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
return labels, nil
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
wants: wants{
|
|
|
|
statusCode: http.StatusOK,
|
|
|
|
contentType: "application/json; charset=utf-8",
|
|
|
|
body: `
|
|
|
|
{
|
|
|
|
"links": {
|
2019-03-06 04:57:50 +00:00
|
|
|
"self": "/api/v2/tasks?limit=100&org=test2"
|
2019-02-20 17:04:46 +00:00
|
|
|
},
|
|
|
|
"tasks": [
|
|
|
|
{
|
|
|
|
"links": {
|
|
|
|
"self": "/api/v2/tasks/0000000000000002",
|
|
|
|
"owners": "/api/v2/tasks/0000000000000002/owners",
|
|
|
|
"members": "/api/v2/tasks/0000000000000002/members",
|
|
|
|
"labels": "/api/v2/tasks/0000000000000002/labels",
|
|
|
|
"runs": "/api/v2/tasks/0000000000000002/runs",
|
|
|
|
"logs": "/api/v2/tasks/0000000000000002/logs"
|
|
|
|
},
|
|
|
|
"id": "0000000000000002",
|
|
|
|
"name": "task2",
|
|
|
|
"labels": [
|
|
|
|
{
|
|
|
|
"id": "fc3dc670a4be9b9a",
|
|
|
|
"name": "label",
|
|
|
|
"properties": {
|
|
|
|
"color": "fff000"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"orgID": "0000000000000002",
|
2019-08-16 00:31:52 +00:00
|
|
|
"ownerID": "0000000000000002",
|
2019-02-20 17:04:46 +00:00
|
|
|
"org": "test2",
|
|
|
|
"status": "",
|
|
|
|
"flux": ""
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}`,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "get tasks by org name bad",
|
2019-04-17 20:30:22 +00:00
|
|
|
getParams: "org=non-existent-org",
|
2019-02-20 17:04:46 +00:00
|
|
|
fields: fields{
|
|
|
|
taskService: &mock.TaskService{
|
2021-04-07 18:42:55 +00:00
|
|
|
FindTasksFn: func(ctx context.Context, f taskmodel.TaskFilter) ([]*taskmodel.Task, int, error) {
|
|
|
|
tasks := []*taskmodel.Task{
|
2019-02-20 17:04:46 +00:00
|
|
|
{
|
2020-08-26 16:26:32 +00:00
|
|
|
ID: 1,
|
|
|
|
Name: "task1",
|
|
|
|
OrganizationID: 1,
|
|
|
|
OwnerID: 1,
|
|
|
|
Organization: "test2",
|
2019-02-20 17:04:46 +00:00
|
|
|
},
|
|
|
|
{
|
2020-08-26 16:26:32 +00:00
|
|
|
ID: 2,
|
|
|
|
Name: "task2",
|
|
|
|
OrganizationID: 2,
|
|
|
|
OwnerID: 2,
|
|
|
|
Organization: "test2",
|
2019-02-20 17:04:46 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
return tasks, len(tasks), nil
|
|
|
|
},
|
|
|
|
},
|
|
|
|
labelService: &mock.LabelService{
|
2020-02-24 19:41:21 +00:00
|
|
|
FindResourceLabelsFn: func(ctx context.Context, f influxdb.LabelMappingFilter) ([]*influxdb.Label, error) {
|
|
|
|
labels := []*influxdb.Label{
|
2019-02-20 17:04:46 +00:00
|
|
|
{
|
2020-02-24 19:41:21 +00:00
|
|
|
ID: influxdbtesting.MustIDBase16("fc3dc670a4be9b9a"),
|
2019-02-20 17:04:46 +00:00
|
|
|
Name: "label",
|
|
|
|
Properties: map[string]string{
|
|
|
|
"color": "fff000",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
return labels, nil
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
wants: wants{
|
|
|
|
statusCode: http.StatusBadRequest,
|
|
|
|
contentType: "application/json; charset=utf-8",
|
|
|
|
body: `{
|
|
|
|
"code": "invalid",
|
2019-09-19 15:06:47 +00:00
|
|
|
"message": "failed to decode request: org non-existent-org not found or unauthorized: org not found or unauthorized"
|
2018-11-21 03:21:37 +00:00
|
|
|
}`,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tt := range tests {
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
2019-02-20 17:04:46 +00:00
|
|
|
r := httptest.NewRequest("GET", "http://any.url?"+tt.getParams, nil)
|
2018-11-21 03:21:37 +00:00
|
|
|
w := httptest.NewRecorder()
|
|
|
|
|
2019-02-07 01:34:54 +00:00
|
|
|
taskBackend := NewMockTaskBackend(t)
|
2021-09-13 19:12:35 +00:00
|
|
|
taskBackend.HTTPErrorHandler = kithttp.NewErrorHandler(zaptest.NewLogger(t))
|
2019-01-16 15:33:49 +00:00
|
|
|
taskBackend.TaskService = tt.fields.taskService
|
|
|
|
taskBackend.LabelService = tt.fields.labelService
|
2019-12-04 23:10:23 +00:00
|
|
|
h := NewTaskHandler(zaptest.NewLogger(t), taskBackend)
|
2018-11-21 03:21:37 +00:00
|
|
|
h.handleGetTasks(w, r)
|
|
|
|
|
|
|
|
res := w.Result()
|
|
|
|
content := res.Header.Get("Content-Type")
|
2022-04-13 20:24:27 +00:00
|
|
|
body, _ := io.ReadAll(res.Body)
|
2018-11-21 03:21:37 +00:00
|
|
|
|
|
|
|
if res.StatusCode != tt.wants.statusCode {
|
|
|
|
t.Errorf("%q. handleGetTasks() = %v, want %v", tt.name, res.StatusCode, tt.wants.statusCode)
|
|
|
|
}
|
|
|
|
if tt.wants.contentType != "" && content != tt.wants.contentType {
|
|
|
|
t.Errorf("%q. handleGetTasks() = %v, want %v", tt.name, content, tt.wants.contentType)
|
|
|
|
}
|
2019-05-08 19:51:03 +00:00
|
|
|
if tt.wants.body != "" {
|
2019-09-19 15:06:47 +00:00
|
|
|
if eq, diff, err := jsonEqual(tt.wants.body, string(body)); err != nil {
|
2020-11-11 18:54:21 +00:00
|
|
|
t.Errorf("%q, handleGetTasks(). error unmarshalling json %v", tt.name, err)
|
2019-05-08 19:51:03 +00:00
|
|
|
} else if !eq {
|
|
|
|
t.Errorf("%q. handleGetTasks() = ***%s***", tt.name, diff)
|
|
|
|
}
|
2018-11-21 03:21:37 +00:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestTaskHandler_handlePostTasks(t *testing.T) {
|
|
|
|
type args struct {
|
2021-04-07 18:42:55 +00:00
|
|
|
taskCreate taskmodel.TaskCreate
|
2018-11-21 03:21:37 +00:00
|
|
|
}
|
|
|
|
type fields struct {
|
2021-04-07 18:42:55 +00:00
|
|
|
taskService taskmodel.TaskService
|
2018-11-21 03:21:37 +00:00
|
|
|
}
|
|
|
|
type wants struct {
|
|
|
|
statusCode int
|
|
|
|
contentType string
|
|
|
|
body string
|
|
|
|
}
|
|
|
|
|
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
args args
|
|
|
|
fields fields
|
|
|
|
wants wants
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "create task",
|
|
|
|
args: args{
|
2021-04-07 18:42:55 +00:00
|
|
|
taskCreate: taskmodel.TaskCreate{
|
2019-01-18 16:10:14 +00:00
|
|
|
OrganizationID: 1,
|
2019-02-07 01:34:54 +00:00
|
|
|
Flux: "abc",
|
2018-11-21 03:21:37 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
fields: fields{
|
|
|
|
taskService: &mock.TaskService{
|
2021-04-07 18:42:55 +00:00
|
|
|
CreateTaskFn: func(ctx context.Context, tc taskmodel.TaskCreate) (*taskmodel.Task, error) {
|
|
|
|
return &taskmodel.Task{
|
2019-08-16 00:31:52 +00:00
|
|
|
ID: 1,
|
|
|
|
Name: "task1",
|
|
|
|
Description: "Brand New Task",
|
|
|
|
OrganizationID: 1,
|
|
|
|
OwnerID: 1,
|
|
|
|
Organization: "test",
|
|
|
|
Flux: "abc",
|
2019-02-09 01:34:44 +00:00
|
|
|
}, nil
|
2018-11-21 03:21:37 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
wants: wants{
|
|
|
|
statusCode: http.StatusCreated,
|
|
|
|
contentType: "application/json; charset=utf-8",
|
|
|
|
body: `
|
|
|
|
{
|
|
|
|
"links": {
|
|
|
|
"self": "/api/v2/tasks/0000000000000001",
|
|
|
|
"owners": "/api/v2/tasks/0000000000000001/owners",
|
|
|
|
"members": "/api/v2/tasks/0000000000000001/members",
|
2019-01-02 19:17:28 +00:00
|
|
|
"labels": "/api/v2/tasks/0000000000000001/labels",
|
2018-11-21 03:21:37 +00:00
|
|
|
"runs": "/api/v2/tasks/0000000000000001/runs",
|
|
|
|
"logs": "/api/v2/tasks/0000000000000001/logs"
|
|
|
|
},
|
|
|
|
"id": "0000000000000001",
|
|
|
|
"name": "task1",
|
2019-05-08 18:16:20 +00:00
|
|
|
"description": "Brand New Task",
|
2019-01-02 19:17:28 +00:00
|
|
|
"labels": [],
|
2019-01-14 18:53:17 +00:00
|
|
|
"orgID": "0000000000000001",
|
2019-08-16 00:31:52 +00:00
|
|
|
"ownerID": "0000000000000001",
|
2019-01-18 16:10:14 +00:00
|
|
|
"org": "test",
|
2018-11-21 03:21:37 +00:00
|
|
|
"status": "",
|
2019-02-07 01:34:54 +00:00
|
|
|
"flux": "abc"
|
2018-11-21 03:21:37 +00:00
|
|
|
}
|
2019-07-31 09:46:28 +00:00
|
|
|
`,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2020-02-24 19:41:21 +00:00
|
|
|
name: "create task - influxdb error creating task",
|
2019-07-31 09:46:28 +00:00
|
|
|
args: args{
|
2021-04-07 18:42:55 +00:00
|
|
|
taskCreate: taskmodel.TaskCreate{
|
2019-07-31 09:46:28 +00:00
|
|
|
OrganizationID: 1,
|
|
|
|
Flux: "abc",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
fields: fields{
|
|
|
|
taskService: &mock.TaskService{
|
2021-04-07 18:42:55 +00:00
|
|
|
CreateTaskFn: func(ctx context.Context, tc taskmodel.TaskCreate) (*taskmodel.Task, error) {
|
2021-03-30 18:10:02 +00:00
|
|
|
return nil, errors2.NewError(
|
|
|
|
errors2.WithErrorErr(errors.New("something went wrong")),
|
|
|
|
errors2.WithErrorMsg("something really went wrong"),
|
|
|
|
errors2.WithErrorCode(errors2.EInvalid),
|
2019-07-31 09:46:28 +00:00
|
|
|
)
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
wants: wants{
|
|
|
|
statusCode: http.StatusBadRequest,
|
|
|
|
contentType: "application/json; charset=utf-8",
|
|
|
|
body: `
|
|
|
|
{
|
|
|
|
"code": "invalid",
|
2019-09-19 15:06:47 +00:00
|
|
|
"message": "something really went wrong: something went wrong"
|
2019-07-31 09:46:28 +00:00
|
|
|
}
|
|
|
|
`,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "create task - error creating task",
|
|
|
|
args: args{
|
2021-04-07 18:42:55 +00:00
|
|
|
taskCreate: taskmodel.TaskCreate{
|
2019-07-31 09:46:28 +00:00
|
|
|
OrganizationID: 1,
|
|
|
|
Flux: "abc",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
fields: fields{
|
|
|
|
taskService: &mock.TaskService{
|
2021-04-07 18:42:55 +00:00
|
|
|
CreateTaskFn: func(ctx context.Context, tc taskmodel.TaskCreate) (*taskmodel.Task, error) {
|
2019-07-31 09:46:28 +00:00
|
|
|
return nil, errors.New("something bad happened")
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
wants: wants{
|
|
|
|
statusCode: http.StatusInternalServerError,
|
|
|
|
contentType: "application/json; charset=utf-8",
|
|
|
|
body: `
|
|
|
|
{
|
|
|
|
"code": "internal error",
|
2019-09-19 15:06:47 +00:00
|
|
|
"message": "failed to create task: something bad happened"
|
2019-07-31 09:46:28 +00:00
|
|
|
}
|
2018-11-21 03:21:37 +00:00
|
|
|
`,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tt := range tests {
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
2019-02-07 01:34:54 +00:00
|
|
|
b, err := json.Marshal(tt.args.taskCreate)
|
2018-11-21 03:21:37 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("failed to unmarshal task: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
r := httptest.NewRequest("POST", "http://any.url", bytes.NewReader(b))
|
2020-02-24 19:41:21 +00:00
|
|
|
ctx := pcontext.SetAuthorizer(context.TODO(), new(influxdb.Authorization))
|
2018-11-21 03:21:37 +00:00
|
|
|
r = r.WithContext(ctx)
|
|
|
|
|
|
|
|
w := httptest.NewRecorder()
|
|
|
|
|
2019-02-07 01:34:54 +00:00
|
|
|
taskBackend := NewMockTaskBackend(t)
|
2021-09-13 19:12:35 +00:00
|
|
|
taskBackend.HTTPErrorHandler = kithttp.NewErrorHandler(zaptest.NewLogger(t))
|
2019-01-16 15:33:49 +00:00
|
|
|
taskBackend.TaskService = tt.fields.taskService
|
2019-12-04 23:10:23 +00:00
|
|
|
h := NewTaskHandler(zaptest.NewLogger(t), taskBackend)
|
2018-11-21 03:21:37 +00:00
|
|
|
h.handlePostTask(w, r)
|
|
|
|
|
|
|
|
res := w.Result()
|
|
|
|
content := res.Header.Get("Content-Type")
|
2022-04-13 20:24:27 +00:00
|
|
|
body, _ := io.ReadAll(res.Body)
|
2018-11-21 03:21:37 +00:00
|
|
|
|
|
|
|
if res.StatusCode != tt.wants.statusCode {
|
2018-12-04 23:10:03 +00:00
|
|
|
t.Errorf("%q. handlePostTask() = %v, want %v", tt.name, res.StatusCode, tt.wants.statusCode)
|
2018-11-21 03:21:37 +00:00
|
|
|
}
|
|
|
|
if tt.wants.contentType != "" && content != tt.wants.contentType {
|
2018-12-04 23:10:03 +00:00
|
|
|
t.Errorf("%q. handlePostTask() = %v, want %v", tt.name, content, tt.wants.contentType)
|
2018-11-21 03:21:37 +00:00
|
|
|
}
|
2019-05-08 19:51:03 +00:00
|
|
|
if tt.wants.body != "" {
|
2019-09-19 15:06:47 +00:00
|
|
|
if eq, diff, err := jsonEqual(tt.wants.body, string(body)); err != nil {
|
2020-11-11 18:54:21 +00:00
|
|
|
t.Errorf("%q, handlePostTask(). error unmarshalling json %v", tt.name, err)
|
2019-05-08 19:51:03 +00:00
|
|
|
} else if !eq {
|
|
|
|
t.Errorf("%q. handlePostTask() = ***%s***", tt.name, diff)
|
|
|
|
}
|
2018-12-04 23:10:03 +00:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestTaskHandler_handleGetRun(t *testing.T) {
|
|
|
|
type fields struct {
|
2021-04-07 18:42:55 +00:00
|
|
|
taskService taskmodel.TaskService
|
2018-12-04 23:10:03 +00:00
|
|
|
}
|
|
|
|
type args struct {
|
2021-03-30 18:10:02 +00:00
|
|
|
taskID platform.ID
|
|
|
|
runID platform.ID
|
2018-12-04 23:10:03 +00:00
|
|
|
}
|
|
|
|
type wants struct {
|
|
|
|
statusCode int
|
|
|
|
contentType string
|
|
|
|
body string
|
|
|
|
}
|
|
|
|
|
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
fields fields
|
|
|
|
args args
|
|
|
|
wants wants
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "get a run by id",
|
|
|
|
fields: fields{
|
|
|
|
taskService: &mock.TaskService{
|
2021-04-07 18:42:55 +00:00
|
|
|
FindRunByIDFn: func(ctx context.Context, taskID platform.ID, runID platform.ID) (*taskmodel.Run, error) {
|
2019-10-18 00:23:45 +00:00
|
|
|
scheduledFor, _ := time.Parse(time.RFC3339, "2018-12-01T17:00:13Z")
|
|
|
|
startedAt, _ := time.Parse(time.RFC3339Nano, "2018-12-01T17:00:03.155645Z")
|
|
|
|
finishedAt, _ := time.Parse(time.RFC3339Nano, "2018-12-01T17:00:13.155645Z")
|
|
|
|
requestedAt, _ := time.Parse(time.RFC3339, "2018-12-01T17:00:13Z")
|
2021-04-07 18:42:55 +00:00
|
|
|
run := taskmodel.Run{
|
2018-12-04 23:10:03 +00:00
|
|
|
ID: runID,
|
|
|
|
TaskID: taskID,
|
|
|
|
Status: "success",
|
2019-10-18 00:23:45 +00:00
|
|
|
ScheduledFor: scheduledFor,
|
|
|
|
StartedAt: startedAt,
|
|
|
|
FinishedAt: finishedAt,
|
|
|
|
RequestedAt: requestedAt,
|
2018-12-04 23:10:03 +00:00
|
|
|
}
|
|
|
|
return &run, nil
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
args: args{
|
|
|
|
taskID: 1,
|
|
|
|
runID: 2,
|
|
|
|
},
|
|
|
|
wants: wants{
|
|
|
|
statusCode: http.StatusOK,
|
|
|
|
contentType: "application/json; charset=utf-8",
|
|
|
|
body: `
|
|
|
|
{
|
|
|
|
"links": {
|
|
|
|
"self": "/api/v2/tasks/0000000000000001/runs/0000000000000002",
|
|
|
|
"task": "/api/v2/tasks/0000000000000001",
|
|
|
|
"retry": "/api/v2/tasks/0000000000000001/runs/0000000000000002/retry",
|
|
|
|
"logs": "/api/v2/tasks/0000000000000001/runs/0000000000000002/logs"
|
|
|
|
},
|
|
|
|
"id": "0000000000000002",
|
|
|
|
"taskID": "0000000000000001",
|
|
|
|
"status": "success",
|
|
|
|
"scheduledFor": "2018-12-01T17:00:13Z",
|
|
|
|
"startedAt": "2018-12-01T17:00:03.155645Z",
|
|
|
|
"finishedAt": "2018-12-01T17:00:13.155645Z",
|
2019-05-16 23:06:08 +00:00
|
|
|
"requestedAt": "2018-12-01T17:00:13Z"
|
2018-12-04 23:10:03 +00:00
|
|
|
}`,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tt := range tests {
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
r := httptest.NewRequest("GET", "http://any.url", nil)
|
|
|
|
r = r.WithContext(context.WithValue(
|
2019-02-20 23:49:55 +00:00
|
|
|
context.Background(),
|
2018-12-04 23:10:03 +00:00
|
|
|
httprouter.ParamsKey,
|
|
|
|
httprouter.Params{
|
|
|
|
{
|
2018-12-21 15:11:57 +00:00
|
|
|
Key: "id",
|
2018-12-04 23:10:03 +00:00
|
|
|
Value: tt.args.taskID.String(),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Key: "rid",
|
|
|
|
Value: tt.args.runID.String(),
|
|
|
|
},
|
|
|
|
}))
|
2020-02-24 19:41:21 +00:00
|
|
|
r = r.WithContext(pcontext.SetAuthorizer(r.Context(), &influxdb.Authorization{Permissions: influxdb.OperPermissions()}))
|
2018-12-04 23:10:03 +00:00
|
|
|
w := httptest.NewRecorder()
|
2019-02-07 01:34:54 +00:00
|
|
|
taskBackend := NewMockTaskBackend(t)
|
2021-09-13 19:12:35 +00:00
|
|
|
taskBackend.HTTPErrorHandler = kithttp.NewErrorHandler(zaptest.NewLogger(t))
|
2019-01-16 15:33:49 +00:00
|
|
|
taskBackend.TaskService = tt.fields.taskService
|
2019-12-04 23:10:23 +00:00
|
|
|
h := NewTaskHandler(zaptest.NewLogger(t), taskBackend)
|
2018-12-04 23:10:03 +00:00
|
|
|
h.handleGetRun(w, r)
|
|
|
|
|
|
|
|
res := w.Result()
|
|
|
|
content := res.Header.Get("Content-Type")
|
2022-04-13 20:24:27 +00:00
|
|
|
body, _ := io.ReadAll(res.Body)
|
2018-12-04 23:10:03 +00:00
|
|
|
|
|
|
|
if res.StatusCode != tt.wants.statusCode {
|
|
|
|
t.Errorf("%q. handleGetRun() = %v, want %v", tt.name, res.StatusCode, tt.wants.statusCode)
|
|
|
|
}
|
|
|
|
if tt.wants.contentType != "" && content != tt.wants.contentType {
|
|
|
|
t.Errorf("%q. handleGetRun() = %v, want %v", tt.name, content, tt.wants.contentType)
|
|
|
|
}
|
2019-05-08 19:51:03 +00:00
|
|
|
if tt.wants.body != "" {
|
|
|
|
if eq, diff, err := jsonEqual(string(body), tt.wants.body); err != nil {
|
2020-11-11 18:54:21 +00:00
|
|
|
t.Errorf("%q, handleGetRun(). error unmarshalling json %v", tt.name, err)
|
2019-05-08 19:51:03 +00:00
|
|
|
} else if !eq {
|
|
|
|
t.Errorf("%q. handleGetRun() = ***%s***", tt.name, diff)
|
|
|
|
}
|
2018-12-04 23:10:03 +00:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestTaskHandler_handleGetRuns(t *testing.T) {
|
|
|
|
type fields struct {
|
2021-04-07 18:42:55 +00:00
|
|
|
taskService taskmodel.TaskService
|
2018-12-04 23:10:03 +00:00
|
|
|
}
|
|
|
|
type args struct {
|
2021-03-30 18:10:02 +00:00
|
|
|
taskID platform.ID
|
2018-12-04 23:10:03 +00:00
|
|
|
}
|
|
|
|
type wants struct {
|
|
|
|
statusCode int
|
|
|
|
contentType string
|
|
|
|
body string
|
|
|
|
}
|
|
|
|
|
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
fields fields
|
|
|
|
args args
|
|
|
|
wants wants
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "get runs by task id",
|
|
|
|
fields: fields{
|
|
|
|
taskService: &mock.TaskService{
|
2021-04-07 18:42:55 +00:00
|
|
|
FindRunsFn: func(ctx context.Context, f taskmodel.RunFilter) ([]*taskmodel.Run, int, error) {
|
2019-10-18 00:23:45 +00:00
|
|
|
scheduledFor, _ := time.Parse(time.RFC3339, "2018-12-01T17:00:13Z")
|
|
|
|
startedAt, _ := time.Parse(time.RFC3339Nano, "2018-12-01T17:00:03.155645Z")
|
|
|
|
finishedAt, _ := time.Parse(time.RFC3339Nano, "2018-12-01T17:00:13.155645Z")
|
|
|
|
requestedAt, _ := time.Parse(time.RFC3339, "2018-12-01T17:00:13Z")
|
2021-04-07 18:42:55 +00:00
|
|
|
runs := []*taskmodel.Run{
|
2018-12-04 23:10:03 +00:00
|
|
|
{
|
2021-03-30 18:10:02 +00:00
|
|
|
ID: platform.ID(2),
|
2019-02-16 00:04:54 +00:00
|
|
|
TaskID: f.Task,
|
2018-12-04 23:10:03 +00:00
|
|
|
Status: "success",
|
2019-10-18 00:23:45 +00:00
|
|
|
ScheduledFor: scheduledFor,
|
|
|
|
StartedAt: startedAt,
|
|
|
|
FinishedAt: finishedAt,
|
|
|
|
RequestedAt: requestedAt,
|
2018-12-04 23:10:03 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
return runs, len(runs), nil
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
args: args{
|
|
|
|
taskID: 1,
|
|
|
|
},
|
|
|
|
wants: wants{
|
|
|
|
statusCode: http.StatusOK,
|
|
|
|
contentType: "application/json; charset=utf-8",
|
|
|
|
body: `
|
|
|
|
{
|
|
|
|
"links": {
|
|
|
|
"self": "/api/v2/tasks/0000000000000001/runs",
|
|
|
|
"task": "/api/v2/tasks/0000000000000001"
|
|
|
|
},
|
|
|
|
"runs": [
|
|
|
|
{
|
|
|
|
"links": {
|
|
|
|
"self": "/api/v2/tasks/0000000000000001/runs/0000000000000002",
|
|
|
|
"task": "/api/v2/tasks/0000000000000001",
|
|
|
|
"retry": "/api/v2/tasks/0000000000000001/runs/0000000000000002/retry",
|
|
|
|
"logs": "/api/v2/tasks/0000000000000001/runs/0000000000000002/logs"
|
|
|
|
},
|
|
|
|
"id": "0000000000000002",
|
|
|
|
"taskID": "0000000000000001",
|
|
|
|
"status": "success",
|
|
|
|
"scheduledFor": "2018-12-01T17:00:13Z",
|
|
|
|
"startedAt": "2018-12-01T17:00:03.155645Z",
|
|
|
|
"finishedAt": "2018-12-01T17:00:13.155645Z",
|
2019-05-16 23:06:08 +00:00
|
|
|
"requestedAt": "2018-12-01T17:00:13Z"
|
2018-12-04 23:10:03 +00:00
|
|
|
}
|
|
|
|
]
|
|
|
|
}`,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tt := range tests {
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
r := httptest.NewRequest("GET", "http://any.url", nil)
|
|
|
|
r = r.WithContext(context.WithValue(
|
2019-02-20 23:49:55 +00:00
|
|
|
context.Background(),
|
2018-12-04 23:10:03 +00:00
|
|
|
httprouter.ParamsKey,
|
|
|
|
httprouter.Params{
|
|
|
|
{
|
2018-12-21 15:11:57 +00:00
|
|
|
Key: "id",
|
2018-12-04 23:10:03 +00:00
|
|
|
Value: tt.args.taskID.String(),
|
|
|
|
},
|
|
|
|
}))
|
2020-02-24 19:41:21 +00:00
|
|
|
r = r.WithContext(pcontext.SetAuthorizer(r.Context(), &influxdb.Authorization{Permissions: influxdb.OperPermissions()}))
|
2018-12-04 23:10:03 +00:00
|
|
|
w := httptest.NewRecorder()
|
2019-02-07 01:34:54 +00:00
|
|
|
taskBackend := NewMockTaskBackend(t)
|
2021-09-13 19:12:35 +00:00
|
|
|
taskBackend.HTTPErrorHandler = kithttp.NewErrorHandler(zaptest.NewLogger(t))
|
2019-01-16 15:33:49 +00:00
|
|
|
taskBackend.TaskService = tt.fields.taskService
|
2019-12-04 23:10:23 +00:00
|
|
|
h := NewTaskHandler(zaptest.NewLogger(t), taskBackend)
|
2018-12-04 23:10:03 +00:00
|
|
|
h.handleGetRuns(w, r)
|
|
|
|
|
|
|
|
res := w.Result()
|
|
|
|
content := res.Header.Get("Content-Type")
|
2022-04-13 20:24:27 +00:00
|
|
|
body, _ := io.ReadAll(res.Body)
|
2018-12-04 23:10:03 +00:00
|
|
|
|
|
|
|
if res.StatusCode != tt.wants.statusCode {
|
|
|
|
t.Errorf("%q. handleGetRuns() = %v, want %v", tt.name, res.StatusCode, tt.wants.statusCode)
|
|
|
|
}
|
|
|
|
if tt.wants.contentType != "" && content != tt.wants.contentType {
|
|
|
|
t.Errorf("%q. handleGetRuns() = %v, want %v", tt.name, content, tt.wants.contentType)
|
|
|
|
}
|
2019-05-08 19:51:03 +00:00
|
|
|
if tt.wants.body != "" {
|
|
|
|
if eq, diff, err := jsonEqual(string(body), tt.wants.body); err != nil {
|
2020-11-11 18:54:21 +00:00
|
|
|
t.Errorf("%q, handleGetRuns(). error unmarshalling json %v", tt.name, err)
|
2019-05-08 19:51:03 +00:00
|
|
|
} else if !eq {
|
|
|
|
t.Errorf("%q. handleGetRuns() = ***%s***", tt.name, diff)
|
|
|
|
}
|
2018-11-21 03:21:37 +00:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
2019-01-25 23:17:30 +00:00
|
|
|
|
|
|
|
func TestTaskHandler_NotFoundStatus(t *testing.T) {
|
|
|
|
// Ensure that the HTTP handlers return 404s for missing resources, and OKs for matching.
|
|
|
|
|
2021-08-31 20:43:45 +00:00
|
|
|
store := influxdbtesting.NewTestInmemStore(t)
|
refactor(kv): delete deprecated kv service code
This includes removal of a lot of kv.Service responsibilities. However,
it does not finish the re-wiring. It removes documents, telegrafs,
notification rules + endpoints, checks, orgs, users, buckets, passwords,
urms, labels and authorizations. There are some oustanding pieces that
are needed to get kv service compiling (dashboard service urm
dependency). Then all the call sites for kv service need updating and
the new implementations of telegraf and notification rules + endpoints
needed installing (along with any necessary migrations).
2020-10-20 13:25:36 +00:00
|
|
|
tenantService := tenant.NewService(tenant.NewStore(store))
|
|
|
|
|
|
|
|
labelStore, _ := label.NewStore(store)
|
|
|
|
labelService := label.NewService(labelStore)
|
|
|
|
|
2019-02-07 01:34:54 +00:00
|
|
|
taskBackend := NewMockTaskBackend(t)
|
2021-09-13 19:12:35 +00:00
|
|
|
taskBackend.HTTPErrorHandler = kithttp.NewErrorHandler(zaptest.NewLogger(t))
|
2019-12-04 23:10:23 +00:00
|
|
|
h := NewTaskHandler(zaptest.NewLogger(t), taskBackend)
|
refactor(kv): delete deprecated kv service code
This includes removal of a lot of kv.Service responsibilities. However,
it does not finish the re-wiring. It removes documents, telegrafs,
notification rules + endpoints, checks, orgs, users, buckets, passwords,
urms, labels and authorizations. There are some oustanding pieces that
are needed to get kv service compiling (dashboard service urm
dependency). Then all the call sites for kv service need updating and
the new implementations of telegraf and notification rules + endpoints
needed installing (along with any necessary migrations).
2020-10-20 13:25:36 +00:00
|
|
|
h.UserResourceMappingService = tenantService
|
|
|
|
h.LabelService = labelService
|
|
|
|
h.UserService = tenantService
|
|
|
|
h.OrganizationService = tenantService
|
2019-01-25 23:17:30 +00:00
|
|
|
|
2020-02-24 19:41:21 +00:00
|
|
|
o := influxdb.Organization{Name: "o"}
|
2019-01-25 23:17:30 +00:00
|
|
|
ctx := context.Background()
|
|
|
|
if err := h.OrganizationService.CreateOrganization(ctx, &o); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2019-02-20 23:49:55 +00:00
|
|
|
// Create a session to associate with the contexts, so authorization checks pass.
|
2020-02-24 19:41:21 +00:00
|
|
|
authz := &influxdb.Authorization{Permissions: influxdb.OperPermissions()}
|
2019-02-20 23:49:55 +00:00
|
|
|
|
2021-03-30 18:10:02 +00:00
|
|
|
const taskID, runID = platform.ID(0xCCCCCC), platform.ID(0xAAAAAA)
|
2019-01-25 23:17:30 +00:00
|
|
|
|
|
|
|
var (
|
|
|
|
okTask = []interface{}{taskID}
|
|
|
|
okTaskRun = []interface{}{taskID, runID}
|
|
|
|
|
|
|
|
notFoundTask = [][]interface{}{
|
|
|
|
{taskID + 1},
|
|
|
|
}
|
|
|
|
notFoundTaskRun = [][]interface{}{
|
|
|
|
{taskID, runID + 1},
|
|
|
|
{taskID + 1, runID},
|
|
|
|
{taskID + 1, runID + 1},
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
|
|
|
tcs := []struct {
|
|
|
|
name string
|
|
|
|
svc *mock.TaskService
|
|
|
|
method string
|
|
|
|
body string
|
|
|
|
pathFmt string
|
|
|
|
okPathArgs []interface{}
|
|
|
|
notFoundPathArgs [][]interface{}
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "get task",
|
|
|
|
svc: &mock.TaskService{
|
2021-04-07 18:42:55 +00:00
|
|
|
FindTaskByIDFn: func(_ context.Context, id platform.ID) (*taskmodel.Task, error) {
|
2019-01-25 23:17:30 +00:00
|
|
|
if id == taskID {
|
2021-04-07 18:42:55 +00:00
|
|
|
return &taskmodel.Task{ID: taskID, Organization: "o"}, nil
|
2019-01-25 23:17:30 +00:00
|
|
|
}
|
|
|
|
|
2021-04-07 18:42:55 +00:00
|
|
|
return nil, taskmodel.ErrTaskNotFound
|
2019-01-25 23:17:30 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
method: http.MethodGet,
|
|
|
|
pathFmt: "/tasks/%s",
|
|
|
|
okPathArgs: okTask,
|
|
|
|
notFoundPathArgs: notFoundTask,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "update task",
|
|
|
|
svc: &mock.TaskService{
|
2021-04-07 18:42:55 +00:00
|
|
|
UpdateTaskFn: func(_ context.Context, id platform.ID, _ taskmodel.TaskUpdate) (*taskmodel.Task, error) {
|
2019-01-25 23:17:30 +00:00
|
|
|
if id == taskID {
|
2021-04-07 18:42:55 +00:00
|
|
|
return &taskmodel.Task{ID: taskID, Organization: "o"}, nil
|
2019-01-25 23:17:30 +00:00
|
|
|
}
|
|
|
|
|
2021-04-07 18:42:55 +00:00
|
|
|
return nil, taskmodel.ErrTaskNotFound
|
2019-01-25 23:17:30 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
method: http.MethodPatch,
|
2019-02-24 06:25:24 +00:00
|
|
|
body: `{"status": "active"}`,
|
2019-01-25 23:17:30 +00:00
|
|
|
pathFmt: "/tasks/%s",
|
|
|
|
okPathArgs: okTask,
|
|
|
|
notFoundPathArgs: notFoundTask,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "delete task",
|
|
|
|
svc: &mock.TaskService{
|
2021-03-30 18:10:02 +00:00
|
|
|
DeleteTaskFn: func(_ context.Context, id platform.ID) error {
|
2019-01-25 23:17:30 +00:00
|
|
|
if id == taskID {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-04-07 18:42:55 +00:00
|
|
|
return taskmodel.ErrTaskNotFound
|
2019-01-25 23:17:30 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
method: http.MethodDelete,
|
|
|
|
pathFmt: "/tasks/%s",
|
|
|
|
okPathArgs: okTask,
|
|
|
|
notFoundPathArgs: notFoundTask,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "get task logs",
|
|
|
|
svc: &mock.TaskService{
|
2021-04-07 18:42:55 +00:00
|
|
|
FindLogsFn: func(_ context.Context, f taskmodel.LogFilter) ([]*taskmodel.Log, int, error) {
|
2019-02-16 00:04:54 +00:00
|
|
|
if f.Task == taskID {
|
2019-01-25 23:17:30 +00:00
|
|
|
return nil, 0, nil
|
|
|
|
}
|
|
|
|
|
2021-04-07 18:42:55 +00:00
|
|
|
return nil, 0, taskmodel.ErrTaskNotFound
|
2019-01-25 23:17:30 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
method: http.MethodGet,
|
|
|
|
pathFmt: "/tasks/%s/logs",
|
|
|
|
okPathArgs: okTask,
|
|
|
|
notFoundPathArgs: notFoundTask,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "get run logs",
|
|
|
|
svc: &mock.TaskService{
|
2021-04-07 18:42:55 +00:00
|
|
|
FindLogsFn: func(_ context.Context, f taskmodel.LogFilter) ([]*taskmodel.Log, int, error) {
|
2019-02-16 00:04:54 +00:00
|
|
|
if f.Task != taskID {
|
2021-04-07 18:42:55 +00:00
|
|
|
return nil, 0, taskmodel.ErrTaskNotFound
|
2019-01-25 23:17:30 +00:00
|
|
|
}
|
|
|
|
if *f.Run != runID {
|
2021-04-07 18:42:55 +00:00
|
|
|
return nil, 0, taskmodel.ErrNoRunsFound
|
2019-01-25 23:17:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil, 0, nil
|
|
|
|
},
|
|
|
|
},
|
|
|
|
method: http.MethodGet,
|
|
|
|
pathFmt: "/tasks/%s/runs/%s/logs",
|
|
|
|
okPathArgs: okTaskRun,
|
|
|
|
notFoundPathArgs: notFoundTaskRun,
|
|
|
|
},
|
|
|
|
{
|
2019-02-19 17:59:21 +00:00
|
|
|
name: "get runs: task not found",
|
2019-01-25 23:17:30 +00:00
|
|
|
svc: &mock.TaskService{
|
2021-04-07 18:42:55 +00:00
|
|
|
FindRunsFn: func(_ context.Context, f taskmodel.RunFilter) ([]*taskmodel.Run, int, error) {
|
2019-02-16 00:04:54 +00:00
|
|
|
if f.Task != taskID {
|
2021-04-07 18:42:55 +00:00
|
|
|
return nil, 0, taskmodel.ErrTaskNotFound
|
2019-01-25 23:17:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil, 0, nil
|
|
|
|
},
|
|
|
|
},
|
|
|
|
method: http.MethodGet,
|
|
|
|
pathFmt: "/tasks/%s/runs",
|
|
|
|
okPathArgs: okTask,
|
|
|
|
notFoundPathArgs: notFoundTask,
|
|
|
|
},
|
2019-02-19 17:59:21 +00:00
|
|
|
{
|
|
|
|
name: "get runs: task found but no runs found",
|
|
|
|
svc: &mock.TaskService{
|
2021-04-07 18:42:55 +00:00
|
|
|
FindRunsFn: func(_ context.Context, f taskmodel.RunFilter) ([]*taskmodel.Run, int, error) {
|
2019-02-19 17:59:21 +00:00
|
|
|
if f.Task != taskID {
|
2021-04-07 18:42:55 +00:00
|
|
|
return nil, 0, taskmodel.ErrNoRunsFound
|
2019-02-19 17:59:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil, 0, nil
|
|
|
|
},
|
|
|
|
},
|
|
|
|
method: http.MethodGet,
|
|
|
|
pathFmt: "/tasks/%s/runs",
|
|
|
|
okPathArgs: okTask,
|
|
|
|
notFoundPathArgs: notFoundTask,
|
|
|
|
},
|
2019-01-25 23:17:30 +00:00
|
|
|
{
|
|
|
|
name: "force run",
|
|
|
|
svc: &mock.TaskService{
|
2021-04-07 18:42:55 +00:00
|
|
|
ForceRunFn: func(_ context.Context, tid platform.ID, _ int64) (*taskmodel.Run, error) {
|
2019-01-25 23:17:30 +00:00
|
|
|
if tid != taskID {
|
2021-04-07 18:42:55 +00:00
|
|
|
return nil, taskmodel.ErrTaskNotFound
|
2019-01-25 23:17:30 +00:00
|
|
|
}
|
|
|
|
|
2021-04-07 18:42:55 +00:00
|
|
|
return &taskmodel.Run{ID: runID, TaskID: taskID, Status: taskmodel.RunScheduled.String()}, nil
|
2019-01-25 23:17:30 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
method: http.MethodPost,
|
|
|
|
body: "{}",
|
|
|
|
pathFmt: "/tasks/%s/runs",
|
|
|
|
okPathArgs: okTask,
|
|
|
|
notFoundPathArgs: notFoundTask,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "get run",
|
|
|
|
svc: &mock.TaskService{
|
2021-04-07 18:42:55 +00:00
|
|
|
FindRunByIDFn: func(_ context.Context, tid, rid platform.ID) (*taskmodel.Run, error) {
|
2019-01-25 23:17:30 +00:00
|
|
|
if tid != taskID {
|
2021-04-07 18:42:55 +00:00
|
|
|
return nil, taskmodel.ErrTaskNotFound
|
2019-01-25 23:17:30 +00:00
|
|
|
}
|
|
|
|
if rid != runID {
|
2021-04-07 18:42:55 +00:00
|
|
|
return nil, taskmodel.ErrRunNotFound
|
2019-01-25 23:17:30 +00:00
|
|
|
}
|
|
|
|
|
2021-04-07 18:42:55 +00:00
|
|
|
return &taskmodel.Run{ID: runID, TaskID: taskID, Status: taskmodel.RunScheduled.String()}, nil
|
2019-01-25 23:17:30 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
method: http.MethodGet,
|
|
|
|
pathFmt: "/tasks/%s/runs/%s",
|
|
|
|
okPathArgs: okTaskRun,
|
|
|
|
notFoundPathArgs: notFoundTaskRun,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "retry run",
|
|
|
|
svc: &mock.TaskService{
|
2021-04-07 18:42:55 +00:00
|
|
|
RetryRunFn: func(_ context.Context, tid, rid platform.ID) (*taskmodel.Run, error) {
|
2019-01-25 23:17:30 +00:00
|
|
|
if tid != taskID {
|
2021-04-07 18:42:55 +00:00
|
|
|
return nil, taskmodel.ErrTaskNotFound
|
2019-01-25 23:17:30 +00:00
|
|
|
}
|
|
|
|
if rid != runID {
|
2021-04-07 18:42:55 +00:00
|
|
|
return nil, taskmodel.ErrRunNotFound
|
2019-01-25 23:17:30 +00:00
|
|
|
}
|
|
|
|
|
2021-04-07 18:42:55 +00:00
|
|
|
return &taskmodel.Run{ID: runID, TaskID: taskID, Status: taskmodel.RunScheduled.String()}, nil
|
2019-01-25 23:17:30 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
method: http.MethodPost,
|
|
|
|
pathFmt: "/tasks/%s/runs/%s/retry",
|
|
|
|
okPathArgs: okTaskRun,
|
|
|
|
notFoundPathArgs: notFoundTaskRun,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "cancel run",
|
|
|
|
svc: &mock.TaskService{
|
2021-03-30 18:10:02 +00:00
|
|
|
CancelRunFn: func(_ context.Context, tid, rid platform.ID) error {
|
2019-01-25 23:17:30 +00:00
|
|
|
if tid != taskID {
|
2021-04-07 18:42:55 +00:00
|
|
|
return taskmodel.ErrTaskNotFound
|
2019-01-25 23:17:30 +00:00
|
|
|
}
|
|
|
|
if rid != runID {
|
2021-04-07 18:42:55 +00:00
|
|
|
return taskmodel.ErrRunNotFound
|
2019-01-25 23:17:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
},
|
|
|
|
},
|
|
|
|
method: http.MethodDelete,
|
|
|
|
pathFmt: "/tasks/%s/runs/%s",
|
|
|
|
okPathArgs: okTaskRun,
|
|
|
|
notFoundPathArgs: notFoundTaskRun,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range tcs {
|
|
|
|
tc := tc
|
|
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
|
|
h.TaskService = tc.svc
|
|
|
|
|
|
|
|
okPath := fmt.Sprintf(tc.pathFmt, tc.okPathArgs...)
|
|
|
|
t.Run("matching ID: "+tc.method+" "+okPath, func(t *testing.T) {
|
|
|
|
w := httptest.NewRecorder()
|
2019-02-20 23:49:55 +00:00
|
|
|
r := httptest.NewRequest(tc.method, "http://task.example/api/v2"+okPath, strings.NewReader(tc.body)).WithContext(
|
|
|
|
pcontext.SetAuthorizer(context.Background(), authz),
|
|
|
|
)
|
2019-01-25 23:17:30 +00:00
|
|
|
|
|
|
|
h.ServeHTTP(w, r)
|
|
|
|
|
|
|
|
res := w.Result()
|
|
|
|
defer res.Body.Close()
|
|
|
|
|
|
|
|
if res.StatusCode < 200 || res.StatusCode > 299 {
|
|
|
|
t.Errorf("expected OK, got %d", res.StatusCode)
|
2022-04-13 20:24:27 +00:00
|
|
|
b, _ := io.ReadAll(res.Body)
|
2019-01-25 23:17:30 +00:00
|
|
|
t.Fatalf("body: %s", string(b))
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("mismatched ID", func(t *testing.T) {
|
|
|
|
for _, nfa := range tc.notFoundPathArgs {
|
|
|
|
path := fmt.Sprintf(tc.pathFmt, nfa...)
|
|
|
|
t.Run(tc.method+" "+path, func(t *testing.T) {
|
|
|
|
w := httptest.NewRecorder()
|
2019-02-20 23:49:55 +00:00
|
|
|
r := httptest.NewRequest(tc.method, "http://task.example/api/v2"+path, strings.NewReader(tc.body)).WithContext(
|
|
|
|
pcontext.SetAuthorizer(context.Background(), authz),
|
|
|
|
)
|
2019-01-25 23:17:30 +00:00
|
|
|
|
|
|
|
h.ServeHTTP(w, r)
|
|
|
|
|
|
|
|
res := w.Result()
|
|
|
|
defer res.Body.Close()
|
|
|
|
|
|
|
|
if res.StatusCode != http.StatusNotFound {
|
|
|
|
t.Errorf("expected Not Found, got %d", res.StatusCode)
|
2022-04-13 20:24:27 +00:00
|
|
|
b, _ := io.ReadAll(res.Body)
|
2019-01-25 23:17:30 +00:00
|
|
|
t.Fatalf("body: %s", string(b))
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
2019-02-05 16:26:26 +00:00
|
|
|
|
2019-02-08 00:07:32 +00:00
|
|
|
func TestService_handlePostTaskLabel(t *testing.T) {
|
|
|
|
type fields struct {
|
2020-02-24 19:41:21 +00:00
|
|
|
LabelService influxdb.LabelService
|
2019-02-08 00:07:32 +00:00
|
|
|
}
|
|
|
|
type args struct {
|
2020-02-24 19:41:21 +00:00
|
|
|
labelMapping *influxdb.LabelMapping
|
2021-03-30 18:10:02 +00:00
|
|
|
taskID platform.ID
|
2019-02-08 00:07:32 +00:00
|
|
|
}
|
|
|
|
type wants struct {
|
|
|
|
statusCode int
|
|
|
|
contentType string
|
|
|
|
body string
|
|
|
|
}
|
|
|
|
|
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
fields fields
|
|
|
|
args args
|
|
|
|
wants wants
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "add label to task",
|
|
|
|
fields: fields{
|
|
|
|
LabelService: &mock.LabelService{
|
2021-03-30 18:10:02 +00:00
|
|
|
FindLabelByIDFn: func(ctx context.Context, id platform.ID) (*influxdb.Label, error) {
|
2020-02-24 19:41:21 +00:00
|
|
|
return &influxdb.Label{
|
2019-02-08 00:07:32 +00:00
|
|
|
ID: 1,
|
|
|
|
Name: "label",
|
|
|
|
Properties: map[string]string{
|
|
|
|
"color": "fff000",
|
|
|
|
},
|
|
|
|
}, nil
|
|
|
|
},
|
2020-02-24 19:41:21 +00:00
|
|
|
CreateLabelMappingFn: func(ctx context.Context, m *influxdb.LabelMapping) error { return nil },
|
2019-02-08 00:07:32 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
args: args{
|
2020-02-24 19:41:21 +00:00
|
|
|
labelMapping: &influxdb.LabelMapping{
|
2019-02-08 00:07:32 +00:00
|
|
|
ResourceID: 100,
|
|
|
|
LabelID: 1,
|
|
|
|
},
|
|
|
|
taskID: 100,
|
|
|
|
},
|
|
|
|
wants: wants{
|
|
|
|
statusCode: http.StatusCreated,
|
|
|
|
contentType: "application/json; charset=utf-8",
|
|
|
|
body: `
|
|
|
|
{
|
|
|
|
"label": {
|
|
|
|
"id": "0000000000000001",
|
|
|
|
"name": "label",
|
|
|
|
"properties": {
|
|
|
|
"color": "fff000"
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"links": {
|
|
|
|
"self": "/api/v2/labels/0000000000000001"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tt := range tests {
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
2019-02-07 01:34:54 +00:00
|
|
|
taskBE := NewMockTaskBackend(t)
|
2019-02-08 00:07:32 +00:00
|
|
|
taskBE.LabelService = tt.fields.LabelService
|
2019-12-04 23:10:23 +00:00
|
|
|
h := NewTaskHandler(zaptest.NewLogger(t), taskBE)
|
2019-02-08 00:07:32 +00:00
|
|
|
|
|
|
|
b, err := json.Marshal(tt.args.labelMapping)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("failed to unmarshal label mapping: %v", err)
|
|
|
|
}
|
|
|
|
|
2020-09-03 21:40:29 +00:00
|
|
|
url := fmt.Sprintf("http://localhost:8086/api/v2/tasks/%s/labels", tt.args.taskID)
|
2019-02-08 00:07:32 +00:00
|
|
|
r := httptest.NewRequest("POST", url, bytes.NewReader(b))
|
|
|
|
w := httptest.NewRecorder()
|
|
|
|
|
|
|
|
h.ServeHTTP(w, r)
|
|
|
|
|
|
|
|
res := w.Result()
|
|
|
|
content := res.Header.Get("Content-Type")
|
2022-04-13 20:24:27 +00:00
|
|
|
body, _ := io.ReadAll(res.Body)
|
2019-02-08 00:07:32 +00:00
|
|
|
|
|
|
|
if res.StatusCode != tt.wants.statusCode {
|
|
|
|
t.Errorf("got %v, want %v", res.StatusCode, tt.wants.statusCode)
|
|
|
|
}
|
|
|
|
if tt.wants.contentType != "" && content != tt.wants.contentType {
|
|
|
|
t.Errorf("got %v, want %v", content, tt.wants.contentType)
|
|
|
|
}
|
2019-05-08 19:51:03 +00:00
|
|
|
if tt.wants.body != "" {
|
|
|
|
if eq, diff, err := jsonEqual(string(body), tt.wants.body); err != nil {
|
2020-11-11 18:54:21 +00:00
|
|
|
t.Errorf("%q, handlePostTaskLabel(). error unmarshalling json %v", tt.name, err)
|
2019-05-08 19:51:03 +00:00
|
|
|
} else if !eq {
|
|
|
|
t.Errorf("%q. handlePostTaskLabel() = ***%s***", tt.name, diff)
|
|
|
|
}
|
2019-02-08 00:07:32 +00:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
2019-02-15 18:44:27 +00:00
|
|
|
|
2019-03-14 22:53:54 +00:00
|
|
|
// Test that org name to org ID translation happens properly in the HTTP layer.
|
|
|
|
// Regression test for https://github.com/influxdata/influxdb/issues/12089.
|
|
|
|
func TestTaskHandler_CreateTaskWithOrgName(t *testing.T) {
|
2021-08-31 20:43:45 +00:00
|
|
|
i := influxdbtesting.NewTestInmemStore(t)
|
2020-09-02 17:50:26 +00:00
|
|
|
|
|
|
|
ts := tenant.NewService(tenant.NewStore(i))
|
|
|
|
aStore, _ := authorization.NewStore(i)
|
|
|
|
as := authorization.NewService(aStore, ts)
|
2019-03-14 22:53:54 +00:00
|
|
|
ctx := context.Background()
|
|
|
|
|
|
|
|
// Set up user and org.
|
2020-02-24 19:41:21 +00:00
|
|
|
u := &influxdb.User{Name: "u"}
|
2020-09-02 17:50:26 +00:00
|
|
|
if err := ts.CreateUser(ctx, u); err != nil {
|
2019-03-14 22:53:54 +00:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2020-02-24 19:41:21 +00:00
|
|
|
o := &influxdb.Organization{Name: "o"}
|
2020-09-02 17:50:26 +00:00
|
|
|
if err := ts.CreateOrganization(ctx, o); err != nil {
|
2019-03-14 22:53:54 +00:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Source and destination buckets for use in task.
|
2020-02-24 19:41:21 +00:00
|
|
|
bSrc := influxdb.Bucket{OrgID: o.ID, Name: "b-src"}
|
2020-09-02 17:50:26 +00:00
|
|
|
if err := ts.CreateBucket(ctx, &bSrc); err != nil {
|
2019-03-14 22:53:54 +00:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2020-02-24 19:41:21 +00:00
|
|
|
bDst := influxdb.Bucket{OrgID: o.ID, Name: "b-dst"}
|
2020-09-02 17:50:26 +00:00
|
|
|
if err := ts.CreateBucket(ctx, &bDst); err != nil {
|
2019-03-14 22:53:54 +00:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2020-02-24 19:41:21 +00:00
|
|
|
authz := influxdb.Authorization{OrgID: o.ID, UserID: u.ID, Permissions: influxdb.OperPermissions()}
|
2020-09-02 17:50:26 +00:00
|
|
|
if err := as.CreateAuthorization(ctx, &authz); err != nil {
|
2019-03-14 22:53:54 +00:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2020-09-02 17:50:26 +00:00
|
|
|
taskSvc := &mock.TaskService{
|
2021-04-07 18:42:55 +00:00
|
|
|
CreateTaskFn: func(_ context.Context, tc taskmodel.TaskCreate) (*taskmodel.Task, error) {
|
2019-03-14 22:53:54 +00:00
|
|
|
if tc.OrganizationID != o.ID {
|
|
|
|
t.Fatalf("expected task to be created with org ID %s, got %s", o.ID, tc.OrganizationID)
|
|
|
|
}
|
|
|
|
|
2021-04-07 18:42:55 +00:00
|
|
|
return &taskmodel.Task{ID: 9, OrganizationID: o.ID, OwnerID: o.ID, Name: "x", Flux: tc.Flux}, nil
|
2019-03-14 22:53:54 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2020-09-02 17:50:26 +00:00
|
|
|
lStore, _ := label.NewStore(i)
|
2019-12-04 23:10:23 +00:00
|
|
|
h := NewTaskHandler(zaptest.NewLogger(t), &TaskBackend{
|
|
|
|
log: zaptest.NewLogger(t),
|
2019-03-14 22:53:54 +00:00
|
|
|
|
2020-09-02 17:50:26 +00:00
|
|
|
TaskService: taskSvc,
|
|
|
|
AuthorizationService: as,
|
|
|
|
OrganizationService: ts,
|
|
|
|
UserResourceMappingService: ts,
|
|
|
|
LabelService: label.NewService(lStore),
|
|
|
|
UserService: ts,
|
|
|
|
BucketService: ts,
|
2019-03-14 22:53:54 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
const script = `option task = {name:"x", every:1m} from(bucket:"b-src") |> range(start:-1m) |> to(bucket:"b-dst", org:"o")`
|
|
|
|
|
2020-09-03 21:40:29 +00:00
|
|
|
url := "http://localhost:8086/api/v2/tasks"
|
2019-03-14 22:53:54 +00:00
|
|
|
|
2021-04-07 18:42:55 +00:00
|
|
|
b, err := json.Marshal(taskmodel.TaskCreate{
|
2019-03-14 22:53:54 +00:00
|
|
|
Flux: script,
|
|
|
|
Organization: o.Name,
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
r := httptest.NewRequest("POST", url, bytes.NewReader(b)).WithContext(
|
|
|
|
pcontext.SetAuthorizer(ctx, &authz),
|
|
|
|
)
|
|
|
|
w := httptest.NewRecorder()
|
|
|
|
|
|
|
|
h.handlePostTask(w, r)
|
|
|
|
|
|
|
|
res := w.Result()
|
|
|
|
defer res.Body.Close()
|
2022-04-13 20:24:27 +00:00
|
|
|
body, err := io.ReadAll(res.Body)
|
2019-03-14 22:53:54 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if res.StatusCode != http.StatusCreated {
|
|
|
|
t.Logf("response body: %s", body)
|
|
|
|
t.Fatalf("expected status created, got %v", res.StatusCode)
|
|
|
|
}
|
|
|
|
|
|
|
|
// The task should have been created with a valid token.
|
2021-04-07 18:42:55 +00:00
|
|
|
var createdTask taskmodel.Task
|
2019-03-14 22:53:54 +00:00
|
|
|
if err := json.Unmarshal([]byte(body), &createdTask); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if createdTask.Flux != script {
|
|
|
|
t.Fatalf("Unexpected script returned:\n got: %s\nwant: %s", createdTask.Flux, script)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-20 23:49:55 +00:00
|
|
|
func TestTaskHandler_Sessions(t *testing.T) {
|
2019-07-23 15:31:39 +00:00
|
|
|
t.Skip("rework these")
|
2019-02-20 23:49:55 +00:00
|
|
|
// Common setup to get a working base for using tasks.
|
2021-08-31 20:43:45 +00:00
|
|
|
st := influxdbtesting.NewTestInmemStore(t)
|
2020-09-02 17:50:26 +00:00
|
|
|
|
|
|
|
tStore := tenant.NewStore(st)
|
|
|
|
tSvc := tenant.NewService(tStore)
|
2019-02-21 22:21:36 +00:00
|
|
|
|
refactor(kv): delete deprecated kv service code
This includes removal of a lot of kv.Service responsibilities. However,
it does not finish the re-wiring. It removes documents, telegrafs,
notification rules + endpoints, checks, orgs, users, buckets, passwords,
urms, labels and authorizations. There are some oustanding pieces that
are needed to get kv service compiling (dashboard service urm
dependency). Then all the call sites for kv service need updating and
the new implementations of telegraf and notification rules + endpoints
needed installing (along with any necessary migrations).
2020-10-20 13:25:36 +00:00
|
|
|
labelStore, err := label.NewStore(st)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
labelService := label.NewService(labelStore)
|
|
|
|
|
|
|
|
authStore, err := authorization.NewStore(st)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
authService := authorization.NewService(authStore, tSvc)
|
|
|
|
|
2019-02-15 18:44:27 +00:00
|
|
|
ctx := context.Background()
|
|
|
|
|
|
|
|
// Set up user and org.
|
2020-02-24 19:41:21 +00:00
|
|
|
u := &influxdb.User{Name: "u"}
|
2020-09-02 17:50:26 +00:00
|
|
|
if err := tSvc.CreateUser(ctx, u); err != nil {
|
2019-02-15 18:44:27 +00:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2020-02-24 19:41:21 +00:00
|
|
|
o := &influxdb.Organization{Name: "o"}
|
2020-09-02 17:50:26 +00:00
|
|
|
if err := tSvc.CreateOrganization(ctx, o); err != nil {
|
2019-02-15 18:44:27 +00:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Map user to org.
|
2020-09-02 17:50:26 +00:00
|
|
|
if err := tSvc.CreateUserResourceMapping(ctx, &influxdb.UserResourceMapping{
|
2020-02-24 19:41:21 +00:00
|
|
|
ResourceType: influxdb.OrgsResourceType,
|
2019-02-15 18:44:27 +00:00
|
|
|
ResourceID: o.ID,
|
|
|
|
UserID: u.ID,
|
2020-02-24 19:41:21 +00:00
|
|
|
UserType: influxdb.Owner,
|
2019-02-15 18:44:27 +00:00
|
|
|
}); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Source and destination buckets for use in task.
|
2020-02-24 19:41:21 +00:00
|
|
|
bSrc := influxdb.Bucket{OrgID: o.ID, Name: "b-src"}
|
2020-09-02 17:50:26 +00:00
|
|
|
if err := tSvc.CreateBucket(ctx, &bSrc); err != nil {
|
2019-02-15 18:44:27 +00:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2020-02-24 19:41:21 +00:00
|
|
|
bDst := influxdb.Bucket{OrgID: o.ID, Name: "b-dst"}
|
2020-09-02 17:50:26 +00:00
|
|
|
if err := tSvc.CreateBucket(ctx, &bDst); err != nil {
|
2019-02-15 18:44:27 +00:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2020-02-24 19:41:21 +00:00
|
|
|
sessionAllPermsCtx := pcontext.SetAuthorizer(context.Background(), &influxdb.Session{
|
2019-02-15 18:44:27 +00:00
|
|
|
UserID: u.ID,
|
2020-02-24 19:41:21 +00:00
|
|
|
Permissions: influxdb.OperPermissions(),
|
2019-02-15 18:44:27 +00:00
|
|
|
ExpiresAt: time.Now().Add(24 * time.Hour),
|
2019-02-20 23:49:55 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
newHandler := func(t *testing.T, ts *mock.TaskService) *TaskHandler {
|
2019-12-04 23:10:23 +00:00
|
|
|
return NewTaskHandler(zaptest.NewLogger(t), &TaskBackend{
|
2021-09-13 19:12:35 +00:00
|
|
|
HTTPErrorHandler: kithttp.NewErrorHandler(zaptest.NewLogger(t)),
|
2019-12-04 23:10:23 +00:00
|
|
|
log: zaptest.NewLogger(t),
|
2019-02-20 23:49:55 +00:00
|
|
|
|
|
|
|
TaskService: ts,
|
refactor(kv): delete deprecated kv service code
This includes removal of a lot of kv.Service responsibilities. However,
it does not finish the re-wiring. It removes documents, telegrafs,
notification rules + endpoints, checks, orgs, users, buckets, passwords,
urms, labels and authorizations. There are some oustanding pieces that
are needed to get kv service compiling (dashboard service urm
dependency). Then all the call sites for kv service need updating and
the new implementations of telegraf and notification rules + endpoints
needed installing (along with any necessary migrations).
2020-10-20 13:25:36 +00:00
|
|
|
AuthorizationService: authService,
|
2020-09-02 17:50:26 +00:00
|
|
|
OrganizationService: tSvc,
|
|
|
|
UserResourceMappingService: tSvc,
|
refactor(kv): delete deprecated kv service code
This includes removal of a lot of kv.Service responsibilities. However,
it does not finish the re-wiring. It removes documents, telegrafs,
notification rules + endpoints, checks, orgs, users, buckets, passwords,
urms, labels and authorizations. There are some oustanding pieces that
are needed to get kv service compiling (dashboard service urm
dependency). Then all the call sites for kv service need updating and
the new implementations of telegraf and notification rules + endpoints
needed installing (along with any necessary migrations).
2020-10-20 13:25:36 +00:00
|
|
|
LabelService: labelService,
|
2020-09-02 17:50:26 +00:00
|
|
|
UserService: tSvc,
|
|
|
|
BucketService: tSvc,
|
2019-02-20 23:49:55 +00:00
|
|
|
})
|
2019-02-15 18:44:27 +00:00
|
|
|
}
|
|
|
|
|
2019-02-20 23:49:55 +00:00
|
|
|
t.Run("get runs for a task", func(t *testing.T) {
|
|
|
|
// Unique authorization to associate with our fake task.
|
2020-02-24 19:41:21 +00:00
|
|
|
taskAuth := &influxdb.Authorization{OrgID: o.ID, UserID: u.ID}
|
refactor(kv): delete deprecated kv service code
This includes removal of a lot of kv.Service responsibilities. However,
it does not finish the re-wiring. It removes documents, telegrafs,
notification rules + endpoints, checks, orgs, users, buckets, passwords,
urms, labels and authorizations. There are some oustanding pieces that
are needed to get kv service compiling (dashboard service urm
dependency). Then all the call sites for kv service need updating and
the new implementations of telegraf and notification rules + endpoints
needed installing (along with any necessary migrations).
2020-10-20 13:25:36 +00:00
|
|
|
if err := authService.CreateAuthorization(ctx, taskAuth); err != nil {
|
2019-02-20 23:49:55 +00:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2019-02-15 18:44:27 +00:00
|
|
|
|
2021-03-30 18:10:02 +00:00
|
|
|
const taskID = platform.ID(12345)
|
|
|
|
const runID = platform.ID(9876)
|
2019-02-15 18:44:27 +00:00
|
|
|
|
2019-02-20 23:49:55 +00:00
|
|
|
var findRunsCtx context.Context
|
|
|
|
ts := &mock.TaskService{
|
2021-04-07 18:42:55 +00:00
|
|
|
FindRunsFn: func(ctx context.Context, f taskmodel.RunFilter) ([]*taskmodel.Run, int, error) {
|
2019-02-20 23:49:55 +00:00
|
|
|
findRunsCtx = ctx
|
|
|
|
if f.Task != taskID {
|
|
|
|
t.Fatalf("expected task ID %v, got %v", taskID, f.Task)
|
|
|
|
}
|
2019-02-15 18:44:27 +00:00
|
|
|
|
2021-04-07 18:42:55 +00:00
|
|
|
return []*taskmodel.Run{
|
2019-02-20 23:49:55 +00:00
|
|
|
{ID: runID, TaskID: taskID},
|
|
|
|
}, 1, nil
|
|
|
|
},
|
2019-02-15 18:44:27 +00:00
|
|
|
|
2021-04-07 18:42:55 +00:00
|
|
|
FindTaskByIDFn: func(ctx context.Context, id platform.ID) (*taskmodel.Task, error) {
|
2019-02-20 23:49:55 +00:00
|
|
|
if id != taskID {
|
2021-04-07 18:42:55 +00:00
|
|
|
return nil, taskmodel.ErrTaskNotFound
|
2019-02-20 23:49:55 +00:00
|
|
|
}
|
2019-02-15 18:44:27 +00:00
|
|
|
|
2021-04-07 18:42:55 +00:00
|
|
|
return &taskmodel.Task{
|
2020-08-26 16:26:32 +00:00
|
|
|
ID: taskID,
|
|
|
|
OrganizationID: o.ID,
|
2019-02-20 23:49:55 +00:00
|
|
|
}, nil
|
|
|
|
},
|
|
|
|
}
|
2019-02-21 22:21:36 +00:00
|
|
|
|
2019-02-20 23:49:55 +00:00
|
|
|
h := newHandler(t, ts)
|
2020-09-03 21:40:29 +00:00
|
|
|
url := fmt.Sprintf("http://localhost:8086/api/v2/tasks/%s/runs", taskID)
|
2019-02-20 23:49:55 +00:00
|
|
|
valCtx := context.WithValue(sessionAllPermsCtx, httprouter.ParamsKey, httprouter.Params{{Key: "id", Value: taskID.String()}})
|
|
|
|
r := httptest.NewRequest("GET", url, nil).WithContext(valCtx)
|
|
|
|
w := httptest.NewRecorder()
|
|
|
|
h.handleGetRuns(w, r)
|
|
|
|
|
|
|
|
res := w.Result()
|
2022-04-13 20:24:27 +00:00
|
|
|
body, err := io.ReadAll(res.Body)
|
2019-02-20 23:49:55 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if res.StatusCode != http.StatusOK {
|
|
|
|
t.Logf("response body: %s", body)
|
|
|
|
t.Fatalf("expected status OK, got %v", res.StatusCode)
|
|
|
|
}
|
2019-02-21 22:21:36 +00:00
|
|
|
|
2019-02-20 23:49:55 +00:00
|
|
|
authr, err := pcontext.GetAuthorizer(findRunsCtx)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2020-02-24 19:41:21 +00:00
|
|
|
if authr.Kind() != influxdb.AuthorizationKind {
|
|
|
|
t.Fatalf("expected context's authorizer to be of kind %q, got %q", influxdb.AuthorizationKind, authr.Kind())
|
2019-02-20 23:49:55 +00:00
|
|
|
}
|
2019-07-23 15:31:39 +00:00
|
|
|
|
2020-02-24 19:41:21 +00:00
|
|
|
orgID := authr.(*influxdb.Authorization).OrgID
|
2019-07-23 15:31:39 +00:00
|
|
|
|
|
|
|
if orgID != o.ID {
|
|
|
|
t.Fatalf("expected context's authorizer org ID to be %v, got %v", o.ID, orgID)
|
2019-02-20 23:49:55 +00:00
|
|
|
}
|
2019-02-21 22:21:36 +00:00
|
|
|
|
2019-02-20 23:49:55 +00:00
|
|
|
// Other user without permissions on the task or authorization should be disallowed.
|
2020-02-24 19:41:21 +00:00
|
|
|
otherUser := &influxdb.User{Name: "other-" + t.Name()}
|
refactor(kv): delete deprecated kv service code
This includes removal of a lot of kv.Service responsibilities. However,
it does not finish the re-wiring. It removes documents, telegrafs,
notification rules + endpoints, checks, orgs, users, buckets, passwords,
urms, labels and authorizations. There are some oustanding pieces that
are needed to get kv service compiling (dashboard service urm
dependency). Then all the call sites for kv service need updating and
the new implementations of telegraf and notification rules + endpoints
needed installing (along with any necessary migrations).
2020-10-20 13:25:36 +00:00
|
|
|
if err := tSvc.CreateUser(ctx, otherUser); err != nil {
|
2019-02-20 23:49:55 +00:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2020-02-24 19:41:21 +00:00
|
|
|
valCtx = pcontext.SetAuthorizer(valCtx, &influxdb.Session{
|
2019-02-20 23:49:55 +00:00
|
|
|
UserID: otherUser.ID,
|
|
|
|
ExpiresAt: time.Now().Add(24 * time.Hour),
|
|
|
|
})
|
|
|
|
|
|
|
|
r = httptest.NewRequest("GET", url, nil).WithContext(valCtx)
|
|
|
|
w = httptest.NewRecorder()
|
|
|
|
h.handleGetRuns(w, r)
|
|
|
|
|
|
|
|
res = w.Result()
|
2022-04-13 20:24:27 +00:00
|
|
|
body, err = io.ReadAll(res.Body)
|
2019-02-20 23:49:55 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if res.StatusCode != http.StatusUnauthorized {
|
|
|
|
t.Logf("response body: %s", body)
|
|
|
|
t.Fatalf("expected status unauthorized, got %v", res.StatusCode)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("get single run for a task", func(t *testing.T) {
|
|
|
|
// Unique authorization to associate with our fake task.
|
2020-02-24 19:41:21 +00:00
|
|
|
taskAuth := &influxdb.Authorization{OrgID: o.ID, UserID: u.ID}
|
refactor(kv): delete deprecated kv service code
This includes removal of a lot of kv.Service responsibilities. However,
it does not finish the re-wiring. It removes documents, telegrafs,
notification rules + endpoints, checks, orgs, users, buckets, passwords,
urms, labels and authorizations. There are some oustanding pieces that
are needed to get kv service compiling (dashboard service urm
dependency). Then all the call sites for kv service need updating and
the new implementations of telegraf and notification rules + endpoints
needed installing (along with any necessary migrations).
2020-10-20 13:25:36 +00:00
|
|
|
if err := authService.CreateAuthorization(ctx, taskAuth); err != nil {
|
2019-02-20 23:49:55 +00:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2021-03-30 18:10:02 +00:00
|
|
|
const taskID = platform.ID(12345)
|
|
|
|
const runID = platform.ID(9876)
|
2019-02-20 23:49:55 +00:00
|
|
|
|
|
|
|
var findRunByIDCtx context.Context
|
|
|
|
ts := &mock.TaskService{
|
2021-04-07 18:42:55 +00:00
|
|
|
FindRunByIDFn: func(ctx context.Context, tid, rid platform.ID) (*taskmodel.Run, error) {
|
2019-02-20 23:49:55 +00:00
|
|
|
findRunByIDCtx = ctx
|
|
|
|
if tid != taskID {
|
|
|
|
t.Fatalf("expected task ID %v, got %v", taskID, tid)
|
|
|
|
}
|
|
|
|
if rid != runID {
|
|
|
|
t.Fatalf("expected run ID %v, got %v", runID, rid)
|
|
|
|
}
|
|
|
|
|
2021-04-07 18:42:55 +00:00
|
|
|
return &taskmodel.Run{ID: runID, TaskID: taskID}, nil
|
2019-02-20 23:49:55 +00:00
|
|
|
},
|
|
|
|
|
2021-04-07 18:42:55 +00:00
|
|
|
FindTaskByIDFn: func(ctx context.Context, id platform.ID) (*taskmodel.Task, error) {
|
2019-02-20 23:49:55 +00:00
|
|
|
if id != taskID {
|
2021-04-07 18:42:55 +00:00
|
|
|
return nil, taskmodel.ErrTaskNotFound
|
2019-02-20 23:49:55 +00:00
|
|
|
}
|
|
|
|
|
2021-04-07 18:42:55 +00:00
|
|
|
return &taskmodel.Task{
|
2020-08-26 16:26:32 +00:00
|
|
|
ID: taskID,
|
|
|
|
OrganizationID: o.ID,
|
2019-02-20 23:49:55 +00:00
|
|
|
}, nil
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
h := newHandler(t, ts)
|
2020-09-03 21:40:29 +00:00
|
|
|
url := fmt.Sprintf("http://localhost:8086/api/v2/tasks/%s/runs/%s", taskID, runID)
|
2019-02-20 23:49:55 +00:00
|
|
|
valCtx := context.WithValue(sessionAllPermsCtx, httprouter.ParamsKey, httprouter.Params{
|
|
|
|
{Key: "id", Value: taskID.String()},
|
|
|
|
{Key: "rid", Value: runID.String()},
|
|
|
|
})
|
|
|
|
r := httptest.NewRequest("GET", url, nil).WithContext(valCtx)
|
|
|
|
w := httptest.NewRecorder()
|
|
|
|
h.handleGetRun(w, r)
|
|
|
|
|
|
|
|
res := w.Result()
|
2022-04-13 20:24:27 +00:00
|
|
|
body, err := io.ReadAll(res.Body)
|
2019-02-20 23:49:55 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if res.StatusCode != http.StatusOK {
|
|
|
|
t.Logf("response body: %s", body)
|
|
|
|
t.Fatalf("expected status OK, got %v", res.StatusCode)
|
|
|
|
}
|
|
|
|
|
|
|
|
// The context passed to TaskService.FindRunByID must be a valid authorization (not a session).
|
|
|
|
authr, err := pcontext.GetAuthorizer(findRunByIDCtx)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2020-02-24 19:41:21 +00:00
|
|
|
if authr.Kind() != influxdb.AuthorizationKind {
|
|
|
|
t.Fatalf("expected context's authorizer to be of kind %q, got %q", influxdb.AuthorizationKind, authr.Kind())
|
2019-02-20 23:49:55 +00:00
|
|
|
}
|
|
|
|
if authr.Identifier() != taskAuth.ID {
|
|
|
|
t.Fatalf("expected context's authorizer ID to be %v, got %v", taskAuth.ID, authr.Identifier())
|
|
|
|
}
|
|
|
|
|
|
|
|
// Other user without permissions on the task or authorization should be disallowed.
|
2020-02-24 19:41:21 +00:00
|
|
|
otherUser := &influxdb.User{Name: "other-" + t.Name()}
|
refactor(kv): delete deprecated kv service code
This includes removal of a lot of kv.Service responsibilities. However,
it does not finish the re-wiring. It removes documents, telegrafs,
notification rules + endpoints, checks, orgs, users, buckets, passwords,
urms, labels and authorizations. There are some oustanding pieces that
are needed to get kv service compiling (dashboard service urm
dependency). Then all the call sites for kv service need updating and
the new implementations of telegraf and notification rules + endpoints
needed installing (along with any necessary migrations).
2020-10-20 13:25:36 +00:00
|
|
|
if err := tSvc.CreateUser(ctx, otherUser); err != nil {
|
2019-02-20 23:49:55 +00:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2020-02-24 19:41:21 +00:00
|
|
|
valCtx = pcontext.SetAuthorizer(valCtx, &influxdb.Session{
|
2019-02-20 23:49:55 +00:00
|
|
|
UserID: otherUser.ID,
|
|
|
|
ExpiresAt: time.Now().Add(24 * time.Hour),
|
|
|
|
})
|
|
|
|
|
|
|
|
r = httptest.NewRequest("GET", url, nil).WithContext(valCtx)
|
|
|
|
w = httptest.NewRecorder()
|
|
|
|
h.handleGetRuns(w, r)
|
|
|
|
|
|
|
|
res = w.Result()
|
2022-04-13 20:24:27 +00:00
|
|
|
body, err = io.ReadAll(res.Body)
|
2019-02-20 23:49:55 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if res.StatusCode != http.StatusUnauthorized {
|
|
|
|
t.Logf("response body: %s", body)
|
|
|
|
t.Fatalf("expected status unauthorized, got %v", res.StatusCode)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("get logs for a run", func(t *testing.T) {
|
|
|
|
// Unique authorization to associate with our fake task.
|
2020-02-24 19:41:21 +00:00
|
|
|
taskAuth := &influxdb.Authorization{OrgID: o.ID, UserID: u.ID}
|
refactor(kv): delete deprecated kv service code
This includes removal of a lot of kv.Service responsibilities. However,
it does not finish the re-wiring. It removes documents, telegrafs,
notification rules + endpoints, checks, orgs, users, buckets, passwords,
urms, labels and authorizations. There are some oustanding pieces that
are needed to get kv service compiling (dashboard service urm
dependency). Then all the call sites for kv service need updating and
the new implementations of telegraf and notification rules + endpoints
needed installing (along with any necessary migrations).
2020-10-20 13:25:36 +00:00
|
|
|
if err := authService.CreateAuthorization(ctx, taskAuth); err != nil {
|
2019-02-20 23:49:55 +00:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2021-03-30 18:10:02 +00:00
|
|
|
const taskID = platform.ID(12345)
|
|
|
|
const runID = platform.ID(9876)
|
2019-02-20 23:49:55 +00:00
|
|
|
|
|
|
|
var findLogsCtx context.Context
|
|
|
|
ts := &mock.TaskService{
|
2021-04-07 18:42:55 +00:00
|
|
|
FindLogsFn: func(ctx context.Context, f taskmodel.LogFilter) ([]*taskmodel.Log, int, error) {
|
2019-02-20 23:49:55 +00:00
|
|
|
findLogsCtx = ctx
|
|
|
|
if f.Task != taskID {
|
|
|
|
t.Fatalf("expected task ID %v, got %v", taskID, f.Task)
|
|
|
|
}
|
|
|
|
if *f.Run != runID {
|
|
|
|
t.Fatalf("expected run ID %v, got %v", runID, *f.Run)
|
|
|
|
}
|
|
|
|
|
2021-04-07 18:42:55 +00:00
|
|
|
line := taskmodel.Log{Time: "time", Message: "a log line"}
|
|
|
|
return []*taskmodel.Log{&line}, 1, nil
|
2019-02-20 23:49:55 +00:00
|
|
|
},
|
|
|
|
|
2021-04-07 18:42:55 +00:00
|
|
|
FindTaskByIDFn: func(ctx context.Context, id platform.ID) (*taskmodel.Task, error) {
|
2019-02-20 23:49:55 +00:00
|
|
|
if id != taskID {
|
2021-04-07 18:42:55 +00:00
|
|
|
return nil, taskmodel.ErrTaskNotFound
|
2019-02-20 23:49:55 +00:00
|
|
|
}
|
|
|
|
|
2021-04-07 18:42:55 +00:00
|
|
|
return &taskmodel.Task{
|
2020-08-26 16:26:32 +00:00
|
|
|
ID: taskID,
|
|
|
|
OrganizationID: o.ID,
|
2019-02-20 23:49:55 +00:00
|
|
|
}, nil
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
h := newHandler(t, ts)
|
2020-09-03 21:40:29 +00:00
|
|
|
url := fmt.Sprintf("http://localhost:8086/api/v2/tasks/%s/runs/%s/logs", taskID, runID)
|
2019-02-20 23:49:55 +00:00
|
|
|
valCtx := context.WithValue(sessionAllPermsCtx, httprouter.ParamsKey, httprouter.Params{
|
|
|
|
{Key: "id", Value: taskID.String()},
|
|
|
|
{Key: "rid", Value: runID.String()},
|
|
|
|
})
|
|
|
|
r := httptest.NewRequest("GET", url, nil).WithContext(valCtx)
|
|
|
|
w := httptest.NewRecorder()
|
|
|
|
h.handleGetLogs(w, r)
|
|
|
|
|
|
|
|
res := w.Result()
|
2022-04-13 20:24:27 +00:00
|
|
|
body, err := io.ReadAll(res.Body)
|
2019-02-20 23:49:55 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if res.StatusCode != http.StatusOK {
|
|
|
|
t.Logf("response body: %s", body)
|
|
|
|
t.Fatalf("expected status OK, got %v", res.StatusCode)
|
|
|
|
}
|
|
|
|
|
|
|
|
// The context passed to TaskService.FindLogs must be a valid authorization (not a session).
|
|
|
|
authr, err := pcontext.GetAuthorizer(findLogsCtx)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2020-02-24 19:41:21 +00:00
|
|
|
if authr.Kind() != influxdb.AuthorizationKind {
|
|
|
|
t.Fatalf("expected context's authorizer to be of kind %q, got %q", influxdb.AuthorizationKind, authr.Kind())
|
2019-02-20 23:49:55 +00:00
|
|
|
}
|
|
|
|
if authr.Identifier() != taskAuth.ID {
|
|
|
|
t.Fatalf("expected context's authorizer ID to be %v, got %v", taskAuth.ID, authr.Identifier())
|
|
|
|
}
|
|
|
|
|
|
|
|
// Other user without permissions on the task or authorization should be disallowed.
|
2020-02-24 19:41:21 +00:00
|
|
|
otherUser := &influxdb.User{Name: "other-" + t.Name()}
|
refactor(kv): delete deprecated kv service code
This includes removal of a lot of kv.Service responsibilities. However,
it does not finish the re-wiring. It removes documents, telegrafs,
notification rules + endpoints, checks, orgs, users, buckets, passwords,
urms, labels and authorizations. There are some oustanding pieces that
are needed to get kv service compiling (dashboard service urm
dependency). Then all the call sites for kv service need updating and
the new implementations of telegraf and notification rules + endpoints
needed installing (along with any necessary migrations).
2020-10-20 13:25:36 +00:00
|
|
|
if err := tSvc.CreateUser(ctx, otherUser); err != nil {
|
2019-02-20 23:49:55 +00:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2020-02-24 19:41:21 +00:00
|
|
|
valCtx = pcontext.SetAuthorizer(valCtx, &influxdb.Session{
|
2019-02-20 23:49:55 +00:00
|
|
|
UserID: otherUser.ID,
|
|
|
|
ExpiresAt: time.Now().Add(24 * time.Hour),
|
|
|
|
})
|
|
|
|
|
|
|
|
r = httptest.NewRequest("GET", url, nil).WithContext(valCtx)
|
|
|
|
w = httptest.NewRecorder()
|
|
|
|
h.handleGetRuns(w, r)
|
|
|
|
|
|
|
|
res = w.Result()
|
2022-04-13 20:24:27 +00:00
|
|
|
body, err = io.ReadAll(res.Body)
|
2019-02-20 23:49:55 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if res.StatusCode != http.StatusUnauthorized {
|
|
|
|
t.Logf("response body: %s", body)
|
|
|
|
t.Fatalf("expected status unauthorized, got %v", res.StatusCode)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("retry a run", func(t *testing.T) {
|
|
|
|
// Unique authorization to associate with our fake task.
|
2020-02-24 19:41:21 +00:00
|
|
|
taskAuth := &influxdb.Authorization{OrgID: o.ID, UserID: u.ID}
|
refactor(kv): delete deprecated kv service code
This includes removal of a lot of kv.Service responsibilities. However,
it does not finish the re-wiring. It removes documents, telegrafs,
notification rules + endpoints, checks, orgs, users, buckets, passwords,
urms, labels and authorizations. There are some oustanding pieces that
are needed to get kv service compiling (dashboard service urm
dependency). Then all the call sites for kv service need updating and
the new implementations of telegraf and notification rules + endpoints
needed installing (along with any necessary migrations).
2020-10-20 13:25:36 +00:00
|
|
|
if err := authService.CreateAuthorization(ctx, taskAuth); err != nil {
|
2019-02-20 23:49:55 +00:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2021-03-30 18:10:02 +00:00
|
|
|
const taskID = platform.ID(12345)
|
|
|
|
const runID = platform.ID(9876)
|
2019-02-20 23:49:55 +00:00
|
|
|
|
|
|
|
var retryRunCtx context.Context
|
|
|
|
ts := &mock.TaskService{
|
2021-04-07 18:42:55 +00:00
|
|
|
RetryRunFn: func(ctx context.Context, tid, rid platform.ID) (*taskmodel.Run, error) {
|
2019-02-20 23:49:55 +00:00
|
|
|
retryRunCtx = ctx
|
|
|
|
if tid != taskID {
|
|
|
|
t.Fatalf("expected task ID %v, got %v", taskID, tid)
|
|
|
|
}
|
|
|
|
if rid != runID {
|
|
|
|
t.Fatalf("expected run ID %v, got %v", runID, rid)
|
|
|
|
}
|
|
|
|
|
2021-04-07 18:42:55 +00:00
|
|
|
return &taskmodel.Run{ID: 10 * runID, TaskID: taskID}, nil
|
2019-02-20 23:49:55 +00:00
|
|
|
},
|
|
|
|
|
2021-04-07 18:42:55 +00:00
|
|
|
FindTaskByIDFn: func(ctx context.Context, id platform.ID) (*taskmodel.Task, error) {
|
2019-02-20 23:49:55 +00:00
|
|
|
if id != taskID {
|
2021-04-07 18:42:55 +00:00
|
|
|
return nil, taskmodel.ErrTaskNotFound
|
2019-02-20 23:49:55 +00:00
|
|
|
}
|
|
|
|
|
2021-04-07 18:42:55 +00:00
|
|
|
return &taskmodel.Task{
|
2020-08-26 16:26:32 +00:00
|
|
|
ID: taskID,
|
|
|
|
OrganizationID: o.ID,
|
2019-02-20 23:49:55 +00:00
|
|
|
}, nil
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
h := newHandler(t, ts)
|
2020-09-03 21:40:29 +00:00
|
|
|
url := fmt.Sprintf("http://localhost:8086/api/v2/tasks/%s/runs/%s/retry", taskID, runID)
|
2019-02-20 23:49:55 +00:00
|
|
|
valCtx := context.WithValue(sessionAllPermsCtx, httprouter.ParamsKey, httprouter.Params{
|
|
|
|
{Key: "id", Value: taskID.String()},
|
|
|
|
{Key: "rid", Value: runID.String()},
|
|
|
|
})
|
|
|
|
r := httptest.NewRequest("POST", url, nil).WithContext(valCtx)
|
|
|
|
w := httptest.NewRecorder()
|
|
|
|
h.handleRetryRun(w, r)
|
|
|
|
|
|
|
|
res := w.Result()
|
2022-04-13 20:24:27 +00:00
|
|
|
body, err := io.ReadAll(res.Body)
|
2019-02-20 23:49:55 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if res.StatusCode != http.StatusOK {
|
|
|
|
t.Logf("response body: %s", body)
|
|
|
|
t.Fatalf("expected status OK, got %v", res.StatusCode)
|
|
|
|
}
|
|
|
|
|
|
|
|
// The context passed to TaskService.RetryRun must be a valid authorization (not a session).
|
|
|
|
authr, err := pcontext.GetAuthorizer(retryRunCtx)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2020-02-24 19:41:21 +00:00
|
|
|
if authr.Kind() != influxdb.AuthorizationKind {
|
|
|
|
t.Fatalf("expected context's authorizer to be of kind %q, got %q", influxdb.AuthorizationKind, authr.Kind())
|
2019-02-20 23:49:55 +00:00
|
|
|
}
|
|
|
|
if authr.Identifier() != taskAuth.ID {
|
|
|
|
t.Fatalf("expected context's authorizer ID to be %v, got %v", taskAuth.ID, authr.Identifier())
|
|
|
|
}
|
|
|
|
|
|
|
|
// Other user without permissions on the task or authorization should be disallowed.
|
2020-02-24 19:41:21 +00:00
|
|
|
otherUser := &influxdb.User{Name: "other-" + t.Name()}
|
refactor(kv): delete deprecated kv service code
This includes removal of a lot of kv.Service responsibilities. However,
it does not finish the re-wiring. It removes documents, telegrafs,
notification rules + endpoints, checks, orgs, users, buckets, passwords,
urms, labels and authorizations. There are some oustanding pieces that
are needed to get kv service compiling (dashboard service urm
dependency). Then all the call sites for kv service need updating and
the new implementations of telegraf and notification rules + endpoints
needed installing (along with any necessary migrations).
2020-10-20 13:25:36 +00:00
|
|
|
if err := tSvc.CreateUser(ctx, otherUser); err != nil {
|
2019-02-20 23:49:55 +00:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2020-02-24 19:41:21 +00:00
|
|
|
valCtx = pcontext.SetAuthorizer(valCtx, &influxdb.Session{
|
2019-02-20 23:49:55 +00:00
|
|
|
UserID: otherUser.ID,
|
|
|
|
ExpiresAt: time.Now().Add(24 * time.Hour),
|
|
|
|
})
|
|
|
|
|
|
|
|
r = httptest.NewRequest("POST", url, nil).WithContext(valCtx)
|
|
|
|
w = httptest.NewRecorder()
|
|
|
|
h.handleGetRuns(w, r)
|
|
|
|
|
|
|
|
res = w.Result()
|
2022-04-13 20:24:27 +00:00
|
|
|
body, err = io.ReadAll(res.Body)
|
2019-02-20 23:49:55 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if res.StatusCode != http.StatusUnauthorized {
|
|
|
|
t.Logf("response body: %s", body)
|
|
|
|
t.Fatalf("expected status unauthorized, got %v", res.StatusCode)
|
|
|
|
}
|
|
|
|
})
|
2019-02-15 18:44:27 +00:00
|
|
|
}
|