mirror of
https://github.com/empayre/fleet.git
synced 2024-11-06 08:55:24 +00:00
6ff2c449cf
Addresses https://github.com/fleetdm/fleet/issues/10112 Improved test coverage, also fixed a bug related to vulnerability processing for mac office apps.
197 lines
6.1 KiB
Go
197 lines
6.1 KiB
Go
package macoffice
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
|
|
"github.com/fleetdm/fleet/v4/server/vulnerabilities/io"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func newMetadataFile(t *testing.T, name string) io.MetadataFileName {
|
|
mfn, err := io.NewMSRCMetadata(name)
|
|
require.NoError(t, err)
|
|
return mfn
|
|
}
|
|
|
|
type testData struct {
|
|
RemoteList map[io.MetadataFileName]string
|
|
RemoteListError error
|
|
RemoteDownloaded []string
|
|
RemoteDownloadError error
|
|
LocalList []io.MetadataFileName
|
|
LocalListError error
|
|
LocalDeleted []io.MetadataFileName
|
|
LocalDeleteError error
|
|
}
|
|
|
|
type ghMock struct{ TestData *testData }
|
|
|
|
func (gh ghMock) MSRCBulletins(ctx context.Context) (map[io.MetadataFileName]string, error) {
|
|
return gh.TestData.RemoteList, gh.TestData.RemoteListError
|
|
}
|
|
|
|
func (gh ghMock) MacOfficeReleaseNotes(ctx context.Context) (io.MetadataFileName, string, error) {
|
|
for k, v := range gh.TestData.RemoteList {
|
|
return k, v, gh.TestData.RemoteListError
|
|
}
|
|
return io.MetadataFileName{}, "", gh.TestData.RemoteListError
|
|
}
|
|
|
|
func (gh ghMock) Download(url string) (string, error) {
|
|
gh.TestData.RemoteDownloaded = append(gh.TestData.RemoteDownloaded, url)
|
|
return "", gh.TestData.RemoteDownloadError
|
|
}
|
|
|
|
type fsMock struct{ TestData *testData }
|
|
|
|
func (fs fsMock) MSRCBulletins() ([]io.MetadataFileName, error) {
|
|
return fs.TestData.LocalList, fs.TestData.LocalListError
|
|
}
|
|
|
|
func (fs fsMock) MacOfficeReleaseNotes() ([]io.MetadataFileName, error) {
|
|
return fs.TestData.LocalList, fs.TestData.LocalListError
|
|
}
|
|
|
|
func (fs fsMock) Delete(d io.MetadataFileName) error {
|
|
fs.TestData.LocalDeleted = append(fs.TestData.LocalDeleted, d)
|
|
return fs.TestData.LocalDeleteError
|
|
}
|
|
|
|
func TestSync(t *testing.T) {
|
|
ctx := context.Background()
|
|
|
|
t.Run("#sync", func(t *testing.T) {
|
|
remote := newMetadataFile(t, "macoffice-2023_10_10.json")
|
|
|
|
t.Run("on GH error", func(t *testing.T) {
|
|
testData := testData{
|
|
RemoteListError: errors.New("some error"),
|
|
}
|
|
err := sync(ctx, fsMock{TestData: &testData}, ghMock{TestData: &testData})
|
|
require.Error(t, err, "some error")
|
|
})
|
|
|
|
t.Run("when nothing published on GH", func(t *testing.T) {
|
|
testData := testData{}
|
|
err := sync(ctx, fsMock{TestData: &testData}, ghMock{TestData: &testData})
|
|
require.NoError(t, err)
|
|
})
|
|
|
|
t.Run("on FS error", func(t *testing.T) {
|
|
testData := testData{
|
|
RemoteList: map[io.MetadataFileName]string{{}: "http://someurl.com"},
|
|
LocalListError: errors.New("some error"),
|
|
}
|
|
err := sync(ctx, fsMock{TestData: &testData}, ghMock{TestData: &testData})
|
|
require.Error(t, err, "some error")
|
|
})
|
|
|
|
t.Run("on error when downloading GH asset", func(t *testing.T) {
|
|
testData := testData{
|
|
RemoteList: map[io.MetadataFileName]string{remote: "http://someurl.com"},
|
|
LocalList: []io.MetadataFileName{
|
|
newMetadataFile(t, "macoffice-2020_10_10.json"),
|
|
},
|
|
RemoteDownloadError: errors.New("some error"),
|
|
}
|
|
err := sync(ctx, fsMock{TestData: &testData}, ghMock{TestData: &testData})
|
|
require.Error(t, err, "some error")
|
|
})
|
|
|
|
t.Run("when there are no local files", func(t *testing.T) {
|
|
testData := testData{
|
|
RemoteList: map[io.MetadataFileName]string{{}: "http://someurl.com"},
|
|
}
|
|
|
|
err := sync(ctx, fsMock{TestData: &testData}, ghMock{TestData: &testData})
|
|
require.NoError(t, err)
|
|
require.Empty(t, testData.LocalDeleted)
|
|
require.Contains(t, testData.RemoteDownloaded, "http://someurl.com")
|
|
})
|
|
|
|
t.Run("when there are no remote rel notes", func(t *testing.T) {
|
|
testData := testData{
|
|
RemoteList: map[io.MetadataFileName]string{{}: "http://someurl.com"},
|
|
LocalList: []io.MetadataFileName{
|
|
newMetadataFile(t, "macoffice-2022_09_10.json"),
|
|
},
|
|
}
|
|
|
|
err := sync(ctx, fsMock{TestData: &testData}, ghMock{TestData: &testData})
|
|
require.NoError(t, err)
|
|
|
|
require.Empty(t, testData.LocalDeleted)
|
|
require.Empty(t, testData.RemoteDownloaded)
|
|
})
|
|
|
|
t.Run("removes multiple out of date copies", func(t *testing.T) {
|
|
local := []io.MetadataFileName{
|
|
newMetadataFile(t, "macoffice-2022_09_10.json"),
|
|
newMetadataFile(t, "macoffice-2022_08_10.json"),
|
|
}
|
|
|
|
testData := testData{
|
|
RemoteList: map[io.MetadataFileName]string{remote: "http://someurl.com"},
|
|
LocalList: local,
|
|
}
|
|
|
|
err := sync(ctx, fsMock{TestData: &testData}, ghMock{TestData: &testData})
|
|
require.NoError(t, err)
|
|
|
|
require.ElementsMatch(t, testData.LocalDeleted, local)
|
|
require.Contains(t, testData.RemoteDownloaded, "http://someurl.com")
|
|
})
|
|
|
|
t.Run("on error when deleting", func(t *testing.T) {
|
|
local := []io.MetadataFileName{
|
|
newMetadataFile(t, "macoffice-2022_09_10.json"),
|
|
newMetadataFile(t, "macoffice-2022_08_10.json"),
|
|
}
|
|
|
|
testData := testData{
|
|
RemoteList: map[io.MetadataFileName]string{remote: "http://someurl.com"},
|
|
LocalList: local,
|
|
LocalDeleteError: errors.New("some error"),
|
|
}
|
|
|
|
err := sync(ctx, fsMock{TestData: &testData}, ghMock{TestData: &testData})
|
|
require.Error(t, err, "some error")
|
|
})
|
|
|
|
t.Run("when local copy is out of date", func(t *testing.T) {
|
|
local := newMetadataFile(t, "macoffice-2022_09_10.json")
|
|
|
|
testData := testData{
|
|
RemoteList: map[io.MetadataFileName]string{remote: "http://someurl.com"},
|
|
LocalList: []io.MetadataFileName{local},
|
|
}
|
|
|
|
err := sync(ctx, fsMock{TestData: &testData}, ghMock{TestData: &testData})
|
|
require.NoError(t, err)
|
|
|
|
require.ElementsMatch(t, testData.RemoteDownloaded, []string{"http://someurl.com"})
|
|
require.ElementsMatch(t, testData.LocalDeleted, []io.MetadataFileName{local})
|
|
})
|
|
|
|
t.Run("when local copy is not out of date", func(t *testing.T) {
|
|
local := []io.MetadataFileName{
|
|
newMetadataFile(t, "macoffice-2023_11_10.json"),
|
|
newMetadataFile(t, "macoffice-2023_01_10.json"),
|
|
}
|
|
|
|
testData := testData{
|
|
RemoteList: map[io.MetadataFileName]string{remote: "http://someurl.com"},
|
|
LocalList: local,
|
|
}
|
|
|
|
err := sync(ctx, fsMock{TestData: &testData}, ghMock{TestData: &testData})
|
|
require.NoError(t, err)
|
|
|
|
require.Empty(t, testData.RemoteDownloaded)
|
|
require.ElementsMatch(t, testData.LocalDeleted, []io.MetadataFileName{local[1]})
|
|
})
|
|
})
|
|
}
|