Skip to content

Commit

Permalink
Allow scheduling same query more than once in UI
Browse files Browse the repository at this point in the history
  • Loading branch information
zwass committed Dec 4, 2020
1 parent 149b4ed commit fd87d63
Show file tree
Hide file tree
Showing 2 changed files with 168 additions and 1 deletion.
25 changes: 24 additions & 1 deletion server/service/service_scheduled_queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,35 @@ func (svc service) ScheduleQuery(ctx context.Context, sq *kolide.ScheduledQuery)
if err != nil {
return nil, errors.Wrap(err, "lookup name for query")
}
sq.Name = query.Name

packQueries, err := svc.ds.ListScheduledQueriesInPack(sq.PackID, kolide.ListOptions{})
if err != nil {
return nil, errors.Wrap(err, "find existing scheduled queries")
}
_ = packQueries

sq.Name = findNextNameForQuery(query.Name, packQueries)
sq.QueryName = query.Name
} else if sq.QueryName == "" {
query, err := svc.ds.Query(sq.QueryID)
if err != nil {
return nil, errors.Wrap(err, "lookup name for query")
}
sq.QueryName = query.Name
}
return svc.ds.NewScheduledQuery(sq)
}

// Add "-1" suffixes to the query name until it is unique
func findNextNameForQuery(name string, scheduled []*kolide.ScheduledQuery) string {
for _, q := range scheduled {
if name == q.Name {
return findNextNameForQuery(name+"-1", scheduled)
}
}
return name
}

func (svc service) ModifyScheduledQuery(ctx context.Context, id uint, p kolide.ScheduledQueryPayload) (*kolide.ScheduledQuery, error) {
sq, err := svc.GetScheduledQuery(ctx, id)
if err != nil {
Expand Down
144 changes: 144 additions & 0 deletions server/service/service_scheduled_queries_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
package service

import (
"context"
"testing"

"github.com/fleetdm/fleet/server/kolide"
"github.com/fleetdm/fleet/server/mock"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestScheduleQuery(t *testing.T) {
ds := new(mock.Store)
svc, err := newTestService(ds, nil, nil)
require.Nil(t, err)

expectedQuery := &kolide.ScheduledQuery{
Name: "foobar",
QueryName: "foobar",
QueryID: 3,
}

ds.NewScheduledQueryFunc = func(q *kolide.ScheduledQuery, opts ...kolide.OptionalArg) (*kolide.ScheduledQuery, error) {
assert.Equal(t, expectedQuery, q)
return expectedQuery, nil
}

_, err = svc.ScheduleQuery(context.Background(), expectedQuery)
assert.NoError(t, err)
assert.True(t, ds.NewScheduledQueryFuncInvoked)
}

func TestScheduleQueryNoName(t *testing.T) {
ds := new(mock.Store)
svc, err := newTestService(ds, nil, nil)
require.Nil(t, err)

expectedQuery := &kolide.ScheduledQuery{
Name: "foobar",
QueryName: "foobar",
QueryID: 3,
}

ds.QueryFunc = func(qid uint) (*kolide.Query, error) {
require.Equal(t, expectedQuery.QueryID, qid)
return &kolide.Query{Name: expectedQuery.QueryName}, nil
}
ds.ListScheduledQueriesInPackFunc = func(id uint, opts kolide.ListOptions) ([]*kolide.ScheduledQuery, error) {
// No matching query
return []*kolide.ScheduledQuery{
&kolide.ScheduledQuery{
Name: "froobling",
},
}, nil
}
ds.NewScheduledQueryFunc = func(q *kolide.ScheduledQuery, opts ...kolide.OptionalArg) (*kolide.ScheduledQuery, error) {
assert.Equal(t, expectedQuery, q)
return expectedQuery, nil
}

_, err = svc.ScheduleQuery(
context.Background(),
&kolide.ScheduledQuery{QueryID: expectedQuery.QueryID},
)
assert.NoError(t, err)
assert.True(t, ds.NewScheduledQueryFuncInvoked)
}

func TestScheduleQueryNoNameMultiple(t *testing.T) {
ds := new(mock.Store)
svc, err := newTestService(ds, nil, nil)
require.Nil(t, err)

expectedQuery := &kolide.ScheduledQuery{
Name: "foobar-1",
QueryName: "foobar",
QueryID: 3,
}

ds.QueryFunc = func(qid uint) (*kolide.Query, error) {
require.Equal(t, expectedQuery.QueryID, qid)
return &kolide.Query{Name: expectedQuery.QueryName}, nil
}
ds.ListScheduledQueriesInPackFunc = func(id uint, opts kolide.ListOptions) ([]*kolide.ScheduledQuery, error) {
// No matching query
return []*kolide.ScheduledQuery{
&kolide.ScheduledQuery{
Name: "foobar",
},
}, nil
}
ds.NewScheduledQueryFunc = func(q *kolide.ScheduledQuery, opts ...kolide.OptionalArg) (*kolide.ScheduledQuery, error) {
assert.Equal(t, expectedQuery, q)
return expectedQuery, nil
}

_, err = svc.ScheduleQuery(
context.Background(),
&kolide.ScheduledQuery{QueryID: expectedQuery.QueryID},
)
assert.NoError(t, err)
assert.True(t, ds.NewScheduledQueryFuncInvoked)
}

func TestFindNextNameForQuery(t *testing.T) {
var testCases = []struct {
name string
scheduled []*kolide.ScheduledQuery
expected string
}{
{
name: "foobar",
scheduled: []*kolide.ScheduledQuery{},
expected: "foobar",
},
{
name: "foobar",
scheduled: []*kolide.ScheduledQuery{
{
Name: "foobar",
},
},
expected: "foobar-1",
}, {
name: "foobar",
scheduled: []*kolide.ScheduledQuery{
{
Name: "foobar",
},
{
Name: "foobar-1",
},
},
expected: "foobar-1-1",
},
}

for _, tt := range testCases {
t.Run("", func(t *testing.T) {
assert.Equal(t, tt.expected, findNextNameForQuery(tt.name, tt.scheduled))
})
}
}

0 comments on commit fd87d63

Please sign in to comment.