359 lines
8.6 KiB
Go
359 lines
8.6 KiB
Go
|
|
package container
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"runtime"
|
||
|
|
"testing"
|
||
|
|
|
||
|
|
"github.com/stretchr/testify/assert"
|
||
|
|
"github.com/stretchr/testify/require"
|
||
|
|
)
|
||
|
|
|
||
|
|
func TestQemuHypervisor_Available_Good(t *testing.T) {
|
||
|
|
q := NewQemuHypervisor()
|
||
|
|
|
||
|
|
// Check if qemu is available on this system
|
||
|
|
available := q.Available()
|
||
|
|
|
||
|
|
// We just verify it returns a boolean without error
|
||
|
|
// The actual availability depends on the system
|
||
|
|
assert.IsType(t, true, available)
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestQemuHypervisor_Available_Bad_InvalidBinary(t *testing.T) {
|
||
|
|
q := &QemuHypervisor{
|
||
|
|
Binary: "nonexistent-qemu-binary-that-does-not-exist",
|
||
|
|
}
|
||
|
|
|
||
|
|
available := q.Available()
|
||
|
|
|
||
|
|
assert.False(t, available)
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestHyperkitHypervisor_Available_Good(t *testing.T) {
|
||
|
|
h := NewHyperkitHypervisor()
|
||
|
|
|
||
|
|
available := h.Available()
|
||
|
|
|
||
|
|
// On non-darwin systems, should always be false
|
||
|
|
if runtime.GOOS != "darwin" {
|
||
|
|
assert.False(t, available)
|
||
|
|
} else {
|
||
|
|
// On darwin, just verify it returns a boolean
|
||
|
|
assert.IsType(t, true, available)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestHyperkitHypervisor_Available_Bad_NotDarwin(t *testing.T) {
|
||
|
|
if runtime.GOOS == "darwin" {
|
||
|
|
t.Skip("This test only runs on non-darwin systems")
|
||
|
|
}
|
||
|
|
|
||
|
|
h := NewHyperkitHypervisor()
|
||
|
|
|
||
|
|
available := h.Available()
|
||
|
|
|
||
|
|
assert.False(t, available, "Hyperkit should not be available on non-darwin systems")
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestHyperkitHypervisor_Available_Bad_InvalidBinary(t *testing.T) {
|
||
|
|
h := &HyperkitHypervisor{
|
||
|
|
Binary: "nonexistent-hyperkit-binary-that-does-not-exist",
|
||
|
|
}
|
||
|
|
|
||
|
|
available := h.Available()
|
||
|
|
|
||
|
|
assert.False(t, available)
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestIsKVMAvailable_Good(t *testing.T) {
|
||
|
|
// This test verifies the function runs without error
|
||
|
|
// The actual result depends on the system
|
||
|
|
result := isKVMAvailable()
|
||
|
|
|
||
|
|
// On non-linux systems, should be false
|
||
|
|
if runtime.GOOS != "linux" {
|
||
|
|
assert.False(t, result, "KVM should not be available on non-linux systems")
|
||
|
|
} else {
|
||
|
|
// On linux, just verify it returns a boolean
|
||
|
|
assert.IsType(t, true, result)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestDetectHypervisor_Good(t *testing.T) {
|
||
|
|
// DetectHypervisor tries to find an available hypervisor
|
||
|
|
hv, err := DetectHypervisor()
|
||
|
|
|
||
|
|
// This test may pass or fail depending on system configuration
|
||
|
|
// If no hypervisor is available, it should return an error
|
||
|
|
if err != nil {
|
||
|
|
assert.Nil(t, hv)
|
||
|
|
assert.Contains(t, err.Error(), "no hypervisor available")
|
||
|
|
} else {
|
||
|
|
assert.NotNil(t, hv)
|
||
|
|
assert.NotEmpty(t, hv.Name())
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestGetHypervisor_Good_Qemu(t *testing.T) {
|
||
|
|
hv, err := GetHypervisor("qemu")
|
||
|
|
|
||
|
|
// Depends on whether qemu is installed
|
||
|
|
if err != nil {
|
||
|
|
assert.Contains(t, err.Error(), "not available")
|
||
|
|
} else {
|
||
|
|
assert.NotNil(t, hv)
|
||
|
|
assert.Equal(t, "qemu", hv.Name())
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestGetHypervisor_Good_QemuUppercase(t *testing.T) {
|
||
|
|
hv, err := GetHypervisor("QEMU")
|
||
|
|
|
||
|
|
// Depends on whether qemu is installed
|
||
|
|
if err != nil {
|
||
|
|
assert.Contains(t, err.Error(), "not available")
|
||
|
|
} else {
|
||
|
|
assert.NotNil(t, hv)
|
||
|
|
assert.Equal(t, "qemu", hv.Name())
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestGetHypervisor_Good_Hyperkit(t *testing.T) {
|
||
|
|
hv, err := GetHypervisor("hyperkit")
|
||
|
|
|
||
|
|
// On non-darwin systems, should always fail
|
||
|
|
if runtime.GOOS != "darwin" {
|
||
|
|
assert.Error(t, err)
|
||
|
|
assert.Contains(t, err.Error(), "not available")
|
||
|
|
} else {
|
||
|
|
// On darwin, depends on whether hyperkit is installed
|
||
|
|
if err != nil {
|
||
|
|
assert.Contains(t, err.Error(), "not available")
|
||
|
|
} else {
|
||
|
|
assert.NotNil(t, hv)
|
||
|
|
assert.Equal(t, "hyperkit", hv.Name())
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestGetHypervisor_Bad_Unknown(t *testing.T) {
|
||
|
|
_, err := GetHypervisor("unknown-hypervisor")
|
||
|
|
|
||
|
|
assert.Error(t, err)
|
||
|
|
assert.Contains(t, err.Error(), "unknown hypervisor")
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestQemuHypervisor_BuildCommand_Good_WithPortsAndVolumes(t *testing.T) {
|
||
|
|
q := NewQemuHypervisor()
|
||
|
|
|
||
|
|
ctx := context.Background()
|
||
|
|
opts := &HypervisorOptions{
|
||
|
|
Memory: 2048,
|
||
|
|
CPUs: 4,
|
||
|
|
SSHPort: 2222,
|
||
|
|
Ports: map[int]int{8080: 80, 443: 443},
|
||
|
|
Volumes: map[string]string{
|
||
|
|
"/host/data": "/container/data",
|
||
|
|
"/host/logs": "/container/logs",
|
||
|
|
},
|
||
|
|
Detach: true,
|
||
|
|
}
|
||
|
|
|
||
|
|
cmd, err := q.BuildCommand(ctx, "/path/to/image.iso", opts)
|
||
|
|
require.NoError(t, err)
|
||
|
|
assert.NotNil(t, cmd)
|
||
|
|
|
||
|
|
// Verify command includes all expected args
|
||
|
|
args := cmd.Args
|
||
|
|
assert.Contains(t, args, "-m")
|
||
|
|
assert.Contains(t, args, "2048")
|
||
|
|
assert.Contains(t, args, "-smp")
|
||
|
|
assert.Contains(t, args, "4")
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestQemuHypervisor_BuildCommand_Good_QCow2Format(t *testing.T) {
|
||
|
|
q := NewQemuHypervisor()
|
||
|
|
|
||
|
|
ctx := context.Background()
|
||
|
|
opts := &HypervisorOptions{Memory: 1024, CPUs: 1}
|
||
|
|
|
||
|
|
cmd, err := q.BuildCommand(ctx, "/path/to/image.qcow2", opts)
|
||
|
|
require.NoError(t, err)
|
||
|
|
|
||
|
|
// Check that the drive format is qcow2
|
||
|
|
found := false
|
||
|
|
for _, arg := range cmd.Args {
|
||
|
|
if arg == "file=/path/to/image.qcow2,format=qcow2" {
|
||
|
|
found = true
|
||
|
|
break
|
||
|
|
}
|
||
|
|
}
|
||
|
|
assert.True(t, found, "Should have qcow2 drive argument")
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestQemuHypervisor_BuildCommand_Good_VMDKFormat(t *testing.T) {
|
||
|
|
q := NewQemuHypervisor()
|
||
|
|
|
||
|
|
ctx := context.Background()
|
||
|
|
opts := &HypervisorOptions{Memory: 1024, CPUs: 1}
|
||
|
|
|
||
|
|
cmd, err := q.BuildCommand(ctx, "/path/to/image.vmdk", opts)
|
||
|
|
require.NoError(t, err)
|
||
|
|
|
||
|
|
// Check that the drive format is vmdk
|
||
|
|
found := false
|
||
|
|
for _, arg := range cmd.Args {
|
||
|
|
if arg == "file=/path/to/image.vmdk,format=vmdk" {
|
||
|
|
found = true
|
||
|
|
break
|
||
|
|
}
|
||
|
|
}
|
||
|
|
assert.True(t, found, "Should have vmdk drive argument")
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestQemuHypervisor_BuildCommand_Good_RawFormat(t *testing.T) {
|
||
|
|
q := NewQemuHypervisor()
|
||
|
|
|
||
|
|
ctx := context.Background()
|
||
|
|
opts := &HypervisorOptions{Memory: 1024, CPUs: 1}
|
||
|
|
|
||
|
|
cmd, err := q.BuildCommand(ctx, "/path/to/image.raw", opts)
|
||
|
|
require.NoError(t, err)
|
||
|
|
|
||
|
|
// Check that the drive format is raw
|
||
|
|
found := false
|
||
|
|
for _, arg := range cmd.Args {
|
||
|
|
if arg == "file=/path/to/image.raw,format=raw" {
|
||
|
|
found = true
|
||
|
|
break
|
||
|
|
}
|
||
|
|
}
|
||
|
|
assert.True(t, found, "Should have raw drive argument")
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestHyperkitHypervisor_BuildCommand_Good_WithPorts(t *testing.T) {
|
||
|
|
h := NewHyperkitHypervisor()
|
||
|
|
|
||
|
|
ctx := context.Background()
|
||
|
|
opts := &HypervisorOptions{
|
||
|
|
Memory: 1024,
|
||
|
|
CPUs: 2,
|
||
|
|
SSHPort: 2222,
|
||
|
|
Ports: map[int]int{8080: 80},
|
||
|
|
}
|
||
|
|
|
||
|
|
cmd, err := h.BuildCommand(ctx, "/path/to/image.iso", opts)
|
||
|
|
require.NoError(t, err)
|
||
|
|
assert.NotNil(t, cmd)
|
||
|
|
|
||
|
|
// Verify it creates a command with memory and CPU args
|
||
|
|
args := cmd.Args
|
||
|
|
assert.Contains(t, args, "-m")
|
||
|
|
assert.Contains(t, args, "1024M")
|
||
|
|
assert.Contains(t, args, "-c")
|
||
|
|
assert.Contains(t, args, "2")
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestHyperkitHypervisor_BuildCommand_Good_QCow2Format(t *testing.T) {
|
||
|
|
h := NewHyperkitHypervisor()
|
||
|
|
|
||
|
|
ctx := context.Background()
|
||
|
|
opts := &HypervisorOptions{Memory: 1024, CPUs: 1}
|
||
|
|
|
||
|
|
cmd, err := h.BuildCommand(ctx, "/path/to/image.qcow2", opts)
|
||
|
|
require.NoError(t, err)
|
||
|
|
assert.NotNil(t, cmd)
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestHyperkitHypervisor_BuildCommand_Good_RawFormat(t *testing.T) {
|
||
|
|
h := NewHyperkitHypervisor()
|
||
|
|
|
||
|
|
ctx := context.Background()
|
||
|
|
opts := &HypervisorOptions{Memory: 1024, CPUs: 1}
|
||
|
|
|
||
|
|
cmd, err := h.BuildCommand(ctx, "/path/to/image.raw", opts)
|
||
|
|
require.NoError(t, err)
|
||
|
|
assert.NotNil(t, cmd)
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestHyperkitHypervisor_BuildCommand_Good_NoPorts(t *testing.T) {
|
||
|
|
h := NewHyperkitHypervisor()
|
||
|
|
|
||
|
|
ctx := context.Background()
|
||
|
|
opts := &HypervisorOptions{
|
||
|
|
Memory: 512,
|
||
|
|
CPUs: 1,
|
||
|
|
SSHPort: 0, // No SSH port
|
||
|
|
Ports: nil,
|
||
|
|
}
|
||
|
|
|
||
|
|
cmd, err := h.BuildCommand(ctx, "/path/to/image.iso", opts)
|
||
|
|
require.NoError(t, err)
|
||
|
|
assert.NotNil(t, cmd)
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestQemuHypervisor_BuildCommand_Good_NoSSHPort(t *testing.T) {
|
||
|
|
q := NewQemuHypervisor()
|
||
|
|
|
||
|
|
ctx := context.Background()
|
||
|
|
opts := &HypervisorOptions{
|
||
|
|
Memory: 512,
|
||
|
|
CPUs: 1,
|
||
|
|
SSHPort: 0, // No SSH port
|
||
|
|
Ports: nil,
|
||
|
|
}
|
||
|
|
|
||
|
|
cmd, err := q.BuildCommand(ctx, "/path/to/image.iso", opts)
|
||
|
|
require.NoError(t, err)
|
||
|
|
assert.NotNil(t, cmd)
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestQemuHypervisor_BuildCommand_Bad_UnknownFormat(t *testing.T) {
|
||
|
|
q := NewQemuHypervisor()
|
||
|
|
|
||
|
|
ctx := context.Background()
|
||
|
|
opts := &HypervisorOptions{Memory: 1024, CPUs: 1}
|
||
|
|
|
||
|
|
_, err := q.BuildCommand(ctx, "/path/to/image.txt", opts)
|
||
|
|
assert.Error(t, err)
|
||
|
|
assert.Contains(t, err.Error(), "unknown image format")
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestHyperkitHypervisor_BuildCommand_Bad_UnknownFormat(t *testing.T) {
|
||
|
|
h := NewHyperkitHypervisor()
|
||
|
|
|
||
|
|
ctx := context.Background()
|
||
|
|
opts := &HypervisorOptions{Memory: 1024, CPUs: 1}
|
||
|
|
|
||
|
|
_, err := h.BuildCommand(ctx, "/path/to/image.unknown", opts)
|
||
|
|
assert.Error(t, err)
|
||
|
|
assert.Contains(t, err.Error(), "unknown image format")
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestHyperkitHypervisor_Name_Good(t *testing.T) {
|
||
|
|
h := NewHyperkitHypervisor()
|
||
|
|
assert.Equal(t, "hyperkit", h.Name())
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestHyperkitHypervisor_BuildCommand_Good_ISOFormat(t *testing.T) {
|
||
|
|
h := NewHyperkitHypervisor()
|
||
|
|
|
||
|
|
ctx := context.Background()
|
||
|
|
opts := &HypervisorOptions{
|
||
|
|
Memory: 1024,
|
||
|
|
CPUs: 2,
|
||
|
|
SSHPort: 2222,
|
||
|
|
}
|
||
|
|
|
||
|
|
cmd, err := h.BuildCommand(ctx, "/path/to/image.iso", opts)
|
||
|
|
require.NoError(t, err)
|
||
|
|
assert.NotNil(t, cmd)
|
||
|
|
|
||
|
|
args := cmd.Args
|
||
|
|
assert.Contains(t, args, "-m")
|
||
|
|
assert.Contains(t, args, "1024M")
|
||
|
|
assert.Contains(t, args, "-c")
|
||
|
|
assert.Contains(t, args, "2")
|
||
|
|
}
|