1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
import Foundation
import SystemPackage
import WasmKit
import WasmKitWASI
import XCTest
final class IntegrationTests: XCTestCase {
func testRunAll() throws {
#if os(Android)
throw XCTSkip("unable to run spectest on Android due to missing files on emulator")
#endif
let testDir = URL(fileURLWithPath: #filePath)
.deletingLastPathComponent().deletingLastPathComponent().deletingLastPathComponent()
.appendingPathComponent("Vendor/wasi-testsuite")
for testSuitePath in ["tests/assemblyscript/testsuite", "tests/c/testsuite", "tests/rust/testsuite"] {
let suitePath = testDir.appendingPathComponent(testSuitePath)
try runTestSuite(path: suitePath)
}
}
struct SuiteManifest: Codable {
let name: String
}
static var skipTests: [String: [String: String]] {
#if os(Windows)
return [
"WASI Assemblyscript tests": [:],
"WASI C tests": [
"fdopendir-with-access": "Not implemented",
"fopen-with-access": "Not implemented",
"lseek": "Not implemented",
"pread-with-access": "Not implemented",
"pwrite-with-access": "Not implemented",
"stat-dev-ino": "Not implemented",
],
"WASI Rust tests": [
"close_preopen": "Not implemented",
"dangling_fd": "Not implemented",
"dangling_symlink": "Not implemented",
"directory_seek": "Not implemented",
"fd_advise": "Not implemented",
"fd_filestat_set": "Not implemented",
"fd_flags_set": "Not implemented",
"fd_readdir": "Not implemented",
"interesting_paths": "Not implemented",
],
]
#else
return [:]
#endif
}
func runTestSuite(path: URL) throws {
let manifestPath = path.appendingPathComponent("manifest.json")
let manifest = try JSONDecoder().decode(SuiteManifest.self, from: Data(contentsOf: manifestPath))
// Clean up **/*.cleanup
do {
let enumerator = FileManager.default.enumerator(at: path, includingPropertiesForKeys: nil, options: [.skipsHiddenFiles])!
for case let url as URL in enumerator {
if url.pathExtension == "cleanup" {
try FileManager.default.removeItem(at: url)
}
}
}
print("Running test suite: \(manifest.name)")
let tests = try FileManager.default.contentsOfDirectory(at: path, includingPropertiesForKeys: nil, options: [])
let skipTests = Self.skipTests[manifest.name] ?? [:]
for test in tests {
guard test.pathExtension == "wasm" else { continue }
let testName = test.deletingPathExtension().lastPathComponent
if let reason = skipTests[testName] {
print("Skipping test \(testName): \(reason)")
continue
}
try runTest(path: test)
}
}
struct CaseManifest: Codable {
var dirs: [String]?
var args: [String]?
var env: [String: String]?
var exitCode: UInt32?
static var empty: CaseManifest {
CaseManifest(dirs: nil, args: nil, env: nil, exitCode: nil)
}
}
func runTest(path: URL) throws {
let manifestPath = path.deletingPathExtension().appendingPathExtension("json")
var manifest: CaseManifest
if FileManager.default.fileExists(atPath: manifestPath.path) {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
manifest = try decoder.decode(CaseManifest.self, from: Data(contentsOf: manifestPath))
} else {
manifest = .empty
}
// HACK: WasmKit intentionally does not support fd_allocate
if path.lastPathComponent == "fd_advise.wasm" {
manifest.env = (manifest.env ?? [:]).merging(["NO_FD_ALLOCATE": "1"]) { _, new in new }
}
let suitePath = path.deletingLastPathComponent()
print("Testing \(path.path)")
let wasi = try WASIBridgeToHost(
args: [path.path] + (manifest.args ?? []),
environment: manifest.env ?? [:],
preopens: (manifest.dirs ?? []).reduce(into: [String: String]()) {
$0[$1] = suitePath.appendingPathComponent($1).path
}
)
let engine = Engine()
let store = Store(engine: engine)
var imports = Imports()
wasi.link(to: &imports, store: store)
let module = try parseWasm(filePath: FilePath(path.path))
let instance = try module.instantiate(store: store, imports: imports)
let exitCode = try wasi.start(instance)
XCTAssertEqual(exitCode, manifest.exitCode ?? 0, path.path)
}
}
|