Skip to content
Merged
Show file tree
Hide file tree
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
24 changes: 24 additions & 0 deletions providers/os/detector/windows/build_version_windows_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright (c) Mondoo, Inc.
// SPDX-License-Identifier: BUSL-1.1

//go:build windows

package windows

import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestGetWindowsOSBuild_Integration(t *testing.T) {
conn := &mockLocalConnection{}
ver, err := GetWindowsOSBuild(conn)
require.NoError(t, err)
require.NotNil(t, ver)

assert.NotEmpty(t, ver.CurrentBuild, "CurrentBuild should not be empty")
assert.NotEmpty(t, ver.ProductName, "ProductName should not be empty")
assert.NotEmpty(t, ver.Architecture, "Architecture should not be empty")
}
31 changes: 31 additions & 0 deletions providers/os/detector/windows/testhelpers_windows_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (c) Mondoo, Inc.
// SPDX-License-Identifier: BUSL-1.1

//go:build windows

package windows

import (
"github.com/spf13/afero"
"go.mondoo.com/mql/v13/providers-sdk/v1/inventory"
"go.mondoo.com/mql/v13/providers/os/connection/shared"
)

// mockLocalConnection implements shared.Connection and returns Type_Local.
// It is used by multiple test files in this package.
type mockLocalConnection struct{}

func (m *mockLocalConnection) ID() uint32 { return 0 }
func (m *mockLocalConnection) ParentID() uint32 { return 0 }
func (m *mockLocalConnection) RunCommand(command string) (*shared.Command, error) { return nil, nil }
func (m *mockLocalConnection) FileInfo(path string) (shared.FileInfoDetails, error) {
return shared.FileInfoDetails{}, nil
}
func (m *mockLocalConnection) FileSystem() afero.Fs { return afero.NewOsFs() }
func (m *mockLocalConnection) Name() string { return "mock-local" }
func (m *mockLocalConnection) Type() shared.ConnectionType { return shared.Type_Local }
func (m *mockLocalConnection) Asset() *inventory.Asset { return &inventory.Asset{} }
func (m *mockLocalConnection) UpdateAsset(asset *inventory.Asset) {}
func (m *mockLocalConnection) Capabilities() shared.Capabilities {
return shared.Capability_None
}
56 changes: 56 additions & 0 deletions providers/os/detector/windows/wmi_windows_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Copyright (c) Mondoo, Inc.
// SPDX-License-Identifier: BUSL-1.1

//go:build windows

package windows

import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestToString(t *testing.T) {
t.Run("nil returns empty string", func(t *testing.T) {
assert.Equal(t, "", toString(nil))
})

t.Run("non-nil returns value", func(t *testing.T) {
s := "hello"
assert.Equal(t, "hello", toString(&s))
})

t.Run("empty string returns empty string", func(t *testing.T) {
s := ""
assert.Equal(t, "", toString(&s))
})
}

func TestIntToString(t *testing.T) {
t.Run("nil returns empty string", func(t *testing.T) {
assert.Equal(t, "", intToString(nil))
})

t.Run("non-nil returns string representation", func(t *testing.T) {
i := 42
assert.Equal(t, "42", intToString(&i))
})

t.Run("zero returns 0", func(t *testing.T) {
i := 0
assert.Equal(t, "0", intToString(&i))
})
}

func TestGetWmiInformation_Integration(t *testing.T) {
conn := &mockLocalConnection{}
info, err := GetWmiInformation(conn)
require.NoError(t, err)
require.NotNil(t, info)

assert.NotEmpty(t, info.Version, "Version should not be empty")
assert.NotEmpty(t, info.BuildNumber, "BuildNumber should not be empty")
assert.NotEmpty(t, info.Caption, "Caption should not be empty")
}
6 changes: 0 additions & 6 deletions providers/os/fsutil/find_files_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,6 @@ func TestFindFiles(t *testing.T) {
mkFile(t, fs, "root/b/file1")
mkFile(t, fs, "root/c/file4")
mkFile(t, fs, "root/c/d/file5")
require.NoError(t, fs.Chmod("root/c/file4", 0o002))

rootAFiles, err := FindFiles(afero.NewIOFS(fs), "root/a", nil, "f", nil, nil)
require.NoError(t, err)
Expand All @@ -186,11 +185,6 @@ func TestFindFiles(t *testing.T) {
require.NoError(t, err)
assert.ElementsMatch(t, file1Files, []string{"root/b/file1", "root/a/file1"})

perm := uint32(0o002)
permFiles, err := FindFiles(afero.NewIOFS(fs), "root", nil, "f", &perm, nil)
require.NoError(t, err)
assert.ElementsMatch(t, permFiles, []string{"root/c/file4"})

depth := 0
depthFiles, err := FindFiles(afero.NewIOFS(fs), "root", nil, "f", nil, &depth)
require.NoError(t, err)
Expand Down
36 changes: 36 additions & 0 deletions providers/os/fsutil/find_files_unix_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (c) Mondoo, Inc.
// SPDX-License-Identifier: BUSL-1.1

//go:build !windows

package fsutil

import (
"testing"

"github.com/spf13/afero"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestFindFilesPermissionFilter(t *testing.T) {
fs := afero.NewMemMapFs()
mkDir(t, fs, "root/a")
mkDir(t, fs, "root/b")
mkDir(t, fs, "root/c")
mkDir(t, fs, "root/c/d")

mkFile(t, fs, "root/file0")
mkFile(t, fs, "root/a/file1")
mkFile(t, fs, "root/a/file2")
mkFile(t, fs, "root/b/file1")
mkFile(t, fs, "root/c/file4")
mkFile(t, fs, "root/c/d/file5")

require.NoError(t, fs.Chmod("root/c/file4", 0o002))

perm := uint32(0o002)
permFiles, err := FindFiles(afero.NewIOFS(fs), "root", nil, "f", &perm, nil)
require.NoError(t, err)
assert.ElementsMatch(t, permFiles, []string{"root/c/file4"})
}
68 changes: 68 additions & 0 deletions providers/os/fsutil/find_files_windows_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright (c) Mondoo, Inc.
// SPDX-License-Identifier: BUSL-1.1

//go:build windows

package fsutil

import (
"errors"
"os"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestHandleFsError(t *testing.T) {
tests := []struct {
name string
err error
wantSkip bool
wantErr error
}{
{
name: "nil error",
err: nil,
wantSkip: false,
wantErr: nil,
},
{
name: "permission denied is skipped",
err: os.ErrPermission,
wantSkip: true,
wantErr: nil,
},
{
name: "not exist is skipped",
err: os.ErrNotExist,
wantSkip: true,
wantErr: nil,
},
{
name: "invalid is skipped",
err: os.ErrInvalid,
wantSkip: true,
wantErr: nil,
},
{
name: "other error is propagated",
err: errors.New("some other error"),
wantSkip: true,
wantErr: errors.New("some other error"),
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
skip, err := handleFsError(tt.err)
assert.Equal(t, tt.wantSkip, skip)
if tt.wantErr != nil {
require.Error(t, err)
assert.Equal(t, tt.wantErr.Error(), err.Error())
} else {
require.NoError(t, err)
}
})
}
}
4 changes: 3 additions & 1 deletion providers/os/fsutil/hash_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package fsutil_test

import (
"path/filepath"
"testing"

"github.com/spf13/afero"
Expand All @@ -14,7 +15,7 @@ import (
)

func TestFileResource(t *testing.T) {
path := "/tmp/test_hash"
path := filepath.Join(t.TempDir(), "test_hash")

conn := local.NewConnection(0, &inventory.Config{
Path: path,
Expand All @@ -30,6 +31,7 @@ func TestFileResource(t *testing.T) {
f, err := fs.Open(path)
assert.Nil(t, err)
if assert.NotNil(t, f) {
defer f.Close()
assert.Equal(t, path, f.Name(), "they should be equal")

md5, err := fsutil.Md5(f)
Expand Down
113 changes: 113 additions & 0 deletions providers/os/registry/registrykey_windows_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
// Copyright (c) Mondoo, Inc.
// SPDX-License-Identifier: BUSL-1.1

//go:build windows

package registry

import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/sys/windows/registry"
)

func TestParseRegistryKeyPath(t *testing.T) {
tests := []struct {
name string
path string
wantKey registry.Key
wantPath string
wantErr bool
errContains string
}{
{
name: "HKEY_LOCAL_MACHINE full prefix",
path: `HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft`,
wantKey: registry.LOCAL_MACHINE,
wantPath: `SOFTWARE\Microsoft`,
},
{
name: "HKLM short prefix",
path: `HKLM\SOFTWARE\Microsoft`,
wantKey: registry.LOCAL_MACHINE,
wantPath: `SOFTWARE\Microsoft`,
},
{
name: "HKEY_CURRENT_USER full prefix",
path: `HKEY_CURRENT_USER\Software\Classes`,
wantKey: registry.CURRENT_USER,
wantPath: `Software\Classes`,
},
{
name: "HKCU short prefix",
path: `HKCU\Software\Classes`,
wantKey: registry.CURRENT_USER,
wantPath: `Software\Classes`,
},
{
name: "HKEY_USERS prefix",
path: `HKEY_USERS\.DEFAULT`,
wantKey: registry.USERS,
wantPath: `.DEFAULT`,
},
{
name: "invalid hive returns error",
path: `HKEY_INVALID\Some\Path`,
wantErr: true,
errContains: "invalid registry key hive",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
key, path, err := parseRegistryKeyPath(tt.path)
if tt.wantErr {
require.Error(t, err)
assert.Contains(t, err.Error(), tt.errContains)
return
}
require.NoError(t, err)
assert.Equal(t, tt.wantKey, key)
assert.Equal(t, tt.wantPath, path)
})
}
}

func TestGetNativeRegistryKeyItems_Integration(t *testing.T) {
// This key exists on every Windows installation
items, err := GetNativeRegistryKeyItems(`HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion`)
require.NoError(t, err)
require.NotEmpty(t, items, "CurrentVersion should have registry values")

// Check that well-known values exist
found := make(map[string]bool)
for _, item := range items {
found[item.Key] = true
}
assert.True(t, found["CurrentBuild"], "expected CurrentBuild value")
assert.True(t, found["ProductName"], "expected ProductName value")
}

func TestGetNativeRegistryKeyChildren_Integration(t *testing.T) {
// This key exists on every Windows installation and has children
children, err := GetNativeRegistryKeyChildren(`HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft`)
require.NoError(t, err)
require.NotEmpty(t, children, "HKLM\\SOFTWARE\\Microsoft should have subkeys")

// Check that at least "Windows NT" subkey exists
found := false
for _, child := range children {
if child.Name == "Windows NT" {
found = true
break
}
}
assert.True(t, found, "expected 'Windows NT' subkey under HKLM\\SOFTWARE\\Microsoft")
}

func TestGetNativeRegistryKeyItems_NotFound(t *testing.T) {
_, err := GetNativeRegistryKeyItems(`HKEY_LOCAL_MACHINE\SOFTWARE\NonExistentKey12345`)
require.Error(t, err)
}
Loading
Loading