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
384 changes: 190 additions & 194 deletions Tests/WASITests/IntegrationTests.swift

Large diffs are not rendered by default.

66 changes: 32 additions & 34 deletions Tests/WASITests/Platform/SandboxPrimitives/OpenParentTests.swift
Original file line number Diff line number Diff line change
@@ -1,42 +1,40 @@
#if canImport(Testing)
import Testing
import SystemPackage
import SystemPackage
import Testing

@testable import WASI
@testable import WASI

@Suite
struct OpenParentTests {
@Test
func testSplitParent() {
func check(
_ lhs: (FilePath, FilePath.Component)?,
_ rhs: (FilePath, FilePath.Component)?,
sourceLocation: SourceLocation = #_sourceLocation
) {
switch (lhs, rhs) {
case (.none, .none): return
case (.some(let lhs), .some(let rhs)):
#expect(lhs.0 == rhs.0, sourceLocation: sourceLocation)
#expect(lhs.1 == rhs.1, sourceLocation: sourceLocation)
default:
#expect((false), "\(String(describing: lhs)) and \(String(describing: rhs)) are not equal", sourceLocation: sourceLocation)
}
@Suite
struct OpenParentTests {
@Test
func testSplitParent() {
func check(
_ lhs: (FilePath, FilePath.Component)?,
_ rhs: (FilePath, FilePath.Component)?,
sourceLocation: SourceLocation = #_sourceLocation
) {
switch (lhs, rhs) {
case (.none, .none): return
case (.some(let lhs), .some(let rhs)):
#expect(lhs.0 == rhs.0, sourceLocation: sourceLocation)
#expect(lhs.1 == rhs.1, sourceLocation: sourceLocation)
default:
#expect((false), "\(String(describing: lhs)) and \(String(describing: rhs)) are not equal", sourceLocation: sourceLocation)
}
}

check(splitParent(path: ""), nil)
check(splitParent(path: ""), nil)

check(splitParent(path: "/"), (FilePath("/"), FilePath.Component(".")))
check(splitParent(path: "/."), (FilePath("/."), FilePath.Component(".")))
check(splitParent(path: "/a"), (FilePath("/"), FilePath.Component("a")))
check(splitParent(path: "/a/"), (FilePath("/a"), FilePath.Component(".")))
check(splitParent(path: "/a/."), (FilePath("/a/."), FilePath.Component(".")))
check(splitParent(path: "/a/.."), (FilePath("/a/.."), FilePath.Component(".")))
check(splitParent(path: "/"), (FilePath("/"), FilePath.Component(".")))
check(splitParent(path: "/."), (FilePath("/."), FilePath.Component(".")))
check(splitParent(path: "/a"), (FilePath("/"), FilePath.Component("a")))
check(splitParent(path: "/a/"), (FilePath("/a"), FilePath.Component(".")))
check(splitParent(path: "/a/."), (FilePath("/a/."), FilePath.Component(".")))
check(splitParent(path: "/a/.."), (FilePath("/a/.."), FilePath.Component(".")))

check(splitParent(path: "b"), (FilePath(""), FilePath.Component("b")))
check(splitParent(path: "b/."), (FilePath("b/."), FilePath.Component(".")))
check(splitParent(path: "b/.."), (FilePath("b/.."), FilePath.Component(".")))
check(splitParent(path: "b"), (FilePath(""), FilePath.Component("b")))
check(splitParent(path: "b/."), (FilePath("b/."), FilePath.Component(".")))
check(splitParent(path: "b/.."), (FilePath("b/.."), FilePath.Component(".")))

check(splitParent(path: "../c"), (FilePath(".."), FilePath.Component("c")))
}
check(splitParent(path: "../c"), (FilePath(".."), FilePath.Component("c")))
}
#endif
}
63 changes: 30 additions & 33 deletions Tests/WASITests/RandomBufferGeneratorTests.swift
Original file line number Diff line number Diff line change
@@ -1,40 +1,37 @@
#if canImport(Testing)
import Testing
import Testing

@testable import WASI
@testable import WASI

@Suite
struct RandomBufferGeneratorTests {
struct DeterministicGenerator: RandomNumberGenerator, RandomBufferGenerator {
var items: [UInt64]
@Suite
struct RandomBufferGeneratorTests {
struct DeterministicGenerator: RandomNumberGenerator, RandomBufferGenerator {
var items: [UInt64]

mutating func next() -> UInt64 {
items.removeFirst()
}
mutating func next() -> UInt64 {
items.removeFirst()
}
@Test
func defaultFill() {
var generator = DeterministicGenerator(items: [
0x0123_4567_89ab_cdef, 0xfedc_ba98_7654_3210, 0xdead_beef_badd_cafe,
])
for (bufferSize, expectedBytes): (Int, [UInt8]) in [
(10, [0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01, 0x10, 0x32]),
(2, [0xfe, 0xca]),
(0, []),
] {
var buffer: [UInt8] = Array(repeating: 0, count: bufferSize)
buffer.withUnsafeMutableBufferPointer {
generator.fill(buffer: $0)
}
let expected: [UInt8]
#if _endian(little)
expected = expectedBytes
#else
expected = Array(expectedBytes.reversed())
#endif
#expect(buffer == expected)
}
@Test
func defaultFill() {
var generator = DeterministicGenerator(items: [
0x0123_4567_89ab_cdef, 0xfedc_ba98_7654_3210, 0xdead_beef_badd_cafe,
])
for (bufferSize, expectedBytes): (Int, [UInt8]) in [
(10, [0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01, 0x10, 0x32]),
(2, [0xfe, 0xca]),
(0, []),
] {
var buffer: [UInt8] = Array(repeating: 0, count: bufferSize)
buffer.withUnsafeMutableBufferPointer {
generator.fill(buffer: $0)
}
let expected: [UInt8]
#if _endian(little)
expected = expectedBytes
#else
expected = Array(expectedBytes.reversed())
#endif
#expect(buffer == expected)
}
}

#endif
}
230 changes: 114 additions & 116 deletions Tests/WASITests/WASITests.swift
Original file line number Diff line number Diff line change
@@ -1,38 +1,57 @@
#if canImport(Testing)
import Testing

@testable import WASI

@Suite
struct WASITests {
#if !os(Windows)
@Test
func pathOpen() throws {
let t = try TestSupport.TemporaryDirectory()

try t.createDir(at: "External")
try t.createDir(at: "External/secret-dir-b")
try t.createFile(at: "External/secret-a.txt", contents: "Secret A")
try t.createFile(at: "External/secret-dir-b/secret-c.txt", contents: "Secret C")
try t.createDir(at: "Sandbox")
try t.createFile(at: "Sandbox/hello.txt", contents: "Hello")
try t.createSymlink(at: "Sandbox/link-hello.txt", to: "hello.txt")
try t.createDir(at: "Sandbox/world.dir")
try t.createSymlink(at: "Sandbox/link-world.dir", to: "world.dir")
try t.createSymlink(at: "Sandbox/link-external-secret-a.txt", to: "../External/secret-a.txt")
try t.createSymlink(at: "Sandbox/link-secret-dir-b", to: "../External/secret-dir-b")
try t.createSymlink(at: "Sandbox/link-updown-hello.txt", to: "../Sandbox/link-updown-hello.txt")
try t.createSymlink(at: "Sandbox/link-external-non-existent.txt", to: "../External/non-existent.txt")
try t.createSymlink(at: "Sandbox/link-root", to: "/")
try t.createSymlink(at: "Sandbox/link-loop.txt", to: "link-loop.txt")

let wasi = try WASIBridgeToHost(
preopens: ["/Sandbox": t.url.appendingPathComponent("Sandbox").path]
import Testing

@testable import WASI

@Suite
struct WASITests {
#if !os(Windows)
@Test
func pathOpen() throws {
let t = try TestSupport.TemporaryDirectory()

try t.createDir(at: "External")
try t.createDir(at: "External/secret-dir-b")
try t.createFile(at: "External/secret-a.txt", contents: "Secret A")
try t.createFile(at: "External/secret-dir-b/secret-c.txt", contents: "Secret C")
try t.createDir(at: "Sandbox")
try t.createFile(at: "Sandbox/hello.txt", contents: "Hello")
try t.createSymlink(at: "Sandbox/link-hello.txt", to: "hello.txt")
try t.createDir(at: "Sandbox/world.dir")
try t.createSymlink(at: "Sandbox/link-world.dir", to: "world.dir")
try t.createSymlink(at: "Sandbox/link-external-secret-a.txt", to: "../External/secret-a.txt")
try t.createSymlink(at: "Sandbox/link-secret-dir-b", to: "../External/secret-dir-b")
try t.createSymlink(at: "Sandbox/link-updown-hello.txt", to: "../Sandbox/link-updown-hello.txt")
try t.createSymlink(at: "Sandbox/link-external-non-existent.txt", to: "../External/non-existent.txt")
try t.createSymlink(at: "Sandbox/link-root", to: "/")
try t.createSymlink(at: "Sandbox/link-loop.txt", to: "link-loop.txt")

let wasi = try WASIBridgeToHost(
preopens: ["/Sandbox": t.url.appendingPathComponent("Sandbox").path]
)
let mntFd: WASIAbi.Fd = 3

func assertResolve(_ path: String, followSymlink: Bool, directory: Bool = false) throws {
let fd = try wasi.path_open(
dirFd: mntFd,
dirFlags: followSymlink ? [.SYMLINK_FOLLOW] : [],
path: path,
oflags: directory ? [.DIRECTORY] : [],
fsRightsBase: .DIRECTORY_BASE_RIGHTS,
fsRightsInheriting: .DIRECTORY_INHERITING_RIGHTS,
fdflags: []
)
let mntFd: WASIAbi.Fd = 3
try wasi.fd_close(fd: fd)
}

func assertResolve(_ path: String, followSymlink: Bool, directory: Bool = false) throws {
let fd = try wasi.path_open(
func assertNotResolve(
_ path: String,
followSymlink: Bool,
directory: Bool = false,
sourceLocation: SourceLocation = #_sourceLocation,
_ checkError: ((WASIAbi.Errno) throws -> Void)?
) throws {
do {
_ = try wasi.path_open(
dirFd: mntFd,
dirFlags: followSymlink ? [.SYMLINK_FOLLOW] : [],
path: path,
Expand All @@ -41,99 +60,78 @@
fsRightsInheriting: .DIRECTORY_INHERITING_RIGHTS,
fdflags: []
)
try wasi.fd_close(fd: fd)
}

func assertNotResolve(
_ path: String,
followSymlink: Bool,
directory: Bool = false,
sourceLocation: SourceLocation = #_sourceLocation,
_ checkError: ((WASIAbi.Errno) throws -> Void)?
) throws {
do {
_ = try wasi.path_open(
dirFd: mntFd,
dirFlags: followSymlink ? [.SYMLINK_FOLLOW] : [],
path: path,
oflags: directory ? [.DIRECTORY] : [],
fsRightsBase: .DIRECTORY_BASE_RIGHTS,
fsRightsInheriting: .DIRECTORY_INHERITING_RIGHTS,
fdflags: []
)
#expect((false), "Expected not to be able to open \(path)", sourceLocation: sourceLocation)
} catch {
guard let error = error as? WASIAbi.Errno else {
#expect((false), "Expected WASIAbi.Errno error but got \(error)", sourceLocation: sourceLocation)
return
}
try checkError?(error)
#expect((false), "Expected not to be able to open \(path)", sourceLocation: sourceLocation)
} catch {
guard let error = error as? WASIAbi.Errno else {
#expect((false), "Expected WASIAbi.Errno error but got \(error)", sourceLocation: sourceLocation)
return
}
try checkError?(error)
}
}

try assertNotResolve("non-existent.txt", followSymlink: false) { error in
#expect(error == .ENOENT)
}
try assertNotResolve("non-existent.txt", followSymlink: false) { error in
#expect(error == .ENOENT)
}

try assertResolve("link-hello.txt", followSymlink: true)
try assertNotResolve("link-hello.txt", followSymlink: false) { error in
#expect(error == .ELOOP)
}
try assertNotResolve("link-hello.txt", followSymlink: true, directory: true) { error in
#expect(error == .ENOTDIR)
}
try assertResolve("link-hello.txt", followSymlink: true)
try assertNotResolve("link-hello.txt", followSymlink: false) { error in
#expect(error == .ELOOP)
}
try assertNotResolve("link-hello.txt", followSymlink: true, directory: true) { error in
#expect(error == .ENOTDIR)
}

try assertNotResolve("link-hello.txt/", followSymlink: true) { error in
#expect(error == .ENOTDIR)
}
try assertNotResolve("link-hello.txt/", followSymlink: true) { error in
#expect(error == .ENOTDIR)
}

try assertResolve("link-world.dir", followSymlink: true)
try assertNotResolve("link-world.dir", followSymlink: false) { error in
#expect(error == .ELOOP)
}
try assertResolve("link-world.dir", followSymlink: true)
try assertNotResolve("link-world.dir", followSymlink: false) { error in
#expect(error == .ELOOP)
}

try assertNotResolve("link-external-secret-a.txt", followSymlink: true) { error in
#expect(error == .EPERM)
}
try assertNotResolve("link-external-secret-a.txt", followSymlink: false) { error in
#expect(error == .ELOOP)
}
try assertNotResolve("link-external-secret-a.txt", followSymlink: true) { error in
#expect(error == .EPERM)
}
try assertNotResolve("link-external-secret-a.txt", followSymlink: false) { error in
#expect(error == .ELOOP)
}

try assertNotResolve("link-external-non-existent.txt", followSymlink: true) { error in
#expect(error == .EPERM)
}
try assertNotResolve("link-external-non-existent.txt", followSymlink: false) { error in
#expect(error == .ELOOP)
}
try assertNotResolve("link-external-non-existent.txt", followSymlink: true) { error in
#expect(error == .EPERM)
}
try assertNotResolve("link-external-non-existent.txt", followSymlink: false) { error in
#expect(error == .ELOOP)
}

try assertNotResolve("link-updown-hello.txt", followSymlink: true) { error in
#expect(error == .EPERM)
}
try assertNotResolve("link-updown-hello.txt", followSymlink: false) { error in
#expect(error == .ELOOP)
}
try assertNotResolve("link-updown-hello.txt", followSymlink: true) { error in
#expect(error == .EPERM)
}
try assertNotResolve("link-updown-hello.txt", followSymlink: false) { error in
#expect(error == .ELOOP)
}

try assertNotResolve("link-secret-dir-b/secret-c.txt", followSymlink: true) { error in
#expect(error == .EPERM)
}
try assertNotResolve("link-secret-dir-b/secret-c.txt", followSymlink: false) { error in
#expect(error == .ENOTDIR)
}
try assertNotResolve("link-secret-dir-b/secret-c.txt", followSymlink: true) { error in
#expect(error == .EPERM)
}
try assertNotResolve("link-secret-dir-b/secret-c.txt", followSymlink: false) { error in
#expect(error == .ENOTDIR)
}

try assertNotResolve("link-root", followSymlink: true) { error in
#expect(error == .EPERM)
}
try assertNotResolve("link-root", followSymlink: false) { error in
#expect(error == .ELOOP)
}
try assertNotResolve("link-root", followSymlink: true) { error in
#expect(error == .EPERM)
}
try assertNotResolve("link-root", followSymlink: false) { error in
#expect(error == .ELOOP)
}

try assertNotResolve("link-loop.txt", followSymlink: false) { error in
#expect(error == .ELOOP)
}
try assertNotResolve("link-loop.txt", followSymlink: true) { error in
#expect(error == .ELOOP)
}
try assertNotResolve("link-loop.txt", followSymlink: false) { error in
#expect(error == .ELOOP)
}
try assertNotResolve("link-loop.txt", followSymlink: true) { error in
#expect(error == .ELOOP)
}
#endif
}
#endif
}
#endif
}
Loading