mirror of
https://github.com/kairos-io/immucore.git
synced 2025-09-18 08:06:44 +00:00
Add tests and fix some issues that arised from testing (#74)
* Add tests and fix some issues that arised from testing Mainly around the cmdargs and how many items it returns. Also drop the iso target and jobs as its not necessary now Signed-off-by: Itxaka <itxaka.garcia@spectrocloud.com> * Lint Signed-off-by: Itxaka <itxaka.garcia@spectrocloud.com> --------- Signed-off-by: Itxaka <itxaka.garcia@spectrocloud.com>
This commit is contained in:
173
tests/mocks/ghw_mock.go
Normal file
173
tests/mocks/ghw_mock.go
Normal file
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
Copyright © 2022 SUSE LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package mocks
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/jaypipes/ghw/pkg/block"
|
||||
"github.com/jaypipes/ghw/pkg/context"
|
||||
"github.com/jaypipes/ghw/pkg/linuxpath"
|
||||
)
|
||||
|
||||
// GhwMock is used to construct a fake disk to present to ghw when scanning block devices
|
||||
// The way this works is ghw will use the existing files in the system to determine the different disks, partitions and
|
||||
// mountpoints. It uses /sys/block, /proc/self/mounts and /run/udev/data to gather everything
|
||||
// It also has an entrypoint to overwrite the root dir from which the paths are constructed so that allows us to override
|
||||
// it easily and make it read from a different location.
|
||||
// This mock is used to construct a fake FS with all its needed files on a different chroot and just add a Disk with its
|
||||
// partitions and let the struct do its thing creating files and mountpoints and such
|
||||
// You can even just pass no disks to simulate a system in which there is no disk/no cos partitions.
|
||||
type GhwMock struct {
|
||||
chroot string
|
||||
paths *linuxpath.Paths
|
||||
disks []block.Disk
|
||||
mounts []string
|
||||
}
|
||||
|
||||
// AddDisk adds a disk to GhwMock.
|
||||
func (g *GhwMock) AddDisk(disk block.Disk) {
|
||||
g.disks = append(g.disks, disk)
|
||||
}
|
||||
|
||||
// AddPartitionToDisk will add a partition to the given disk and call Clean+CreateDevices, so we recreate all files
|
||||
// It makes no effort checking if the disk exists.
|
||||
func (g *GhwMock) AddPartitionToDisk(diskName string, partition *block.Partition) {
|
||||
for _, disk := range g.disks {
|
||||
if disk.Name == diskName {
|
||||
disk.Partitions = append(disk.Partitions, partition)
|
||||
g.Clean()
|
||||
g.CreateDevices()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// CreateDevices will create a new context and paths for ghw using the Chroot value as base, then set the env var GHW_ROOT so the
|
||||
// ghw library picks that up and then iterate over the disks and partitions and create the necessary files.
|
||||
func (g *GhwMock) CreateDevices() {
|
||||
d, _ := os.MkdirTemp("", "ghwmock")
|
||||
g.chroot = d
|
||||
ctx := context.New()
|
||||
ctx.Chroot = d
|
||||
g.paths = linuxpath.New(ctx)
|
||||
_ = os.Setenv("GHW_CHROOT", g.chroot)
|
||||
// Create the /sys/block dir
|
||||
_ = os.MkdirAll(g.paths.SysBlock, 0755)
|
||||
// Create the /run/udev/data dir
|
||||
_ = os.MkdirAll(g.paths.RunUdevData, 0755)
|
||||
// Create only the /proc/self dir, we add the mounts file afterwards
|
||||
procDir, _ := filepath.Split(g.paths.ProcMounts)
|
||||
_ = os.MkdirAll(procDir, 0755)
|
||||
|
||||
for indexDisk, disk := range g.disks {
|
||||
// For each dir we create the /sys/block/DISK_NAME
|
||||
diskPath := filepath.Join(g.paths.SysBlock, disk.Name)
|
||||
_ = os.Mkdir(diskPath, 0755)
|
||||
for indexPart, partition := range disk.Partitions {
|
||||
// For each partition we create the /sys/block/DISK_NAME/PARTITION_NAME
|
||||
_ = os.Mkdir(filepath.Join(diskPath, partition.Name), 0755)
|
||||
// Create the /sys/block/DISK_NAME/PARTITION_NAME/dev file which contains the major:minor of the partition
|
||||
_ = os.WriteFile(filepath.Join(diskPath, partition.Name, "dev"), []byte(fmt.Sprintf("%d:6%d\n", indexDisk, indexPart)), 0644)
|
||||
// Create the /run/udev/data/bMAJOR:MINOR file with the data inside to mimic the udev database
|
||||
data := []string{fmt.Sprintf("E:ID_FS_LABEL=%s\n", partition.Label)}
|
||||
if partition.Type != "" {
|
||||
data = append(data, fmt.Sprintf("E:ID_FS_TYPE=%s\n", partition.Type))
|
||||
}
|
||||
_ = os.WriteFile(filepath.Join(g.paths.RunUdevData, fmt.Sprintf("b%d:6%d", indexDisk, indexPart)), []byte(strings.Join(data, "")), 0644)
|
||||
// If we got a mountpoint, add it to our fake /proc/self/mounts
|
||||
if partition.MountPoint != "" {
|
||||
// Check if the partition has a fs, otherwise default to ext4
|
||||
if partition.Type == "" {
|
||||
partition.Type = "ext4"
|
||||
}
|
||||
// Prepare the g.mounts with all the mount lines
|
||||
g.mounts = append(
|
||||
g.mounts,
|
||||
fmt.Sprintf("%s %s %s ro,relatime 0 0\n", filepath.Join("/dev", partition.Name), partition.MountPoint, partition.Type))
|
||||
}
|
||||
}
|
||||
}
|
||||
// Finally, write all the mounts
|
||||
_ = os.WriteFile(g.paths.ProcMounts, []byte(strings.Join(g.mounts, "")), 0644)
|
||||
}
|
||||
|
||||
// RemoveDisk will remove the files for a disk. It makes no effort to check if the disk exists or not.
|
||||
func (g *GhwMock) RemoveDisk(disk string) {
|
||||
// This could be simpler I think, just removing the /sys/block/DEVICE should make ghw not find anything and not search
|
||||
// for partitions, but just in case do it properly
|
||||
var newMounts []string
|
||||
diskPath := filepath.Join(g.paths.SysBlock, disk)
|
||||
_ = os.RemoveAll(diskPath)
|
||||
|
||||
// Try to find any mounts that match the disk given and remove them from the mounts
|
||||
for _, mount := range g.mounts {
|
||||
fields := strings.Fields(mount)
|
||||
// If first field does not contain the /dev/DEVICE, add it to the newmounts
|
||||
if !strings.Contains(fields[0], filepath.Join("/dev", disk)) {
|
||||
newMounts = append(newMounts, mount)
|
||||
}
|
||||
}
|
||||
g.mounts = newMounts
|
||||
// Write the mounts again
|
||||
_ = os.WriteFile(g.paths.ProcMounts, []byte(strings.Join(g.mounts, "")), 0644)
|
||||
}
|
||||
|
||||
// RemovePartitionFromDisk will remove the files for a partition
|
||||
// It makes no effort checking if the disk/partition/files exist.
|
||||
func (g *GhwMock) RemovePartitionFromDisk(diskName string, partitionName string) {
|
||||
var newMounts []string
|
||||
diskPath := filepath.Join(g.paths.SysBlock, diskName)
|
||||
// Read the dev major:minor
|
||||
devName, _ := os.ReadFile(filepath.Join(diskPath, partitionName, "dev"))
|
||||
// Remove the MAJOR:MINOR file from the udev database
|
||||
_ = os.RemoveAll(filepath.Join(g.paths.RunUdevData, fmt.Sprintf("b%s", devName)))
|
||||
// Remove the /sys/block/DISK/PARTITION dir
|
||||
_ = os.RemoveAll(filepath.Join(diskPath, partitionName))
|
||||
|
||||
// Try to find any mounts that match the partition given and remove them from the mounts
|
||||
for _, mount := range g.mounts {
|
||||
fields := strings.Fields(mount)
|
||||
// If first field does not contain the /dev/PARTITION, add it to the newmounts
|
||||
if !strings.Contains(fields[0], filepath.Join("/dev", partitionName)) {
|
||||
newMounts = append(newMounts, mount)
|
||||
}
|
||||
}
|
||||
g.mounts = newMounts
|
||||
// Write the mounts again
|
||||
_ = os.WriteFile(g.paths.ProcMounts, []byte(strings.Join(g.mounts, "")), 0644)
|
||||
// Remove it from the partitions list
|
||||
for index, disk := range g.disks {
|
||||
if disk.Name == diskName {
|
||||
var newPartitions []*block.Partition
|
||||
for _, partition := range disk.Partitions {
|
||||
if partition.Name != partitionName {
|
||||
newPartitions = append(newPartitions, partition)
|
||||
}
|
||||
}
|
||||
g.disks[index].Partitions = newPartitions
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clean will remove the chroot dir and unset the env var.
|
||||
func (g *GhwMock) Clean() {
|
||||
_ = os.Unsetenv("GHW_CHROOT")
|
||||
_ = os.RemoveAll(g.chroot)
|
||||
}
|
117
tests/state_test.go
Normal file
117
tests/state_test.go
Normal file
@@ -0,0 +1,117 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/kairos-io/immucore/pkg/mount"
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/spectrocloud-labs/herd"
|
||||
)
|
||||
|
||||
var _ = Describe("mounting immutable setup", func() {
|
||||
var g *herd.Graph
|
||||
|
||||
BeforeEach(func() {
|
||||
g = herd.DAG(herd.EnableInit)
|
||||
Expect(g).ToNot(BeNil())
|
||||
})
|
||||
|
||||
Context("simple invocation", func() {
|
||||
It("generates normal dag", func() {
|
||||
s := &mount.State{
|
||||
Rootdir: "/",
|
||||
TargetImage: "/cOS/myimage.img",
|
||||
TargetDevice: "/dev/disk/by-label/COS_LABEL",
|
||||
}
|
||||
|
||||
err := s.RegisterNormalBoot(g)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
dag := g.Analyze()
|
||||
|
||||
checkDag(dag, s.WriteDAG(g))
|
||||
|
||||
})
|
||||
It("generates normal dag with extra dirs", func() {
|
||||
s := &mount.State{Rootdir: "/",
|
||||
OverlayDirs: []string{"/etc"},
|
||||
BindMounts: []string{"/etc/kubernetes"},
|
||||
CustomMounts: map[string]string{"COS_PERSISTENT": "/usr/local"}}
|
||||
|
||||
err := s.RegisterNormalBoot(g)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
dag := g.Analyze()
|
||||
|
||||
checkDag(dag, s.WriteDAG(g))
|
||||
})
|
||||
It("generates livecd dag", func() {
|
||||
s := &mount.State{}
|
||||
err := s.RegisterLiveMedia(g)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
dag := g.Analyze()
|
||||
checkLiveCDDag(dag, s.WriteDAG(g))
|
||||
|
||||
})
|
||||
|
||||
It("Mountop timeouts", func() {
|
||||
s := &mount.State{}
|
||||
f := s.MountOP("/dev/doesntexist", "/tmp/jojobizarreadventure", "", []string{}, 500*time.Millisecond)
|
||||
err := f(context.Background())
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err.Error()).To(ContainSubstring("exhausted"))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
func checkLiveCDDag(dag [][]herd.GraphEntry, actualDag string) {
|
||||
Expect(len(dag)).To(Equal(2), actualDag)
|
||||
Expect(len(dag[0])).To(Equal(1), actualDag)
|
||||
Expect(len(dag[1])).To(Equal(1), actualDag)
|
||||
|
||||
Expect(dag[0][0].Name).To(Equal("init"))
|
||||
Expect(dag[1][0].Name).To(Equal("create-sentinel"))
|
||||
|
||||
}
|
||||
func checkDag(dag [][]herd.GraphEntry, actualDag string) {
|
||||
Expect(len(dag)).To(Equal(10), actualDag)
|
||||
Expect(len(dag[0])).To(Equal(1), actualDag)
|
||||
Expect(len(dag[1])).To(Equal(3), actualDag)
|
||||
Expect(len(dag[2])).To(Equal(1), actualDag)
|
||||
Expect(len(dag[3])).To(Equal(1), actualDag)
|
||||
Expect(len(dag[4])).To(Equal(1), actualDag)
|
||||
Expect(len(dag[5])).To(Equal(1), actualDag)
|
||||
Expect(len(dag[6])).To(Equal(1), actualDag)
|
||||
Expect(len(dag[7])).To(Equal(2), actualDag)
|
||||
Expect(len(dag[8])).To(Equal(2), actualDag)
|
||||
Expect(len(dag[9])).To(Equal(1), actualDag)
|
||||
|
||||
Expect(dag[0][0].Name).To(Equal("init"))
|
||||
Expect(dag[1][0].Name).To(Or(
|
||||
Equal("mount-tmpfs"),
|
||||
Equal("create-sentinel"),
|
||||
Equal("mount-state"),
|
||||
), actualDag)
|
||||
Expect(dag[1][1].Name).To(Or(
|
||||
Equal("mount-tmpfs"),
|
||||
Equal("create-sentinel"),
|
||||
Equal("mount-state"),
|
||||
), actualDag)
|
||||
Expect(dag[1][2].Name).To(Or(
|
||||
Equal("mount-tmpfs"),
|
||||
Equal("create-sentinel"),
|
||||
Equal("mount-state"),
|
||||
), actualDag)
|
||||
Expect(dag[2][0].Name).To(Equal("discover-state"), actualDag)
|
||||
Expect(dag[3][0].Name).To(Equal("mount-root"), actualDag)
|
||||
Expect(dag[4][0].Name).To(Equal("mount-oem"), actualDag)
|
||||
Expect(dag[5][0].Name).To(Equal("rootfs-hook"), actualDag)
|
||||
Expect(dag[6][0].Name).To(Equal("load-config"), actualDag)
|
||||
Expect(dag[7][0].Name).To(Or(Equal("mount-base-overlay"), Equal("custom-mount")), actualDag)
|
||||
Expect(dag[7][1].Name).To(Or(Equal("mount-base-overlay"), Equal("custom-mount")), actualDag)
|
||||
Expect(dag[8][0].Name).To(Or(Equal("mount-bind"), Equal("overlay-mount")), actualDag)
|
||||
Expect(dag[8][1].Name).To(Or(Equal("mount-bind"), Equal("overlay-mount")), actualDag)
|
||||
Expect(dag[9][0].Name).To(Equal("write-fstab"), actualDag)
|
||||
}
|
13
tests/suite_test.go
Normal file
13
tests/suite_test.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
func TestSuite(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecs(t, "Test Suite")
|
||||
}
|
351
tests/utils_test.go
Normal file
351
tests/utils_test.go
Normal file
@@ -0,0 +1,351 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"github.com/containerd/containerd/mount"
|
||||
"github.com/jaypipes/ghw/pkg/block"
|
||||
"github.com/kairos-io/immucore/internal/utils"
|
||||
"github.com/kairos-io/immucore/tests/mocks"
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/twpayne/go-vfs"
|
||||
"github.com/twpayne/go-vfs/vfst"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
var _ = Describe("mount utils", func() {
|
||||
var fs vfs.FS
|
||||
var cleanup func()
|
||||
|
||||
BeforeEach(func() {
|
||||
fs, cleanup, _ = vfst.NewTestFS(map[string]interface{}{
|
||||
"/proc/cmdline": "",
|
||||
})
|
||||
_, err := fs.Stat("/proc/cmdline")
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
fakeCmdline, _ := fs.RawPath("/proc/cmdline")
|
||||
err = os.Setenv("HOST_PROC_CMDLINE", fakeCmdline)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
})
|
||||
AfterEach(func() {
|
||||
cleanup()
|
||||
})
|
||||
|
||||
Context("ReadCMDLineArg", func() {
|
||||
BeforeEach(func() {
|
||||
err := fs.WriteFile("/proc/cmdline", []byte("test/key=value1 rd.immucore.debug rd.immucore.uki rd.cos.oemlabel=FAKE_LABEL empty=\n"), os.ModePerm)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
})
|
||||
It("splits arguments from cmdline", func() {
|
||||
value := utils.ReadCMDLineArg("test/key=")
|
||||
Expect(len(value)).To(Equal(1))
|
||||
Expect(value[0]).To(Equal("value1"))
|
||||
value = utils.ReadCMDLineArg("rd.cos.oemlabel=")
|
||||
Expect(len(value)).To(Equal(1))
|
||||
Expect(value[0]).To(Equal("FAKE_LABEL"))
|
||||
// This is mostly wrong, it should return and empty value, not a []string of 1 empty value
|
||||
// Requires refactoring
|
||||
value = utils.ReadCMDLineArg("empty=")
|
||||
Expect(len(value)).To(Equal(1))
|
||||
Expect(value[0]).To(Equal(""))
|
||||
|
||||
})
|
||||
It("returns properly for stanzas without value", func() {
|
||||
Expect(len(utils.ReadCMDLineArg("rd.immucore.debug"))).To(Equal(1))
|
||||
Expect(len(utils.ReadCMDLineArg("rd.immucore.uki"))).To(Equal(1))
|
||||
})
|
||||
})
|
||||
Context("GetRootDir", func() {
|
||||
It("Returns / for uki", func() {
|
||||
err := fs.WriteFile("/proc/cmdline", []byte("rd.immucore.uki"), os.ModePerm)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(utils.GetRootDir()).To(Equal("/"))
|
||||
})
|
||||
It("Returns /sysroot", func() {
|
||||
Expect(utils.GetRootDir()).To(Equal("/sysroot"))
|
||||
})
|
||||
})
|
||||
Context("UniqueSlice", func() {
|
||||
It("Removes duplicates", func() {
|
||||
dups := []string{"a", "b", "c", "d", "b", "a"}
|
||||
dupsRemoved := utils.UniqueSlice(dups)
|
||||
Expect(len(dupsRemoved)).To(Equal(4))
|
||||
})
|
||||
})
|
||||
Context("ReadEnv", func() {
|
||||
It("Parses correctly an env file", func() {
|
||||
tmpDir, err := os.MkdirTemp("", "")
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
defer os.RemoveAll(tmpDir)
|
||||
err = os.WriteFile(filepath.Join(tmpDir, "layout.env"), []byte("OVERLAY=\"tmpfs:25%\"\nPERSISTENT_STATE_BIND=\"true\"\nPERSISTENT_STATE_PATHS=\"/home /opt /root\"\nRW_PATHS=\"/var /etc /srv\"\nVOLUMES=\"LABEL=COS_OEM:/oem LABEL=COS_PERSISTENT:/usr/local\""), os.ModePerm)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
env, err := utils.ReadEnv(filepath.Join(tmpDir, "layout.env"))
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(env).To(HaveKey("OVERLAY"))
|
||||
Expect(env).To(HaveKey("PERSISTENT_STATE_BIND"))
|
||||
Expect(env).To(HaveKey("PERSISTENT_STATE_PATHS"))
|
||||
Expect(env).To(HaveKey("RW_PATHS"))
|
||||
Expect(env).To(HaveKey("VOLUMES"))
|
||||
Expect(env["OVERLAY"]).To(Equal("tmpfs:25%"))
|
||||
Expect(env["PERSISTENT_STATE_BIND"]).To(Equal("true"))
|
||||
Expect(env["PERSISTENT_STATE_PATHS"]).To(Equal("/home /opt /root"))
|
||||
Expect(env["RW_PATHS"]).To(Equal("/var /etc /srv"))
|
||||
Expect(env["VOLUMES"]).To(Equal("LABEL=COS_OEM:/oem LABEL=COS_PERSISTENT:/usr/local"))
|
||||
})
|
||||
})
|
||||
Context("CleanupSlice", func() {
|
||||
It("Cleans up the slice of empty values", func() {
|
||||
slice := []string{"", " "}
|
||||
sliceCleaned := utils.CleanupSlice(slice)
|
||||
Expect(len(sliceCleaned)).To(Equal(0))
|
||||
})
|
||||
})
|
||||
Context("GetTarget", func() {
|
||||
It("Returns a fake target if called with dry run", func() {
|
||||
target, label, err := utils.GetTarget(true)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(target).To(Equal("fake"))
|
||||
// We cant manipulate runtime, so it will return an empty label as it cant identify where are we
|
||||
Expect(label).To(Equal(""))
|
||||
})
|
||||
It("Returns a fake target if immucore is disabled", func() {
|
||||
err := fs.WriteFile("/proc/cmdline", []byte("rd.immucore.disabled\n"), os.ModePerm)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
target, label, err := utils.GetTarget(false)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(target).To(Equal("fake"))
|
||||
// We cant manipulate runtime, so it will return an empty label as it cant identify where are we
|
||||
Expect(label).To(Equal(""))
|
||||
})
|
||||
It("Returns the proper target from cmdline", func() {
|
||||
err := fs.WriteFile("/proc/cmdline", []byte("cos-img/filename=active.img\n"), os.ModePerm)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
target, label, err := utils.GetTarget(false)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(target).To(Equal("active.img"))
|
||||
// We cant manipulate runtime, so it will return an empty label as it cant identify where are we
|
||||
Expect(label).To(Equal(""))
|
||||
})
|
||||
It("Returns an empty target if we are on UKI", func() {
|
||||
err := fs.WriteFile("/proc/cmdline", []byte("rd.immucore.uki\n"), os.ModePerm)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
target, label, err := utils.GetTarget(false)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(target).To(Equal(""))
|
||||
// We cant manipulate runtime, so it will return an empty label as it cant identify where are we
|
||||
Expect(label).To(Equal(""))
|
||||
})
|
||||
It("Returns an error if we dont have the target in the cmdline", func() {
|
||||
target, label, err := utils.GetTarget(false)
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(target).To(Equal(""))
|
||||
Expect(label).To(Equal(""))
|
||||
})
|
||||
})
|
||||
Context("DisableImmucore", func() {
|
||||
It("Disables immucore if cmdline contains live:LABEL", func() {
|
||||
err := fs.WriteFile("/proc/cmdline", []byte("root=live:LABEL=COS_LIVE\n"), os.ModePerm)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(utils.DisableImmucore()).To(BeTrue())
|
||||
})
|
||||
It("Disables immucore if cmdline contains live:CDLABEL", func() {
|
||||
err := fs.WriteFile("/proc/cmdline", []byte("root=live:CDLABEL=COS_LIVE\n"), os.ModePerm)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(utils.DisableImmucore()).To(BeTrue())
|
||||
})
|
||||
It("Disables immucore if cmdline contains netboot", func() {
|
||||
err := fs.WriteFile("/proc/cmdline", []byte("netboot\n"), os.ModePerm)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(utils.DisableImmucore()).To(BeTrue())
|
||||
})
|
||||
It("Disables immucore if cmdline contains rd.cos.disable", func() {
|
||||
err := fs.WriteFile("/proc/cmdline", []byte("rd.cos.disable\n"), os.ModePerm)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(utils.DisableImmucore()).To(BeTrue())
|
||||
})
|
||||
It("Disables immucore if cmdline contains rd.immucore.disable", func() {
|
||||
err := fs.WriteFile("/proc/cmdline", []byte("rd.immucore.disable\n"), os.ModePerm)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(utils.DisableImmucore()).To(BeTrue())
|
||||
})
|
||||
It("Enables immucore by default", func() {
|
||||
Expect(utils.DisableImmucore()).To(BeFalse())
|
||||
})
|
||||
})
|
||||
Context("RootRW", func() {
|
||||
It("Defaults to RO", func() {
|
||||
Expect(utils.RootRW()).To(Equal("ro"))
|
||||
})
|
||||
It("Sets RW if set via cmdline with rd.cos.debugrw", func() {
|
||||
err := fs.WriteFile("/proc/cmdline", []byte("rd.cos.debugrw\n"), os.ModePerm)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(utils.RootRW()).To(Equal("rw"))
|
||||
})
|
||||
It("Sets RW if set via cmdline with rd.immucore.debugrw", func() {
|
||||
err := fs.WriteFile("/proc/cmdline", []byte("rd.immucore.debugrw\n"), os.ModePerm)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(utils.RootRW()).To(Equal("rw"))
|
||||
})
|
||||
It("Sets RW if set via cmdline with both rd.cos.debugrw and rd.immucore.debugrw at the same time", func() {
|
||||
err := fs.WriteFile("/proc/cmdline", []byte("rd.cos.debugrw rd.immucore.debugrw\n"), os.ModePerm)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(utils.RootRW()).To(Equal("rw"))
|
||||
})
|
||||
})
|
||||
Context("IsUKI", func() {
|
||||
It("Returns false in a normal boot", func() {
|
||||
Expect(utils.IsUKI()).To(BeFalse())
|
||||
})
|
||||
It("Returns true if set via cmdline with rd.immucore.uki", func() {
|
||||
err := fs.WriteFile("/proc/cmdline", []byte("rd.immucore.uki\n"), os.ModePerm)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(utils.IsUKI()).To(BeTrue())
|
||||
})
|
||||
})
|
||||
Context("ParseMount", func() {
|
||||
It("Returns disk path by LABEL", func() {
|
||||
Expect(utils.ParseMount("LABEL=MY_LABEL")).To(Equal("/dev/disk/by-label/MY_LABEL"))
|
||||
})
|
||||
It("Returns disk path by UUID", func() {
|
||||
Expect(utils.ParseMount("UUID=9999")).To(Equal("/dev/disk/by-uuid/9999"))
|
||||
})
|
||||
})
|
||||
Context("AppendSlash", func() {
|
||||
It("Appends a slash if it doesnt have one", func() {
|
||||
noSlash := "/noslash"
|
||||
Expect(utils.AppendSlash(noSlash)).To(Equal("/noslash/"))
|
||||
})
|
||||
It("Does not append a slash if it already has one", func() {
|
||||
slash := "/yesslash/"
|
||||
Expect(utils.AppendSlash(slash)).To(Equal("/yesslash/"))
|
||||
})
|
||||
})
|
||||
Context("MountToFstab", func() {
|
||||
It("Generates teh proper fstab config", func() {
|
||||
m := mount.Mount{
|
||||
Type: "fakefs",
|
||||
Source: "/dev/fake",
|
||||
Options: []string{"option1", "option=2"},
|
||||
}
|
||||
fstab := utils.MountToFstab(m)
|
||||
fstab.File = "/mnt/fake"
|
||||
// Options can be shown in whatever order, so regexp that
|
||||
Expect(fstab.String()).To(MatchRegexp("/dev/fake /mnt/fake fakefs (option1|option=2),(option=2|option1) 0 0"))
|
||||
Expect(fstab.Spec).To(Equal("/dev/fake"))
|
||||
Expect(fstab.VfsType).To(Equal("fakefs"))
|
||||
Expect(fstab.MntOps).To(HaveKey("option1"))
|
||||
Expect(fstab.MntOps).To(HaveKey("option"))
|
||||
Expect(fstab.MntOps["option1"]).To(Equal(""))
|
||||
Expect(fstab.MntOps["option"]).To(Equal("2"))
|
||||
})
|
||||
})
|
||||
Context("CleanSysrootForFstab", func() {
|
||||
It("Removes /sysroot", func() {
|
||||
Expect(utils.CleanSysrootForFstab("/sysroot/dev")).To(Equal("/dev"))
|
||||
Expect(utils.CleanSysrootForFstab("/sysroot/sysroot/dev")).To(Equal("/dev"))
|
||||
Expect(utils.CleanSysrootForFstab("sysroot/dev")).To(Equal("sysroot/dev"))
|
||||
Expect(utils.CleanSysrootForFstab("/dev/sysroot/dev")).To(Equal("/dev/dev"))
|
||||
Expect(utils.CleanSysrootForFstab("/dev/")).To(Equal("/dev/"))
|
||||
Expect(utils.CleanSysrootForFstab("/dev")).To(Equal("/dev"))
|
||||
Expect(utils.CleanSysrootForFstab("//sysroot/dev")).To(Equal("//dev"))
|
||||
Expect(utils.CleanSysrootForFstab("/sysroot//dev")).To(Equal("//dev"))
|
||||
})
|
||||
})
|
||||
Context("GetOemTimeout", func() {
|
||||
It("Gets timeout from rd.cos.oemtimeout", func() {
|
||||
err := fs.WriteFile("/proc/cmdline", []byte("rd.cos.oemtimeout=100\n"), os.ModePerm)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(utils.GetOemTimeout()).To(Equal(100))
|
||||
})
|
||||
It("Gets timeout from rd.immucore.oemtimeout", func() {
|
||||
err := fs.WriteFile("/proc/cmdline", []byte("rd.immucore.oemtimeout=200\n"), os.ModePerm)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(utils.GetOemTimeout()).To(Equal(200))
|
||||
})
|
||||
It("Gets timeout from both rd.cos.oemtimeout and rd.immucore.oemtimeout(immucore has precedence)", func() {
|
||||
err := fs.WriteFile("/proc/cmdline", []byte("rd.cos.oemtimeout=100 rd.immucore.oemtimeout=200\n"), os.ModePerm)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(utils.GetOemTimeout()).To(Equal(200))
|
||||
})
|
||||
It("Fails to parse from cmdline and gets default", func() {
|
||||
err := fs.WriteFile("/proc/cmdline", []byte("rd.immucore.oemtimeout=really\n"), os.ModePerm)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(utils.GetOemTimeout()).To(Equal(5))
|
||||
err = fs.WriteFile("/proc/cmdline", []byte("rd.immucore.oemtimeout=\n"), os.ModePerm)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(utils.GetOemTimeout()).To(Equal(5))
|
||||
})
|
||||
It("Gets default timeout", func() {
|
||||
Expect(utils.GetOemTimeout()).To(Equal(5))
|
||||
})
|
||||
})
|
||||
Context("GetOverlayBase", func() {
|
||||
It("Gets overlay from rd.cos.overlay", func() {
|
||||
err := fs.WriteFile("/proc/cmdline", []byte("rd.cos.overlay=tmpfs:100%\n"), os.ModePerm)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(utils.GetOverlayBase()).To(Equal("tmpfs:100%"))
|
||||
})
|
||||
It("Gets overlay from rd.immucore.overlay", func() {
|
||||
err := fs.WriteFile("/proc/cmdline", []byte("rd.immucore.overlay=tmpfs:200%\n"), os.ModePerm)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(utils.GetOverlayBase()).To(Equal("tmpfs:200%"))
|
||||
})
|
||||
It("Gets overlay from both rd.cos.overlay and rd.immucore.overlay(immucore has precedence)", func() {
|
||||
err := fs.WriteFile("/proc/cmdline", []byte("rd.cos.overlay=tmpfs:100% rd.immucore.overlay=tmpfs:200%\n"), os.ModePerm)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(utils.GetOverlayBase()).To(Equal("tmpfs:200%"))
|
||||
})
|
||||
It("Fails to parse from cmdline and gets default", func() {
|
||||
err := fs.WriteFile("/proc/cmdline", []byte("rd.immucore.overlay=\n"), os.ModePerm)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(utils.GetOverlayBase()).To(Equal("tmpfs:20%"))
|
||||
err = fs.WriteFile("/proc/cmdline", []byte("rd.immucore.overlay=\n"), os.ModePerm)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(utils.GetOverlayBase()).To(Equal("tmpfs:20%"))
|
||||
})
|
||||
It("Gets default overlay", func() {
|
||||
Expect(utils.GetOverlayBase()).To(Equal("tmpfs:20%"))
|
||||
})
|
||||
})
|
||||
Context("GetOemLabel", func() {
|
||||
It("Gets label from rd.cos.oemlabel", func() {
|
||||
err := fs.WriteFile("/proc/cmdline", []byte("rd.cos.oemlabel=COS_LABEL\n"), os.ModePerm)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(utils.GetOemLabel()).To(Equal("COS_LABEL"))
|
||||
})
|
||||
It("Gets label from rd.immucore.oemlabel", func() {
|
||||
err := fs.WriteFile("/proc/cmdline", []byte("rd.immucore.oemlabel=IMMUCORE_LABEL\n"), os.ModePerm)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(utils.GetOemLabel()).To(Equal("IMMUCORE_LABEL"))
|
||||
})
|
||||
It("Gets label from both rd.cos.oemlabel and rd.immucore.oemlabel(immucore has precedence)", func() {
|
||||
err := fs.WriteFile("/proc/cmdline", []byte("rd.cos.oemlabel=COS_LABEL rd.immucore.oemlabel=IMMUCORE_LABEL\n"), os.ModePerm)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(utils.GetOemLabel()).To(Equal("IMMUCORE_LABEL"))
|
||||
})
|
||||
It("Fails to parse from cmdline and gets default from runtime", func() {
|
||||
mainDisk := block.Disk{
|
||||
Name: "device",
|
||||
Partitions: []*block.Partition{
|
||||
{
|
||||
Name: "device2",
|
||||
Label: "COS_OEM",
|
||||
Type: "ext4",
|
||||
MountPoint: "/oem",
|
||||
},
|
||||
},
|
||||
}
|
||||
ghwTest := mocks.GhwMock{}
|
||||
ghwTest.AddDisk(mainDisk)
|
||||
ghwTest.CreateDevices()
|
||||
defer ghwTest.Clean()
|
||||
|
||||
err := fs.WriteFile("/proc/cmdline", []byte("rd.cos.oemlabel=\n"), os.ModePerm)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(utils.GetOemLabel()).To(Equal("COS_OEM"))
|
||||
err = fs.WriteFile("/proc/cmdline", []byte("rd.immucore.oemlabel=\n"), os.ModePerm)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(utils.GetOemLabel()).To(Equal("COS_OEM"))
|
||||
})
|
||||
})
|
||||
})
|
Reference in New Issue
Block a user