mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-04-28 19:41:17 +00:00
test: expand backend coverage
This commit is contained in:
parent
3ea5f54d93
commit
7f7edfceb4
118 changed files with 21980 additions and 74 deletions
456
pkg/discovery/envdetect/envdetect_additional_test.go
Normal file
456
pkg/discovery/envdetect/envdetect_additional_test.go
Normal file
|
|
@ -0,0 +1,456 @@
|
|||
package envdetect
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDetectContainer_SystemdDetectVirtDocker(t *testing.T) {
|
||||
probe := fakeEnvironmentProbe{
|
||||
lookPathPresent: map[string]bool{"systemd-detect-virt": true},
|
||||
commandOutput: map[string][]byte{
|
||||
"systemd-detect-virt\x00--container": []byte("docker\n"),
|
||||
},
|
||||
}
|
||||
|
||||
isContainer, containerType := detectContainer(probe)
|
||||
if !isContainer {
|
||||
t.Fatalf("expected container, got non-container")
|
||||
}
|
||||
if containerType != "docker" {
|
||||
t.Fatalf("containerType = %q, want docker", containerType)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDetectContainer_SystemdDetectVirtUnknown(t *testing.T) {
|
||||
probe := fakeEnvironmentProbe{
|
||||
lookPathPresent: map[string]bool{"systemd-detect-virt": true},
|
||||
commandOutput: map[string][]byte{
|
||||
"systemd-detect-virt\x00--container": []byte("rkt\n"),
|
||||
},
|
||||
}
|
||||
|
||||
isContainer, containerType := detectContainer(probe)
|
||||
if !isContainer {
|
||||
t.Fatalf("expected container, got non-container")
|
||||
}
|
||||
if containerType != "rkt" {
|
||||
t.Fatalf("containerType = %q, want rkt", containerType)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDetectContainer_MarkersAndCgroup(t *testing.T) {
|
||||
t.Run("marker-containerenv", func(t *testing.T) {
|
||||
probe := fakeEnvironmentProbe{
|
||||
statPresent: map[string]bool{"/run/.containerenv": true},
|
||||
}
|
||||
|
||||
isContainer, containerType := detectContainer(probe)
|
||||
if !isContainer || containerType != "docker" {
|
||||
t.Fatalf("marker detection = (%v, %q), want (true, docker)", isContainer, containerType)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("cgroup-docker", func(t *testing.T) {
|
||||
probe := fakeEnvironmentProbe{
|
||||
fileData: map[string][]byte{
|
||||
"/proc/1/cgroup": []byte("12:cpu:/docker/abc\n"),
|
||||
},
|
||||
}
|
||||
|
||||
isContainer, containerType := detectContainer(probe)
|
||||
if !isContainer || containerType != "docker" {
|
||||
t.Fatalf("cgroup detection = (%v, %q), want (true, docker)", isContainer, containerType)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("environ-lxc", func(t *testing.T) {
|
||||
probe := fakeEnvironmentProbe{
|
||||
fileErr: map[string]error{
|
||||
"/proc/1/cgroup": errors.New("nope"),
|
||||
},
|
||||
fileData: map[string][]byte{
|
||||
"/proc/1/environ": []byte("container=lxc\x00"),
|
||||
},
|
||||
}
|
||||
|
||||
isContainer, containerType := detectContainer(probe)
|
||||
if !isContainer || containerType != "lxc" {
|
||||
t.Fatalf("environ detection = (%v, %q), want (true, lxc)", isContainer, containerType)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestDetectContainer_NoMarkers(t *testing.T) {
|
||||
probe := fakeEnvironmentProbe{
|
||||
fileErr: map[string]error{
|
||||
"/proc/1/cgroup": os.ErrNotExist,
|
||||
"/proc/1/environ": os.ErrNotExist,
|
||||
},
|
||||
}
|
||||
|
||||
isContainer, containerType := detectContainer(probe)
|
||||
if isContainer {
|
||||
t.Fatalf("expected non-container, got container type %q", containerType)
|
||||
}
|
||||
if containerType != "" {
|
||||
t.Fatalf("containerType = %q, want empty", containerType)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDetectNativeEnvironment_FallbackOnError(t *testing.T) {
|
||||
profile := &EnvironmentProfile{
|
||||
Policy: DefaultScanPolicy(),
|
||||
Metadata: map[string]string{},
|
||||
}
|
||||
probe := fakeEnvironmentProbe{interfacesErr: errors.New("boom")}
|
||||
|
||||
result, err := detectNativeEnvironment(profile, probe)
|
||||
if err != nil {
|
||||
t.Fatalf("detectNativeEnvironment returned error: %v", err)
|
||||
}
|
||||
if len(result.Phases) == 0 || result.Phases[0].Name != "fallback_common_subnets" {
|
||||
t.Fatalf("expected fallback subnets, got %#v", result.Phases)
|
||||
}
|
||||
|
||||
found := false
|
||||
for _, warn := range result.Warnings {
|
||||
if strings.Contains(warn, "Failed to enumerate interfaces") {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Fatalf("expected warning about interface enumeration, got %#v", result.Warnings)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDetectNativeEnvironment_NoSubnetsFallback(t *testing.T) {
|
||||
profile := &EnvironmentProfile{
|
||||
Policy: DefaultScanPolicy(),
|
||||
Metadata: map[string]string{},
|
||||
}
|
||||
probe := fakeEnvironmentProbe{
|
||||
interfaces: []ifaceInfo{
|
||||
{
|
||||
Name: "lo",
|
||||
Flags: net.FlagUp | net.FlagLoopback,
|
||||
Addrs: []net.Addr{
|
||||
&net.IPNet{IP: net.IPv4(127, 0, 0, 1), Mask: net.CIDRMask(8, 32)},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "eth0",
|
||||
Flags: net.FlagUp,
|
||||
Addrs: []net.Addr{
|
||||
&net.IPNet{IP: net.IPv4(169, 254, 1, 2), Mask: net.CIDRMask(16, 32)},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
result, err := detectNativeEnvironment(profile, probe)
|
||||
if err != nil {
|
||||
t.Fatalf("detectNativeEnvironment returned error: %v", err)
|
||||
}
|
||||
if len(result.Phases) == 0 || result.Phases[0].Name != "fallback_common_subnets" {
|
||||
t.Fatalf("expected fallback subnets, got %#v", result.Phases)
|
||||
}
|
||||
|
||||
found := false
|
||||
for _, warn := range result.Warnings {
|
||||
if strings.Contains(warn, "No active IPv4 interfaces found") {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Fatalf("expected warning about missing interfaces, got %#v", result.Warnings)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAllLocalSubnets_DedupAndSkip(t *testing.T) {
|
||||
probe := fakeEnvironmentProbe{
|
||||
interfaces: []ifaceInfo{
|
||||
{
|
||||
Name: "lo",
|
||||
Flags: net.FlagUp | net.FlagLoopback,
|
||||
Addrs: []net.Addr{&net.IPNet{IP: net.IPv4(127, 0, 0, 1), Mask: net.CIDRMask(8, 32)}},
|
||||
},
|
||||
{
|
||||
Name: "down0",
|
||||
Flags: 0,
|
||||
Addrs: []net.Addr{&net.IPNet{IP: net.IPv4(10, 0, 0, 2), Mask: net.CIDRMask(24, 32)}},
|
||||
},
|
||||
{
|
||||
Name: "err0",
|
||||
Flags: net.FlagUp,
|
||||
AddrsErr: errors.New("boom"),
|
||||
},
|
||||
{
|
||||
Name: "v6",
|
||||
Flags: net.FlagUp,
|
||||
Addrs: []net.Addr{&net.IPNet{IP: net.ParseIP("fe80::1"), Mask: net.CIDRMask(64, 128)}},
|
||||
},
|
||||
{
|
||||
Name: "eth0",
|
||||
Flags: net.FlagUp,
|
||||
Addrs: []net.Addr{&net.IPNet{IP: net.IPv4(192, 168, 50, 10), Mask: net.CIDRMask(24, 32)}},
|
||||
},
|
||||
{
|
||||
Name: "eth1",
|
||||
Flags: net.FlagUp,
|
||||
Addrs: []net.Addr{&net.IPNet{IP: net.IPv4(192, 168, 50, 20), Mask: net.CIDRMask(24, 32)}},
|
||||
},
|
||||
{
|
||||
Name: "linklocal",
|
||||
Flags: net.FlagUp,
|
||||
Addrs: []net.Addr{&net.IPNet{IP: net.IPv4(169, 254, 10, 2), Mask: net.CIDRMask(16, 32)}},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
subnets, err := getAllLocalSubnets(probe)
|
||||
if err != nil {
|
||||
t.Fatalf("getAllLocalSubnets returned error: %v", err)
|
||||
}
|
||||
if len(subnets) != 1 {
|
||||
t.Fatalf("subnets = %#v, want 1 unique subnet", subnets)
|
||||
}
|
||||
if got := subnets[0].String(); got != mustIPNet(t, "192.168.50.0/24").String() {
|
||||
t.Fatalf("subnet = %q, want 192.168.50.0/24", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsDockerHostMode_InterfaceError(t *testing.T) {
|
||||
probe := fakeEnvironmentProbe{interfacesErr: errors.New("boom")}
|
||||
|
||||
hostMode, warnings := isDockerHostMode(probe)
|
||||
if hostMode {
|
||||
t.Fatalf("expected hostMode=false on error")
|
||||
}
|
||||
if len(warnings) == 0 || !strings.Contains(warnings[0], "Unable to enumerate interfaces") {
|
||||
t.Fatalf("warnings = %#v, want interface enumeration warning", warnings)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDetectDockerEnvironment_BridgeFallback(t *testing.T) {
|
||||
profile := &EnvironmentProfile{
|
||||
Policy: DefaultScanPolicy(),
|
||||
Metadata: map[string]string{},
|
||||
}
|
||||
profile.Policy.ScanGateways = false
|
||||
|
||||
probe := fakeEnvironmentProbe{
|
||||
fileErr: map[string]error{
|
||||
"/proc/net/route": errors.New("nope"),
|
||||
},
|
||||
interfaces: []ifaceInfo{
|
||||
{
|
||||
Name: "lo",
|
||||
Flags: net.FlagUp | net.FlagLoopback,
|
||||
Addrs: []net.Addr{&net.IPNet{IP: net.IPv4(127, 0, 0, 1), Mask: net.CIDRMask(8, 32)}},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
result, err := detectDockerEnvironment(profile, probe)
|
||||
if err != nil {
|
||||
t.Fatalf("detectDockerEnvironment returned error: %v", err)
|
||||
}
|
||||
if result.Type != DockerBridge {
|
||||
t.Fatalf("Type = %v, want %v", result.Type, DockerBridge)
|
||||
}
|
||||
if len(result.Phases) == 0 || result.Phases[0].Name != "fallback_common_subnets" {
|
||||
t.Fatalf("expected fallback subnets, got %#v", result.Phases)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDetectHostNetworkFromContainer_NonStandardGateway(t *testing.T) {
|
||||
route := strings.Join([]string{
|
||||
"Iface\tDestination\tGateway",
|
||||
"eth0\t00000000\t2A00000A",
|
||||
}, "\n")
|
||||
|
||||
probe := fakeEnvironmentProbe{
|
||||
fileData: map[string][]byte{"/proc/net/route": []byte(route)},
|
||||
}
|
||||
|
||||
subnets, confidence, warnings := detectHostNetworkFromContainer(probe)
|
||||
if confidence != 0.4 {
|
||||
t.Fatalf("confidence = %v, want 0.4", confidence)
|
||||
}
|
||||
if len(subnets) != 1 || subnets[0].String() != "10.0.0.0/24" {
|
||||
t.Fatalf("subnets = %#v, want 10.0.0.0/24", subnets)
|
||||
}
|
||||
found := false
|
||||
for _, warn := range warnings {
|
||||
if strings.Contains(warn, "does not end with .1 or .254") {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Fatalf("warnings = %#v, want non-standard gateway warning", warnings)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDetectHostNetworkFromContainer_GatewayErrorFallback(t *testing.T) {
|
||||
probe := fakeEnvironmentProbe{
|
||||
fileErr: map[string]error{"/proc/net/route": errors.New("boom")},
|
||||
}
|
||||
|
||||
subnets, confidence, warnings := detectHostNetworkFromContainer(probe)
|
||||
if confidence != 0.3 {
|
||||
t.Fatalf("confidence = %v, want 0.3", confidence)
|
||||
}
|
||||
if len(subnets) == 0 {
|
||||
t.Fatalf("expected fallback subnets, got none")
|
||||
}
|
||||
if len(warnings) == 0 || !strings.Contains(warnings[0], "Could not determine default gateway") {
|
||||
t.Fatalf("warnings = %#v, want gateway warning", warnings)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetDefaultGateway_InvalidHex(t *testing.T) {
|
||||
route := strings.Join([]string{
|
||||
"Iface\tDestination\tGateway",
|
||||
"eth0\t00000000\tZZZZZZZZ",
|
||||
}, "\n")
|
||||
|
||||
probe := fakeEnvironmentProbe{
|
||||
fileData: map[string][]byte{"/proc/net/route": []byte(route)},
|
||||
}
|
||||
|
||||
_, err := getDefaultGateway(probe)
|
||||
if err == nil {
|
||||
t.Fatalf("expected error, got nil")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "failed to parse default gateway") {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCountKernelRoutes_ReadFileError(t *testing.T) {
|
||||
probe := fakeEnvironmentProbe{
|
||||
fileErr: map[string]error{"/proc/net/route": errors.New("boom")},
|
||||
}
|
||||
|
||||
count, warn := countKernelRoutes(probe)
|
||||
if count != 0 {
|
||||
t.Fatalf("count = %d, want 0", count)
|
||||
}
|
||||
if warn == "" || !strings.Contains(warn, "Unable to read /proc/net/route") {
|
||||
t.Fatalf("warn = %q, want read error warning", warn)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsLXCPrivileged_ErrorPaths(t *testing.T) {
|
||||
t.Run("permission", func(t *testing.T) {
|
||||
probe := fakeEnvironmentProbe{
|
||||
fileErr: map[string]error{"/proc/self/uid_map": os.ErrPermission},
|
||||
}
|
||||
privileged, warn := isLXCPrivileged(probe)
|
||||
if privileged {
|
||||
t.Fatalf("expected unprivileged on permission error")
|
||||
}
|
||||
if !strings.Contains(warn, "permission denied") {
|
||||
t.Fatalf("warn = %q, want permission warning", warn)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("bad-format", func(t *testing.T) {
|
||||
probe := fakeEnvironmentProbe{
|
||||
fileData: map[string][]byte{"/proc/self/uid_map": []byte("0 0\n")},
|
||||
}
|
||||
privileged, warn := isLXCPrivileged(probe)
|
||||
if privileged {
|
||||
t.Fatalf("expected unprivileged on format error")
|
||||
}
|
||||
if !strings.Contains(warn, "Unexpected format") {
|
||||
t.Fatalf("warn = %q, want format warning", warn)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("bad-hostuid", func(t *testing.T) {
|
||||
probe := fakeEnvironmentProbe{
|
||||
fileData: map[string][]byte{"/proc/self/uid_map": []byte("0 x 1\n")},
|
||||
}
|
||||
privileged, warn := isLXCPrivileged(probe)
|
||||
if privileged {
|
||||
t.Fatalf("expected unprivileged on parse error")
|
||||
}
|
||||
if !strings.Contains(warn, "Failed to parse uid_map") {
|
||||
t.Fatalf("warn = %q, want parse warning", warn)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("bad-length", func(t *testing.T) {
|
||||
probe := fakeEnvironmentProbe{
|
||||
fileData: map[string][]byte{"/proc/self/uid_map": []byte("0 0 nope\n")},
|
||||
}
|
||||
privileged, warn := isLXCPrivileged(probe)
|
||||
if privileged {
|
||||
t.Fatalf("expected unprivileged on length parse error")
|
||||
}
|
||||
if !strings.Contains(warn, "Failed to parse uid_map length") {
|
||||
t.Fatalf("warn = %q, want length warning", warn)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestDetectEnvironment_UnsupportedContainerType(t *testing.T) {
|
||||
probe := fakeEnvironmentProbe{
|
||||
lookPathPresent: map[string]bool{"systemd-detect-virt": true},
|
||||
commandOutput: map[string][]byte{
|
||||
"systemd-detect-virt\x00--container": []byte("rkt\n"),
|
||||
},
|
||||
}
|
||||
|
||||
profile, err := detectEnvironment(probe)
|
||||
if err != nil {
|
||||
t.Fatalf("detectEnvironment returned error: %v", err)
|
||||
}
|
||||
if profile.Type != Unknown {
|
||||
t.Fatalf("Type = %v, want %v", profile.Type, Unknown)
|
||||
}
|
||||
if profile.Metadata["container_type"] != "rkt" {
|
||||
t.Fatalf("container_type = %q, want rkt", profile.Metadata["container_type"])
|
||||
}
|
||||
if len(profile.Phases) == 0 || profile.Phases[0].Name != "fallback_common_subnets" {
|
||||
t.Fatalf("expected fallback subnets, got %#v", profile.Phases)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDetectLXCEnvironment_UnprivilegedFallback(t *testing.T) {
|
||||
profile := &EnvironmentProfile{
|
||||
Policy: DefaultScanPolicy(),
|
||||
Metadata: map[string]string{},
|
||||
}
|
||||
profile.Policy.ScanGateways = false
|
||||
|
||||
probe := fakeEnvironmentProbe{
|
||||
fileData: map[string][]byte{"/proc/self/uid_map": []byte("0 100000 65536\n")},
|
||||
interfaces: []ifaceInfo{
|
||||
{
|
||||
Name: "lo",
|
||||
Flags: net.FlagUp | net.FlagLoopback,
|
||||
Addrs: []net.Addr{&net.IPNet{IP: net.IPv4(127, 0, 0, 1), Mask: net.CIDRMask(8, 32)}},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
result, err := detectLXCEnvironment(profile, probe)
|
||||
if err != nil {
|
||||
t.Fatalf("detectLXCEnvironment returned error: %v", err)
|
||||
}
|
||||
if result.Type != LXCUnprivileged {
|
||||
t.Fatalf("Type = %v, want %v", result.Type, LXCUnprivileged)
|
||||
}
|
||||
if len(result.Phases) == 0 || result.Phases[0].Name != "fallback_common_subnets" {
|
||||
t.Fatalf("expected fallback subnets, got %#v", result.Phases)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue