Skip to content

Commit cd312ae

Browse files
committed
StdlibUnittest: refactor child I/O code
Detangle protocol parsing logic from I/O handling.
1 parent d872098 commit cd312ae

File tree

1 file changed

+86
-72
lines changed

1 file changed

+86
-72
lines changed

stdlib/private/StdlibUnittest/StdlibUnittest.swift.gyb

Lines changed: 86 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,49 @@ struct _ParentProcess {
706706
return status
707707
}
708708

709+
internal mutating func _readFromChild(
710+
onStdoutLine: (String) -> Bool,
711+
onStderrLine: (String) -> Bool
712+
) {
713+
var readfds = _stdlib_fd_set()
714+
var writefds = _stdlib_fd_set()
715+
var errorfds = _stdlib_fd_set()
716+
var done = false
717+
while !((_childStdout.isEOF && _childStderr.isEOF) || done) {
718+
readfds.zero()
719+
errorfds.zero()
720+
if !_childStdout.isEOF {
721+
readfds.set(_childStdout.fd)
722+
errorfds.set(_childStdout.fd)
723+
}
724+
if !_childStderr.isEOF {
725+
readfds.set(_childStderr.fd)
726+
errorfds.set(_childStderr.fd)
727+
}
728+
var ret: CInt
729+
repeat {
730+
ret = _stdlib_select(&readfds, &writefds, &errorfds, nil)
731+
} while ret == -1 && errno == EINTR
732+
if ret <= 0 {
733+
fatalError("select() returned an error")
734+
}
735+
if readfds.isset(_childStdout.fd) || errorfds.isset(_childStdout.fd) {
736+
_childStdout.read()
737+
while let line = _childStdout.getline() {
738+
done = onStdoutLine(line)
739+
}
740+
continue
741+
}
742+
if readfds.isset(_childStderr.fd) || errorfds.isset(_childStderr.fd) {
743+
_childStderr.read()
744+
while let line = _childStderr.getline() {
745+
done = onStderrLine(line)
746+
}
747+
continue
748+
}
749+
}
750+
}
751+
709752
/// Returns the values of the corresponding variables in the child process.
710753
internal mutating func _runTestInChild(
711754
_ testSuite: TestSuite,
@@ -733,95 +776,66 @@ struct _ParentProcess {
733776
_childStdin.close()
734777
}
735778

736-
var readfds = _stdlib_fd_set()
737-
var writefds = _stdlib_fd_set()
738-
var errorfds = _stdlib_fd_set()
739779
var stdoutSeenCrashDelimiter = false
740780
var stderrSeenCrashDelimiter = false
741781
var stdoutEnd = false
742782
var stderrEnd = false
743783
var capturedCrashStdout: [String] = []
744784
var capturedCrashStderr: [String] = []
745785
var anyExpectFailedInChild = false
746-
while !((_childStdout.isEOF && _childStderr.isEOF) ||
747-
(stdoutEnd && stderrEnd)) {
748786

749-
readfds.zero()
750-
errorfds.zero()
751-
if !_childStdout.isEOF {
752-
readfds.set(_childStdout.fd)
753-
errorfds.set(_childStdout.fd)
754-
}
755-
if !_childStderr.isEOF {
756-
readfds.set(_childStderr.fd)
757-
errorfds.set(_childStderr.fd)
758-
}
759-
var ret: CInt
760-
repeat {
761-
ret = _stdlib_select(&readfds, &writefds, &errorfds, nil)
762-
} while ret == -1 && errno == EINTR
763-
if ret <= 0 {
764-
fatalError("select() returned an error")
765-
}
766-
if readfds.isset(_childStdout.fd) || errorfds.isset(_childStdout.fd) {
767-
_childStdout.read()
768-
while var line = _childStdout.getline() {
769-
if let index = findSubstring(line, _stdlibUnittestStreamPrefix) {
770-
let controlMessage =
771-
line[index..<line.endIndex]._split(separator: ";")
772-
switch controlMessage[1] {
773-
case "expectCrash":
774-
stdoutSeenCrashDelimiter = true
775-
anyExpectFailedInChild = controlMessage[2] == "true"
776-
case "end":
777-
stdoutEnd = true
778-
anyExpectFailedInChild = controlMessage[2] == "true"
779-
default:
780-
fatalError("unexpected message")
781-
}
782-
line = line[line.startIndex..<index]
783-
if line.isEmpty {
784-
continue
785-
}
787+
func processLine(_ line: String, isStdout: Bool) -> Bool {
788+
var line = line
789+
if let index = findSubstring(line, _stdlibUnittestStreamPrefix) {
790+
let controlMessage =
791+
line[index..<line.endIndex]._split(separator: ";")
792+
switch controlMessage[1] {
793+
case "expectCrash":
794+
if isStdout {
795+
stdoutSeenCrashDelimiter = true
796+
anyExpectFailedInChild = controlMessage[2] == "true"
797+
} else {
798+
stderrSeenCrashDelimiter = true
786799
}
787-
if stdoutSeenCrashDelimiter {
788-
capturedCrashStdout.append(line)
800+
case "end":
801+
if isStdout {
802+
stdoutEnd = true
803+
anyExpectFailedInChild = controlMessage[2] == "true"
804+
} else {
805+
stderrEnd = true
789806
}
790-
print("stdout>>> \(line)")
807+
default:
808+
fatalError("unexpected message")
809+
}
810+
line = line[line.startIndex..<index]
811+
if line.isEmpty {
812+
return stdoutEnd && stderrEnd
791813
}
792-
continue
793814
}
794-
if readfds.isset(_childStderr.fd) || errorfds.isset(_childStderr.fd) {
795-
_childStderr.read()
796-
while var line = _childStderr.getline() {
797-
if let index = findSubstring(line, _stdlibUnittestStreamPrefix) {
798-
let controlMessage =
799-
line[index..<line.endIndex]._split(separator: ";")
800-
switch controlMessage[1] {
801-
case "expectCrash":
802-
stderrSeenCrashDelimiter = true
803-
case "end":
804-
stderrEnd = true
805-
default:
806-
fatalError("unexpected message")
807-
}
808-
line = line[line.startIndex..<index]
809-
if line.isEmpty {
810-
continue
811-
}
812-
}
813-
if stderrSeenCrashDelimiter {
814-
capturedCrashStderr.append(line)
815-
if findSubstring(line, _crashedPrefix) != nil {
816-
line = "OK: saw expected \"\(line.lowercased())\""
817-
}
815+
if isStdout {
816+
if stdoutSeenCrashDelimiter {
817+
capturedCrashStdout.append(line)
818+
}
819+
} else {
820+
if stderrSeenCrashDelimiter {
821+
capturedCrashStderr.append(line)
822+
if findSubstring(line, _crashedPrefix) != nil {
823+
line = "OK: saw expected \"\(line.lowercased())\""
818824
}
819-
print("stderr>>> \(line)")
820825
}
821-
continue
822826
}
827+
if isStdout {
828+
print("stdout>>> \(line)")
829+
} else {
830+
print("stderr>>> \(line)")
831+
}
832+
return stdoutEnd && stderrEnd
823833
}
824834

835+
_readFromChild(
836+
onStdoutLine: { processLine($0, isStdout: true) },
837+
onStderrLine: { processLine($0, isStdout: false) })
838+
825839
// Check if the child has sent us "end" markers for the current test.
826840
if stdoutEnd && stderrEnd {
827841
var status: ProcessTerminationStatus? = nil

0 commit comments

Comments
 (0)