2019-04-09 22:52:54 +00:00
|
|
|
package kv_test
|
|
|
|
|
|
|
|
import (
|
2019-08-23 22:52:55 +00:00
|
|
|
"bytes"
|
2019-04-09 22:52:54 +00:00
|
|
|
"context"
|
2019-08-23 22:52:55 +00:00
|
|
|
"encoding/json"
|
2019-04-09 22:52:54 +00:00
|
|
|
"testing"
|
2019-08-15 21:28:35 +00:00
|
|
|
"time"
|
2019-04-09 22:52:54 +00:00
|
|
|
|
2019-08-15 21:28:35 +00:00
|
|
|
"github.com/influxdata/influxdb"
|
|
|
|
icontext "github.com/influxdata/influxdb/context"
|
2019-04-09 22:52:54 +00:00
|
|
|
"github.com/influxdata/influxdb/kv"
|
|
|
|
_ "github.com/influxdata/influxdb/query/builtin"
|
2019-12-02 22:16:10 +00:00
|
|
|
"github.com/influxdata/influxdb/task/backend"
|
2019-04-09 22:52:54 +00:00
|
|
|
"github.com/influxdata/influxdb/task/servicetest"
|
2019-12-04 23:10:23 +00:00
|
|
|
"go.uber.org/zap/zaptest"
|
2019-04-09 22:52:54 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestInmemTaskService(t *testing.T) {
|
|
|
|
servicetest.TestTaskService(
|
|
|
|
t,
|
|
|
|
func(t *testing.T) (*servicetest.System, context.CancelFunc) {
|
2019-12-04 23:10:23 +00:00
|
|
|
store, close, err := NewTestInmemStore(t)
|
2019-04-09 22:52:54 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2019-12-04 23:10:23 +00:00
|
|
|
service := kv.NewService(zaptest.NewLogger(t), store)
|
2019-04-09 22:52:54 +00:00
|
|
|
ctx, cancelFunc := context.WithCancel(context.Background())
|
|
|
|
|
|
|
|
if err := service.Initialize(ctx); err != nil {
|
|
|
|
t.Fatalf("error initializing urm service: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
<-ctx.Done()
|
|
|
|
close()
|
|
|
|
}()
|
|
|
|
|
|
|
|
return &servicetest.System{
|
|
|
|
TaskControlService: service,
|
|
|
|
TaskService: service,
|
|
|
|
I: service,
|
|
|
|
Ctx: ctx,
|
|
|
|
}, cancelFunc
|
|
|
|
},
|
|
|
|
"transactional",
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestBoltTaskService(t *testing.T) {
|
|
|
|
servicetest.TestTaskService(
|
|
|
|
t,
|
|
|
|
func(t *testing.T) (*servicetest.System, context.CancelFunc) {
|
2019-12-04 23:10:23 +00:00
|
|
|
store, close, err := NewTestBoltStore(t)
|
2019-04-09 22:52:54 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2019-12-04 23:10:23 +00:00
|
|
|
service := kv.NewService(zaptest.NewLogger(t), store)
|
2019-04-09 22:52:54 +00:00
|
|
|
ctx, cancelFunc := context.WithCancel(context.Background())
|
|
|
|
if err := service.Initialize(ctx); err != nil {
|
|
|
|
t.Fatalf("error initializing urm service: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
<-ctx.Done()
|
|
|
|
close()
|
|
|
|
}()
|
|
|
|
|
|
|
|
return &servicetest.System{
|
|
|
|
TaskControlService: service,
|
|
|
|
TaskService: service,
|
|
|
|
I: service,
|
|
|
|
Ctx: ctx,
|
|
|
|
}, cancelFunc
|
|
|
|
},
|
|
|
|
"transactional",
|
|
|
|
)
|
|
|
|
}
|
2019-08-15 21:28:35 +00:00
|
|
|
|
|
|
|
func TestNextRunDue(t *testing.T) {
|
2019-12-04 23:10:23 +00:00
|
|
|
store, close, err := NewTestBoltStore(t)
|
2019-08-15 21:28:35 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
defer close()
|
|
|
|
|
2019-12-04 23:10:23 +00:00
|
|
|
service := kv.NewService(zaptest.NewLogger(t), store)
|
2019-08-15 21:28:35 +00:00
|
|
|
ctx, cancelFunc := context.WithCancel(context.Background())
|
|
|
|
if err := service.Initialize(ctx); err != nil {
|
|
|
|
t.Fatalf("error initializing urm service: %v", err)
|
|
|
|
}
|
|
|
|
defer cancelFunc()
|
|
|
|
u := &influxdb.User{Name: t.Name() + "-user"}
|
|
|
|
if err := service.CreateUser(ctx, u); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
o := &influxdb.Organization{Name: t.Name() + "-org"}
|
|
|
|
if err := service.CreateOrganization(ctx, o); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := service.CreateUserResourceMapping(ctx, &influxdb.UserResourceMapping{
|
|
|
|
ResourceType: influxdb.OrgsResourceType,
|
|
|
|
ResourceID: o.ID,
|
|
|
|
UserID: u.ID,
|
|
|
|
UserType: influxdb.Owner,
|
|
|
|
}); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
authz := influxdb.Authorization{
|
|
|
|
OrgID: o.ID,
|
|
|
|
UserID: u.ID,
|
|
|
|
Permissions: influxdb.OperPermissions(),
|
|
|
|
}
|
|
|
|
if err := service.CreateAuthorization(context.Background(), &authz); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx = icontext.SetAuthorizer(ctx, &authz)
|
|
|
|
|
2019-09-25 21:21:37 +00:00
|
|
|
task1, err := service.CreateTask(ctx, influxdb.TaskCreate{
|
|
|
|
Flux: `option task = {name: "a task",cron: "0 * * * *", offset: 20s} from(bucket:"test") |> range(start:-1h)`,
|
2019-08-15 21:28:35 +00:00
|
|
|
OrganizationID: o.ID,
|
2019-08-16 00:31:52 +00:00
|
|
|
OwnerID: u.ID,
|
2019-08-15 21:28:35 +00:00
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2019-09-25 21:21:37 +00:00
|
|
|
task2, err := service.CreateTask(ctx, influxdb.TaskCreate{
|
|
|
|
Flux: `option task = {name: "a task",every: 1h, offset: 20s} from(bucket:"test") |> range(start:-1h)`,
|
|
|
|
OrganizationID: o.ID,
|
|
|
|
OwnerID: u.ID,
|
|
|
|
})
|
2019-08-15 21:28:35 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2019-09-25 21:21:37 +00:00
|
|
|
task3, err := service.CreateTask(ctx, influxdb.TaskCreate{
|
|
|
|
Flux: `option task = {name: "a task",every: 1h} from(bucket:"test") |> range(start:-1h)`,
|
|
|
|
OrganizationID: o.ID,
|
|
|
|
OwnerID: u.ID,
|
|
|
|
})
|
2019-08-15 21:28:35 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2019-09-25 21:21:37 +00:00
|
|
|
for _, task := range []*influxdb.Task{task1, task2, task3} {
|
|
|
|
nd, err := service.NextDueRun(ctx, task.ID)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
run, err := service.CreateNextRun(ctx, task.ID, time.Now().Add(time.Hour).Unix())
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// +20 to account for the 20 second offset in the flux script
|
|
|
|
oldNextDue := run.Created.Now
|
2019-11-13 01:13:56 +00:00
|
|
|
if task.Offset != 0 {
|
2019-09-25 21:21:37 +00:00
|
|
|
oldNextDue += 20
|
|
|
|
}
|
|
|
|
if oldNextDue != nd {
|
|
|
|
t.Fatalf("expected nextRunDue and created run to match, %d, %d", nd, run.Created.Now)
|
|
|
|
}
|
|
|
|
nd1, err := service.NextDueRun(ctx, task.ID)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if run.NextDue != nd1 {
|
|
|
|
t.Fatalf("expected returned next run to be the same as teh next due after scheduling %d, %d", run.NextDue, nd1)
|
|
|
|
}
|
2019-08-15 21:28:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2019-08-23 22:52:55 +00:00
|
|
|
|
|
|
|
func TestRetrieveTaskWithBadAuth(t *testing.T) {
|
2019-12-04 23:10:23 +00:00
|
|
|
store, close, err := NewTestInmemStore(t)
|
2019-08-23 22:52:55 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
defer close()
|
|
|
|
|
2019-12-04 23:10:23 +00:00
|
|
|
service := kv.NewService(zaptest.NewLogger(t), store)
|
2019-08-23 22:52:55 +00:00
|
|
|
ctx, cancelFunc := context.WithCancel(context.Background())
|
|
|
|
if err := service.Initialize(ctx); err != nil {
|
|
|
|
t.Fatalf("error initializing urm service: %v", err)
|
|
|
|
}
|
|
|
|
defer cancelFunc()
|
|
|
|
u := &influxdb.User{Name: t.Name() + "-user"}
|
|
|
|
if err := service.CreateUser(ctx, u); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
o := &influxdb.Organization{Name: t.Name() + "-org"}
|
|
|
|
if err := service.CreateOrganization(ctx, o); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := service.CreateUserResourceMapping(ctx, &influxdb.UserResourceMapping{
|
|
|
|
ResourceType: influxdb.OrgsResourceType,
|
|
|
|
ResourceID: o.ID,
|
|
|
|
UserID: u.ID,
|
|
|
|
UserType: influxdb.Owner,
|
|
|
|
}); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
authz := influxdb.Authorization{
|
|
|
|
OrgID: o.ID,
|
|
|
|
UserID: u.ID,
|
|
|
|
Permissions: influxdb.OperPermissions(),
|
|
|
|
}
|
|
|
|
if err := service.CreateAuthorization(context.Background(), &authz); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx = icontext.SetAuthorizer(ctx, &authz)
|
|
|
|
|
|
|
|
task, err := service.CreateTask(ctx, influxdb.TaskCreate{
|
|
|
|
Flux: `option task = {name: "a task",every: 1h} from(bucket:"test") |> range(start:-1h)`,
|
|
|
|
OrganizationID: o.ID,
|
|
|
|
OwnerID: u.ID,
|
2019-12-02 22:16:10 +00:00
|
|
|
Status: string(backend.TaskActive),
|
2019-08-23 22:52:55 +00:00
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// convert task to old one with a bad auth
|
|
|
|
err = store.Update(ctx, func(tx kv.Tx) error {
|
|
|
|
b, err := tx.Bucket([]byte("tasksv1"))
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
bID, err := task.ID.Encode()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
task.OwnerID = influxdb.ID(1)
|
|
|
|
task.AuthorizationID = influxdb.ID(132) // bad id or an id that doesnt match any auth
|
|
|
|
tbyte, err := json.Marshal(task)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
// have to actually hack the bytes here because the system doesnt like us to encode bad id's.
|
|
|
|
tbyte = bytes.Replace(tbyte, []byte(`,"ownerID":"0000000000000001"`), []byte{}, 1)
|
|
|
|
if err := b.Put(bID, tbyte); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// lets see if we can list and find the task
|
|
|
|
newTask, err := service.FindTaskByID(ctx, task.ID)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if newTask.ID != task.ID {
|
|
|
|
t.Fatal("miss matching taskID's")
|
|
|
|
}
|
|
|
|
|
|
|
|
tasks, _, err := service.FindTasks(ctx, influxdb.TaskFilter{})
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if len(tasks) != 1 {
|
|
|
|
t.Fatal("failed to return task")
|
|
|
|
}
|
2019-12-02 22:16:10 +00:00
|
|
|
|
|
|
|
// test status filter
|
|
|
|
active := string(backend.TaskActive)
|
|
|
|
tasksWithActiveFilter, _, err := service.FindTasks(ctx, influxdb.TaskFilter{Status: &active})
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal("could not find tasks")
|
|
|
|
}
|
|
|
|
if len(tasksWithActiveFilter) != 1 {
|
|
|
|
t.Fatal("failed to find active task with filter")
|
|
|
|
}
|
2019-08-23 22:52:55 +00:00
|
|
|
}
|