mirror of
https://github.com/kairos-io/kairos-sdk.git
synced 2025-08-31 14:51:52 +00:00
385 lines
11 KiB
Go
385 lines
11 KiB
Go
package ghw_test
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/kairos-io/kairos-sdk/ghw"
|
|
"github.com/kairos-io/kairos-sdk/ghw/mocks"
|
|
"github.com/kairos-io/kairos-sdk/types"
|
|
|
|
. "github.com/onsi/ginkgo/v2"
|
|
. "github.com/onsi/gomega"
|
|
)
|
|
|
|
func TestGHW(t *testing.T) {
|
|
RegisterFailHandler(Fail)
|
|
RunSpecs(t, "GHW test suite")
|
|
}
|
|
|
|
var _ = Describe("GHW functions tests", func() {
|
|
var ghwMock mocks.GhwMock
|
|
BeforeEach(func() {
|
|
ghwMock = mocks.GhwMock{}
|
|
})
|
|
AfterEach(func() {
|
|
ghwMock.Clean()
|
|
})
|
|
Describe("With a disk", func() {
|
|
BeforeEach(func() {
|
|
mainDisk := types.Disk{
|
|
Name: "disk",
|
|
UUID: "555",
|
|
SizeBytes: 1 * 1024,
|
|
Partitions: []*types.Partition{
|
|
{
|
|
Name: "disk1",
|
|
FilesystemLabel: "COS_GRUB",
|
|
FS: "ext4",
|
|
MountPoint: "/efi",
|
|
Size: 0,
|
|
UUID: "666",
|
|
},
|
|
},
|
|
}
|
|
|
|
ghwMock.AddDisk(mainDisk)
|
|
ghwMock.CreateDevices()
|
|
})
|
|
|
|
It("Finds the disk and partition", func() {
|
|
disks := ghw.GetDisks(ghw.NewPaths(ghwMock.Chroot), nil)
|
|
Expect(len(disks)).To(Equal(1), disks)
|
|
Expect(disks[0].Name).To(Equal("disk"), disks)
|
|
Expect(disks[0].UUID).To(Equal("555"), disks)
|
|
// Expected is size * sectorsize which is 512
|
|
Expect(disks[0].SizeBytes).To(Equal(uint64(1*1024*512)), disks)
|
|
Expect(len(disks[0].Partitions)).To(Equal(1), disks)
|
|
Expect(disks[0].Partitions[0].Name).To(Equal("disk1"), disks)
|
|
Expect(disks[0].Partitions[0].FilesystemLabel).To(Equal("COS_GRUB"), disks)
|
|
Expect(disks[0].Partitions[0].FS).To(Equal("ext4"), disks)
|
|
Expect(disks[0].Partitions[0].MountPoint).To(Equal("/efi"), disks)
|
|
Expect(disks[0].Partitions[0].UUID).To(Equal("666"), disks)
|
|
})
|
|
})
|
|
Describe("With no disks", func() {
|
|
It("Finds nothing", func() {
|
|
ghwMock.CreateDevices()
|
|
disks := ghw.GetDisks(ghw.NewPaths(ghwMock.Chroot), nil)
|
|
Expect(len(disks)).To(Equal(0), disks)
|
|
})
|
|
})
|
|
|
|
Describe("With multipath devices", func() {
|
|
BeforeEach(func() {
|
|
// Create a multipath device dm-0 with two partitions dm-1 and dm-2
|
|
multipathDisk := types.Disk{
|
|
Name: "dm-0",
|
|
UUID: "mpath-uuid-123",
|
|
SizeBytes: 10 * 1024 * 1024, // 10MB
|
|
Partitions: []*types.Partition{
|
|
{
|
|
Name: "dm-1",
|
|
FilesystemLabel: "MPATH_BOOT",
|
|
FS: "ext4",
|
|
MountPoint: "/boot",
|
|
Size: 512,
|
|
UUID: "part1-mpath-uuid-456",
|
|
},
|
|
{
|
|
Name: "dm-2",
|
|
FilesystemLabel: "MPATH_DATA",
|
|
FS: "xfs",
|
|
MountPoint: "/data",
|
|
Size: 1024,
|
|
UUID: "part2-mpath-uuid-789",
|
|
},
|
|
},
|
|
}
|
|
|
|
ghwMock.AddDisk(multipathDisk)
|
|
ghwMock.CreateMultipathDevices()
|
|
})
|
|
|
|
It("Identifies multipath device correctly", func() {
|
|
disks := ghw.GetDisks(ghw.NewPaths(ghwMock.Chroot), nil)
|
|
|
|
// Should find the multipath device but not the partitions as separate disks
|
|
Expect(len(disks)).To(Equal(1), "Should find only the multipath device")
|
|
|
|
disk := disks[0]
|
|
Expect(disk.Name).To(Equal("dm-0"))
|
|
Expect(disk.UUID).To(Equal("mpath-uuid-123"))
|
|
Expect(disk.SizeBytes).To(Equal(uint64(10 * 1024 * 1024 * 512))) // size * sectorSize
|
|
})
|
|
|
|
It("Finds multipath partitions using MultipathPartitionHandler", func() {
|
|
disks := ghw.GetDisks(ghw.NewPaths(ghwMock.Chroot), nil)
|
|
|
|
Expect(len(disks)).To(Equal(1))
|
|
disk := disks[0]
|
|
|
|
// Should find both partitions
|
|
Expect(len(disk.Partitions)).To(Equal(2))
|
|
|
|
// Verify first partition
|
|
part1 := disk.Partitions[0]
|
|
Expect(part1.Name).To(Equal("dm-1"))
|
|
Expect(part1.FilesystemLabel).To(Equal("MPATH_BOOT"))
|
|
Expect(part1.FS).To(Equal("ext4"))
|
|
Expect(part1.MountPoint).To(Equal("/boot"))
|
|
Expect(part1.UUID).To(Equal("part1-mpath-uuid-456"))
|
|
Expect(part1.Path).To(Equal("/dev/dm-1"))
|
|
Expect(part1.Disk).To(Equal("/dev/dm-0"))
|
|
|
|
// Verify second partition
|
|
part2 := disk.Partitions[1]
|
|
Expect(part2.Name).To(Equal("dm-2"))
|
|
Expect(part2.FilesystemLabel).To(Equal("MPATH_DATA"))
|
|
Expect(part2.FS).To(Equal("xfs"))
|
|
Expect(part2.MountPoint).To(Equal("/data"))
|
|
Expect(part2.UUID).To(Equal("part2-mpath-uuid-789"))
|
|
Expect(part2.Path).To(Equal("/dev/dm-2"))
|
|
Expect(part2.Disk).To(Equal("/dev/dm-0"))
|
|
})
|
|
|
|
It("Skips multipath partitions in main disk enumeration", func() {
|
|
// This test verifies that multipath partitions (dm-1, dm-2) are not
|
|
// returned as separate disks in the main GetDisks call
|
|
disks := ghw.GetDisks(ghw.NewPaths(ghwMock.Chroot), nil)
|
|
|
|
// Should only find the parent multipath device, not the partition devices
|
|
Expect(len(disks)).To(Equal(1))
|
|
Expect(disks[0].Name).To(Equal("dm-0"))
|
|
|
|
// Verify no disk named dm-1 or dm-2 is returned
|
|
for _, disk := range disks {
|
|
Expect(disk.Name).ToNot(Equal("dm-1"))
|
|
Expect(disk.Name).ToNot(Equal("dm-2"))
|
|
}
|
|
})
|
|
})
|
|
|
|
Describe("With multipath devices using /dev/dm-<n> mount format", func() {
|
|
BeforeEach(func() {
|
|
// Create a multipath device dm-3 with partitions mounted as /dev/dm-<n> instead of /dev/mapper/<name>
|
|
multipathDisk := types.Disk{
|
|
Name: "dm-3",
|
|
UUID: "mpath-dm-mount-uuid",
|
|
SizeBytes: 8 * 1024 * 1024,
|
|
Partitions: []*types.Partition{
|
|
{
|
|
Name: "dm-4",
|
|
FilesystemLabel: "DM_BOOT",
|
|
FS: "ext4",
|
|
MountPoint: "/boot",
|
|
Size: 256,
|
|
UUID: "part1-mpath-uuid",
|
|
},
|
|
{
|
|
Name: "dm-5",
|
|
FilesystemLabel: "DM_DATA",
|
|
FS: "xfs",
|
|
MountPoint: "/data",
|
|
Size: 512,
|
|
UUID: "part2-mpath-uuid",
|
|
},
|
|
},
|
|
}
|
|
|
|
ghwMock.AddDisk(multipathDisk)
|
|
ghwMock.CreateMultipathDevicesWithDmMounts()
|
|
})
|
|
|
|
It("Finds multipath partitions mounted as /dev/dm-<n>", func() {
|
|
disks := ghw.GetDisks(ghw.NewPaths(ghwMock.Chroot), nil)
|
|
|
|
Expect(len(disks)).To(Equal(1))
|
|
disk := disks[0]
|
|
|
|
// Should find both partitions
|
|
Expect(len(disk.Partitions)).To(Equal(2))
|
|
|
|
// Verify partitions can be found regardless of mount format
|
|
var bootPartition, dataPartition *types.Partition
|
|
for _, part := range disk.Partitions {
|
|
if part.MountPoint == "/boot" {
|
|
bootPartition = part
|
|
} else if part.MountPoint == "/data" {
|
|
dataPartition = part
|
|
}
|
|
}
|
|
|
|
Expect(bootPartition).ToNot(BeNil())
|
|
Expect(bootPartition.Name).To(Equal("dm-4"))
|
|
Expect(bootPartition.FilesystemLabel).To(Equal("DM_BOOT"))
|
|
Expect(bootPartition.MountPoint).To(Equal("/boot"))
|
|
Expect(bootPartition.FS).To(Equal("ext4"))
|
|
Expect(bootPartition.Path).To(Equal("/dev/dm-4"))
|
|
|
|
Expect(dataPartition).ToNot(BeNil())
|
|
Expect(dataPartition.Name).To(Equal("dm-5"))
|
|
Expect(dataPartition.FilesystemLabel).To(Equal("DM_DATA"))
|
|
Expect(dataPartition.MountPoint).To(Equal("/data"))
|
|
Expect(dataPartition.FS).To(Equal("xfs"))
|
|
Expect(dataPartition.Path).To(Equal("/dev/dm-5"))
|
|
})
|
|
})
|
|
|
|
Describe("With standalone multipath device (no partitions)", func() {
|
|
It("Handles multipath device with no partitions", func() {
|
|
multipathDisk := types.Disk{
|
|
Name: "dm-5",
|
|
UUID: "mpath-empty-uuid",
|
|
SizeBytes: 5 * 1024 * 1024,
|
|
}
|
|
|
|
ghwMock.AddDisk(multipathDisk)
|
|
ghwMock.CreateMultipathDevices()
|
|
|
|
disks := ghw.GetDisks(ghw.NewPaths(ghwMock.Chroot), nil)
|
|
|
|
Expect(len(disks)).To(Equal(1))
|
|
disk := disks[0]
|
|
Expect(disk.Name).To(Equal("dm-5"))
|
|
Expect(len(disk.Partitions)).To(Equal(0))
|
|
})
|
|
})
|
|
|
|
Describe("With mixed regular and multipath disks", func() {
|
|
It("Handles mixed regular and multipath disks", func() {
|
|
// Create multipath device
|
|
multipathDeviceDef := types.Disk{
|
|
Name: "dm-0",
|
|
UUID: "mpath-uuid-123",
|
|
SizeBytes: 10 * 1024 * 1024,
|
|
Partitions: []*types.Partition{
|
|
{
|
|
Name: "dm-1",
|
|
FilesystemLabel: "MPATH_BOOT",
|
|
FS: "ext4",
|
|
MountPoint: "/boot",
|
|
Size: 512,
|
|
UUID: "part1-mpath-uuid-456",
|
|
},
|
|
},
|
|
}
|
|
|
|
// Create regular disk
|
|
regularDisk := types.Disk{
|
|
Name: "sda",
|
|
UUID: "regular-uuid-999",
|
|
SizeBytes: 8 * 1024 * 1024,
|
|
Partitions: []*types.Partition{
|
|
{
|
|
Name: "sda1",
|
|
FilesystemLabel: "REGULAR_ROOT",
|
|
FS: "ext4",
|
|
MountPoint: "/",
|
|
Size: 2048,
|
|
UUID: "regular-part-uuid",
|
|
},
|
|
},
|
|
}
|
|
|
|
// Add both disks
|
|
ghwMock.AddDisk(multipathDeviceDef)
|
|
ghwMock.AddDisk(regularDisk)
|
|
|
|
// Create multipath structure (this will handle both disks appropriately)
|
|
ghwMock.CreateMultipathDevices()
|
|
|
|
disks := ghw.GetDisks(ghw.NewPaths(ghwMock.Chroot), nil)
|
|
|
|
// Should find both the regular disk and multipath device
|
|
Expect(len(disks)).To(Equal(2))
|
|
|
|
var foundMultipathDisk, foundRegularDisk *types.Disk
|
|
for _, disk := range disks {
|
|
if disk.Name == "dm-0" {
|
|
foundMultipathDisk = disk
|
|
} else if disk.Name == "sda" {
|
|
foundRegularDisk = disk
|
|
}
|
|
}
|
|
|
|
Expect(foundMultipathDisk).ToNot(BeNil())
|
|
Expect(foundRegularDisk).ToNot(BeNil())
|
|
|
|
// Verify multipath device has its partition
|
|
Expect(len(foundMultipathDisk.Partitions)).To(Equal(1))
|
|
Expect(foundMultipathDisk.Partitions[0].Name).To(Equal("dm-1"))
|
|
|
|
// Verify regular device has its partition
|
|
Expect(len(foundRegularDisk.Partitions)).To(Equal(1))
|
|
Expect(foundRegularDisk.Partitions[0].Name).To(Equal("sda1"))
|
|
})
|
|
})
|
|
|
|
Describe("It can differentiate between multipath-disks and other device-mapper devices", func() {
|
|
It("Identifies only multipath devices", func() {
|
|
// Create multipath device
|
|
multipathDeviceDef := types.Disk{
|
|
Name: "dm-0",
|
|
UUID: "mpath-uuid-123",
|
|
SizeBytes: 10 * 1024 * 1024,
|
|
Partitions: []*types.Partition{
|
|
{
|
|
Name: "dm-1",
|
|
FilesystemLabel: "MPATH_BOOT",
|
|
FS: "ext4",
|
|
MountPoint: "/boot",
|
|
Size: 512,
|
|
UUID: "part1-mpath-uuid-456",
|
|
},
|
|
},
|
|
}
|
|
|
|
// Create a device-mapper device that is not multipath
|
|
cryptsDisk := types.Disk{
|
|
Name: "dm-2",
|
|
UUID: "CRYPT-LUKS1-fdsfsdfsdgxv-luks-34214546534dfd",
|
|
SizeBytes: 8 * 1024 * 1024,
|
|
Partitions: []*types.Partition{
|
|
{
|
|
Name: "dm-3",
|
|
FilesystemLabel: "REGULAR_ROOT",
|
|
FS: "ext4",
|
|
MountPoint: "/",
|
|
Size: 2048,
|
|
UUID: "part1-CRYPT-LUKS1-fdsfsdfsdgxv-luks-34214546534dfd",
|
|
},
|
|
},
|
|
}
|
|
|
|
// Add both disks
|
|
ghwMock.AddDisk(multipathDeviceDef)
|
|
ghwMock.AddDisk(cryptsDisk)
|
|
|
|
// Create multipath structure (this will handle both disks appropriately)
|
|
ghwMock.CreateMultipathDevices()
|
|
|
|
disks := ghw.GetDisks(ghw.NewPaths(ghwMock.Chroot), nil)
|
|
|
|
// The LUKS device is identified as a regular disk, so we have 3 disks in total.
|
|
// This is because the LUKS device is not skipped like multipath partitions are and currently will not work
|
|
// with Kairos.
|
|
Expect(len(disks)).To(Equal(3))
|
|
|
|
// Make sure we can identify the multipath device
|
|
var foundMultipathDisk *types.Disk
|
|
for _, disk := range disks {
|
|
if disk.Name == "dm-0" {
|
|
foundMultipathDisk = disk
|
|
}
|
|
}
|
|
|
|
Expect(foundMultipathDisk).ToNot(BeNil())
|
|
|
|
// Verify multipath device has its partition
|
|
Expect(len(foundMultipathDisk.Partitions)).To(Equal(1))
|
|
Expect(foundMultipathDisk.Partitions[0].Name).To(Equal("dm-1"))
|
|
})
|
|
})
|
|
|
|
})
|