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
4 changes: 2 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ let package = Package(
],
dependencies: [
.package(url: "https://github.com/onevcat/Rainbow.git", from: "3.0.0"),
.package(url: "https://github.com/JohnSundell/ShellOut.git", from: "2.1.0"),
.package(url: "https://github.com/apple/swift-package-manager.git", from: "0.1.0"),
],
targets: [
.target(
name: "LiteSupport",
dependencies: ["Rainbow", "ShellOut"]),
dependencies: ["Rainbow", "Utility"]),

// This needs to be named `lite-test` instead of `lite` because consumers
// of `lite` should use the target name `lite`.
Expand Down
2 changes: 1 addition & 1 deletion Sources/LiteSupport/ParallelExecutor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ final class ParallelExecutor<TaskResult> {
/// Adds a task to run asynchronously on the next worker. Workers are chosen
/// in a round-robin fashion.
func addTask(_ work: @escaping () -> TaskResult) {
queues[nextTask % queues.count].async(group: group) {
queues[nextTask % queues.count].async(group: group, qos: .userInitiated) {
self.addResult(work())
}
}
Expand Down
90 changes: 80 additions & 10 deletions Sources/LiteSupport/TestRunner.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@

import Foundation
import Rainbow
import ShellOut
import Basic
import Utility
import POSIX
import Dispatch

/// Specifies how to parallelize test runs.
Expand Down Expand Up @@ -36,7 +38,7 @@ public enum ParallelismLevel {
class TestRunner {

/// The test directory in which tests reside.
let testDir: URL
let testDir: Foundation.URL

/// The set of substitutions to apply to each run line.
let substitutor: Substitutor
Expand Down Expand Up @@ -92,7 +94,7 @@ class TestRunner {
let enumerator = fm.enumerator(at: testDir,
includingPropertiesForKeys: nil)!
var files = [TestFile]()
for case let file as URL in enumerator {
for case let file as Foundation.URL in enumerator {
guard pathExtensions.contains(file.pathExtension) else { continue }
let nsPath = NSString(string: file.path)
let matchesFilter = filters.contains {
Expand Down Expand Up @@ -250,15 +252,26 @@ class TestRunner {
let exitCode: Int
let bash = file.makeCommandLine(line, substitutor: substitutor)
do {
stdout = try shellOut(to: bash)
let args = bash.split(separator: " ").map { String($0 as Substring) }
let result = try Process.popen(arguments: args)
stdout = try result.utf8Output().chomp()
stderr = ""
exitCode = 0
} catch let error as ShellOutError {
stderr = error.message
stdout = error.output
exitCode = Int(error.terminationStatus)
switch result.exitStatus {
case let .terminated(code: code):
exitCode = Int(code)
case let .signalled(signal: code):
exitCode = Int(code)
}
} catch let error as SystemError {
stderr = error.description
stdout = ""
exitCode = Int(error.exitCode)
} catch let error as Basic.Process.Error {
stderr = error.description
stdout = ""
exitCode = Int(EXIT_FAILURE)
} catch {
fatalError("unhandled error")
fatalError("\(error)")
}
let end = Date()
results.append(TestResult(line: line,
Expand All @@ -271,3 +284,60 @@ class TestRunner {
return results
}
}

extension SystemError {
var exitCode: Int32 {
switch self {
case .chdir(let errno, _):
return errno
case .close(let errno):
return errno
case .dirfd(let errno, _):
return errno
case .exec(let errno, _, _):
return errno
case .fgetc(let errno):
return errno
case .fread(let errno):
return errno
case .getcwd(let errno):
return errno
case .mkdir(let errno, _):
return errno
case .mkdtemp(let errno):
return errno
case .pipe(let errno):
return errno
case .posix_spawn(let errno, _):
return errno
case .popen(let errno, _):
return errno
case .read(let errno):
return errno
case .readdir(let errno, _):
return errno
case .realpath(let errno, _):
return errno
case .rename(let errno, _, _):
return errno
case .rmdir(let errno, _):
return errno
case .setenv(let errno, _):
return errno
case .stat(let errno, _):
return errno
case .symlink(let errno, _, _):
return errno
case .symlinkat(let errno, _):
return errno
case .unlink(let errno, _):
return errno
case .unsetenv(let errno, _):
return errno
case .waitpid(let errno):
return errno
case .usleep(let errno):
return errno
}
}
}