mirror of
https://github.com/kairos-io/osbuilder.git
synced 2025-08-31 06:35:23 +00:00
Add more testing
Signed-off-by: Itxaka <itxaka.garcia@spectrocloud.com>
This commit is contained in:
28
tools-image/enki/pkg/action/action_suite_test.go
Normal file
28
tools-image/enki/pkg/action/action_suite_test.go
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
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 action_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
func TestActionSuite(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecs(t, "Actions test suite")
|
||||
}
|
@@ -37,7 +37,7 @@ func (b *BuildISOAction) ISORun() (err error) {
|
||||
cleanup := utils.NewCleanStack()
|
||||
defer func() { err = cleanup.Cleanup(err) }()
|
||||
|
||||
isoTmpDir, err := utils.TempDir(b.cfg.Fs, "", "elemental-iso")
|
||||
isoTmpDir, err := utils.TempDir(b.cfg.Fs, "", "enki-iso")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
195
tools-image/enki/pkg/action/build_test.go
Normal file
195
tools-image/enki/pkg/action/build_test.go
Normal file
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
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 action_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/kairos-io/enki/pkg/action"
|
||||
"github.com/kairos-io/enki/pkg/config"
|
||||
"github.com/kairos-io/enki/pkg/constants"
|
||||
"github.com/kairos-io/enki/pkg/utils"
|
||||
v1 "github.com/kairos-io/kairos-agent/v2/pkg/types/v1"
|
||||
v1mock "github.com/kairos-io/kairos-agent/v2/tests/mocks"
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/twpayne/go-vfs"
|
||||
"github.com/twpayne/go-vfs/vfst"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
var _ = Describe("Runtime Actions", func() {
|
||||
var cfg *v1.BuildConfig
|
||||
var runner *v1mock.FakeRunner
|
||||
var fs vfs.FS
|
||||
var logger v1.Logger
|
||||
var mounter *v1mock.ErrorMounter
|
||||
var syscall *v1mock.FakeSyscall
|
||||
var client *v1mock.FakeHTTPClient
|
||||
var cloudInit *v1mock.FakeCloudInitRunner
|
||||
var cleanup func()
|
||||
var memLog *bytes.Buffer
|
||||
var imageExtractor *v1mock.FakeImageExtractor
|
||||
BeforeEach(func() {
|
||||
runner = v1mock.NewFakeRunner()
|
||||
syscall = &v1mock.FakeSyscall{}
|
||||
mounter = v1mock.NewErrorMounter()
|
||||
client = &v1mock.FakeHTTPClient{}
|
||||
memLog = &bytes.Buffer{}
|
||||
logger = v1.NewBufferLogger(memLog)
|
||||
logger.SetLevel(logrus.DebugLevel)
|
||||
cloudInit = &v1mock.FakeCloudInitRunner{}
|
||||
fs, cleanup, _ = vfst.NewTestFS(map[string]interface{}{})
|
||||
imageExtractor = v1mock.NewFakeImageExtractor(logger)
|
||||
|
||||
cfg = config.NewBuildConfig(
|
||||
config.WithFs(fs),
|
||||
config.WithRunner(runner),
|
||||
config.WithLogger(logger),
|
||||
config.WithMounter(mounter),
|
||||
config.WithSyscall(syscall),
|
||||
config.WithClient(client),
|
||||
config.WithCloudInitRunner(cloudInit),
|
||||
config.WithImageExtractor(imageExtractor),
|
||||
)
|
||||
})
|
||||
AfterEach(func() {
|
||||
cleanup()
|
||||
})
|
||||
Describe("Build ISO", Label("iso"), func() {
|
||||
var iso *v1.LiveISO
|
||||
BeforeEach(func() {
|
||||
iso = config.NewISO()
|
||||
|
||||
tmpDir, err := utils.TempDir(fs, "", "test")
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
|
||||
cfg.Date = false
|
||||
cfg.OutDir = tmpDir
|
||||
|
||||
runner.SideEffect = func(cmd string, args ...string) ([]byte, error) {
|
||||
switch cmd {
|
||||
case "xorriso":
|
||||
err := fs.WriteFile(filepath.Join(tmpDir, "elemental.iso"), []byte("profound thoughts"), constants.FilePerm)
|
||||
return []byte{}, err
|
||||
default:
|
||||
return []byte{}, nil
|
||||
}
|
||||
}
|
||||
})
|
||||
It("Successfully builds an ISO from a Docker image", func() {
|
||||
rootSrc, _ := v1.NewSrcFromURI("oci:image:version")
|
||||
iso.RootFS = []*v1.ImageSource{rootSrc}
|
||||
uefiSrc, _ := v1.NewSrcFromURI("oci:image:version")
|
||||
iso.UEFI = []*v1.ImageSource{uefiSrc}
|
||||
imageSrc, _ := v1.NewSrcFromURI("oci:image:version")
|
||||
iso.Image = []*v1.ImageSource{imageSrc}
|
||||
|
||||
// Create kernel and vmlinuz
|
||||
// Thanks to the testfs stuff in utils.TempDir we know what the temp fs is gonna be as
|
||||
// its predictable
|
||||
bootDir := filepath.Join("/tmp/enki-iso/rootfs", "boot")
|
||||
err := utils.MkdirAll(fs, bootDir, constants.DirPerm)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
_, err = fs.Create(filepath.Join(bootDir, "vmlinuz"))
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
_, err = fs.Create(filepath.Join(bootDir, "initrd"))
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
|
||||
buildISO := action.NewBuildISOAction(cfg, iso)
|
||||
err = buildISO.ISORun()
|
||||
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
})
|
||||
It("Fails if kernel or initrd is not found in rootfs", func() {
|
||||
rootSrc, _ := v1.NewSrcFromURI("oci:image:version")
|
||||
iso.RootFS = []*v1.ImageSource{rootSrc}
|
||||
uefiSrc, _ := v1.NewSrcFromURI("oci:image:version")
|
||||
iso.UEFI = []*v1.ImageSource{uefiSrc}
|
||||
imageSrc, _ := v1.NewSrcFromURI("oci:image:version")
|
||||
iso.Image = []*v1.ImageSource{imageSrc}
|
||||
|
||||
By("fails without kernel")
|
||||
buildISO := action.NewBuildISOAction(cfg, iso)
|
||||
err := buildISO.ISORun()
|
||||
Expect(err).Should(HaveOccurred())
|
||||
Expect(err.Error()).To(ContainSubstring("No file found with prefixes"))
|
||||
Expect(err.Error()).To(ContainSubstring("uImage Image zImage vmlinuz image"))
|
||||
|
||||
bootDir := filepath.Join("/tmp/enki-iso/rootfs", "boot")
|
||||
err = utils.MkdirAll(fs, bootDir, constants.DirPerm)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
_, err = fs.Create(filepath.Join(bootDir, "vmlinuz"))
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
|
||||
By("fails without initrd")
|
||||
buildISO = action.NewBuildISOAction(cfg, iso)
|
||||
err = buildISO.ISORun()
|
||||
Expect(err).Should(HaveOccurred())
|
||||
Expect(err.Error()).To(ContainSubstring("No file found with prefixes"))
|
||||
Expect(err.Error()).To(ContainSubstring("initrd initramfs"))
|
||||
})
|
||||
It("Fails installing image sources", func() {
|
||||
rootSrc, _ := v1.NewSrcFromURI("oci:image:version")
|
||||
iso.RootFS = []*v1.ImageSource{rootSrc}
|
||||
uefiSrc, _ := v1.NewSrcFromURI("oci:image:version")
|
||||
iso.UEFI = []*v1.ImageSource{uefiSrc}
|
||||
imageSrc, _ := v1.NewSrcFromURI("oci:image:version")
|
||||
iso.Image = []*v1.ImageSource{imageSrc}
|
||||
|
||||
imageExtractor.SideEffect = func(imageRef, destination, platformRef string) error {
|
||||
return fmt.Errorf("uh oh")
|
||||
}
|
||||
|
||||
buildISO := action.NewBuildISOAction(cfg, iso)
|
||||
err := buildISO.ISORun()
|
||||
Expect(err).Should(HaveOccurred())
|
||||
Expect(err.Error()).To(ContainSubstring("uh oh"))
|
||||
})
|
||||
It("Fails on ISO filesystem creation", func() {
|
||||
rootSrc, _ := v1.NewSrcFromURI("oci:image:version")
|
||||
iso.RootFS = []*v1.ImageSource{rootSrc}
|
||||
uefiSrc, _ := v1.NewSrcFromURI("oci:image:version")
|
||||
iso.UEFI = []*v1.ImageSource{uefiSrc}
|
||||
imageSrc, _ := v1.NewSrcFromURI("oci:image:version")
|
||||
iso.Image = []*v1.ImageSource{imageSrc}
|
||||
|
||||
bootDir := filepath.Join("/tmp/enki-iso/rootfs", "boot")
|
||||
err := utils.MkdirAll(fs, bootDir, constants.DirPerm)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
_, err = fs.Create(filepath.Join(bootDir, "vmlinuz"))
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
_, err = fs.Create(filepath.Join(bootDir, "initrd"))
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
|
||||
runner.SideEffect = func(command string, args ...string) ([]byte, error) {
|
||||
if command == "xorriso" {
|
||||
return []byte{}, errors.New("Burn ISO error")
|
||||
}
|
||||
return []byte{}, nil
|
||||
}
|
||||
|
||||
buildISO := action.NewBuildISOAction(cfg, iso)
|
||||
err = buildISO.ISORun()
|
||||
|
||||
Expect(err).Should(HaveOccurred())
|
||||
Expect(err.Error()).To(ContainSubstring("Burn ISO error"))
|
||||
})
|
||||
})
|
||||
})
|
@@ -32,6 +32,13 @@ var decodeHook = viper.DecodeHook(
|
||||
),
|
||||
)
|
||||
|
||||
func WithFs(fs v1.FS) func(r *v1.Config) error {
|
||||
return func(r *v1.Config) error {
|
||||
r.Fs = fs
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func WithLogger(logger v1.Logger) func(r *v1.Config) error {
|
||||
return func(r *v1.Config) error {
|
||||
r.Logger = logger
|
||||
@@ -39,6 +46,13 @@ func WithLogger(logger v1.Logger) func(r *v1.Config) error {
|
||||
}
|
||||
}
|
||||
|
||||
func WithSyscall(syscall v1.SyscallInterface) func(r *v1.Config) error {
|
||||
return func(r *v1.Config) error {
|
||||
r.Syscall = syscall
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func WithMounter(mounter mount.Interface) func(r *v1.Config) error {
|
||||
return func(r *v1.Config) error {
|
||||
r.Mounter = mounter
|
||||
@@ -46,6 +60,41 @@ func WithMounter(mounter mount.Interface) func(r *v1.Config) error {
|
||||
}
|
||||
}
|
||||
|
||||
func WithRunner(runner v1.Runner) func(r *v1.Config) error {
|
||||
return func(r *v1.Config) error {
|
||||
r.Runner = runner
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func WithClient(client v1.HTTPClient) func(r *v1.Config) error {
|
||||
return func(r *v1.Config) error {
|
||||
r.Client = client
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func WithCloudInitRunner(ci v1.CloudInitRunner) func(r *v1.Config) error {
|
||||
return func(r *v1.Config) error {
|
||||
r.CloudInitRunner = ci
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func WithArch(arch string) func(r *v1.Config) error {
|
||||
return func(r *v1.Config) error {
|
||||
r.Arch = arch
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func WithImageExtractor(extractor v1.ImageExtractor) func(r *v1.Config) error {
|
||||
return func(r *v1.Config) error {
|
||||
r.ImageExtractor = extractor
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
type GenericOptions func(a *v1.Config) error
|
||||
|
||||
func ReadConfigBuild(configDir string, flags *pflag.FlagSet, mounter mount.Interface) (*v1.BuildConfig, error) {
|
||||
|
29
tools-image/enki/pkg/utils/utils_suite_test.go
Normal file
29
tools-image/enki/pkg/utils/utils_suite_test.go
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
Copyright © 2021 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 utils_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
func TestWhitebox(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecs(t, "Utils test suite")
|
||||
}
|
368
tools-image/enki/pkg/utils/utils_test.go
Normal file
368
tools-image/enki/pkg/utils/utils_test.go
Normal file
@@ -0,0 +1,368 @@
|
||||
/*
|
||||
Copyright © 2021 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 utils_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
conf "github.com/kairos-io/enki/pkg/config"
|
||||
"github.com/kairos-io/enki/pkg/constants"
|
||||
"github.com/kairos-io/enki/pkg/utils"
|
||||
v1 "github.com/kairos-io/kairos-agent/v2/pkg/types/v1"
|
||||
v1mock "github.com/kairos-io/kairos-agent/v2/tests/mocks"
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/twpayne/go-vfs"
|
||||
"github.com/twpayne/go-vfs/vfst"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var _ = Describe("Utils", Label("utils"), func() {
|
||||
var config *v1.Config
|
||||
var runner *v1mock.FakeRunner
|
||||
var logger v1.Logger
|
||||
var syscall *v1mock.FakeSyscall
|
||||
var client *v1mock.FakeHTTPClient
|
||||
var mounter *v1mock.ErrorMounter
|
||||
var fs vfs.FS
|
||||
var cleanup func()
|
||||
|
||||
BeforeEach(func() {
|
||||
runner = v1mock.NewFakeRunner()
|
||||
syscall = &v1mock.FakeSyscall{}
|
||||
mounter = v1mock.NewErrorMounter()
|
||||
client = &v1mock.FakeHTTPClient{}
|
||||
logger = v1.NewNullLogger()
|
||||
// Ensure /tmp exists in the VFS
|
||||
fs, cleanup, _ = vfst.NewTestFS(nil)
|
||||
fs.Mkdir("/tmp", constants.DirPerm)
|
||||
fs.Mkdir("/run", constants.DirPerm)
|
||||
fs.Mkdir("/etc", constants.DirPerm)
|
||||
|
||||
config = conf.NewConfig(
|
||||
conf.WithFs(fs),
|
||||
conf.WithRunner(runner),
|
||||
conf.WithLogger(logger),
|
||||
conf.WithMounter(mounter),
|
||||
conf.WithSyscall(syscall),
|
||||
conf.WithClient(client),
|
||||
)
|
||||
})
|
||||
AfterEach(func() { cleanup() })
|
||||
|
||||
Describe("Chroot", Label("chroot"), func() {
|
||||
var chroot *utils.Chroot
|
||||
BeforeEach(func() {
|
||||
chroot = utils.NewChroot(
|
||||
"/whatever",
|
||||
config,
|
||||
)
|
||||
})
|
||||
Describe("ChrootedCallback method", func() {
|
||||
It("runs a callback in a chroot", func() {
|
||||
err := utils.ChrootedCallback(config, "/somepath", map[string]string{}, func() error {
|
||||
return nil
|
||||
})
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = utils.ChrootedCallback(config, "/somepath", map[string]string{}, func() error {
|
||||
return fmt.Errorf("callback error")
|
||||
})
|
||||
Expect(err).Should(HaveOccurred())
|
||||
Expect(err.Error()).To(ContainSubstring("callback error"))
|
||||
})
|
||||
})
|
||||
Describe("on success", func() {
|
||||
It("command should be called in the chroot", func() {
|
||||
_, err := chroot.Run("chroot-command")
|
||||
Expect(err).To(BeNil())
|
||||
Expect(syscall.WasChrootCalledWith("/whatever")).To(BeTrue())
|
||||
})
|
||||
It("commands should be called with a customized chroot", func() {
|
||||
chroot.SetExtraMounts(map[string]string{"/real/path": "/in/chroot/path"})
|
||||
Expect(chroot.Prepare()).To(BeNil())
|
||||
defer chroot.Close()
|
||||
_, err := chroot.Run("chroot-command")
|
||||
Expect(err).To(BeNil())
|
||||
Expect(syscall.WasChrootCalledWith("/whatever")).To(BeTrue())
|
||||
_, err = chroot.Run("chroot-another-command")
|
||||
Expect(err).To(BeNil())
|
||||
})
|
||||
It("runs a callback in a custom chroot", func() {
|
||||
called := false
|
||||
callback := func() error {
|
||||
called = true
|
||||
return nil
|
||||
}
|
||||
err := chroot.RunCallback(callback)
|
||||
Expect(err).To(BeNil())
|
||||
Expect(syscall.WasChrootCalledWith("/whatever")).To(BeTrue())
|
||||
Expect(called).To(BeTrue())
|
||||
})
|
||||
})
|
||||
Describe("on failure", func() {
|
||||
It("should return error if chroot-command fails", func() {
|
||||
runner.ReturnError = errors.New("run error")
|
||||
_, err := chroot.Run("chroot-command")
|
||||
Expect(err).NotTo(BeNil())
|
||||
Expect(syscall.WasChrootCalledWith("/whatever")).To(BeTrue())
|
||||
})
|
||||
It("should return error if callback fails", func() {
|
||||
called := false
|
||||
callback := func() error {
|
||||
called = true
|
||||
return errors.New("Callback error")
|
||||
}
|
||||
err := chroot.RunCallback(callback)
|
||||
Expect(err).NotTo(BeNil())
|
||||
Expect(syscall.WasChrootCalledWith("/whatever")).To(BeTrue())
|
||||
Expect(called).To(BeTrue())
|
||||
})
|
||||
It("should return error if preparing twice before closing", func() {
|
||||
Expect(chroot.Prepare()).To(BeNil())
|
||||
defer chroot.Close()
|
||||
Expect(chroot.Prepare()).NotTo(BeNil())
|
||||
Expect(chroot.Close()).To(BeNil())
|
||||
Expect(chroot.Prepare()).To(BeNil())
|
||||
})
|
||||
It("should return error if failed to chroot", func() {
|
||||
syscall.ErrorOnChroot = true
|
||||
_, err := chroot.Run("chroot-command")
|
||||
Expect(err).ToNot(BeNil())
|
||||
Expect(syscall.WasChrootCalledWith("/whatever")).To(BeTrue())
|
||||
Expect(err.Error()).To(ContainSubstring("chroot error"))
|
||||
})
|
||||
It("should return error if failed to mount on prepare", Label("mount"), func() {
|
||||
mounter.ErrorOnMount = true
|
||||
_, err := chroot.Run("chroot-command")
|
||||
Expect(err).ToNot(BeNil())
|
||||
Expect(err.Error()).To(ContainSubstring("mount error"))
|
||||
})
|
||||
It("should return error if failed to unmount on close", Label("unmount"), func() {
|
||||
mounter.ErrorOnUnmount = true
|
||||
_, err := chroot.Run("chroot-command")
|
||||
Expect(err).ToNot(BeNil())
|
||||
Expect(err.Error()).To(ContainSubstring("failed closing chroot"))
|
||||
})
|
||||
})
|
||||
})
|
||||
Describe("CopyFile", Label("CopyFile"), func() {
|
||||
It("Copies source file to target file", func() {
|
||||
err := utils.MkdirAll(fs, "/some", constants.DirPerm)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
_, err = fs.Create("/some/file")
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
_, err = fs.Stat("/some/otherfile")
|
||||
Expect(err).Should(HaveOccurred())
|
||||
Expect(utils.CopyFile(fs, "/some/file", "/some/otherfile")).ShouldNot(HaveOccurred())
|
||||
e, err := utils.Exists(fs, "/some/otherfile")
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
Expect(e).To(BeTrue())
|
||||
})
|
||||
It("Copies source file to target folder", func() {
|
||||
err := utils.MkdirAll(fs, "/some", constants.DirPerm)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = utils.MkdirAll(fs, "/someotherfolder", constants.DirPerm)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
_, err = fs.Create("/some/file")
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
_, err = fs.Stat("/someotherfolder/file")
|
||||
Expect(err).Should(HaveOccurred())
|
||||
Expect(utils.CopyFile(fs, "/some/file", "/someotherfolder")).ShouldNot(HaveOccurred())
|
||||
e, err := utils.Exists(fs, "/someotherfolder/file")
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
Expect(e).To(BeTrue())
|
||||
})
|
||||
It("Fails to open non existing file", func() {
|
||||
err := utils.MkdirAll(fs, "/some", constants.DirPerm)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
Expect(utils.CopyFile(fs, "/some/file", "/some/otherfile")).NotTo(BeNil())
|
||||
_, err = fs.Stat("/some/otherfile")
|
||||
Expect(err).NotTo(BeNil())
|
||||
})
|
||||
It("Fails to copy on non writable target", func() {
|
||||
err := utils.MkdirAll(fs, "/some", constants.DirPerm)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
fs.Create("/some/file")
|
||||
_, err = fs.Stat("/some/otherfile")
|
||||
Expect(err).NotTo(BeNil())
|
||||
fs = vfs.NewReadOnlyFS(fs)
|
||||
Expect(utils.CopyFile(fs, "/some/file", "/some/otherfile")).NotTo(BeNil())
|
||||
_, err = fs.Stat("/some/otherfile")
|
||||
Expect(err).NotTo(BeNil())
|
||||
})
|
||||
})
|
||||
Describe("CreateDirStructure", Label("CreateDirStructure"), func() {
|
||||
It("Creates essential directories", func() {
|
||||
dirList := []string{"sys", "proc", "dev", "tmp", "boot", "usr/local", "oem"}
|
||||
for _, dir := range dirList {
|
||||
_, err := fs.Stat(fmt.Sprintf("/my/root/%s", dir))
|
||||
Expect(err).NotTo(BeNil())
|
||||
}
|
||||
Expect(utils.CreateDirStructure(fs, "/my/root")).To(BeNil())
|
||||
for _, dir := range dirList {
|
||||
fi, err := fs.Stat(fmt.Sprintf("/my/root/%s", dir))
|
||||
Expect(err).To(BeNil())
|
||||
if fi.Name() == "tmp" {
|
||||
Expect(fmt.Sprintf("%04o", fi.Mode().Perm())).To(Equal("0777"))
|
||||
Expect(fi.Mode() & os.ModeSticky).NotTo(Equal(0))
|
||||
}
|
||||
if fi.Name() == "sys" {
|
||||
Expect(fmt.Sprintf("%04o", fi.Mode().Perm())).To(Equal("0555"))
|
||||
}
|
||||
}
|
||||
})
|
||||
It("Fails on non writable target", func() {
|
||||
fs = vfs.NewReadOnlyFS(fs)
|
||||
Expect(utils.CreateDirStructure(fs, "/my/root")).NotTo(BeNil())
|
||||
})
|
||||
})
|
||||
Describe("DirSize", Label("fs"), func() {
|
||||
BeforeEach(func() {
|
||||
err := utils.MkdirAll(fs, "/folder/subfolder", constants.DirPerm)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
f, err := fs.Create("/folder/file")
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = f.Truncate(1024)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
f, err = fs.Create("/folder/subfolder/file")
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = f.Truncate(2048)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
})
|
||||
It("Returns the expected size of a test folder", func() {
|
||||
size, err := utils.DirSize(fs, "/folder")
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
Expect(size).To(Equal(int64(3072)))
|
||||
})
|
||||
})
|
||||
Describe("CalcFileChecksum", Label("checksum"), func() {
|
||||
It("compute correct sha256 checksum", func() {
|
||||
testData := strings.Repeat("abcdefghilmnopqrstuvz\n", 20)
|
||||
testDataSHA256 := "7f182529f6362ae9cfa952ab87342a7180db45d2c57b52b50a68b6130b15a422"
|
||||
|
||||
err := fs.Mkdir("/iso", constants.DirPerm)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
err = fs.WriteFile("/iso/test.iso", []byte(testData), 0644)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
|
||||
checksum, err := utils.CalcFileChecksum(fs, "/iso/test.iso")
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
Expect(checksum).To(Equal(testDataSHA256))
|
||||
})
|
||||
})
|
||||
Describe("CreateSquashFS", Label("CreateSquashFS"), func() {
|
||||
It("runs with no options if none given", func() {
|
||||
err := utils.CreateSquashFS(runner, logger, "source", "dest", []string{})
|
||||
Expect(runner.IncludesCmds([][]string{
|
||||
{"mksquashfs", "source", "dest"},
|
||||
})).To(BeNil())
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
})
|
||||
It("runs with options if given", func() {
|
||||
err := utils.CreateSquashFS(runner, logger, "source", "dest", constants.GetDefaultSquashfsOptions())
|
||||
cmd := []string{"mksquashfs", "source", "dest"}
|
||||
cmd = append(cmd, constants.GetDefaultSquashfsOptions()...)
|
||||
Expect(runner.IncludesCmds([][]string{
|
||||
cmd,
|
||||
})).To(BeNil())
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
})
|
||||
It("returns an error if it fails", func() {
|
||||
runner.ReturnError = errors.New("error")
|
||||
err := utils.CreateSquashFS(runner, logger, "source", "dest", []string{})
|
||||
Expect(runner.IncludesCmds([][]string{
|
||||
{"mksquashfs", "source", "dest"},
|
||||
})).To(BeNil())
|
||||
Expect(err).To(HaveOccurred())
|
||||
})
|
||||
})
|
||||
Describe("CleanStack", Label("CleanStack"), func() {
|
||||
var cleaner *utils.CleanStack
|
||||
BeforeEach(func() {
|
||||
cleaner = utils.NewCleanStack()
|
||||
})
|
||||
It("Adds a callback to the stack and pops it", func() {
|
||||
var flag bool
|
||||
callback := func() error {
|
||||
flag = true
|
||||
return nil
|
||||
}
|
||||
Expect(cleaner.Pop()).To(BeNil())
|
||||
cleaner.Push(callback)
|
||||
poppedJob := cleaner.Pop()
|
||||
Expect(poppedJob).NotTo(BeNil())
|
||||
poppedJob()
|
||||
Expect(flag).To(BeTrue())
|
||||
})
|
||||
It("On Cleanup runs callback stack in reverse order", func() {
|
||||
result := ""
|
||||
callback1 := func() error {
|
||||
result = result + "one "
|
||||
return nil
|
||||
}
|
||||
callback2 := func() error {
|
||||
result = result + "two "
|
||||
return nil
|
||||
}
|
||||
callback3 := func() error {
|
||||
result = result + "three "
|
||||
return nil
|
||||
}
|
||||
cleaner.Push(callback1)
|
||||
cleaner.Push(callback2)
|
||||
cleaner.Push(callback3)
|
||||
cleaner.Cleanup(nil)
|
||||
Expect(result).To(Equal("three two one "))
|
||||
})
|
||||
It("On Cleanup keeps former error and all callbacks are executed", func() {
|
||||
err := errors.New("Former error")
|
||||
count := 0
|
||||
callback := func() error {
|
||||
count++
|
||||
if count == 2 {
|
||||
return errors.New("Cleanup Error")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
cleaner.Push(callback)
|
||||
cleaner.Push(callback)
|
||||
cleaner.Push(callback)
|
||||
err = cleaner.Cleanup(err)
|
||||
Expect(count).To(Equal(3))
|
||||
Expect(err.Error()).To(ContainSubstring("Former error"))
|
||||
})
|
||||
It("On Cleanup error reports first error and all callbacks are executed", func() {
|
||||
var err error
|
||||
count := 0
|
||||
callback := func() error {
|
||||
count++
|
||||
if count >= 2 {
|
||||
return errors.New(fmt.Sprintf("Cleanup error %d", count))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
cleaner.Push(callback)
|
||||
cleaner.Push(callback)
|
||||
cleaner.Push(callback)
|
||||
err = cleaner.Cleanup(err)
|
||||
Expect(count).To(Equal(3))
|
||||
Expect(err.Error()).To(ContainSubstring("Cleanup error 2"))
|
||||
Expect(err.Error()).To(ContainSubstring("Cleanup error 3"))
|
||||
})
|
||||
})
|
||||
})
|
Reference in New Issue
Block a user