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:
Itxaka
2023-03-02 16:46:25 +01:00
committed by GitHub
parent b0b326313b
commit fecfbf8e92
22 changed files with 673 additions and 220 deletions

173
tests/mocks/ghw_mock.go Normal file
View 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
View 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
View 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
View 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"))
})
})
})