- Notifications
You must be signed in to change notification settings - Fork 1.2k
/
Copy pathTestURLSessionFTP.swift
126 lines (111 loc) · 4.82 KB
/
TestURLSessionFTP.swift
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
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
#if !os(Windows)
import Synchronization
classTestURLSessionFTP:LoopbackFTPServerTest{
letsaveString="""
FTP implementation to test FTP
upload, download and data tasks. Instead of sending a file,
we are sending the hardcoded data.We are going to test FTP
data, download and upload tasks with delegates & completion handlers.
Creating the data here as we need to pass the count
as part of the header.\r\n
"""
func test_ftpDataTask()throws{
throwXCTSkip("<https://bugs.swift.org/browse/SR-10922> non-deterministic SEGFAULT in TestURLSessionFTP.test_ftpDataTask")
#if false
#if !DARWIN_COMPATIBILITY_TESTS
letftpURL="ftp://127.0.0.1:\(TestURLSessionFTP.serverPort)/test.txt"
letreq=URLRequest(url:URL(string: ftpURL)!)
letconfiguration=URLSessionConfiguration.default
letexpect=expectation(description:"URL test with custom protocol")
letsesh=URLSession(configuration: configuration)
letdataTask1= sesh.dataTask(with: req, completionHandler:{ data, res, error in
defer{ expect.fulfill()}
XCTAssertNil(error)
XCTAssertEqual(self.saveString,String(data: data!, encoding:String.Encoding.utf8))
})
dataTask1.resume()
waitForExpectations(timeout:60)
#endif
#endif
}
func test_ftpDataTaskDelegate()throws{
throwXCTSkip("<https://bugs.swift.org/browse/SR-10922> non-deterministic SEGFAULT in TestURLSessionFTP.test_ftpDataTask")
#if false
leturlString="ftp://127.0.0.1:\(TestURLSessionFTP.serverPort)/test.txt"
leturl=URL(string: urlString)!
letdataTask=FTPDataTask(with:expectation(description:"data task"))
dataTask.run(with: url)
waitForExpectations(timeout:60)
if !dataTask.error {
XCTAssertNotNil(dataTask.fileData)
}
#endif
}
}
// Sendable note: Access to ivars is essentially serialized by the XCTestExpectation. It would be better to do it with a lock, but this is sufficient for now.
classFTPDataTask:NSObject,@uncheckedSendable{
letdataTaskExpectation:XCTestExpectation!
varfileData:NSMutableData=NSMutableData()
varsession:URLSession!=nil
vartask:URLSessionDataTask!=nil
varcancelExpectation:XCTestExpectation?
varresponseReceivedExpectation:XCTestExpectation?
varhasTransferCompleted=false
privatelet_error=Mutex(false)
publicvarerror:Bool{
get{ _error.withLock{ $0 }}
set{ _error.withLock{ $0 = newValue }}
}
init(with expectation:XCTestExpectation){
dataTaskExpectation = expectation
}
func run(with request:URLRequest){
letconfig=URLSessionConfiguration.default
config.timeoutIntervalForRequest =8
session =URLSession(configuration: config, delegate:self, delegateQueue:nil)
task = session.dataTask(with: request)
task.resume()
}
func run(with url:URL){
letconfig=URLSessionConfiguration.default
config.timeoutIntervalForRequest =8
session =URLSession(configuration: config, delegate:self, delegateQueue:nil)
task = session.dataTask(with: url)
task.resume()
}
func cancel(){
task.cancel()
}
}
extensionFTPDataTask:URLSessionDataDelegate{
publicfunc urlSession(_ session:URLSession, dataTask:URLSessionDataTask, didReceive data:Data){
fileData.append(data)
responseReceivedExpectation?.fulfill()
}
publicfunc urlSession(_ session:URLSession,
dataTask:URLSessionDataTask,
didReceive response:URLResponse,
completionHandler:@escaping(URLSession.ResponseDisposition)->Void){
guard responseReceivedExpectation !=nilelse{return}
responseReceivedExpectation!.fulfill()
}
}
extensionFTPDataTask:URLSessionTaskDelegate{
publicfunc urlSession(_ session:URLSession, task:URLSessionTask, didCompleteWithError error:Error?){
dataTaskExpectation.fulfill()
guard(error as?URLError)!=nilelse{return}
iflet cancellation = cancelExpectation {
cancellation.fulfill()
}
self.error =true
}
}
#endif