Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 129 additions & 0 deletions tables/alt_system_info/alt_system_info_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package alt_system_info_test

import (
"errors"
"testing"

"github.com/macadmins/osquery-extension/pkg/utils"
Expand All @@ -10,6 +11,29 @@ import (
"github.com/stretchr/testify/require"
)

type errorOsqueryClienter struct {
err error
}

func (e errorOsqueryClienter) NewOsqueryClient() (utils.OsqueryClient, error) {
return nil, e.err
}

type errorOsqueryClient struct {
rowsErr error
rowErr error
}

func (e errorOsqueryClient) QueryRows(query string) ([]map[string]string, error) {
return nil, e.rowsErr
}

func (e errorOsqueryClient) QueryRow(query string) (map[string]string, error) {
return nil, e.rowErr
}

func (e errorOsqueryClient) Close() {}

var mockIOReg = `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
Expand Down Expand Up @@ -65,6 +89,13 @@ func TestGetCPUType(t *testing.T) {
assert.Equal(t, "arm64e", cpuType)
}

func TestGetCPUTypeCommandError(t *testing.T) {
_, err := alt_system_info.GetCPUType(utils.MockCmdRunner{Err: errors.New("machine failed")})
require.Error(t, err)
assert.ErrorContains(t, err, "could not run machine command")
assert.ErrorContains(t, err, "machine failed")
}

func TestGetIORegData(t *testing.T) {
data, err := alt_system_info.GetIORegData(mockCmdRunner)
require.NoError(t, err)
Expand All @@ -75,6 +106,27 @@ func TestGetIORegData(t *testing.T) {
assert.Equal(t, "MYSERIAL", data.HardwareSerial)
}

func TestGetIORegDataErrors(t *testing.T) {
t.Run("command error", func(t *testing.T) {
_, err := alt_system_info.GetIORegData(utils.MockCmdRunner{Err: errors.New("ioreg failed")})
require.Error(t, err)
assert.ErrorContains(t, err, "could not run ioreg command")
})

t.Run("invalid plist", func(t *testing.T) {
_, err := alt_system_info.GetIORegData(utils.MockCmdRunner{Output: "not plist"})
require.Error(t, err)
assert.ErrorContains(t, err, "could not unmarshal plist")
})

t.Run("no children", func(t *testing.T) {
plistWithoutChildren := `<?xml version="1.0" encoding="UTF-8"?><plist version="1.0"><dict></dict></plist>`
_, err := alt_system_info.GetIORegData(utils.MockCmdRunner{Output: plistWithoutChildren})
require.Error(t, err)
assert.ErrorContains(t, err, "no children found")
})
}

func TestGetSysctlData(t *testing.T) {
data, err := alt_system_info.GetSysctlData(mockCmdRunner)
require.NoError(t, err)
Expand All @@ -84,6 +136,25 @@ func TestGetSysctlData(t *testing.T) {
assert.Equal(t, "34359738368", data.PhysicalMemory)
}

func TestGetSysctlDataCommandError(t *testing.T) {
_, err := alt_system_info.GetSysctlData(utils.MockCmdRunner{Err: errors.New("sysctl failed")})
require.Error(t, err)
assert.ErrorContains(t, err, "could not run sysctl command")
}

func TestGetSysctlDataIgnoresMalformedLines(t *testing.T) {
data, err := alt_system_info.GetSysctlData(utils.MockCmdRunner{Output: `ignored line
machdep.cpu.brand_string: Apple M3
too:many:colons
hw.memsize: 17179869184
`})
require.NoError(t, err)
assert.Equal(t, "Apple M3", data.CPUBrand)
assert.Equal(t, "17179869184", data.PhysicalMemory)
assert.Empty(t, data.CPUPhysicalCores)
assert.Empty(t, data.CPULogicalCores)
}

func TestGetHostData(t *testing.T) {
data, err := alt_system_info.GetHostData(mockCmdRunner)
require.NoError(t, err)
Expand All @@ -92,6 +163,20 @@ func TestGetHostData(t *testing.T) {
assert.Equal(t, "mylocalhostname", data.LocalHostname)
}

func TestGetHostDataCommandError(t *testing.T) {
runner := &utils.MultiMockCmdRunner{
Commands: map[string]utils.MockCmdRunner{
"hostname": {Output: "myhostname.local\n"},
"scutil --get ComputerName": {Err: errors.New("scutil failed")},
"scutil --get LocalHostName": {Output: "mylocalhostname\n"},
},
}

_, err := alt_system_info.GetHostData(runner)
require.Error(t, err)
assert.ErrorContains(t, err, "could not run scutil --get ComputerName command")
}

var (
isMacOS15Query = "select * from os_version where name = 'macOS' and major = '15' and minor = 0;"
systemInfoQuery = "select * from system_info;"
Expand All @@ -114,6 +199,12 @@ func TestIsMacOS15(t *testing.T) {
assert.True(t, isMacOS15)
}

func TestIsMacOS15QueryError(t *testing.T) {
_, err := alt_system_info.IsMacOS150(errorOsqueryClient{rowsErr: errors.New("query failed")})
require.Error(t, err)
assert.ErrorContains(t, err, "query failed")
}

func TestFallback(t *testing.T) {
mockOsquery := &utils.MockOsqueryClient{
Data: map[string][]map[string]string{
Expand All @@ -126,6 +217,12 @@ func TestFallback(t *testing.T) {
assert.Equal(t, mockOsquery.Data[systemInfoQuery], value)
}

func TestFallbackQueryError(t *testing.T) {
_, err := alt_system_info.Fallback(errorOsqueryClient{rowErr: errors.New("system_info failed")})
require.Error(t, err)
assert.ErrorContains(t, err, "system_info failed")
}

func TestGenerateInfo(t *testing.T) {
mockOsquery := &utils.MockOsqueryClienter{
Data: map[string][]map[string]string{
Expand Down Expand Up @@ -169,3 +266,35 @@ func TestGenerateInfo(t *testing.T) {
assert.False(t, *cache.IsMacOS15)
}
}

func TestGenerateInfoClientCreationError(t *testing.T) {
_, err := alt_system_info.GenerateInfo(
mockCmdRunner,
errorOsqueryClienter{err: errors.New("socket unavailable")},
new(alt_system_info.Cache),
)
require.Error(t, err)
assert.ErrorContains(t, err, "could not create osquery client")
}

func TestGenerateInfoCommandError(t *testing.T) {
mockOsquery := &utils.MockOsqueryClienter{
Data: map[string][]map[string]string{
isMacOS15Query: {{"version": "15.0"}},
},
}
runner := &utils.MultiMockCmdRunner{
Commands: map[string]utils.MockCmdRunner{
"machine": {Err: errors.New("machine failed")},
"ioreg -d2 -c IOPlatformExpertDevice -a": {Output: mockIOReg},
"sysctl machdep.cpu.brand_string machdep.cpu.core_count machdep.cpu.thread_count hw.memsize": {Output: mockSysctl},
"hostname": {Output: "myhostname.local\n"},
"scutil --get ComputerName": {Output: "mycomputername\n"},
"scutil --get LocalHostName": {Output: "mylocalhostname\n"},
},
}

_, err := alt_system_info.GenerateInfo(runner, mockOsquery, new(alt_system_info.Cache))
require.Error(t, err)
assert.ErrorContains(t, err, "could not get cpu type")
}
Loading