From a9f2ebc9e7773caeca6c3707a86b9e78837097a9 Mon Sep 17 00:00:00 2001 From: mmark Date: Fri, 4 Dec 2020 16:51:56 -0800 Subject: [PATCH] remove preconditions b/c their failures are impossible to debug --- .../Configuration/PinpillConfiguration.swift | 27 +++++++++++---- .../pinpill/Configuration/PinpillURLs.swift | 34 ++++++++++--------- pinpill/pinpill/PinpillCLI.swift | 11 +++--- 3 files changed, 45 insertions(+), 27 deletions(-) diff --git a/pinpill/pinpill/Configuration/PinpillConfiguration.swift b/pinpill/pinpill/Configuration/PinpillConfiguration.swift index 325d6191..67f8891d 100644 --- a/pinpill/pinpill/Configuration/PinpillConfiguration.swift +++ b/pinpill/pinpill/Configuration/PinpillConfiguration.swift @@ -11,6 +11,7 @@ import Foundation class PinpillConfiguration: Codable { enum PinpillConfigurationError: Error { case missingRequiredConfig(String) + case invalidConfig(String) } static let kDefaultHeadless = true @@ -94,7 +95,7 @@ class PinpillConfiguration: Codable { Logger.verbose(msg: "Found xcode path: \(xcodeTask.stdOut)") let xcodeURL = URL(fileURLWithPath: xcodeTask.stdOut.trimmingCharacters(in: .whitespacesAndNewlines)) - let urls = PinpillURLs( + let urls = try PinpillURLs( fileManager: FileManager.default, testBundleURL: testBundleURL, appBundleURL: appBundleURL, @@ -104,7 +105,7 @@ class PinpillConfiguration: Codable { outputURL: outputURL, simulatorPreferencesURL: simulatorPreferencesURL ) - return PinpillConfiguration( + return try PinpillConfiguration( headless: headless, maxSims: maxSims, maxRetries: maxRetries, @@ -131,18 +132,30 @@ class PinpillConfiguration: Codable { urls: PinpillURLs, recordVideo: Bool, recordScreenshot: Bool - ) { + ) throws { self.headless = headless - precondition(maxSims > 0, "maxSims must be a positive integer. Got \(maxSims)") + if (maxSims <= 0) { + throw PinpillConfigurationError.invalidConfig("maxSims must be a positive integer. Got \(maxSims)") + } self.maxSims = maxSims - precondition(maxRetries >= 0, "numTestRuns must be a non-negative integer. Got \(maxRetries)") + + if (maxRetries < 0) { + throw PinpillConfigurationError.invalidConfig("numTestRuns must be a non-negative integer. Got \(maxRetries)") + } self.maxRetries = maxRetries - precondition(numTestRuns > 0, "numTestRuns must be a positive integer. Got \(numTestRuns)") + + if (numTestRuns <= 0) { + throw PinpillConfigurationError.invalidConfig("numTestRuns must be a positive integer. Got \(numTestRuns)") + } self.numTestRuns = numTestRuns self.device = device self.runtime = runtime - precondition(!testTasks.isEmpty, "Must contain at least one test task") + + if (testTasks.isEmpty) { + throw PinpillConfigurationError.invalidConfig("testTasks must be non-empty.") + } self.testTasks = testTasks + self.environment = environment self.urls = urls self.recordVideo = recordVideo diff --git a/pinpill/pinpill/Configuration/PinpillURLs.swift b/pinpill/pinpill/Configuration/PinpillURLs.swift index 7ac7fa08..d2ca3b21 100644 --- a/pinpill/pinpill/Configuration/PinpillURLs.swift +++ b/pinpill/pinpill/Configuration/PinpillURLs.swift @@ -9,6 +9,10 @@ import Foundation class PinpillURLs: Codable { + enum PinpillURLError: Error { + case fileNotFoundError(String) + } + let testBundleURL: URL let appBundleURL: URL let xcTestRunURL: URL @@ -17,33 +21,25 @@ class PinpillURLs: Codable { let bpURL: URL let outputURL: URL let simulatorPreferencesURL: URL - let simulatorURL: URL - init(fileManager: FileManager, testBundleURL: URL, appBundleURL: URL, xcTestRunURL: URL, xcodeURL: URL, bpURL: URL, outputURL: URL, simulatorPreferencesURL: URL) { - precondition(fileManager.fileExists(atPath: testBundleURL.path), "Test bundle not found at path \(testBundleURL.path)") + init(fileManager: FileManager, testBundleURL: URL, appBundleURL: URL, xcTestRunURL: URL, xcodeURL: URL, bpURL: URL, outputURL: URL, simulatorPreferencesURL: URL) throws { self.testBundleURL = testBundleURL - - precondition(fileManager.fileExists(atPath: appBundleURL.path), "App bundle not found at path \(appBundleURL.path)") self.appBundleURL = appBundleURL - - precondition(fileManager.fileExists(atPath: xcTestRunURL.path), ".xctestrun not found at path \(xcTestRunURL.path)") self.xcTestRunURL = xcTestRunURL - - precondition(fileManager.fileExists(atPath: xcodeURL.path), "xcode not found at path \(xcodeURL.path)") self.xcodeURL = xcodeURL - - precondition(fileManager.fileExists(atPath: bpURL.path), "bp executable not found at path \(bpURL.path)") self.bpURL = bpURL - - // Don't verify this exists because bp will create it for us if it's missing. self.outputURL = outputURL - - precondition(fileManager.fileExists(atPath: simulatorPreferencesURL.path), "simulator preferences not found at path \(simulatorPreferencesURL.path)") self.simulatorPreferencesURL = simulatorPreferencesURL - testRootURL = xcTestRunURL.deletingLastPathComponent() simulatorURL = xcodeURL.appendingPathComponent("/Applications/Simulator.app/Contents/MacOS/Simulator") + + try checkExists(fileManager: fileManager, path: testBundleURL, description: "test bundle") + try checkExists(fileManager: fileManager, path: appBundleURL, description: "app bundle") + try checkExists(fileManager: fileManager, path: xcTestRunURL, description: ".xctestrun") + try checkExists(fileManager: fileManager, path: testBundleURL, description: "xcode") + try checkExists(fileManager: fileManager, path: bpURL, description: "bp executable") + try checkExists(fileManager: fileManager, path: simulatorPreferencesURL, description: "simulator preferences") } func findXCTestURLs() -> [URL] { @@ -58,4 +54,10 @@ class PinpillURLs: Codable { return pluginURLs.filter { $0.pathExtension == "xctest" } } + + func checkExists(fileManager: FileManager, path: URL, description: String) throws { + if(!fileManager.fileExists(atPath: path.path)) { + throw PinpillURLError.fileNotFoundError("\(description) not found at path \(path)") + } + } } diff --git a/pinpill/pinpill/PinpillCLI.swift b/pinpill/pinpill/PinpillCLI.swift index 1775c3ce..7ef9db65 100644 --- a/pinpill/pinpill/PinpillCLI.swift +++ b/pinpill/pinpill/PinpillCLI.swift @@ -22,10 +22,10 @@ struct PinpillCLI: ParsableCommand { var headless: Bool = false @Flag(help: "Disable saving videos of test runs.") - var noRecordVideo: Bool + var noRecordVideo: Bool = false @Flag(help: "Disable saving screenshots of failed UI tests.") - var noRecordScreenshot: Bool + var noRecordScreenshot: Bool = false @Option(help: "Maximum number of concurrent simulators") var maxSims: Int? @@ -113,7 +113,10 @@ struct PinpillCLI: ParsableCommand { func readArgumentsFromFile(fileManager: FileManager, path: String) -> JSONPinpillArguments? { let configURL = URL(fileURLWithPath: path) - precondition(fileManager.fileExists(atPath: configURL.path), "config file not found at path \(configURL.path)") + if (!fileManager.fileExists(atPath: configURL.path)) { + Logger.error(msg: "Config file not found at path \(configURL.path)") + return nil + } let decoder = JSONDecoder() do { let jsonArgs = try decoder.decode(JSONPinpillArguments.self, from: Data(contentsOf: configURL)) @@ -121,7 +124,7 @@ struct PinpillCLI: ParsableCommand { Logger.verbose(msg: jsonArgs.toJSON()) return jsonArgs } catch { - Logger.error(msg: "error: failed to decode arguments from file at \(path).") + Logger.error(msg: "Failed to decode arguments from file at \(path).") return nil } }