InspectorEventMonitor.swift 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. //
  2. // InspectorEventMonitor.swift
  3. //
  4. // Copyright (c) 2025 Alamofire Software Foundation (http://alamofire.org/)
  5. //
  6. // Permission is hereby granted, free of charge, to any person obtaining a copy
  7. // of this software and associated documentation files (the "Software"), to deal
  8. // in the Software without restriction, including without limitation the rights
  9. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. // copies of the Software, and to permit persons to whom the Software is
  11. // furnished to do so, subject to the following conditions:
  12. //
  13. // The above copyright notice and this permission notice shall be included in
  14. // all copies or substantial portions of the Software.
  15. //
  16. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. // THE SOFTWARE.
  23. //
  24. import Foundation
  25. @testable import Alamofire
  26. final class InspectorEventMonitor: EventMonitor {
  27. let label: String
  28. let queue: DispatchQueue
  29. struct TimelineEvent {
  30. var date: Date
  31. var event: String
  32. var label: String
  33. }
  34. var events: [String] {
  35. _timeline.read { $0.map(\.event) }
  36. }
  37. var timeline: [TimelineEvent] {
  38. _timeline.read(\.self)
  39. }
  40. private let _timeline = Protected<[TimelineEvent]>([])
  41. init(label: String = "InspectorEventMonitor", queue: DispatchQueue = DispatchQueue(label: "org.alamofire.inspectorEventMonitor")) {
  42. self.label = label
  43. self.queue = queue
  44. }
  45. func pendingEvents() async {
  46. await queue.pendingWork()
  47. }
  48. private func append(_ event: String) {
  49. _timeline.write { $0.append(TimelineEvent(date: .now, event: event, label: label)) }
  50. }
  51. func urlSession(_ session: URLSession, didBecomeInvalidWithError error: (any Error)?) {
  52. append("\(#function)")
  53. }
  54. func urlSession(_ session: URLSession, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge) {
  55. append("\(#function)")
  56. }
  57. func urlSession(_ session: URLSession,
  58. task: URLSessionTask,
  59. didSendBodyData bytesSent: Int64,
  60. totalBytesSent: Int64,
  61. totalBytesExpectedToSend: Int64) {
  62. append("\(#function)")
  63. }
  64. func urlSession(_ session: URLSession, taskNeedsNewBodyStream task: URLSessionTask) {
  65. append("\(#function)")
  66. }
  67. func urlSession(_ session: URLSession,
  68. task: URLSessionTask,
  69. willPerformHTTPRedirection response: HTTPURLResponse,
  70. newRequest request: URLRequest) {
  71. append("\(#function)")
  72. }
  73. func urlSession(_ session: URLSession, task: URLSessionTask, didFinishCollecting metrics: URLSessionTaskMetrics) {
  74. append("\(#function)")
  75. }
  76. func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: (any Error)?) {
  77. append("\(#function)")
  78. }
  79. func urlSession(_ session: URLSession, taskIsWaitingForConnectivity task: URLSessionTask) {
  80. append("\(#function)")
  81. }
  82. func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
  83. append("\(#function)")
  84. }
  85. func urlSession(_ session: URLSession,
  86. dataTask: URLSessionDataTask,
  87. willCacheResponse proposedResponse: CachedURLResponse) {
  88. append("\(#function)")
  89. }
  90. func urlSession(_ session: URLSession,
  91. downloadTask: URLSessionDownloadTask,
  92. didResumeAtOffset fileOffset: Int64,
  93. expectedTotalBytes: Int64) {
  94. append("\(#function)")
  95. }
  96. func urlSession(_ session: URLSession,
  97. downloadTask: URLSessionDownloadTask,
  98. didWriteData bytesWritten: Int64,
  99. totalBytesWritten: Int64,
  100. totalBytesExpectedToWrite: Int64) {
  101. append("\(#function)")
  102. }
  103. func urlSession(_ session: URLSession,
  104. downloadTask: URLSessionDownloadTask,
  105. didFinishDownloadingTo location: URL) {
  106. append("\(#function)")
  107. }
  108. func request(_ request: Request, didCreateInitialURLRequest urlRequest: URLRequest) {
  109. append("\(#function)")
  110. }
  111. func request(_ request: Request, didFailToCreateURLRequestWithError error: any Error) {
  112. append("\(#function)")
  113. }
  114. func request(_ request: Request, didAdaptInitialRequest initialRequest: URLRequest, to adaptedRequest: URLRequest) {
  115. append("\(#function)")
  116. }
  117. func request(_ request: Request, didFailToAdaptURLRequest initialRequest: URLRequest, withError error: any Error) {
  118. append("\(#function)")
  119. }
  120. func request(_ request: Request, didCreateURLRequest urlRequest: URLRequest) {
  121. append("\(#function)")
  122. }
  123. func request(_ request: Request, didCreateTask task: URLSessionTask) {
  124. append("\(#function)")
  125. }
  126. func request(_ request: Request, didGatherMetrics metrics: URLSessionTaskMetrics) {
  127. append("\(#function)")
  128. }
  129. func request(_ request: Request, didFailTask task: URLSessionTask, earlyWithError error: any Error) {
  130. append("\(#function)")
  131. }
  132. func request(_ request: Request, didCompleteTask task: URLSessionTask, with error: (any Error)?) {
  133. append("\(#function)")
  134. }
  135. func requestDidFinish(_ request: Request) {
  136. append("\(#function)")
  137. }
  138. func requestDidResume(_ request: Request) {
  139. append("\(#function)")
  140. }
  141. func request(_ request: Request, didResumeTask task: URLSessionTask) {
  142. append("\(#function)")
  143. }
  144. func requestDidSuspend(_ request: Request) {
  145. append("\(#function)")
  146. }
  147. func request(_ request: Request, didSuspendTask task: URLSessionTask) {
  148. append("\(#function)")
  149. }
  150. func requestDidCancel(_ request: Request) {
  151. append("\(#function)")
  152. }
  153. func request(_ request: Request, didCancelTask task: URLSessionTask) {
  154. append("\(#function)")
  155. }
  156. func request(_ request: DataRequest, didParseResponse response: DataResponse<Data?, AFError>) {
  157. append("\(#function)")
  158. }
  159. func request<Value>(_ request: DataRequest, didParseResponse response: DataResponse<Value, AFError>) {
  160. append("\(#function)")
  161. }
  162. func request(_ request: DownloadRequest, didParseResponse response: DownloadResponse<URL?, AFError>) {
  163. append("\(#function)")
  164. }
  165. func request(_ request: DownloadRequest, didParseResponse response: DownloadResponse<Data?, AFError>) {
  166. append("\(#function)")
  167. }
  168. func request<Value>(_ request: DownloadRequest, didParseResponse response: DownloadResponse<Value, AFError>) {
  169. append("\(#function)")
  170. }
  171. func requestIsRetrying(_ request: Request) {
  172. append("\(#function)")
  173. }
  174. func request(_ request: DataRequest, didValidateRequest urlRequest: URLRequest?, response: HTTPURLResponse, data: Data?, withResult result: Request.ValidationResult) {
  175. append("\(#function)")
  176. }
  177. func request(_ request: DataStreamRequest, didValidateRequest urlRequest: URLRequest?, response: HTTPURLResponse, withResult result: Request.ValidationResult) {
  178. append("\(#function)")
  179. }
  180. func request<Value>(_ request: DataStreamRequest, didParseStream result: Result<Value, AFError>) {
  181. append("\(#function)")
  182. }
  183. func request(_ request: UploadRequest, didCreateUploadable uploadable: UploadRequest.Uploadable) {
  184. append("\(#function)")
  185. }
  186. func request(_ request: UploadRequest, didFailToCreateUploadableWithError error: any Error) {
  187. append("\(#function)")
  188. }
  189. func request(_ request: UploadRequest, didProvideInputStream stream: InputStream) {
  190. append("\(#function)")
  191. }
  192. func request(_ request: DownloadRequest, didFinishDownloadingUsing task: URLSessionTask, with result: Result<URL, any Error>) {
  193. append("\(#function)")
  194. }
  195. func request(_ request: DownloadRequest, didCreateDestinationURL url: URL) {
  196. append("\(#function)")
  197. }
  198. func request(_ request: DownloadRequest, didValidateRequest urlRequest: URLRequest?, response: HTTPURLResponse, temporaryURL: URL?, destinationURL: URL?, withResult result: Request.ValidationResult) {
  199. append("\(#function)")
  200. }
  201. }