mirror of
https://github.com/fleetdm/fleet
synced 2026-04-21 21:47:20 +00:00
222 lines
5.5 KiB
Go
222 lines
5.5 KiB
Go
package utils
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/fleetdm/fleet/v4/server/fleet"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestRecentVulns(t *testing.T) {
|
|
meta := []fleet.CVEMeta{
|
|
{CVE: "cve-recent-1"},
|
|
{CVE: "cve-recent-2"},
|
|
{CVE: "cve-recent-3"},
|
|
}
|
|
|
|
t.Run("no NVD nor OVAL vulns", func(t *testing.T) {
|
|
vulns, meta := RecentVulns[fleet.SoftwareVulnerability](nil, meta)
|
|
require.Empty(t, vulns)
|
|
require.Empty(t, meta)
|
|
})
|
|
|
|
t.Run("filters vulnerabilities based on max age", func(t *testing.T) {
|
|
ovalVulns := []fleet.SoftwareVulnerability{
|
|
{CVE: "cve-recent-1"},
|
|
{CVE: "cve-recent-2"},
|
|
{CVE: "cve-recent-2"},
|
|
{CVE: "cve-outdated-1"},
|
|
}
|
|
|
|
nvdVulns := []fleet.SoftwareVulnerability{
|
|
{CVE: "cve-recent-1"},
|
|
{CVE: "cve-recent-3"},
|
|
{CVE: "cve-outdated-2"},
|
|
{CVE: "cve-outdated-3"},
|
|
}
|
|
|
|
expected := []string{
|
|
"cve-recent-1",
|
|
"cve-recent-2",
|
|
"cve-recent-3",
|
|
}
|
|
|
|
var input []fleet.SoftwareVulnerability
|
|
input = append(input, ovalVulns...)
|
|
input = append(input, nvdVulns...)
|
|
|
|
var actual []string
|
|
vulns, meta := RecentVulns(input, meta)
|
|
for _, r := range vulns {
|
|
actual = append(actual, r.GetCVE())
|
|
}
|
|
|
|
expectedMeta := map[string]fleet.CVEMeta{
|
|
"cve-recent-1": {CVE: "cve-recent-1"},
|
|
"cve-recent-2": {CVE: "cve-recent-2"},
|
|
"cve-recent-3": {CVE: "cve-recent-3"},
|
|
}
|
|
|
|
require.Equal(t, len(expected), len(actual))
|
|
require.ElementsMatch(t, expected, actual)
|
|
require.Equal(t, expectedMeta, meta)
|
|
})
|
|
}
|
|
|
|
func TestVulnsDelta(t *testing.T) {
|
|
t.Run("no existing vulnerabilities", func(t *testing.T) {
|
|
var found []fleet.SoftwareVulnerability
|
|
var existing []fleet.SoftwareVulnerability
|
|
|
|
toInsert, toDelete := VulnsDelta(found, existing)
|
|
require.Empty(t, toInsert)
|
|
require.Empty(t, toDelete)
|
|
})
|
|
|
|
t.Run("existing match found", func(t *testing.T) {
|
|
found := []fleet.SoftwareVulnerability{
|
|
{SoftwareID: 1, CVE: "cve_1"},
|
|
{SoftwareID: 1, CVE: "cve_2"},
|
|
{SoftwareID: 2, CVE: "cve_3"},
|
|
{SoftwareID: 2, CVE: "cve_4"},
|
|
}
|
|
|
|
existing := []fleet.SoftwareVulnerability{
|
|
{SoftwareID: 1, CVE: "cve_1"},
|
|
{SoftwareID: 1, CVE: "cve_2"},
|
|
{SoftwareID: 2, CVE: "cve_3"},
|
|
{SoftwareID: 2, CVE: "cve_4"},
|
|
}
|
|
|
|
toInsert, toDelete := VulnsDelta(found, existing)
|
|
require.Empty(t, toInsert)
|
|
require.Empty(t, toDelete)
|
|
})
|
|
|
|
t.Run("existing differ from found", func(t *testing.T) {
|
|
found := []fleet.SoftwareVulnerability{
|
|
{SoftwareID: 1, CVE: "cve_1"},
|
|
{SoftwareID: 1, CVE: "cve_2"},
|
|
{SoftwareID: 3, CVE: "cve_5"},
|
|
{SoftwareID: 3, CVE: "cve_6"},
|
|
}
|
|
|
|
existing := []fleet.SoftwareVulnerability{
|
|
{SoftwareID: 1, CVE: "cve_1"},
|
|
{SoftwareID: 1, CVE: "cve_2"},
|
|
{SoftwareID: 2, CVE: "cve_3"},
|
|
{SoftwareID: 2, CVE: "cve_4"},
|
|
}
|
|
|
|
expectedToInsert := []fleet.SoftwareVulnerability{
|
|
{SoftwareID: 3, CVE: "cve_5"},
|
|
{SoftwareID: 3, CVE: "cve_6"},
|
|
}
|
|
|
|
expectedToDelete := []fleet.SoftwareVulnerability{
|
|
{SoftwareID: 2, CVE: "cve_3"},
|
|
{SoftwareID: 2, CVE: "cve_4"},
|
|
}
|
|
|
|
toInsert, toDelete := VulnsDelta(found, existing)
|
|
require.Equal(t, expectedToInsert, toInsert)
|
|
require.ElementsMatch(t, expectedToDelete, toDelete)
|
|
})
|
|
|
|
t.Run("nothing found but vulns exist", func(t *testing.T) {
|
|
var found []fleet.SoftwareVulnerability
|
|
|
|
existing := []fleet.SoftwareVulnerability{
|
|
{SoftwareID: 1, CVE: "cve_1"},
|
|
{SoftwareID: 1, CVE: "cve_2"},
|
|
{SoftwareID: 2, CVE: "cve_3"},
|
|
{SoftwareID: 2, CVE: "cve_4"},
|
|
}
|
|
|
|
toInsert, toDelete := VulnsDelta(found, existing)
|
|
require.Empty(t, toInsert)
|
|
require.ElementsMatch(t, existing, toDelete)
|
|
})
|
|
}
|
|
|
|
func TestProductsIntersect(t *testing.T) {
|
|
a := map[string]bool{
|
|
"1": true,
|
|
"2": true,
|
|
"3": true,
|
|
}
|
|
|
|
b := map[string]bool{
|
|
"1": true,
|
|
}
|
|
|
|
c := map[string]bool{
|
|
"10": true,
|
|
}
|
|
|
|
d := make(map[string]bool)
|
|
|
|
require.True(t, ProductIDsIntersect(a, b))
|
|
require.True(t, ProductIDsIntersect(b, a))
|
|
|
|
require.False(t, ProductIDsIntersect(b, c))
|
|
require.False(t, ProductIDsIntersect(c, b))
|
|
|
|
require.False(t, ProductIDsIntersect(b, d))
|
|
require.False(t, ProductIDsIntersect(d, b))
|
|
}
|
|
|
|
func TestLatestFile(t *testing.T) {
|
|
t.Run("file exists", func(t *testing.T) {
|
|
dir := t.TempDir()
|
|
|
|
today := time.Now()
|
|
fileName := fmt.Sprintf("file1-%d_%02d_%02d.%s", today.Year(), today.Month(), today.Day(), "json")
|
|
|
|
f1, err := os.Create(filepath.Join(dir, fileName))
|
|
require.NoError(t, err)
|
|
f1.Close()
|
|
|
|
result, err := LatestFile(fileName, dir)
|
|
require.NoError(t, err)
|
|
require.Equal(t, filepath.Join(dir, fileName), result)
|
|
})
|
|
|
|
t.Run("file exists but not for date", func(t *testing.T) {
|
|
dir := t.TempDir()
|
|
|
|
today := time.Now()
|
|
yesterday := today.Add(-24 * time.Hour)
|
|
|
|
todayFile := fmt.Sprintf("file1-%d_%02d_%02d.%s", today.Year(), today.Month(), today.Day(), "json")
|
|
yesterdayFile := fmt.Sprintf("file1-%d_%02d_%02d.%s", yesterday.Year(), yesterday.Month(), yesterday.Day(), "json")
|
|
|
|
f1, err := os.Create(filepath.Join(dir, yesterdayFile))
|
|
require.NoError(t, err)
|
|
f1.Close()
|
|
|
|
result, err := LatestFile(todayFile, dir)
|
|
require.NoError(t, err)
|
|
require.Equal(t, filepath.Join(dir, yesterdayFile), result)
|
|
})
|
|
|
|
t.Run("file does not exists", func(t *testing.T) {
|
|
dir := t.TempDir()
|
|
|
|
today := time.Now()
|
|
|
|
wantedFile := fmt.Sprintf("file1-%d_%02d_%02d.%s", today.Year(), today.Month(), today.Day(), "json")
|
|
existingFile := fmt.Sprintf("file2-%d_%02d_%02d.%s", today.Year(), today.Month(), today.Day(), "json")
|
|
|
|
f1, err := os.Create(filepath.Join(dir, existingFile))
|
|
require.NoError(t, err)
|
|
f1.Close()
|
|
|
|
_, err = LatestFile(wantedFile, dir)
|
|
require.Error(t, err, "file not found")
|
|
})
|
|
}
|