Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 25 additions & 4 deletions Sources/_InternalTestSupport/SwiftTesting+Tags.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import Testing
extension Tag {
public enum TestSize {}
public enum Feature {}
public enum Platform {}
@Tag public static var UserWorkflow: Tag
}

Expand All @@ -22,25 +23,35 @@ extension Tag.TestSize {
@Tag public static var large: Tag
}

extension Tag.Platform {
@Tag public static var FileSystem: Tag
}

extension Tag.Feature {
public enum Command {}
public enum CommandLineArguments {}
public enum EnvironmentVariables {}
public enum EnvironmentVariables {}
public enum PackageType {}
public enum ProductType {}
public enum TargetType {}
public enum Product {}

@Tag public static var BuildCache: Tag
@Tag public static var CodeCoverage: Tag
@Tag public static var CTargets: Tag
@Tag public static var DependencyResolution: Tag
@Tag public static var ModuleAliasing: Tag
@Tag public static var Mirror: Tag
@Tag public static var NetRc: Tag
@Tag public static var Plugin: Tag
@Tag public static var Resource: Tag
@Tag public static var SourceGeneration: Tag
@Tag public static var SpecialCharacters: Tag
@Tag public static var Snippets: Tag
@Tag public static var TestDiscovery: Tag
@Tag public static var Traits: Tag
@Tag public static var TargetSettings: Tag

@Tag public static var Version: Tag
}

extension Tag.Feature.Command {
Expand Down Expand Up @@ -75,9 +86,10 @@ extension Tag.Feature.CommandLineArguments {
@Tag public static var Verbose: Tag
@Tag public static var VeryVerbose: Tag
@Tag public static var Xlinker: Tag
@Tag public static var XbuildToolsSwiftc: Tag
@Tag public static var Xcc: Tag
@Tag public static var Xcxx: Tag
@Tag public static var SWIFT_ORIGINAL_PATH: Tag
@Tag public static var Xld: Tag
@Tag public static var Xswiftc: Tag
@Tag public static var TestParallel: Tag
@Tag public static var TestNoParallel: Tag
Expand All @@ -93,7 +105,8 @@ extension Tag.Feature.CommandLineArguments {
}

extension Tag.Feature.CommandLineArguments.Experimental {
@Tag public static var BuildDylibsAsFrameworks: Tag
@Tag public static var BuildDylibsAsFrameworks: Tag
@Tag public static var PruneUnusedDependencies: Tag
}
extension Tag.Feature.EnvironmentVariables {
@Tag public static var CUSTOM_SWIFT_VERSION: Tag
Expand Down Expand Up @@ -143,9 +156,16 @@ extension Tag.Feature.Command.PackageRegistry {
}

extension Tag.Feature.TargetType {
public enum BinaryTarget {}
@Tag public static var Executable: Tag
@Tag public static var Library: Tag
@Tag public static var Macro: Tag
@Tag public static var Test: Tag
}

extension Tag.Feature.TargetType.BinaryTarget {
@Tag public static var ArtifactBundle: Tag
@Tag public static var XCFramework: Tag
}

extension Tag.Feature.ProductType {
Expand All @@ -157,6 +177,7 @@ extension Tag.Feature.ProductType {
}
extension Tag.Feature.PackageType {
@Tag public static var Library: Tag
@Tag public static var Empty: Tag
@Tag public static var Executable: Tag
@Tag public static var Tool: Tag
@Tag public static var Plugin: Tag
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import TSCclibc // for SPM_posix_spawn_file_actions_addchdir_np_supported

extension Trait where Self == Testing.ConditionTrait {
/// Skip test if the host operating system does not match the running OS.
public static func requireHostOS(_ os: OperatingSystem, when condition: Bool = true) -> Self {
enabled("This test requires a \(os) host OS.") {
public static func requireHostOS(_ os: OperatingSystem, _ comment: Comment? = nil, when condition: Bool = true) -> Self {
enabled(comment ?? "This test requires a \(os) host OS.") {
ProcessInfo.hostOperatingSystem == os && condition
}
}
Expand Down
6 changes: 6 additions & 0 deletions Tests/BasicsTests/FileSystem/InMemoryFilesSystemTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ let isLinux = true
let isLinux = false
#endif

@Suite(
.tags(
.TestSize.small,
.Platform.FileSystem,
),
)
struct InMemoryFileSystemTests {
@Test(
arguments: [
Expand Down
6 changes: 6 additions & 0 deletions Tests/BasicsTests/FileSystem/PathTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ private var windows: Bool { false }
#endif


@Suite(
.tags(
.TestSize.small,
.Platform.FileSystem,
),
)
struct PathTests {
struct AbsolutePathTests {
private func pathStringIsSetCorrectlyTestImplementation(path: String, expected: String, label: String) {
Expand Down
208 changes: 106 additions & 102 deletions Tests/BasicsTests/FileSystem/VFSTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,110 +37,114 @@ func testWithTemporaryDirectory(


struct VFSTests {
@Test
@Test(
.issue("https://github.com/swiftlang/swift-package-manager/issues/9310", relationship: .defect),
.skipHostOS(.windows, "Test currently fails with: you don't have permissions."),
.tags(
.TestSize.medium,
.Platform.FileSystem,
.UserWorkflow,
)
)
func localBasics() throws {
try withKnownIssue("Permission issues on Windows") {
// tiny PE binary from: https://archive.is/w01DO
let contents: [UInt8] = [
0x4d, 0x5a, 0x00, 0x00, 0x50, 0x45, 0x00, 0x00, 0x4c, 0x01, 0x01, 0x00,
0x6a, 0x2a, 0x58, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x04, 0x00, 0x03, 0x01, 0x0b, 0x01, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x68, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02
]

let fs = localFileSystem
try withTemporaryFile { [contents] vfsPath in
try withTemporaryDirectory(removeTreeOnDeinit: true) { [contents] tempDirPath in
let file = tempDirPath.appending("best")
try fs.writeFileContents(file, string: "best")

let sym = tempDirPath.appending("hello")
try fs.createSymbolicLink(sym, pointingAt: file, relative: false)

let executable = tempDirPath.appending("exec-foo")
try fs.writeFileContents(executable, bytes: ByteString(contents))
#if !os(Windows)
try fs.chmod(.executable, path: executable, options: [])
#endif

let executableSym = tempDirPath.appending("exec-sym")
try fs.createSymbolicLink(executableSym, pointingAt: executable, relative: false)

try fs.createDirectory(tempDirPath.appending("dir"))
try fs.writeFileContents(tempDirPath.appending(components: ["dir", "file"]), bytes: [])

try VirtualFileSystem.serializeDirectoryTree(tempDirPath, into: AbsolutePath(vfsPath.path), fs: fs, includeContents: [executable])
}

let vfs = try VirtualFileSystem(path: vfsPath.path, fs: fs)

// exists()
#expect(vfs.exists(AbsolutePath("/")))
#expect(!vfs.exists(AbsolutePath("/does-not-exist")))

// isFile()
let filePath = AbsolutePath("/best")
#expect(vfs.exists(filePath))
#expect(vfs.isFile(filePath))
#expect(try vfs.getFileInfo(filePath).fileType == .typeRegular)
#expect(!vfs.isDirectory(filePath))
#expect(!vfs.isFile(AbsolutePath("/does-not-exist")))
#expect(!vfs.isSymlink(AbsolutePath("/does-not-exist")))
#expect(throws: (any Error).self) {
try vfs.getFileInfo(AbsolutePath("/does-not-exist"))
}

// isSymlink()
let symPath = AbsolutePath("/hello")
#expect(vfs.isSymlink(symPath))
#expect(vfs.isFile(symPath))
#expect(try vfs.getFileInfo(symPath).fileType == .typeSymbolicLink)
#expect(!vfs.isDirectory(symPath))

// isExecutableFile
let executablePath = AbsolutePath("/exec-foo")
let executableSymPath = AbsolutePath("/exec-sym")
#expect(vfs.isExecutableFile(executablePath))
#expect(vfs.isExecutableFile(executableSymPath))
#expect(vfs.isSymlink(executableSymPath))
#expect(!vfs.isExecutableFile(symPath))
#expect(!vfs.isExecutableFile(filePath))
#expect(!vfs.isExecutableFile(AbsolutePath("/does-not-exist")))
#expect(!vfs.isExecutableFile(AbsolutePath("/")))

// readFileContents
let execFileContents = try vfs.readFileContents(executablePath)
#expect(execFileContents == ByteString(contents))

// isDirectory()
#expect(vfs.isDirectory(AbsolutePath("/")))
#expect(!vfs.isDirectory(AbsolutePath("/does-not-exist")))

// getDirectoryContents()
let dirContents = try vfs.getDirectoryContents(AbsolutePath("/"))
#expect(dirContents.sorted() == ["best", "dir", "exec-foo", "exec-sym", "hello"])
#expect {try vfs.getDirectoryContents(AbsolutePath("/does-not-exist"))} throws: { error in
(error.localizedDescription == "no such file or directory: \(AbsolutePath("/does-not-exist"))")
}

let thisDirectoryContents = try vfs.getDirectoryContents(AbsolutePath("/"))
#expect(!thisDirectoryContents.contains(where: { $0 == "." }))
#expect(!thisDirectoryContents.contains(where: { $0 == ".." }))
#expect(thisDirectoryContents.sorted() == ["best", "dir", "exec-foo", "exec-sym", "hello"])

let contents = try vfs.getDirectoryContents(AbsolutePath("/dir"))
#expect(contents == ["file"])

let fileContents = try vfs.readFileContents(AbsolutePath("/dir/file"))
#expect(fileContents == "")
// tiny PE binary from: https://archive.is/w01DO
let contents: [UInt8] = [
0x4d, 0x5a, 0x00, 0x00, 0x50, 0x45, 0x00, 0x00, 0x4c, 0x01, 0x01, 0x00,
0x6a, 0x2a, 0x58, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x04, 0x00, 0x03, 0x01, 0x0b, 0x01, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x68, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02
]

let fs = localFileSystem
try withTemporaryFile { [contents] vfsPath in
try withTemporaryDirectory(removeTreeOnDeinit: true) { [contents] tempDirPath in
let file = tempDirPath.appending("best")
try fs.writeFileContents(file, string: "best")

let sym = tempDirPath.appending("hello")
try fs.createSymbolicLink(sym, pointingAt: file, relative: false)

let executable = tempDirPath.appending("exec-foo")
try fs.writeFileContents(executable, bytes: ByteString(contents))
#if !os(Windows)
try fs.chmod(.executable, path: executable, options: [])
#endif

let executableSym = tempDirPath.appending("exec-sym")
try fs.createSymbolicLink(executableSym, pointingAt: executable, relative: false)

try fs.createDirectory(tempDirPath.appending("dir"))
try fs.writeFileContents(tempDirPath.appending(components: ["dir", "file"]), bytes: [])

try VirtualFileSystem.serializeDirectoryTree(tempDirPath, into: AbsolutePath(vfsPath.path), fs: fs, includeContents: [executable])
}
} when: {
ProcessInfo.hostOperatingSystem == .windows

let vfs = try VirtualFileSystem(path: vfsPath.path, fs: fs)

// exists()
#expect(vfs.exists(AbsolutePath("/")))
#expect(!vfs.exists(AbsolutePath("/does-not-exist")))

// isFile()
let filePath = AbsolutePath("/best")
#expect(vfs.exists(filePath))
#expect(vfs.isFile(filePath))
#expect(try vfs.getFileInfo(filePath).fileType == .typeRegular)
#expect(!vfs.isDirectory(filePath))
#expect(!vfs.isFile(AbsolutePath("/does-not-exist")))
#expect(!vfs.isSymlink(AbsolutePath("/does-not-exist")))
#expect(throws: (any Error).self) {
try vfs.getFileInfo(AbsolutePath("/does-not-exist"))
}

// isSymlink()
let symPath = AbsolutePath("/hello")
#expect(vfs.isSymlink(symPath))
#expect(vfs.isFile(symPath))
#expect(try vfs.getFileInfo(symPath).fileType == .typeSymbolicLink)
#expect(!vfs.isDirectory(symPath))

// isExecutableFile
let executablePath = AbsolutePath("/exec-foo")
let executableSymPath = AbsolutePath("/exec-sym")
#expect(vfs.isExecutableFile(executablePath))
#expect(vfs.isExecutableFile(executableSymPath))
#expect(vfs.isSymlink(executableSymPath))
#expect(!vfs.isExecutableFile(symPath))
#expect(!vfs.isExecutableFile(filePath))
#expect(!vfs.isExecutableFile(AbsolutePath("/does-not-exist")))
#expect(!vfs.isExecutableFile(AbsolutePath("/")))

// readFileContents
let execFileContents = try vfs.readFileContents(executablePath)
#expect(execFileContents == ByteString(contents))

// isDirectory()
#expect(vfs.isDirectory(AbsolutePath("/")))
#expect(!vfs.isDirectory(AbsolutePath("/does-not-exist")))

// getDirectoryContents()
let dirContents = try vfs.getDirectoryContents(AbsolutePath("/"))
#expect(dirContents.sorted() == ["best", "dir", "exec-foo", "exec-sym", "hello"])
#expect {try vfs.getDirectoryContents(AbsolutePath("/does-not-exist"))} throws: { error in
(error.localizedDescription == "no such file or directory: \(AbsolutePath("/does-not-exist"))")
}

let thisDirectoryContents = try vfs.getDirectoryContents(AbsolutePath("/"))
#expect(!thisDirectoryContents.contains(where: { $0 == "." }))
#expect(!thisDirectoryContents.contains(where: { $0 == ".." }))
#expect(thisDirectoryContents.sorted() == ["best", "dir", "exec-foo", "exec-sym", "hello"])

let contents = try vfs.getDirectoryContents(AbsolutePath("/dir"))
#expect(contents == ["file"])

let fileContents = try vfs.readFileContents(AbsolutePath("/dir/file"))
#expect(fileContents == "")
}
}
}
7 changes: 7 additions & 0 deletions Tests/BuildTests/BuildSystemDelegateTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,13 @@ struct BuildSystemDelegateTests {
@Test(
.issue("https://github.com/swiftlang/swift-package-manager/issues/8540", relationship: .defect), // Package fails to build when the test is being executed"
.requiresSDKDependentTestsSupport,
.tags(
.Feature.Command.Build,
.Feature.TargetType.Executable,
.Feature.TargetType.Library,
.Feature.CommandLineArguments.BuildSystem,
.Feature.CommandLineArguments.Configuration,
),
arguments: getBuildData(for: SupportedBuildSystemOnAllPlatforms),
)
func filterNonFatalCodesignMessages(
Expand Down
2 changes: 2 additions & 0 deletions Tests/BuildTests/PluginsBuildPlanTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ struct PluginsBuildPlanTests {
@Test(
.tags(
.Feature.Command.Build,
.Feature.Plugin,
.Feature.SourceGeneration,
),
.IssueWindowsPathTestsFailures, // Fails to build the project to due to incorrect Path handling
arguments: BuildConfiguration.allCases,
Expand Down
Loading