diff --git a/pkg/agent/flags/flag_controller.go b/pkg/agent/flags/flag_controller.go index 93ef61334..c18915f01 100644 --- a/pkg/agent/flags/flag_controller.go +++ b/pkg/agent/flags/flag_controller.go @@ -511,3 +511,9 @@ func (fc *FlagController) OsqueryHealthcheckStartupDelay() time.Duration { WithMax(1*time.Hour), ).get(fc.getControlServerValue(keys.OsqueryHealthcheckStartupDelay)) } + +func (fc *FlagController) LocalDevelopmentPath() string { + return NewStringFlagValue( + WithDefaultString(fc.cmdLineOpts.LocalDevelopmentPath), + ).get(nil) +} diff --git a/pkg/agent/flags/keys/keys.go b/pkg/agent/flags/keys/keys.go index fef2d5846..cc7df4e20 100644 --- a/pkg/agent/flags/keys/keys.go +++ b/pkg/agent/flags/keys/keys.go @@ -49,6 +49,7 @@ const ( TraceIngestServerURL FlagKey = "trace_ingest_url" DisableTraceIngestTLS FlagKey = "disable_trace_ingest_tls" InModernStandby FlagKey = "in_modern_standby" + LocalDevelopmentPath FlagKey = "localdev_path" ) func (key FlagKey) String() string { diff --git a/pkg/agent/knapsack/knapsack.go b/pkg/agent/knapsack/knapsack.go index 7258f29a0..25d6e7d30 100644 --- a/pkg/agent/knapsack/knapsack.go +++ b/pkg/agent/knapsack/knapsack.go @@ -413,3 +413,7 @@ func (k *knapsack) SetOsqueryHealthcheckStartupDelay(delay time.Duration) error func (k *knapsack) OsqueryHealthcheckStartupDelay() time.Duration { return k.flags.OsqueryHealthcheckStartupDelay() } + +func (k *knapsack) LocalDevelopmentPath() string { + return k.flags.LocalDevelopmentPath() +} diff --git a/pkg/agent/types/flags.go b/pkg/agent/types/flags.go index 31a6f591e..2873faca4 100644 --- a/pkg/agent/types/flags.go +++ b/pkg/agent/types/flags.go @@ -196,4 +196,7 @@ type Flags interface { // OsqueryHealthcheckStartupDelay is the time to wait before beginning osquery healthchecks SetOsqueryHealthcheckStartupDelay(delay time.Duration) error OsqueryHealthcheckStartupDelay() time.Duration + + // LocalDevelopmentPath points to a local build of launcher to use instead of the one selected from the autoupdate library + LocalDevelopmentPath() string } diff --git a/pkg/agent/types/mocks/flags.go b/pkg/agent/types/mocks/flags.go index 9b10f77c7..87176985d 100644 --- a/pkg/agent/types/mocks/flags.go +++ b/pkg/agent/types/mocks/flags.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.34.2. DO NOT EDIT. +// Code generated by mockery v2.21.1. DO NOT EDIT. package mocks @@ -398,6 +398,20 @@ func (_m *Flags) KolideServerURL() string { return r0 } +// LocalDevelopmentPath provides a mock function with given fields: +func (_m *Flags) LocalDevelopmentPath() string { + ret := _m.Called() + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + // LogIngestServerURL provides a mock function with given fields: func (_m *Flags) LogIngestServerURL() string { ret := _m.Called() @@ -1173,12 +1187,13 @@ func (_m *Flags) UpdateDirectory() string { return r0 } -// NewFlags creates a new instance of Flags. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewFlags(t interface { +type mockConstructorTestingTNewFlags interface { mock.TestingT Cleanup(func()) -}) *Flags { +} + +// NewFlags creates a new instance of Flags. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewFlags(t mockConstructorTestingTNewFlags) *Flags { mock := &Flags{} mock.Mock.Test(t) diff --git a/pkg/agent/types/mocks/knapsack.go b/pkg/agent/types/mocks/knapsack.go index 2d8ffbe39..ecb1a4586 100644 --- a/pkg/agent/types/mocks/knapsack.go +++ b/pkg/agent/types/mocks/knapsack.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.34.2. DO NOT EDIT. +// Code generated by mockery v2.21.1. DO NOT EDIT. package mocks @@ -513,6 +513,20 @@ func (_m *Knapsack) LatestOsquerydPath(ctx context.Context) string { return r0 } +// LocalDevelopmentPath provides a mock function with given fields: +func (_m *Knapsack) LocalDevelopmentPath() string { + ret := _m.Called() + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + // LogIngestServerURL provides a mock function with given fields: func (_m *Knapsack) LogIngestServerURL() string { ret := _m.Called() @@ -1384,12 +1398,13 @@ func (_m *Knapsack) UpdateDirectory() string { return r0 } -// NewKnapsack creates a new instance of Knapsack. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewKnapsack(t interface { +type mockConstructorTestingTNewKnapsack interface { mock.TestingT Cleanup(func()) -}) *Knapsack { +} + +// NewKnapsack creates a new instance of Knapsack. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewKnapsack(t mockConstructorTestingTNewKnapsack) *Knapsack { mock := &Knapsack{} mock.Mock.Test(t) diff --git a/pkg/autoupdate/tuf/autoupdate.go b/pkg/autoupdate/tuf/autoupdate.go index 3ff123ad5..dc373a461 100644 --- a/pkg/autoupdate/tuf/autoupdate.go +++ b/pkg/autoupdate/tuf/autoupdate.go @@ -62,9 +62,7 @@ type TufAutoupdater struct { libraryManager librarian osquerier querier // used to query for current running osquery version osquerierRetryInterval time.Duration - channel string - initialDelay time.Duration - checkInterval time.Duration + knapsack types.Knapsack store types.KVStore // stores autoupdater errors for kolide_tuf_autoupdater_errors table interrupt chan struct{} interrupted bool @@ -93,11 +91,9 @@ func WithOsqueryRestart(restart func() error) TufAutoupdaterOption { func NewTufAutoupdater(k types.Knapsack, metadataHttpClient *http.Client, mirrorHttpClient *http.Client, osquerier querier, opts ...TufAutoupdaterOption) (*TufAutoupdater, error) { ta := &TufAutoupdater{ - channel: k.UpdateChannel(), + knapsack: k, interrupt: make(chan struct{}, 1), signalRestart: make(chan error, 1), - checkInterval: k.AutoupdateInterval(), - initialDelay: k.AutoupdateInitialDelay(), store: k.AutoupdateErrorsStore(), osquerier: osquerier, osquerierRetryInterval: 30 * time.Second, @@ -183,7 +179,7 @@ func (ta *TufAutoupdater) Execute() (err error) { case <-ta.interrupt: level.Debug(ta.logger).Log("msg", "received external interrupt during initial delay, stopping") return nil - case <-time.After(ta.initialDelay): + case <-time.After(ta.knapsack.AutoupdateInitialDelay()): break } @@ -191,7 +187,7 @@ func (ta *TufAutoupdater) Execute() (err error) { // earlier, after version selection. ta.tidyLibrary() - checkTicker := time.NewTicker(ta.checkInterval) + checkTicker := time.NewTicker(ta.knapsack.AutoupdateInterval()) defer checkTicker.Stop() cleanupTicker := time.NewTicker(12 * time.Hour) defer cleanupTicker.Stop() @@ -324,7 +320,7 @@ func (ta *TufAutoupdater) checkForUpdate() error { // Only perform restarts if we're configured to use this new autoupdate library, // to prevent performing unnecessary restarts. - if !ChannelUsesNewAutoupdater(ta.channel) { + if !ChannelUsesNewAutoupdater(ta.knapsack.UpdateChannel()) { return nil } @@ -362,24 +358,36 @@ func (ta *TufAutoupdater) checkForUpdate() error { // downloadUpdate will download a new release for the given binary, if available from TUF // and not already downloaded. func (ta *TufAutoupdater) downloadUpdate(binary autoupdatableBinary, targets data.TargetFiles) (string, error) { - release, releaseMetadata, err := findRelease(binary, targets, ta.channel) + release, releaseMetadata, err := findRelease(binary, targets, ta.knapsack.UpdateChannel()) if err != nil { return "", fmt.Errorf("could not find release: %w", err) } - if ta.libraryManager.Available(binary, release) { - return "", nil - } - - // Get the current running version if available -- don't error out if we can't - // get it, since the worst case is that we download an update whose version matches - // our install version. + // Ensure we don't download duplicate versions var currentVersion string currentVersion, _ = ta.currentRunningVersion(binary) if currentVersion == versionFromTarget(binary, release) { return "", nil } + if ta.libraryManager.Available(binary, release) { + // The release is already available in the library but we don't know if we're running it -- + // err on the side of not restarting. + if currentVersion == "" { + return "", nil + } + + // We're choosing to run a local build, so we don't need to restart to run a new download. + if binary == binaryLauncher && ta.knapsack.LocalDevelopmentPath() != "" { + return "", nil + } + + // The release is already available in the library and it's not our current running version -- + // return the version to signal for a restart. + return release, nil + } + + // We haven't yet downloaded this release -- download it if err := ta.libraryManager.AddToLibrary(binary, currentVersion, release, releaseMetadata); err != nil { return "", fmt.Errorf("could not add release %s for binary %s to library: %w", release, binary, err) } diff --git a/pkg/autoupdate/tuf/autoupdate_test.go b/pkg/autoupdate/tuf/autoupdate_test.go index 9933f73f1..93173f40d 100644 --- a/pkg/autoupdate/tuf/autoupdate_test.go +++ b/pkg/autoupdate/tuf/autoupdate_test.go @@ -32,9 +32,6 @@ func TestNewTufAutoupdater(t *testing.T) { s := setupStorage(t) mockKnapsack := typesmocks.NewKnapsack(t) mockKnapsack.On("RootDirectory").Return(testRootDir) - mockKnapsack.On("UpdateChannel").Return("nightly") - mockKnapsack.On("AutoupdateInterval").Return(60 * time.Second) - mockKnapsack.On("AutoupdateInitialDelay").Return(0 * time.Second) mockKnapsack.On("AutoupdateErrorsStore").Return(s) mockKnapsack.On("TufServerURL").Return("https://example.com") mockKnapsack.On("UpdateDirectory").Return("") @@ -70,7 +67,7 @@ func TestExecute_launcherUpdate(t *testing.T) { mockKnapsack := typesmocks.NewKnapsack(t) mockKnapsack.On("RootDirectory").Return(testRootDir) mockKnapsack.On("UpdateChannel").Return("nightly") - mockKnapsack.On("AutoupdateInterval").Return(60 * time.Second) + mockKnapsack.On("AutoupdateInterval").Return(100 * time.Millisecond) // Set the check interval to something short so we can make a couple requests to our test metadata server mockKnapsack.On("AutoupdateInitialDelay").Return(0 * time.Second) mockKnapsack.On("AutoupdateErrorsStore").Return(s) mockKnapsack.On("TufServerURL").Return(tufServerUrl) @@ -82,15 +79,9 @@ func TestExecute_launcherUpdate(t *testing.T) { autoupdater, err := NewTufAutoupdater(mockKnapsack, http.DefaultClient, http.DefaultClient, mockQuerier) require.NoError(t, err, "could not initialize new TUF autoupdater") - // Confirm we pulled all config items as expected - mockKnapsack.AssertExpectations(t) - // Update the metadata client with our test root JSON require.NoError(t, autoupdater.metadataClient.Init(rootJson), "could not initialize metadata client with test root JSON") - // Set the check interval to something short so we can make a couple requests to our test metadata server - autoupdater.checkInterval = 100 * time.Millisecond - // Set logger so that we can capture output var logBytes threadsafebuffer.ThreadSafeBuffer autoupdater.logger = log.NewJSONLogger(&logBytes) @@ -120,7 +111,7 @@ func TestExecute_launcherUpdate(t *testing.T) { // Let the autoupdater run for a bit -- it will shut itself down after a launcher update go autoupdater.Execute() - // Wait up to 5 seconds to confirm we see log files `received interrupt to restart launcher after update, stopping`, indicating that + // Wait up to 5 seconds to confirm we see log lines `received interrupt to restart launcher after update, stopping`, indicating that // the autoupdater shut down at the end shutdownDeadline := time.Now().Add(5 * time.Second).Unix() for { @@ -149,6 +140,8 @@ func TestExecute_launcherUpdate(t *testing.T) { // Assert expectation that we added the expected `testReleaseVersion` to the updates library mockLibraryManager.AssertExpectations(t) + // Confirm we pulled all config items as expected + mockKnapsack.AssertExpectations(t) } func TestExecute_launcherUpdate_noRestartIfUsingLegacyAutoupdater(t *testing.T) { @@ -161,7 +154,7 @@ func TestExecute_launcherUpdate_noRestartIfUsingLegacyAutoupdater(t *testing.T) mockKnapsack := typesmocks.NewKnapsack(t) mockKnapsack.On("RootDirectory").Return(testRootDir) mockKnapsack.On("UpdateChannel").Return("stable") - mockKnapsack.On("AutoupdateInterval").Return(60 * time.Second) + mockKnapsack.On("AutoupdateInterval").Return(100 * time.Millisecond) // Set the check interval to something short so we can make a couple requests to our test metadata server mockKnapsack.On("AutoupdateInitialDelay").Return(0 * time.Second) mockKnapsack.On("AutoupdateErrorsStore").Return(s) mockKnapsack.On("TufServerURL").Return(tufServerUrl) @@ -173,15 +166,9 @@ func TestExecute_launcherUpdate_noRestartIfUsingLegacyAutoupdater(t *testing.T) autoupdater, err := NewTufAutoupdater(mockKnapsack, http.DefaultClient, http.DefaultClient, mockQuerier) require.NoError(t, err, "could not initialize new TUF autoupdater") - // Confirm we pulled all config items as expected - mockKnapsack.AssertExpectations(t) - // Update the metadata client with our test root JSON require.NoError(t, autoupdater.metadataClient.Init(rootJson), "could not initialize metadata client with test root JSON") - // Set the check interval to something short so we can make a couple requests to our test metadata server - autoupdater.checkInterval = 100 * time.Millisecond - // Set logger so that we can capture output var logBytes threadsafebuffer.ThreadSafeBuffer autoupdater.logger = log.NewJSONLogger(&logBytes) @@ -224,6 +211,9 @@ func TestExecute_launcherUpdate_noRestartIfUsingLegacyAutoupdater(t *testing.T) // The autoupdater won't stop on its own, so stop it autoupdater.Interrupt(errors.New("test error")) time.Sleep(100 * time.Millisecond) + + // Confirm we pulled all config items as expected + mockKnapsack.AssertExpectations(t) } func TestExecute_osquerydUpdate(t *testing.T) { @@ -236,7 +226,7 @@ func TestExecute_osquerydUpdate(t *testing.T) { mockKnapsack := typesmocks.NewKnapsack(t) mockKnapsack.On("RootDirectory").Return(testRootDir) mockKnapsack.On("UpdateChannel").Return("nightly") - mockKnapsack.On("AutoupdateInterval").Return(60 * time.Second) + mockKnapsack.On("AutoupdateInterval").Return(100 * time.Millisecond) // Set the check interval to something short so we can make a couple requests to our test metadata server mockKnapsack.On("AutoupdateInitialDelay").Return(0 * time.Second) mockKnapsack.On("AutoupdateErrorsStore").Return(s) mockKnapsack.On("TufServerURL").Return(tufServerUrl) @@ -248,15 +238,9 @@ func TestExecute_osquerydUpdate(t *testing.T) { autoupdater, err := NewTufAutoupdater(mockKnapsack, http.DefaultClient, http.DefaultClient, mockQuerier, WithOsqueryRestart(func() error { return nil })) require.NoError(t, err, "could not initialize new TUF autoupdater") - // Confirm we pulled all config items as expected - mockKnapsack.AssertExpectations(t) - // Update the metadata client with our test root JSON require.NoError(t, autoupdater.metadataClient.Init(rootJson), "could not initialize metadata client with test root JSON") - // Set the check interval to something short so we can make a couple requests to our test metadata server - autoupdater.checkInterval = 100 * time.Millisecond - // Set logger so that we can capture output var logBytes threadsafebuffer.ThreadSafeBuffer autoupdater.logger = log.NewJSONLogger(&logBytes) @@ -299,6 +283,94 @@ func TestExecute_osquerydUpdate(t *testing.T) { // The autoupdater won't stop after an osqueryd download, so interrupt it and let it shut down autoupdater.Interrupt(errors.New("test error")) time.Sleep(100 * time.Millisecond) + + // Confirm we pulled all config items as expected + mockKnapsack.AssertExpectations(t) +} + +func TestExecute_downgrade(t *testing.T) { + t.Parallel() + + testRootDir := t.TempDir() + testReleaseVersion := "3.22.9" + tufServerUrl, rootJson := tufci.InitRemoteTufServer(t, testReleaseVersion) + s := setupStorage(t) + + mockKnapsack := typesmocks.NewKnapsack(t) + mockKnapsack.On("RootDirectory").Return(testRootDir) + mockKnapsack.On("UpdateChannel").Return("nightly") + mockKnapsack.On("AutoupdateInterval").Return(100 * time.Millisecond) // Set the check interval to something short so we can make a couple requests to our test metadata server + mockKnapsack.On("AutoupdateInitialDelay").Return(0 * time.Second) + mockKnapsack.On("AutoupdateErrorsStore").Return(s) + mockKnapsack.On("TufServerURL").Return(tufServerUrl) + mockKnapsack.On("UpdateDirectory").Return("") + mockKnapsack.On("MirrorServerURL").Return("https://example.com") + mockQuerier := newMockQuerier(t) + + // Set up autoupdater + autoupdater, err := NewTufAutoupdater(mockKnapsack, http.DefaultClient, http.DefaultClient, mockQuerier, WithOsqueryRestart(func() error { return nil })) + require.NoError(t, err, "could not initialize new TUF autoupdater") + + // Update the metadata client with our test root JSON + require.NoError(t, autoupdater.metadataClient.Init(rootJson), "could not initialize metadata client with test root JSON") + + // Set logger so that we can capture output + var logBytes threadsafebuffer.ThreadSafeBuffer + autoupdater.logger = log.NewJSONLogger(&logBytes) + + // Get metadata for each release + _, err = autoupdater.metadataClient.Update() + require.NoError(t, err, "could not update metadata client to fetch target metadata") + + // Expect that we attempt to tidy the library first before running execute loop + mockLibraryManager := NewMocklibrarian(t) + autoupdater.libraryManager = mockLibraryManager + currentOsqueryVersion := "4.0.0" + mockQuerier.On("Query", mock.Anything).Return([]map[string]string{{"version": currentOsqueryVersion}}, nil) + mockLibraryManager.On("TidyLibrary", binaryOsqueryd, mock.Anything).Return().Once() + + // Expect that we do not attempt to update the library (i.e. the osquery update was previously downloaded) + mockLibraryManager.On("Available", binaryOsqueryd, fmt.Sprintf("osqueryd-%s.tar.gz", testReleaseVersion)).Return(true) + mockLibraryManager.On("Available", binaryLauncher, fmt.Sprintf("launcher-%s.tar.gz", testReleaseVersion)).Return(true) + + // Let the autoupdater run for a bit + go autoupdater.Execute() + + // Wait up to 5 seconds to confirm we see log lines `restarted binary after update`, indicating that + // the autoupdater restarted osqueryd even though it did not perform a download + shutdownDeadline := time.Now().Add(5 * time.Second).Unix() + for { + if time.Now().Unix() > shutdownDeadline { + t.Error("autoupdater did not restart osquery within 5 seconds") + t.FailNow() + } + + // Wait for Execute to do its thing + time.Sleep(100 * time.Millisecond) + + logLines := strings.Split(strings.TrimSpace(logBytes.String()), "\n") + osquerydRestarted := false + for _, line := range logLines { + if strings.Contains(line, "restarted binary after update") { + osquerydRestarted = true + break + } + } + + if osquerydRestarted { + break + } + } + + // Assert expectation that we checked to see if version was available in library + mockLibraryManager.AssertExpectations(t) + + // The autoupdater won't stop after an osqueryd download, so interrupt it and let it shut down + autoupdater.Interrupt(errors.New("test error")) + time.Sleep(100 * time.Millisecond) + + // Confirm we pulled all config items as expected + mockKnapsack.AssertExpectations(t) } func TestExecute_withInitialDelay(t *testing.T) { @@ -312,8 +384,6 @@ func TestExecute_withInitialDelay(t *testing.T) { s := setupStorage(t) mockKnapsack := typesmocks.NewKnapsack(t) mockKnapsack.On("RootDirectory").Return(testRootDir) - mockKnapsack.On("UpdateChannel").Return("nightly") - mockKnapsack.On("AutoupdateInterval").Return(60 * time.Second) mockKnapsack.On("AutoupdateInitialDelay").Return(initialDelay) mockKnapsack.On("AutoupdateErrorsStore").Return(s) mockKnapsack.On("TufServerURL").Return(tufServerUrl) @@ -326,9 +396,6 @@ func TestExecute_withInitialDelay(t *testing.T) { mockQuerier, WithOsqueryRestart(func() error { return nil })) require.NoError(t, err, "could not initialize new TUF autoupdater") - // Confirm we pulled all config items as expected - mockKnapsack.AssertExpectations(t) - // Set logger so that we can capture output var logBytes threadsafebuffer.ThreadSafeBuffer autoupdater.logger = log.NewJSONLogger(&logBytes) @@ -357,6 +424,9 @@ func TestExecute_withInitialDelay(t *testing.T) { // Check that we shut down require.Contains(t, logLines[len(logLines)-1], "received external interrupt during initial delay, stopping") + + // Confirm we pulled all config items as expected + mockKnapsack.AssertExpectations(t) } func TestInterrupt_Multiple(t *testing.T) { @@ -376,7 +446,6 @@ func TestInterrupt_Multiple(t *testing.T) { s := setupStorage(t) mockKnapsack := typesmocks.NewKnapsack(t) mockKnapsack.On("RootDirectory").Return(testRootDir) - mockKnapsack.On("UpdateChannel").Return("nightly") mockKnapsack.On("AutoupdateInterval").Return(60 * time.Second) mockKnapsack.On("AutoupdateInitialDelay").Return(0 * time.Second) mockKnapsack.On("AutoupdateErrorsStore").Return(s) @@ -390,9 +459,6 @@ func TestInterrupt_Multiple(t *testing.T) { mockQuerier, WithOsqueryRestart(func() error { return nil })) require.NoError(t, err, "could not initialize new TUF autoupdater") - // Confirm we pulled all config items as expected - mockKnapsack.AssertExpectations(t) - // Set logger so that we can capture output var logBytes threadsafebuffer.ThreadSafeBuffer autoupdater.logger = log.NewJSONLogger(&logBytes) @@ -435,6 +501,9 @@ func TestInterrupt_Multiple(t *testing.T) { } require.Equal(t, expectedInterrupts, receivedInterrupts) + + // Confirm we pulled all config items as expected + mockKnapsack.AssertExpectations(t) } func Test_currentRunningVersion_launcher_errorWhenVersionIsNotSet(t *testing.T) { @@ -501,8 +570,7 @@ func Test_storeError(t *testing.T) { defer testTufServer.Close() mockKnapsack := typesmocks.NewKnapsack(t) mockKnapsack.On("RootDirectory").Return(testRootDir) - mockKnapsack.On("UpdateChannel").Return("nightly") - mockKnapsack.On("AutoupdateInterval").Return(60 * time.Second) + mockKnapsack.On("AutoupdateInterval").Return(100 * time.Millisecond) // Set the check interval to something short so we can accumulate some errors mockKnapsack.On("AutoupdateInitialDelay").Return(0 * time.Second) mockKnapsack.On("AutoupdateErrorsStore").Return(setupStorage(t)) mockKnapsack.On("TufServerURL").Return(testTufServer.URL) @@ -513,9 +581,6 @@ func Test_storeError(t *testing.T) { autoupdater, err := NewTufAutoupdater(mockKnapsack, http.DefaultClient, http.DefaultClient, mockQuerier) require.NoError(t, err, "could not initialize new TUF autoupdater") - // Confirm we pulled all config items as expected - mockKnapsack.AssertExpectations(t) - mockLibraryManager := NewMocklibrarian(t) autoupdater.libraryManager = mockLibraryManager mockQuerier.On("Query", mock.Anything).Return([]map[string]string{{"version": "1.1.1"}}, nil).Once() @@ -524,9 +589,6 @@ func Test_storeError(t *testing.T) { // for launcher in tests. mockLibraryManager.On("TidyLibrary", binaryOsqueryd, mock.Anything).Return().Once() - // Set the check interval to something short so we can accumulate some errors - autoupdater.checkInterval = 100 * time.Millisecond - // Start the autoupdater going go autoupdater.Execute() @@ -552,6 +614,7 @@ func Test_storeError(t *testing.T) { mockLibraryManager.AssertExpectations(t) mockQuerier.AssertExpectations(t) + mockKnapsack.AssertExpectations(t) } func Test_cleanUpOldErrors(t *testing.T) {