diff --git a/mantle/kola/tests/ignition/qemufailure.go b/mantle/kola/tests/ignition/qemufailure.go index ba5e4798a1..3b0f7ef510 100644 --- a/mantle/kola/tests/ignition/qemufailure.go +++ b/mantle/kola/tests/ignition/qemufailure.go @@ -29,12 +29,10 @@ import ( "github.com/coreos/coreos-assembler/mantle/kola/register" "github.com/coreos/coreos-assembler/mantle/platform" "github.com/coreos/coreos-assembler/mantle/platform/conf" - "github.com/coreos/ignition/v2/config/v3_2/types" "github.com/coreos/coreos-assembler/mantle/util" + "github.com/coreos/ignition/v2/config/v3_2/types" ) -var console bool - func init() { register.RegisterTest(®ister.Test{ Name: "coreos.ignition.failure", @@ -78,40 +76,42 @@ func runDualBootfsIgnitionFailure(c cluster.TestCluster) { } } -func ignitionFailure(c cluster.TestCluster) error { - // We can't create files in / due to the immutable bit OSTree creates, so - // this is a convenient way to test Ignition failure. - failConfig, err := conf.EmptyIgnition().Render(conf.FailWarnings) - if err != nil { - return errors.Wrapf(err, "creating empty config") - } - failConfig.AddFile("/notwritable.txt", "Hello world", 0644) - - builder := platform.NewQemuBuilder() // platform.Manhole() - if err != nil { - return err - } - builder.MemoryMiB = 1024 - builder.Firmware = kola.QEMUOptions.Firmware +// take string and grep for it in console logs +func VerifyError(builder *platform.QemuBuilder, tempLogFile string, searchString string) error { inst, err := builder.Exec() if err != nil { return err } defer inst.Destroy() - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + defer cancel() errchan := make(chan error) go func() { - err := inst.WaitAll(ctx) - if err == nil { - err = fmt.Errorf("Ignition unexpectedly succeeded") - } else if err == platform.ErrInitramfsEmergency { - // The expected case - err = nil + resultingError := inst.WaitAll(ctx) + + if resultingError == nil { + resultingError = fmt.Errorf("Ignition unexpectedly succeeded") + } else if resultingError == platform.ErrInitramfsEmergency { + // Expectred initramfs failure, checking the console file to insure + // that coreos.ignition.failure failed + b, err := os.ReadFile(tempLogFile) + if err != nil { + resultingError = err + } + textExists, err := regexp.Match(searchString, b) + if err != nil { + resultingError = err + } + if textExists { + // The expected case + resultingError = nil + } else { + resultingError = errors.Wrapf(err, "expected coreos.ignition.failure to fail") + } } else { - err = errors.Wrapf(err, "expected initramfs emergency.target error") + resultingError = errors.Wrapf(err, "expected initramfs emergency.target error") } errchan <- err }() @@ -130,15 +130,44 @@ func ignitionFailure(c cluster.TestCluster) error { } } -// Verify that there is only one boot filesystem attached to the device -func dualBootfsFailure(c cluster.TestCluster) error { - builder := platform.NewQemuBuilder() +func ignitionFailure(c cluster.TestCluster) error { + // We can't create files in / due to the immutable bit OSTree creates, so + // this is a convenient way to test Ignition failure. + failConfig, err := conf.EmptyIgnition().Render(conf.FailWarnings) + if err != nil { + return errors.Wrapf(err, "creating empty config") + } + failConfig.AddFile("/notwritable.txt", "Hello world", 0644) - consoleFile, err := builder.TempFile("console.log") + builder := platform.NewQemuBuilder() // platform.Manhole() + + // Create a temporary log file + tempLogFile := platform.CreateTempLogFile(builder) + + defer builder.Close() + builder.SetConfig(failConfig) + err = builder.AddBootDisk(&platform.Disk{ + BackingFile: kola.QEMUOptions.DiskImage, + }) if err != nil { return err } - builder.ConsoleFile = consoleFile.Name() + + builder.MemoryMiB = 1024 + builder.Firmware = kola.QEMUOptions.Firmware + + searchString := "/notwritable.txt" + if VerifyError(builder, tempLogFile, searchString) != nil { + return err + } + return nil +} + +// Verify that there is only one boot filesystem attached to the device +func dualBootfsFailure(c cluster.TestCluster) error { + builder := platform.NewQemuBuilder() + // Create a temporary log file + tempLogFile := platform.CreateTempLogFile(builder) // get current path and create tmp dir fakeBootFile, err := builder.TempFile("fakeBoot") @@ -174,85 +203,35 @@ func dualBootfsFailure(c cluster.TestCluster) error { } builder.MemoryMiB = 1024 builder.Firmware = kola.QEMUOptions.Firmware - inst, err := builder.Exec() - if err != nil { - return err - } // platform.Manhole() - defer inst.Destroy() - - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - defer cancel() - - errchan := make(chan error) - go func() { - resultingError := inst.WaitAll(ctx) - - if resultingError == nil { - resultingError = fmt.Errorf("bootfs unexpectedly succeeded") - } else if resultingError == platform.ErrInitramfsEmergency { - // Expectred initramfs failure, checking the console file to insure - // that coreos-unique-boot.service failed - b, err := os.ReadFile(builder.ConsoleFile) - if err != nil { - panic(err) - } - isExist, err := regexp.Match("Error: System has 2 devices with a filesystem labeled 'boot'", b) - if err != nil { - panic(err) - } - if isExist { - // The expected case - resultingError = nil - } else { - resultingError = errors.Wrapf(err, "expected coreos-unique-boot.service to fail") - } - } else { - resultingError = errors.Wrapf(err, "expected initramfs emergency.target error") - } - errchan <- resultingError - }() - select { - case <-ctx.Done(): - if err := inst.Kill(); err != nil { - return errors.Wrapf(err, "failed to kill the vm instance") - } - return errors.Wrapf(ctx.Err(), "timed out waiting for initramfs error") - case err := <-errchan: - if err != nil { - return err - } - return nil + searchString := "Error: System has 2 devices with a filesystem labeled 'boot'" + if VerifyError(builder, tempLogFile, searchString) != nil { + return err } + return nil } // Use ignition config to create a second bootfs // 1 - produce an ignition file that format a disk with a"boot" label. // 2 - boot the VM with the ignition file and an extra disk. -// 3 - observe the failure +// 3 - observe the failure func dualBootfsIgnitionFailure(c cluster.TestCluster) error { builder := platform.NewQemuBuilder() - // inserting log file for troubleshooting - // file located in coreos-assembler directory - // consoleFile, err := builder.TempFile("console.log") - // if err != nil { - // return err - // } - //builder.ConsoleFile = consoleFile.Name() - builder.ConsoleFile = "console.txt" + // Create a temporary log file + tempLogFile := platform.CreateTempLogFile(builder) failConfig, err := conf.EmptyIgnition().Render(conf.FailWarnings) if err != nil { return errors.Wrapf(err, "creating empty config") } - // Craft an ingniton file that format a partition - formaterConfig := types.Config { + // Craft an ingniton file that formats a partition + formaterConfig := types.Config{ Ignition: types.Ignition{ Version: "3.2.0", }, - Storage: types.Storage { + Storage: types.Storage{ Filesystems: []types.Filesystem{ { Device: "/dev/disk/by-id/virtio-extra-boot", @@ -281,54 +260,10 @@ func dualBootfsIgnitionFailure(c cluster.TestCluster) error { builder.MemoryMiB = 1024 builder.Firmware = kola.QEMUOptions.Firmware - inst, err := builder.Exec() - if err != nil { - return err - } - defer inst.Destroy() - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) - defer cancel() - - errchan := make(chan error) - go func() { - resultingError := inst.WaitAll(ctx) - - if resultingError == nil { - resultingError = fmt.Errorf("bootfs unexpectedly succeeded") - } else if resultingError == platform.ErrInitramfsEmergency { - // Expectred initramfs failure, checking the console file to insure - // that coreos-unique-boot.service failed - b, err := os.ReadFile(builder.ConsoleFile) - if err != nil { - panic(err) - } - isExist, err := regexp.Match("Error: System has 2 devices with a filesystem labeled 'boot'", b) - if err != nil { - panic(err) - } - if isExist { - // The expected case - resultingError = nil - } else { - resultingError = errors.Wrapf(err, "expected coreos-unique-boot.service to fail") - } - } else { - resultingError = errors.Wrapf(err, "expected initramfs emergency.target error") - } - errchan <- resultingError - }() - - select { - case <-ctx.Done(): - if err := inst.Kill(); err != nil { - return errors.Wrapf(err, "failed to kill the vm instance") - } - return errors.Wrapf(ctx.Err(), "timed out waiting for initramfs error") - case err := <-errchan: - if err != nil { - return err - } - return nil + searchString := "Error: System has 2 devices with a filesystem labeled 'boot'" + if VerifyError(builder, tempLogFile, searchString) != nil { + return err } + return nil }