@@ -116,51 +116,72 @@ class ProcessTests: XCTestCase {
116116
117117 #if !os(Windows) // Signals are not supported in Windows
118118 func testSignals( ) throws {
119+ let group = DispatchGroup ( )
119120
120- // Test sigint terminates the script.
121- try testWithTemporaryDirectory { tmpdir in
122- let file = tmpdir. appending ( component: " pidfile " )
123- let waitFile = tmpdir. appending ( component: " waitFile " )
124- let process = Process ( args: script ( " print-pid " ) , file. pathString, waitFile. pathString)
125- try process. launch ( )
126- guard waitForFile ( waitFile) else {
127- return XCTFail ( " Couldn't launch the process " )
121+ DispatchQueue . global ( ) . async ( group: group) {
122+ do {
123+ // Test sigint terminates the script.
124+ try testWithTemporaryDirectory { tmpdir in
125+ let file = tmpdir. appending ( component: " pidfile " )
126+ let waitFile = tmpdir. appending ( component: " waitFile " )
127+ let process = Process ( args: self . script ( " print-pid " ) , file. pathString, waitFile. pathString)
128+ try process. launch ( )
129+ guard waitForFile ( waitFile) else {
130+ return XCTFail ( " Couldn't launch the process " )
131+ }
132+ // Ensure process has started running.
133+ guard try Process . running ( process. processID) else {
134+ return XCTFail ( " Couldn't launch the process " )
135+ }
136+ process. signal ( SIGINT)
137+ try process. waitUntilExit ( )
138+ // Ensure the process's pid was written.
139+ let contents = try localFileSystem. readFileContents ( file) . description
140+ XCTAssertEqual ( " \( process. processID) " , contents)
141+ XCTAssertFalse ( try Process . running ( process. processID) )
142+ }
143+ } catch {
144+ XCTFail ( " \( error) " )
128145 }
129- // Ensure process has started running.
130- XCTAssertTrue ( try Process . running ( process. processID) )
131- process. signal ( SIGINT)
132- try process. waitUntilExit ( )
133- // Ensure the process's pid was written.
134- let contents = try localFileSystem. readFileContents ( file) . description
135- XCTAssertEqual ( " \( process. processID) " , contents)
136- XCTAssertFalse ( try Process . running ( process. processID) )
137146 }
138147
139148 // Test SIGKILL terminates the subprocess and any of its subprocess.
140- try testWithTemporaryDirectory { tmpdir in
141- let file = tmpdir. appending ( component: " pidfile " )
142- let waitFile = tmpdir. appending ( component: " waitFile " )
143- let process = Process ( args: script ( " subprocess " ) , file. pathString, waitFile. pathString)
144- try process. launch ( )
145- guard waitForFile ( waitFile) else {
146- return XCTFail ( " Couldn't launch the process " )
147- }
148- // Ensure process has started running.
149- XCTAssertTrue ( try Process . running ( process. processID) )
150- process. signal ( SIGKILL)
151- let result = try process. waitUntilExit ( )
152- XCTAssertEqual ( result. exitStatus, . signalled( signal: SIGKILL) )
153- let json = try JSON ( bytes: localFileSystem. readFileContents ( file) )
154- guard case let . dictionary( dict) = json,
155- case let . int( parent) ? = dict [ " parent " ] ,
156- case let . int( child) ? = dict [ " child " ] else {
157- return XCTFail ( " Couldn't launch the process " )
149+ DispatchQueue . global ( ) . async ( group: group) {
150+ do {
151+ try testWithTemporaryDirectory { tmpdir in
152+ let file = tmpdir. appending ( component: " pidfile " )
153+ let waitFile = tmpdir. appending ( component: " waitFile " )
154+ let process = Process ( args: self . script ( " subprocess " ) , file. pathString, waitFile. pathString)
155+ try process. launch ( )
156+ guard waitForFile ( waitFile) else {
157+ return XCTFail ( " Couldn't launch the process " )
158+ }
159+ // Ensure process has started running.
160+ guard try Process . running ( process. processID) else {
161+ return XCTFail ( " Couldn't launch the process " )
162+ }
163+ process. signal ( SIGKILL)
164+ let result = try process. waitUntilExit ( )
165+ XCTAssertEqual ( result. exitStatus, . signalled( signal: SIGKILL) )
166+ let json = try JSON ( bytes: localFileSystem. readFileContents ( file) )
167+ guard case let . dictionary( dict) = json,
168+ case let . int( parent) ? = dict [ " parent " ] ,
169+ case let . int( child) ? = dict [ " child " ] else {
170+ return XCTFail ( " Couldn't launch the process " )
171+ }
172+ XCTAssertEqual ( process. processID, ProcessID ( parent) )
173+ // We should have killed the process and any subprocess spawned by it.
174+ XCTAssertFalse ( try Process . running ( ProcessID ( parent) ) )
175+ // FIXME: The child process becomes defunct when executing the tests using docker directly without entering the bash.
176+ XCTAssertFalse ( try Process . running ( ProcessID ( child) , orDefunct: true ) )
177+ }
178+ } catch {
179+ XCTFail ( " \( error) " )
158180 }
159- XCTAssertEqual ( process. processID, ProcessID ( parent) )
160- // We should have killed the process and any subprocess spawned by it.
161- XCTAssertFalse ( try Process . running ( ProcessID ( parent) ) )
162- // FIXME: The child process becomes defunct when executing the tests using docker directly without entering the bash.
163- XCTAssertFalse ( try Process . running ( ProcessID ( child) , orDefunct: true ) )
181+ }
182+
183+ if case . timedOut = group. wait ( timeout: . now( ) + 1 ) {
184+ XCTFail ( " timeout waiting for signals to be processed " )
164185 }
165186 }
166187 #endif
0 commit comments