elemental-toolkit/pkg/action/init_test.go

185 lines
5.5 KiB
Go

/*
Copyright © 2022 - 2025 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 action_test
import (
"bytes"
"fmt"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/sirupsen/logrus"
"github.com/twpayne/go-vfs/v4"
"github.com/twpayne/go-vfs/v4/vfst"
"github.com/rancher/elemental-toolkit/v2/pkg/action"
"github.com/rancher/elemental-toolkit/v2/pkg/config"
"github.com/rancher/elemental-toolkit/v2/pkg/constants"
"github.com/rancher/elemental-toolkit/v2/pkg/features"
"github.com/rancher/elemental-toolkit/v2/pkg/mocks"
"github.com/rancher/elemental-toolkit/v2/pkg/types"
"github.com/rancher/elemental-toolkit/v2/pkg/utils"
)
var _ = Describe("Init Action", func() {
var cfg *types.RunConfig
var runner *mocks.FakeRunner
var fs vfs.FS
var logger types.Logger
var cleanup func()
var memLog *bytes.Buffer
var expectedNumUnits int
var spec *types.InitSpec
var enabledUnits []string
var errCmd, initrdFile string
var mounter *mocks.FakeMounter
BeforeEach(func() {
mounter = mocks.NewFakeMounter()
runner = mocks.NewFakeRunner()
memLog = &bytes.Buffer{}
logger = types.NewBufferLogger(memLog)
logger.SetLevel(logrus.DebugLevel)
fs, cleanup, _ = vfst.NewTestFS(map[string]interface{}{})
cfg = config.NewRunConfig(
config.WithFs(fs),
config.WithRunner(runner),
config.WithMounter(mounter),
config.WithLogger(logger),
)
feats, err := features.Get(features.All)
Expect(err).To(BeNil())
expectedNumUnits = 0
for _, feat := range feats {
expectedNumUnits += len(feat.Units)
}
spec = config.NewInitSpec()
enabledUnits = []string{}
initrdFile = "/boot/elemental.initrd-6.4"
// Emulate running in a dockerenv
Expect(fs.WriteFile("/.dockerenv", []byte{}, 0644)).To(Succeed())
runner.SideEffect = func(cmd string, args ...string) ([]byte, error) {
if cmd == errCmd {
return []byte{}, fmt.Errorf("failed calling %s", cmd)
}
switch cmd {
case "systemctl":
if args[0] == "enable" {
enabledUnits = append(enabledUnits, args[1])
}
return []byte{}, nil
case "dracut":
_, err := fs.Create(initrdFile)
Expect(err).To(Succeed())
return []byte{}, nil
default:
return []byte{}, nil
}
}
// Create a kernel file and modules folder
Expect(utils.MkdirAll(fs, "/lib/modules/6.4", constants.DirPerm)).To(Succeed())
Expect(utils.MkdirAll(fs, "/boot", constants.DirPerm)).To(Succeed())
_, err = fs.Create("/boot/vmlinuz-6.4")
Expect(err).To(Succeed())
})
AfterEach(func() {
cleanup()
})
Describe("Init action", Label("init"), func() {
It("Shows an error if /.dockerenv does not exist", func() {
Expect(fs.Remove("/.dockerenv")).To(Succeed())
Expect(action.RunInit(cfg, spec)).ToNot(Succeed())
Expect(len(enabledUnits)).To(Equal(0))
})
It("Successfully runs init and install files", func() {
preExistingInitrd := "/boot/elemental.initrd-6.2"
_, err := fs.Create(preExistingInitrd)
Expect(err).NotTo(HaveOccurred())
Expect(action.RunInit(cfg, spec)).To(Succeed())
Expect(len(enabledUnits)).To(Equal(expectedNumUnits))
for _, unit := range enabledUnits {
exists, err := utils.Exists(fs, fmt.Sprintf("/etc/systemd/system/%v", unit))
Expect(err).To(BeNil())
Expect(exists).To(BeTrue())
}
exists, _ := utils.Exists(fs, "/boot/elemental.initrd-6.4")
Expect(exists).To(BeTrue())
exists, _ = utils.Exists(fs, preExistingInitrd)
Expect(exists).To(BeFalse())
// Check expected initrd and kernel files are created
exists, _ = utils.Exists(fs, "/boot/vmlinuz")
Expect(exists).To(BeTrue())
exists, _ = utils.Exists(fs, "/boot/initrd")
Expect(exists).To(BeTrue())
})
It("fails if requested feature does not exist", func() {
spec.Features = append(spec.Features, "nonexisting")
Expect(action.RunInit(cfg, spec)).NotTo(Succeed())
Expect(len(enabledUnits)).To(Equal(0))
})
It("fails if the kernel file is not there", func() {
Expect(fs.Remove("/boot/vmlinuz-6.4")).To(Succeed())
Expect(action.RunInit(cfg, spec)).NotTo(Succeed())
Expect(len(enabledUnits)).To(Equal(expectedNumUnits))
for _, unit := range enabledUnits {
exists, err := utils.Exists(fs, fmt.Sprintf("/etc/systemd/system/%v", unit))
Expect(err).To(BeNil())
Expect(exists).To(BeTrue())
}
})
It("fails on dracut call", func() {
errCmd = "dracut"
Expect(action.RunInit(cfg, spec)).NotTo(Succeed())
Expect(len(enabledUnits)).To(Equal(expectedNumUnits))
for _, unit := range enabledUnits {
exists, err := utils.Exists(fs, fmt.Sprintf("/etc/systemd/system/%v", unit))
Expect(err).To(BeNil())
Expect(exists).To(BeTrue())
}
})
It("fails if initrd is not found", func() {
initrdFile = "/boot/wrongInird"
Expect(action.RunInit(cfg, spec)).NotTo(Succeed())
Expect(len(enabledUnits)).To(Equal(expectedNumUnits))
for _, unit := range enabledUnits {
exists, err := utils.Exists(fs, fmt.Sprintf("/etc/systemd/system/%v", unit))
Expect(err).To(BeNil())
Expect(exists).To(BeTrue())
}
})
})
})