debian-forge-composer/internal/disk/disk_test.go
Achilleas Koutsou c347373c90 disk: basic partition table creation tests
Add a few test partition tables with well known configurations, like
LVM, LVM on top of LVM and Btrfs in addition to the plain layout that
is currently used in most partition tables. Add very basic checks,
such as that `NewPartitionTable` works and we have approximately the
correct size.

Co-Authored-By: Christian Kellner <christian@kellner.me>
2022-02-22 19:23:41 +00:00

371 lines
8.4 KiB
Go

package disk
import (
"math/rand"
"testing"
"github.com/osbuild/osbuild-composer/internal/blueprint"
"github.com/stretchr/testify/assert"
)
func TestDisk_AlignUp(t *testing.T) {
pt := PartitionTable{}
firstAligned := DefaultGrainBytes
tests := []struct {
size uint64
want uint64
}{
{0, 0},
{1, firstAligned},
{firstAligned - 1, firstAligned},
{firstAligned, firstAligned}, // grain is already aligned => no change
{firstAligned / 2, firstAligned},
{firstAligned + 1, firstAligned * 2},
}
for _, tt := range tests {
got := pt.AlignUp(tt.size)
assert.Equal(t, tt.want, got, "Expected %d, got %d", tt.want, got)
}
}
func TestDisk_DynamicallyResizePartitionTable(t *testing.T) {
mountpoints := []blueprint.FilesystemCustomization{
{
MinSize: 2147483648,
Mountpoint: "/usr",
},
}
pt := PartitionTable{
UUID: "D209C89E-EA5E-4FBD-B161-B461CCE297E0",
Type: "gpt",
Partitions: []Partition{
{
Size: 2048,
Bootable: true,
Type: BIOSBootPartitionGUID,
UUID: BIOSBootPartitionUUID,
},
{
Type: FilesystemDataGUID,
UUID: RootPartitionUUID,
Payload: &Filesystem{
Type: "xfs",
Label: "root",
Mountpoint: "/",
FSTabOptions: "defaults",
FSTabFreq: 0,
FSTabPassNo: 0,
},
},
},
}
var expectedSize uint64 = 2147483648
// math/rand is good enough in this case
/* #nosec G404 */
rng := rand.New(rand.NewSource(0))
newpt, err := NewPartitionTable(&pt, mountpoints, 1024, rng)
assert.NoError(t, err)
assert.GreaterOrEqual(t, newpt.Size, expectedSize)
}
var testPartitionTables = map[string]PartitionTable{
"plain": {
UUID: "D209C89E-EA5E-4FBD-B161-B461CCE297E0",
Type: "gpt",
Partitions: []Partition{
{
Size: 1048576, // 1MB
Bootable: true,
Type: BIOSBootPartitionGUID,
UUID: BIOSBootPartitionUUID,
},
{
Size: 209715200, // 200 MB
Type: EFISystemPartitionGUID,
UUID: EFISystemPartitionUUID,
Payload: &Filesystem{
Type: "vfat",
UUID: EFIFilesystemUUID,
Mountpoint: "/boot/efi",
Label: "EFI-SYSTEM",
FSTabOptions: "defaults,uid=0,gid=0,umask=077,shortname=winnt",
FSTabFreq: 0,
FSTabPassNo: 2,
},
},
{
Size: 1024000, // 500 MB
Type: FilesystemDataGUID,
UUID: FilesystemDataUUID,
Payload: &Filesystem{
Type: "xfs",
Mountpoint: "/boot",
Label: "boot",
FSTabOptions: "defaults",
FSTabFreq: 0,
FSTabPassNo: 0,
},
},
{
Type: FilesystemDataGUID,
UUID: RootPartitionUUID,
Payload: &Filesystem{
Type: "xfs",
Label: "root",
Mountpoint: "/",
FSTabOptions: "defaults",
FSTabFreq: 0,
FSTabPassNo: 0,
},
},
},
},
"luks": {
UUID: "D209C89E-EA5E-4FBD-B161-B461CCE297E0",
Type: "gpt",
Partitions: []Partition{
{
Size: 1048576, // 1MB
Bootable: true,
Type: BIOSBootPartitionGUID,
UUID: BIOSBootPartitionUUID,
},
{
Size: 209715200, // 200 MB
Type: EFISystemPartitionGUID,
UUID: EFISystemPartitionUUID,
Payload: &Filesystem{
Type: "vfat",
UUID: EFIFilesystemUUID,
Mountpoint: "/boot/efi",
Label: "EFI-SYSTEM",
FSTabOptions: "defaults,uid=0,gid=0,umask=077,shortname=winnt",
FSTabFreq: 0,
FSTabPassNo: 2,
},
},
{
Size: 1024000, // 500 MB
Type: FilesystemDataGUID,
UUID: FilesystemDataUUID,
Payload: &Filesystem{
Type: "xfs",
Mountpoint: "/boot",
Label: "boot",
FSTabOptions: "defaults",
FSTabFreq: 0,
FSTabPassNo: 0,
},
},
{
Type: FilesystemDataGUID,
UUID: RootPartitionUUID,
Payload: &LUKSContainer{
UUID: "",
Label: "crypt_root",
Payload: &Filesystem{
Type: "xfs",
Label: "root",
Mountpoint: "/",
FSTabOptions: "defaults",
FSTabFreq: 0,
FSTabPassNo: 0,
},
},
},
},
},
"luks+lvm": {
UUID: "D209C89E-EA5E-4FBD-B161-B461CCE297E0",
Type: "gpt",
Partitions: []Partition{
{
Size: 1048576, // 1MB
Bootable: true,
Type: BIOSBootPartitionGUID,
UUID: BIOSBootPartitionUUID,
},
{
Size: 209715200, // 200 MB
Type: EFISystemPartitionGUID,
UUID: EFISystemPartitionUUID,
Payload: &Filesystem{
Type: "vfat",
UUID: EFIFilesystemUUID,
Mountpoint: "/boot/efi",
Label: "EFI-SYSTEM",
FSTabOptions: "defaults,uid=0,gid=0,umask=077,shortname=winnt",
FSTabFreq: 0,
FSTabPassNo: 2,
},
},
{
Size: 1024000, // 500 MB
Type: FilesystemDataGUID,
UUID: FilesystemDataUUID,
Payload: &Filesystem{
Type: "xfs",
Mountpoint: "/boot",
Label: "boot",
FSTabOptions: "defaults",
FSTabFreq: 0,
FSTabPassNo: 0,
},
},
{
Type: FilesystemDataGUID,
UUID: RootPartitionUUID,
Size: 5 * 1024 * 1024 * 1024,
Payload: &LUKSContainer{
UUID: "",
Payload: &LVMVolumeGroup{
Name: "",
Description: "",
LogicalVolumes: []LVMLogicalVolume{
{
Size: 2 * 1024 * 1024 * 1024,
Payload: &Filesystem{
Type: "xfs",
Label: "root",
Mountpoint: "/",
FSTabOptions: "defaults",
FSTabFreq: 0,
FSTabPassNo: 0,
},
},
{
Size: 2 * 1024 * 1024 * 1024,
Payload: &Filesystem{
Type: "xfs",
Label: "root",
Mountpoint: "/home",
FSTabOptions: "defaults",
FSTabFreq: 0,
FSTabPassNo: 0,
},
},
},
},
},
},
},
},
"btrfs": {
UUID: "D209C89E-EA5E-4FBD-B161-B461CCE297E0",
Type: "gpt",
Partitions: []Partition{
{
Size: 1048576, // 1MB
Bootable: true,
Type: BIOSBootPartitionGUID,
UUID: BIOSBootPartitionUUID,
},
{
Size: 209715200, // 200 MB
Type: EFISystemPartitionGUID,
UUID: EFISystemPartitionUUID,
Payload: &Filesystem{
Type: "vfat",
UUID: EFIFilesystemUUID,
Mountpoint: "/boot/efi",
Label: "EFI-SYSTEM",
FSTabOptions: "defaults,uid=0,gid=0,umask=077,shortname=winnt",
FSTabFreq: 0,
FSTabPassNo: 2,
},
},
{
Size: 1024000, // 500 MB
Type: FilesystemDataGUID,
UUID: FilesystemDataUUID,
Payload: &Filesystem{
Type: "xfs",
Mountpoint: "/boot",
Label: "boot",
FSTabOptions: "defaults",
FSTabFreq: 0,
FSTabPassNo: 0,
},
},
{
Type: FilesystemDataGUID,
UUID: RootPartitionUUID,
Size: 10 * 1024 * 1024 * 1024,
Payload: &Btrfs{
UUID: "",
Label: "",
Mountpoint: "",
Subvolumes: []BtrfsSubvolume{
{
Size: 0,
Mountpoint: "/",
GroupID: 0,
},
{
Size: 5 * 1024 * 1024 * 1024,
Mountpoint: "/var",
GroupID: 0,
},
},
},
},
},
},
}
var bp = []blueprint.FilesystemCustomization{
{
Mountpoint: "/",
MinSize: 10 * 1024 * 1024 * 1024,
},
{
Mountpoint: "/home",
MinSize: 20 * 1024 * 1024 * 1024,
},
{
Mountpoint: "/opt",
MinSize: 7 * 1024 * 1024 * 1024,
},
}
func TestDisk_ForEachEntity(t *testing.T) {
count := 0
plain := testPartitionTables["plain"]
err := plain.ForEachEntity(func(e Entity, path []Entity) error {
assert.NotNil(t, e)
assert.NotNil(t, path)
count += 1
return nil
})
assert.NoError(t, err)
// PartitionTable, 4 partitions, 3 filesystems -> 8 entities
assert.Equal(t, 8, count)
}
func TestCreatePartitionTable(t *testing.T) {
assert := assert.New(t)
// math/rand is good enough in this case
/* #nosec G404 */
rng := rand.New(rand.NewSource(13))
for name := range testPartitionTables {
pt := testPartitionTables[name]
mpt, err := NewPartitionTable(&pt, bp, uint64(13*1024*1024), rng)
assert.NoError(err, "Partition table generation failed: %s (%s)", name, err)
assert.NotNil(mpt, "Partition table generation failed: %s (nil partition table)", name)
assert.Greater(mpt.GetSize(), uint64(37*1024*1024*1024))
assert.NotNil(mpt.Type, "Partition table generation failed: %s (nil partition table type)", name)
mnt := pt.FindMountable("/")
assert.NotNil(mnt, "Partition table '%s': failed to find root mountable", name)
}
}