idb_companion/SwiftServer/MethodHandlers/XCTestRunMethodHandler.swift (80 lines of code) (raw):

/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import Foundation import IDBGRPCSwift import GRPC import FBSimulatorControl struct XCTestRunMethodHandler { let target: FBiOSTarget let commandExecutor: FBIDBCommandExecutor let reporter: FBEventReporter let targetLogger: FBControlCoreLogger let logger: FBIDBLogger func handle(request: Idb_XctestRunRequest, responseStream: GRPCAsyncResponseStreamWriter<Idb_XctestRunResponse>, context: GRPCAsyncServerCallContext) async throws { guard let request = transform(value: request) else { throw GRPCStatus(code: .invalidArgument, message: "failed to create FBXCTestRunRequest") } let reporter = IDBXCTestReporter(responseStream: responseStream, queue: target.workQueue, logger: logger) let operationFuture = commandExecutor.xctest_run(request, reporter: reporter, logger: FBControlCoreLoggerFactory.logger(to: reporter)) let operation = try await FutureBox(operationFuture).value reporter.configuration = .init(legacy: operation.reporterConfiguration) try await FutureBox(operation.completed).await() _ = try await FutureBox(reporter.reportingTerminated).value } func transform(value request: Idb_XctestRunRequest) -> FBXCTestRunRequest? { let testsToRun = request.testsToRun.isEmpty ? nil : Set(request.testsToRun) switch request.mode.mode { case .logic: return FBXCTestRunRequest.logicTest(withTestBundleID: request.testBundleID, environment: request.environment, arguments: request.arguments, testsToRun: testsToRun, testsToSkip: Set(request.testsToSkip), testTimeout: request.timeout as NSNumber, reportActivities: request.reportActivities, reportAttachments: request.reportAttachments, coverageRequest: extractCodeCoverage(from: request), collectLogs: request.collectLogs, waitForDebugger: request.waitForDebugger) case let .application(app): return FBXCTestRunRequest.applicationTest(withTestBundleID: request.testBundleID, appBundleID: app.appBundleID, environment: request.environment, arguments: request.arguments, testsToRun: testsToRun, testsToSkip: Set(request.testsToSkip), testTimeout: request.timeout as NSNumber, reportActivities: request.reportActivities, reportAttachments: request.reportAttachments, coverageRequest: extractCodeCoverage(from: request), collectLogs: request.collectLogs, waitForDebugger: request.waitForDebugger) case let .ui(ui): return FBXCTestRunRequest.uiTest(withTestBundleID: request.testBundleID, appBundleID: ui.appBundleID, testHostAppBundleID: ui.testHostAppBundleID, environment: request.environment, arguments: request.arguments, testsToRun: testsToRun, testsToSkip: Set(request.testsToSkip), testTimeout: request.timeout as NSNumber, reportActivities: request.reportActivities, reportAttachments: request.reportAttachments, coverageRequest: extractCodeCoverage(from: request), collectLogs: request.collectLogs) case .none: return nil } } private func extractCodeCoverage(from request: Idb_XctestRunRequest) -> FBCodeCoverageRequest { if request.hasCodeCoverage { switch request.codeCoverage.format { case .raw: return FBCodeCoverageRequest(collect: request.codeCoverage.collect, format: .raw) case .exported, .UNRECOGNIZED: return FBCodeCoverageRequest(collect: request.codeCoverage.collect, format: .exported) } } // fallback to deprecated request field for backwards compatibility return FBCodeCoverageRequest(collect: request.collectCoverage, format: .exported) } }