2016-11-02 14:59:53 +00:00
|
|
|
package service
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
2016-11-18 17:23:44 +00:00
|
|
|
"github.com/WatchBeam/clock"
|
2016-11-25 18:08:22 +00:00
|
|
|
"github.com/kolide/kolide-ose/server/config"
|
2016-11-16 13:47:49 +00:00
|
|
|
"github.com/kolide/kolide-ose/server/datastore/inmem"
|
2016-11-02 14:59:53 +00:00
|
|
|
"github.com/kolide/kolide-ose/server/kolide"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"golang.org/x/net/context"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestSearchTargets(t *testing.T) {
|
2016-11-25 18:08:22 +00:00
|
|
|
ds, err := inmem.New(config.TestConfig())
|
2016-11-02 14:59:53 +00:00
|
|
|
require.Nil(t, err)
|
|
|
|
|
2016-11-14 18:22:54 +00:00
|
|
|
svc, err := newTestService(ds, nil)
|
2016-11-02 14:59:53 +00:00
|
|
|
require.Nil(t, err)
|
|
|
|
|
|
|
|
ctx := context.Background()
|
|
|
|
|
|
|
|
h1, err := ds.NewHost(&kolide.Host{
|
2016-12-01 17:00:00 +00:00
|
|
|
HostName: "foo.local",
|
2016-11-02 14:59:53 +00:00
|
|
|
})
|
|
|
|
require.Nil(t, err)
|
|
|
|
|
|
|
|
l1, err := ds.NewLabel(&kolide.Label{
|
2016-11-03 01:17:23 +00:00
|
|
|
Name: "label foo",
|
|
|
|
Query: "query foo",
|
2016-11-02 14:59:53 +00:00
|
|
|
})
|
|
|
|
require.Nil(t, err)
|
|
|
|
|
|
|
|
results, err := svc.SearchTargets(ctx, "foo", nil, nil)
|
|
|
|
require.Nil(t, err)
|
|
|
|
|
|
|
|
require.Len(t, results.Hosts, 1)
|
|
|
|
assert.Equal(t, h1.HostName, results.Hosts[0].HostName)
|
|
|
|
|
|
|
|
require.Len(t, results.Labels, 1)
|
|
|
|
assert.Equal(t, l1.Name, results.Labels[0].Name)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestCountHostsInTargets(t *testing.T) {
|
2016-11-25 18:08:22 +00:00
|
|
|
ds, err := inmem.New(config.TestConfig())
|
2016-11-02 14:59:53 +00:00
|
|
|
require.Nil(t, err)
|
|
|
|
|
2016-11-18 17:23:44 +00:00
|
|
|
mockClock := clock.NewMockClock()
|
|
|
|
|
|
|
|
svc, err := newTestServiceWithClock(ds, nil, mockClock)
|
2016-11-02 14:59:53 +00:00
|
|
|
require.Nil(t, err)
|
|
|
|
|
|
|
|
ctx := context.Background()
|
|
|
|
|
|
|
|
h1, err := ds.NewHost(&kolide.Host{
|
2016-12-01 17:00:00 +00:00
|
|
|
HostName: "foo.local",
|
|
|
|
NodeKey: "1",
|
|
|
|
UUID: "1",
|
2016-11-02 14:59:53 +00:00
|
|
|
})
|
|
|
|
require.Nil(t, err)
|
2016-11-18 17:23:44 +00:00
|
|
|
require.Nil(t, ds.MarkHostSeen(h1, mockClock.Now()))
|
2016-11-02 14:59:53 +00:00
|
|
|
|
|
|
|
h2, err := ds.NewHost(&kolide.Host{
|
2016-12-01 17:00:00 +00:00
|
|
|
HostName: "bar.local",
|
|
|
|
NodeKey: "2",
|
|
|
|
UUID: "2",
|
2016-11-02 14:59:53 +00:00
|
|
|
})
|
|
|
|
require.Nil(t, err)
|
2016-11-18 17:23:44 +00:00
|
|
|
// make this host "offline"
|
|
|
|
require.Nil(t, ds.MarkHostSeen(h2, mockClock.Now().Add(-1*time.Hour)))
|
2016-11-02 14:59:53 +00:00
|
|
|
|
|
|
|
h3, err := ds.NewHost(&kolide.Host{
|
2016-12-01 17:00:00 +00:00
|
|
|
HostName: "baz.local",
|
|
|
|
NodeKey: "3",
|
|
|
|
UUID: "3",
|
2016-11-02 14:59:53 +00:00
|
|
|
})
|
|
|
|
require.Nil(t, err)
|
2016-11-18 17:23:44 +00:00
|
|
|
require.Nil(t, ds.MarkHostSeen(h3, mockClock.Now().Add(-5*time.Minute)))
|
2016-11-02 14:59:53 +00:00
|
|
|
|
|
|
|
h4, err := ds.NewHost(&kolide.Host{
|
2016-12-01 17:00:00 +00:00
|
|
|
HostName: "xxx.local",
|
|
|
|
NodeKey: "4",
|
|
|
|
UUID: "4",
|
2016-11-02 14:59:53 +00:00
|
|
|
})
|
|
|
|
require.Nil(t, err)
|
2016-11-18 17:23:44 +00:00
|
|
|
require.Nil(t, ds.MarkHostSeen(h4, mockClock.Now()))
|
2016-11-02 14:59:53 +00:00
|
|
|
|
|
|
|
h5, err := ds.NewHost(&kolide.Host{
|
2016-12-01 17:00:00 +00:00
|
|
|
HostName: "yyy.local",
|
|
|
|
NodeKey: "5",
|
|
|
|
UUID: "5",
|
2016-11-02 14:59:53 +00:00
|
|
|
})
|
|
|
|
require.Nil(t, err)
|
2016-11-18 17:23:44 +00:00
|
|
|
require.Nil(t, ds.MarkHostSeen(h5, mockClock.Now()))
|
2016-11-02 14:59:53 +00:00
|
|
|
|
2016-12-06 17:37:22 +00:00
|
|
|
h6, err := ds.NewHost(&kolide.Host{
|
|
|
|
HostName: "zzz.local",
|
|
|
|
NodeKey: "6",
|
|
|
|
UUID: "6",
|
|
|
|
})
|
|
|
|
require.Nil(t, err)
|
|
|
|
const thirtyDaysAndAMinuteAgo = -1 * (30*24*60 + 1)
|
|
|
|
require.Nil(t, ds.MarkHostSeen(h6, mockClock.Now().Add(thirtyDaysAndAMinuteAgo*time.Minute)))
|
|
|
|
|
2016-11-02 14:59:53 +00:00
|
|
|
l1, err := ds.NewLabel(&kolide.Label{
|
2016-11-03 01:17:23 +00:00
|
|
|
Name: "label foo",
|
|
|
|
Query: "query foo",
|
2016-11-02 14:59:53 +00:00
|
|
|
})
|
|
|
|
require.Nil(t, err)
|
|
|
|
require.NotZero(t, l1.ID)
|
|
|
|
l1ID := fmt.Sprintf("%d", l1.ID)
|
|
|
|
|
|
|
|
l2, err := ds.NewLabel(&kolide.Label{
|
2016-11-03 01:17:23 +00:00
|
|
|
Name: "label bar",
|
|
|
|
Query: "query foo",
|
2016-11-02 14:59:53 +00:00
|
|
|
})
|
|
|
|
require.Nil(t, err)
|
|
|
|
require.NotZero(t, l2.ID)
|
|
|
|
l2ID := fmt.Sprintf("%d", l2.ID)
|
|
|
|
|
2016-12-06 17:37:22 +00:00
|
|
|
for _, h := range []*kolide.Host{h1, h2, h3, h6} {
|
2017-01-04 21:16:17 +00:00
|
|
|
err = ds.RecordLabelQueryExecutions(h, map[string]bool{l1ID: true}, mockClock.Now())
|
2016-11-02 14:59:53 +00:00
|
|
|
assert.Nil(t, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, h := range []*kolide.Host{h3, h4, h5} {
|
2017-01-04 21:16:17 +00:00
|
|
|
err = ds.RecordLabelQueryExecutions(h, map[string]bool{l2ID: true}, mockClock.Now())
|
2016-11-02 14:59:53 +00:00
|
|
|
assert.Nil(t, err)
|
|
|
|
}
|
|
|
|
|
2016-12-06 17:37:22 +00:00
|
|
|
metrics, err := svc.CountHostsInTargets(ctx, nil, []uint{l1.ID, l2.ID})
|
|
|
|
require.Nil(t, err)
|
|
|
|
require.NotNil(t, metrics)
|
|
|
|
assert.Equal(t, uint(6), metrics.TotalHosts)
|
|
|
|
assert.Equal(t, uint(1), metrics.OfflineHosts)
|
|
|
|
assert.Equal(t, uint(4), metrics.OnlineHosts)
|
|
|
|
assert.Equal(t, uint(1), metrics.MissingInActionHosts)
|
2016-11-02 14:59:53 +00:00
|
|
|
|
2016-12-06 17:37:22 +00:00
|
|
|
metrics, err = svc.CountHostsInTargets(ctx, []uint{h1.ID, h2.ID}, []uint{l1.ID, l2.ID})
|
|
|
|
require.Nil(t, err)
|
|
|
|
require.NotNil(t, metrics)
|
|
|
|
assert.Equal(t, uint(6), metrics.TotalHosts)
|
|
|
|
assert.Equal(t, uint(1), metrics.OfflineHosts)
|
|
|
|
assert.Equal(t, uint(4), metrics.OnlineHosts)
|
|
|
|
assert.Equal(t, uint(1), metrics.MissingInActionHosts)
|
2016-11-02 14:59:53 +00:00
|
|
|
|
2016-12-06 17:37:22 +00:00
|
|
|
metrics, err = svc.CountHostsInTargets(ctx, []uint{h1.ID, h2.ID}, nil)
|
|
|
|
require.Nil(t, err)
|
|
|
|
require.NotNil(t, metrics)
|
|
|
|
assert.Equal(t, uint(2), metrics.TotalHosts)
|
|
|
|
assert.Equal(t, uint(1), metrics.OnlineHosts)
|
|
|
|
assert.Equal(t, uint(1), metrics.OfflineHosts)
|
|
|
|
assert.Equal(t, uint(0), metrics.MissingInActionHosts)
|
2016-11-02 14:59:53 +00:00
|
|
|
|
2016-12-06 17:37:22 +00:00
|
|
|
metrics, err = svc.CountHostsInTargets(ctx, []uint{h1.ID}, []uint{l2.ID})
|
|
|
|
require.Nil(t, err)
|
|
|
|
require.NotNil(t, metrics)
|
|
|
|
assert.Equal(t, uint(4), metrics.TotalHosts)
|
|
|
|
assert.Equal(t, uint(4), metrics.OnlineHosts)
|
|
|
|
assert.Equal(t, uint(0), metrics.OfflineHosts)
|
|
|
|
assert.Equal(t, uint(0), metrics.MissingInActionHosts)
|
2016-11-02 14:59:53 +00:00
|
|
|
|
2016-12-06 17:37:22 +00:00
|
|
|
metrics, err = svc.CountHostsInTargets(ctx, nil, nil)
|
|
|
|
require.Nil(t, err)
|
|
|
|
require.NotNil(t, metrics)
|
|
|
|
assert.Equal(t, uint(0), metrics.TotalHosts)
|
|
|
|
assert.Equal(t, uint(0), metrics.OnlineHosts)
|
|
|
|
assert.Equal(t, uint(0), metrics.OfflineHosts)
|
|
|
|
assert.Equal(t, uint(0), metrics.MissingInActionHosts)
|
2016-11-18 17:23:44 +00:00
|
|
|
|
|
|
|
// Advance clock so all hosts are offline
|
|
|
|
mockClock.AddTime(1 * time.Hour)
|
2016-12-06 17:37:22 +00:00
|
|
|
metrics, err = svc.CountHostsInTargets(ctx, nil, []uint{l1.ID, l2.ID})
|
|
|
|
require.Nil(t, err)
|
|
|
|
require.NotNil(t, metrics)
|
|
|
|
assert.Equal(t, uint(6), metrics.TotalHosts)
|
|
|
|
assert.Equal(t, uint(0), metrics.OnlineHosts)
|
|
|
|
assert.Equal(t, uint(5), metrics.OfflineHosts)
|
|
|
|
assert.Equal(t, uint(1), metrics.MissingInActionHosts)
|
2016-11-18 17:23:44 +00:00
|
|
|
|
2016-11-02 14:59:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestSearchWithOmit(t *testing.T) {
|
2016-11-25 18:08:22 +00:00
|
|
|
ds, err := inmem.New(config.TestConfig())
|
2016-11-02 14:59:53 +00:00
|
|
|
require.Nil(t, err)
|
|
|
|
|
2016-11-14 18:22:54 +00:00
|
|
|
svc, err := newTestService(ds, nil)
|
2016-11-02 14:59:53 +00:00
|
|
|
require.Nil(t, err)
|
|
|
|
|
|
|
|
ctx := context.Background()
|
|
|
|
|
|
|
|
h1, err := ds.NewHost(&kolide.Host{
|
2016-12-01 17:00:00 +00:00
|
|
|
HostName: "foo.local",
|
|
|
|
NodeKey: "1",
|
|
|
|
UUID: "1",
|
2016-11-02 14:59:53 +00:00
|
|
|
})
|
|
|
|
require.Nil(t, err)
|
|
|
|
|
|
|
|
h2, err := ds.NewHost(&kolide.Host{
|
2016-12-01 17:00:00 +00:00
|
|
|
HostName: "foobar.local",
|
|
|
|
NodeKey: "2",
|
|
|
|
UUID: "2",
|
2016-11-02 14:59:53 +00:00
|
|
|
})
|
|
|
|
require.Nil(t, err)
|
|
|
|
|
|
|
|
l1, err := ds.NewLabel(&kolide.Label{
|
2016-11-03 01:17:23 +00:00
|
|
|
Name: "label foo",
|
|
|
|
Query: "query foo",
|
2016-11-02 14:59:53 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
{
|
|
|
|
results, err := svc.SearchTargets(ctx, "foo", nil, nil)
|
|
|
|
require.Nil(t, err)
|
|
|
|
|
|
|
|
require.Len(t, results.Hosts, 2)
|
|
|
|
|
|
|
|
require.Len(t, results.Labels, 1)
|
|
|
|
assert.Equal(t, l1.Name, results.Labels[0].Name)
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
results, err := svc.SearchTargets(ctx, "foo", []uint{h2.ID}, nil)
|
|
|
|
require.Nil(t, err)
|
|
|
|
|
|
|
|
require.Len(t, results.Hosts, 1)
|
|
|
|
assert.Equal(t, h1.HostName, results.Hosts[0].HostName)
|
|
|
|
|
|
|
|
require.Len(t, results.Labels, 1)
|
|
|
|
assert.Equal(t, l1.Name, results.Labels[0].Name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSearchHostsInLabels(t *testing.T) {
|
2016-11-25 18:08:22 +00:00
|
|
|
ds, err := inmem.New(config.TestConfig())
|
2016-11-02 14:59:53 +00:00
|
|
|
require.Nil(t, err)
|
|
|
|
|
2016-11-14 18:22:54 +00:00
|
|
|
svc, err := newTestService(ds, nil)
|
2016-11-02 14:59:53 +00:00
|
|
|
require.Nil(t, err)
|
|
|
|
|
|
|
|
ctx := context.Background()
|
|
|
|
|
|
|
|
h1, err := ds.NewHost(&kolide.Host{
|
2016-12-01 17:00:00 +00:00
|
|
|
HostName: "foo.local",
|
|
|
|
NodeKey: "1",
|
|
|
|
UUID: "1",
|
2016-11-02 14:59:53 +00:00
|
|
|
})
|
|
|
|
require.Nil(t, err)
|
|
|
|
|
|
|
|
h2, err := ds.NewHost(&kolide.Host{
|
2016-12-01 17:00:00 +00:00
|
|
|
HostName: "bar.local",
|
|
|
|
NodeKey: "2",
|
|
|
|
UUID: "2",
|
2016-11-02 14:59:53 +00:00
|
|
|
})
|
|
|
|
require.Nil(t, err)
|
|
|
|
|
|
|
|
h3, err := ds.NewHost(&kolide.Host{
|
2016-12-01 17:00:00 +00:00
|
|
|
HostName: "baz.local",
|
|
|
|
NodeKey: "3",
|
|
|
|
UUID: "3",
|
2016-11-02 14:59:53 +00:00
|
|
|
})
|
|
|
|
require.Nil(t, err)
|
|
|
|
|
|
|
|
l1, err := ds.NewLabel(&kolide.Label{
|
2016-11-03 01:17:23 +00:00
|
|
|
Name: "label foo",
|
|
|
|
Query: "query foo",
|
2016-11-02 14:59:53 +00:00
|
|
|
})
|
|
|
|
require.Nil(t, err)
|
|
|
|
require.NotZero(t, l1.ID)
|
|
|
|
l1ID := fmt.Sprintf("%d", l1.ID)
|
|
|
|
|
|
|
|
for _, h := range []*kolide.Host{h1, h2, h3} {
|
|
|
|
err = ds.RecordLabelQueryExecutions(h, map[string]bool{l1ID: true}, time.Now())
|
|
|
|
assert.Nil(t, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
results, err := svc.SearchTargets(ctx, "baz", nil, nil)
|
|
|
|
require.Nil(t, err)
|
|
|
|
|
|
|
|
require.Len(t, results.Hosts, 1)
|
|
|
|
assert.Equal(t, h3.HostName, results.Hosts[0].HostName)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSearchResultsLimit(t *testing.T) {
|
2016-11-25 18:08:22 +00:00
|
|
|
ds, err := inmem.New(config.TestConfig())
|
2016-11-02 14:59:53 +00:00
|
|
|
require.Nil(t, err)
|
|
|
|
|
2016-11-14 18:22:54 +00:00
|
|
|
svc, err := newTestService(ds, nil)
|
2016-11-02 14:59:53 +00:00
|
|
|
require.Nil(t, err)
|
|
|
|
|
|
|
|
ctx := context.Background()
|
|
|
|
|
|
|
|
for i := 0; i < 15; i++ {
|
|
|
|
_, err := ds.NewHost(&kolide.Host{
|
2016-12-01 17:00:00 +00:00
|
|
|
HostName: fmt.Sprintf("foo.%d.local", i),
|
|
|
|
NodeKey: fmt.Sprintf("%d", i+1),
|
|
|
|
UUID: fmt.Sprintf("%d", i+1),
|
2016-11-02 14:59:53 +00:00
|
|
|
})
|
|
|
|
require.Nil(t, err)
|
|
|
|
}
|
|
|
|
targets, err := svc.SearchTargets(ctx, "foo", nil, nil)
|
|
|
|
require.Nil(t, err)
|
|
|
|
assert.Len(t, targets.Hosts, 10)
|
|
|
|
}
|