@@ -25,55 +25,66 @@ class ProcessTests: XCTestCase {
25
25
26
26
func testBasics( ) throws {
27
27
do {
28
+ #if os(Windows)
29
+ let process = Process ( args: " cmd " , " /c " , " echo " , " hello " )
30
+ #else
28
31
let process = Process ( args: " echo " , " hello " )
32
+ #endif
29
33
try process. launch ( )
30
34
let result = try process. waitUntilExit ( )
31
35
XCTAssertEqual ( try result. utf8Output ( ) , " hello \n " )
32
36
XCTAssertEqual ( result. exitStatus, . terminated( code: 0 ) )
33
37
XCTAssertEqual ( result. arguments, process. arguments)
34
38
}
35
-
36
39
do {
40
+ #if os(Windows)
41
+ let process = Process ( args: " cmd.exe " , " /c " , " exit " , " 4 " )
42
+ #else
37
43
let process = Process ( args: script ( " exit4 " ) )
44
+ #endif
38
45
try process. launch ( )
39
46
let result = try process. waitUntilExit ( )
40
47
XCTAssertEqual ( result. exitStatus, . terminated( code: 4 ) )
41
48
}
42
49
}
43
50
44
51
func testPopen( ) throws {
45
- #if os(Windows)
46
- let echo = " echo .exe"
47
- #else
48
- let echo = " echo "
49
- #endif
52
+ #if os(Windows)
53
+ let echo = [ " cmd .exe" , " /c " , " echo " ]
54
+ #else
55
+ let echo = [ " echo " ]
56
+ #endif
50
57
// Test basic echo.
51
- XCTAssertEqual ( try Process . popen ( arguments: [ echo, " hello " ] ) . utf8Output ( ) , " hello \n " )
58
+ XCTAssertEqual ( try Process . popen ( arguments: echo + [ " hello " ] ) . utf8Output ( ) , " hello \n " )
52
59
53
60
// Test buffer larger than that allocated.
54
61
try withTemporaryFile { file in
55
62
let count = 10_000
56
63
let stream = BufferedOutputByteStream ( )
57
64
stream <<< Format . asRepeating ( string: " a " , count: count)
58
65
try localFileSystem. writeFileContents ( file. path, bytes: stream. bytes)
59
- #if os(Windows)
60
- let cat = " cat .exe"
61
- #else
62
- let cat = " cat "
63
- #endif
64
- let outputCount = try Process . popen ( args : cat , file . path . pathString ) . utf8Output ( ) . count
66
+ #if os(Windows)
67
+ let process = try Process . popen ( args : " cmd .exe" , " /c " , " type " , file . path . pathString )
68
+ #else
69
+ let process = try Process . popen ( args : " cat " , file . path . pathString )
70
+ #endif
71
+ let outputCount = try process . utf8Output ( ) . count
65
72
XCTAssert ( outputCount == count)
66
73
}
67
74
}
68
75
69
76
func testPopenAsync( ) throws {
70
- #if os(Windows)
77
+ #if os(Windows)
71
78
let args = [ " where.exe " , " where " ]
72
- let answer = " C: \\ Windows \\ System32 \\ where.exe "
73
- #else
79
+ var buffer = Array < WCHAR > ( repeating: 0 , count: Int ( MAX_PATH + 1 ) )
80
+ guard GetSystemDirectoryW ( & buffer, . init( buffer. count) ) > 0 else {
81
+ return XCTFail ( )
82
+ }
83
+ let answer = String ( decodingCString: buffer, as: UTF16 . self) + " \\ where.exe "
84
+ #else
74
85
let args = [ " whoami " ]
75
86
let answer = NSUserName ( )
76
- #endif
87
+ #endif
77
88
var popenResult : Result < ProcessResult , Error > ?
78
89
let group = DispatchGroup ( )
79
90
group. enter ( )
@@ -95,25 +106,34 @@ class ProcessTests: XCTestCase {
95
106
96
107
func testCheckNonZeroExit( ) throws {
97
108
do {
109
+ #if os(Windows)
110
+ let output = try Process . checkNonZeroExit ( args: " cmd.exe " , " /c " , " echo " , " hello " )
111
+ #else
98
112
let output = try Process . checkNonZeroExit ( args: " echo " , " hello " )
113
+ #endif
99
114
XCTAssertEqual ( output, " hello \n " )
100
115
}
101
116
102
117
do {
118
+ #if os(Windows)
119
+ let output = try Process . checkNonZeroExit ( args: " cmd.exe " , " /c " , " exit " , " 4 " )
120
+ #else
103
121
let output = try Process . checkNonZeroExit ( args: script ( " exit4 " ) )
122
+ #endif
104
123
XCTFail ( " Unexpected success \( output) " )
105
124
} catch ProcessResult . Error . nonZeroExit( let result) {
106
125
XCTAssertEqual ( result. exitStatus, . terminated( code: 4 ) )
107
126
}
108
127
}
109
128
110
129
func testFindExecutable( ) throws {
130
+ #if !os(Windows)
111
131
try testWithTemporaryDirectory { tmpdir in
112
132
// This process should always work.
113
- XCTAssertTrue ( Process . findExecutable ( " ls " ) != nil )
133
+ XCTAssertNotNil ( Process . findExecutable ( " ls " ) )
114
134
115
- XCTAssertEqual ( Process . findExecutable ( " nonExistantProgram " ) , nil )
116
- XCTAssertEqual ( Process . findExecutable ( " " ) , nil )
135
+ XCTAssertNil ( Process . findExecutable ( " nonExistantProgram " ) )
136
+ XCTAssertNil ( Process . findExecutable ( " " ) )
117
137
118
138
// Create a local nonexecutable file to test.
119
139
let tempExecutable = tmpdir. appending ( component: " nonExecutableProgram " )
@@ -124,9 +144,40 @@ class ProcessTests: XCTestCase {
124
144
""" )
125
145
126
146
try withCustomEnv ( [ " PATH " : tmpdir. pathString] ) {
127
- XCTAssertEqual ( Process . findExecutable ( " nonExecutableProgram " ) , nil )
147
+ XCTAssertNil ( Process . findExecutable ( " nonExecutableProgram " ) )
128
148
}
129
149
}
150
+ #else
151
+ try testWithTemporaryDirectory { tmpdir in
152
+ // Test System32 without .exe suffix.
153
+ XCTAssertNotNil ( Process . findExecutable ( " cmd " ) )
154
+
155
+ // Test Windows with .exe suffix.
156
+ XCTAssertNotNil ( Process . findExecutable ( " explorer.exe " ) )
157
+
158
+ // Test non-existant programs.
159
+ XCTAssertNil ( Process . findExecutable ( " nonExistantProgram " ) )
160
+ XCTAssertNil ( Process . findExecutable ( " " ) )
161
+
162
+ // Copy an executable file to test.
163
+ let tempExecutable = tmpdir. appending ( component: " executableProgram.exe " )
164
+ try localFileSystem. copy ( from: Process . findExecutable ( " cmd " ) !, to: tempExecutable)
165
+
166
+ // Create a non-executable file to test.
167
+ let tempNonExecutable = tmpdir. appending ( component: " program.bat " )
168
+ try localFileSystem. writeFileContents ( tempNonExecutable, bytes: """
169
+ @echo off
170
+ exit
171
+
172
+ """ )
173
+
174
+ try withCustomEnv ( [ " Path " : tmpdir. pathString] ) {
175
+ XCTAssertNotNil ( Process . findExecutable ( " executableProgram.exe " ) )
176
+ XCTAssertNotNil ( Process . findExecutable ( " executableProgram " ) )
177
+ XCTAssertNil ( Process . findExecutable ( " program.bat " ) )
178
+ }
179
+ }
180
+ #endif
130
181
}
131
182
132
183
func testNonExecutableLaunch( ) throws {
@@ -144,7 +195,7 @@ class ProcessTests: XCTestCase {
144
195
let process = Process ( args: " nonExecutableProgram " )
145
196
try process. launch ( )
146
197
XCTFail ( " Should have failed to validate nonExecutableProgram " )
147
- } catch Process . Error . missingExecutableProgram ( let program) {
198
+ } catch Process . Error . missingExecutableProgram( let program) {
148
199
XCTAssert ( program == " nonExecutableProgram " )
149
200
}
150
201
}
@@ -230,7 +281,11 @@ class ProcessTests: XCTestCase {
230
281
#endif
231
282
232
283
func testThreadSafetyOnWaitUntilExit( ) throws {
284
+ #if os(Windows)
285
+ let process = Process ( args: " cmd " , " /c " , " echo " , " hello " )
286
+ #else
233
287
let process = Process ( args: " echo " , " hello " )
288
+ #endif
234
289
try process. launch ( )
235
290
236
291
var result1 : String = " "
@@ -255,7 +310,12 @@ class ProcessTests: XCTestCase {
255
310
256
311
func testStdin( ) throws {
257
312
var stdout = [ UInt8] ( )
258
- let process = Process ( args: script ( " in-to-out " ) , outputRedirection: . stream( stdout: { stdoutBytes in
313
+ #if os(Windows)
314
+ let inToOut = [ " python.exe " , script ( " in-to-out " ) ]
315
+ #else
316
+ let inToOut = [ script ( " in-to-out " ) ]
317
+ #endif
318
+ let process = Process ( arguments: inToOut, outputRedirection: . stream( stdout: { stdoutBytes in
259
319
stdout += stdoutBytes
260
320
} , stderr: { _ in } ) )
261
321
let stdinStream = try process. launch ( )
@@ -273,14 +333,24 @@ class ProcessTests: XCTestCase {
273
333
func testStdoutStdErr( ) throws {
274
334
// A simple script to check that stdout and stderr are captured separatly.
275
335
do {
276
- let result = try Process . popen ( args: script ( " simple-stdout-stderr " ) )
336
+ #if os(Windows)
337
+ let simpleStdoutStdErr = [ " python.exe " , script ( " simple-stdout-stderr " ) ]
338
+ #else
339
+ let simpleStdoutStdErr = [ script ( " simple-stdout-stderr " ) ]
340
+ #endif
341
+ let result = try Process . popen ( arguments: simpleStdoutStdErr)
277
342
XCTAssertEqual ( try result. utf8Output ( ) , " simple output \n " )
278
343
XCTAssertEqual ( try result. utf8stderrOutput ( ) , " simple error \n " )
279
344
}
280
345
281
346
// A long stdout and stderr output.
282
347
do {
283
- let result = try Process . popen ( args: script ( " long-stdout-stderr " ) )
348
+ #if os(Windows)
349
+ let longStdoutStdErr = [ " python.exe " , script ( " long-stdout-stderr " ) ]
350
+ #else
351
+ let longStdoutStdErr = [ script ( " long-stdout-stderr " ) ]
352
+ #endif
353
+ let result = try Process . popen ( arguments: longStdoutStdErr)
284
354
let count = 16 * 1024
285
355
XCTAssertEqual ( try result. utf8Output ( ) , String ( repeating: " 1 " , count: count) )
286
356
XCTAssertEqual ( try result. utf8stderrOutput ( ) , String ( repeating: " 2 " , count: count) )
@@ -298,7 +368,12 @@ class ProcessTests: XCTestCase {
298
368
func testStdoutStdErrRedirected( ) throws {
299
369
// A simple script to check that stdout and stderr are captured in the same location.
300
370
do {
301
- let process = Process ( args: script ( " simple-stdout-stderr " ) , outputRedirection: . collect( redirectStderr: true ) )
371
+ #if os(Windows)
372
+ let simpleStdoutStdErr = [ " python.exe " , script ( " simple-stdout-stderr " ) ]
373
+ #else
374
+ let simpleStdoutStdErr = [ script ( " simple-stdout-stderr " ) ]
375
+ #endif
376
+ let process = Process ( arguments: simpleStdoutStdErr, outputRedirection: . collect( redirectStderr: true ) )
302
377
try process. launch ( )
303
378
let result = try process. waitUntilExit ( )
304
379
XCTAssertEqual ( try result. utf8Output ( ) , " simple error \n simple output \n " )
@@ -307,7 +382,12 @@ class ProcessTests: XCTestCase {
307
382
308
383
// A long stdout and stderr output.
309
384
do {
310
- let process = Process ( args: script ( " long-stdout-stderr " ) , outputRedirection: . collect( redirectStderr: true ) )
385
+ #if os(Windows)
386
+ let longStdoutStdErr = [ " python.exe " , script ( " long-stdout-stderr " ) ]
387
+ #else
388
+ let longStdoutStdErr = [ script ( " long-stdout-stderr " ) ]
389
+ #endif
390
+ let process = Process ( arguments: longStdoutStdErr, outputRedirection: . collect( redirectStderr: true ) )
311
391
try process. launch ( )
312
392
let result = try process. waitUntilExit ( )
313
393
@@ -320,7 +400,12 @@ class ProcessTests: XCTestCase {
320
400
func testStdoutStdErrStreaming( ) throws {
321
401
var stdout = [ UInt8] ( )
322
402
var stderr = [ UInt8] ( )
323
- let process = Process ( args: script ( " long-stdout-stderr " ) , outputRedirection: . stream( stdout: { stdoutBytes in
403
+ #if os(Windows)
404
+ let longStdoutStdErr = [ " python.exe " , script ( " long-stdout-stderr " ) ]
405
+ #else
406
+ let longStdoutStdErr = [ script ( " long-stdout-stderr " ) ]
407
+ #endif
408
+ let process = Process ( arguments: longStdoutStdErr, outputRedirection: . stream( stdout: { stdoutBytes in
324
409
stdout += stdoutBytes
325
410
} , stderr: { stderrBytes in
326
411
stderr += stderrBytes
@@ -336,7 +421,12 @@ class ProcessTests: XCTestCase {
336
421
func testStdoutStdErrStreamingRedirected( ) throws {
337
422
var stdout = [ UInt8] ( )
338
423
var stderr = [ UInt8] ( )
339
- let process = Process ( args: script ( " long-stdout-stderr " ) , outputRedirection: . stream( stdout: { stdoutBytes in
424
+ #if os(Windows)
425
+ let longStdoutStdErr = [ " python.exe " , script ( " long-stdout-stderr " ) ]
426
+ #else
427
+ let longStdoutStdErr = [ script ( " long-stdout-stderr " ) ]
428
+ #endif
429
+ let process = Process ( arguments: longStdoutStdErr, outputRedirection: . stream( stdout: { stdoutBytes in
340
430
stdout += stdoutBytes
341
431
} , stderr: { stderrBytes in
342
432
stderr += stderrBytes
@@ -370,15 +460,21 @@ class ProcessTests: XCTestCase {
370
460
try localFileSystem. createDirectory ( childPath. parentDirectory, recursive: true )
371
461
try localFileSystem. writeFileContents ( childPath, bytes: ByteString ( " child " ) )
372
462
463
+ #if os(Windows)
464
+ let args = [ " cmd.exe " , " /c " , " type " , " file " ]
465
+ #else
466
+ let args = [ " cat " , " file " ]
467
+ #endif
468
+
373
469
do {
374
- let process = Process ( arguments: [ " cat " , " file " ] , workingDirectory: tempDirPath)
470
+ let process = Process ( arguments: args , workingDirectory: tempDirPath)
375
471
try process. launch ( )
376
472
let result = try process. waitUntilExit ( )
377
473
XCTAssertEqual ( try result. utf8Output ( ) , " parent " )
378
474
}
379
475
380
476
do {
381
- let process = Process ( arguments: [ " cat " , " file " ] , workingDirectory: childPath. parentDirectory)
477
+ let process = Process ( arguments: args , workingDirectory: childPath. parentDirectory)
382
478
try process. launch ( )
383
479
let result = try process. waitUntilExit ( )
384
480
XCTAssertEqual ( try result. utf8Output ( ) , " child " )
0 commit comments