diff --git a/.github/workflows/linux-build.yml b/.github/workflows/linux-build.yml index 230bafdf..2d0acac6 100644 --- a/.github/workflows/linux-build.yml +++ b/.github/workflows/linux-build.yml @@ -55,3 +55,6 @@ jobs: - name: Build vminitd (musl) run: make -C vminitd + + - name: Run unit tests + run: swift test --disable-automatic-resolution -Xswiftc -warnings-as-errors diff --git a/Makefile b/Makefile index b2f61687..3bb39d18 100644 --- a/Makefile +++ b/Makefile @@ -89,6 +89,10 @@ ifeq ($(LIBC),all) else $(call linux_run,make containerization && make -C vminitd LIBC=$(LIBC)) endif + +.PHONY: linux-test +linux-test: + $(call linux_run,swift test $(SWIFT_CONFIGURATION)) endif .PHONY: all diff --git a/Tests/ContainerizationOCITests/RegistryClientTests.swift b/Tests/ContainerizationOCITests/RegistryClientTests.swift index 6b00ea5e..f25fcb17 100644 --- a/Tests/ContainerizationOCITests/RegistryClientTests.swift +++ b/Tests/ContainerizationOCITests/RegistryClientTests.swift @@ -199,7 +199,7 @@ struct OCIClientTests: ~Copyable { buffer.withUnsafeReadableBytes { pointer in let unsafeBufferPointer = pointer.bindMemory(to: UInt8.self) if let addr = unsafeBufferPointer.baseAddress { - outputStream!.write(addr, maxLength: buffer.readableBytes) + _ = outputStream!.write(addr, maxLength: buffer.readableBytes) } } } diff --git a/Tests/ContainerizationOSTests/FileDescriptor+SecurePathTests.swift b/Tests/ContainerizationOSTests/FileDescriptor+SecurePathTests.swift index 17280a7d..445f6ab6 100644 --- a/Tests/ContainerizationOSTests/FileDescriptor+SecurePathTests.swift +++ b/Tests/ContainerizationOSTests/FileDescriptor+SecurePathTests.swift @@ -132,8 +132,8 @@ struct FileDescriptorPathSecureTests { let attrs = try FileManager.default.attributesOfItem(atPath: dirPath.string) let posixPerms = attrs[.posixPermissions] as? NSNumber // Mask to permission bits only (not file type bits) - let permMask: UInt16 = 0o777 - let actualPerms = (posixPerms?.uint16Value ?? 0) & permMask + let permMask: CModeT = 0o777 + let actualPerms = CModeT(posixPerms?.uint16Value ?? 0) & permMask let expectedPerms = permissions.rawValue & permMask #expect( actualPerms == expectedPerms, @@ -396,7 +396,7 @@ struct FileDescriptorPathSecureTests { // Create a regular file let filePath = tempPath.appending("testfile.txt") - FileManager.default.createFile(atPath: filePath.string, contents: Data("test".utf8)) + _ = FileManager.default.createFile(atPath: filePath.string, contents: Data("test".utf8)) // Verify file exists #expect(FileManager.default.fileExists(atPath: filePath.string)) @@ -452,9 +452,9 @@ struct FileDescriptorPathSecureTests { let deepdirPath = subdirPath.appending("deepdir") try FileManager.default.createDirectory(atPath: deepdirPath.string, withIntermediateDirectories: true) - FileManager.default.createFile(atPath: nestedPath.appending("file1.txt").string, contents: Data("1".utf8)) - FileManager.default.createFile(atPath: subdirPath.appending("file2.txt").string, contents: Data("2".utf8)) - FileManager.default.createFile(atPath: deepdirPath.appending("file3.txt").string, contents: Data("3".utf8)) + _ = FileManager.default.createFile(atPath: nestedPath.appending("file1.txt").string, contents: Data("1".utf8)) + _ = FileManager.default.createFile(atPath: subdirPath.appending("file2.txt").string, contents: Data("2".utf8)) + _ = FileManager.default.createFile(atPath: deepdirPath.appending("file3.txt").string, contents: Data("3".utf8)) // Verify structure exists #expect(FileManager.default.fileExists(atPath: nestedPath.string)) @@ -491,7 +491,7 @@ struct FileDescriptorPathSecureTests { // Create target file and symlink let targetPath = tempPath.appending("target.txt") let linkPath = tempPath.appending("link") - FileManager.default.createFile(atPath: targetPath.string, contents: Data("target".utf8)) + _ = FileManager.default.createFile(atPath: targetPath.string, contents: Data("target".utf8)) try FileManager.default.createSymbolicLink(atPath: linkPath.string, withDestinationPath: "target.txt") // Verify both exist @@ -523,7 +523,7 @@ struct FileDescriptorPathSecureTests { let subdirPath = mixedPath.appending("subdir") try FileManager.default.createDirectory(atPath: subdirPath.string, withIntermediateDirectories: true) - FileManager.default.createFile(atPath: mixedPath.appending("file.txt").string, contents: Data("test".utf8)) + _ = FileManager.default.createFile(atPath: mixedPath.appending("file.txt").string, contents: Data("test".utf8)) try FileManager.default.createSymbolicLink( atPath: mixedPath.appending("link").string, withDestinationPath: "file.txt" @@ -643,7 +643,7 @@ struct FileDescriptorPathSecureTests { attributes: permissions.map { [.posixPermissions: $0.rawValue] } ) } - FileManager.default.createFile( + _ = FileManager.default.createFile( atPath: fullPath.string, contents: Data("test".utf8) ) diff --git a/Tests/ContainerizationOSTests/KeychainQueryTests.swift b/Tests/ContainerizationOSTests/KeychainQueryTests.swift index 54da7a52..301cc4fe 100644 --- a/Tests/ContainerizationOSTests/KeychainQueryTests.swift +++ b/Tests/ContainerizationOSTests/KeychainQueryTests.swift @@ -14,6 +14,8 @@ // limitations under the License. //===----------------------------------------------------------------------===// +#if os(macOS) + import Foundation import Testing @@ -77,3 +79,5 @@ struct KeychainQueryTests { ProcessInfo.processInfo.environment["CI"] != nil } } + +#endif diff --git a/Tests/ContainerizationOSTests/SocketTests.swift b/Tests/ContainerizationOSTests/SocketTests.swift index 03860144..e941cd4a 100644 --- a/Tests/ContainerizationOSTests/SocketTests.swift +++ b/Tests/ContainerizationOSTests/SocketTests.swift @@ -47,7 +47,7 @@ final class SocketTests { var cmsgBuf = [UInt8](repeating: 0, count: Int(CZ_CMSG_SPACE(Int(MemoryLayout.size)))) msg.msg_control = withUnsafeMutablePointer(to: &cmsgBuf[0]) { UnsafeMutableRawPointer($0) } - msg.msg_controllen = socklen_t(cmsgBuf.count) + msg.msg_controllen = .init(cmsgBuf.count) // Set up control message let cmsgPtr = withUnsafeMutablePointer(to: &msg) { CZ_CMSG_FIRSTHDR($0) } @@ -56,8 +56,8 @@ final class SocketTests { } cmsg.pointee.cmsg_level = SOL_SOCKET - cmsg.pointee.cmsg_type = SCM_RIGHTS - cmsg.pointee.cmsg_len = socklen_t(CZ_CMSG_LEN(Int(MemoryLayout.size))) + cmsg.pointee.cmsg_type = .init(SCM_RIGHTS) + cmsg.pointee.cmsg_len = .init(CZ_CMSG_LEN(Int(MemoryLayout.size))) guard let dataPtr = CZ_CMSG_DATA(cmsg) else { throw SocketError.invalidFileDescriptor @@ -78,7 +78,11 @@ final class SocketTests { func testSCMRightsFileDescriptorPassing() throws { // Create a socketpair for testing var fds: [Int32] = [0, 0] + #if os(macOS) let result = socketpair(AF_UNIX, SOCK_STREAM, 0, &fds) + #else + let result = socketpair(AF_UNIX, Int32(SOCK_STREAM.rawValue), 0, &fds) + #endif try #require(result == 0, "socketpair should succeed") defer { diff --git a/Tests/ContainerizationTests/ContainerManagerTests.swift b/Tests/ContainerizationTests/ContainerManagerTests.swift index dcac62bf..8b7f945d 100644 --- a/Tests/ContainerizationTests/ContainerManagerTests.swift +++ b/Tests/ContainerizationTests/ContainerManagerTests.swift @@ -14,6 +14,8 @@ // limitations under the License. //===----------------------------------------------------------------------===// +#if os(macOS) + import Containerization import ContainerizationArchive import ContainerizationError @@ -151,3 +153,5 @@ struct ContainerManagerTests { #expect(closureWasCalled, "configuration closure must be invoked to validate interfaces") } } + +#endif