diff --git a/Sources/Containerization/VZVirtualMachineInstance.swift b/Sources/Containerization/VZVirtualMachineInstance.swift index a5107ea2..87af204d 100644 --- a/Sources/Containerization/VZVirtualMachineInstance.swift +++ b/Sources/Containerization/VZVirtualMachineInstance.swift @@ -294,16 +294,18 @@ extension VZVirtualMachineInstance.Configuration { try mount.configure(config: &config) } - #if arch(arm64) - let platform = VZGenericPlatformConfiguration() - if VZGenericPlatformConfiguration.isNestedVirtualizationSupported { - platform.isNestedVirtualizationEnabled = self.nestedVirtualization + // We shouldn't silently succeed if the user asked for virt and their hardware does + // not support it. + if !VZGenericPlatformConfiguration.isNestedVirtualizationSupported && self.nestedVirtualization { + throw ContainerizationError( + .unsupported, + message: "nested virtualization is not supported on the platform" + ) } + platform.isNestedVirtualizationEnabled = self.nestedVirtualization config.platform = platform - #endif - try config.validate() return config } diff --git a/Sources/Integration/Suite.swift b/Sources/Integration/Suite.swift index d7cfb07e..b5760ada 100644 --- a/Sources/Integration/Suite.swift +++ b/Sources/Integration/Suite.swift @@ -37,6 +37,14 @@ enum IntegrationError: Swift.Error { case noOutput } +struct SkipTest: Swift.Error, CustomStringConvertible { + let reason: String + + var description: String { + reason + } +} + @main struct IntegrationSuite: AsyncParsableCommand { static let appRoot: URL = { @@ -209,6 +217,7 @@ struct IntegrationSuite: AsyncParsableCommand { ] var passed = 0 + var skipped = 0 for (name, test) in tests { do { log.info("test \(name) started...") @@ -218,15 +227,24 @@ struct IntegrationSuite: AsyncParsableCommand { let lasted = CFAbsoluteTimeGetCurrent() - started log.info("✅ test \(name) complete in \(lasted)s.") passed += 1 + } catch let err as SkipTest { + log.info("⏭️ skipped test: \(err)") + skipped += 1 } catch { log.error("❌ test \(name) failed: \(error)") } } let ended = CFAbsoluteTimeGetCurrent() - suiteStarted - log.info("\nintegration suite completed in \(ended)s with \(passed)/\(tests.count) passed!") + var finishingText = "\n\nIntegration suite completed in \(ended)s with \(passed)/\(tests.count) passed" + if skipped > 0 { + finishingText += " and \(skipped)/\(tests.count) skipped" + } + finishingText += "!" - if passed < tests.count { + log.info("\(finishingText)") + + if passed + skipped < tests.count { log.error("❌") throw ExitCode(1) } diff --git a/Sources/Integration/VMTests.swift b/Sources/Integration/VMTests.swift index e20013ad..682558b9 100644 --- a/Sources/Integration/VMTests.swift +++ b/Sources/Integration/VMTests.swift @@ -17,6 +17,7 @@ import ArgumentParser import Containerization +import ContainerizationError import ContainerizationOCI import Foundation import Logging @@ -69,8 +70,16 @@ extension IntegrationSuite { container.virtualization = true - try await container.create() - try await container.start() + do { + try await container.create() + try await container.start() + } catch { + if let err = error as? ContainerizationError { + if err.code == .unsupported { + throw SkipTest(reason: err.message) + } + } + } let status = try await container.wait() try await container.stop()