fleet/server/datastore/datastore_targets_test.go
Zachary Wasserman bde7256a09
Update labels interfaces for fleetctl (#1686)
- Remove unnecessary labels code
- Remove unnecessary packs code
- Update tests as appropriate
2018-01-10 11:38:20 -08:00

180 lines
6.0 KiB
Go

package datastore
import (
"strconv"
"testing"
"time"
"github.com/WatchBeam/clock"
"github.com/kolide/fleet/server/kolide"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func testCountHostsInTargets(t *testing.T, ds kolide.Datastore) {
if ds.Name() == "inmem" {
t.Skip("inmem is being deprecated, test skipped")
}
mockClock := clock.NewMockClock()
hostCount := 0
initHost := func(seenTime time.Time, distributedInterval uint, configTLSRefresh uint) *kolide.Host {
hostCount += 1
h, err := ds.NewHost(&kolide.Host{
OsqueryHostID: strconv.Itoa(hostCount),
DetailUpdateTime: mockClock.Now(),
SeenTime: mockClock.Now(),
NodeKey: strconv.Itoa(hostCount),
DistributedInterval: distributedInterval,
ConfigTLSRefresh: configTLSRefresh,
})
require.Nil(t, err)
require.Nil(t, ds.MarkHostSeen(h, seenTime))
return h
}
// Checks in every
h1 := initHost(mockClock.Now().Add(-1*time.Second), 10, 60)
h2 := initHost(mockClock.Now().Add(-1*time.Hour), 30, 7200)
h3 := initHost(mockClock.Now().Add(-5*time.Second), 20, 20)
h4 := initHost(mockClock.Now().Add(-47*time.Second), 10, 10)
h5 := initHost(mockClock.Now(), 5, 5)
const thirtyDaysAndAMinuteAgo = -1 * (30*24*60 + 1)
h6 := initHost(mockClock.Now().Add(thirtyDaysAndAMinuteAgo*time.Minute), 3600, 3600)
l1 := kolide.LabelSpec{
ID: 1,
Name: "label foo",
Query: "query foo",
}
l2 := kolide.LabelSpec{
ID: 2,
Name: "label bar",
Query: "query bar",
}
err := ds.ApplyLabelSpecs([]*kolide.LabelSpec{&l1, &l2})
require.Nil(t, err)
for _, h := range []*kolide.Host{h1, h2, h3, h6} {
err = ds.RecordLabelQueryExecutions(h, map[uint]bool{l1.ID: true}, mockClock.Now())
assert.Nil(t, err)
}
for _, h := range []*kolide.Host{h3, h4, h5} {
err = ds.RecordLabelQueryExecutions(h, map[uint]bool{l2.ID: true}, mockClock.Now())
assert.Nil(t, err)
}
metrics, err := ds.CountHostsInTargets(nil, []uint{l1.ID, l2.ID}, mockClock.Now())
require.Nil(t, err)
assert.Equal(t, uint(6), metrics.TotalHosts)
assert.Equal(t, uint(2), metrics.OfflineHosts)
assert.Equal(t, uint(3), metrics.OnlineHosts)
assert.Equal(t, uint(1), metrics.MissingInActionHosts)
metrics, err = ds.CountHostsInTargets([]uint{h1.ID, h2.ID}, []uint{l1.ID, l2.ID}, mockClock.Now())
require.Nil(t, err)
assert.Equal(t, uint(6), metrics.TotalHosts)
assert.Equal(t, uint(2), metrics.OfflineHosts)
assert.Equal(t, uint(3), metrics.OnlineHosts)
assert.Equal(t, uint(1), metrics.MissingInActionHosts)
metrics, err = ds.CountHostsInTargets([]uint{h1.ID, h2.ID}, nil, mockClock.Now())
require.Nil(t, err)
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)
metrics, err = ds.CountHostsInTargets([]uint{h1.ID}, []uint{l2.ID}, mockClock.Now())
require.Nil(t, err)
assert.Equal(t, uint(4), metrics.TotalHosts)
assert.Equal(t, uint(3), metrics.OnlineHosts)
assert.Equal(t, uint(1), metrics.OfflineHosts)
assert.Equal(t, uint(0), metrics.MissingInActionHosts)
metrics, err = ds.CountHostsInTargets(nil, nil, mockClock.Now())
require.Nil(t, err)
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)
metrics, err = ds.CountHostsInTargets([]uint{}, []uint{}, mockClock.Now())
require.Nil(t, err)
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)
// Advance clock so all hosts are offline
mockClock.AddTime(2 * time.Minute)
metrics, err = ds.CountHostsInTargets(nil, []uint{l1.ID, l2.ID}, mockClock.Now())
require.Nil(t, err)
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)
}
func testHostStatus(t *testing.T, ds kolide.Datastore) {
if ds.Name() == "inmem" {
t.Skip("inmem is being deprecated, test skipped")
}
mockClock := clock.NewMockClock()
h, err := ds.EnrollHost("1", 24)
require.Nil(t, err)
// Make host no longer appear new
mockClock.AddTime(36 * time.Hour)
expectOnline := kolide.TargetMetrics{TotalHosts: 1, OnlineHosts: 1}
expectOffline := kolide.TargetMetrics{TotalHosts: 1, OfflineHosts: 1}
expectMIA := kolide.TargetMetrics{TotalHosts: 1, MissingInActionHosts: 1}
var testCases = []struct {
seenTime time.Time
distributedInterval uint
configTLSRefresh uint
metrics kolide.TargetMetrics
}{
{mockClock.Now().Add(-30 * time.Second), 10, 3600, expectOnline},
{mockClock.Now().Add(-45 * time.Second), 10, 3600, expectOffline},
{mockClock.Now().Add(-30 * time.Second), 3600, 10, expectOnline},
{mockClock.Now().Add(-45 * time.Second), 3600, 10, expectOffline},
{mockClock.Now().Add(-70 * time.Second), 60, 60, expectOnline},
{mockClock.Now().Add(-91 * time.Second), 60, 60, expectOffline},
{mockClock.Now().Add(-1 * time.Second), 10, 10, expectOnline},
{mockClock.Now().Add(-1 * time.Minute), 10, 10, expectOffline},
{mockClock.Now().Add(-31 * 24 * time.Hour), 10, 10, expectMIA},
// Ensure behavior is reasonable if we don't have the values
{mockClock.Now().Add(-1 * time.Second), 0, 0, expectOnline},
{mockClock.Now().Add(-1 * time.Minute), 0, 0, expectOffline},
{mockClock.Now().Add(-31 * 24 * time.Hour), 0, 0, expectMIA},
}
for _, tt := range testCases {
t.Run("", func(t *testing.T) {
// Save interval values
h.DistributedInterval = tt.distributedInterval
h.ConfigTLSRefresh = tt.configTLSRefresh
require.Nil(t, ds.SaveHost(h))
// Mark seen
require.Nil(t, ds.MarkHostSeen(h, tt.seenTime))
// Verify status
metrics, err := ds.CountHostsInTargets([]uint{h.ID}, []uint{}, mockClock.Now())
require.Nil(t, err)
assert.Equal(t, tt.metrics, metrics)
})
}
}