From 59bde82bd2a3aedc3edba4b98f23f5a8fc9e0171 Mon Sep 17 00:00:00 2001 From: Karl Stenerud Date: Mon, 7 Aug 2023 15:46:37 +0200 Subject: [PATCH 01/61] Allow Maze Runner commands to finish --- .../ios/iOSTestApp/CommandReaderThread.swift | 43 ++++++++++++++----- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/features/fixtures/ios/iOSTestApp/CommandReaderThread.swift b/features/fixtures/ios/iOSTestApp/CommandReaderThread.swift index c410abb8f..0ba3f497d 100644 --- a/features/fixtures/ios/iOSTestApp/CommandReaderThread.swift +++ b/features/fixtures/ios/iOSTestApp/CommandReaderThread.swift @@ -21,9 +21,17 @@ class CommandReaderThread: Thread { Scenario.baseMazeAddress = self.loadMazeRunnerAddress() } + var isRunningCommand = false + while true { - Scenario.executeMazeRunnerCommand() { scenarioName, eventMode in - self.action(scenarioName, eventMode) + if isRunningCommand { + logInfo("A command fetch is already in progress, waiting 1 second more...") + } else { + isRunningCommand = true + Scenario.executeMazeRunnerCommand() { scenarioName, eventMode in + self.action(scenarioName, eventMode) + isRunningCommand = false + } } Thread.sleep(forTimeInterval: 1) } @@ -41,7 +49,7 @@ class CommandReaderThread: Thread { for n in 1...30 { let documentsUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] - log("Reading Maze Runner address from fixture_config.json") + logInfo("Reading Maze Runner address from fixture_config.json") do { let fileUrl = URL(fileURLWithPath: "fixture_config", relativeTo: documentsUrl).appendingPathExtension("json") @@ -49,28 +57,41 @@ class CommandReaderThread: Thread { let savedData = try Data(contentsOf: fileUrl) if let contents = String(data: savedData, encoding: .utf8) { - NSLog("Found fixture_config.json after %d seconds", n) + logInfo(String(format: "Found fixture_config.json after %d seconds", n)) let decoder = JSONDecoder() let jsonData = contents.data(using: .utf8) let config = try decoder.decode(FixtureConfig.self, from: jsonData!) let address = "http://" + config.maze_address - log("Using Maze Runner address: " + address) + logInfo("Using Maze Runner address: " + address) return address } } catch let error as NSError { - log("Failed to read fixture_config.json: \(error)") + logWarn("Failed to read fixture_config.json: \(error)") } - log("Waiting for fixture_config.json to appear") + logInfo("Waiting for fixture_config.json to appear") Thread.sleep(forTimeInterval: 1) } - log("Unable to read from fixture_config.json, defaulting to BrowserStack environment") + logError("Unable to read from fixture_config.json, defaulting to BrowserStack environment") return bsAddress; } } -private func log(_ message: String) { - NSLog("%@", message) - kslog("\(Date()) \(message)") +private func logInfo(_ message: String) { + let fullMessage = String(format: "bugsnagci info: %s", message) + NSLog("%@", fullMessage) + kslog("\(Date()) \(fullMessage)") +} + +private func logWarn(_ message: String) { + let fullMessage = String(format: "bugsnagci warn: %s", message) + NSLog("%@", fullMessage) + kslog("\(Date()) \(fullMessage)") +} + +private func logError(_ message: String) { + let fullMessage = String(format: "bugsnagci error: %s", message) + NSLog("%@", fullMessage) + kslog("\(Date()) \(fullMessage)") } From 41a3f6d372be85bd9b316e0a25a4c87bf7650761 Mon Sep 17 00:00:00 2001 From: Steve Kirkland-Walton Date: Tue, 8 Aug 2023 20:28:54 +0100 Subject: [PATCH 02/61] Resume polling after failure conditions --- features/fixtures/ios/iOSTestApp/CommandReaderThread.swift | 4 +++- features/fixtures/shared/scenarios/Scenario.m | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/features/fixtures/ios/iOSTestApp/CommandReaderThread.swift b/features/fixtures/ios/iOSTestApp/CommandReaderThread.swift index 0ba3f497d..002dc11ea 100644 --- a/features/fixtures/ios/iOSTestApp/CommandReaderThread.swift +++ b/features/fixtures/ios/iOSTestApp/CommandReaderThread.swift @@ -29,7 +29,9 @@ class CommandReaderThread: Thread { } else { isRunningCommand = true Scenario.executeMazeRunnerCommand() { scenarioName, eventMode in - self.action(scenarioName, eventMode) + if (!scenarioName.isEmpty) { + self.action(scenarioName, eventMode) + } isRunningCommand = false } } diff --git a/features/fixtures/shared/scenarios/Scenario.m b/features/fixtures/shared/scenarios/Scenario.m index b80a1570a..02a92ff17 100644 --- a/features/fixtures/shared/scenarios/Scenario.m +++ b/features/fixtures/shared/scenarios/Scenario.m @@ -225,6 +225,7 @@ + (void)executeMazeRunnerCommand:(void (^)(NSString *scenarioName, NSString *sce [[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { if (![response isKindOfClass:[NSHTTPURLResponse class]] || [(NSHTTPURLResponse *)response statusCode] != 200) { NSLog(@"%s request failed with %@", __PRETTY_FUNCTION__, response ?: error); + preHandler(@"", NULL); return; } NSLog(@"%s response body: %@", __PRETTY_FUNCTION__, [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]); @@ -233,6 +234,7 @@ + (void)executeMazeRunnerCommand:(void (^)(NSString *scenarioName, NSString *sce NSString *action = [command objectForKey:@"action"]; if ([action isEqualToString:@"noop"]) { NSLog(@"No Maze Runner command queued at present"); + preHandler(@"", NULL); return; } From bd805c628708215778d40fee48bfcb042bf03f94 Mon Sep 17 00:00:00 2001 From: Steve Kirkland-Walton Date: Wed, 9 Aug 2023 17:01:58 +0100 Subject: [PATCH 03/61] Update test fixtures just once [full ci] --- .buildkite/pipeline.full.yml | 40 ++++++++++++++++++------------------ .buildkite/pipeline.yml | 38 ++++++++++++++++++---------------- 2 files changed, 40 insertions(+), 38 deletions(-) diff --git a/.buildkite/pipeline.full.yml b/.buildkite/pipeline.full.yml index 85792944b..2d0bea3df 100644 --- a/.buildkite/pipeline.full.yml +++ b/.buildkite/pipeline.full.yml @@ -17,7 +17,7 @@ steps: queue: opensource plugins: artifacts#v1.9.0: - download: "features/fixtures/ios/output/iOSTestApp.ipa" + download: "features/fixtures/ios/output/ipa_url_bb.txt" upload: "maze_output/failed/**/*" docker-compose#v4.7.0: pull: cocoa-maze-runner-bitbar @@ -25,7 +25,7 @@ steps: service-ports: true command: - "--exclude=features/[e-z].*.feature$" - - "--app=/app/build/iOSTestApp.ipa" + - "--app=@/app/build/ipa_url_bb.txt" - "--farm=bb" - "--device=IOS_15" - "--no-tunnel" @@ -41,7 +41,7 @@ steps: queue: opensource plugins: artifacts#v1.9.0: - download: "features/fixtures/ios/output/iOSTestApp.ipa" + download: "features/fixtures/ios/output/ipa_url_bb.txt" upload: "maze_output/failed/**/*" docker-compose#v4.7.0: pull: cocoa-maze-runner-bitbar @@ -49,7 +49,7 @@ steps: service-ports: true command: - "--exclude=features/[a-d].*.feature$" - - "--app=/app/build/iOSTestApp.ipa" + - "--app=@/app/build/ipa_url_bb.txt" - "--farm=bb" - "--device=IOS_15" - "--no-tunnel" @@ -66,14 +66,14 @@ steps: queue: opensource plugins: artifacts#v1.9.0: - download: "features/fixtures/ios/output/iOSTestApp.ipa" + download: "features/fixtures/ios/output/ipa_url_bb.txt" upload: "maze_output/failed/**/*" docker-compose#v4.7.0: pull: cocoa-maze-runner-bitbar run: cocoa-maze-runner-bitbar service-ports: true command: - - "--app=/app/build/iOSTestApp.ipa" + - "--app=@/app/build/ipa_url_bb.txt" - "--farm=bb" - "--device=IOS_14" - "--no-tunnel" @@ -97,14 +97,14 @@ steps: queue: opensource plugins: artifacts#v1.9.0: - download: "features/fixtures/ios/output/iOSTestApp.ipa" + download: "features/fixtures/ios/output/ipa_url_bb.txt" upload: "maze_output/failed/**/*" docker-compose#v4.7.0: pull: cocoa-maze-runner-bitbar run: cocoa-maze-runner-bitbar service-ports: true command: - - "--app=/app/build/iOSTestApp.ipa" + - "--app=@/app/build/ipa_url_bb.txt" - "--farm=bb" - "--device=IOS_14" - "--no-tunnel" @@ -128,14 +128,14 @@ steps: queue: opensource plugins: artifacts#v1.9.0: - download: "features/fixtures/ios/output/iOSTestApp.ipa" + download: "features/fixtures/ios/output/ipa_url_bb.txt" upload: "maze_output/failed/**/*" docker-compose#v4.7.0: pull: cocoa-maze-runner-bitbar run: cocoa-maze-runner-bitbar service-ports: true command: - - "--app=/app/build/iOSTestApp.ipa" + - "--app=@/app/build/ipa_url_bb.txt" - "--farm=bb" - "--device=IOS_13" - "--no-tunnel" @@ -159,14 +159,14 @@ steps: queue: opensource plugins: artifacts#v1.9.0: - download: "features/fixtures/ios/output/iOSTestApp.ipa" + download: "features/fixtures/ios/output/ipa_url_bb.txt" upload: "maze_output/failed/**/*" docker-compose#v4.7.0: pull: cocoa-maze-runner-bitbar run: cocoa-maze-runner-bitbar service-ports: true command: - - "--app=/app/build/iOSTestApp.ipa" + - "--app=@/app/build/ipa_url_bb.txt" - "--farm=bb" - "--device=IOS_13" - "--no-tunnel" @@ -190,14 +190,14 @@ steps: queue: opensource plugins: artifacts#v1.9.0: - download: "features/fixtures/ios/output/iOSTestApp.ipa" + download: "features/fixtures/ios/output/ipa_url_bb.txt" upload: "maze_output/failed/**/*" docker-compose#v4.7.0: pull: cocoa-maze-runner-bitbar run: cocoa-maze-runner-bitbar service-ports: true command: - - "--app=/app/build/iOSTestApp.ipa" + - "--app=@/app/build/ipa_url_bb.txt" - "--farm=bb" - "--device=IOS_12" - "--no-tunnel" @@ -221,14 +221,14 @@ steps: queue: opensource plugins: artifacts#v1.9.0: - download: "features/fixtures/ios/output/iOSTestApp.ipa" + download: "features/fixtures/ios/output/ipa_url_bb.txt" upload: "maze_output/failed/**/*" docker-compose#v4.7.0: pull: cocoa-maze-runner-bitbar run: cocoa-maze-runner-bitbar service-ports: true command: - - "--app=/app/build/iOSTestApp.ipa" + - "--app=@/app/build/ipa_url_bb.txt" - "--farm=bb" - "--device=IOS_12" - "--no-tunnel" @@ -257,13 +257,13 @@ steps: queue: opensource plugins: artifacts#v1.5.0: - download: "features/fixtures/ios/output/ipa_url.txt" + download: "features/fixtures/ios/output/ipa_url_bs.txt" upload: "maze_output/failed/**/*" docker-compose#v3.7.0: pull: cocoa-maze-runner-legacy run: cocoa-maze-runner-legacy command: - - "--app=@build/ipa_url.txt" + - "--app=@build/ipa_url_bs.txt" - "--farm=bs" - "--device=IOS_11_0_IPHONE_8_PLUS" - "--appium-version=1.16.0" @@ -288,13 +288,13 @@ steps: queue: opensource plugins: artifacts#v1.5.0: - download: "features/fixtures/ios/output/ipa_url.txt" + download: "features/fixtures/ios/output/ipa_url_bs.txt" upload: "maze_output/failed/**/*" docker-compose#v3.7.0: pull: cocoa-maze-runner-legacy run: cocoa-maze-runner-legacy command: - - "--app=@build/ipa_url.txt" + - "--app=@build/ipa_url_bs.txt" - "--farm=bs" - "--device=IOS_11_0_IPHONE_8_PLUS" - "--appium-version=1.16.0" diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 1735d6220..c9d2c9021 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -15,11 +15,13 @@ steps: artifact_paths: - features/fixtures/ios/output/iOSTestApp.ipa - features/fixtures/macos/output/macOSTestApp.zip - - features/fixtures/ios/output/ipa_url.txt + - features/fixtures/ios/output/ipa_url_bb.txt + - features/fixtures/ios/output/ipa_url_bs.txt commands: - bundle install - make test-fixtures - - bundle exec upload-app --app=./features/fixtures/ios/output/iOSTestApp.ipa --app-id-file=./features/fixtures/ios/output/ipa_url.txt + - bundle exec upload-app --farm=bb --app=./features/fixtures/ios/output/iOSTestApp.ipa --app-id-file=./features/fixtures/ios/output/ipa_url_bb.txt + - bundle exec upload-app --farm=bs --app=./features/fixtures/ios/output/iOSTestApp.ipa --app-id-file=./features/fixtures/ios/output/ipa_url_bs.txt - label: Static framework and Swift Package Manager builds timeout_in_minutes: 10 @@ -293,14 +295,14 @@ steps: queue: opensource plugins: artifacts#v1.9.0: - download: "features/fixtures/ios/output/iOSTestApp.ipa" + download: "features/fixtures/ios/output/ipa_url_bb.txt" upload: "maze_output/failed/**/*" docker-compose#v4.7.0: pull: cocoa-maze-runner-bitbar run: cocoa-maze-runner-bitbar service-ports: true command: - - "--app=/app/build/iOSTestApp.ipa" + - "--app=@/app/build/ipa_url_bb.txt" - "--farm=bb" - "--device=IOS_16" - "--no-tunnel" @@ -324,14 +326,14 @@ steps: queue: opensource plugins: artifacts#v1.9.0: - download: "features/fixtures/ios/output/iOSTestApp.ipa" + download: "features/fixtures/ios/output/ipa_url_bb.txt" upload: "maze_output/failed/**/*" docker-compose#v4.7.0: pull: cocoa-maze-runner-bitbar run: cocoa-maze-runner-bitbar service-ports: true command: - - "--app=/app/build/iOSTestApp.ipa" + - "--app=@/app/build/ipa_url_bb.txt" - "--farm=bb" - "--device=IOS_16" - "--no-tunnel" @@ -355,14 +357,14 @@ steps: queue: opensource plugins: artifacts#v1.9.0: - download: "features/fixtures/ios/output/iOSTestApp.ipa" + download: "features/fixtures/ios/output/ipa_url_bb.txt" upload: "maze_output/failed/**/*" docker-compose#v4.7.0: pull: cocoa-maze-runner-bitbar run: cocoa-maze-runner-bitbar service-ports: true command: - - "--app=/app/build/iOSTestApp.ipa" + - "--app=@/app/build/ipa_url_bb.txt" - "--farm=bb" - "--device=IOS_15" - "--no-tunnel" @@ -385,14 +387,14 @@ steps: queue: opensource plugins: artifacts#v1.9.0: - download: "features/fixtures/ios/output/iOSTestApp.ipa" + download: "features/fixtures/ios/output/ipa_url_bb.txt" upload: "maze_output/failed/**/*" docker-compose#v4.7.0: pull: cocoa-maze-runner-bitbar run: cocoa-maze-runner-bitbar service-ports: true command: - - "--app=/app/build/iOSTestApp.ipa" + - "--app=@/app/build/ipa_url_bb.txt" - "--farm=bb" - "--device=IOS_14" - "--no-tunnel" @@ -415,14 +417,14 @@ steps: queue: opensource plugins: artifacts#v1.9.0: - download: "features/fixtures/ios/output/iOSTestApp.ipa" + download: "features/fixtures/ios/output/ipa_url_bb.txt" upload: "maze_output/failed/**/*" docker-compose#v4.7.0: pull: cocoa-maze-runner-bitbar run: cocoa-maze-runner-bitbar service-ports: true command: - - "--app=/app/build/iOSTestApp.ipa" + - "--app=@/app/build/ipa_url_bb.txt" - "--farm=bb" - "--device=IOS_13" - "--no-tunnel" @@ -445,14 +447,14 @@ steps: queue: opensource plugins: artifacts#v1.9.0: - download: "features/fixtures/ios/output/iOSTestApp.ipa" + download: "features/fixtures/ios/output/ipa_url_bb.txt" upload: "maze_output/failed/**/*" docker-compose#v4.7.0: pull: cocoa-maze-runner-bitbar run: cocoa-maze-runner-bitbar service-ports: true command: - - "--app=/app/build/iOSTestApp.ipa" + - "--app=@/app/build/ipa_url_bb.txt" - "--farm=bb" - "--device=IOS_12" - "--no-tunnel" @@ -478,13 +480,13 @@ steps: queue: opensource plugins: artifacts#v1.5.0: - download: "features/fixtures/ios/output/ipa_url.txt" + download: "features/fixtures/ios/output/ipa_url_bs.txt" upload: "maze_output/failed/**/*" docker-compose#v3.7.0: pull: cocoa-maze-runner run: cocoa-maze-runner command: - - "--app=@build/ipa_url.txt" + - "--app=@build/ipa_url_bs.txt" - "--farm=bs" - "--device=IOS_11_0_IPHONE_8_PLUS" - "--appium-version=1.16.0" @@ -505,13 +507,13 @@ steps: queue: opensource plugins: artifacts#v1.5.0: - download: "features/fixtures/ios/output/ipa_url.txt" + download: "features/fixtures/ios/output/ipa_url_bs.txt" upload: "maze_output/failed/**/*" docker-compose#v3.7.0: pull: cocoa-maze-runner run: cocoa-maze-runner command: - - "--app=@build/ipa_url.txt" + - "--app=@build/ipa_url_bs.txt" - "--farm=bs" - "--device=IOS_10" - "--appium-version=1.15.0" From dde826289c3d14d7703fefca981a6e44d3bd53e6 Mon Sep 17 00:00:00 2001 From: Steve Kirkland-Walton Date: Wed, 9 Aug 2023 23:26:38 +0100 Subject: [PATCH 04/61] Attempted fix of flaky test scenarios --- features/app_hangs.feature | 9 +++++---- .../shared/scenarios/AppHangFatalOnlyScenario.swift | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/features/app_hangs.feature b/features/app_hangs.feature index 93966d9ee..18c415e94 100644 --- a/features/app_hangs.feature +++ b/features/app_hangs.feature @@ -107,7 +107,7 @@ Feature: App hangs Scenario: Fatal app hangs should be reported if appHangThresholdMillis = BugsnagAppHangThresholdFatalOnly When I run "AppHangFatalOnlyScenario" - And I wait for 3 seconds + And I wait for 6 seconds And I kill and relaunch the app And I set the HTTP status code to 500 And I configure Bugsnag for "AppHangFatalOnlyScenario" @@ -139,7 +139,7 @@ Feature: App hangs Scenario: Fatal app hangs should not be reported if enabledErrorTypes.appHangs = false When I run "AppHangFatalDisabledScenario" - And I wait for 3 seconds + And I wait for 5 seconds And I kill and relaunch the app And I configure Bugsnag for "AppHangFatalDisabledScenario" Then I should receive no errors @@ -147,7 +147,8 @@ Feature: App hangs @skip_macos Scenario: Fatal app hangs should be reported if the app hangs before going to the background When I run "AppHangFatalOnlyScenario" - And I send the app to the background for 3 seconds + And I wait for 5 seconds + And I send the app to the background And I kill and relaunch the app And I configure Bugsnag for "AppHangFatalOnlyScenario" And I wait to receive an error @@ -156,7 +157,7 @@ Feature: App hangs @skip_macos Scenario: Fatal app hangs should not be reported if they occur once the app is in the background When I run "AppHangDidEnterBackgroundScenario" - And I send the app to the background for 3 seconds + And I send the app to the background for 6 seconds And I kill and relaunch the app And I configure Bugsnag for "AppHangDidEnterBackgroundScenario" Then I should receive no errors diff --git a/features/fixtures/shared/scenarios/AppHangFatalOnlyScenario.swift b/features/fixtures/shared/scenarios/AppHangFatalOnlyScenario.swift index 95e4f81cd..f76630479 100644 --- a/features/fixtures/shared/scenarios/AppHangFatalOnlyScenario.swift +++ b/features/fixtures/shared/scenarios/AppHangFatalOnlyScenario.swift @@ -11,7 +11,7 @@ class AppHangFatalOnlyScenario: Scenario { override func run() { NSLog("Hanging indefinitely...") // Use asyncAfter to allow the Appium click event to be handled - DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { + DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) { while true {} } } From 88ffb4a13d288fcfe7486a1c15493916b792592a Mon Sep 17 00:00:00 2001 From: Steve Kirkland-Walton Date: Thu, 10 Aug 2023 00:48:12 +0100 Subject: [PATCH 05/61] Relax condition that the app is not running --- features/steps/app_steps.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/features/steps/app_steps.rb b/features/steps/app_steps.rb index 54afd4fa6..d0d579c37 100644 --- a/features/steps/app_steps.rb +++ b/features/steps/app_steps.rb @@ -66,7 +66,7 @@ # 4: The application is running in the foreground Then('the app is not running') do - wait_for_true do + wait_for_true('the app is not running') do case Maze::Helper.get_current_platform when 'ios' Maze.driver.app_state('com.bugsnag.fixtures.iOSTestApp') == :not_running @@ -112,7 +112,7 @@ def trigger_app_command end end -def wait_for_true +def wait_for_true(description) max_attempts = 300 attempts = 0 assertion_passed = false @@ -121,7 +121,7 @@ def wait_for_true assertion_passed = yield sleep 0.1 end - raise 'Assertion not passed in 30s' unless assertion_passed + $logger.warn "Assertion not passed in 30s: #{description}" unless assertion_passed end def run_macos_app From b43d4ecddcae3f895270b04a39793fa9dbe4d7b9 Mon Sep 17 00:00:00 2001 From: Steve Kirkland-Walton Date: Thu, 10 Aug 2023 12:24:14 +0100 Subject: [PATCH 06/61] Further flaky test fix attempt --- features/app_hangs.feature | 2 +- .../shared/scenarios/ReportBackgroundAppHangScenario.swift | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/features/app_hangs.feature b/features/app_hangs.feature index 18c415e94..8f31de417 100644 --- a/features/app_hangs.feature +++ b/features/app_hangs.feature @@ -183,7 +183,7 @@ Feature: App hangs @skip_macos Scenario: Background app hangs should be reported if reportBackgroundAppHangs = true When I run "ReportBackgroundAppHangScenario" - And I send the app to the background for 3 seconds + And I send the app to the background And I wait to receive an error Then the exception "errorClass" equals "App Hang" And the exception "message" equals "The app's main thread failed to respond to an event within 1000 milliseconds" diff --git a/features/fixtures/shared/scenarios/ReportBackgroundAppHangScenario.swift b/features/fixtures/shared/scenarios/ReportBackgroundAppHangScenario.swift index 247b0211a..20f42a554 100644 --- a/features/fixtures/shared/scenarios/ReportBackgroundAppHangScenario.swift +++ b/features/fixtures/shared/scenarios/ReportBackgroundAppHangScenario.swift @@ -21,9 +21,10 @@ class ReportBackgroundAppHangScenario: Scenario { let timeInterval: TimeInterval = 2 NSLog("Simulating an app hang of \(timeInterval) seconds...") Thread.sleep(forTimeInterval: timeInterval) + Thread.sleep(forTimeInterval: timeInterval) NSLog("Finished sleeping") - DispatchQueue.main.asyncAfter(deadline: .now() + 1) { + DispatchQueue.main.asyncAfter(deadline: .now() + 3) { UIApplication.shared.endBackgroundTask(backgroundTask) } } From cd04ead6c4fb3a5557b1d712e1f9a4994b44dcbd Mon Sep 17 00:00:00 2001 From: Steve Kirkland-Walton Date: Fri, 11 Aug 2023 13:17:09 +0100 Subject: [PATCH 07/61] Correction --- .../shared/scenarios/ReportBackgroundAppHangScenario.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/features/fixtures/shared/scenarios/ReportBackgroundAppHangScenario.swift b/features/fixtures/shared/scenarios/ReportBackgroundAppHangScenario.swift index 20f42a554..c2d3f13b5 100644 --- a/features/fixtures/shared/scenarios/ReportBackgroundAppHangScenario.swift +++ b/features/fixtures/shared/scenarios/ReportBackgroundAppHangScenario.swift @@ -21,7 +21,6 @@ class ReportBackgroundAppHangScenario: Scenario { let timeInterval: TimeInterval = 2 NSLog("Simulating an app hang of \(timeInterval) seconds...") Thread.sleep(forTimeInterval: timeInterval) - Thread.sleep(forTimeInterval: timeInterval) NSLog("Finished sleeping") DispatchQueue.main.asyncAfter(deadline: .now() + 3) { From 8d130642165747e692ba39a1e547cdbb1a85fe30 Mon Sep 17 00:00:00 2001 From: Steve Kirkland-Walton Date: Fri, 11 Aug 2023 13:17:26 +0100 Subject: [PATCH 08/61] Skip flaky step --- features/crashprobe.feature | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/features/crashprobe.feature b/features/crashprobe.feature index e04fa68ab..7809025a9 100644 --- a/features/crashprobe.feature +++ b/features/crashprobe.feature @@ -54,7 +54,8 @@ Feature: Reporting crash events | | | ___forwarding___ | And the "method" of stack frame 4 equals "_CF_forwarding_prep_0" - And the "method" of stack frame 5 equals "-[NonExistentMethodScenario run]" + # Skipped pending PLAT-10759 + #And the "method" of stack frame 5 equals "-[NonExistentMethodScenario run]" And the "isPC" of stack frame 0 is null And the "isLR" of stack frame 0 is null From 2e78a15527ff0cd83888575cac94b690ffcca4d9 Mon Sep 17 00:00:00 2001 From: Karl Stenerud Date: Thu, 31 Aug 2023 11:27:48 +0300 Subject: [PATCH 09/61] Don't use syscall on osx --- Bugsnag/Helpers/BSGDefines.h | 2 +- Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_Jailbreak.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Bugsnag/Helpers/BSGDefines.h b/Bugsnag/Helpers/BSGDefines.h index cf60fb14e..25ac28bf2 100644 --- a/Bugsnag/Helpers/BSGDefines.h +++ b/Bugsnag/Helpers/BSGDefines.h @@ -19,7 +19,7 @@ #define BSG_HAVE_REACHABILITY_WWAN ( TARGET_OS_IOS || TARGET_OS_TV ) #define BSG_HAVE_SIGNAL (TARGET_OS_OSX || TARGET_OS_IOS || TARGET_OS_TV ) #define BSG_HAVE_SIGALTSTACK (TARGET_OS_OSX || TARGET_OS_IOS ) -#define BSG_HAVE_SYSCALL (TARGET_OS_OSX || TARGET_OS_IOS || TARGET_OS_TV ) +#define BSG_HAVE_SYSCALL (TARGET_OS_IOS || TARGET_OS_TV ) #define BSG_HAVE_UIDEVICE __has_include() #define BSG_HAVE_WINDOW (TARGET_OS_OSX || TARGET_OS_IOS || TARGET_OS_TV ) diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_Jailbreak.h b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_Jailbreak.h index 05e9cb7fe..f9f1b23ed 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_Jailbreak.h +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_Jailbreak.h @@ -76,7 +76,7 @@ static inline bool bsg_local_is_insert_libraries_env_var(const char* str) { // - Use pointers for output parameters, with labels that identify them as such. // - Beware of global consts or defines bleeding through. -#if TARGET_CPU_ARM64 +#if TARGET_CPU_ARM64 && !TARGET_OS_OSX #define BSG_HAS_CUSTOM_SYSCALL 1 // ARM64 3-parameter syscall @@ -105,7 +105,7 @@ static inline bool bsg_local_is_insert_libraries_env_var(const char* str) { } \ } while(0) -#elif TARGET_CPU_X86_64 && defined(__GCC_ASM_FLAG_OUTPUTS__) +#elif TARGET_CPU_X86_64 && defined(__GCC_ASM_FLAG_OUTPUTS__) && !TARGET_OS_OSX #define BSG_HAS_CUSTOM_SYSCALL 1 // X86_64 3-parameter syscall From 8f9f484fd2d1411d174577181e1f826a9aa43796 Mon Sep 17 00:00:00 2001 From: Karl Stenerud Date: Wed, 27 Sep 2023 14:43:01 +0200 Subject: [PATCH 10/61] Remove NXArchInfo because it's deprecated --- .../KSCrash/Source/KSCrash/Recording/BSG_KSSystemInfo.m | 9 ++++----- .../KSCrash/Source/KSCrash/Recording/Tools/BSG_KSMach.c | 5 ----- .../KSCrash/Source/KSCrash/Recording/Tools/BSG_KSMach.h | 6 ------ 3 files changed, 4 insertions(+), 16 deletions(-) diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSSystemInfo.m b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSSystemInfo.m index 2c91cc76b..266593139 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSSystemInfo.m +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSSystemInfo.m @@ -239,11 +239,10 @@ + (NSString *)CPUArchForCPUType:(cpu_type_t)cpuType } + (NSString *)currentCPUArch { - NSString *result = - [self CPUArchForCPUType:bsg_kssysctl_int32ForName("hw.cputype") - subType:bsg_kssysctl_int32ForName("hw.cpusubtype")]; - - return result ?: [NSString stringWithUTF8String:bsg_ksmachcurrentCPUArch()]; + int32_t cpu_type = bsg_kssysctl_int32ForName("hw.cputype"); + int32_t cpu_subtype = bsg_kssysctl_int32ForName("hw.cpusubtype"); + NSString *result = [self CPUArchForCPUType:cpu_type subType:cpu_subtype]; + return result ?: [NSString stringWithFormat:@"unknown (type %d, subtype %d)", cpu_type, cpu_subtype]; } // ============================================================================ diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSMach.c b/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSMach.c index d593948b0..b0535d991 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSMach.c +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSMach.c @@ -43,11 +43,6 @@ #pragma mark - General Information - // ============================================================================ -const char *bsg_ksmachcurrentCPUArch(void) { - const NXArchInfo *archInfo = NXGetLocalArchInfo(); - return archInfo == NULL ? NULL : archInfo->name; -} - #define RETURN_NAME_FOR_ENUM(A) \ case A: \ return #A diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSMach.h b/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSMach.h index 902c87c63..0f3d99e04 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSMach.h +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSMach.h @@ -46,12 +46,6 @@ extern "C" { #pragma mark - General Information - // ============================================================================ -/** Get the current CPU architecture. - * - * @return The current architecture. - */ -const char *bsg_ksmachcurrentCPUArch(void); - /** Get the name of a mach exception. * * @param exceptionType The exception type. From f7a85256d29c7a27aa2f986a05f8087c4a8fa67d Mon Sep 17 00:00:00 2001 From: Steve Kirkland-Walton Date: Fri, 29 Sep 2023 11:35:37 +0100 Subject: [PATCH 11/61] Rationalise BitBar CI concurrency group --- .buildkite/pipeline.full.yml | 20 ++++++++++---------- .buildkite/pipeline.yml | 16 ++++++++-------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/.buildkite/pipeline.full.yml b/.buildkite/pipeline.full.yml index 2d0bea3df..beacf56c6 100644 --- a/.buildkite/pipeline.full.yml +++ b/.buildkite/pipeline.full.yml @@ -31,7 +31,7 @@ steps: - "--no-tunnel" - "--aws-public-ip" concurrency: 25 - concurrency_group: 'bitbar-app' + concurrency_group: 'bitbar' concurrency_method: eager - label: ':bitbar: iOS 15 E2E tests batch 2' @@ -55,7 +55,7 @@ steps: - "--no-tunnel" - "--aws-public-ip" concurrency: 25 - concurrency_group: 'bitbar-app' + concurrency_group: 'bitbar' concurrency_method: eager - label: ':bitbar: iOS 14 E2E tests batch 1' @@ -82,7 +82,7 @@ steps: - "--exclude=features/[e-z].*.feature$" - "--order=random" concurrency: 25 - concurrency_group: 'bitbar-app' + concurrency_group: 'bitbar' concurrency_method: eager retry: automatic: @@ -113,7 +113,7 @@ steps: - "--exclude=features/[a-d].*.feature$" - "--order=random" concurrency: 25 - concurrency_group: 'bitbar-app' + concurrency_group: 'bitbar' concurrency_method: eager retry: automatic: @@ -144,7 +144,7 @@ steps: - "--exclude=features/[e-z].*.feature$" - "--order=random" concurrency: 25 - concurrency_group: 'bitbar-app' + concurrency_group: 'bitbar' concurrency_method: eager retry: automatic: @@ -175,7 +175,7 @@ steps: - "--exclude=features/[a-d].*.feature$" - "--order=random" concurrency: 25 - concurrency_group: 'bitbar-app' + concurrency_group: 'bitbar' concurrency_method: eager retry: automatic: @@ -206,7 +206,7 @@ steps: - "--exclude=features/[e-z].*.feature$" - "--order=random" concurrency: 25 - concurrency_group: 'bitbar-app' + concurrency_group: 'bitbar' concurrency_method: eager retry: automatic: @@ -237,7 +237,7 @@ steps: - "--exclude=features/[a-d].*.feature$" - "--order=random" concurrency: 25 - concurrency_group: 'bitbar-app' + concurrency_group: 'bitbar' concurrency_method: eager retry: automatic: @@ -271,7 +271,7 @@ steps: - "--exclude=features/[e-z].*.feature$" - "--order=random" concurrency: 5 - concurrency_group: browserstack-app + concurrency_group: 'browserstack-app' concurrency_method: eager retry: automatic: @@ -302,7 +302,7 @@ steps: - "--exclude=features/[a-d].*.feature$" - "--order=random" concurrency: 5 - concurrency_group: browserstack-app + concurrency_group: 'browserstack-app' concurrency_method: eager retry: automatic: diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index c9d2c9021..2bdaff2ed 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -311,7 +311,7 @@ steps: - "--exclude=features/[e-z].*.feature$" - "--order=random" concurrency: 25 - concurrency_group: 'bitbar-app' + concurrency_group: 'bitbar' concurrency_method: eager retry: automatic: @@ -342,7 +342,7 @@ steps: - "--exclude=features/[a-d].*.feature$" - "--order=random" concurrency: 25 - concurrency_group: 'bitbar-app' + concurrency_group: 'bitbar' concurrency_method: eager retry: automatic: @@ -372,7 +372,7 @@ steps: - "--fail-fast" - "features/barebone_tests.feature" concurrency: 25 - concurrency_group: 'bitbar-app' + concurrency_group: 'bitbar' concurrency_method: eager retry: automatic: @@ -402,7 +402,7 @@ steps: - "--fail-fast" - "features/barebone_tests.feature" concurrency: 25 - concurrency_group: 'bitbar-app' + concurrency_group: 'bitbar' concurrency_method: eager retry: automatic: @@ -432,7 +432,7 @@ steps: - "--fail-fast" - "features/barebone_tests.feature" concurrency: 25 - concurrency_group: 'bitbar-app' + concurrency_group: 'bitbar' concurrency_method: eager retry: automatic: @@ -462,7 +462,7 @@ steps: - "--fail-fast" - "features/barebone_tests.feature" concurrency: 25 - concurrency_group: 'bitbar-app' + concurrency_group: 'bitbar' concurrency_method: eager retry: automatic: @@ -492,7 +492,7 @@ steps: - "--appium-version=1.16.0" - "features/barebone_tests.feature" concurrency: 5 - concurrency_group: browserstack-app + concurrency_group: 'browserstack-app' concurrency_method: eager retry: automatic: @@ -520,7 +520,7 @@ steps: - "--fail-fast" - "features/barebone_tests.feature" concurrency: 5 - concurrency_group: browserstack-app + concurrency_group: 'browserstack-app' concurrency_method: eager retry: automatic: From b9a45f4630e246be424db8d99454f169feaaedbb Mon Sep 17 00:00:00 2001 From: Josh Edney Date: Thu, 19 Oct 2023 14:59:13 +0100 Subject: [PATCH 12/61] add BUILDKITE_JOB_ID to docker-compose --- docker-compose.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker-compose.yml b/docker-compose.yml index 539321250..6ee1dc6b1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,6 +8,7 @@ x-common-environment: &common-environment BUILDKITE_BUILD_CREATOR: BUILDKITE_BUILD_NUMBER: BUILDKITE_BUILD_URL: + BUILDKITE_JOB_ID: BUILDKITE_LABEL: BUILDKITE_MESSAGE: BUILDKITE_PIPELINE_NAME: From b955e3fcb549201db51f1d852de49e391725027a Mon Sep 17 00:00:00 2001 From: Karl Stenerud Date: Wed, 1 Nov 2023 11:57:48 +0100 Subject: [PATCH 13/61] Temporarily disable ios 11 barebones tests --- .buildkite/pipeline.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 2bdaff2ed..9ca0f78c0 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -473,6 +473,7 @@ steps: # BrowserStack # - label: ':browserstack: iOS 11 barebone tests' + skip: "https://smartbear.atlassian.net/browse/PLAT-11154" depends_on: - cocoa_fixture timeout_in_minutes: 60 From 4e1f95f42723031d0b28b59205534e7ed808941d Mon Sep 17 00:00:00 2001 From: Karl Stenerud Date: Wed, 1 Nov 2023 14:32:58 +0100 Subject: [PATCH 14/61] Temporarily disable ios 16 app hang tests --- features/app_hangs.feature | 3 +++ 1 file changed, 3 insertions(+) diff --git a/features/app_hangs.feature b/features/app_hangs.feature index 8f31de417..f2761d085 100644 --- a/features/app_hangs.feature +++ b/features/app_hangs.feature @@ -105,6 +105,7 @@ Feature: App hangs When I run "AppHangDisabledScenario" Then I should receive no errors + @skip_ios_16 # https://smartbear.atlassian.net/browse/PLAT-11155 Scenario: Fatal app hangs should be reported if appHangThresholdMillis = BugsnagAppHangThresholdFatalOnly When I run "AppHangFatalOnlyScenario" And I wait for 6 seconds @@ -137,6 +138,7 @@ Feature: App hangs And the event "session.events.handled" equals 0 And the event "session.events.unhandled" equals 1 + @skip_ios_16 # https://smartbear.atlassian.net/browse/PLAT-11155 Scenario: Fatal app hangs should not be reported if enabledErrorTypes.appHangs = false When I run "AppHangFatalDisabledScenario" And I wait for 5 seconds @@ -145,6 +147,7 @@ Feature: App hangs Then I should receive no errors @skip_macos + @skip_ios_16 # https://smartbear.atlassian.net/browse/PLAT-11155 Scenario: Fatal app hangs should be reported if the app hangs before going to the background When I run "AppHangFatalOnlyScenario" And I wait for 5 seconds From ce12a7d37a4531bd0e5f67e8f58aaa63ccc960cc Mon Sep 17 00:00:00 2001 From: Steve Kirkland-Walton Date: Wed, 25 Oct 2023 17:49:44 +0100 Subject: [PATCH 15/61] Correct format specifier for logged messages --- features/fixtures/ios/iOSTestApp/CommandReaderThread.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/features/fixtures/ios/iOSTestApp/CommandReaderThread.swift b/features/fixtures/ios/iOSTestApp/CommandReaderThread.swift index 002dc11ea..0168cd695 100644 --- a/features/fixtures/ios/iOSTestApp/CommandReaderThread.swift +++ b/features/fixtures/ios/iOSTestApp/CommandReaderThread.swift @@ -81,19 +81,19 @@ class CommandReaderThread: Thread { } private func logInfo(_ message: String) { - let fullMessage = String(format: "bugsnagci info: %s", message) + let fullMessage = String(format: "bugsnagci info: %@", message) NSLog("%@", fullMessage) kslog("\(Date()) \(fullMessage)") } private func logWarn(_ message: String) { - let fullMessage = String(format: "bugsnagci warn: %s", message) + let fullMessage = String(format: "bugsnagci warn: %@", message) NSLog("%@", fullMessage) kslog("\(Date()) \(fullMessage)") } private func logError(_ message: String) { - let fullMessage = String(format: "bugsnagci error: %s", message) + let fullMessage = String(format: "bugsnagci error: %@", message) NSLog("%@", fullMessage) kslog("\(Date()) \(fullMessage)") } From df8c49769a75c2e4588a5355ac6bde6d28c20ab7 Mon Sep 17 00:00:00 2001 From: Karl Stenerud Date: Wed, 1 Nov 2023 16:17:35 +0100 Subject: [PATCH 16/61] Temporarily disable ios 11 E2E tests batches 1 and 2 --- .buildkite/pipeline.full.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.buildkite/pipeline.full.yml b/.buildkite/pipeline.full.yml index beacf56c6..3acc8fab0 100644 --- a/.buildkite/pipeline.full.yml +++ b/.buildkite/pipeline.full.yml @@ -248,6 +248,7 @@ steps: # BrowserStack # - label: ':browserstack: iOS 11 E2E tests batch 1' + skip: "https://smartbear.atlassian.net/browse/PLAT-11154" depends_on: - cocoa_fixture # More time than other steps as the BrowserStack iOS 11 devices seem particularly unstable and @@ -279,6 +280,7 @@ steps: limit: 2 - label: ':browserstack: iOS 11 E2E tests batch 2' + skip: "https://smartbear.atlassian.net/browse/PLAT-11154" depends_on: - cocoa_fixture # More time than other steps as the BrowserStack iOS 11 devices seem particularly unstable and From 3c0e2116af2d39e0e2fc9655c097a3ea3bc04e84 Mon Sep 17 00:00:00 2001 From: Steve Kirkland-Walton Date: Thu, 2 Nov 2023 11:55:26 +0000 Subject: [PATCH 17/61] Skip app hang scenarios on all platforms and iOS versions --- features/app_hangs.feature | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/features/app_hangs.feature b/features/app_hangs.feature index f2761d085..a2c91dbca 100644 --- a/features/app_hangs.feature +++ b/features/app_hangs.feature @@ -1,3 +1,4 @@ +@skip # https://smartbear.atlassian.net/browse/PLAT-11155 Feature: App hangs Background: @@ -105,7 +106,6 @@ Feature: App hangs When I run "AppHangDisabledScenario" Then I should receive no errors - @skip_ios_16 # https://smartbear.atlassian.net/browse/PLAT-11155 Scenario: Fatal app hangs should be reported if appHangThresholdMillis = BugsnagAppHangThresholdFatalOnly When I run "AppHangFatalOnlyScenario" And I wait for 6 seconds @@ -138,7 +138,6 @@ Feature: App hangs And the event "session.events.handled" equals 0 And the event "session.events.unhandled" equals 1 - @skip_ios_16 # https://smartbear.atlassian.net/browse/PLAT-11155 Scenario: Fatal app hangs should not be reported if enabledErrorTypes.appHangs = false When I run "AppHangFatalDisabledScenario" And I wait for 5 seconds @@ -147,7 +146,6 @@ Feature: App hangs Then I should receive no errors @skip_macos - @skip_ios_16 # https://smartbear.atlassian.net/browse/PLAT-11155 Scenario: Fatal app hangs should be reported if the app hangs before going to the background When I run "AppHangFatalOnlyScenario" And I wait for 5 seconds From 9f53e7bc997d2cf954d3656f596826c0684eb8f4 Mon Sep 17 00:00:00 2001 From: Steve Kirkland-Walton Date: Thu, 2 Nov 2023 12:10:16 +0000 Subject: [PATCH 18/61] Remove random ordering --- .buildkite/pipeline.full.yml | 12 ------------ .buildkite/pipeline.yml | 5 ----- 2 files changed, 17 deletions(-) diff --git a/.buildkite/pipeline.full.yml b/.buildkite/pipeline.full.yml index 3acc8fab0..52ddff668 100644 --- a/.buildkite/pipeline.full.yml +++ b/.buildkite/pipeline.full.yml @@ -80,7 +80,6 @@ steps: - "--aws-public-ip" - "--fail-fast" - "--exclude=features/[e-z].*.feature$" - - "--order=random" concurrency: 25 concurrency_group: 'bitbar' concurrency_method: eager @@ -111,7 +110,6 @@ steps: - "--aws-public-ip" - "--fail-fast" - "--exclude=features/[a-d].*.feature$" - - "--order=random" concurrency: 25 concurrency_group: 'bitbar' concurrency_method: eager @@ -142,7 +140,6 @@ steps: - "--aws-public-ip" - "--fail-fast" - "--exclude=features/[e-z].*.feature$" - - "--order=random" concurrency: 25 concurrency_group: 'bitbar' concurrency_method: eager @@ -173,7 +170,6 @@ steps: - "--aws-public-ip" - "--fail-fast" - "--exclude=features/[a-d].*.feature$" - - "--order=random" concurrency: 25 concurrency_group: 'bitbar' concurrency_method: eager @@ -204,7 +200,6 @@ steps: - "--aws-public-ip" - "--fail-fast" - "--exclude=features/[e-z].*.feature$" - - "--order=random" concurrency: 25 concurrency_group: 'bitbar' concurrency_method: eager @@ -235,7 +230,6 @@ steps: - "--aws-public-ip" - "--fail-fast" - "--exclude=features/[a-d].*.feature$" - - "--order=random" concurrency: 25 concurrency_group: 'bitbar' concurrency_method: eager @@ -270,7 +264,6 @@ steps: - "--appium-version=1.16.0" - "--fail-fast" - "--exclude=features/[e-z].*.feature$" - - "--order=random" concurrency: 5 concurrency_group: 'browserstack-app' concurrency_method: eager @@ -302,7 +295,6 @@ steps: - "--appium-version=1.16.0" - "--fail-fast" - "--exclude=features/[a-d].*.feature$" - - "--order=random" concurrency: 5 concurrency_group: 'browserstack-app' concurrency_method: eager @@ -326,7 +318,6 @@ steps: - bundle exec maze-runner --os=macos --fail-fast - --order=random - label: 'ARM macOS 12 E2E tests' depends_on: @@ -345,7 +336,6 @@ steps: - bundle exec maze-runner --os=macos --fail-fast - --order=random - label: 'macOS 10.13 E2E tests' depends_on: @@ -362,7 +352,6 @@ steps: - bundle exec maze-runner --os=macos --fail-fast - --order=random - label: 'macOS 10.14 E2E tests' depends_on: @@ -379,7 +368,6 @@ steps: - bundle exec maze-runner --os=macos --fail-fast - --order=random ############################################################################## # diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 9ca0f78c0..161921db4 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -221,7 +221,6 @@ steps: features/barebone_tests.feature --os=macos --fail-fast - --order=random - label: 'macOS 10.15 E2E tests' depends_on: @@ -238,7 +237,6 @@ steps: - bundle exec maze-runner --os=macos --fail-fast - --order=random - label: 'ARM macOS 12 barebones E2E tests' depends_on: @@ -258,7 +256,6 @@ steps: features/barebone_tests.feature --os=macos --fail-fast - --order=random - label: 'macOS 12 stress test' timeout_in_minutes: 3 @@ -309,7 +306,6 @@ steps: - "--aws-public-ip" - "--fail-fast" - "--exclude=features/[e-z].*.feature$" - - "--order=random" concurrency: 25 concurrency_group: 'bitbar' concurrency_method: eager @@ -340,7 +336,6 @@ steps: - "--aws-public-ip" - "--fail-fast" - "--exclude=features/[a-d].*.feature$" - - "--order=random" concurrency: 25 concurrency_group: 'bitbar' concurrency_method: eager From 957aad4869b4dc6f16587eaeb8bf8bdbae2e28f6 Mon Sep 17 00:00:00 2001 From: Karl Stenerud Date: Thu, 2 Nov 2023 13:09:03 +0100 Subject: [PATCH 19/61] Harmonize logging --- .../ios/iOSTestApp.xcodeproj/project.pbxproj | 12 ++++- .../fixtures/ios/iOSTestApp/AppDelegate.swift | 2 + .../ios/iOSTestApp/CommandReaderThread.swift | 18 -------- .../ios/iOSTestApp/ViewController.swift | 14 +++--- .../macOSTestApp.xcodeproj/project.pbxproj | 10 +++++ .../macos/macOSTestApp/MainWindowController.m | 28 ++++-------- .../shared/scenarios/AbortOverrideScenario.m | 1 + .../fixtures/shared/scenarios/AbortScenario.m | 1 + .../scenarios/AccessNonObjectScenario.m | 1 + .../AppHangDefaultConfigScenario.swift | 4 +- .../AppHangDidBecomeActiveScenario.swift | 2 +- .../AppHangDidEnterBackgroundScenario.swift | 2 +- .../scenarios/AppHangDisabledScenario.swift | 4 +- .../AppHangFatalDisabledScenario.swift | 2 +- .../scenarios/AppHangFatalOnlyScenario.swift | 2 +- .../AppHangInTerminationScenario.swift | 2 +- .../shared/scenarios/AppHangScenario.swift | 4 +- .../scenarios/AsyncSafeMallocScenario.m | 1 + .../scenarios/AsyncSafeThreadScenario.m | 3 +- .../shared/scenarios/AutoCaptureRunScenario.m | 1 + .../AutoSessionCustomVersionScenario.m | 1 + .../AutoSessionHandledEventsScenario.m | 1 + .../AutoSessionMixedEventsScenario.m | 1 + .../shared/scenarios/AutoSessionScenario.m | 1 + .../scenarios/AutoSessionUnhandledScenario.m | 1 + .../scenarios/AutoSessionWithUserScenario.m | 1 + .../BreadcrumbCallbackRemovalScenario.m | 1 + .../shared/scenarios/BuiltinTrapScenario.m | 1 + .../scenarios/ConcurrentCrashesScenario.mm | 1 + .../CouldNotCreateDirectoryScenario.swift | 2 +- .../CustomPluginNotifierDescriptionScenario.m | 1 + .../shared/scenarios/CxxBareThrowScenario.mm | 1 + .../scenarios/CxxExceptionOverrideScenario.mm | 1 + .../shared/scenarios/CxxExceptionScenario.mm | 1 + .../shared/scenarios/CxxUnexpectedScenario.mm | 1 + ...llExceptManualExceptionsAndCrashScenario.m | 1 + .../scenarios/DisableMachExceptionScenario.m | 1 + .../scenarios/DisableNSExceptionScenario.m | 1 + .../DisableSignalsExceptionScenario.m | 1 + .../DisabledSessionTrackingScenario.m | 1 + .../scenarios/EnabledErrorTypesCxxScenario.mm | 1 + .../HandledErrorThreadSendAlwaysScenario.m | 1 + ...dledErrorThreadSendUnhandledOnlyScenario.m | 1 + .../scenarios/InvalidCrashReportScenario.m | 1 + .../scenarios/LastRunInfoScenario.swift | 2 +- features/fixtures/shared/scenarios/Logging.h | 21 +++++++++ features/fixtures/shared/scenarios/Logging.m | 44 +++++++++++++++++++ .../shared/scenarios/ManualSessionScenario.m | 1 + .../scenarios/ManualSessionWithUserScenario.m | 1 + .../scenarios/ManyConcurrentNotifyScenario.m | 1 + .../scenarios/MarkUnhandledHandledScenario.m | 1 + .../scenarios/MaxPersistedSessionsScenario.m | 1 + .../scenarios/NSExceptionShiftScenario.m | 1 + .../scenarios/NonExistentMethodScenario.m | 1 + .../shared/scenarios/NullPointerScenario.m | 1 + .../scenarios/OOMInactiveScenario.swift | 2 +- .../fixtures/shared/scenarios/OOMScenario.m | 17 +++---- .../shared/scenarios/OOMSessionlessScenario.m | 1 + .../scenarios/OOMWillTerminateScenario.m | 1 + .../scenarios/ObjCExceptionOverrideScenario.m | 1 + .../shared/scenarios/ObjCExceptionScenario.m | 1 + .../shared/scenarios/ObjCMsgSendScenario.m | 1 + .../scenarios/OldCrashReportScenario.swift | 4 +- .../scenarios/OldHandledErrorScenario.swift | 4 +- .../shared/scenarios/OldSessionScenario.m | 5 ++- .../shared/scenarios/OnCrashHandlerScenario.m | 1 + .../scenarios/OnSendCallbackRemovalScenario.m | 1 + .../OnSendErrorPersistenceScenario.m | 1 + .../scenarios/OverwriteLinkRegisterScenario.m | 1 + .../scenarios/PrivilegedInstructionScenario.m | 1 + .../scenarios/ReadGarbagePointerScenario.m | 1 + .../shared/scenarios/ReadOnlyPageScenario.m | 1 + .../shared/scenarios/RecrashScenarios.mm | 1 + .../shared/scenarios/ReleasedObjectScenario.m | 1 + .../ReportBackgroundAppHangScenario.swift | 4 +- .../scenarios/ResumeSessionOOMScenario.m | 1 + .../shared/scenarios/SIGBUSScenario.m | 1 + .../shared/scenarios/SIGFPEScenario.m | 1 + .../shared/scenarios/SIGILLScenario.m | 1 + .../shared/scenarios/SIGPIPEIgnoredScenario.m | 1 + .../shared/scenarios/SIGPIPEScenario.m | 1 + .../shared/scenarios/SIGSEGVScenario.m | 1 + .../shared/scenarios/SIGSYSScenario.m | 1 + .../shared/scenarios/SIGTRAPScenario.m | 1 + features/fixtures/shared/scenarios/Scenario.h | 2 +- features/fixtures/shared/scenarios/Scenario.m | 36 +++++++-------- ...SynchronouslyLaunchCompletedScenario.swift | 2 +- ...ndLaunchCrashesSynchronouslyScenario.swift | 4 +- .../SessionCallbackRemovalScenario.m | 1 + .../shared/scenarios/SessionOOMScenario.m | 1 + .../shared/scenarios/StackOverflowScenario.m | 1 + .../shared/scenarios/StopSessionOOMScenario.m | 1 + .../scenarios/UndefinedInstructionScenario.m | 1 + .../UnhandledErrorThreadSendAlwaysScenario.m | 1 + .../UnhandledErrorThreadSendNeverScenario.m | 1 + .../UnhandledMachExceptionOverrideScenario.m | 1 + .../UnhandledMachExceptionScenario.m | 1 + .../UserPersistenceDontPersistUserScenario.m | 1 + .../scenarios/UserPersistenceNoUserScenario.m | 1 + ...UserPersistencePersistUserClientScenario.m | 1 + .../UserPersistencePersistUserScenario.m | 1 + .../shared/utils/BugsnagWrapper.swift | 4 +- features/fixtures/shared/utils/Logging.swift | 36 +++++++++++++++ 103 files changed, 265 insertions(+), 105 deletions(-) create mode 100644 features/fixtures/shared/scenarios/Logging.h create mode 100644 features/fixtures/shared/scenarios/Logging.m create mode 100644 features/fixtures/shared/utils/Logging.swift diff --git a/features/fixtures/ios/iOSTestApp.xcodeproj/project.pbxproj b/features/fixtures/ios/iOSTestApp.xcodeproj/project.pbxproj index 4e06e3de9..af196dd77 100644 --- a/features/fixtures/ios/iOSTestApp.xcodeproj/project.pbxproj +++ b/features/fixtures/ios/iOSTestApp.xcodeproj/project.pbxproj @@ -86,6 +86,8 @@ 01F6B75E2832757F00B75C5D /* OversizedCrashReportScenario.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01F6B75C2832757F00B75C5D /* OversizedCrashReportScenario.swift */; }; 01F6B75F2832757F00B75C5D /* OversizedHandledErrorScenario.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01F6B75D2832757F00B75C5D /* OversizedHandledErrorScenario.swift */; }; 01FA9EC426D63BB20059FF4A /* AppHangInTerminationScenario.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01FA9EC326D63BB20059FF4A /* AppHangInTerminationScenario.swift */; }; + 095E095A2AF3BE8D00273F1F /* Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 095E09592AF3BE8D00273F1F /* Logging.swift */; }; + 095E095D2AF3BFDA00273F1F /* Logging.m in Sources */ = {isa = PBXBuildFile; fileRef = 095E095C2AF3BFDA00273F1F /* Logging.m */; }; 6526A0D4248A83350002E2C9 /* LoadConfigFromFileAutoScenario.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6526A0D3248A83350002E2C9 /* LoadConfigFromFileAutoScenario.swift */; }; 8A096DF627C7E56C00DB6ECC /* CxxUnexpectedScenario.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8A096DF527C7E56C00DB6ECC /* CxxUnexpectedScenario.mm */; }; 8A096DFC27C7E77600DB6ECC /* CxxBareThrowScenario.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8A096DFB27C7E77600DB6ECC /* CxxBareThrowScenario.mm */; }; @@ -283,6 +285,9 @@ 01F6B75C2832757F00B75C5D /* OversizedCrashReportScenario.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OversizedCrashReportScenario.swift; sourceTree = ""; }; 01F6B75D2832757F00B75C5D /* OversizedHandledErrorScenario.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OversizedHandledErrorScenario.swift; sourceTree = ""; }; 01FA9EC326D63BB20059FF4A /* AppHangInTerminationScenario.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppHangInTerminationScenario.swift; sourceTree = ""; }; + 095E09592AF3BE8D00273F1F /* Logging.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Logging.swift; sourceTree = ""; }; + 095E095B2AF3BFDA00273F1F /* Logging.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Logging.h; sourceTree = ""; }; + 095E095C2AF3BFDA00273F1F /* Logging.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Logging.m; sourceTree = ""; }; 6526A0D3248A83350002E2C9 /* LoadConfigFromFileAutoScenario.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoadConfigFromFileAutoScenario.swift; sourceTree = ""; }; 8A096DF527C7E56C00DB6ECC /* CxxUnexpectedScenario.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = CxxUnexpectedScenario.mm; sourceTree = ""; }; 8A096DFB27C7E77600DB6ECC /* CxxBareThrowScenario.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CxxBareThrowScenario.mm; sourceTree = ""; }; @@ -454,6 +459,7 @@ isa = PBXGroup; children = ( AA4C7F1429AEA0C4009B09A9 /* BugsnagWrapper.swift */, + 095E09592AF3BE8D00273F1F /* Logging.swift */, ); name = utils; path = ../shared/utils; @@ -547,10 +553,13 @@ 8AB1081823301FE600672818 /* HandledErrorValidReleaseStageScenario.swift */, F429526319377A8848136413 /* HandledExceptionScenario.swift */, 8AF8FCAD22BD23BA00A967CA /* HandledInternalNotifyScenario.swift */, + 967F6F1129B2236A0054EED8 /* InternalWorkingsScenario.swift */, 01847DD526453D4E00ADA4C7 /* InvalidCrashReportScenario.m */, 01B6BB7425D5748800FC4DE6 /* LastRunInfoScenario.swift */, 6526A0D3248A83350002E2C9 /* LoadConfigFromFileAutoScenario.swift */, 8AB65FCB22DC77CB001200AB /* LoadConfigFromFileScenario.swift */, + 095E095B2AF3BFDA00273F1F /* Logging.h */, + 095E095C2AF3BFDA00273F1F /* Logging.m */, E7B79CD1247FD66E0039FB88 /* ManualContextClientScenario.swift */, E7B79CCF247FD6660039FB88 /* ManualContextConfigurationScenario.swift */, E7B79CD3247FD6760039FB88 /* ManualContextOnErrorScenario.swift */, @@ -657,7 +666,6 @@ 010BAAF22833CE570003FF36 /* UserPersistencePersistUserClientScenario.m */, 010BAAF82833CE570003FF36 /* UserPersistencePersistUserScenario.m */, E700EE49247D1164008CFFB6 /* UserSessionOverrideScenario.swift */, - 967F6F1129B2236A0054EED8 /* InternalWorkingsScenario.swift */, ); name = scenarios; path = ../shared/scenarios; @@ -843,10 +851,12 @@ 010BAB0B2833CE570003FF36 /* CxxExceptionOverrideScenario.mm in Sources */, 01DE903826CE99B800455213 /* CriticalThermalStateScenario.swift in Sources */, 01B6BBB625DA82B800FC4DE6 /* SendLaunchCrashesSynchronouslyScenario.swift in Sources */, + 095E095D2AF3BFDA00273F1F /* Logging.m in Sources */, F4295836C8AF75547C675E8D /* ReleasedObjectScenario.m in Sources */, 01E5EAD225B713990066EA8A /* OOMScenario.m in Sources */, 010BAB3D2833D2890003FF36 /* DisabledReleaseStageManualSessionScenario.swift in Sources */, 01F6B75E2832757F00B75C5D /* OversizedCrashReportScenario.swift in Sources */, + 095E095A2AF3BE8D00273F1F /* Logging.swift in Sources */, 8A530CCC22FDDBF000F0C108 /* ManyConcurrentNotifyScenario.m in Sources */, 010BAB112833CEEC0003FF36 /* AppAndDeviceAttributesConfigOverrideScenario.swift in Sources */, 010BAB0A2833CE570003FF36 /* DisableSignalsExceptionScenario.m in Sources */, diff --git a/features/fixtures/ios/iOSTestApp/AppDelegate.swift b/features/fixtures/ios/iOSTestApp/AppDelegate.swift index 00612edbc..fa9713898 100644 --- a/features/fixtures/ios/iOSTestApp/AppDelegate.swift +++ b/features/fixtures/ios/iOSTestApp/AppDelegate.swift @@ -1,4 +1,5 @@ import UIKit +import os @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { @@ -6,6 +7,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + logInfo("========== Fixture app has launched ==========") return true } } diff --git a/features/fixtures/ios/iOSTestApp/CommandReaderThread.swift b/features/fixtures/ios/iOSTestApp/CommandReaderThread.swift index 0168cd695..85f5e2a8a 100644 --- a/features/fixtures/ios/iOSTestApp/CommandReaderThread.swift +++ b/features/fixtures/ios/iOSTestApp/CommandReaderThread.swift @@ -79,21 +79,3 @@ class CommandReaderThread: Thread { return bsAddress; } } - -private func logInfo(_ message: String) { - let fullMessage = String(format: "bugsnagci info: %@", message) - NSLog("%@", fullMessage) - kslog("\(Date()) \(fullMessage)") -} - -private func logWarn(_ message: String) { - let fullMessage = String(format: "bugsnagci warn: %@", message) - NSLog("%@", fullMessage) - kslog("\(Date()) \(fullMessage)") -} - -private func logError(_ message: String) { - let fullMessage = String(format: "bugsnagci error: %@", message) - NSLog("%@", fullMessage) - kslog("\(Date()) \(fullMessage)") -} diff --git a/features/fixtures/ios/iOSTestApp/ViewController.swift b/features/fixtures/ios/iOSTestApp/ViewController.swift index 708d5306f..ab408a0da 100644 --- a/features/fixtures/ios/iOSTestApp/ViewController.swift +++ b/features/fixtures/ios/iOSTestApp/ViewController.swift @@ -25,6 +25,7 @@ class ViewController: UIViewController { self.view.addGestureRecognizer(UITapGestureRecognizer(target: self.view, action: #selector(UIView.endEditing(_:)))) NotificationCenter.default.addObserver(self, selector: #selector(didEnterBackgroundNotification), name: UIApplication.didEnterBackgroundNotification, object: nil) apiKeyField.text = UserDefaults.standard.string(forKey: "apiKey") + logInfo("Read API key from UserDefaults: \(apiKeyField.text!)") // Poll for commands to run if #available(iOS 10.0, *) { @@ -43,18 +44,18 @@ class ViewController: UIViewController { if Scenario.current == nil { prepareScenario() - log("Starting Bugsnag for scenario: \(Scenario.current!)") + logInfo("Starting Bugsnag for scenario: \(Scenario.current!)") Scenario.current!.startBugsnag() } - log("Running scenario: \(Scenario.current!)") + logInfo("Running scenario: \(Scenario.current!)") Scenario.current!.run() } @IBAction func startBugsnag() { prepareScenario() - log("Starting Bugsnag for scenario: \(Scenario.current!)") + logInfo("Starting Bugsnag for scenario: \(Scenario.current!)") Scenario.current!.startBugsnag() } @@ -67,7 +68,7 @@ class ViewController: UIViewController { if (apiKeyField.text!.count > 0) { // Manual testing mode - use the real dashboard and the API key provided let apiKey = apiKeyField.text! - NSLog("Running in manual mode with API key: %@", apiKey) + logInfo("Running in manual mode with API key: \(apiKey)") UserDefaults.standard.setValue(apiKey, forKey: "apiKey") config = BugsnagConfiguration(apiKeyField.text!) } @@ -81,8 +82,3 @@ class ViewController: UIViewController { Scenario.current?.didEnterBackgroundNotification() } } - -private func log(_ message: String) { - NSLog("%@", message) - kslog("\(Date()) \(message)") -} diff --git a/features/fixtures/macos/macOSTestApp.xcodeproj/project.pbxproj b/features/fixtures/macos/macOSTestApp.xcodeproj/project.pbxproj index 86fcd1b83..4bba25555 100644 --- a/features/fixtures/macos/macOSTestApp.xcodeproj/project.pbxproj +++ b/features/fixtures/macos/macOSTestApp.xcodeproj/project.pbxproj @@ -182,6 +182,8 @@ 01F6B74F2832381300B75C5D /* OversizedCrashReportScenario.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01F6B74B2832381300B75C5D /* OversizedCrashReportScenario.swift */; }; 01F7365A278D90440000113C /* NetworkBreadcrumbsScenario.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01F73659278D90440000113C /* NetworkBreadcrumbsScenario.swift */; }; 01FA9EC626D64FFF0059FF4A /* AppHangInTerminationScenario.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01FA9EC526D64FFF0059FF4A /* AppHangInTerminationScenario.swift */; }; + 095E095F2AF3C98F00273F1F /* Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 095E095E2AF3C98F00273F1F /* Logging.swift */; }; + 095E09622AF3C9A500273F1F /* Logging.m in Sources */ = {isa = PBXBuildFile; fileRef = 095E09612AF3C9A500273F1F /* Logging.m */; }; 8A096DF827C7E63A00DB6ECC /* CxxUnexpectedScenario.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8A096DF727C7E63A00DB6ECC /* CxxUnexpectedScenario.mm */; }; 8A096DFA27C7E6D800DB6ECC /* CxxBareThrowScenario.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8A096DF927C7E6D800DB6ECC /* CxxBareThrowScenario.mm */; }; 967F6F1629B767CE0054EED8 /* InternalWorkingsScenario.swift in Sources */ = {isa = PBXBuildFile; fileRef = 967F6F1529B767CE0054EED8 /* InternalWorkingsScenario.swift */; }; @@ -388,6 +390,9 @@ 01F6B74B2832381300B75C5D /* OversizedCrashReportScenario.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OversizedCrashReportScenario.swift; sourceTree = ""; }; 01F73659278D90440000113C /* NetworkBreadcrumbsScenario.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkBreadcrumbsScenario.swift; sourceTree = ""; }; 01FA9EC526D64FFF0059FF4A /* AppHangInTerminationScenario.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppHangInTerminationScenario.swift; sourceTree = ""; }; + 095E095E2AF3C98F00273F1F /* Logging.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Logging.swift; sourceTree = ""; }; + 095E09602AF3C9A500273F1F /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Logging.h; sourceTree = ""; }; + 095E09612AF3C9A500273F1F /* Logging.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Logging.m; sourceTree = ""; }; 2C49722B331FF4B0DC477462 /* Pods-macOSTestApp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-macOSTestApp.release.xcconfig"; path = "Target Support Files/Pods-macOSTestApp/Pods-macOSTestApp.release.xcconfig"; sourceTree = ""; }; 5C65BFC9838298CFA8A35072 /* Pods_macOSTestApp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_macOSTestApp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 8A096DF727C7E63A00DB6ECC /* CxxUnexpectedScenario.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CxxUnexpectedScenario.mm; sourceTree = ""; }; @@ -494,6 +499,8 @@ 01B6BB7125D56CBF00FC4DE6 /* LastRunInfoScenario.swift */, 01F47C23254B1B2C00B184AD /* LoadConfigFromFileAutoScenario.swift */, 01F47C94254B1B2F00B184AD /* LoadConfigFromFileScenario.swift */, + 095E09602AF3C9A500273F1F /* Logging.h */, + 095E09612AF3C9A500273F1F /* Logging.m */, 01F47C3B254B1B2D00B184AD /* ManualContextClientScenario.swift */, 01F47C47254B1B2D00B184AD /* ManualContextConfigurationScenario.swift */, 01F47C82254B1B2F00B184AD /* ManualContextOnErrorScenario.swift */, @@ -658,6 +665,7 @@ isa = PBXGroup; children = ( AA4C7F1729AEA31D009B09A9 /* BugsnagWrapper.swift */, + 095E095E2AF3C98F00273F1F /* Logging.swift */, ); name = utils; path = ../shared/utils; @@ -795,6 +803,7 @@ 01F47D08254B1B3100B184AD /* AutoSessionCustomVersionScenario.m in Sources */, 01F47CC6254B1B3100B184AD /* HandledExceptionScenario.swift in Sources */, 01F47D0D254B1B3100B184AD /* LoadConfigFromFileScenario.swift in Sources */, + 095E09622AF3C9A500273F1F /* Logging.m in Sources */, 01F47CF5254B1B3100B184AD /* StoppedSessionScenario.swift in Sources */, 010BAB772833D34A0003FF36 /* DiscardClassesHandledExceptionRegexScenario.swift in Sources */, 01F47D23254B1B3100B184AD /* SwiftAssertionScenario.swift in Sources */, @@ -849,6 +858,7 @@ 010BAB722833D34A0003FF36 /* BareboneTestHandledScenario.swift in Sources */, 017D9CFC2833C81100B0AA87 /* DisableMachExceptionScenario.m in Sources */, 01DE903A26CEAD1200455213 /* CriticalThermalStateScenario.swift in Sources */, + 095E095F2AF3C98F00273F1F /* Logging.swift in Sources */, 01F47CF9254B1B3100B184AD /* BreadcrumbCallbackDiscardScenario.swift in Sources */, AA6ACD1E2773E39C006464C4 /* UserInfoScenario.swift in Sources */, 01018BAB25E417EC000312C6 /* AsyncSafeMallocScenario.m in Sources */, diff --git a/features/fixtures/macos/macOSTestApp/MainWindowController.m b/features/fixtures/macos/macOSTestApp/MainWindowController.m index 479d24ee4..7eecaa82f 100644 --- a/features/fixtures/macos/macOSTestApp/MainWindowController.m +++ b/features/fixtures/macos/macOSTestApp/MainWindowController.m @@ -9,12 +9,10 @@ #import "MainWindowController.h" #import "Scenario.h" +#import "Logging.h" #import -static void BSLog(NSString *format, ...) NS_FORMAT_FUNCTION(1,2) NS_NO_TAIL_CALL; - - @interface MainWindowController () // These properties are used with Cocoa Bindings @@ -50,39 +48,39 @@ - (BugsnagConfiguration *)configuration { } - (IBAction)runScenario:(id)sender { - BSLog(@"%s %@", __PRETTY_FUNCTION__, self.scenarioName); + logInfo(@"%s %@", __PRETTY_FUNCTION__, self.scenarioName); // Cater for multiple calls to -run if (!Scenario.currentScenario) { [Scenario createScenarioNamed:self.scenarioName withConfig:[self configuration]]; Scenario.currentScenario.eventMode = self.scenarioMetadata; - BSLog(@"Starting Bugsnag for scenario: %@", Scenario.currentScenario); + logInfo(@"Starting Bugsnag for scenario: %@", Scenario.currentScenario); [Scenario.currentScenario startBugsnag]; } - BSLog(@"Will run scenario: %@", Scenario.currentScenario); + logInfo(@"Will run scenario: %@", Scenario.currentScenario); // Using dispatch_async to prevent AppleEvents swallowing exceptions. // For more info see https://www.chimehq.com/blog/sad-state-of-exceptions // 0.1s delay allows accessibility APIs to finish handling the mouse click and returns control to the tests framework. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - BSLog(@"Running scenario: %@", Scenario.currentScenario); + logInfo(@"Running scenario: %@", Scenario.currentScenario); [Scenario.currentScenario run]; }); } - (IBAction)startBugsnag:(id)sender { - BSLog(@"%s %@", __PRETTY_FUNCTION__, self.scenarioName); + logInfo(@"%s %@", __PRETTY_FUNCTION__, self.scenarioName); [Scenario createScenarioNamed:self.scenarioName withConfig:[self configuration]]; Scenario.currentScenario.eventMode = self.scenarioMetadata; - BSLog(@"Starting Bugsnag for scenario: %@", Scenario.currentScenario); + logInfo(@"Starting Bugsnag for scenario: %@", Scenario.currentScenario); [Scenario.currentScenario startBugsnag]; } - (IBAction)clearPersistentData:(id)sender { - BSLog(@"Clearing persistent data"); + logInfo(@"Clearing persistent data"); [Scenario clearPersistentData]; } @@ -100,13 +98,3 @@ - (IBAction)executeMazeRunnerCommand:(id)sender { } @end - - -static void BSLog(NSString *format, ...) { - va_list vl; - va_start(vl, format); - NSString *message = [[NSString alloc] initWithFormat:format arguments:vl]; - NSLog(@"%@", message); - kslog(message.UTF8String); - va_end(vl); -} diff --git a/features/fixtures/shared/scenarios/AbortOverrideScenario.m b/features/fixtures/shared/scenarios/AbortOverrideScenario.m index 9b8c33b3c..1f1e3d347 100644 --- a/features/fixtures/shared/scenarios/AbortOverrideScenario.m +++ b/features/fixtures/shared/scenarios/AbortOverrideScenario.m @@ -25,6 +25,7 @@ */ #import "MarkUnhandledHandledScenario.h" +#import "Logging.h" @interface AbortOverrideScenario : MarkUnhandledHandledScenario @end diff --git a/features/fixtures/shared/scenarios/AbortScenario.m b/features/fixtures/shared/scenarios/AbortScenario.m index b1d5aa8d2..3c5a2d3e1 100644 --- a/features/fixtures/shared/scenarios/AbortScenario.m +++ b/features/fixtures/shared/scenarios/AbortScenario.m @@ -25,6 +25,7 @@ */ #import "Scenario.h" +#import "Logging.h" @interface AbortScenario : Scenario @end diff --git a/features/fixtures/shared/scenarios/AccessNonObjectScenario.m b/features/fixtures/shared/scenarios/AccessNonObjectScenario.m index f932f74a1..0927824ef 100644 --- a/features/fixtures/shared/scenarios/AccessNonObjectScenario.m +++ b/features/fixtures/shared/scenarios/AccessNonObjectScenario.m @@ -25,6 +25,7 @@ */ #import "Scenario.h" +#import "Logging.h" /** * Call NSLog(@"%@", 16);, causing a crash when the runtime attempts to treat 16 as a pointer to an object. diff --git a/features/fixtures/shared/scenarios/AppHangDefaultConfigScenario.swift b/features/fixtures/shared/scenarios/AppHangDefaultConfigScenario.swift index 7f57fff30..0754b0656 100644 --- a/features/fixtures/shared/scenarios/AppHangDefaultConfigScenario.swift +++ b/features/fixtures/shared/scenarios/AppHangDefaultConfigScenario.swift @@ -2,8 +2,8 @@ class AppHangDefaultConfigScenario: Scenario { override func run() { let timeInterval: TimeInterval = 5 - NSLog("Simulating an app hang of \(timeInterval) seconds...") + logInfo("Simulating an app hang of \(timeInterval) seconds...") Thread.sleep(forTimeInterval: timeInterval) - NSLog("Finished sleeping") + logInfo("Finished sleeping") } } diff --git a/features/fixtures/shared/scenarios/AppHangDidBecomeActiveScenario.swift b/features/fixtures/shared/scenarios/AppHangDidBecomeActiveScenario.swift index db796072e..bb1f1bbea 100644 --- a/features/fixtures/shared/scenarios/AppHangDidBecomeActiveScenario.swift +++ b/features/fixtures/shared/scenarios/AppHangDidBecomeActiveScenario.swift @@ -10,7 +10,7 @@ class AppHangDidBecomeActiveScenario: Scenario { override func run() { NotificationCenter.default.addObserver(forName: UIApplication.didBecomeActiveNotification, object: nil, queue: nil) { - NSLog("Received \($0.name), now sleeping for 3 seconds...") + logInfo("Received \($0.name), now sleeping for 3 seconds...") Thread.sleep(forTimeInterval: 3) } } diff --git a/features/fixtures/shared/scenarios/AppHangDidEnterBackgroundScenario.swift b/features/fixtures/shared/scenarios/AppHangDidEnterBackgroundScenario.swift index a5e650522..8905719a5 100644 --- a/features/fixtures/shared/scenarios/AppHangDidEnterBackgroundScenario.swift +++ b/features/fixtures/shared/scenarios/AppHangDidEnterBackgroundScenario.swift @@ -4,7 +4,7 @@ class AppHangDidEnterBackgroundScenario: Scenario { override func run() { NotificationCenter.default.addObserver(forName: UIApplication.didEnterBackgroundNotification, object: nil, queue: nil) { - NSLog("Received \($0.name), now hanging indefinitely...") + logInfo("Received \($0.name), now hanging indefinitely...") while true {} } } diff --git a/features/fixtures/shared/scenarios/AppHangDisabledScenario.swift b/features/fixtures/shared/scenarios/AppHangDisabledScenario.swift index 2be4b4de3..852ff3168 100644 --- a/features/fixtures/shared/scenarios/AppHangDisabledScenario.swift +++ b/features/fixtures/shared/scenarios/AppHangDisabledScenario.swift @@ -7,8 +7,8 @@ class AppHangDisabledScenario: Scenario { override func run() { let timeInterval: TimeInterval = 5 - NSLog("Simulating an app hang of \(timeInterval) seconds...") + logInfo("Simulating an app hang of \(timeInterval) seconds...") Thread.sleep(forTimeInterval: timeInterval) - NSLog("Finished sleeping") + logInfo("Finished sleeping") } } diff --git a/features/fixtures/shared/scenarios/AppHangFatalDisabledScenario.swift b/features/fixtures/shared/scenarios/AppHangFatalDisabledScenario.swift index 912674eb2..7cf1a1bd8 100644 --- a/features/fixtures/shared/scenarios/AppHangFatalDisabledScenario.swift +++ b/features/fixtures/shared/scenarios/AppHangFatalDisabledScenario.swift @@ -7,7 +7,7 @@ class AppHangFatalDisabledScenario: Scenario { } override func run() { - NSLog("Hanging indefinitely...") + logInfo("Hanging indefinitely...") // Use asyncAfter to allow the Appium click event to be handled DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { while true {} diff --git a/features/fixtures/shared/scenarios/AppHangFatalOnlyScenario.swift b/features/fixtures/shared/scenarios/AppHangFatalOnlyScenario.swift index f76630479..2b43e3882 100644 --- a/features/fixtures/shared/scenarios/AppHangFatalOnlyScenario.swift +++ b/features/fixtures/shared/scenarios/AppHangFatalOnlyScenario.swift @@ -9,7 +9,7 @@ class AppHangFatalOnlyScenario: Scenario { } override func run() { - NSLog("Hanging indefinitely...") + logInfo("Hanging indefinitely...") // Use asyncAfter to allow the Appium click event to be handled DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) { while true {} diff --git a/features/fixtures/shared/scenarios/AppHangInTerminationScenario.swift b/features/fixtures/shared/scenarios/AppHangInTerminationScenario.swift index 8a3026f5e..a774a6433 100644 --- a/features/fixtures/shared/scenarios/AppHangInTerminationScenario.swift +++ b/features/fixtures/shared/scenarios/AppHangInTerminationScenario.swift @@ -27,7 +27,7 @@ class AppHangInTerminationScenario: Scenario { #endif NotificationCenter.default.addObserver(forName: willTerminate, object: nil, queue: nil) { - NSLog("Received \($0.name.rawValue), simulating an app hang...") + logInfo("Received \($0.name.rawValue), simulating an app hang...") Thread.sleep(forTimeInterval: 3) } diff --git a/features/fixtures/shared/scenarios/AppHangScenario.swift b/features/fixtures/shared/scenarios/AppHangScenario.swift index 6bcc202cc..5dda91cd5 100644 --- a/features/fixtures/shared/scenarios/AppHangScenario.swift +++ b/features/fixtures/shared/scenarios/AppHangScenario.swift @@ -18,7 +18,7 @@ class AppHangScenario: Scenario { override func run() { Bugsnag.setContext("App Hang Scenario") let timeInterval = TimeInterval(eventMode!)! - NSLog("Simulating an app hang of \(timeInterval) seconds...") + logInfo("Simulating an app hang of \(timeInterval) seconds...") if timeInterval > 2 { Thread.sleep(forTimeInterval: 1.5) Bugsnag.leaveBreadcrumb(withMessage: "This breadcrumb was left during the hang, before detection") @@ -27,6 +27,6 @@ class AppHangScenario: Scenario { Thread.sleep(forTimeInterval: timeInterval) } Bugsnag.leaveBreadcrumb(withMessage: "This breadcrumb was left after the hang") - NSLog("Finished sleeping") + logInfo("Finished sleeping") } } diff --git a/features/fixtures/shared/scenarios/AsyncSafeMallocScenario.m b/features/fixtures/shared/scenarios/AsyncSafeMallocScenario.m index bf955a39a..35927083e 100644 --- a/features/fixtures/shared/scenarios/AsyncSafeMallocScenario.m +++ b/features/fixtures/shared/scenarios/AsyncSafeMallocScenario.m @@ -7,6 +7,7 @@ // #import "Scenario.h" +#import "Logging.h" #include "spin_malloc.h" @interface AsyncSafeMallocScenario : Scenario diff --git a/features/fixtures/shared/scenarios/AsyncSafeThreadScenario.m b/features/fixtures/shared/scenarios/AsyncSafeThreadScenario.m index a72792f68..21469d72e 100644 --- a/features/fixtures/shared/scenarios/AsyncSafeThreadScenario.m +++ b/features/fixtures/shared/scenarios/AsyncSafeThreadScenario.m @@ -25,6 +25,7 @@ */ #import "Scenario.h" +#import "Logging.h" #import /** @@ -46,7 +47,7 @@ - (void)run { /* This is unreachable, but prevents clang from applying TCO to the above when * optimization is enabled. */ - NSLog(@"I'm here from the tail call prevention department."); + logInfo(@"I'm here from the tail call prevention department."); } @end diff --git a/features/fixtures/shared/scenarios/AutoCaptureRunScenario.m b/features/fixtures/shared/scenarios/AutoCaptureRunScenario.m index 21332dd4b..dc720615c 100644 --- a/features/fixtures/shared/scenarios/AutoCaptureRunScenario.m +++ b/features/fixtures/shared/scenarios/AutoCaptureRunScenario.m @@ -7,6 +7,7 @@ // #import "Scenario.h" +#import "Logging.h" @interface AutoCaptureRunScenario : Scenario @end diff --git a/features/fixtures/shared/scenarios/AutoSessionCustomVersionScenario.m b/features/fixtures/shared/scenarios/AutoSessionCustomVersionScenario.m index f73ba2f34..a5ff35082 100644 --- a/features/fixtures/shared/scenarios/AutoSessionCustomVersionScenario.m +++ b/features/fixtures/shared/scenarios/AutoSessionCustomVersionScenario.m @@ -7,6 +7,7 @@ // #import "Scenario.h" +#import "Logging.h" @interface AutoSessionCustomVersionScenario : Scenario @end diff --git a/features/fixtures/shared/scenarios/AutoSessionHandledEventsScenario.m b/features/fixtures/shared/scenarios/AutoSessionHandledEventsScenario.m index 7f057ae89..79c36adb5 100644 --- a/features/fixtures/shared/scenarios/AutoSessionHandledEventsScenario.m +++ b/features/fixtures/shared/scenarios/AutoSessionHandledEventsScenario.m @@ -7,6 +7,7 @@ // #import "Scenario.h" +#import "Logging.h" @interface AutoSessionHandledEventsScenario : Scenario @end diff --git a/features/fixtures/shared/scenarios/AutoSessionMixedEventsScenario.m b/features/fixtures/shared/scenarios/AutoSessionMixedEventsScenario.m index fd03d0f2e..09bd7a1f5 100644 --- a/features/fixtures/shared/scenarios/AutoSessionMixedEventsScenario.m +++ b/features/fixtures/shared/scenarios/AutoSessionMixedEventsScenario.m @@ -7,6 +7,7 @@ // #import "Scenario.h" +#import "Logging.h" @interface AutoSessionMixedEventsScenario : Scenario diff --git a/features/fixtures/shared/scenarios/AutoSessionScenario.m b/features/fixtures/shared/scenarios/AutoSessionScenario.m index 49ef6d824..8ef94cb27 100644 --- a/features/fixtures/shared/scenarios/AutoSessionScenario.m +++ b/features/fixtures/shared/scenarios/AutoSessionScenario.m @@ -4,6 +4,7 @@ // #import "Scenario.h" +#import "Logging.h" /** * Sends an automatic session payload to Bugsnag. diff --git a/features/fixtures/shared/scenarios/AutoSessionUnhandledScenario.m b/features/fixtures/shared/scenarios/AutoSessionUnhandledScenario.m index d1eb8b40a..bbfd91200 100644 --- a/features/fixtures/shared/scenarios/AutoSessionUnhandledScenario.m +++ b/features/fixtures/shared/scenarios/AutoSessionUnhandledScenario.m @@ -7,6 +7,7 @@ // #import "Scenario.h" +#import "Logging.h" @interface AutoSessionUnhandledScenario : Scenario @end diff --git a/features/fixtures/shared/scenarios/AutoSessionWithUserScenario.m b/features/fixtures/shared/scenarios/AutoSessionWithUserScenario.m index 0c70fc70d..4e951eaef 100644 --- a/features/fixtures/shared/scenarios/AutoSessionWithUserScenario.m +++ b/features/fixtures/shared/scenarios/AutoSessionWithUserScenario.m @@ -7,6 +7,7 @@ // #import "Scenario.h" +#import "Logging.h" @interface AutoSessionWithUserScenario : Scenario @end diff --git a/features/fixtures/shared/scenarios/BreadcrumbCallbackRemovalScenario.m b/features/fixtures/shared/scenarios/BreadcrumbCallbackRemovalScenario.m index 30f19c8fa..7fd294638 100644 --- a/features/fixtures/shared/scenarios/BreadcrumbCallbackRemovalScenario.m +++ b/features/fixtures/shared/scenarios/BreadcrumbCallbackRemovalScenario.m @@ -7,6 +7,7 @@ // #import "Scenario.h" +#import "Logging.h" @interface BreadcrumbCallbackRemovalScenario : Scenario @end diff --git a/features/fixtures/shared/scenarios/BuiltinTrapScenario.m b/features/fixtures/shared/scenarios/BuiltinTrapScenario.m index 633260ad3..2018d978d 100644 --- a/features/fixtures/shared/scenarios/BuiltinTrapScenario.m +++ b/features/fixtures/shared/scenarios/BuiltinTrapScenario.m @@ -4,6 +4,7 @@ // #import "Scenario.h" +#import "Logging.h" #import "spin_malloc.h" diff --git a/features/fixtures/shared/scenarios/ConcurrentCrashesScenario.mm b/features/fixtures/shared/scenarios/ConcurrentCrashesScenario.mm index 5043fda71..c4b7f069a 100644 --- a/features/fixtures/shared/scenarios/ConcurrentCrashesScenario.mm +++ b/features/fixtures/shared/scenarios/ConcurrentCrashesScenario.mm @@ -7,6 +7,7 @@ // #import "Scenario.h" +#import "Logging.h" #import #import diff --git a/features/fixtures/shared/scenarios/CouldNotCreateDirectoryScenario.swift b/features/fixtures/shared/scenarios/CouldNotCreateDirectoryScenario.swift index 293f5dd22..e5e2f6c23 100644 --- a/features/fixtures/shared/scenarios/CouldNotCreateDirectoryScenario.swift +++ b/features/fixtures/shared/scenarios/CouldNotCreateDirectoryScenario.swift @@ -26,7 +26,7 @@ class CouldNotCreateDirectoryScenario: Scenario { try fileManager.setAttributes([.posixPermissions: 0o600], ofItemAtPath: dir.path) super.startBugsnag() } catch { - NSLog("\(error)") + logError("\(error)") } } diff --git a/features/fixtures/shared/scenarios/CustomPluginNotifierDescriptionScenario.m b/features/fixtures/shared/scenarios/CustomPluginNotifierDescriptionScenario.m index ef171cabc..0310e8832 100644 --- a/features/fixtures/shared/scenarios/CustomPluginNotifierDescriptionScenario.m +++ b/features/fixtures/shared/scenarios/CustomPluginNotifierDescriptionScenario.m @@ -1,4 +1,5 @@ #import "Scenario.h" +#import "Logging.h" @interface CustomPluginNotifierDescriptionScenario : Scenario @end diff --git a/features/fixtures/shared/scenarios/CxxBareThrowScenario.mm b/features/fixtures/shared/scenarios/CxxBareThrowScenario.mm index 37a3f4e8f..cfd546e90 100644 --- a/features/fixtures/shared/scenarios/CxxBareThrowScenario.mm +++ b/features/fixtures/shared/scenarios/CxxBareThrowScenario.mm @@ -7,6 +7,7 @@ // #import "Scenario.h" +#import "Logging.h" #import @interface CxxBareThrowScenario : Scenario diff --git a/features/fixtures/shared/scenarios/CxxExceptionOverrideScenario.mm b/features/fixtures/shared/scenarios/CxxExceptionOverrideScenario.mm index 888d07d16..cc487d97f 100644 --- a/features/fixtures/shared/scenarios/CxxExceptionOverrideScenario.mm +++ b/features/fixtures/shared/scenarios/CxxExceptionOverrideScenario.mm @@ -25,6 +25,7 @@ */ #import "MarkUnhandledHandledScenario.h" +#import "Logging.h" #import diff --git a/features/fixtures/shared/scenarios/CxxExceptionScenario.mm b/features/fixtures/shared/scenarios/CxxExceptionScenario.mm index 168d426d7..e9b6a362d 100644 --- a/features/fixtures/shared/scenarios/CxxExceptionScenario.mm +++ b/features/fixtures/shared/scenarios/CxxExceptionScenario.mm @@ -25,6 +25,7 @@ */ #import "Scenario.h" +#import "Logging.h" #import diff --git a/features/fixtures/shared/scenarios/CxxUnexpectedScenario.mm b/features/fixtures/shared/scenarios/CxxUnexpectedScenario.mm index 7f6fd4fe9..334c25449 100644 --- a/features/fixtures/shared/scenarios/CxxUnexpectedScenario.mm +++ b/features/fixtures/shared/scenarios/CxxUnexpectedScenario.mm @@ -7,6 +7,7 @@ // #import "Scenario.h" +#import "Logging.h" #import @interface CxxUnexpectedScenario : Scenario diff --git a/features/fixtures/shared/scenarios/DisableAllExceptManualExceptionsAndCrashScenario.m b/features/fixtures/shared/scenarios/DisableAllExceptManualExceptionsAndCrashScenario.m index 00df4ff33..254075afd 100644 --- a/features/fixtures/shared/scenarios/DisableAllExceptManualExceptionsAndCrashScenario.m +++ b/features/fixtures/shared/scenarios/DisableAllExceptManualExceptionsAndCrashScenario.m @@ -9,6 +9,7 @@ // C++ crashes are handled in a separate scenario, and OOM is not tested for. #import "Scenario.h" +#import "Logging.h" /** * Disable all crash reporting (except, implicitly, manual) and crash the app diff --git a/features/fixtures/shared/scenarios/DisableMachExceptionScenario.m b/features/fixtures/shared/scenarios/DisableMachExceptionScenario.m index 77fa2ed9b..a4401ec8c 100644 --- a/features/fixtures/shared/scenarios/DisableMachExceptionScenario.m +++ b/features/fixtures/shared/scenarios/DisableMachExceptionScenario.m @@ -9,6 +9,7 @@ // C++ crashes are handled in a separate scenario, and OOM is not tested for. #import "Scenario.h" +#import "Logging.h" @interface DisableMachExceptionScenario : Scenario @end diff --git a/features/fixtures/shared/scenarios/DisableNSExceptionScenario.m b/features/fixtures/shared/scenarios/DisableNSExceptionScenario.m index 823173a54..e5cdf9be7 100644 --- a/features/fixtures/shared/scenarios/DisableNSExceptionScenario.m +++ b/features/fixtures/shared/scenarios/DisableNSExceptionScenario.m @@ -9,6 +9,7 @@ // C++ crashes are handled in a separate scenario, and OOM is not tested for. #import "Scenario.h" +#import "Logging.h" @interface DisableNSExceptionScenario : Scenario @end diff --git a/features/fixtures/shared/scenarios/DisableSignalsExceptionScenario.m b/features/fixtures/shared/scenarios/DisableSignalsExceptionScenario.m index ed4c2cb10..22d3ff90b 100644 --- a/features/fixtures/shared/scenarios/DisableSignalsExceptionScenario.m +++ b/features/fixtures/shared/scenarios/DisableSignalsExceptionScenario.m @@ -9,6 +9,7 @@ // C++ crashes are handled in a separate scenario, and OOM is not tested for. #import "Scenario.h" +#import "Logging.h" @interface DisableSignalsExceptionScenario : Scenario @end diff --git a/features/fixtures/shared/scenarios/DisabledSessionTrackingScenario.m b/features/fixtures/shared/scenarios/DisabledSessionTrackingScenario.m index e3c378446..cc87e35db 100644 --- a/features/fixtures/shared/scenarios/DisabledSessionTrackingScenario.m +++ b/features/fixtures/shared/scenarios/DisabledSessionTrackingScenario.m @@ -4,6 +4,7 @@ // #import "Scenario.h" +#import "Logging.h" @interface DisabledSessionTrackingScenario : Scenario @end diff --git a/features/fixtures/shared/scenarios/EnabledErrorTypesCxxScenario.mm b/features/fixtures/shared/scenarios/EnabledErrorTypesCxxScenario.mm index c424d9f1a..f09a10a01 100644 --- a/features/fixtures/shared/scenarios/EnabledErrorTypesCxxScenario.mm +++ b/features/fixtures/shared/scenarios/EnabledErrorTypesCxxScenario.mm @@ -1,4 +1,5 @@ #import "Scenario.h" +#import "Logging.h" #import diff --git a/features/fixtures/shared/scenarios/HandledErrorThreadSendAlwaysScenario.m b/features/fixtures/shared/scenarios/HandledErrorThreadSendAlwaysScenario.m index c6b936dfc..30b657b4b 100644 --- a/features/fixtures/shared/scenarios/HandledErrorThreadSendAlwaysScenario.m +++ b/features/fixtures/shared/scenarios/HandledErrorThreadSendAlwaysScenario.m @@ -7,6 +7,7 @@ // #import "Scenario.h" +#import "Logging.h" @interface HandledErrorThreadSendAlwaysScenario : Scenario @end diff --git a/features/fixtures/shared/scenarios/HandledErrorThreadSendUnhandledOnlyScenario.m b/features/fixtures/shared/scenarios/HandledErrorThreadSendUnhandledOnlyScenario.m index 94a0d7d39..63432ec7a 100644 --- a/features/fixtures/shared/scenarios/HandledErrorThreadSendUnhandledOnlyScenario.m +++ b/features/fixtures/shared/scenarios/HandledErrorThreadSendUnhandledOnlyScenario.m @@ -7,6 +7,7 @@ // #import "Scenario.h" +#import "Logging.h" @interface HandledErrorThreadSendUnhandledOnlyScenario : Scenario @end diff --git a/features/fixtures/shared/scenarios/InvalidCrashReportScenario.m b/features/fixtures/shared/scenarios/InvalidCrashReportScenario.m index f8719868a..19c3118c8 100644 --- a/features/fixtures/shared/scenarios/InvalidCrashReportScenario.m +++ b/features/fixtures/shared/scenarios/InvalidCrashReportScenario.m @@ -7,6 +7,7 @@ // #import "Scenario.h" +#import "Logging.h" @interface InvalidCrashReportScenario : Scenario @end diff --git a/features/fixtures/shared/scenarios/LastRunInfoScenario.swift b/features/fixtures/shared/scenarios/LastRunInfoScenario.swift index 735bbed14..16be0159c 100644 --- a/features/fixtures/shared/scenarios/LastRunInfoScenario.swift +++ b/features/fixtures/shared/scenarios/LastRunInfoScenario.swift @@ -46,7 +46,7 @@ class LastRunInfoScenario: Scenario { while try! !FileManager.default.contentsOfDirectory(at: dir, includingPropertiesForKeys: nil, options: []) .filter({ $0.lastPathComponent.hasPrefix("CrashReport-") }).isEmpty { - NSLog("LastRunInfoScenario: waiting for delivery of crash reports...") + logInfo("LastRunInfoScenario: waiting for delivery of crash reports...") Thread.sleep(forTimeInterval: 0.1) } } diff --git a/features/fixtures/shared/scenarios/Logging.h b/features/fixtures/shared/scenarios/Logging.h new file mode 100644 index 000000000..bbbbbfa93 --- /dev/null +++ b/features/fixtures/shared/scenarios/Logging.h @@ -0,0 +1,21 @@ +// +// Logging.h +// iOSTestApp +// +// Created by Karl Stenerud on 02.11.23. +// Copyright © 2023 Bugsnag. All rights reserved. +// + +#import + +void logInfoObjC(NSString *format, ...); +void logWarnObjC(NSString *format, ...); +void logErrorObjC(NSString *format, ...); + +//#define logInfo(FMT, ...) logInfoObjC(FMT, __VA_ARGS__) +//#define logWarn(FMT, ...) logWarnObjC(FMT, __VA_ARGS__) +//#define logError(FMT, ...) logErrorObjC(FMT, __VA_ARGS__) + +#define logInfo logInfoObjC +#define logWarn logWarnObjC +#define logError logErrorObjC diff --git a/features/fixtures/shared/scenarios/Logging.m b/features/fixtures/shared/scenarios/Logging.m new file mode 100644 index 000000000..919dff9d4 --- /dev/null +++ b/features/fixtures/shared/scenarios/Logging.m @@ -0,0 +1,44 @@ +// +// Logging.m +// iOSTestApp +// +// Created by Karl Stenerud on 02.11.23. +// Copyright © 2023 Bugsnag. All rights reserved. +// + +#import "Logging.h" + +extern void bsg_i_kslog_logCBasic(const char *fmt, ...) __printflike(1, 2); + +void logInternal(const char* level, NSString *format, va_list args) { + NSString *formatted = [[NSString alloc] initWithFormat:format arguments:args]; + NSString *fullMessage = [NSString stringWithFormat:@"bugsnagci %s: %@", level, formatted]; + + NSLog(@"%@", fullMessage); + bsg_i_kslog_logCBasic("%s", + [[NSString stringWithFormat:@"%@ %@", + [NSDate date], fullMessage] + cStringUsingEncoding:NSUTF8StringEncoding]); + +} + +void logInfoObjC(NSString *format, ...) { + va_list args; + va_start(args, format); + logInternal("info", format, args); + va_end(args); +} + +void logWarnObjC(NSString *format, ...) { + va_list args; + va_start(args, format); + logInternal("warn", format, args); + va_end(args); +} + +void logErrorObjC(NSString *format, ...) { + va_list args; + va_start(args, format); + logInternal("error", format, args); + va_end(args); +} diff --git a/features/fixtures/shared/scenarios/ManualSessionScenario.m b/features/fixtures/shared/scenarios/ManualSessionScenario.m index 2bd7283ad..26c912d2e 100644 --- a/features/fixtures/shared/scenarios/ManualSessionScenario.m +++ b/features/fixtures/shared/scenarios/ManualSessionScenario.m @@ -4,6 +4,7 @@ // #import "Scenario.h" +#import "Logging.h" /** * Sends a manual session payload to Bugsnag. diff --git a/features/fixtures/shared/scenarios/ManualSessionWithUserScenario.m b/features/fixtures/shared/scenarios/ManualSessionWithUserScenario.m index dd4ca4b8b..842a028b9 100644 --- a/features/fixtures/shared/scenarios/ManualSessionWithUserScenario.m +++ b/features/fixtures/shared/scenarios/ManualSessionWithUserScenario.m @@ -7,6 +7,7 @@ // #import "Scenario.h" +#import "Logging.h" @interface ManualSessionWithUserScenario : Scenario @end diff --git a/features/fixtures/shared/scenarios/ManyConcurrentNotifyScenario.m b/features/fixtures/shared/scenarios/ManyConcurrentNotifyScenario.m index 97330e1e8..a4904b226 100644 --- a/features/fixtures/shared/scenarios/ManyConcurrentNotifyScenario.m +++ b/features/fixtures/shared/scenarios/ManyConcurrentNotifyScenario.m @@ -1,4 +1,5 @@ #import "Scenario.h" +#import "Logging.h" @interface ManyConcurrentNotifyScenario : Scenario @property (nonatomic) dispatch_queue_t queue1; diff --git a/features/fixtures/shared/scenarios/MarkUnhandledHandledScenario.m b/features/fixtures/shared/scenarios/MarkUnhandledHandledScenario.m index d394089ab..83e4cb409 100644 --- a/features/fixtures/shared/scenarios/MarkUnhandledHandledScenario.m +++ b/features/fixtures/shared/scenarios/MarkUnhandledHandledScenario.m @@ -7,6 +7,7 @@ // #import "MarkUnhandledHandledScenario.h" +#import "Logging.h" @implementation MarkUnhandledHandledScenario diff --git a/features/fixtures/shared/scenarios/MaxPersistedSessionsScenario.m b/features/fixtures/shared/scenarios/MaxPersistedSessionsScenario.m index 3b308879a..f39155546 100644 --- a/features/fixtures/shared/scenarios/MaxPersistedSessionsScenario.m +++ b/features/fixtures/shared/scenarios/MaxPersistedSessionsScenario.m @@ -7,6 +7,7 @@ // #import "Scenario.h" +#import "Logging.h" @interface MaxPersistedSessionsScenario : Scenario @end diff --git a/features/fixtures/shared/scenarios/NSExceptionShiftScenario.m b/features/fixtures/shared/scenarios/NSExceptionShiftScenario.m index 7bb440161..e1b0d059b 100644 --- a/features/fixtures/shared/scenarios/NSExceptionShiftScenario.m +++ b/features/fixtures/shared/scenarios/NSExceptionShiftScenario.m @@ -1,4 +1,5 @@ #import "Scenario.h" +#import "Logging.h" @interface NSExceptionShiftScenario : Scenario @end diff --git a/features/fixtures/shared/scenarios/NonExistentMethodScenario.m b/features/fixtures/shared/scenarios/NonExistentMethodScenario.m index 3716d5bde..8990d003c 100644 --- a/features/fixtures/shared/scenarios/NonExistentMethodScenario.m +++ b/features/fixtures/shared/scenarios/NonExistentMethodScenario.m @@ -4,6 +4,7 @@ // #import "Scenario.h" +#import "Logging.h" /** * Calls a non-existent method on an object diff --git a/features/fixtures/shared/scenarios/NullPointerScenario.m b/features/fixtures/shared/scenarios/NullPointerScenario.m index 852e169f4..81318f063 100644 --- a/features/fixtures/shared/scenarios/NullPointerScenario.m +++ b/features/fixtures/shared/scenarios/NullPointerScenario.m @@ -24,6 +24,7 @@ * OTHER DEALINGS IN THE SOFTWARE. */ #import "Scenario.h" +#import "Logging.h" #import "spin_malloc.h" diff --git a/features/fixtures/shared/scenarios/OOMInactiveScenario.swift b/features/fixtures/shared/scenarios/OOMInactiveScenario.swift index 648286580..513d0a46c 100644 --- a/features/fixtures/shared/scenarios/OOMInactiveScenario.swift +++ b/features/fixtures/shared/scenarios/OOMInactiveScenario.swift @@ -22,7 +22,7 @@ class OOMInactiveScenario: Scenario { NotificationCenter.default.post(name: UIApplication.willResignActiveNotification, object: UIApplication.shared, userInfo: nil) - NSLog("Killing app to fake an OOM") + logInfo("Killing app to fake an OOM") kill(getpid(), SIGKILL) } } diff --git a/features/fixtures/shared/scenarios/OOMScenario.m b/features/fixtures/shared/scenarios/OOMScenario.m index b32b8d592..ebfb4c700 100644 --- a/features/fixtures/shared/scenarios/OOMScenario.m +++ b/features/fixtures/shared/scenarios/OOMScenario.m @@ -7,6 +7,7 @@ // #import "Scenario.h" +#import "Logging.h" #import @@ -57,7 +58,7 @@ - (void)run { [Bugsnag setContext:@"OOM Scenario"]; [NSNotificationCenter.defaultCenter addObserverForName:UIApplicationDidReceiveMemoryWarningNotification object:nil queue:nil usingBlock:^(NSNotification *note) { - NSLog(@"*** Received memory warning"); + logInfo(@"*** Received memory warning"); }]; // Delay to allow session payload to be sent [self performSelector:@selector(consumeAllMemory) withObject:nil afterDelay:2]; @@ -66,11 +67,11 @@ - (void)run { - (void)consumeAllMemory { struct utsname system = {0}; uname(&system); - NSLog(@"*** Device = %s", system.machine); + logInfo(@"*** Device = %s", system.machine); NSUInteger physicalMemory = (NSUInteger)NSProcessInfo.processInfo.physicalMemory; NSUInteger megabytes = physicalMemory / MEGABYTE; - NSLog(@"*** Physical memory = %lu MB", (unsigned long)megabytes); + logInfo(@"*** Physical memory = %lu MB", (unsigned long)megabytes); // // The ActiveHard limit and point at which a memory warning is sent varies by device @@ -104,21 +105,21 @@ - (void)consumeAllMemory { kern_return_t result = task_info(mach_task_self(), TASK_VM_INFO, (task_info_t)&vm_info, &count); if (result == KERN_SUCCESS && count >= TASK_VM_INFO_REV4_COUNT) { limit = (NSUInteger)(vm_info.phys_footprint + vm_info.limit_bytes_remaining) / MEGABYTE; - NSLog(@"*** Memory limit = %lu MB", (unsigned long)limit); + logInfo(@"*** Memory limit = %lu MB", (unsigned long)limit); } else if (!strcmp(system.machine, "iPhone6,2")) { limit = 650; - NSLog(@"*** Memory limit = %lu MB", (unsigned long)limit); + logInfo(@"*** Memory limit = %lu MB", (unsigned long)limit); } else { limit = MIN(2098, megabytes * 70 / 100); - NSLog(@"*** Memory limit = %lu MB (estimated)", (unsigned long)limit); + logInfo(@"*** Memory limit = %lu MB (estimated)", (unsigned long)limit); } // The size of the initial block needs to be under the memory warning limit in order for one to be reliably sent. NSUInteger initial = limit * 70 / 100; - NSLog(@"*** Dirtying an initial block of %lu MB", (unsigned long)initial); + logInfo(@"*** Dirtying an initial block of %lu MB", (unsigned long)initial); [self consumeMegabytes:initial]; - NSLog(@"*** Dirtying remaining memory in ~2 seconds"); + logInfo(@"*** Dirtying remaining memory in ~2 seconds"); NSTimeInterval timeInterval = 2.0 / (limit - initial); [NSTimer scheduledTimerWithTimeInterval:timeInterval target:self selector:@selector(timerFired) userInfo:nil repeats:YES]; } diff --git a/features/fixtures/shared/scenarios/OOMSessionlessScenario.m b/features/fixtures/shared/scenarios/OOMSessionlessScenario.m index 4b9c4c305..eff7e4904 100644 --- a/features/fixtures/shared/scenarios/OOMSessionlessScenario.m +++ b/features/fixtures/shared/scenarios/OOMSessionlessScenario.m @@ -7,6 +7,7 @@ // #import "Scenario.h" +#import "Logging.h" @interface OOMSessionlessScenario : Scenario diff --git a/features/fixtures/shared/scenarios/OOMWillTerminateScenario.m b/features/fixtures/shared/scenarios/OOMWillTerminateScenario.m index 072a3cb5a..4c8e0eedf 100644 --- a/features/fixtures/shared/scenarios/OOMWillTerminateScenario.m +++ b/features/fixtures/shared/scenarios/OOMWillTerminateScenario.m @@ -1,5 +1,6 @@ #import "Scenario.h" +#import "Logging.h" #import diff --git a/features/fixtures/shared/scenarios/ObjCExceptionOverrideScenario.m b/features/fixtures/shared/scenarios/ObjCExceptionOverrideScenario.m index 4b25d51de..5ab2177c4 100644 --- a/features/fixtures/shared/scenarios/ObjCExceptionOverrideScenario.m +++ b/features/fixtures/shared/scenarios/ObjCExceptionOverrideScenario.m @@ -25,6 +25,7 @@ */ #import "MarkUnhandledHandledScenario.h" +#import "Logging.h" /** * Throw an uncaught Objective-C exception. It's possible to generate a better crash report here diff --git a/features/fixtures/shared/scenarios/ObjCExceptionScenario.m b/features/fixtures/shared/scenarios/ObjCExceptionScenario.m index 4e889d96b..b7e491c63 100644 --- a/features/fixtures/shared/scenarios/ObjCExceptionScenario.m +++ b/features/fixtures/shared/scenarios/ObjCExceptionScenario.m @@ -25,6 +25,7 @@ */ #import "MarkUnhandledHandledScenario.h" +#import "Logging.h" /** * Throw an uncaught Objective-C exception. It's possible to generate a better crash report here diff --git a/features/fixtures/shared/scenarios/ObjCMsgSendScenario.m b/features/fixtures/shared/scenarios/ObjCMsgSendScenario.m index d272b1c33..eb8c9cb06 100644 --- a/features/fixtures/shared/scenarios/ObjCMsgSendScenario.m +++ b/features/fixtures/shared/scenarios/ObjCMsgSendScenario.m @@ -25,6 +25,7 @@ */ #import "Scenario.h" +#import "Logging.h" #import diff --git a/features/fixtures/shared/scenarios/OldCrashReportScenario.swift b/features/fixtures/shared/scenarios/OldCrashReportScenario.swift index 7ad986648..86126bd50 100644 --- a/features/fixtures/shared/scenarios/OldCrashReportScenario.swift +++ b/features/fixtures/shared/scenarios/OldCrashReportScenario.swift @@ -24,10 +24,10 @@ class OldCrashReportScenario: Scenario { for name in try FileManager.default.contentsOfDirectory(atPath: dir) { let file = (dir as NSString).appendingPathComponent(name) try FileManager.default.setAttributes([.creationDate: creationDate], ofItemAtPath: file) - NSLog("OldCrashReportScenario: Updated creation date of \((file as NSString).lastPathComponent) to \(creationDate)") + logInfo("OldCrashReportScenario: Updated creation date of \((file as NSString).lastPathComponent) to \(creationDate)") } } catch { - NSLog("\(error)") + logError("\(error)") } } } diff --git a/features/fixtures/shared/scenarios/OldHandledErrorScenario.swift b/features/fixtures/shared/scenarios/OldHandledErrorScenario.swift index e3dfc2fc7..c00795176 100644 --- a/features/fixtures/shared/scenarios/OldHandledErrorScenario.swift +++ b/features/fixtures/shared/scenarios/OldHandledErrorScenario.swift @@ -24,10 +24,10 @@ class OldHandledErrorScenario: Scenario { for name in try FileManager.default.contentsOfDirectory(atPath: dir) { let file = (dir as NSString).appendingPathComponent(name) try FileManager.default.setAttributes([.creationDate: creationDate], ofItemAtPath: file) - NSLog("OldCrashReportScenario: Updated creation date of \((file as NSString).lastPathComponent) to \(creationDate)") + logInfo("OldCrashReportScenario: Updated creation date of \((file as NSString).lastPathComponent) to \(creationDate)") } } catch { - NSLog("\(error)") + logError("\(error)") } } } diff --git a/features/fixtures/shared/scenarios/OldSessionScenario.m b/features/fixtures/shared/scenarios/OldSessionScenario.m index 07f1149ed..b98ef7cbb 100644 --- a/features/fixtures/shared/scenarios/OldSessionScenario.m +++ b/features/fixtures/shared/scenarios/OldSessionScenario.m @@ -7,6 +7,7 @@ // #import "Scenario.h" +#import "Logging.h" @interface OldSessionScenario : Scenario @end @@ -40,10 +41,10 @@ - (void)modifySessionCreationDate { NSString *file = [dir stringByAppendingPathComponent:name]; NSError *error; if ([NSFileManager.defaultManager setAttributes:@{NSFileCreationDate: creationDate} ofItemAtPath:file error:&error]) { - NSLog(@"OldSessionScenario: Updated creation date of %@ to %@", file.lastPathComponent, + logInfo(@"OldSessionScenario: Updated creation date of %@ to %@", file.lastPathComponent, [NSFileManager.defaultManager attributesOfItemAtPath:file error:nil].fileCreationDate); } else { - NSLog(@"OldSessionScenario: %@", error); + logError(@"OldSessionScenario: %@", error); abort(); } } diff --git a/features/fixtures/shared/scenarios/OnCrashHandlerScenario.m b/features/fixtures/shared/scenarios/OnCrashHandlerScenario.m index abd9a739b..edd7b4c32 100644 --- a/features/fixtures/shared/scenarios/OnCrashHandlerScenario.m +++ b/features/fixtures/shared/scenarios/OnCrashHandlerScenario.m @@ -7,6 +7,7 @@ // #import "Scenario.h" +#import "Logging.h" // Create crash handler void HandleCrashedThread(const BSG_KSCrashReportWriter *writer) { diff --git a/features/fixtures/shared/scenarios/OnSendCallbackRemovalScenario.m b/features/fixtures/shared/scenarios/OnSendCallbackRemovalScenario.m index 92aa94a52..aa1f3f7ed 100644 --- a/features/fixtures/shared/scenarios/OnSendCallbackRemovalScenario.m +++ b/features/fixtures/shared/scenarios/OnSendCallbackRemovalScenario.m @@ -7,6 +7,7 @@ // #import "Scenario.h" +#import "Logging.h" /** * Verifies that removing an OnSend callback does not affect other OnSend callbacks diff --git a/features/fixtures/shared/scenarios/OnSendErrorPersistenceScenario.m b/features/fixtures/shared/scenarios/OnSendErrorPersistenceScenario.m index 340549f21..a59c953a5 100644 --- a/features/fixtures/shared/scenarios/OnSendErrorPersistenceScenario.m +++ b/features/fixtures/shared/scenarios/OnSendErrorPersistenceScenario.m @@ -7,6 +7,7 @@ // #import "Scenario.h" +#import "Logging.h" NSString * const HasNotifiedKey = @"OnSendErrorPersistenceScenario.hasNotified"; diff --git a/features/fixtures/shared/scenarios/OverwriteLinkRegisterScenario.m b/features/fixtures/shared/scenarios/OverwriteLinkRegisterScenario.m index 53cdeb56d..6aa1f2284 100644 --- a/features/fixtures/shared/scenarios/OverwriteLinkRegisterScenario.m +++ b/features/fixtures/shared/scenarios/OverwriteLinkRegisterScenario.m @@ -25,6 +25,7 @@ */ #import "Scenario.h" +#import "Logging.h" #import "spin_malloc.h" diff --git a/features/fixtures/shared/scenarios/PrivilegedInstructionScenario.m b/features/fixtures/shared/scenarios/PrivilegedInstructionScenario.m index 445c2029a..2860f5311 100644 --- a/features/fixtures/shared/scenarios/PrivilegedInstructionScenario.m +++ b/features/fixtures/shared/scenarios/PrivilegedInstructionScenario.m @@ -25,6 +25,7 @@ */ #import "Scenario.h" +#import "Logging.h" #import "spin_malloc.h" diff --git a/features/fixtures/shared/scenarios/ReadGarbagePointerScenario.m b/features/fixtures/shared/scenarios/ReadGarbagePointerScenario.m index 071e75d94..1c50c0509 100644 --- a/features/fixtures/shared/scenarios/ReadGarbagePointerScenario.m +++ b/features/fixtures/shared/scenarios/ReadGarbagePointerScenario.m @@ -25,6 +25,7 @@ */ #import "Scenario.h" +#import "Logging.h" #import "spin_malloc.h" diff --git a/features/fixtures/shared/scenarios/ReadOnlyPageScenario.m b/features/fixtures/shared/scenarios/ReadOnlyPageScenario.m index 840a65cca..0ebfeb63b 100644 --- a/features/fixtures/shared/scenarios/ReadOnlyPageScenario.m +++ b/features/fixtures/shared/scenarios/ReadOnlyPageScenario.m @@ -25,6 +25,7 @@ */ #import "Scenario.h" +#import "Logging.h" #import "spin_malloc.h" diff --git a/features/fixtures/shared/scenarios/RecrashScenarios.mm b/features/fixtures/shared/scenarios/RecrashScenarios.mm index 7cb12d0d2..784bf81a1 100644 --- a/features/fixtures/shared/scenarios/RecrashScenarios.mm +++ b/features/fixtures/shared/scenarios/RecrashScenarios.mm @@ -7,6 +7,7 @@ // #import "Scenario.h" +#import "Logging.h" #import diff --git a/features/fixtures/shared/scenarios/ReleasedObjectScenario.m b/features/fixtures/shared/scenarios/ReleasedObjectScenario.m index 5f1518901..75a098378 100644 --- a/features/fixtures/shared/scenarios/ReleasedObjectScenario.m +++ b/features/fixtures/shared/scenarios/ReleasedObjectScenario.m @@ -25,6 +25,7 @@ */ #import "Scenario.h" +#import "Logging.h" #import diff --git a/features/fixtures/shared/scenarios/ReportBackgroundAppHangScenario.swift b/features/fixtures/shared/scenarios/ReportBackgroundAppHangScenario.swift index c2d3f13b5..cbf0a76f3 100644 --- a/features/fixtures/shared/scenarios/ReportBackgroundAppHangScenario.swift +++ b/features/fixtures/shared/scenarios/ReportBackgroundAppHangScenario.swift @@ -19,9 +19,9 @@ class ReportBackgroundAppHangScenario: Scenario { let backgroundTask = UIApplication.shared.beginBackgroundTask() let timeInterval: TimeInterval = 2 - NSLog("Simulating an app hang of \(timeInterval) seconds...") + logInfo("Simulating an app hang of \(timeInterval) seconds...") Thread.sleep(forTimeInterval: timeInterval) - NSLog("Finished sleeping") + logInfo("Finished sleeping") DispatchQueue.main.asyncAfter(deadline: .now() + 3) { UIApplication.shared.endBackgroundTask(backgroundTask) diff --git a/features/fixtures/shared/scenarios/ResumeSessionOOMScenario.m b/features/fixtures/shared/scenarios/ResumeSessionOOMScenario.m index 0b7cdc886..9c7aeacc5 100644 --- a/features/fixtures/shared/scenarios/ResumeSessionOOMScenario.m +++ b/features/fixtures/shared/scenarios/ResumeSessionOOMScenario.m @@ -1,4 +1,5 @@ #import "Scenario.h" +#import "Logging.h" @interface ResumeSessionOOMScenario : Scenario @end diff --git a/features/fixtures/shared/scenarios/SIGBUSScenario.m b/features/fixtures/shared/scenarios/SIGBUSScenario.m index f777264f6..6d974de38 100644 --- a/features/fixtures/shared/scenarios/SIGBUSScenario.m +++ b/features/fixtures/shared/scenarios/SIGBUSScenario.m @@ -7,6 +7,7 @@ // #import "Scenario.h" +#import "Logging.h" @interface SIGBUSScenario : Scenario @end diff --git a/features/fixtures/shared/scenarios/SIGFPEScenario.m b/features/fixtures/shared/scenarios/SIGFPEScenario.m index ac1ba04ae..193cbd9a5 100644 --- a/features/fixtures/shared/scenarios/SIGFPEScenario.m +++ b/features/fixtures/shared/scenarios/SIGFPEScenario.m @@ -7,6 +7,7 @@ // #import "Scenario.h" +#import "Logging.h" @interface SIGFPEScenario : Scenario @end diff --git a/features/fixtures/shared/scenarios/SIGILLScenario.m b/features/fixtures/shared/scenarios/SIGILLScenario.m index 3d3926726..0b43f8536 100644 --- a/features/fixtures/shared/scenarios/SIGILLScenario.m +++ b/features/fixtures/shared/scenarios/SIGILLScenario.m @@ -7,6 +7,7 @@ // #import "Scenario.h" +#import "Logging.h" @interface SIGILLScenario : Scenario @end diff --git a/features/fixtures/shared/scenarios/SIGPIPEIgnoredScenario.m b/features/fixtures/shared/scenarios/SIGPIPEIgnoredScenario.m index 13f973a53..9a5dd01d5 100644 --- a/features/fixtures/shared/scenarios/SIGPIPEIgnoredScenario.m +++ b/features/fixtures/shared/scenarios/SIGPIPEIgnoredScenario.m @@ -7,6 +7,7 @@ // #import "Scenario.h" +#import "Logging.h" @interface SIGPIPEIgnoredScenario : Scenario diff --git a/features/fixtures/shared/scenarios/SIGPIPEScenario.m b/features/fixtures/shared/scenarios/SIGPIPEScenario.m index 2a3c9ef34..be4696c12 100644 --- a/features/fixtures/shared/scenarios/SIGPIPEScenario.m +++ b/features/fixtures/shared/scenarios/SIGPIPEScenario.m @@ -7,6 +7,7 @@ // #import "Scenario.h" +#import "Logging.h" @interface SIGPIPEScenario : Scenario @end diff --git a/features/fixtures/shared/scenarios/SIGSEGVScenario.m b/features/fixtures/shared/scenarios/SIGSEGVScenario.m index 7ced08c05..667eb4569 100644 --- a/features/fixtures/shared/scenarios/SIGSEGVScenario.m +++ b/features/fixtures/shared/scenarios/SIGSEGVScenario.m @@ -7,6 +7,7 @@ // #import "Scenario.h" +#import "Logging.h" @interface SIGSEGVScenario : Scenario @end diff --git a/features/fixtures/shared/scenarios/SIGSYSScenario.m b/features/fixtures/shared/scenarios/SIGSYSScenario.m index 322e3bbe6..607c9919c 100644 --- a/features/fixtures/shared/scenarios/SIGSYSScenario.m +++ b/features/fixtures/shared/scenarios/SIGSYSScenario.m @@ -7,6 +7,7 @@ // #import "Scenario.h" +#import "Logging.h" @interface SIGSYSScenario : Scenario @end diff --git a/features/fixtures/shared/scenarios/SIGTRAPScenario.m b/features/fixtures/shared/scenarios/SIGTRAPScenario.m index 3bee4645f..c8ca433a2 100644 --- a/features/fixtures/shared/scenarios/SIGTRAPScenario.m +++ b/features/fixtures/shared/scenarios/SIGTRAPScenario.m @@ -7,6 +7,7 @@ // #import "Scenario.h" +#import "Logging.h" @interface SIGTRAPScenario : Scenario @end diff --git a/features/fixtures/shared/scenarios/Scenario.h b/features/fixtures/shared/scenarios/Scenario.h index a419f8247..9f05796f9 100644 --- a/features/fixtures/shared/scenarios/Scenario.h +++ b/features/fixtures/shared/scenarios/Scenario.h @@ -9,7 +9,7 @@ NS_ASSUME_NONNULL_BEGIN -void kslog(const char *message); +void logInternal(const char* level, NSString *format, va_list args); void markErrorHandledCallback(const BSG_KSCrashReportWriter *writer); diff --git a/features/fixtures/shared/scenarios/Scenario.m b/features/fixtures/shared/scenarios/Scenario.m index 02a92ff17..a710361aa 100644 --- a/features/fixtures/shared/scenarios/Scenario.m +++ b/features/fixtures/shared/scenarios/Scenario.m @@ -3,6 +3,7 @@ // Copyright (c) 2018 Bugsnag. All rights reserved. // #import "Scenario.h" +#import "Logging.h" #import @@ -19,12 +20,6 @@ extern bool bsg_kslog_setLogFilename(const char *filename, bool overwrite); -extern void bsg_i_kslog_logCBasic(const char *fmt, ...) __printflike(1, 2); - -void kslog(const char *message) { - bsg_i_kslog_logCBasic("%s", message); -} - void markErrorHandledCallback(const BSG_KSCrashReportWriter *writer) { writer->addBooleanElement(writer, "unhandled", false); } @@ -65,7 +60,7 @@ + (void)load { return; } #endif - NSLog(@"%@", notification.name); + logInfo(@"Received notification %@", notification.name); }]; } @@ -184,7 +179,7 @@ + (void)initialize { } + (void)clearPersistentData { - NSLog(@"%s", __PRETTY_FUNCTION__); + logInfo(@"%s", __PRETTY_FUNCTION__); [NSUserDefaults.standardUserDefaults removePersistentDomainForName:NSBundle.mainBundle.bundleIdentifier]; NSString *cachesDir = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject; NSArray *entries = @[ @@ -200,7 +195,7 @@ + (void)clearPersistentData { NSError *error = nil; if (![NSFileManager.defaultManager removeItemAtPath:path error:&error]) { if (![error.domain isEqualToString:NSCocoaErrorDomain] && error.code != NSFileNoSuchFileError) { - NSLog(@"%@", error); + logError(@"Error removing path %@: %@", path, error); } } } @@ -209,7 +204,7 @@ + (void)clearPersistentData { NSError *error = nil; if (![NSFileManager.defaultManager removeItemAtPath:rootDir error:&error]) { if (![error.domain isEqualToString:NSCocoaErrorDomain] && error.code != NSFileNoSuchFileError) { - NSLog(@"%@", error); + logError(@"Error removing path %@: %@", rootDir, error); } } #if !TARGET_OS_WATCH @@ -218,28 +213,29 @@ + (void)clearPersistentData { } + (void)executeMazeRunnerCommand:(void (^)(NSString *scenarioName, NSString *scenarioMode))preHandler { - NSLog(@"%s", __PRETTY_FUNCTION__); + logInfo(@"%s", __PRETTY_FUNCTION__); NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration ephemeralSessionConfiguration]]; NSString *commandEndpoint = [NSString stringWithFormat:@"%@/command", theBaseMazeAddress]; NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:commandEndpoint]]; + logInfo(@"%s: Sending command request to %@", __PRETTY_FUNCTION__, commandEndpoint); [[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { if (![response isKindOfClass:[NSHTTPURLResponse class]] || [(NSHTTPURLResponse *)response statusCode] != 200) { - NSLog(@"%s request failed with %@", __PRETTY_FUNCTION__, response ?: error); + logError(@"%s: command request failed with %@", __PRETTY_FUNCTION__, response ?: error); preHandler(@"", NULL); return; } - NSLog(@"%s response body: %@", __PRETTY_FUNCTION__, [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]); + logInfo(@"%s: command response body: %@", __PRETTY_FUNCTION__, [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]); NSDictionary *command = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; NSString *action = [command objectForKey:@"action"]; + NSParameterAssert([action isKindOfClass:[NSString class]]); + if ([action isEqualToString:@"noop"]) { - NSLog(@"No Maze Runner command queued at present"); + logInfo(@"%s: No Maze Runner command queued at present", __PRETTY_FUNCTION__); preHandler(@"", NULL); return; } - - NSParameterAssert([action isKindOfClass:[NSString class]]); - + NSString *scenarioName = [command objectForKey:@"scenario_name"]; NSParameterAssert([scenarioName isKindOfClass:[NSString class]]); @@ -270,7 +266,7 @@ + (void)executeMazeRunnerCommand:(void (^)(NSString *scenarioName, NSString *sce } + (void)runScenario:(NSString *)scenarioName eventMode:(NSString *)eventMode { - NSLog(@"%s %@ %@", __PRETTY_FUNCTION__, scenarioName, eventMode); + logInfo(@"%s %@ %@", __PRETTY_FUNCTION__, scenarioName, eventMode); [self startBugsnagForScenario:scenarioName eventMode:eventMode]; @@ -278,12 +274,12 @@ + (void)runScenario:(NSString *)scenarioName eventMode:(NSString *)eventMode { } + (void)startBugsnagForScenario:(NSString *)scenarioName eventMode:(NSString *)eventMode { - NSLog(@"%s %@ %@", __PRETTY_FUNCTION__, scenarioName, eventMode); + logInfo(@"%s %@ %@", __PRETTY_FUNCTION__, scenarioName, eventMode); theScenario = [Scenario createScenarioNamed:scenarioName withConfig:nil]; theScenario.eventMode = eventMode; - NSLog(@"Starting scenario \"%@\"", NSStringFromClass([self class])); + logInfo(@"%s: Starting scenario \"%@\"", __PRETTY_FUNCTION__, NSStringFromClass([self class])); [theScenario startBugsnag]; } diff --git a/features/fixtures/shared/scenarios/SendLaunchCrashesSynchronouslyLaunchCompletedScenario.swift b/features/fixtures/shared/scenarios/SendLaunchCrashesSynchronouslyLaunchCompletedScenario.swift index 721899bba..17d030cf0 100644 --- a/features/fixtures/shared/scenarios/SendLaunchCrashesSynchronouslyLaunchCompletedScenario.swift +++ b/features/fixtures/shared/scenarios/SendLaunchCrashesSynchronouslyLaunchCompletedScenario.swift @@ -2,7 +2,7 @@ class SendLaunchCrashesSynchronouslyLaunchCompletedScenario: SendLaunchCrashesSy override func run() { if eventMode != "report" { - NSLog(">>> Calling markLaunchCompleted()") + logInfo(">>> Calling markLaunchCompleted()") Bugsnag.markLaunchCompleted() } super.run() diff --git a/features/fixtures/shared/scenarios/SendLaunchCrashesSynchronouslyScenario.swift b/features/fixtures/shared/scenarios/SendLaunchCrashesSynchronouslyScenario.swift index 0ffe6a7d7..08cb9c1c8 100644 --- a/features/fixtures/shared/scenarios/SendLaunchCrashesSynchronouslyScenario.swift +++ b/features/fixtures/shared/scenarios/SendLaunchCrashesSynchronouslyScenario.swift @@ -20,7 +20,7 @@ class SendLaunchCrashesSynchronouslyScenario: Scenario { override func run() { if eventMode == "report" { - NSLog(">>> Delaying to allow previous run's crash report to be sent") + logInfo(">>> Delaying to allow previous run's crash report to be sent") DispatchQueue.main.asyncAfter(deadline: .now() + 5) { [startDuration] in NSLog(">>> Calling notify() with startDuration = \(startDuration)") Bugsnag.notifyError(NSError(domain: "DummyError", code: 0)) { @@ -29,7 +29,7 @@ class SendLaunchCrashesSynchronouslyScenario: Scenario { } } } else { - NSLog(">>> Calling fatalError()") + logInfo(">>> Calling fatalError()") fatalError() } } diff --git a/features/fixtures/shared/scenarios/SessionCallbackRemovalScenario.m b/features/fixtures/shared/scenarios/SessionCallbackRemovalScenario.m index c8b7df6d0..49b49e780 100644 --- a/features/fixtures/shared/scenarios/SessionCallbackRemovalScenario.m +++ b/features/fixtures/shared/scenarios/SessionCallbackRemovalScenario.m @@ -7,6 +7,7 @@ // #import "Scenario.h" +#import "Logging.h" @interface SessionCallbackRemovalScenario : Scenario @end diff --git a/features/fixtures/shared/scenarios/SessionOOMScenario.m b/features/fixtures/shared/scenarios/SessionOOMScenario.m index 38294aaf4..70d071ebc 100644 --- a/features/fixtures/shared/scenarios/SessionOOMScenario.m +++ b/features/fixtures/shared/scenarios/SessionOOMScenario.m @@ -1,4 +1,5 @@ #import "Scenario.h" +#import "Logging.h" #import diff --git a/features/fixtures/shared/scenarios/StackOverflowScenario.m b/features/fixtures/shared/scenarios/StackOverflowScenario.m index 3b3560550..8d5b06de3 100644 --- a/features/fixtures/shared/scenarios/StackOverflowScenario.m +++ b/features/fixtures/shared/scenarios/StackOverflowScenario.m @@ -25,6 +25,7 @@ */ #import "Scenario.h" +#import "Logging.h" /** * Execute an infinitely recursive method, which overflows the stack and diff --git a/features/fixtures/shared/scenarios/StopSessionOOMScenario.m b/features/fixtures/shared/scenarios/StopSessionOOMScenario.m index 44a7d9a2f..a23df8904 100644 --- a/features/fixtures/shared/scenarios/StopSessionOOMScenario.m +++ b/features/fixtures/shared/scenarios/StopSessionOOMScenario.m @@ -1,4 +1,5 @@ #import "Scenario.h" +#import "Logging.h" @interface StopSessionOOMScenario : Scenario @end diff --git a/features/fixtures/shared/scenarios/UndefinedInstructionScenario.m b/features/fixtures/shared/scenarios/UndefinedInstructionScenario.m index 26325cf71..8a242e95a 100644 --- a/features/fixtures/shared/scenarios/UndefinedInstructionScenario.m +++ b/features/fixtures/shared/scenarios/UndefinedInstructionScenario.m @@ -25,6 +25,7 @@ */ #import "Scenario.h" +#import "Logging.h" #import "spin_malloc.h" diff --git a/features/fixtures/shared/scenarios/UnhandledErrorThreadSendAlwaysScenario.m b/features/fixtures/shared/scenarios/UnhandledErrorThreadSendAlwaysScenario.m index 3f8840ab0..b23f297bf 100644 --- a/features/fixtures/shared/scenarios/UnhandledErrorThreadSendAlwaysScenario.m +++ b/features/fixtures/shared/scenarios/UnhandledErrorThreadSendAlwaysScenario.m @@ -7,6 +7,7 @@ // #import "Scenario.h" +#import "Logging.h" @interface UnhandledErrorThreadSendAlwaysScenario : Scenario @end diff --git a/features/fixtures/shared/scenarios/UnhandledErrorThreadSendNeverScenario.m b/features/fixtures/shared/scenarios/UnhandledErrorThreadSendNeverScenario.m index 64d06dc81..36df09b01 100644 --- a/features/fixtures/shared/scenarios/UnhandledErrorThreadSendNeverScenario.m +++ b/features/fixtures/shared/scenarios/UnhandledErrorThreadSendNeverScenario.m @@ -7,6 +7,7 @@ // #import "Scenario.h" +#import "Logging.h" @interface UnhandledErrorThreadSendNeverScenario : Scenario @end diff --git a/features/fixtures/shared/scenarios/UnhandledMachExceptionOverrideScenario.m b/features/fixtures/shared/scenarios/UnhandledMachExceptionOverrideScenario.m index 4131adc1d..ac5feb761 100644 --- a/features/fixtures/shared/scenarios/UnhandledMachExceptionOverrideScenario.m +++ b/features/fixtures/shared/scenarios/UnhandledMachExceptionOverrideScenario.m @@ -7,6 +7,7 @@ // #import "MarkUnhandledHandledScenario.h" +#import "Logging.h" @interface UnhandledMachExceptionOverrideScenario : MarkUnhandledHandledScenario @end diff --git a/features/fixtures/shared/scenarios/UnhandledMachExceptionScenario.m b/features/fixtures/shared/scenarios/UnhandledMachExceptionScenario.m index b2d958886..b41682e0c 100644 --- a/features/fixtures/shared/scenarios/UnhandledMachExceptionScenario.m +++ b/features/fixtures/shared/scenarios/UnhandledMachExceptionScenario.m @@ -7,6 +7,7 @@ // #import "Scenario.h" +#import "Logging.h" @interface UnhandledMachExceptionScenario : Scenario @end diff --git a/features/fixtures/shared/scenarios/UserPersistenceDontPersistUserScenario.m b/features/fixtures/shared/scenarios/UserPersistenceDontPersistUserScenario.m index 3cdf7b98c..82b4c0305 100644 --- a/features/fixtures/shared/scenarios/UserPersistenceDontPersistUserScenario.m +++ b/features/fixtures/shared/scenarios/UserPersistenceDontPersistUserScenario.m @@ -7,6 +7,7 @@ // #import "Scenario.h" +#import "Logging.h" /** * Set a user but don't persist it diff --git a/features/fixtures/shared/scenarios/UserPersistenceNoUserScenario.m b/features/fixtures/shared/scenarios/UserPersistenceNoUserScenario.m index e352c13ba..7affb9ab6 100644 --- a/features/fixtures/shared/scenarios/UserPersistenceNoUserScenario.m +++ b/features/fixtures/shared/scenarios/UserPersistenceNoUserScenario.m @@ -7,6 +7,7 @@ // #import "Scenario.h" +#import "Logging.h" /** * Don't set a user, don't change persistence (defaults to True). diff --git a/features/fixtures/shared/scenarios/UserPersistencePersistUserClientScenario.m b/features/fixtures/shared/scenarios/UserPersistencePersistUserClientScenario.m index bf4ceb2e1..b36aa7fda 100644 --- a/features/fixtures/shared/scenarios/UserPersistencePersistUserClientScenario.m +++ b/features/fixtures/shared/scenarios/UserPersistencePersistUserClientScenario.m @@ -7,6 +7,7 @@ // #import "Scenario.h" +#import "Logging.h" /** * Set a user on the client and persist it diff --git a/features/fixtures/shared/scenarios/UserPersistencePersistUserScenario.m b/features/fixtures/shared/scenarios/UserPersistencePersistUserScenario.m index f247cbab8..c793f09b6 100644 --- a/features/fixtures/shared/scenarios/UserPersistencePersistUserScenario.m +++ b/features/fixtures/shared/scenarios/UserPersistencePersistUserScenario.m @@ -7,6 +7,7 @@ // #import "Scenario.h" +#import "Logging.h" /** * Set a user on the config and persist it diff --git a/features/fixtures/shared/utils/BugsnagWrapper.swift b/features/fixtures/shared/utils/BugsnagWrapper.swift index cd51e3d49..79d0d50ba 100644 --- a/features/fixtures/shared/utils/BugsnagWrapper.swift +++ b/features/fixtures/shared/utils/BugsnagWrapper.swift @@ -19,8 +19,8 @@ class BugsnagWrapper : Bugsnag { plistNotifyEndpoint = configuration.endpoints.notify; plistSessionsEndpoint = configuration.endpoints.sessions; - NSLog("Plist notify endpoint: %@", plistNotifyEndpoint); - NSLog("Plist sessions endpoint: %@", plistSessionsEndpoint); + logInfo("Plist notify endpoint: %@", plistNotifyEndpoint); + logInfo("Plist sessions endpoint: %@", plistSessionsEndpoint); if (plistNotifyEndpoint != "http://example.com/notify" || plistSessionsEndpoint != "http://example.com/sessions") { diff --git a/features/fixtures/shared/utils/Logging.swift b/features/fixtures/shared/utils/Logging.swift new file mode 100644 index 000000000..7e411da03 --- /dev/null +++ b/features/fixtures/shared/utils/Logging.swift @@ -0,0 +1,36 @@ +// +// logging.swift +// iOSTestApp +// +// Created by Karl Stenerud on 02.11.23. +// Copyright © 2023 Bugsnag. All rights reserved. +// + +import Foundation + +//public func logInfo(_ format: String) { +// logInfo(format: format, args: 0 as Int) +//} +public func logInfo(_ format: String, _ args: CVarArg...) { + withVaList(args) { + logInternal("info", format, $0) + } +} + +//public func logWarn(_ format: String) { +// logWarn(format: format, args: 0 as Int) +//} +public func logWarn(_ format: String, _ args: CVarArg...) { + withVaList(args) { + logInternal("warn", format, $0) + } +} + +//public func logError(_ format: String) { +// logError(format: format, args: 0 as Int) +//} +public func logError(_ format: String, _ args: CVarArg...) { + withVaList(args) { + logInternal("error", format, $0) + } +} From 802ffb1969187dc07d079b56175a661cb4ee8025 Mon Sep 17 00:00:00 2001 From: Steve Kirkland-Walton Date: Thu, 2 Nov 2023 19:42:18 +0000 Subject: [PATCH 20/61] Tune down detail logs to debug level --- .../macos/macOSTestApp/MainWindowController.m | 4 ++-- .../scenarios/AppHangDefaultConfigScenario.swift | 4 ++-- .../AppHangDidBecomeActiveScenario.swift | 2 +- .../AppHangDidEnterBackgroundScenario.swift | 2 +- .../scenarios/AppHangDisabledScenario.swift | 4 ++-- .../scenarios/AppHangFatalDisabledScenario.swift | 2 +- .../scenarios/AppHangFatalOnlyScenario.swift | 2 +- .../scenarios/AppHangInTerminationScenario.swift | 2 +- .../shared/scenarios/AppHangScenario.swift | 4 ++-- .../shared/scenarios/LastRunInfoScenario.swift | 2 +- .../shared/scenarios/OOMInactiveScenario.swift | 2 +- features/fixtures/shared/scenarios/OOMScenario.m | 16 ++++++++-------- .../scenarios/OldCrashReportScenario.swift | 2 +- .../scenarios/OldHandledErrorScenario.swift | 2 +- .../shared/scenarios/OldSessionScenario.m | 2 +- .../ReportBackgroundAppHangScenario.swift | 4 ++-- features/fixtures/shared/scenarios/Scenario.m | 10 +++++----- ...hesSynchronouslyLaunchCompletedScenario.swift | 2 +- .../SendLaunchCrashesSynchronouslyScenario.swift | 4 ++-- 19 files changed, 36 insertions(+), 36 deletions(-) diff --git a/features/fixtures/macos/macOSTestApp/MainWindowController.m b/features/fixtures/macos/macOSTestApp/MainWindowController.m index 7eecaa82f..16fa42131 100644 --- a/features/fixtures/macos/macOSTestApp/MainWindowController.m +++ b/features/fixtures/macos/macOSTestApp/MainWindowController.m @@ -48,7 +48,7 @@ - (BugsnagConfiguration *)configuration { } - (IBAction)runScenario:(id)sender { - logInfo(@"%s %@", __PRETTY_FUNCTION__, self.scenarioName); + logDebug(@"%s %@", __PRETTY_FUNCTION__, self.scenarioName); // Cater for multiple calls to -run if (!Scenario.currentScenario) { @@ -70,7 +70,7 @@ - (IBAction)runScenario:(id)sender { } - (IBAction)startBugsnag:(id)sender { - logInfo(@"%s %@", __PRETTY_FUNCTION__, self.scenarioName); + logDebug(@"%s %@", __PRETTY_FUNCTION__, self.scenarioName); [Scenario createScenarioNamed:self.scenarioName withConfig:[self configuration]]; Scenario.currentScenario.eventMode = self.scenarioMetadata; diff --git a/features/fixtures/shared/scenarios/AppHangDefaultConfigScenario.swift b/features/fixtures/shared/scenarios/AppHangDefaultConfigScenario.swift index 0754b0656..f6eb77f5a 100644 --- a/features/fixtures/shared/scenarios/AppHangDefaultConfigScenario.swift +++ b/features/fixtures/shared/scenarios/AppHangDefaultConfigScenario.swift @@ -2,8 +2,8 @@ class AppHangDefaultConfigScenario: Scenario { override func run() { let timeInterval: TimeInterval = 5 - logInfo("Simulating an app hang of \(timeInterval) seconds...") + logDebug("Simulating an app hang of \(timeInterval) seconds...") Thread.sleep(forTimeInterval: timeInterval) - logInfo("Finished sleeping") + logDebug("Finished sleeping") } } diff --git a/features/fixtures/shared/scenarios/AppHangDidBecomeActiveScenario.swift b/features/fixtures/shared/scenarios/AppHangDidBecomeActiveScenario.swift index bb1f1bbea..b54f0781e 100644 --- a/features/fixtures/shared/scenarios/AppHangDidBecomeActiveScenario.swift +++ b/features/fixtures/shared/scenarios/AppHangDidBecomeActiveScenario.swift @@ -10,7 +10,7 @@ class AppHangDidBecomeActiveScenario: Scenario { override func run() { NotificationCenter.default.addObserver(forName: UIApplication.didBecomeActiveNotification, object: nil, queue: nil) { - logInfo("Received \($0.name), now sleeping for 3 seconds...") + logDebug("Received \($0.name), now sleeping for 3 seconds...") Thread.sleep(forTimeInterval: 3) } } diff --git a/features/fixtures/shared/scenarios/AppHangDidEnterBackgroundScenario.swift b/features/fixtures/shared/scenarios/AppHangDidEnterBackgroundScenario.swift index 8905719a5..73eaeccf4 100644 --- a/features/fixtures/shared/scenarios/AppHangDidEnterBackgroundScenario.swift +++ b/features/fixtures/shared/scenarios/AppHangDidEnterBackgroundScenario.swift @@ -4,7 +4,7 @@ class AppHangDidEnterBackgroundScenario: Scenario { override func run() { NotificationCenter.default.addObserver(forName: UIApplication.didEnterBackgroundNotification, object: nil, queue: nil) { - logInfo("Received \($0.name), now hanging indefinitely...") + logDebug("Received \($0.name), now hanging indefinitely...") while true {} } } diff --git a/features/fixtures/shared/scenarios/AppHangDisabledScenario.swift b/features/fixtures/shared/scenarios/AppHangDisabledScenario.swift index 852ff3168..513b2df18 100644 --- a/features/fixtures/shared/scenarios/AppHangDisabledScenario.swift +++ b/features/fixtures/shared/scenarios/AppHangDisabledScenario.swift @@ -7,8 +7,8 @@ class AppHangDisabledScenario: Scenario { override func run() { let timeInterval: TimeInterval = 5 - logInfo("Simulating an app hang of \(timeInterval) seconds...") + logDebug("Simulating an app hang of \(timeInterval) seconds...") Thread.sleep(forTimeInterval: timeInterval) - logInfo("Finished sleeping") + logDebug("Finished sleeping") } } diff --git a/features/fixtures/shared/scenarios/AppHangFatalDisabledScenario.swift b/features/fixtures/shared/scenarios/AppHangFatalDisabledScenario.swift index 7cf1a1bd8..a5b08b688 100644 --- a/features/fixtures/shared/scenarios/AppHangFatalDisabledScenario.swift +++ b/features/fixtures/shared/scenarios/AppHangFatalDisabledScenario.swift @@ -7,7 +7,7 @@ class AppHangFatalDisabledScenario: Scenario { } override func run() { - logInfo("Hanging indefinitely...") + logDebug("Hanging indefinitely...") // Use asyncAfter to allow the Appium click event to be handled DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { while true {} diff --git a/features/fixtures/shared/scenarios/AppHangFatalOnlyScenario.swift b/features/fixtures/shared/scenarios/AppHangFatalOnlyScenario.swift index 2b43e3882..c5071c426 100644 --- a/features/fixtures/shared/scenarios/AppHangFatalOnlyScenario.swift +++ b/features/fixtures/shared/scenarios/AppHangFatalOnlyScenario.swift @@ -9,7 +9,7 @@ class AppHangFatalOnlyScenario: Scenario { } override func run() { - logInfo("Hanging indefinitely...") + logDebug("Hanging indefinitely...") // Use asyncAfter to allow the Appium click event to be handled DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) { while true {} diff --git a/features/fixtures/shared/scenarios/AppHangInTerminationScenario.swift b/features/fixtures/shared/scenarios/AppHangInTerminationScenario.swift index a774a6433..63e7b8942 100644 --- a/features/fixtures/shared/scenarios/AppHangInTerminationScenario.swift +++ b/features/fixtures/shared/scenarios/AppHangInTerminationScenario.swift @@ -27,7 +27,7 @@ class AppHangInTerminationScenario: Scenario { #endif NotificationCenter.default.addObserver(forName: willTerminate, object: nil, queue: nil) { - logInfo("Received \($0.name.rawValue), simulating an app hang...") + logDebug("Received \($0.name.rawValue), simulating an app hang...") Thread.sleep(forTimeInterval: 3) } diff --git a/features/fixtures/shared/scenarios/AppHangScenario.swift b/features/fixtures/shared/scenarios/AppHangScenario.swift index 5dda91cd5..5f3474afc 100644 --- a/features/fixtures/shared/scenarios/AppHangScenario.swift +++ b/features/fixtures/shared/scenarios/AppHangScenario.swift @@ -18,7 +18,7 @@ class AppHangScenario: Scenario { override func run() { Bugsnag.setContext("App Hang Scenario") let timeInterval = TimeInterval(eventMode!)! - logInfo("Simulating an app hang of \(timeInterval) seconds...") + logDebug("Simulating an app hang of \(timeInterval) seconds...") if timeInterval > 2 { Thread.sleep(forTimeInterval: 1.5) Bugsnag.leaveBreadcrumb(withMessage: "This breadcrumb was left during the hang, before detection") @@ -27,6 +27,6 @@ class AppHangScenario: Scenario { Thread.sleep(forTimeInterval: timeInterval) } Bugsnag.leaveBreadcrumb(withMessage: "This breadcrumb was left after the hang") - logInfo("Finished sleeping") + logDebug("Finished sleeping") } } diff --git a/features/fixtures/shared/scenarios/LastRunInfoScenario.swift b/features/fixtures/shared/scenarios/LastRunInfoScenario.swift index 16be0159c..4995e7b7e 100644 --- a/features/fixtures/shared/scenarios/LastRunInfoScenario.swift +++ b/features/fixtures/shared/scenarios/LastRunInfoScenario.swift @@ -46,7 +46,7 @@ class LastRunInfoScenario: Scenario { while try! !FileManager.default.contentsOfDirectory(at: dir, includingPropertiesForKeys: nil, options: []) .filter({ $0.lastPathComponent.hasPrefix("CrashReport-") }).isEmpty { - logInfo("LastRunInfoScenario: waiting for delivery of crash reports...") + logDebug("LastRunInfoScenario: waiting for delivery of crash reports...") Thread.sleep(forTimeInterval: 0.1) } } diff --git a/features/fixtures/shared/scenarios/OOMInactiveScenario.swift b/features/fixtures/shared/scenarios/OOMInactiveScenario.swift index 513d0a46c..a9b496b36 100644 --- a/features/fixtures/shared/scenarios/OOMInactiveScenario.swift +++ b/features/fixtures/shared/scenarios/OOMInactiveScenario.swift @@ -22,7 +22,7 @@ class OOMInactiveScenario: Scenario { NotificationCenter.default.post(name: UIApplication.willResignActiveNotification, object: UIApplication.shared, userInfo: nil) - logInfo("Killing app to fake an OOM") + logDebug("Killing app to fake an OOM") kill(getpid(), SIGKILL) } } diff --git a/features/fixtures/shared/scenarios/OOMScenario.m b/features/fixtures/shared/scenarios/OOMScenario.m index ebfb4c700..e5f0622f6 100644 --- a/features/fixtures/shared/scenarios/OOMScenario.m +++ b/features/fixtures/shared/scenarios/OOMScenario.m @@ -58,7 +58,7 @@ - (void)run { [Bugsnag setContext:@"OOM Scenario"]; [NSNotificationCenter.defaultCenter addObserverForName:UIApplicationDidReceiveMemoryWarningNotification object:nil queue:nil usingBlock:^(NSNotification *note) { - logInfo(@"*** Received memory warning"); + logDebug(@"*** Received memory warning"); }]; // Delay to allow session payload to be sent [self performSelector:@selector(consumeAllMemory) withObject:nil afterDelay:2]; @@ -67,11 +67,11 @@ - (void)run { - (void)consumeAllMemory { struct utsname system = {0}; uname(&system); - logInfo(@"*** Device = %s", system.machine); + logDebug(@"*** Device = %s", system.machine); NSUInteger physicalMemory = (NSUInteger)NSProcessInfo.processInfo.physicalMemory; NSUInteger megabytes = physicalMemory / MEGABYTE; - logInfo(@"*** Physical memory = %lu MB", (unsigned long)megabytes); + logDebug(@"*** Physical memory = %lu MB", (unsigned long)megabytes); // // The ActiveHard limit and point at which a memory warning is sent varies by device @@ -105,21 +105,21 @@ - (void)consumeAllMemory { kern_return_t result = task_info(mach_task_self(), TASK_VM_INFO, (task_info_t)&vm_info, &count); if (result == KERN_SUCCESS && count >= TASK_VM_INFO_REV4_COUNT) { limit = (NSUInteger)(vm_info.phys_footprint + vm_info.limit_bytes_remaining) / MEGABYTE; - logInfo(@"*** Memory limit = %lu MB", (unsigned long)limit); + logDebug(@"*** Memory limit = %lu MB", (unsigned long)limit); } else if (!strcmp(system.machine, "iPhone6,2")) { limit = 650; - logInfo(@"*** Memory limit = %lu MB", (unsigned long)limit); + logDebug(@"*** Memory limit = %lu MB", (unsigned long)limit); } else { limit = MIN(2098, megabytes * 70 / 100); - logInfo(@"*** Memory limit = %lu MB (estimated)", (unsigned long)limit); + logDebug(@"*** Memory limit = %lu MB (estimated)", (unsigned long)limit); } // The size of the initial block needs to be under the memory warning limit in order for one to be reliably sent. NSUInteger initial = limit * 70 / 100; - logInfo(@"*** Dirtying an initial block of %lu MB", (unsigned long)initial); + logDebug(@"*** Dirtying an initial block of %lu MB", (unsigned long)initial); [self consumeMegabytes:initial]; - logInfo(@"*** Dirtying remaining memory in ~2 seconds"); + logDebug(@"*** Dirtying remaining memory in ~2 seconds"); NSTimeInterval timeInterval = 2.0 / (limit - initial); [NSTimer scheduledTimerWithTimeInterval:timeInterval target:self selector:@selector(timerFired) userInfo:nil repeats:YES]; } diff --git a/features/fixtures/shared/scenarios/OldCrashReportScenario.swift b/features/fixtures/shared/scenarios/OldCrashReportScenario.swift index 86126bd50..48de226cd 100644 --- a/features/fixtures/shared/scenarios/OldCrashReportScenario.swift +++ b/features/fixtures/shared/scenarios/OldCrashReportScenario.swift @@ -24,7 +24,7 @@ class OldCrashReportScenario: Scenario { for name in try FileManager.default.contentsOfDirectory(atPath: dir) { let file = (dir as NSString).appendingPathComponent(name) try FileManager.default.setAttributes([.creationDate: creationDate], ofItemAtPath: file) - logInfo("OldCrashReportScenario: Updated creation date of \((file as NSString).lastPathComponent) to \(creationDate)") + logDebug("OldCrashReportScenario: Updated creation date of \((file as NSString).lastPathComponent) to \(creationDate)") } } catch { logError("\(error)") diff --git a/features/fixtures/shared/scenarios/OldHandledErrorScenario.swift b/features/fixtures/shared/scenarios/OldHandledErrorScenario.swift index c00795176..499a1995e 100644 --- a/features/fixtures/shared/scenarios/OldHandledErrorScenario.swift +++ b/features/fixtures/shared/scenarios/OldHandledErrorScenario.swift @@ -24,7 +24,7 @@ class OldHandledErrorScenario: Scenario { for name in try FileManager.default.contentsOfDirectory(atPath: dir) { let file = (dir as NSString).appendingPathComponent(name) try FileManager.default.setAttributes([.creationDate: creationDate], ofItemAtPath: file) - logInfo("OldCrashReportScenario: Updated creation date of \((file as NSString).lastPathComponent) to \(creationDate)") + logDebug("OldCrashReportScenario: Updated creation date of \((file as NSString).lastPathComponent) to \(creationDate)") } } catch { logError("\(error)") diff --git a/features/fixtures/shared/scenarios/OldSessionScenario.m b/features/fixtures/shared/scenarios/OldSessionScenario.m index b98ef7cbb..2aca8e73c 100644 --- a/features/fixtures/shared/scenarios/OldSessionScenario.m +++ b/features/fixtures/shared/scenarios/OldSessionScenario.m @@ -41,7 +41,7 @@ - (void)modifySessionCreationDate { NSString *file = [dir stringByAppendingPathComponent:name]; NSError *error; if ([NSFileManager.defaultManager setAttributes:@{NSFileCreationDate: creationDate} ofItemAtPath:file error:&error]) { - logInfo(@"OldSessionScenario: Updated creation date of %@ to %@", file.lastPathComponent, + logDebug(@"OldSessionScenario: Updated creation date of %@ to %@", file.lastPathComponent, [NSFileManager.defaultManager attributesOfItemAtPath:file error:nil].fileCreationDate); } else { logError(@"OldSessionScenario: %@", error); diff --git a/features/fixtures/shared/scenarios/ReportBackgroundAppHangScenario.swift b/features/fixtures/shared/scenarios/ReportBackgroundAppHangScenario.swift index cbf0a76f3..cc98ee1f1 100644 --- a/features/fixtures/shared/scenarios/ReportBackgroundAppHangScenario.swift +++ b/features/fixtures/shared/scenarios/ReportBackgroundAppHangScenario.swift @@ -19,9 +19,9 @@ class ReportBackgroundAppHangScenario: Scenario { let backgroundTask = UIApplication.shared.beginBackgroundTask() let timeInterval: TimeInterval = 2 - logInfo("Simulating an app hang of \(timeInterval) seconds...") + logDebug("Simulating an app hang of \(timeInterval) seconds...") Thread.sleep(forTimeInterval: timeInterval) - logInfo("Finished sleeping") + logDebug("Finished sleeping") DispatchQueue.main.asyncAfter(deadline: .now() + 3) { UIApplication.shared.endBackgroundTask(backgroundTask) diff --git a/features/fixtures/shared/scenarios/Scenario.m b/features/fixtures/shared/scenarios/Scenario.m index a710361aa..7f2f20fae 100644 --- a/features/fixtures/shared/scenarios/Scenario.m +++ b/features/fixtures/shared/scenarios/Scenario.m @@ -60,7 +60,7 @@ + (void)load { return; } #endif - logInfo(@"Received notification %@", notification.name); + logDebug(@"Received notification %@", notification.name); }]; } @@ -213,11 +213,11 @@ + (void)clearPersistentData { } + (void)executeMazeRunnerCommand:(void (^)(NSString *scenarioName, NSString *scenarioMode))preHandler { - logInfo(@"%s", __PRETTY_FUNCTION__); + logDebug(@"%s", __PRETTY_FUNCTION__); NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration ephemeralSessionConfiguration]]; NSString *commandEndpoint = [NSString stringWithFormat:@"%@/command", theBaseMazeAddress]; NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:commandEndpoint]]; - logInfo(@"%s: Sending command request to %@", __PRETTY_FUNCTION__, commandEndpoint); + logDebug(@"%s: Sending command request to %@", __PRETTY_FUNCTION__, commandEndpoint); [[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { if (![response isKindOfClass:[NSHTTPURLResponse class]] || [(NSHTTPURLResponse *)response statusCode] != 200) { logError(@"%s: command request failed with %@", __PRETTY_FUNCTION__, response ?: error); @@ -266,7 +266,7 @@ + (void)executeMazeRunnerCommand:(void (^)(NSString *scenarioName, NSString *sce } + (void)runScenario:(NSString *)scenarioName eventMode:(NSString *)eventMode { - logInfo(@"%s %@ %@", __PRETTY_FUNCTION__, scenarioName, eventMode); + logDebug(@"%s %@ %@", __PRETTY_FUNCTION__, scenarioName, eventMode); [self startBugsnagForScenario:scenarioName eventMode:eventMode]; @@ -274,7 +274,7 @@ + (void)runScenario:(NSString *)scenarioName eventMode:(NSString *)eventMode { } + (void)startBugsnagForScenario:(NSString *)scenarioName eventMode:(NSString *)eventMode { - logInfo(@"%s %@ %@", __PRETTY_FUNCTION__, scenarioName, eventMode); + logDebug(@"%s %@ %@", __PRETTY_FUNCTION__, scenarioName, eventMode); theScenario = [Scenario createScenarioNamed:scenarioName withConfig:nil]; theScenario.eventMode = eventMode; diff --git a/features/fixtures/shared/scenarios/SendLaunchCrashesSynchronouslyLaunchCompletedScenario.swift b/features/fixtures/shared/scenarios/SendLaunchCrashesSynchronouslyLaunchCompletedScenario.swift index 17d030cf0..1c9b1ce3e 100644 --- a/features/fixtures/shared/scenarios/SendLaunchCrashesSynchronouslyLaunchCompletedScenario.swift +++ b/features/fixtures/shared/scenarios/SendLaunchCrashesSynchronouslyLaunchCompletedScenario.swift @@ -2,7 +2,7 @@ class SendLaunchCrashesSynchronouslyLaunchCompletedScenario: SendLaunchCrashesSy override func run() { if eventMode != "report" { - logInfo(">>> Calling markLaunchCompleted()") + logDebug(">>> Calling markLaunchCompleted()") Bugsnag.markLaunchCompleted() } super.run() diff --git a/features/fixtures/shared/scenarios/SendLaunchCrashesSynchronouslyScenario.swift b/features/fixtures/shared/scenarios/SendLaunchCrashesSynchronouslyScenario.swift index 08cb9c1c8..ff3111a9c 100644 --- a/features/fixtures/shared/scenarios/SendLaunchCrashesSynchronouslyScenario.swift +++ b/features/fixtures/shared/scenarios/SendLaunchCrashesSynchronouslyScenario.swift @@ -20,7 +20,7 @@ class SendLaunchCrashesSynchronouslyScenario: Scenario { override func run() { if eventMode == "report" { - logInfo(">>> Delaying to allow previous run's crash report to be sent") + logDebug(">>> Delaying to allow previous run's crash report to be sent") DispatchQueue.main.asyncAfter(deadline: .now() + 5) { [startDuration] in NSLog(">>> Calling notify() with startDuration = \(startDuration)") Bugsnag.notifyError(NSError(domain: "DummyError", code: 0)) { @@ -29,7 +29,7 @@ class SendLaunchCrashesSynchronouslyScenario: Scenario { } } } else { - logInfo(">>> Calling fatalError()") + logDebug(">>> Calling fatalError()") fatalError() } } From c2fd0c1447ae29d006ac4561160bf72b87a4cdf7 Mon Sep 17 00:00:00 2001 From: Josh Edney Date: Fri, 3 Nov 2023 09:06:21 +0000 Subject: [PATCH 21/61] dynamically select watchos target --- Makefile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 990110d37..842568a78 100644 --- a/Makefile +++ b/Makefile @@ -34,8 +34,9 @@ else DESTINATION?=platform=iOS Simulator,name=$(DEVICE),OS=$(OS) RELEASE_DIR=Release-iphoneos else - SDK?=watchsimulator8.5 - DEVICE?=Apple Watch Series 5 - 40mm + SDK?=watchsimulator +# Due to the inconsistency of device names as a result of running; xcodebuild -downloadAllPlatforms, this dynamically selects the watchOS device. + DEVICE?=$(shell xcrun simctl list --json | jq -r '.devices."com.apple.CoreSimulator.SimRuntime.watchOS-8-5"[] | select(.name | test("Apple Watch Series 5 .+ ?40mm ?")) | .name') DESTINATION?=platform=watchOS Simulator,name=$(DEVICE),OS=$(OS) RELEASE_DIR=Release-watchos endif From e7843e72303d751bd46d058ddc2906c7d934ac33 Mon Sep 17 00:00:00 2001 From: Steve Kirkland-Walton Date: Fri, 3 Nov 2023 11:06:26 +0000 Subject: [PATCH 22/61] Add logDebug --- features/fixtures/shared/scenarios/Logging.h | 2 ++ features/fixtures/shared/scenarios/Logging.m | 7 +++++++ features/fixtures/shared/utils/Logging.swift | 9 +++++++++ 3 files changed, 18 insertions(+) diff --git a/features/fixtures/shared/scenarios/Logging.h b/features/fixtures/shared/scenarios/Logging.h index bbbbbfa93..6305e7eac 100644 --- a/features/fixtures/shared/scenarios/Logging.h +++ b/features/fixtures/shared/scenarios/Logging.h @@ -8,6 +8,7 @@ #import +void logDebugObjC(NSString *format, ...); void logInfoObjC(NSString *format, ...); void logWarnObjC(NSString *format, ...); void logErrorObjC(NSString *format, ...); @@ -16,6 +17,7 @@ void logErrorObjC(NSString *format, ...); //#define logWarn(FMT, ...) logWarnObjC(FMT, __VA_ARGS__) //#define logError(FMT, ...) logErrorObjC(FMT, __VA_ARGS__) +#define logDebug logDebugObjC #define logInfo logInfoObjC #define logWarn logWarnObjC #define logError logErrorObjC diff --git a/features/fixtures/shared/scenarios/Logging.m b/features/fixtures/shared/scenarios/Logging.m index 919dff9d4..742201d72 100644 --- a/features/fixtures/shared/scenarios/Logging.m +++ b/features/fixtures/shared/scenarios/Logging.m @@ -22,6 +22,13 @@ void logInternal(const char* level, NSString *format, va_list args) { } +void logDebugObjC(NSString *format, ...) { + va_list args; + va_start(args, format); + logInternal("debug", format, args); + va_end(args); +} + void logInfoObjC(NSString *format, ...) { va_list args; va_start(args, format); diff --git a/features/fixtures/shared/utils/Logging.swift b/features/fixtures/shared/utils/Logging.swift index 7e411da03..72721666a 100644 --- a/features/fixtures/shared/utils/Logging.swift +++ b/features/fixtures/shared/utils/Logging.swift @@ -8,6 +8,15 @@ import Foundation +//public func logDebug(_ format: String) { +// logDebug(format: format, args: 0 as Int) +//} +public func logDebug(_ format: String, _ args: CVarArg...) { + withVaList(args) { + logInternal("debug", format, $0) + } +} + //public func logInfo(_ format: String) { // logInfo(format: format, args: 0 as Int) //} From 800ce32309606872352ce9934dbd6f20fa04abe7 Mon Sep 17 00:00:00 2001 From: Steve Kirkland-Walton Date: Mon, 6 Nov 2023 18:57:19 +0000 Subject: [PATCH 23/61] Skip app_hangs.feature on BitBar (Appium 2) --- .buildkite/pipeline.yml | 2 ++ .gitignore | 1 + features/app_hangs.feature | 1 - 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 161921db4..11439a3f4 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -305,6 +305,8 @@ steps: - "--no-tunnel" - "--aws-public-ip" - "--fail-fast" + # App hang scenarios run on BrowserStack, see PLAT-11155 + - "--exclude=features/app_hangs.feature" - "--exclude=features/[e-z].*.feature$" concurrency: 25 concurrency_group: 'bitbar' diff --git a/.gitignore b/.gitignore index 001e898bd..da7e5f018 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,4 @@ Package.resolved /docs/ /infer-out /oclint.json +bb.ready diff --git a/features/app_hangs.feature b/features/app_hangs.feature index a2c91dbca..8f31de417 100644 --- a/features/app_hangs.feature +++ b/features/app_hangs.feature @@ -1,4 +1,3 @@ -@skip # https://smartbear.atlassian.net/browse/PLAT-11155 Feature: App hangs Background: From 7a429153b6c3bdd2f98a5bc80feba163be365921 Mon Sep 17 00:00:00 2001 From: Steve Kirkland-Walton Date: Mon, 6 Nov 2023 19:34:25 +0000 Subject: [PATCH 24/61] Run app hang tests on Appium 1 (BrowserStack) [full ci] --- .buildkite/pipeline.full.yml | 120 +++++++++++++++++++++++++++++++++++ .buildkite/pipeline.yml | 30 ++++++++- 2 files changed, 149 insertions(+), 1 deletion(-) diff --git a/.buildkite/pipeline.full.yml b/.buildkite/pipeline.full.yml index 52ddff668..37d6e60f4 100644 --- a/.buildkite/pipeline.full.yml +++ b/.buildkite/pipeline.full.yml @@ -24,6 +24,8 @@ steps: run: cocoa-maze-runner-bitbar service-ports: true command: + # PLAT-11155: App hang scenarios run on BrowserStack + - "--exclude=features/app_hangs.feature" - "--exclude=features/[e-z].*.feature$" - "--app=@/app/build/ipa_url_bb.txt" - "--farm=bb" @@ -79,6 +81,8 @@ steps: - "--no-tunnel" - "--aws-public-ip" - "--fail-fast" + # PLAT-11155: App hang scenarios run on BrowserStack + - "--exclude=features/app_hangs.feature" - "--exclude=features/[e-z].*.feature$" concurrency: 25 concurrency_group: 'bitbar' @@ -139,6 +143,8 @@ steps: - "--no-tunnel" - "--aws-public-ip" - "--fail-fast" + # PLAT-11155: App hang scenarios run on BrowserStack + - "--exclude=features/app_hangs.feature" - "--exclude=features/[e-z].*.feature$" concurrency: 25 concurrency_group: 'bitbar' @@ -199,6 +205,8 @@ steps: - "--no-tunnel" - "--aws-public-ip" - "--fail-fast" + # PLAT-11155: App hang scenarios run on BrowserStack + - "--exclude=features/app_hangs.feature" - "--exclude=features/[e-z].*.feature$" concurrency: 25 concurrency_group: 'bitbar' @@ -241,6 +249,118 @@ steps: # # BrowserStack # + # PLAT-11155: App hang tests run on BrowserStack (Appium 1.x) for now + - label: ':browserstack: iOS 15 app hang tests' + depends_on: + - cocoa_fixture + timeout_in_minutes: 10 + agents: + queue: opensource + plugins: + artifacts#v1.5.0: + download: "features/fixtures/ios/output/ipa_url_bs.txt" + upload: "maze_output/failed/**/*" + docker-compose#v3.7.0: + pull: cocoa-maze-runner + run: cocoa-maze-runner + command: + - "--app=@build/ipa_url_bs.txt" + - "--farm=bs" + - "--device=IOS_15" + - "--appium-version=1.22.0" + - "features/app_hangs.feature" + concurrency: 5 + concurrency_group: 'browserstack-app' + concurrency_method: eager + retry: + automatic: + - exit_status: -1 # Agent was lost + limit: 2 + + # PLAT-11155: App hang tests run on BrowserStack (Appium 1.x) for now + - label: ':browserstack: iOS 14 app hang tests' + depends_on: + - cocoa_fixture + timeout_in_minutes: 10 + agents: + queue: opensource + plugins: + artifacts#v1.5.0: + download: "features/fixtures/ios/output/ipa_url_bs.txt" + upload: "maze_output/failed/**/*" + docker-compose#v3.7.0: + pull: cocoa-maze-runner + run: cocoa-maze-runner + command: + - "--app=@build/ipa_url_bs.txt" + - "--farm=bs" + - "--device=IOS_14" + - "--appium-version=1.22.0" + - "features/app_hangs.feature" + concurrency: 5 + concurrency_group: 'browserstack-app' + concurrency_method: eager + retry: + automatic: + - exit_status: -1 # Agent was lost + limit: 2 + + # PLAT-11155: App hang tests run on BrowserStack (Appium 1.x) for now + - label: ':browserstack: iOS 13 app hang tests' + depends_on: + - cocoa_fixture + timeout_in_minutes: 10 + agents: + queue: opensource + plugins: + artifacts#v1.5.0: + download: "features/fixtures/ios/output/ipa_url_bs.txt" + upload: "maze_output/failed/**/*" + docker-compose#v3.7.0: + pull: cocoa-maze-runner + run: cocoa-maze-runner + command: + - "--app=@build/ipa_url_bs.txt" + - "--farm=bs" + - "--device=IOS_13" + - "--appium-version=1.22.0" + - "features/app_hangs.feature" + concurrency: 5 + concurrency_group: 'browserstack-app' + concurrency_method: eager + retry: + automatic: + - exit_status: -1 # Agent was lost + limit: 2 + + # PLAT-11155: App hang tests run on BrowserStack (Appium 1.x) for now + - label: ':browserstack: iOS 12 app hang tests' + depends_on: + - cocoa_fixture + timeout_in_minutes: 10 + agents: + queue: opensource + plugins: + artifacts#v1.5.0: + download: "features/fixtures/ios/output/ipa_url_bs.txt" + upload: "maze_output/failed/**/*" + docker-compose#v3.7.0: + pull: cocoa-maze-runner + run: cocoa-maze-runner + command: + - "--app=@build/ipa_url_bs.txt" + - "--farm=bs" + - "--device=IOS_12" + - "--appium-version=1.22.0" + - "features/app_hangs.feature" + concurrency: 5 + concurrency_group: 'browserstack-app' + concurrency_method: eager + retry: + automatic: + - exit_status: -1 # Agent was lost + limit: 2 + - label: ':browserstack: iOS 11 E2E tests batch 1' skip: "https://smartbear.atlassian.net/browse/PLAT-11154" depends_on: diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 11439a3f4..93faa1f1c 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -305,7 +305,7 @@ steps: - "--no-tunnel" - "--aws-public-ip" - "--fail-fast" - # App hang scenarios run on BrowserStack, see PLAT-11155 + # PLAT-11155: App hang scenarios run on BrowserStack - "--exclude=features/app_hangs.feature" - "--exclude=features/[e-z].*.feature$" concurrency: 25 @@ -346,6 +346,34 @@ steps: - exit_status: -1 # Agent was lost limit: 2 + # PLAT-11155: App hang tests run on BrowserStack (Appium 1.x) for now + - label: ':browserstack: iOS 16 app hang tests' + depends_on: + - cocoa_fixture + timeout_in_minutes: 10 + agents: + queue: opensource + plugins: + artifacts#v1.5.0: + download: "features/fixtures/ios/output/ipa_url_bs.txt" + upload: "maze_output/failed/**/*" + docker-compose#v3.7.0: + pull: cocoa-maze-runner + run: cocoa-maze-runner + command: + - "--app=@build/ipa_url_bs.txt" + - "--farm=bs" + - "--device=IOS_16" + - "--appium-version=1.22.0" + - "features/app_hangs.feature" + concurrency: 5 + concurrency_group: 'browserstack-app' + concurrency_method: eager + retry: + automatic: + - exit_status: -1 # Agent was lost + limit: 2 + - label: ':bitbar: iOS 15 barebone tests' depends_on: - cocoa_fixture From 7e2d0568b72efbb30216e00e0f8c9aec9126ceed Mon Sep 17 00:00:00 2001 From: Karl Stenerud Date: Mon, 23 Oct 2023 16:02:42 +0200 Subject: [PATCH 25/61] Fix handling of null fields in the user --- Bugsnag/BugsnagInternals.h | 2 ++ Bugsnag/Client/BugsnagClient.m | 2 +- Bugsnag/Payload/BugsnagUser.m | 19 ++++++++++++++++++ Tests/BugsnagTests/BugsnagUserTest.m | 29 ++++++++++++++++++++++++++++ 4 files changed, 51 insertions(+), 1 deletion(-) diff --git a/Bugsnag/BugsnagInternals.h b/Bugsnag/BugsnagInternals.h index 7a71c091e..76c00bea4 100644 --- a/Bugsnag/BugsnagInternals.h +++ b/Bugsnag/BugsnagInternals.h @@ -231,6 +231,8 @@ typedef void (^ BSGClientObserver)(BSGClientObserverEvent event, _Nullable id va - (NSDictionary *)toJson; +- (NSDictionary *)toJsonWithNSNulls; + @end #pragma mark - diff --git a/Bugsnag/Client/BugsnagClient.m b/Bugsnag/Client/BugsnagClient.m index 5cf220a98..6a187b3fe 100644 --- a/Bugsnag/Client/BugsnagClient.m +++ b/Bugsnag/Client/BugsnagClient.m @@ -560,7 +560,7 @@ - (BugsnagUser *)user { - (void)setUser:(NSString *)userId withEmail:(NSString *)email andName:(NSString *)name { @synchronized (self.configuration) { [self.configuration setUser:userId withEmail:email andName:name]; - [self.state addMetadata:[self.configuration.user toJson] toSection:BSGKeyUser]; + [self.state addMetadata:[self.configuration.user toJsonWithNSNulls] toSection:BSGKeyUser]; if (self.observer) { self.observer(BSGClientObserverUpdateUser, self.user); } diff --git a/Bugsnag/Payload/BugsnagUser.m b/Bugsnag/Payload/BugsnagUser.m index da65734db..fa26575d2 100644 --- a/Bugsnag/Payload/BugsnagUser.m +++ b/Bugsnag/Payload/BugsnagUser.m @@ -16,9 +16,19 @@ @implementation BugsnagUser - (instancetype)initWithDictionary:(NSDictionary *)dict { if ((self = [super init])) { + id nsnull = [NSNull null]; _id = dict[@"id"]; + if (_id == nsnull) { + _id = nil; + } _email = dict[@"email"]; + if (_email == nsnull) { + _email = nil; + } _name = dict[@"name"]; + if (_name == nsnull) { + _name = nil; + } } return self; } @@ -32,6 +42,14 @@ - (instancetype)initWithId:(NSString *)id name:(NSString *)name emailAddress:(NS return self; } +- (NSDictionary *)toJsonWithNSNulls { + NSMutableDictionary *dict = [NSMutableDictionary new]; + dict[@"id"] = self.id ?: [NSNull null]; + dict[@"email"] = self.email ?: [NSNull null]; + dict[@"name"] = self.name ?: [NSNull null]; + return [NSDictionary dictionaryWithDictionary:dict]; +} + - (NSDictionary *)toJson { NSMutableDictionary *dict = [NSMutableDictionary new]; dict[@"id"] = self.id; @@ -40,6 +58,7 @@ - (NSDictionary *)toJson { return [NSDictionary dictionaryWithDictionary:dict]; } + - (BugsnagUser *)withId { if (self.id) { return self; diff --git a/Tests/BugsnagTests/BugsnagUserTest.m b/Tests/BugsnagTests/BugsnagUserTest.m index 3bf3e458a..c834b89e3 100644 --- a/Tests/BugsnagTests/BugsnagUserTest.m +++ b/Tests/BugsnagTests/BugsnagUserTest.m @@ -31,6 +31,35 @@ - (void)testDictDeserialisation { XCTAssertEqualObjects(user.name, @"Tom Bombadil"); } +- (void)testDictNullDeserialisation { + + NSDictionary *dict = @{ + @"id": [NSNull null], + @"email": [NSNull null], + @"name": [NSNull null] + }; + BugsnagUser *user = [[BugsnagUser alloc] initWithDictionary:dict]; + + XCTAssertNotNil(user); + XCTAssertNil(user.id); + XCTAssertNil(user.email); + XCTAssertNil(user.name); +} + +- (void)testDictNullSerialisation { + BugsnagUser *user = [[BugsnagUser alloc] initWithId:nil name:nil emailAddress:nil]; + NSDictionary *dict = [user toJson]; + XCTAssertEqualObjects(@{}, dict); + + dict = [user toJsonWithNSNulls]; + NSDictionary *expected = @{ + @"id": [NSNull null], + @"email": [NSNull null], + @"name": [NSNull null] + }; + XCTAssertEqualObjects(expected, dict); +} + - (void)testPayloadSerialisation { BugsnagUser *payload = [[BugsnagUser alloc] initWithId:@"test" name:@"Tom Bombadil" emailAddress:@"fake@example.com"]; NSDictionary *rootNode = [payload toJson]; From 6762e106a58e465a609e24de490e0f6156d641cb Mon Sep 17 00:00:00 2001 From: Robert Date: Wed, 11 Oct 2023 05:45:43 +0200 Subject: [PATCH 26/61] Added iOS 17 testing to the pipeline --- .buildkite/pipeline.yml | 73 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 161921db4..c25d7b244 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -11,7 +11,7 @@ steps: key: cocoa_fixture timeout_in_minutes: 30 agents: - queue: macos-12-arm + queue: macos-13-arm artifact_paths: - features/fixtures/ios/output/iOSTestApp.ipa - features/fixtures/macos/output/macOSTestApp.zip @@ -90,6 +90,15 @@ steps: - ./scripts/run-unit-tests.sh PLATFORM=macOS artifact_paths: - logs/* + + - label: iOS 17 unit tests + timeout_in_minutes: 10 + agents: + queue: macos-13-arm + commands: + - ./scripts/run-unit-tests.sh PLATFORM=iOS OS=17.0 + artifact_paths: + - logs/* - label: iOS 15 unit tests timeout_in_minutes: 10 @@ -284,6 +293,68 @@ steps: # # BitBar # + - label: ':bitbar: iOS 17 E2E tests batch 1' + depends_on: + - cocoa_fixture + timeout_in_minutes: 60 + agents: + queue: opensource + plugins: + artifacts#v1.9.0: + download: "features/fixtures/ios/output/ipa_url_bb.txt" + upload: "maze_output/failed/**/*" + docker-compose#v4.7.0: + pull: cocoa-maze-runner-bitbar + run: cocoa-maze-runner-bitbar + service-ports: true + command: + - "--app=@/app/build/ipa_url_bb.txt" + - "--farm=bb" + - "--device=IOS_17" + - "--no-tunnel" + - "--aws-public-ip" + - "--fail-fast" + - "--exclude=features/[e-z].*.feature$" + - "--order=random" + concurrency: 25 + concurrency_group: 'bitbar' + concurrency_method: eager + retry: + automatic: + - exit_status: -1 # Agent was lost + limit: 2 + + - label: ':bitbar: iOS 17 E2E tests batch 2' + depends_on: + - cocoa_fixture + timeout_in_minutes: 60 + agents: + queue: opensource + plugins: + artifacts#v1.9.0: + download: "features/fixtures/ios/output/ipa_url_bb.txt" + upload: "maze_output/failed/**/*" + docker-compose#v4.7.0: + pull: cocoa-maze-runner-bitbar + run: cocoa-maze-runner-bitbar + service-ports: true + command: + - "--app=@/app/build/ipa_url_bb.txt" + - "--farm=bb" + - "--device=IOS_17" + - "--no-tunnel" + - "--aws-public-ip" + - "--fail-fast" + - "--exclude=features/[a-d].*.feature$" + - "--order=random" + concurrency: 25 + concurrency_group: 'bitbar' + concurrency_method: eager + retry: + automatic: + - exit_status: -1 # Agent was lost + limit: 2 + - label: ':bitbar: iOS 16 E2E tests batch 1' depends_on: - cocoa_fixture From aab45046f5e020138b54d4fb7619b45e22aa2b9d Mon Sep 17 00:00:00 2001 From: Robert Date: Wed, 11 Oct 2023 06:05:26 +0200 Subject: [PATCH 27/61] Updated pipeline --- .buildkite/pipeline.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index c25d7b244..816d4fad0 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -26,7 +26,7 @@ steps: - label: Static framework and Swift Package Manager builds timeout_in_minutes: 10 agents: - queue: macos-12-arm + queue: macos-13-arm commands: - make build_swift - make build_ios_static @@ -34,7 +34,7 @@ steps: - label: Carthage timeout_in_minutes: 15 agents: - queue: macos-12-arm + queue: macos-13-arm commands: - ./scripts/build-carthage.sh plugins: @@ -105,7 +105,7 @@ steps: agents: queue: macos-12-arm commands: - - ./scripts/run-unit-tests.sh PLATFORM=iOS OS=15.0 + - ./scripts/run-unit-tests.sh PLATFORM=iOS OS=15.4 artifact_paths: - logs/* From 6247d94b4c3a00e445f4c1c85f3264abe3178db6 Mon Sep 17 00:00:00 2001 From: Robert Date: Wed, 11 Oct 2023 09:48:46 +0200 Subject: [PATCH 28/61] Updated pipeline --- .buildkite/pipeline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 816d4fad0..6a5bd9f73 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -105,7 +105,7 @@ steps: agents: queue: macos-12-arm commands: - - ./scripts/run-unit-tests.sh PLATFORM=iOS OS=15.4 + - ./scripts/run-unit-tests.sh PLATFORM=iOS OS=15.0 artifact_paths: - logs/* From aa0cf2cf6c3aca6eb06837cbccc4b4bde2b53896 Mon Sep 17 00:00:00 2001 From: Robert Date: Wed, 11 Oct 2023 09:57:13 +0200 Subject: [PATCH 29/61] Bumped deployment target for the network request plugin --- .../BugsnagNetworkRequestPlugin.xcodeproj/project.pbxproj | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/BugsnagNetworkRequestPlugin/BugsnagNetworkRequestPlugin.xcodeproj/project.pbxproj b/BugsnagNetworkRequestPlugin/BugsnagNetworkRequestPlugin.xcodeproj/project.pbxproj index 1110195f5..fff8a89fe 100644 --- a/BugsnagNetworkRequestPlugin/BugsnagNetworkRequestPlugin.xcodeproj/project.pbxproj +++ b/BugsnagNetworkRequestPlugin/BugsnagNetworkRequestPlugin.xcodeproj/project.pbxproj @@ -888,6 +888,7 @@ CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = 372ZUL2ZB7; INFOPLIST_FILE = "../Tests/TestHost-iOS/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -905,6 +906,7 @@ CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = 372ZUL2ZB7; INFOPLIST_FILE = "../Tests/TestHost-iOS/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1250,6 +1252,7 @@ DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = BugsnagNetworkRequestPlugin/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1273,6 +1276,7 @@ DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = BugsnagNetworkRequestPlugin/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1293,6 +1297,7 @@ GCC_WARN_PEDANTIC = NO; GCC_WARN_UNUSED_PARAMETER = NO; INFOPLIST_FILE = BugsnagNetworkRequestPluginTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1313,6 +1318,7 @@ GCC_WARN_PEDANTIC = NO; GCC_WARN_UNUSED_PARAMETER = NO; INFOPLIST_FILE = BugsnagNetworkRequestPluginTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", From 241ae3ab5d14a64b4d5f9b80ecfb41a3f71bcd05 Mon Sep 17 00:00:00 2001 From: Robert Date: Wed, 11 Oct 2023 17:43:01 +0200 Subject: [PATCH 30/61] Updated Makefile for iOS 17 support --- Makefile | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 842568a78..352c5ea02 100644 --- a/Makefile +++ b/Makefile @@ -30,7 +30,12 @@ else else ifeq ($(PLATFORM),iOS) SDK?=iphonesimulator - DEVICE?=iPhone 8 + ifeq ($(shell expr $(OS) \>= 17.0), 1) + DEVICE?=iPhone 14 + else + DEVICE?=iPhone 8 + endif + DESTINATION?=platform=iOS Simulator,name=$(DEVICE),OS=$(OS) RELEASE_DIR=Release-iphoneos else From 1784ac45bb722be1c46eb62f0e6738bd56f97eea Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 16 Oct 2023 09:57:15 +0200 Subject: [PATCH 31/61] Fixed Unit tests for iOS 17 --- Gemfile | 2 +- Gemfile.lock | 23 ++++++++++--------- .../BSGInternalErrorReporterTests.m | 6 ++++- Tests/BugsnagTests/BugsnagStackframeTest.m | 4 ++++ 4 files changed, 22 insertions(+), 13 deletions(-) diff --git a/Gemfile b/Gemfile index 427043d09..95566ec28 100644 --- a/Gemfile +++ b/Gemfile @@ -4,7 +4,7 @@ gem 'cocoapods' # A reference to Maze Runner is only needed for running tests locally and if committed it must be # portable for CI, e.g. a specific release. However, leaving it commented out would mean quicker CI. -gem 'bugsnag-maze-runner', '~> 8.0' +gem 'bugsnag-maze-runner', '~> 8.8' # Use a specific branch #gem 'bugsnag-maze-runner', git: 'https://github.com/bugsnag/maze-runner', branch: 'master' diff --git a/Gemfile.lock b/Gemfile.lock index 1c00ea98a..d50a61457 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -21,9 +21,9 @@ GEM faye-websocket (~> 0.11.0) selenium-webdriver (~> 4.2, < 4.6) atomos (0.1.3) - bugsnag (6.25.2) + bugsnag (6.26.0) concurrent-ruby (~> 1.0) - bugsnag-maze-runner (8.1.4) + bugsnag-maze-runner (8.8.0) appium_lib (~> 12.0.0) appium_lib_core (~> 5.4.0) bugsnag (~> 6.24) @@ -122,7 +122,7 @@ GEM ethon (0.16.0) ffi (>= 1.15.0) eventmachine (1.2.7) - faye-websocket (0.11.2) + faye-websocket (0.11.3) eventmachine (>= 0.12.0) websocket-driver (>= 0.5.1) ffi (1.15.5) @@ -140,25 +140,25 @@ GEM regexp_parser (~> 2.0) simpleidn (~> 0.2) uri_template (~> 0.7) - mime-types (3.4.1) + mime-types (3.5.1) mime-types-data (~> 3.2015) - mime-types-data (3.2023.0218.1) + mime-types-data (3.2023.1003) minitest (5.18.1) molinillo (0.8.0) multi_test (0.1.2) nanaimo (0.3.0) nap (1.1.0) netrc (0.11.0) - nokogiri (1.15.3-x86_64-darwin) + nokogiri (1.15.4-x86_64-darwin) racc (~> 1.4) optimist (3.0.1) os (1.0.1) power_assert (2.0.3) public_suffix (4.0.7) racc (1.7.1) - rack (2.2.7) + rack (2.2.8) rake (12.3.3) - regexp_parser (2.8.1) + regexp_parser (2.8.2) rexml (3.2.5) ruby-macho (2.5.1) rubyzip (2.3.2) @@ -183,8 +183,8 @@ GEM unf_ext (0.0.8.2) uri_template (0.7.0) webrick (1.7.0) - websocket (1.2.9) - websocket-driver (0.7.5) + websocket (1.2.10) + websocket-driver (0.7.6) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) xcodeproj (1.22.0) @@ -198,9 +198,10 @@ GEM PLATFORMS x86_64-darwin-19 x86_64-darwin-20 + x86_64-darwin-21 DEPENDENCIES - bugsnag-maze-runner (~> 8.0) + bugsnag-maze-runner (~> 8.8) cocoapods BUNDLED WITH diff --git a/Tests/BugsnagTests/BSGInternalErrorReporterTests.m b/Tests/BugsnagTests/BSGInternalErrorReporterTests.m index 37aeea86e..0aa315b41 100644 --- a/Tests/BugsnagTests/BSGInternalErrorReporterTests.m +++ b/Tests/BugsnagTests/BSGInternalErrorReporterTests.m @@ -70,7 +70,11 @@ - (void)testEventWithException { BugsnagEvent *event = [reporter eventWithException:exception diagnostics:nil groupingHash:@"test"]; XCTAssertEqualObjects(event.errors[0].errorClass, @"NSRangeException"); - XCTAssertEqualObjects(event.errors[0].errorMessage, @"*** -[__NSArray0 objectAtIndex:]: index 0 beyond bounds for empty NSArray"); + if ([UIDevice.currentDevice.systemVersion doubleValue] >= 17.0) { + XCTAssertEqualObjects(event.errors[0].errorMessage, @"*** -[__NSArray0 objectAtIndex:]: index 0 beyond bounds for empty array"); + } else { + XCTAssertEqualObjects(event.errors[0].errorMessage, @"*** -[__NSArray0 objectAtIndex:]: index 0 beyond bounds for empty NSArray"); + } XCTAssertEqualObjects(event.groupingHash, @"test"); XCTAssertEqualObjects(event.threads, @[]); XCTAssertGreaterThan(event.errors[0].stacktrace.count, 0); diff --git a/Tests/BugsnagTests/BugsnagStackframeTest.m b/Tests/BugsnagTests/BugsnagStackframeTest.m index c647c2385..bb584fd86 100644 --- a/Tests/BugsnagTests/BugsnagStackframeTest.m +++ b/Tests/BugsnagTests/BugsnagStackframeTest.m @@ -253,6 +253,10 @@ - (void)testRealCallStackSymbols { // This frame is not in any known image return; } + if ([stackframe.method isEqualToString: @"start_sim"]) { + // This frame is part of the simulator environment + return; + } #endif XCTAssertNotNil(stackframe.machoUuid); XCTAssertNotNil(stackframe.machoVmAddress); From b8f5268b11a3b8248aa01796cc31e7cbf1e5d70f Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 16 Oct 2023 10:04:48 +0200 Subject: [PATCH 32/61] Fixed unit tests on macOS --- Tests/BugsnagTests/BSGInternalErrorReporterTests.m | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Tests/BugsnagTests/BSGInternalErrorReporterTests.m b/Tests/BugsnagTests/BSGInternalErrorReporterTests.m index 0aa315b41..0469b96bf 100644 --- a/Tests/BugsnagTests/BSGInternalErrorReporterTests.m +++ b/Tests/BugsnagTests/BSGInternalErrorReporterTests.m @@ -70,11 +70,16 @@ - (void)testEventWithException { BugsnagEvent *event = [reporter eventWithException:exception diagnostics:nil groupingHash:@"test"]; XCTAssertEqualObjects(event.errors[0].errorClass, @"NSRangeException"); +#if TARGET_OS_IOS if ([UIDevice.currentDevice.systemVersion doubleValue] >= 17.0) { XCTAssertEqualObjects(event.errors[0].errorMessage, @"*** -[__NSArray0 objectAtIndex:]: index 0 beyond bounds for empty array"); } else { XCTAssertEqualObjects(event.errors[0].errorMessage, @"*** -[__NSArray0 objectAtIndex:]: index 0 beyond bounds for empty NSArray"); } +#else + XCTAssertEqualObjects(event.errors[0].errorMessage, @"*** -[__NSArray0 objectAtIndex:]: index 0 beyond bounds for empty NSArray"); +#endif + XCTAssertEqualObjects(event.groupingHash, @"test"); XCTAssertEqualObjects(event.threads, @[]); XCTAssertGreaterThan(event.errors[0].stacktrace.count, 0); From 7ca774f17f0d67c09e3189579e80f684d962f0a4 Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 16 Oct 2023 16:09:41 +0200 Subject: [PATCH 33/61] Moved iOS 17 E2E tests to browserstack --- .buildkite/pipeline.yml | 86 ++++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 6a5bd9f73..044e01d62 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -293,7 +293,7 @@ steps: # # BitBar # - - label: ':bitbar: iOS 17 E2E tests batch 1' + - label: ':bitbar: iOS 16 E2E tests batch 1' depends_on: - cocoa_fixture timeout_in_minutes: 60 @@ -310,12 +310,11 @@ steps: command: - "--app=@/app/build/ipa_url_bb.txt" - "--farm=bb" - - "--device=IOS_17" + - "--device=IOS_16" - "--no-tunnel" - "--aws-public-ip" - "--fail-fast" - "--exclude=features/[e-z].*.feature$" - - "--order=random" concurrency: 25 concurrency_group: 'bitbar' concurrency_method: eager @@ -324,7 +323,7 @@ steps: - exit_status: -1 # Agent was lost limit: 2 - - label: ':bitbar: iOS 17 E2E tests batch 2' + - label: ':bitbar: iOS 16 E2E tests batch 2' depends_on: - cocoa_fixture timeout_in_minutes: 60 @@ -341,12 +340,11 @@ steps: command: - "--app=@/app/build/ipa_url_bb.txt" - "--farm=bb" - - "--device=IOS_17" + - "--device=IOS_16" - "--no-tunnel" - "--aws-public-ip" - "--fail-fast" - "--exclude=features/[a-d].*.feature$" - - "--order=random" concurrency: 25 concurrency_group: 'bitbar' concurrency_method: eager @@ -354,8 +352,8 @@ steps: automatic: - exit_status: -1 # Agent was lost limit: 2 - - - label: ':bitbar: iOS 16 E2E tests batch 1' + + - label: ':bitbar: iOS 15 barebone tests' depends_on: - cocoa_fixture timeout_in_minutes: 60 @@ -372,11 +370,11 @@ steps: command: - "--app=@/app/build/ipa_url_bb.txt" - "--farm=bb" - - "--device=IOS_16" + - "--device=IOS_15" - "--no-tunnel" - "--aws-public-ip" - "--fail-fast" - - "--exclude=features/[e-z].*.feature$" + - "features/barebone_tests.feature" concurrency: 25 concurrency_group: 'bitbar' concurrency_method: eager @@ -385,7 +383,7 @@ steps: - exit_status: -1 # Agent was lost limit: 2 - - label: ':bitbar: iOS 16 E2E tests batch 2' + - label: ':bitbar: iOS 14 barebone tests' depends_on: - cocoa_fixture timeout_in_minutes: 60 @@ -402,11 +400,11 @@ steps: command: - "--app=@/app/build/ipa_url_bb.txt" - "--farm=bb" - - "--device=IOS_16" + - "--device=IOS_14" - "--no-tunnel" - "--aws-public-ip" - "--fail-fast" - - "--exclude=features/[a-d].*.feature$" + - "features/barebone_tests.feature" concurrency: 25 concurrency_group: 'bitbar' concurrency_method: eager @@ -415,7 +413,7 @@ steps: - exit_status: -1 # Agent was lost limit: 2 - - label: ':bitbar: iOS 15 barebone tests' + - label: ':bitbar: iOS 13 barebone tests' depends_on: - cocoa_fixture timeout_in_minutes: 60 @@ -432,7 +430,7 @@ steps: command: - "--app=@/app/build/ipa_url_bb.txt" - "--farm=bb" - - "--device=IOS_15" + - "--device=IOS_13" - "--no-tunnel" - "--aws-public-ip" - "--fail-fast" @@ -445,7 +443,7 @@ steps: - exit_status: -1 # Agent was lost limit: 2 - - label: ':bitbar: iOS 14 barebone tests' + - label: ':bitbar: iOS 12 barebone tests' depends_on: - cocoa_fixture timeout_in_minutes: 60 @@ -462,7 +460,7 @@ steps: command: - "--app=@/app/build/ipa_url_bb.txt" - "--farm=bb" - - "--device=IOS_14" + - "--device=IOS_12" - "--no-tunnel" - "--aws-public-ip" - "--fail-fast" @@ -475,69 +473,71 @@ steps: - exit_status: -1 # Agent was lost limit: 2 - - label: ':bitbar: iOS 13 barebone tests' + # + # BrowserStack + # + - label: ':browserstack: iOS 17 E2E tests batch 1' depends_on: - cocoa_fixture timeout_in_minutes: 60 agents: queue: opensource plugins: - artifacts#v1.9.0: - download: "features/fixtures/ios/output/ipa_url_bb.txt" + artifacts#v1.5.0: + download: "features/fixtures/ios/output/ipa_url_bs.txt" upload: "maze_output/failed/**/*" - docker-compose#v4.7.0: - pull: cocoa-maze-runner-bitbar - run: cocoa-maze-runner-bitbar + docker-compose#v3.7.0: + pull: cocoa-maze-runner + run: cocoa-maze-runner service-ports: true command: - - "--app=@/app/build/ipa_url_bb.txt" - - "--farm=bb" - - "--device=IOS_13" + - "--app=@/app/build/ipa_url_bs.txt" + - "--farm=bs" + - "--device=IOS_17" - "--no-tunnel" - "--aws-public-ip" - "--fail-fast" - - "features/barebone_tests.feature" + - "--exclude=features/[e-z].*.feature$" + - "--order=random" concurrency: 25 - concurrency_group: 'bitbar' + concurrency_group: 'browserstack-app' concurrency_method: eager retry: automatic: - exit_status: -1 # Agent was lost limit: 2 - - label: ':bitbar: iOS 12 barebone tests' + - label: ':browserstack: iOS 17 E2E tests batch 2' depends_on: - cocoa_fixture timeout_in_minutes: 60 agents: queue: opensource plugins: - artifacts#v1.9.0: - download: "features/fixtures/ios/output/ipa_url_bb.txt" + artifacts#v1.5.0: + download: "features/fixtures/ios/output/ipa_url_bs.txt" upload: "maze_output/failed/**/*" - docker-compose#v4.7.0: - pull: cocoa-maze-runner-bitbar - run: cocoa-maze-runner-bitbar + docker-compose#v3.7.0: + pull: cocoa-maze-runner + run: cocoa-maze-runner service-ports: true command: - - "--app=@/app/build/ipa_url_bb.txt" - - "--farm=bb" - - "--device=IOS_12" + - "--app=@/app/build/ipa_url_bs.txt" + - "--farm=bs" + - "--device=IOS_17" - "--no-tunnel" - "--aws-public-ip" - "--fail-fast" - - "features/barebone_tests.feature" + - "--exclude=features/[a-d].*.feature$" + - "--order=random" concurrency: 25 - concurrency_group: 'bitbar' + concurrency_group: 'browserstack-app' concurrency_method: eager retry: automatic: - exit_status: -1 # Agent was lost limit: 2 - - # - # BrowserStack - # + - label: ':browserstack: iOS 11 barebone tests' skip: "https://smartbear.atlassian.net/browse/PLAT-11154" depends_on: From eaf7cf748033e300c8ea3cecc5b73d0ac0cd545b Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 16 Oct 2023 16:13:40 +0200 Subject: [PATCH 34/61] Fixes to pipeline.yml --- .buildkite/pipeline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 044e01d62..f32fe1823 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -442,7 +442,7 @@ steps: automatic: - exit_status: -1 # Agent was lost limit: 2 - + - label: ':bitbar: iOS 12 barebone tests' depends_on: - cocoa_fixture From ad4f9107f2aa851babfeed02758bad43ea14a3cb Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 16 Oct 2023 16:18:11 +0200 Subject: [PATCH 35/61] Fixed indentation in pipeline.yml --- .buildkite/pipeline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index f32fe1823..de9c8183d 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -476,7 +476,7 @@ steps: # # BrowserStack # - - label: ':browserstack: iOS 17 E2E tests batch 1' + - label: ':browserstack: iOS 17 E2E tests batch 1' depends_on: - cocoa_fixture timeout_in_minutes: 60 From 9e208c80a7c078f81e790f5abb8ffc1b17b17689 Mon Sep 17 00:00:00 2001 From: Josh Edney Date: Tue, 17 Oct 2023 09:08:46 +0100 Subject: [PATCH 36/61] adjust bs options for ios 17 --- .buildkite/pipeline.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index de9c8183d..4d60f0c01 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -90,7 +90,7 @@ steps: - ./scripts/run-unit-tests.sh PLATFORM=macOS artifact_paths: - logs/* - + - label: iOS 17 unit tests timeout_in_minutes: 10 agents: @@ -442,7 +442,7 @@ steps: automatic: - exit_status: -1 # Agent was lost limit: 2 - + - label: ':bitbar: iOS 12 barebone tests' depends_on: - cocoa_fixture @@ -491,14 +491,14 @@ steps: run: cocoa-maze-runner service-ports: true command: - - "--app=@/app/build/ipa_url_bs.txt" - - "--farm=bs" - - "--device=IOS_17" - - "--no-tunnel" - - "--aws-public-ip" - - "--fail-fast" - - "--exclude=features/[e-z].*.feature$" - - "--order=random" + - --app=@/app/build/ipa_url_bs.txt + - --farm=bs + - --device=IOS_17 + - --appium-version=1.18.0 + - --a11y-locator + - --fail-fast + - --exclude=features/[e-z].*.feature$ + - --order=random concurrency: 25 concurrency_group: 'browserstack-app' concurrency_method: eager @@ -537,7 +537,7 @@ steps: automatic: - exit_status: -1 # Agent was lost limit: 2 - + - label: ':browserstack: iOS 11 barebone tests' skip: "https://smartbear.atlassian.net/browse/PLAT-11154" depends_on: From 2e7a5109678a345cdf118fd86415b425af7e953f Mon Sep 17 00:00:00 2001 From: Josh Edney Date: Tue, 17 Oct 2023 09:20:03 +0100 Subject: [PATCH 37/61] adjust bs options for ios 17 --- .buildkite/pipeline.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 4d60f0c01..bd49aa3be 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -522,14 +522,14 @@ steps: run: cocoa-maze-runner service-ports: true command: - - "--app=@/app/build/ipa_url_bs.txt" - - "--farm=bs" - - "--device=IOS_17" - - "--no-tunnel" - - "--aws-public-ip" - - "--fail-fast" - - "--exclude=features/[a-d].*.feature$" - - "--order=random" + - --app=@/app/build/ipa_url_bs.txt + - --farm=bs + - --device=IOS_17 + - --appium-version=1.18.0 + - --a11y-locator + - --fail-fast + - --exclude=features/[e-z].*.feature$ + - --order=random concurrency: 25 concurrency_group: 'browserstack-app' concurrency_method: eager From 14ca84f1eaa19e84c945f116bc2ac85904456df3 Mon Sep 17 00:00:00 2001 From: Josh Edney Date: Tue, 17 Oct 2023 09:30:57 +0100 Subject: [PATCH 38/61] update ios 17 batch 2 settings --- .buildkite/pipeline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index bd49aa3be..2e7947f21 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -528,7 +528,7 @@ steps: - --appium-version=1.18.0 - --a11y-locator - --fail-fast - - --exclude=features/[e-z].*.feature$ + - --exclude=features/[a-d].*.feature$ - --order=random concurrency: 25 concurrency_group: 'browserstack-app' From 43cd2ec79690d67aa57713bf34c350dd62648549 Mon Sep 17 00:00:00 2001 From: Josh Edney Date: Tue, 17 Oct 2023 11:18:01 +0100 Subject: [PATCH 39/61] ios 17 testing --- features/delivery.feature | 26 +++++++++++++++++++++++++- features/support/env.rb | 8 ++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/features/delivery.feature b/features/delivery.feature index 6855ffa90..061fa97dd 100644 --- a/features/delivery.feature +++ b/features/delivery.feature @@ -46,7 +46,7 @@ Feature: Delivery of errors And I configure Bugsnag for "OldHandledErrorScenario" And I wait to receive an error And I wait for the fixture to process the response - # The error should now have been deleted + # The error should now have been deleted And I kill and relaunch the app And I clear the error queue And I configure Bugsnag for "OldHandledErrorScenario" @@ -157,6 +157,7 @@ Feature: Delivery of errors And the event "usage.system.stringCharsTruncated" is not null And the event "usage.system.stringsTruncated" is not null + @skip_ios_17 Scenario Outline: Attempt Delivery On Crash When I set the app to "" mode And I run "AttemptDeliveryOnCrashScenario" @@ -178,3 +179,26 @@ Feature: Delivery of errors | NSException | nsexception | NSRangeException | *** -[__NSArray0 objectAtIndex:]: index 42 beyond bounds for empty NSArray | | SwiftFatalError | mach | Fatal error | Unexpectedly found nil while unwrapping an Optional value | | BadAccess | mach | EXC_BAD_ACCESS | Attempted to dereference garbage pointer 0x20. | + + @skip_below_ios_17 + Scenario Outline: Attempt Delivery On Crash iOS 17 + When I set the app to "" mode + And I run "AttemptDeliveryOnCrashScenario" + And I wait to receive an error + Then the error is valid for the error reporting API + And the event "context" equals "OnSendError" + And the exception "errorClass" equals "" + And the exception "message" equals "" + And the event "metaData.error.type" equals "" + And the event "unhandled" is true + And the event "usage.config.attemptDeliveryOnCrash" is true + And I discard the oldest error + And I relaunch the app after a crash + And I configure Bugsnag for "AttemptDeliveryOnCrashScenario" + And I wait to receive 2 sessions + Then I should receive no error + Examples: + | scenario_mode | error_type | error_class | message | + | NSException | nsexception | NSRangeException | *** -[__NSArray0 objectAtIndex:]: index 42 beyond bounds for empty array | + | SwiftFatalError | mach | Fatal error | Unexpectedly found nil while unwrapping an Optional value | + | BadAccess | mach | EXC_BAD_ACCESS | Attempted to dereference garbage pointer 0x20. | diff --git a/features/support/env.rb b/features/support/env.rb index e4e4bd9d5..72b2c6012 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -77,6 +77,10 @@ def skip_between(os, version_lo, version_hi) skip_between('ios', 16, 16.99) end +Before('@skip_ios_17') do |_scenario| + skip_between('ios', 17, 17.99) +end + Before('@skip_below_ios_11') do |_scenario| skip_below('ios', 11) end @@ -85,6 +89,10 @@ def skip_between(os, version_lo, version_hi) skip_below('ios', 13) end +Before('@skip_below_ios_13') do |_scenario| + skip_below('ios', 17) +end + Before('@skip_below_macos_10_15') do |_scenario| skip_below('macos', 10.15) end From 07686b69bc8532abf9df9e7a20ad5b7f8a773f0b Mon Sep 17 00:00:00 2001 From: Robert Date: Tue, 17 Oct 2023 12:46:08 +0200 Subject: [PATCH 40/61] Added a fix for barebone tests --- features/barebone_tests.feature | 1 + 1 file changed, 1 insertion(+) diff --git a/features/barebone_tests.feature b/features/barebone_tests.feature index 497eea7c7..8ded437b7 100644 --- a/features/barebone_tests.feature +++ b/features/barebone_tests.feature @@ -244,6 +244,7 @@ Feature: Barebone tests @skip_macos @skip_ios_16 # https://smartbear.atlassian.net/browse/PLAT-9724 + @skip_ios_17 Scenario: Barebone test: Out Of Memory When I run "OOMScenario" From b0a18ba584b6d85311081716da95fbf9a00836d4 Mon Sep 17 00:00:00 2001 From: Karl Stenerud Date: Tue, 17 Oct 2023 14:09:41 +0200 Subject: [PATCH 41/61] macos still uses NSArray, not array. --- features/delivery.feature | 1 + 1 file changed, 1 insertion(+) diff --git a/features/delivery.feature b/features/delivery.feature index 061fa97dd..8482cbf4e 100644 --- a/features/delivery.feature +++ b/features/delivery.feature @@ -181,6 +181,7 @@ Feature: Delivery of errors | BadAccess | mach | EXC_BAD_ACCESS | Attempted to dereference garbage pointer 0x20. | @skip_below_ios_17 + @skip_macos Scenario Outline: Attempt Delivery On Crash iOS 17 When I set the app to "" mode And I run "AttemptDeliveryOnCrashScenario" From 9dc78a56ebfb2eb382aedaf30b5fcc3d022861b9 Mon Sep 17 00:00:00 2001 From: Josh Edney Date: Fri, 20 Oct 2023 11:04:27 +0100 Subject: [PATCH 42/61] set xcode version to 14.3 --- .buildkite/pipeline.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 2e7947f21..635ce3afc 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -12,6 +12,8 @@ steps: timeout_in_minutes: 30 agents: queue: macos-13-arm + env: + DEVELOPER_DIR: /Applications/Xcode14.3.app artifact_paths: - features/fixtures/ios/output/iOSTestApp.ipa - features/fixtures/macos/output/macOSTestApp.zip From 6c72cd90a45870c9db3f6fbf38771fa824bc7203 Mon Sep 17 00:00:00 2001 From: Steve Kirkland-Walton Date: Tue, 7 Nov 2023 09:44:31 +0000 Subject: [PATCH 43/61] Use Appium 1.21.0, not 1.22.0 to prevent app hang scenario problems [full ci] --- .buildkite/pipeline.full.yml | 8 ++++---- .buildkite/pipeline.yml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.buildkite/pipeline.full.yml b/.buildkite/pipeline.full.yml index 37d6e60f4..d4eea6b16 100644 --- a/.buildkite/pipeline.full.yml +++ b/.buildkite/pipeline.full.yml @@ -267,7 +267,7 @@ steps: - "--app=@build/ipa_url_bs.txt" - "--farm=bs" - "--device=IOS_15" - - "--appium-version=1.22.0" + - "--appium-version=1.21.0" - "features/app_hangs.feature" concurrency: 5 concurrency_group: 'browserstack-app' @@ -295,7 +295,7 @@ steps: - "--app=@build/ipa_url_bs.txt" - "--farm=bs" - "--device=IOS_14" - - "--appium-version=1.22.0" + - "--appium-version=1.21.0" - "features/app_hangs.feature" concurrency: 5 concurrency_group: 'browserstack-app' @@ -323,7 +323,7 @@ steps: - "--app=@build/ipa_url_bs.txt" - "--farm=bs" - "--device=IOS_13" - - "--appium-version=1.22.0" + - "--appium-version=1.21.0" - "features/app_hangs.feature" concurrency: 5 concurrency_group: 'browserstack-app' @@ -351,7 +351,7 @@ steps: - "--app=@build/ipa_url_bs.txt" - "--farm=bs" - "--device=IOS_12" - - "--appium-version=1.22.0" + - "--appium-version=1.21.0" - "features/app_hangs.feature" concurrency: 5 concurrency_group: 'browserstack-app' diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 93faa1f1c..21708f4c4 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -364,7 +364,7 @@ steps: - "--app=@build/ipa_url_bs.txt" - "--farm=bs" - "--device=IOS_16" - - "--appium-version=1.22.0" + - "--appium-version=1.21.0" - "features/app_hangs.feature" concurrency: 5 concurrency_group: 'browserstack-app' From 9eb3bf6ae6f9ba4d074fe95a1f128003199ddf98 Mon Sep 17 00:00:00 2001 From: Karl Stenerud Date: Tue, 7 Nov 2023 16:05:18 +0100 Subject: [PATCH 44/61] Use exceptions whose messages we control in tests --- .../BugsnagTests/BSGInternalErrorReporterTests.m | 14 ++++---------- features/barebone_tests.feature | 8 ++++---- features/delivery.feature | 16 ++++++++-------- .../AttemptDeliveryOnCrashScenario.swift | 9 ++++++++- .../scenarios/BareboneTestHandledScenario.swift | 2 +- .../BareboneTestUnhandledErrorScenario.swift | 2 +- .../shared/scenarios/RecrashScenarios.mm | 5 ++++- 7 files changed, 30 insertions(+), 26 deletions(-) diff --git a/Tests/BugsnagTests/BSGInternalErrorReporterTests.m b/Tests/BugsnagTests/BSGInternalErrorReporterTests.m index 0469b96bf..2948d5154 100644 --- a/Tests/BugsnagTests/BSGInternalErrorReporterTests.m +++ b/Tests/BugsnagTests/BSGInternalErrorReporterTests.m @@ -63,22 +63,16 @@ - (void)testEventWithException { NSException *exception = nil; @try { - NSLog(@"%@", @[][0]); + [[NSException exceptionWithName:NSRangeException + reason:@"Something is out of range" + userInfo:nil] raise]; } @catch (NSException *e) { exception = e; } BugsnagEvent *event = [reporter eventWithException:exception diagnostics:nil groupingHash:@"test"]; XCTAssertEqualObjects(event.errors[0].errorClass, @"NSRangeException"); -#if TARGET_OS_IOS - if ([UIDevice.currentDevice.systemVersion doubleValue] >= 17.0) { - XCTAssertEqualObjects(event.errors[0].errorMessage, @"*** -[__NSArray0 objectAtIndex:]: index 0 beyond bounds for empty array"); - } else { - XCTAssertEqualObjects(event.errors[0].errorMessage, @"*** -[__NSArray0 objectAtIndex:]: index 0 beyond bounds for empty NSArray"); - } -#else - XCTAssertEqualObjects(event.errors[0].errorMessage, @"*** -[__NSArray0 objectAtIndex:]: index 0 beyond bounds for empty NSArray"); -#endif + XCTAssertEqualObjects(event.errors[0].errorMessage, @"Something is out of range"); XCTAssertEqualObjects(event.groupingHash, @"test"); XCTAssertEqualObjects(event.threads, @[]); diff --git a/features/barebone_tests.feature b/features/barebone_tests.feature index 8ded437b7..691eeb534 100644 --- a/features/barebone_tests.feature +++ b/features/barebone_tests.feature @@ -68,7 +68,7 @@ Feature: Barebone tests And the event "metaData.error.nsexception.userInfo.date" equals "2001-01-01 00:00:00 +0000" And the event "metaData.error.nsexception.userInfo.NSUnderlyingError" matches "Error Domain=ErrorDomain Code=0" And the event "metaData.error.nsexception.userInfo.scenario" equals "BareboneTestHandledScenario" - And the event "metaData.error.reason" equals "-[__NSSingleObjectArrayI objectAtIndex:]: index 1 beyond bounds [0 .. 0]" + And the event "metaData.error.reason" equals "Something is out of range" And the event "metaData.error.type" equals "nsexception" And the event "metaData.usage" is null And the event "metaData.user.email" is null @@ -103,7 +103,7 @@ Feature: Barebone tests | notify | rangeException | And the event does not contain the feature flag "nope" And the exception "errorClass" equals "NSRangeException" - And the exception "message" equals "-[__NSSingleObjectArrayI objectAtIndex:]: index 1 beyond bounds [0 .. 0]" + And the exception "message" equals "Something is out of range" And the exception "type" equals "cocoa" And the error payload field "events.0.app.dsymUUIDs" is a non-empty array And the error payload field "events.0.app.duration" is a number @@ -199,7 +199,7 @@ Feature: Barebone tests And the event "metaData.error.nsexception.userInfo.date" equals "2001-01-01 00:00:00 +0000" And the event "metaData.error.nsexception.userInfo.NSUnderlyingError" matches "Error Domain=ErrorDomain Code=0" And the event "metaData.error.nsexception.userInfo.scenario" equals "BareboneTestUnhandledErrorScenario" - And the event "metaData.error.reason" equals "*** -[__NSArray0 objectAtIndex:]: index 42 beyond bounds for empty NSArray" + And the event "metaData.error.reason" equals "Something is out of range" And the event "metaData.error.type" equals "nsexception" And the event "metaData.usage" is null And the event "metaData.user.email" is null @@ -227,7 +227,7 @@ Feature: Barebone tests | featureFlag | variant | | Testing | | And the exception "errorClass" equals "NSRangeException" - And the exception "message" equals "*** -[__NSArray0 objectAtIndex:]: index 42 beyond bounds for empty NSArray" + And the exception "message" equals "Something is out of range" And the exception "type" equals "cocoa" And the error payload field "events.0.app.dsymUUIDs" is a non-empty array And the error payload field "events.0.app.duration" is a number diff --git a/features/delivery.feature b/features/delivery.feature index 8482cbf4e..08af636e5 100644 --- a/features/delivery.feature +++ b/features/delivery.feature @@ -175,10 +175,10 @@ Feature: Delivery of errors And I wait to receive 2 sessions Then I should receive no error Examples: - | scenario_mode | error_type | error_class | message | - | NSException | nsexception | NSRangeException | *** -[__NSArray0 objectAtIndex:]: index 42 beyond bounds for empty NSArray | - | SwiftFatalError | mach | Fatal error | Unexpectedly found nil while unwrapping an Optional value | - | BadAccess | mach | EXC_BAD_ACCESS | Attempted to dereference garbage pointer 0x20. | + | scenario_mode | error_type | error_class | message | + | NSException | nsexception | NSRangeException | Something is out of range | + | SwiftFatalError | mach | Fatal error | Unexpectedly found nil while unwrapping an Optional value | + | BadAccess | mach | EXC_BAD_ACCESS | Attempted to dereference garbage pointer 0x20. | @skip_below_ios_17 @skip_macos @@ -199,7 +199,7 @@ Feature: Delivery of errors And I wait to receive 2 sessions Then I should receive no error Examples: - | scenario_mode | error_type | error_class | message | - | NSException | nsexception | NSRangeException | *** -[__NSArray0 objectAtIndex:]: index 42 beyond bounds for empty array | - | SwiftFatalError | mach | Fatal error | Unexpectedly found nil while unwrapping an Optional value | - | BadAccess | mach | EXC_BAD_ACCESS | Attempted to dereference garbage pointer 0x20. | + | scenario_mode | error_type | error_class | message | + | NSException | nsexception | NSRangeException | Something is out of range | + | SwiftFatalError | mach | Fatal error | Unexpectedly found nil while unwrapping an Optional value | + | BadAccess | mach | EXC_BAD_ACCESS | Attempted to dereference garbage pointer 0x20. | diff --git a/features/fixtures/shared/scenarios/AttemptDeliveryOnCrashScenario.swift b/features/fixtures/shared/scenarios/AttemptDeliveryOnCrashScenario.swift index c3ccf1ae4..5dd2f1b03 100644 --- a/features/fixtures/shared/scenarios/AttemptDeliveryOnCrashScenario.swift +++ b/features/fixtures/shared/scenarios/AttemptDeliveryOnCrashScenario.swift @@ -28,7 +28,14 @@ class AttemptDeliveryOnCrashScenario: Scenario { break case "NSException": - NSArray().object(at: 42) + NSException( + name: .rangeException, + reason: "Something is out of range", + userInfo: [ + "date": Date(timeIntervalSinceReferenceDate: 0), + "scenario": "BareboneTestUnhandledErrorScenario", + NSUnderlyingErrorKey: NSError(domain: "ErrorDomain", code: 0)]) + .raise() break case "SwiftFatalError": diff --git a/features/fixtures/shared/scenarios/BareboneTestHandledScenario.swift b/features/fixtures/shared/scenarios/BareboneTestHandledScenario.swift index 763a83822..ae7e85198 100644 --- a/features/fixtures/shared/scenarios/BareboneTestHandledScenario.swift +++ b/features/fixtures/shared/scenarios/BareboneTestHandledScenario.swift @@ -89,7 +89,7 @@ class BareboneTestHandledScenario: Scenario { """, key: "shouldBeTruncated", section: "Other") Bugsnag.notify(NSException(name: .rangeException, - reason: "-[__NSSingleObjectArrayI objectAtIndex:]: index 1 beyond bounds [0 .. 0]", + reason: "Something is out of range", userInfo: ["date": Date(timeIntervalSinceReferenceDate: 0), "scenario": "BareboneTestHandledScenario", NSUnderlyingErrorKey: NSError(domain: "ErrorDomain", code: 0)])) { diff --git a/features/fixtures/shared/scenarios/BareboneTestUnhandledErrorScenario.swift b/features/fixtures/shared/scenarios/BareboneTestUnhandledErrorScenario.swift index 1c3c4d5f3..689505e39 100644 --- a/features/fixtures/shared/scenarios/BareboneTestUnhandledErrorScenario.swift +++ b/features/fixtures/shared/scenarios/BareboneTestUnhandledErrorScenario.swift @@ -33,7 +33,7 @@ class BareboneTestUnhandledErrorScenario: Scenario { // Manually constructing an exception to verify handling of userInfo NSException( name: .rangeException, - reason: "*** -[__NSArray0 objectAtIndex:]: index 42 beyond bounds for empty NSArray", + reason: "Something is out of range", userInfo: [ "date": Date(timeIntervalSinceReferenceDate: 0), "scenario": "BareboneTestUnhandledErrorScenario", diff --git a/features/fixtures/shared/scenarios/RecrashScenarios.mm b/features/fixtures/shared/scenarios/RecrashScenarios.mm index 784bf81a1..da496aa9b 100644 --- a/features/fixtures/shared/scenarios/RecrashScenarios.mm +++ b/features/fixtures/shared/scenarios/RecrashScenarios.mm @@ -12,7 +12,10 @@ #import #define THROW_CPP_EXCEPTION throw std::runtime_error("err") -#define THROW_OBJC_EXCEPTION [@[] objectAtIndex:42] +#define THROW_OBJC_EXCEPTION \ + [[NSException exceptionWithName:NSRangeException \ + reason:@"Something is out of range" \ + userInfo:nil] raise] #define CAUSE_MACH_EXCEPTION volatile int *ptr = NULL; *ptr = 42 #define RAISE_SIGNAL abort() From 0430c7980087e2b8d7ef98e5f728b5c106400a47 Mon Sep 17 00:00:00 2001 From: Tom Longridge Date: Tue, 24 Oct 2023 10:43:32 +0100 Subject: [PATCH 45/61] build: pushing watchOS unit tests to later Xcode version --- .buildkite/pipeline.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 62ec64a6c..3a2437d6a 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -196,8 +196,6 @@ steps: timeout_in_minutes: 10 agents: queue: opensource-arm-mac-cocoa-12 - env: - DEVELOPER_DIR: /Applications/Xcode13.4.app commands: - ./scripts/run-unit-tests.sh PLATFORM=watchOS OS=8.3 artifact_paths: From 187597281507c7eaf018ab622e22a2d991b4e23c Mon Sep 17 00:00:00 2001 From: Josh Edney Date: Wed, 25 Oct 2023 10:11:55 +0100 Subject: [PATCH 46/61] move watchos tests to xcode 14 --- .buildkite/pipeline.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 3a2437d6a..7775590b8 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -196,6 +196,8 @@ steps: timeout_in_minutes: 10 agents: queue: opensource-arm-mac-cocoa-12 + env: + DEVELOPER_DIR: /Applications/Xcode14.0.app commands: - ./scripts/run-unit-tests.sh PLATFORM=watchOS OS=8.3 artifact_paths: @@ -206,7 +208,7 @@ steps: agents: queue: opensource-arm-mac-cocoa-12 env: - DEVELOPER_DIR: /Applications/Xcode13.4.app + DEVELOPER_DIR: /Applications/Xcode14.0.app commands: - ./scripts/run-unit-tests.sh PLATFORM=watchOS OS=7.4 artifact_paths: From 78c8d4faa410acd9f20b8f58b6d9ee05e58718f8 Mon Sep 17 00:00:00 2001 From: Josh Edney Date: Wed, 25 Oct 2023 11:04:43 +0100 Subject: [PATCH 47/61] use watchsimulator9.0 for the ci tests --- .buildkite/pipeline.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 7775590b8..4bcf9e638 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -199,7 +199,7 @@ steps: env: DEVELOPER_DIR: /Applications/Xcode14.0.app commands: - - ./scripts/run-unit-tests.sh PLATFORM=watchOS OS=8.3 + - ./scripts/run-unit-tests.sh PLATFORM=watchOS OS=8.3 SDK=watchsimulator9.0 artifact_paths: - logs/* @@ -210,7 +210,7 @@ steps: env: DEVELOPER_DIR: /Applications/Xcode14.0.app commands: - - ./scripts/run-unit-tests.sh PLATFORM=watchOS OS=7.4 + - ./scripts/run-unit-tests.sh PLATFORM=watchOS OS=7.4 SDK=watchsimulator9.0 artifact_paths: - logs/* From f0fb054957c42cec436dd56877303a11877a06e3 Mon Sep 17 00:00:00 2001 From: Josh Edney Date: Wed, 25 Oct 2023 11:20:19 +0100 Subject: [PATCH 48/61] increase timeout for watchos steps --- .buildkite/pipeline.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 4bcf9e638..900e50617 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -193,7 +193,7 @@ steps: - logs/* - label: watchOS 8 unit tests - timeout_in_minutes: 10 + timeout_in_minutes: 25 agents: queue: opensource-arm-mac-cocoa-12 env: @@ -204,7 +204,7 @@ steps: - logs/* - label: watchOS 7 unit tests - timeout_in_minutes: 10 + timeout_in_minutes: 25 agents: queue: opensource-arm-mac-cocoa-12 env: From 190d4e7aa38c6e84635a1c936d827a8b0cf8934e Mon Sep 17 00:00:00 2001 From: Josh Edney Date: Wed, 25 Oct 2023 12:15:25 +0100 Subject: [PATCH 49/61] increase timeout for watchos steps --- .buildkite/pipeline.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 900e50617..ead95af6d 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -193,7 +193,7 @@ steps: - logs/* - label: watchOS 8 unit tests - timeout_in_minutes: 25 + timeout_in_minutes: 60 agents: queue: opensource-arm-mac-cocoa-12 env: @@ -204,7 +204,7 @@ steps: - logs/* - label: watchOS 7 unit tests - timeout_in_minutes: 25 + timeout_in_minutes: 60 agents: queue: opensource-arm-mac-cocoa-12 env: From 11cfa37fb5a9c97db0ce7529511128f03db1c785 Mon Sep 17 00:00:00 2001 From: Karl Stenerud Date: Tue, 7 Nov 2023 13:23:34 +0100 Subject: [PATCH 50/61] Also run the test setup on watchos. --- Tests/KSCrashTests/KSCrashState_Tests.m | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Tests/KSCrashTests/KSCrashState_Tests.m b/Tests/KSCrashTests/KSCrashState_Tests.m index cf5e401f8..1c8dbe94b 100755 --- a/Tests/KSCrashTests/KSCrashState_Tests.m +++ b/Tests/KSCrashTests/KSCrashState_Tests.m @@ -38,11 +38,10 @@ @interface bsg_kscrashstate_Tests : FileBasedTestCase @implementation bsg_kscrashstate_Tests -#if TARGET_OS_OSX || TARGET_OS_TV // Not needed on iOS because there the tests are injected into a host app +#if TARGET_OS_OSX || TARGET_OS_TV || TARGET_OS_WATCH // Not needed on iOS because there the tests are injected into a host app - (void)setUp { - struct BSGRunContext *oldContext = bsg_runContext; static struct BSGRunContext context = {0}; context.isForeground = YES; // These tests assume applicationState == .active From 2769b604e7554bba9f0948d9b7f36bed6bff9847 Mon Sep 17 00:00:00 2001 From: Karl Stenerud Date: Thu, 9 Nov 2023 15:49:50 +0100 Subject: [PATCH 51/61] Make sure the mach images list is initialized before use. --- Bugsnag/Helpers/BSGRunContext.m | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Bugsnag/Helpers/BSGRunContext.m b/Bugsnag/Helpers/BSGRunContext.m index 5e9f7a5bd..d48bc6b85 100644 --- a/Bugsnag/Helpers/BSGRunContext.m +++ b/Bugsnag/Helpers/BSGRunContext.m @@ -63,7 +63,10 @@ static void InitRunContext(void) { } bsg_runContext->bootTime = GetBootTime(); - + + // Make sure the images list is populated. + bsg_mach_headers_initialize(); + BSG_Mach_Header_Info *image = bsg_mach_headers_get_main_image(); if (image && image->uuid) { uuid_copy(bsg_runContext->machoUUID, image->uuid); From 1db81a4e35d3d55b02ca24651bea37ee25f69342 Mon Sep 17 00:00:00 2001 From: Gustavo Ambrozio Date: Thu, 14 Sep 2023 12:02:39 -1000 Subject: [PATCH 52/61] Fixes issue when using Bugsnag on a WatchOS app The code was trying to access an extension but on latest WatchOS we can have a standalone app. --- Bugsnag/Helpers/BSGRunContext.m | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/Bugsnag/Helpers/BSGRunContext.m b/Bugsnag/Helpers/BSGRunContext.m index d48bc6b85..e06e6b85a 100644 --- a/Bugsnag/Helpers/BSGRunContext.m +++ b/Bugsnag/Helpers/BSGRunContext.m @@ -112,8 +112,13 @@ static bool GetIsActive(void) { #endif #if TARGET_OS_WATCH - WKExtension *ext = [WKExtension sharedExtension]; - return ext && ext.applicationState == WKApplicationStateActive; + if ([BSG_KSSystemInfo isRunningInAppExtension]) { + WKExtension *ext = [WKExtension sharedExtension]; + return ext && ext.applicationState == WKApplicationStateActive; + } else { + WKApplication *app = [WKApplication sharedApplication]; + return app && app.applicationState == WKApplicationStateActive; + } #endif } @@ -170,8 +175,13 @@ static bool GetIsForeground(void) { #endif #if TARGET_OS_WATCH - WKExtension *ext = [WKExtension sharedExtension]; - return ext && ext.applicationState != WKApplicationStateBackground; + if ([BSG_KSSystemInfo isRunningInAppExtension]) { + WKExtension *ext = [WKExtension sharedExtension]; + return ext && ext.applicationState != WKApplicationStateBackground; + } else { + WKApplication *app = [WKApplication sharedApplication]; + return app && app.applicationState == WKApplicationStateBackground; + } #endif } From 214457261d45cbad0eff80e4813c40ed99b7ce0e Mon Sep 17 00:00:00 2001 From: Karl Stenerud Date: Thu, 12 Oct 2023 09:47:08 +0200 Subject: [PATCH 53/61] WKApplication is only available on WatchOS 7+ --- Bugsnag/Helpers/BSGRunContext.m | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Bugsnag/Helpers/BSGRunContext.m b/Bugsnag/Helpers/BSGRunContext.m index e06e6b85a..c7ce2a57b 100644 --- a/Bugsnag/Helpers/BSGRunContext.m +++ b/Bugsnag/Helpers/BSGRunContext.m @@ -115,9 +115,11 @@ static bool GetIsActive(void) { if ([BSG_KSSystemInfo isRunningInAppExtension]) { WKExtension *ext = [WKExtension sharedExtension]; return ext && ext.applicationState == WKApplicationStateActive; - } else { + } else if (@available(watchOS 7.0, *)) { WKApplication *app = [WKApplication sharedApplication]; return app && app.applicationState == WKApplicationStateActive; + } else { + return true; } #endif } @@ -178,9 +180,11 @@ static bool GetIsForeground(void) { if ([BSG_KSSystemInfo isRunningInAppExtension]) { WKExtension *ext = [WKExtension sharedExtension]; return ext && ext.applicationState != WKApplicationStateBackground; - } else { + } else if (@available(watchOS 7.0, *)) { WKApplication *app = [WKApplication sharedApplication]; return app && app.applicationState == WKApplicationStateBackground; + } else { + return true; } #endif } From bbe5cfcd5534572a58453b37c4f1a792f0d6c5ed Mon Sep 17 00:00:00 2001 From: Karl Stenerud Date: Thu, 9 Nov 2023 14:19:56 +0100 Subject: [PATCH 54/61] Override the main bundle in watchos unit tests to add an NSExtension field to the bundle dictionary. --- Bugsnag.xcodeproj/project.pbxproj | 28 +++++- .../BugsnagNetworkRequestPluginTests.m | 1 + Tests/BugsnagTests/BSGAppKitTests.m | 4 +- Tests/BugsnagTests/BSGClientObserverTests.m | 5 +- .../BSGConfigurationBuilderTests.m | 4 +- Tests/BugsnagTests/BSGConnectivityTest.m | 4 +- Tests/BugsnagTests/BSGDefinesTests.m | 4 +- ...SGEventUploadKSCrashReportOperationTests.m | 5 +- Tests/BugsnagTests/BSGFeatureFlagStoreTests.m | 6 +- .../BSGInternalErrorReporterTests.m | 5 +- .../BugsnagTests/BSGJSONSerializationTests.m | 4 +- .../BugsnagTests/BSGNetworkBreadcrumbTests.m | 6 +- .../BSGNotificationBreadcrumbsTests.m | 5 +- Tests/BugsnagTests/BSGOutOfMemoryTests.m | 4 +- Tests/BugsnagTests/BSGRunContextTests.m | 5 +- Tests/BugsnagTests/BSGSerializationTests.m | 4 +- .../BSGStorageMigratorV0V1Tests.m | 6 +- Tests/BugsnagTests/BSGTelemetryTests.m | 4 +- Tests/BugsnagTests/BSGTestCase.h | 17 ++++ Tests/BugsnagTests/BSGTestCase.mm | 91 +++++++++++++++++++ Tests/BugsnagTests/BSGUtilsTests.m | 4 +- Tests/BugsnagTests/BugsnagApiClientTest.m | 5 +- Tests/BugsnagTests/BugsnagApiValidationTest.m | 6 +- Tests/BugsnagTests/BugsnagAppTest.m | 4 +- Tests/BugsnagTests/BugsnagBreadcrumbsTest.m | 5 +- Tests/BugsnagTests/BugsnagClientMirrorTest.m | 6 +- .../BugsnagClientPayloadInfoTest.m | 5 +- Tests/BugsnagTests/BugsnagClientTests.m | 5 +- Tests/BugsnagTests/BugsnagCollectionsTests.m | 5 +- .../BugsnagTests/BugsnagConfigurationTests.m | 4 +- Tests/BugsnagTests/BugsnagDeviceTest.m | 4 +- .../BugsnagEnabledBreadcrumbTest.m | 4 +- Tests/BugsnagTests/BugsnagErrorTest.m | 5 +- .../BugsnagEventFromKSCrashReportTest.m | 4 +- .../BugsnagEventPersistLoadTest.m | 4 +- Tests/BugsnagTests/BugsnagEventTests.m | 5 +- Tests/BugsnagTests/BugsnagHandledStateTest.m | 5 +- .../BugsnagMetadataRedactionTest.m | 4 +- Tests/BugsnagTests/BugsnagMetadataTests.m | 6 +- Tests/BugsnagTests/BugsnagNotifierTest.m | 6 +- Tests/BugsnagTests/BugsnagOnBreadcrumbTest.m | 4 +- Tests/BugsnagTests/BugsnagOnCrashTest.m | 4 +- Tests/BugsnagTests/BugsnagPluginTest.m | 4 +- Tests/BugsnagTests/BugsnagSessionTest.m | 5 +- .../BugsnagSessionTrackerStopTest.m | 4 +- .../BugsnagTests/BugsnagSessionTrackerTest.m | 4 +- Tests/BugsnagTests/BugsnagStackframeTest.m | 5 +- Tests/BugsnagTests/BugsnagStacktraceTest.m | 5 +- .../BugsnagSwiftConfigurationTests.swift | 3 +- .../BugsnagSwiftPublicAPITests.swift | 4 +- Tests/BugsnagTests/BugsnagSwiftTests.swift | 4 +- Tests/BugsnagTests/BugsnagTests.m | 4 +- .../BugsnagThreadSerializationTest.m | 4 +- Tests/BugsnagTests/BugsnagThreadTests.m | 6 +- Tests/BugsnagTests/BugsnagUserTest.m | 4 +- Tests/BugsnagTests/ClientApiValidationTest.m | 6 +- .../ConfigurationApiValidationTest.m | 6 +- Tests/BugsnagTests/EventApiValidationTest.m | 5 +- Tests/BugsnagTests/FileBasedTest.h | 4 +- Tests/BugsnagTests/FileBasedTest.m | 1 + Tests/BugsnagTests/Swizzle.h | 36 ++++++++ Tests/BugsnagTests/Swizzle.mm | 68 ++++++++++++++ Tests/BugsnagTests/Tests-Bridging-Header.h | 1 + Tests/KSCrashTests/BSG_KSFileTests.m | 1 + Tests/KSCrashTests/BSG_KSMachHeadersTests.m | 1 + Tests/KSCrashTests/KSCrashNames_Test.m | 8 -- Tests/KSCrashTests/KSCrashSentry_Tests.m | 1 + 67 files changed, 387 insertions(+), 123 deletions(-) create mode 100644 Tests/BugsnagTests/BSGTestCase.h create mode 100644 Tests/BugsnagTests/BSGTestCase.mm create mode 100644 Tests/BugsnagTests/Swizzle.h create mode 100644 Tests/BugsnagTests/Swizzle.mm diff --git a/Bugsnag.xcodeproj/project.pbxproj b/Bugsnag.xcodeproj/project.pbxproj index d1843abe5..2907142e6 100644 --- a/Bugsnag.xcodeproj/project.pbxproj +++ b/Bugsnag.xcodeproj/project.pbxproj @@ -721,6 +721,14 @@ 01FF490728BF8B7B001F817B /* BugsnagInternals.h in Headers */ = {isa = PBXBuildFile; fileRef = 01FF490528BF8B7B001F817B /* BugsnagInternals.h */; }; 01FF490828BF8B7B001F817B /* BugsnagInternals.h in Headers */ = {isa = PBXBuildFile; fileRef = 01FF490528BF8B7B001F817B /* BugsnagInternals.h */; }; 01FF490928BF8B7B001F817B /* BugsnagInternals.h in Headers */ = {isa = PBXBuildFile; fileRef = 01FF490528BF8B7B001F817B /* BugsnagInternals.h */; }; + 093EB6602AFE447E006EB7E3 /* Swizzle.mm in Sources */ = {isa = PBXBuildFile; fileRef = 093EB65F2AFE447E006EB7E3 /* Swizzle.mm */; }; + 093EB6612AFE447E006EB7E3 /* Swizzle.mm in Sources */ = {isa = PBXBuildFile; fileRef = 093EB65F2AFE447E006EB7E3 /* Swizzle.mm */; }; + 093EB6622AFE447E006EB7E3 /* Swizzle.mm in Sources */ = {isa = PBXBuildFile; fileRef = 093EB65F2AFE447E006EB7E3 /* Swizzle.mm */; }; + 093EB6632AFE447E006EB7E3 /* Swizzle.mm in Sources */ = {isa = PBXBuildFile; fileRef = 093EB65F2AFE447E006EB7E3 /* Swizzle.mm */; }; + 093EB6662AFE4580006EB7E3 /* BSGTestCase.mm in Sources */ = {isa = PBXBuildFile; fileRef = 093EB6652AFE4580006EB7E3 /* BSGTestCase.mm */; }; + 093EB6672AFE4580006EB7E3 /* BSGTestCase.mm in Sources */ = {isa = PBXBuildFile; fileRef = 093EB6652AFE4580006EB7E3 /* BSGTestCase.mm */; }; + 093EB6682AFE4580006EB7E3 /* BSGTestCase.mm in Sources */ = {isa = PBXBuildFile; fileRef = 093EB6652AFE4580006EB7E3 /* BSGTestCase.mm */; }; + 093EB6692AFE4580006EB7E3 /* BSGTestCase.mm in Sources */ = {isa = PBXBuildFile; fileRef = 093EB6652AFE4580006EB7E3 /* BSGTestCase.mm */; }; 3A700A9424A63ABC0068CD1B /* BugsnagThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A700A8024A63A8E0068CD1B /* BugsnagThread.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3A700A9524A63AC50068CD1B /* BugsnagSession.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A700A8124A63A8E0068CD1B /* BugsnagSession.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3A700A9624A63AC60068CD1B /* BugsnagStackframe.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A700A8224A63A8E0068CD1B /* BugsnagStackframe.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -1539,6 +1547,10 @@ 01E8765D256684E700F4B70A /* URLSessionMock.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = URLSessionMock.m; sourceTree = ""; }; 01F9FCB528929336005EDD8C /* BSGSerializationTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BSGSerializationTests.m; sourceTree = ""; }; 01FF490528BF8B7B001F817B /* BugsnagInternals.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BugsnagInternals.h; sourceTree = ""; }; + 093EB65E2AFE447E006EB7E3 /* Swizzle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Swizzle.h; sourceTree = ""; }; + 093EB65F2AFE447E006EB7E3 /* Swizzle.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Swizzle.mm; sourceTree = ""; }; + 093EB6642AFE4580006EB7E3 /* BSGTestCase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BSGTestCase.h; sourceTree = ""; }; + 093EB6652AFE4580006EB7E3 /* BSGTestCase.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = BSGTestCase.mm; sourceTree = ""; }; 3A700A8024A63A8E0068CD1B /* BugsnagThread.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BugsnagThread.h; sourceTree = ""; }; 3A700A8124A63A8E0068CD1B /* BugsnagSession.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BugsnagSession.h; sourceTree = ""; }; 3A700A8224A63A8E0068CD1B /* BugsnagStackframe.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BugsnagStackframe.h; sourceTree = ""; }; @@ -1934,8 +1946,6 @@ 00AD1C7F24869B0E00A27979 /* BugsnagTests */ = { isa = PBXGroup; children = ( - CBEC893E2A4ACD230088A3CE /* FileBasedTest.h */, - CBEC893F2A4ACD230088A3CE /* FileBasedTest.m */, 019480D32625F3EB00E833ED /* BSGAppKitTests.m */, 008966BD2486D43500DC48C2 /* BSGClientObserverTests.m */, 00896A3F2486DBDD00DC48C2 /* BSGConfigurationBuilderTests.m */, @@ -1953,6 +1963,8 @@ 01F9FCB528929336005EDD8C /* BSGSerializationTests.m */, CB6419AA25A73E8C00613D25 /* BSGStorageMigratorV0V1Tests.m */, 017DCF9A287422BB000ECB22 /* BSGTelemetryTests.m */, + 093EB6642AFE4580006EB7E3 /* BSGTestCase.h */, + 093EB6652AFE4580006EB7E3 /* BSGTestCase.mm */, 01DE903B26CEAF9E00455213 /* BSGUtilsTests.m */, CB9103632502320A00E9D1E2 /* BugsnagApiClientTest.m */, E701FA9E2490EF4A008D842F /* BugsnagApiValidationTest.m */, @@ -1995,9 +2007,13 @@ E701FAAE2490EFE8008D842F /* ConfigurationApiValidationTest.m */, 01BDB21425DEC02900A91FAF /* Data */, E701FAAA2490EFD9008D842F /* EventApiValidationTest.m */, + CBEC893E2A4ACD230088A3CE /* FileBasedTest.h */, + CBEC893F2A4ACD230088A3CE /* FileBasedTest.m */, 00E636C324878FFC006CBF1A /* Info.plist */, 01B14C55251CE55F00118748 /* report-react-native-promise-rejection.json */, 008966B72486D43500DC48C2 /* report.json */, + 093EB65E2AFE447E006EB7E3 /* Swizzle.h */, + 093EB65F2AFE447E006EB7E3 /* Swizzle.mm */, 004E35392487B375007FBAE4 /* Tests-Bridging-Header.h */, CBA22499251E429C00B87416 /* TestSupport.h */, CBA2249A251E429C00B87416 /* TestSupport.m */, @@ -3149,6 +3165,7 @@ 0089679F2486D43700DC48C2 /* KSCrashSentry_Tests.m in Sources */, 008967872486D43700DC48C2 /* KSCrashSentry_NSException_Tests.m in Sources */, 0089679C2486D43700DC48C2 /* KSFileUtils_Tests.m in Sources */, + 093EB6602AFE447E006EB7E3 /* Swizzle.mm in Sources */, 008966EE2486D43700DC48C2 /* BugsnagClientPayloadInfoTest.m in Sources */, 010F80C228645B4200D6569E /* BSGDefinesTests.m in Sources */, 01BDB1F525DEBFB200A91FAF /* BSGEventUploadKSCrashReportOperationTests.m in Sources */, @@ -3168,6 +3185,7 @@ 008967152486D43700DC48C2 /* BugsnagCollectionsTests.m in Sources */, 01E8765E256684E700F4B70A /* URLSessionMock.m in Sources */, 008967AB2486D43700DC48C2 /* BSG_KSMachTests.m in Sources */, + 093EB6662AFE4580006EB7E3 /* BSGTestCase.mm in Sources */, 0089672A2486D43700DC48C2 /* BugsnagStacktraceTest.m in Sources */, 01847DAC26441A5E00ADA4C7 /* BSGInternalErrorReporterTests.m in Sources */, 0163BF5925823D8D008DC28B /* BSGNotificationBreadcrumbsTests.m in Sources */, @@ -3315,6 +3333,7 @@ 008967822486D43700DC48C2 /* KSSystemInfo_Tests.m in Sources */, 008967612486D43700DC48C2 /* BugsnagBreadcrumbsTest.m in Sources */, 01DE903D26CEAF9E00455213 /* BSGUtilsTests.m in Sources */, + 093EB6672AFE4580006EB7E3 /* BSGTestCase.mm in Sources */, CB156242270707740097334C /* KSCrashNames_Test.m in Sources */, 008967012486D43700DC48C2 /* BugsnagEventPersistLoadTest.m in Sources */, 0089671C2486D43700DC48C2 /* BugsnagSessionTest.m in Sources */, @@ -3341,6 +3360,7 @@ 004E353B2487B3B3007FBAE4 /* BugsnagSwiftPublicAPITests.swift in Sources */, 0089677C2486D43700DC48C2 /* RFC3339DateTool_Tests.m in Sources */, CBEC89412A4ACD240088A3CE /* FileBasedTest.m in Sources */, + 093EB6612AFE447E006EB7E3 /* Swizzle.mm in Sources */, 01A2958728B667C2005FCC8C /* BSGNetworkBreadcrumbTests.m in Sources */, 008967552486D43700DC48C2 /* BugsnagOnCrashTest.m in Sources */, 008967A02486D43700DC48C2 /* KSCrashSentry_Tests.m in Sources */, @@ -3481,6 +3501,7 @@ 01B6BB7E25D5777F00FC4DE6 /* BugsnagSwiftPublicAPITests.swift in Sources */, 0089677A2486D43700DC48C2 /* BSG_KSMachHeadersTests.m in Sources */, 0089672C2486D43700DC48C2 /* BugsnagStacktraceTest.m in Sources */, + 093EB6682AFE4580006EB7E3 /* BSGTestCase.mm in Sources */, 008966F32486D43700DC48C2 /* BugsnagMetadataRedactionTest.m in Sources */, 008967382486D43700DC48C2 /* BugsnagMetadataTests.m in Sources */, 008967832486D43700DC48C2 /* KSSystemInfo_Tests.m in Sources */, @@ -3514,6 +3535,7 @@ 008967442486D43700DC48C2 /* BugsnagSessionTrackerStopTest.m in Sources */, CB26E9BC28350E0C005A1865 /* UISceneStub.m in Sources */, 008967982486D43700DC48C2 /* KSCrashState_Tests.m in Sources */, + 093EB6622AFE447E006EB7E3 /* Swizzle.mm in Sources */, 008967772486D43700DC48C2 /* XCTestCase+KSCrash.m in Sources */, 01A2958828B667C2005FCC8C /* BSGNetworkBreadcrumbTests.m in Sources */, CBEC89422A4ACD240088A3CE /* FileBasedTest.m in Sources */, @@ -3748,7 +3770,9 @@ CB28F0B828294DE1003AB200 /* BSGConfigurationBuilderTests.m in Sources */, CB28F0DB282A4BA6003AB200 /* BugsnagMetadataTests.m in Sources */, CB28F0B028294D4F003AB200 /* KSFileUtils_Tests.m in Sources */, + 093EB6632AFE447E006EB7E3 /* Swizzle.mm in Sources */, CB28F0DC282A4BEE003AB200 /* BugsnagSessionTrackerTest.m in Sources */, + 093EB6692AFE4580006EB7E3 /* BSGTestCase.mm in Sources */, CB28F0B728294DE1003AB200 /* BSGFeatureFlagStoreTests.m in Sources */, 010F80C528645B4200D6569E /* BSGDefinesTests.m in Sources */, CB28F0A028294D44003AB200 /* BSG_KSFileTests.m in Sources */, diff --git a/BugsnagNetworkRequestPlugin/BugsnagNetworkRequestPluginTests/BugsnagNetworkRequestPluginTests.m b/BugsnagNetworkRequestPlugin/BugsnagNetworkRequestPluginTests/BugsnagNetworkRequestPluginTests.m index f3ce61d3c..0e11b7ffc 100644 --- a/BugsnagNetworkRequestPlugin/BugsnagNetworkRequestPluginTests/BugsnagNetworkRequestPluginTests.m +++ b/BugsnagNetworkRequestPlugin/BugsnagNetworkRequestPluginTests/BugsnagNetworkRequestPluginTests.m @@ -87,6 +87,7 @@ - (void)resetBreadcrumbs { } - (void)setUp { + [super setUp]; [BSGURLSessionTracingDelegate setClient:(id)self]; [self resetBreadcrumbs]; } diff --git a/Tests/BugsnagTests/BSGAppKitTests.m b/Tests/BugsnagTests/BSGAppKitTests.m index c11002925..565d7bac8 100644 --- a/Tests/BugsnagTests/BSGAppKitTests.m +++ b/Tests/BugsnagTests/BSGAppKitTests.m @@ -6,9 +6,9 @@ // Copyright © 2021 Bugsnag Inc. All rights reserved. // -#import +#import "BSGTestCase.h" -@interface BSGAppKitTests : XCTestCase +@interface BSGAppKitTests : BSGTestCase @end diff --git a/Tests/BugsnagTests/BSGClientObserverTests.m b/Tests/BugsnagTests/BSGClientObserverTests.m index 32f165b9c..a9a60f846 100644 --- a/Tests/BugsnagTests/BSGClientObserverTests.m +++ b/Tests/BugsnagTests/BSGClientObserverTests.m @@ -6,7 +6,7 @@ // Copyright © 2020 Bugsnag. All rights reserved. // -#import +#import "BSGTestCase.h" #import "Bugsnag.h" #import "BugsnagClient+Private.h" @@ -15,7 +15,7 @@ #import "BugsnagMetadata+Private.h" #import "BugsnagUser+Private.h" -@interface BSGClientObserverTests : XCTestCase +@interface BSGClientObserverTests : BSGTestCase @property BugsnagClient *client; @property BSGClientObserverEvent event; @property id value; @@ -24,6 +24,7 @@ @interface BSGClientObserverTests : XCTestCase @implementation BSGClientObserverTests - (void)setUp { + [super setUp]; BugsnagConfiguration *config = [[BugsnagConfiguration alloc] initWithApiKey:DUMMY_APIKEY_32CHAR_1]; self.client = [Bugsnag startWithConfiguration:config]; diff --git a/Tests/BugsnagTests/BSGConfigurationBuilderTests.m b/Tests/BugsnagTests/BSGConfigurationBuilderTests.m index 0aa05ce2c..682c79c32 100644 --- a/Tests/BugsnagTests/BSGConfigurationBuilderTests.m +++ b/Tests/BugsnagTests/BSGConfigurationBuilderTests.m @@ -1,4 +1,4 @@ -#import +#import "BSGTestCase.h" #import #import "BSGConfigurationBuilder.h" @@ -6,7 +6,7 @@ #import "BugsnagTestConstants.h" #import -@interface BSGConfigurationBuilderTests : XCTestCase +@interface BSGConfigurationBuilderTests : BSGTestCase @end @implementation BSGConfigurationBuilderTests diff --git a/Tests/BugsnagTests/BSGConnectivityTest.m b/Tests/BugsnagTests/BSGConnectivityTest.m index 75f18f5f2..7eefe6563 100644 --- a/Tests/BugsnagTests/BSGConnectivityTest.m +++ b/Tests/BugsnagTests/BSGConnectivityTest.m @@ -1,9 +1,9 @@ -#import +#import "BSGTestCase.h" #import "BSGConnectivity.h" #import "BSGDefines.h" -@interface BSGConnectivityTest : XCTestCase +@interface BSGConnectivityTest : BSGTestCase @end @implementation BSGConnectivityTest diff --git a/Tests/BugsnagTests/BSGDefinesTests.m b/Tests/BugsnagTests/BSGDefinesTests.m index e68b13b38..dc5154542 100644 --- a/Tests/BugsnagTests/BSGDefinesTests.m +++ b/Tests/BugsnagTests/BSGDefinesTests.m @@ -6,11 +6,11 @@ // Copyright © 2022 Bugsnag Inc. All rights reserved. // -#import +#import "BSGTestCase.h" #import "BSGDefines.h" -@interface BSGDefinesTests : XCTestCase +@interface BSGDefinesTests : BSGTestCase @end diff --git a/Tests/BugsnagTests/BSGEventUploadKSCrashReportOperationTests.m b/Tests/BugsnagTests/BSGEventUploadKSCrashReportOperationTests.m index 86a3bf28d..3874b8e99 100644 --- a/Tests/BugsnagTests/BSGEventUploadKSCrashReportOperationTests.m +++ b/Tests/BugsnagTests/BSGEventUploadKSCrashReportOperationTests.m @@ -6,13 +6,14 @@ // Copyright © 2021 Bugsnag Inc. All rights reserved. // +#import "BSGTestCase.h" + #import -#import #import "BSGEventUploadKSCrashReportOperation.h" #import "BSGInternalErrorReporter.h" -@interface BSGEventUploadKSCrashReportOperationTests : XCTestCase +@interface BSGEventUploadKSCrashReportOperationTests : BSGTestCase @property NSString *errorClass; @property NSString *context; diff --git a/Tests/BugsnagTests/BSGFeatureFlagStoreTests.m b/Tests/BugsnagTests/BSGFeatureFlagStoreTests.m index 8144687d6..296f8cfd5 100644 --- a/Tests/BugsnagTests/BSGFeatureFlagStoreTests.m +++ b/Tests/BugsnagTests/BSGFeatureFlagStoreTests.m @@ -6,11 +6,11 @@ // Copyright © 2021 Bugsnag Inc. All rights reserved. // -#import "BSGFeatureFlagStore.h" +#import "BSGTestCase.h" -#import +#import "BSGFeatureFlagStore.h" -@interface BSGFeatureFlagStoreTests : XCTestCase +@interface BSGFeatureFlagStoreTests : BSGTestCase @end diff --git a/Tests/BugsnagTests/BSGInternalErrorReporterTests.m b/Tests/BugsnagTests/BSGInternalErrorReporterTests.m index 2948d5154..a9f75b620 100644 --- a/Tests/BugsnagTests/BSGInternalErrorReporterTests.m +++ b/Tests/BugsnagTests/BSGInternalErrorReporterTests.m @@ -6,7 +6,7 @@ // Copyright © 2021 Bugsnag Inc. All rights reserved. // -#import +#import "BSGTestCase.h" #import @@ -18,7 +18,7 @@ #import "BugsnagNotifier.h" #import "BSGPersistentDeviceID.h" -@interface BSGInternalErrorReporterTests : XCTestCase +@interface BSGInternalErrorReporterTests : BSGTestCase @property (nonatomic) BugsnagConfiguration *configuration; @@ -27,6 +27,7 @@ @interface BSGInternalErrorReporterTests : XCTestCase @implementation BSGInternalErrorReporterTests - (void)setUp { + [super setUp]; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wnonnull" [BSGInternalErrorReporter setSharedInstance:nil]; diff --git a/Tests/BugsnagTests/BSGJSONSerializationTests.m b/Tests/BugsnagTests/BSGJSONSerializationTests.m index 531768040..2f37482e2 100644 --- a/Tests/BugsnagTests/BSGJSONSerializationTests.m +++ b/Tests/BugsnagTests/BSGJSONSerializationTests.m @@ -6,11 +6,11 @@ // Copyright © 2020 Bugsnag Inc. All rights reserved. // -#import +#import "BSGTestCase.h" #import "BSGJSONSerialization.h" -@interface BSGJSONSerializationTests : XCTestCase +@interface BSGJSONSerializationTests : BSGTestCase @end @implementation BSGJSONSerializationTests diff --git a/Tests/BugsnagTests/BSGNetworkBreadcrumbTests.m b/Tests/BugsnagTests/BSGNetworkBreadcrumbTests.m index e488e03e7..d52968b5d 100644 --- a/Tests/BugsnagTests/BSGNetworkBreadcrumbTests.m +++ b/Tests/BugsnagTests/BSGNetworkBreadcrumbTests.m @@ -5,11 +5,11 @@ // Created by Nick Dowell on 22/09/2021. // -#import "BSGNetworkBreadcrumb.h" +#import "BSGTestCase.h" -#import +#import "BSGNetworkBreadcrumb.h" -@interface BSGNetworkBreadcrumbTests : XCTestCase +@interface BSGNetworkBreadcrumbTests : BSGTestCase @end diff --git a/Tests/BugsnagTests/BSGNotificationBreadcrumbsTests.m b/Tests/BugsnagTests/BSGNotificationBreadcrumbsTests.m index efef0cf7c..98a3614b5 100644 --- a/Tests/BugsnagTests/BSGNotificationBreadcrumbsTests.m +++ b/Tests/BugsnagTests/BSGNotificationBreadcrumbsTests.m @@ -6,7 +6,7 @@ // Copyright © 2020 Bugsnag Inc. All rights reserved. // -#import +#import "BSGTestCase.h" #import @@ -19,7 +19,7 @@ #endif -@interface BSGNotificationBreadcrumbsTests : XCTestCase +@interface BSGNotificationBreadcrumbsTests : BSGTestCase @property NSNotificationCenter *notificationCenter; @property id notificationObject; @@ -114,6 +114,7 @@ @implementation BSGNotificationBreadcrumbsTests #pragma mark Setup - (void)setUp { + [super setUp]; self.breadcrumb = nil; BugsnagConfiguration *configuration = [[BugsnagConfiguration alloc] initWithApiKey:@"0192837465afbecd0192837465afbecd"]; self.notificationBreadcrumbs = [[BSGNotificationBreadcrumbs alloc] initWithConfiguration:configuration breadcrumbSink:self]; diff --git a/Tests/BugsnagTests/BSGOutOfMemoryTests.m b/Tests/BugsnagTests/BSGOutOfMemoryTests.m index aeda8869e..8cafa6c4f 100644 --- a/Tests/BugsnagTests/BSGOutOfMemoryTests.m +++ b/Tests/BugsnagTests/BSGOutOfMemoryTests.m @@ -1,4 +1,4 @@ -#import +#import "BSGTestCase.h" #import "BSGFileLocations.h" #import "BSGRunContext.h" @@ -10,7 +10,7 @@ #import "BugsnagSystemState.h" #import "BugsnagTestConstants.h" -@interface BSGOutOfMemoryTests : XCTestCase +@interface BSGOutOfMemoryTests : BSGTestCase @end @implementation BSGOutOfMemoryTests diff --git a/Tests/BugsnagTests/BSGRunContextTests.m b/Tests/BugsnagTests/BSGRunContextTests.m index 0fb7ee656..beda07936 100644 --- a/Tests/BugsnagTests/BSGRunContextTests.m +++ b/Tests/BugsnagTests/BSGRunContextTests.m @@ -6,18 +6,19 @@ // Copyright © 2022 Bugsnag Inc. All rights reserved. // -#import +#import "BSGTestCase.h" #import "BSGFileLocations.h" #import "BSGRunContext.h" -@interface BSGRunContextTests : XCTestCase +@interface BSGRunContextTests : BSGTestCase @end @implementation BSGRunContextTests - (void)setUp { + [super setUp]; if (!bsg_runContext) { BSGRunContextInit(BSGFileLocations.current.runContext); } diff --git a/Tests/BugsnagTests/BSGSerializationTests.m b/Tests/BugsnagTests/BSGSerializationTests.m index c36621781..1b5dce9ed 100644 --- a/Tests/BugsnagTests/BSGSerializationTests.m +++ b/Tests/BugsnagTests/BSGSerializationTests.m @@ -6,11 +6,11 @@ // Copyright © 2022 Bugsnag Inc. All rights reserved. // -#import +#import "BSGTestCase.h" #import "BSGSerialization.h" -@interface BSGSerializationTests : XCTestCase +@interface BSGSerializationTests : BSGTestCase @end diff --git a/Tests/BugsnagTests/BSGStorageMigratorV0V1Tests.m b/Tests/BugsnagTests/BSGStorageMigratorV0V1Tests.m index 1c928d61c..f4e857a8d 100644 --- a/Tests/BugsnagTests/BSGStorageMigratorV0V1Tests.m +++ b/Tests/BugsnagTests/BSGStorageMigratorV0V1Tests.m @@ -6,13 +6,14 @@ // Copyright © 2021 Bugsnag Inc. All rights reserved. // -#import +#import "BSGTestCase.h" + #import "BSGStorageMigratorV0V1.h" #import "BugsnagClient+Private.h" #import "BugsnagConfiguration+Private.h" #import "BugsnagTestConstants.h" -@interface BSGStorageMigratorV0V1Tests : XCTestCase +@interface BSGStorageMigratorV0V1Tests : BSGTestCase @end @@ -79,6 +80,7 @@ - (NSDictionary *)getFiles { } - (void)setUp { + [super setUp]; NSFileManager *fm = [NSFileManager defaultManager]; NSBundle *bundle = [NSBundle bundleForClass:[self class]]; NSString *cachesPath = [self getCachesDir]; diff --git a/Tests/BugsnagTests/BSGTelemetryTests.m b/Tests/BugsnagTests/BSGTelemetryTests.m index 264cdecc5..889697bd6 100644 --- a/Tests/BugsnagTests/BSGTelemetryTests.m +++ b/Tests/BugsnagTests/BSGTelemetryTests.m @@ -6,14 +6,14 @@ // Copyright © 2022 Bugsnag Inc. All rights reserved. // -#import +#import "BSGTestCase.h" #import #import "BSGTelemetry.h" #import "BugsnagTestConstants.h" -@interface BSGTelemetryTests : XCTestCase +@interface BSGTelemetryTests : BSGTestCase @end diff --git a/Tests/BugsnagTests/BSGTestCase.h b/Tests/BugsnagTests/BSGTestCase.h new file mode 100644 index 000000000..1986a7fe4 --- /dev/null +++ b/Tests/BugsnagTests/BSGTestCase.h @@ -0,0 +1,17 @@ +// +// BSGTestCase.h +// Bugsnag +// +// Created by Karl Stenerud on 10.11.23. +// Copyright © 2023 Bugsnag Inc. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface BSGTestCase : XCTestCase + +@end + +NS_ASSUME_NONNULL_END diff --git a/Tests/BugsnagTests/BSGTestCase.mm b/Tests/BugsnagTests/BSGTestCase.mm new file mode 100644 index 000000000..91008a43d --- /dev/null +++ b/Tests/BugsnagTests/BSGTestCase.mm @@ -0,0 +1,91 @@ +// +// BSGTestCase.m +// Bugsnag +// +// Created by Karl Stenerud on 10.11.23. +// Copyright © 2023 Bugsnag Inc. All rights reserved. +// + +#import "BSGTestCase.h" +#import "Swizzle.h" +#import + +using namespace bugsnag; + +@interface BSGWatchKitBundle: NSProxy + +@property(nonatomic,readwrite) NSBundle *bundle; +@property(nonatomic,readwrite) NSDictionary *dict; + +- (instancetype) initWithBundle:(NSBundle *)bundle; + +@end + +@implementation BSGWatchKitBundle + +- (instancetype) initWithBundle:(NSBundle *)bundle { + // Force the main bundle's dictionary to have an NSExtension section on WatchOS. + // This is necessary because the unit tests run in an extension environment but + // don't set this field that is normally present in a real environment, which + // confuses our extension detection code in + // Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSSystemInfo.m + NSMutableDictionary *dict = [NSBundle.mainBundle.infoDictionary mutableCopy]; + if (dict[@"NSExtension"] == nil) { + dict[@"NSExtension"] = @{ + @"NSExtensionAttributes": @{ + @"WKAppBundleIdentifier": @"com.bugsnag.swift-watchos.watchkitapp", + }, + @"NSExtensionPointIdentifier": @"com.apple.watchkit", + }; + } + _dict = dict; + _bundle = bundle; + + return self; +} + +- (void)forwardInvocation:(NSInvocation *)invocation +{ + if (self.bundle) { + [invocation setTarget:self.bundle]; + [invocation invoke]; + } +} + +- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel +{ + if ([self.bundle methodSignatureForSelector:sel]) { + return [self.bundle methodSignatureForSelector:sel]; + } else { + return [super methodSignatureForSelector:sel]; + } +} + +- (NSDictionary *)infoDictionary { + return self.dict; +} + +@end + + +@implementation BSGTestCase + +- (void)setUp { + if ([super respondsToSelector:@selector(setUp)]) { + [super setUp]; + } + +#if TARGET_OS_WATCH + static _Atomic(bool) hasSwizzled = false; + bool expectedValue = false; + if (atomic_compare_exchange_strong(&hasSwizzled, &expectedValue, true)) { + BSGWatchKitBundle *bundleProxy = [[BSGWatchKitBundle alloc] initWithBundle:NSBundle.mainBundle]; + ObjCSwizzle::setClassMethodImplementation(NSBundle.class, @selector(mainBundle), ^NSBundle *{ + return (NSBundle *)bundleProxy; + }); + } + +#endif +} + +@end diff --git a/Tests/BugsnagTests/BSGUtilsTests.m b/Tests/BugsnagTests/BSGUtilsTests.m index 70e9d9853..d87da8441 100644 --- a/Tests/BugsnagTests/BSGUtilsTests.m +++ b/Tests/BugsnagTests/BSGUtilsTests.m @@ -6,11 +6,11 @@ // Copyright © 2021 Bugsnag Inc. All rights reserved. // -#import +#import "BSGTestCase.h" #import "BSGUtils.h" -@interface BSGUtilsTests : XCTestCase +@interface BSGUtilsTests : BSGTestCase @end @implementation BSGUtilsTests diff --git a/Tests/BugsnagTests/BugsnagApiClientTest.m b/Tests/BugsnagTests/BugsnagApiClientTest.m index 4abfb2992..dcdfdf391 100644 --- a/Tests/BugsnagTests/BugsnagApiClientTest.m +++ b/Tests/BugsnagTests/BugsnagApiClientTest.m @@ -6,13 +6,14 @@ // Copyright © 2020 Bugsnag Inc. All rights reserved. // -#import +#import "BSGTestCase.h" + #import "BugsnagApiClient.h" #import #import "BugsnagTestConstants.h" #import "URLSessionMock.h" -@interface BugsnagApiClientTest : XCTestCase +@interface BugsnagApiClientTest : BSGTestCase @end diff --git a/Tests/BugsnagTests/BugsnagApiValidationTest.m b/Tests/BugsnagTests/BugsnagApiValidationTest.m index b204e0c48..0d3dd7a3c 100644 --- a/Tests/BugsnagTests/BugsnagApiValidationTest.m +++ b/Tests/BugsnagTests/BugsnagApiValidationTest.m @@ -6,7 +6,8 @@ // Copyright © 2020 Bugsnag Inc. All rights reserved. // -#import +#import "BSGTestCase.h" + #import #import "BugsnagTestConstants.h" #import "TestSupport.h" @@ -14,13 +15,14 @@ /** * Validates that the Bugsnag API interface handles any invalid input gracefully. */ -@interface BugsnagApiValidationTest : XCTestCase +@interface BugsnagApiValidationTest : BSGTestCase @end @implementation BugsnagApiValidationTest - (void)setUp { + [super setUp]; [TestSupport purgePersistentData]; [Bugsnag startWithApiKey:DUMMY_APIKEY_32CHAR_1]; } diff --git a/Tests/BugsnagTests/BugsnagAppTest.m b/Tests/BugsnagTests/BugsnagAppTest.m index 94f1a19a7..092c85bdf 100644 --- a/Tests/BugsnagTests/BugsnagAppTest.m +++ b/Tests/BugsnagTests/BugsnagAppTest.m @@ -6,7 +6,7 @@ // Copyright © 2020 Bugsnag. All rights reserved. // -#import +#import "BSGTestCase.h" #import "BSG_KSSystemInfo.h" #import "BugsnagApp+Private.h" @@ -16,7 +16,7 @@ #include -@interface BugsnagAppTest : XCTestCase +@interface BugsnagAppTest : BSGTestCase @property NSDictionary *data; @property BugsnagConfiguration *config; @property NSString *codeBundleId; diff --git a/Tests/BugsnagTests/BugsnagBreadcrumbsTest.m b/Tests/BugsnagTests/BugsnagBreadcrumbsTest.m index 465269d06..26edd15d2 100644 --- a/Tests/BugsnagTests/BugsnagBreadcrumbsTest.m +++ b/Tests/BugsnagTests/BugsnagBreadcrumbsTest.m @@ -6,6 +6,8 @@ // // +#import "BSGTestCase.h" + #import "BSGUtils.h" #import "BSG_KSJSONCodec.h" #import "Bugsnag.h" @@ -15,7 +17,6 @@ #import "BugsnagTestConstants.h" #import "BSGDefines.h" -#import #import #import #import @@ -61,7 +62,7 @@ static id JSONObject(void (^ block)(BSG_KSCrashReportWriter *writer)) { }); } -@interface BugsnagBreadcrumbsTest : XCTestCase +@interface BugsnagBreadcrumbsTest : BSGTestCase @property(nonatomic, strong) BugsnagBreadcrumbs *crumbs; @end diff --git a/Tests/BugsnagTests/BugsnagClientMirrorTest.m b/Tests/BugsnagTests/BugsnagClientMirrorTest.m index e31ff1a27..3a5d9acb9 100644 --- a/Tests/BugsnagTests/BugsnagClientMirrorTest.m +++ b/Tests/BugsnagTests/BugsnagClientMirrorTest.m @@ -6,11 +6,12 @@ // Copyright © 2020 Bugsnag. All rights reserved. // -#import +#import "BSGTestCase.h" + #import #import -@interface BugsnagClientMirrorTest : XCTestCase +@interface BugsnagClientMirrorTest : BSGTestCase @property NSSet *clientMethodsNotRequiredOnBugsnag; @property NSSet *bugsnagMethodsNotRequiredOnClient; @end @@ -26,6 +27,7 @@ @interface BugsnagClientMirrorTest : XCTestCase @implementation BugsnagClientMirrorTest - (void)setUp { + [super setUp]; // the following methods are implemented on BugsnagClient but do not need to // be mirrored on the Bugsnag facade self.clientMethodsNotRequiredOnBugsnag = [NSSet setWithArray:@[ diff --git a/Tests/BugsnagTests/BugsnagClientPayloadInfoTest.m b/Tests/BugsnagTests/BugsnagClientPayloadInfoTest.m index 31cca1552..fe60f3a31 100755 --- a/Tests/BugsnagTests/BugsnagClientPayloadInfoTest.m +++ b/Tests/BugsnagTests/BugsnagClientPayloadInfoTest.m @@ -6,20 +6,21 @@ // Copyright © 2020 Bugsnag. All rights reserved. // -#import +#import "BSGTestCase.h" #import "BugsnagAppWithState+Private.h" #import "BugsnagConfiguration.h" #import "BugsnagDeviceWithState+Private.h" #import "BugsnagTestConstants.h" -@interface BugsnagClientPayloadInfoTest : XCTestCase +@interface BugsnagClientPayloadInfoTest : BSGTestCase @end @implementation BugsnagClientPayloadInfoTest - (void)setUp { + [super setUp]; BugsnagConfiguration *configuration = [[BugsnagConfiguration alloc] initWithApiKey:DUMMY_APIKEY_32CHAR_1]; [Bugsnag startWithConfiguration:configuration]; } diff --git a/Tests/BugsnagTests/BugsnagClientTests.m b/Tests/BugsnagTests/BugsnagClientTests.m index 0efbb186c..4dde42d3e 100644 --- a/Tests/BugsnagTests/BugsnagClientTests.m +++ b/Tests/BugsnagTests/BugsnagClientTests.m @@ -6,6 +6,8 @@ // Copyright © 2020 Bugsnag. All rights reserved. // +#import "BSGTestCase.h" + #import "BSGInternalErrorReporter.h" #import "BSGKeys.h" #import "BSGRunContext.h" @@ -19,7 +21,6 @@ #import "BugsnagUser.h" #import -#import /** * Tests for BugsnagClient. @@ -31,7 +32,7 @@ * * For these reasons, test cases should only be added here as a matter of last resort. */ -@interface BugsnagClientTests : XCTestCase +@interface BugsnagClientTests : BSGTestCase @end NSString *BSGFormatSeverity(BSGSeverity severity); diff --git a/Tests/BugsnagTests/BugsnagCollectionsTests.m b/Tests/BugsnagTests/BugsnagCollectionsTests.m index b376fb0cd..3d816573f 100644 --- a/Tests/BugsnagTests/BugsnagCollectionsTests.m +++ b/Tests/BugsnagTests/BugsnagCollectionsTests.m @@ -6,10 +6,11 @@ // Copyright © 2019 Bugsnag. All rights reserved. // -@import XCTest; +#import "BSGTestCase.h" + #import "BugsnagCollections.h" -@interface BugsnagCollectionsTests : XCTestCase +@interface BugsnagCollectionsTests : BSGTestCase @end @interface BugsnagCollectionsTests_DummyObject : NSObject diff --git a/Tests/BugsnagTests/BugsnagConfigurationTests.m b/Tests/BugsnagTests/BugsnagConfigurationTests.m index bbff7fe76..b21702bc9 100644 --- a/Tests/BugsnagTests/BugsnagConfigurationTests.m +++ b/Tests/BugsnagTests/BugsnagConfigurationTests.m @@ -2,7 +2,7 @@ * Unit test the BugsnagConfiguration class */ -#import +#import "BSGTestCase.h" #import "BugsnagConfiguration+Private.h" @@ -19,7 +19,7 @@ // MARK: - Tests // ============================================================================= -@interface BugsnagConfigurationTests : XCTestCase +@interface BugsnagConfigurationTests : BSGTestCase @end @implementation BugsnagConfigurationTests diff --git a/Tests/BugsnagTests/BugsnagDeviceTest.m b/Tests/BugsnagTests/BugsnagDeviceTest.m index d66039f94..f0bfd6e5e 100644 --- a/Tests/BugsnagTests/BugsnagDeviceTest.m +++ b/Tests/BugsnagTests/BugsnagDeviceTest.m @@ -6,13 +6,13 @@ // Copyright © 2020 Bugsnag. All rights reserved. // -#import +#import "BSGTestCase.h" #import "BSG_KSSystemInfo.h" #import "BugsnagDevice+Private.h" #import "BugsnagDeviceWithState+Private.h" -@interface BugsnagDeviceTest : XCTestCase +@interface BugsnagDeviceTest : BSGTestCase @property NSDictionary *data; @end diff --git a/Tests/BugsnagTests/BugsnagEnabledBreadcrumbTest.m b/Tests/BugsnagTests/BugsnagEnabledBreadcrumbTest.m index 06f33e8b9..7af6a20b9 100644 --- a/Tests/BugsnagTests/BugsnagEnabledBreadcrumbTest.m +++ b/Tests/BugsnagTests/BugsnagEnabledBreadcrumbTest.m @@ -6,12 +6,12 @@ // Copyright © 2020 Bugsnag. All rights reserved. // -#import +#import "BSGTestCase.h" #import "BugsnagConfiguration+Private.h" #import "BugsnagTestConstants.h" -@interface BugsnagEnabledBreadcrumbTest : XCTestCase +@interface BugsnagEnabledBreadcrumbTest : BSGTestCase @end diff --git a/Tests/BugsnagTests/BugsnagErrorTest.m b/Tests/BugsnagTests/BugsnagErrorTest.m index 1662f9685..8838cf3cc 100644 --- a/Tests/BugsnagTests/BugsnagErrorTest.m +++ b/Tests/BugsnagTests/BugsnagErrorTest.m @@ -6,7 +6,7 @@ // Copyright © 2020 Bugsnag. All rights reserved. // -#import +#import "BSGTestCase.h" #import "BSGKeys.h" #import "BugsnagError+Private.h" @@ -17,13 +17,14 @@ NSString *BSGParseErrorMessage(NSDictionary *report, NSDictionary *error, NSString *errorType); -@interface BugsnagErrorTest : XCTestCase +@interface BugsnagErrorTest : BSGTestCase @property NSDictionary *event; @end @implementation BugsnagErrorTest - (void)setUp { + [super setUp]; NSDictionary *thread = @{ @"current_thread": @YES, @"crashed": @YES, diff --git a/Tests/BugsnagTests/BugsnagEventFromKSCrashReportTest.m b/Tests/BugsnagTests/BugsnagEventFromKSCrashReportTest.m index eb89ec446..b704af6d2 100644 --- a/Tests/BugsnagTests/BugsnagEventFromKSCrashReportTest.m +++ b/Tests/BugsnagTests/BugsnagEventFromKSCrashReportTest.m @@ -6,12 +6,12 @@ // Copyright © 2019 Bugsnag. All rights reserved. // -@import XCTest; +#import "BSGTestCase.h" #import "Bugsnag+Private.h" #import "BugsnagEvent+Private.h" -@interface BugsnagEventFromKSCrashReportTest : XCTestCase +@interface BugsnagEventFromKSCrashReportTest : BSGTestCase @property BugsnagEvent *event; @end diff --git a/Tests/BugsnagTests/BugsnagEventPersistLoadTest.m b/Tests/BugsnagTests/BugsnagEventPersistLoadTest.m index ad199cca8..10d9ef103 100644 --- a/Tests/BugsnagTests/BugsnagEventPersistLoadTest.m +++ b/Tests/BugsnagTests/BugsnagEventPersistLoadTest.m @@ -6,7 +6,7 @@ // Copyright © 2020 Bugsnag. All rights reserved. // -#import +#import "BSGTestCase.h" #import "BugsnagEvent+Private.h" #import "BugsnagAppWithState.h" @@ -22,7 +22,7 @@ #import "BugsnagStackframe.h" #import "BugsnagThread.h" -@interface BugsnagEventPersistLoadTest : XCTestCase +@interface BugsnagEventPersistLoadTest : BSGTestCase @property NSDictionary *eventData; @end diff --git a/Tests/BugsnagTests/BugsnagEventTests.m b/Tests/BugsnagTests/BugsnagEventTests.m index 7766508fd..a1d06753f 100644 --- a/Tests/BugsnagTests/BugsnagEventTests.m +++ b/Tests/BugsnagTests/BugsnagEventTests.m @@ -6,8 +6,7 @@ // // -#import -#import +#import "BSGTestCase.h" #import "BSG_RFC3339DateTool.h" #import "Bugsnag.h" @@ -22,7 +21,7 @@ #import "BugsnagTestConstants.h" #import "BugsnagTestsDummyClass.h" -@interface BugsnagEventTests : XCTestCase +@interface BugsnagEventTests : BSGTestCase @end @implementation BugsnagEventTests diff --git a/Tests/BugsnagTests/BugsnagHandledStateTest.m b/Tests/BugsnagTests/BugsnagHandledStateTest.m index 0a35ea49c..cf47d6e47 100644 --- a/Tests/BugsnagTests/BugsnagHandledStateTest.m +++ b/Tests/BugsnagTests/BugsnagHandledStateTest.m @@ -6,11 +6,12 @@ // Copyright © 2017 Bugsnag. All rights reserved. // -#import +#import "BSGTestCase.h" + #import #import "BugsnagHandledState.h" -@interface BugsnagHandledStateTest : XCTestCase +@interface BugsnagHandledStateTest : BSGTestCase @end diff --git a/Tests/BugsnagTests/BugsnagMetadataRedactionTest.m b/Tests/BugsnagTests/BugsnagMetadataRedactionTest.m index c0be86955..5b9ce8dbe 100644 --- a/Tests/BugsnagTests/BugsnagMetadataRedactionTest.m +++ b/Tests/BugsnagTests/BugsnagMetadataRedactionTest.m @@ -6,12 +6,12 @@ // Copyright © 2020 Bugsnag. All rights reserved. // -#import +#import "BSGTestCase.h" #import "BugsnagBreadcrumb+Private.h" #import "BugsnagEvent+Private.h" -@interface BugsnagMetadataRedactionTest : XCTestCase +@interface BugsnagMetadataRedactionTest : BSGTestCase @end diff --git a/Tests/BugsnagTests/BugsnagMetadataTests.m b/Tests/BugsnagTests/BugsnagMetadataTests.m index 24a121b9a..42b7677ca 100644 --- a/Tests/BugsnagTests/BugsnagMetadataTests.m +++ b/Tests/BugsnagTests/BugsnagMetadataTests.m @@ -6,17 +6,18 @@ // Copyright © 2020 Bugsnag. All rights reserved. // +#import "BSGTestCase.h" + #import "BugsnagMetadata.h" #import "BugsnagMetadata+Private.h" #import "BSGDefines.h" -#import #import #import // MARK: - Expose tested-class internals -@interface BugsnagMetadataTests : XCTestCase +@interface BugsnagMetadataTests : BSGTestCase @property BOOL delegateCalled; @property BugsnagMetadata *metadata; @end @@ -45,6 +46,7 @@ @implementation BugsnagMetadataTests @synthesize metadata; -(void) setUp { + [super setUp]; metadata = [[BugsnagMetadata alloc] init]; __weak __typeof__(self) weakSelf = self; diff --git a/Tests/BugsnagTests/BugsnagNotifierTest.m b/Tests/BugsnagTests/BugsnagNotifierTest.m index a89435ce1..e5dbe6c03 100644 --- a/Tests/BugsnagTests/BugsnagNotifierTest.m +++ b/Tests/BugsnagTests/BugsnagNotifierTest.m @@ -6,16 +6,18 @@ // Copyright © 2020 Bugsnag. All rights reserved. // -#import +#import "BSGTestCase.h" + #import "BugsnagNotifier.h" -@interface BugsnagNotifierTest : XCTestCase +@interface BugsnagNotifierTest : BSGTestCase @property BugsnagNotifier *notifier; @end @implementation BugsnagNotifierTest - (void)setUp { + [super setUp]; self.notifier = [BugsnagNotifier new]; self.notifier.name = @"Foo Notifier"; self.notifier.version = @"6.0.0"; diff --git a/Tests/BugsnagTests/BugsnagOnBreadcrumbTest.m b/Tests/BugsnagTests/BugsnagOnBreadcrumbTest.m index 877d9a2e0..f73d6b765 100644 --- a/Tests/BugsnagTests/BugsnagOnBreadcrumbTest.m +++ b/Tests/BugsnagTests/BugsnagOnBreadcrumbTest.m @@ -6,7 +6,7 @@ // Copyright © 2020 Bugsnag. All rights reserved. // -#import +#import "BSGTestCase.h" #import "Bugsnag.h" #import "BugsnagBreadcrumb+Private.h" @@ -15,7 +15,7 @@ #import "BugsnagTestConstants.h" #import "BugsnagBreadcrumbs.h" -@interface BugsnagOnBreadcrumbTest : XCTestCase +@interface BugsnagOnBreadcrumbTest : BSGTestCase @end @implementation BugsnagOnBreadcrumbTest diff --git a/Tests/BugsnagTests/BugsnagOnCrashTest.m b/Tests/BugsnagTests/BugsnagOnCrashTest.m index 7dd48d8bb..31bdaf35e 100644 --- a/Tests/BugsnagTests/BugsnagOnCrashTest.m +++ b/Tests/BugsnagTests/BugsnagOnCrashTest.m @@ -6,12 +6,12 @@ // Copyright © 2020 Bugsnag. All rights reserved. // -#import +#import "BSGTestCase.h" #import #import "BugsnagEvent+Private.h" -@interface BugsnagOnCrashTest : XCTestCase +@interface BugsnagOnCrashTest : BSGTestCase @end diff --git a/Tests/BugsnagTests/BugsnagPluginTest.m b/Tests/BugsnagTests/BugsnagPluginTest.m index 3a1393bec..06c89ae51 100644 --- a/Tests/BugsnagTests/BugsnagPluginTest.m +++ b/Tests/BugsnagTests/BugsnagPluginTest.m @@ -6,14 +6,14 @@ // Copyright © 2020 Bugsnag. All rights reserved. // -#import +#import "BSGTestCase.h" #import "BugsnagTestConstants.h" #import "Bugsnag.h" #import "BugsnagClient+Private.h" #import "BugsnagConfiguration+Private.h" -@interface BugsnagPluginTest : XCTestCase +@interface BugsnagPluginTest : BSGTestCase @end diff --git a/Tests/BugsnagTests/BugsnagSessionTest.m b/Tests/BugsnagTests/BugsnagSessionTest.m index a2c48040e..cf4600d63 100644 --- a/Tests/BugsnagTests/BugsnagSessionTest.m +++ b/Tests/BugsnagTests/BugsnagSessionTest.m @@ -6,7 +6,7 @@ // Copyright © 2017 Bugsnag. All rights reserved. // -#import +#import "BSGTestCase.h" #import "BugsnagApp+Private.h" #import "BugsnagConfiguration+Private.h" @@ -16,7 +16,7 @@ #import "BSG_RFC3339DateTool.h" #import "BugsnagTestConstants.h" -@interface BugsnagSessionTest : XCTestCase +@interface BugsnagSessionTest : BSGTestCase @property BugsnagApp *app; @property BugsnagDevice *device; @property NSDictionary *serializedSession; @@ -25,6 +25,7 @@ @interface BugsnagSessionTest : XCTestCase @implementation BugsnagSessionTest - (void)setUp { + [super setUp]; self.app = [self generateApp]; self.device = [self generateDevice]; self.serializedSession = [self generateSerializedSession]; diff --git a/Tests/BugsnagTests/BugsnagSessionTrackerStopTest.m b/Tests/BugsnagTests/BugsnagSessionTrackerStopTest.m index 7e1628330..53416fcc7 100644 --- a/Tests/BugsnagTests/BugsnagSessionTrackerStopTest.m +++ b/Tests/BugsnagTests/BugsnagSessionTrackerStopTest.m @@ -6,13 +6,13 @@ // Copyright © 2019 Bugsnag. All rights reserved. // -#import +#import "BSGTestCase.h" #import "BugsnagSession+Private.h" #import "BugsnagSessionTracker.h" #import "BugsnagTestConstants.h" -@interface BugsnagSessionTrackerStopTest : XCTestCase +@interface BugsnagSessionTrackerStopTest : BSGTestCase @property BugsnagConfiguration *configuration; @property BugsnagSessionTracker *tracker; @end diff --git a/Tests/BugsnagTests/BugsnagSessionTrackerTest.m b/Tests/BugsnagTests/BugsnagSessionTrackerTest.m index 016464429..13bf85853 100644 --- a/Tests/BugsnagTests/BugsnagSessionTrackerTest.m +++ b/Tests/BugsnagTests/BugsnagSessionTrackerTest.m @@ -6,7 +6,7 @@ // Copyright © 2017 Bugsnag. All rights reserved. // -#import +#import "BSGTestCase.h" #import "BugsnagUser.h" #import "BugsnagConfiguration+Private.h" @@ -16,7 +16,7 @@ #import "BSGDefines.h" #import "BSGWatchKit.h" -@interface BugsnagSessionTrackerTest : XCTestCase +@interface BugsnagSessionTrackerTest : BSGTestCase @property BugsnagConfiguration *configuration; @property BugsnagSessionTracker *sessionTracker; @property BugsnagUser *user; diff --git a/Tests/BugsnagTests/BugsnagStackframeTest.m b/Tests/BugsnagTests/BugsnagStackframeTest.m index bb584fd86..d8333fb7d 100644 --- a/Tests/BugsnagTests/BugsnagStackframeTest.m +++ b/Tests/BugsnagTests/BugsnagStackframeTest.m @@ -6,12 +6,12 @@ // Copyright © 2020 Bugsnag. All rights reserved. // -#import +#import "BSGTestCase.h" #import "BSG_KSMachHeaders.h" #import "BugsnagStackframe+Private.h" -@interface BugsnagStackframeTest : XCTestCase +@interface BugsnagStackframeTest : BSGTestCase @property NSDictionary *frameDict; @property NSArray *binaryImages; @end @@ -19,6 +19,7 @@ @interface BugsnagStackframeTest : XCTestCase @implementation BugsnagStackframeTest - (void)setUp { + [super setUp]; self.frameDict = @{ @"symbol_addr": @0x10b574fa0, @"instruction_addr": @0x10b5756bf, diff --git a/Tests/BugsnagTests/BugsnagStacktraceTest.m b/Tests/BugsnagTests/BugsnagStacktraceTest.m index 123184ac8..e11e94611 100644 --- a/Tests/BugsnagTests/BugsnagStacktraceTest.m +++ b/Tests/BugsnagTests/BugsnagStacktraceTest.m @@ -6,11 +6,11 @@ // Copyright © 2020 Bugsnag. All rights reserved. // -#import +#import "BSGTestCase.h" #import "BugsnagStacktrace.h" -@interface BugsnagStacktraceTest : XCTestCase +@interface BugsnagStacktraceTest : BSGTestCase @property NSDictionary *frameDict; @property NSArray *binaryImages; @end @@ -18,6 +18,7 @@ @interface BugsnagStacktraceTest : XCTestCase @implementation BugsnagStacktraceTest - (void)setUp { + [super setUp]; self.frameDict = @{ @"symbol_addr": @0x10b574fa0, @"instruction_addr": @0x10b5756bf, diff --git a/Tests/BugsnagTests/BugsnagSwiftConfigurationTests.swift b/Tests/BugsnagTests/BugsnagSwiftConfigurationTests.swift index b10f56e4f..fa648f29f 100644 --- a/Tests/BugsnagTests/BugsnagSwiftConfigurationTests.swift +++ b/Tests/BugsnagTests/BugsnagSwiftConfigurationTests.swift @@ -6,10 +6,9 @@ // Copyright © 2020 Bugsnag. All rights reserved. // -import XCTest import Bugsnag -class BugsnagSwiftConfigurationTests: XCTestCase { +class BugsnagSwiftConfigurationTests: BSGTestCase { /** * Objective C trailing-NSError* initializers are translated into throwing diff --git a/Tests/BugsnagTests/BugsnagSwiftPublicAPITests.swift b/Tests/BugsnagTests/BugsnagSwiftPublicAPITests.swift index a5b53d9a5..5b4ec5211 100644 --- a/Tests/BugsnagTests/BugsnagSwiftPublicAPITests.swift +++ b/Tests/BugsnagTests/BugsnagSwiftPublicAPITests.swift @@ -6,7 +6,7 @@ // Copyright © 2020 Bugsnag. All rights reserved. // -import XCTest +import Bugsnag /** * Test all public APIs from Swift. Purely existence tests, no attempt to verify correctness @@ -34,7 +34,7 @@ class myMetadata: NSObject, BugsnagMetadataStore, BugsnagClassLevelMetadataStore func clearMetadata(section sectionName: String, key: String) {} } -class BugsnagSwiftPublicAPITests: XCTestCase { +class BugsnagSwiftPublicAPITests: BSGTestCase { let apiKey = "01234567890123456789012345678901" let ex = NSException(name: NSExceptionName("exception"), diff --git a/Tests/BugsnagTests/BugsnagSwiftTests.swift b/Tests/BugsnagTests/BugsnagSwiftTests.swift index a30eab783..2e0511c63 100644 --- a/Tests/BugsnagTests/BugsnagSwiftTests.swift +++ b/Tests/BugsnagTests/BugsnagSwiftTests.swift @@ -7,9 +7,9 @@ // // Swift unit tests of global Bugsnag behaviour -import XCTest +import Bugsnag -class BugsnagSwiftTests: XCTestCase { +class BugsnagSwiftTests: BSGTestCase { /** * Confirm that the addMetadata() method is exposed to Swift correctly diff --git a/Tests/BugsnagTests/BugsnagTests.m b/Tests/BugsnagTests/BugsnagTests.m index 268f76665..da803d83b 100644 --- a/Tests/BugsnagTests/BugsnagTests.m +++ b/Tests/BugsnagTests/BugsnagTests.m @@ -7,7 +7,7 @@ // // Unit tests of global Bugsnag behaviour -#import +#import "BSGTestCase.h" #import "Bugsnag.h" #import "BugsnagClient+Private.h" @@ -18,7 +18,7 @@ // MARK: - BugsnagTests -@interface BugsnagTests : XCTestCase +@interface BugsnagTests : BSGTestCase @end @implementation BugsnagTests diff --git a/Tests/BugsnagTests/BugsnagThreadSerializationTest.m b/Tests/BugsnagTests/BugsnagThreadSerializationTest.m index 0a41b0c29..98e41a76e 100644 --- a/Tests/BugsnagTests/BugsnagThreadSerializationTest.m +++ b/Tests/BugsnagTests/BugsnagThreadSerializationTest.m @@ -3,11 +3,11 @@ // Copyright (c) 2018 Bugsnag. All rights reserved. // -#import +#import "BSGTestCase.h" #import "BugsnagEvent+Private.h" -@interface BugsnagThreadSerializationTest : XCTestCase +@interface BugsnagThreadSerializationTest : BSGTestCase @end @implementation BugsnagThreadSerializationTest diff --git a/Tests/BugsnagTests/BugsnagThreadTests.m b/Tests/BugsnagTests/BugsnagThreadTests.m index 6f664aa1f..75d9305e2 100644 --- a/Tests/BugsnagTests/BugsnagThreadTests.m +++ b/Tests/BugsnagTests/BugsnagThreadTests.m @@ -6,7 +6,7 @@ // Copyright © 2020 Bugsnag. All rights reserved. // -#import +#import "BSGTestCase.h" #import "BSG_KSMachHeaders.h" #import "BugsnagStackframe+Private.h" @@ -15,7 +15,7 @@ #import #import -@interface BugsnagThreadTests : XCTestCase +@interface BugsnagThreadTests : BSGTestCase @property NSArray *binaryImages; @property NSDictionary *thread; @end @@ -23,11 +23,13 @@ @interface BugsnagThreadTests : XCTestCase @implementation BugsnagThreadTests + (void)setUp { + [super setUp]; bsg_mach_headers_initialize(); bsg_mach_headers_get_images(); // Ensure call stack can be symbolicated } - (void)setUp { + [super setUp]; self.thread = @{ @"current_thread": @YES, @"crashed": @YES, diff --git a/Tests/BugsnagTests/BugsnagUserTest.m b/Tests/BugsnagTests/BugsnagUserTest.m index c834b89e3..b74779ed5 100644 --- a/Tests/BugsnagTests/BugsnagUserTest.m +++ b/Tests/BugsnagTests/BugsnagUserTest.m @@ -6,12 +6,12 @@ // Copyright © 2017 Bugsnag. All rights reserved. // -#import +#import "BSGTestCase.h" #import "BugsnagEvent+Private.h" #import "BugsnagUser+Private.h" -@interface BugsnagUserTest : XCTestCase +@interface BugsnagUserTest : BSGTestCase @end @implementation BugsnagUserTest diff --git a/Tests/BugsnagTests/ClientApiValidationTest.m b/Tests/BugsnagTests/ClientApiValidationTest.m index 75a5c3bca..b24edd3ae 100644 --- a/Tests/BugsnagTests/ClientApiValidationTest.m +++ b/Tests/BugsnagTests/ClientApiValidationTest.m @@ -6,20 +6,22 @@ // Copyright © 2020 Bugsnag Inc. All rights reserved. // -#import +#import "BSGTestCase.h" + #import #import "BugsnagTestConstants.h" /** * Validates that the Client API interface handles any invalid input gracefully. */ -@interface ClientApiValidationTest : XCTestCase +@interface ClientApiValidationTest : BSGTestCase @property BugsnagClient *client; @end @implementation ClientApiValidationTest - (void)setUp { + [super setUp]; BugsnagConfiguration *config = [[BugsnagConfiguration alloc] initWithApiKey:DUMMY_APIKEY_32CHAR_1]; [config addOnSendErrorBlock:^BOOL(BugsnagEvent *event) { return NO; diff --git a/Tests/BugsnagTests/ConfigurationApiValidationTest.m b/Tests/BugsnagTests/ConfigurationApiValidationTest.m index 2c4c0fb8b..3cb8a1101 100644 --- a/Tests/BugsnagTests/ConfigurationApiValidationTest.m +++ b/Tests/BugsnagTests/ConfigurationApiValidationTest.m @@ -6,7 +6,8 @@ // Copyright © 2020 Bugsnag Inc. All rights reserved. // -#import +#import "BSGTestCase.h" + #import #import "BugsnagConfiguration+Private.h" #import "BugsnagPlugin.h" @@ -23,13 +24,14 @@ - (void)unload {} /** * Validates that the Configuration API interface handles any invalid input gracefully. */ -@interface ConfigurationApiValidationTest : XCTestCase +@interface ConfigurationApiValidationTest : BSGTestCase @property BugsnagConfiguration *config; @end @implementation ConfigurationApiValidationTest - (void)setUp { + [super setUp]; self.config = [[BugsnagConfiguration alloc] initWithApiKey:DUMMY_APIKEY_32CHAR_1]; } diff --git a/Tests/BugsnagTests/EventApiValidationTest.m b/Tests/BugsnagTests/EventApiValidationTest.m index 164093a9a..5e964756f 100644 --- a/Tests/BugsnagTests/EventApiValidationTest.m +++ b/Tests/BugsnagTests/EventApiValidationTest.m @@ -6,7 +6,7 @@ // Copyright © 2020 Bugsnag Inc. All rights reserved. // -#import +#import "BSGTestCase.h" #import #import "BugsnagEvent+Private.h" @@ -14,13 +14,14 @@ /** * Validates that the Event API interface handles any invalid input gracefully. */ -@interface EventApiValidationTest : XCTestCase +@interface EventApiValidationTest : BSGTestCase @property BugsnagEvent *event; @end @implementation EventApiValidationTest - (void)setUp { + [super setUp]; self.event = [[BugsnagEvent alloc] initWithKSReport:@{@"user": @{}}]; } diff --git a/Tests/BugsnagTests/FileBasedTest.h b/Tests/BugsnagTests/FileBasedTest.h index 70e231638..270e78fd6 100644 --- a/Tests/BugsnagTests/FileBasedTest.h +++ b/Tests/BugsnagTests/FileBasedTest.h @@ -6,9 +6,9 @@ // Copyright © 2023 Bugsnag. All rights reserved. // -#import +#import "BSGTestCase.h" -@interface FileBasedTest : XCTestCase +@interface FileBasedTest : BSGTestCase @property(readwrite, nonatomic) NSString *filePath; diff --git a/Tests/BugsnagTests/FileBasedTest.m b/Tests/BugsnagTests/FileBasedTest.m index 219550380..849f11ab0 100644 --- a/Tests/BugsnagTests/FileBasedTest.m +++ b/Tests/BugsnagTests/FileBasedTest.m @@ -15,6 +15,7 @@ - (NSString *)newPath { } - (void)setUp { + [super setUp]; self.filePath = [self newPath]; } diff --git a/Tests/BugsnagTests/Swizzle.h b/Tests/BugsnagTests/Swizzle.h new file mode 100644 index 000000000..68c22611f --- /dev/null +++ b/Tests/BugsnagTests/Swizzle.h @@ -0,0 +1,36 @@ +// +// Swizzle.h +// Bugsnag +// +// Created by Karl Stenerud on 21.04.23. +// Copyright © 2023 Bugsnag. All rights reserved. +// + +#pragma once + +#import + +namespace bugsnag { + +class ObjCSwizzle { +public: + /** + * Replace a class's current method implementation with a new implementation block, returning the replaced one. + * Returns nil if the method was not found (in the class or any superclass). + */ + static IMP _Nullable setClassMethodImplementation(Class _Nonnull clazz, SEL _Nonnull selector, id _Nonnull implementationBlock) noexcept; + + /** + * Replace a class's override of a method (i.e. only if this class overrides the method). No superclass implementation is replaced. + * Returns nil if no method was replaced (either method not found, or this class doesn't overrde the method). + */ + static IMP _Nullable replaceInstanceMethodOverride(Class _Nonnull cls, SEL _Nonnull name, id _Nonnull block) noexcept; + + /** + * Get any classes or superclasses that implement the specified selector. + */ + static NSArray * _Nonnull getClassesWithSelector(Class _Nullable cls, SEL _Nonnull selector) noexcept; + +}; + +} diff --git a/Tests/BugsnagTests/Swizzle.mm b/Tests/BugsnagTests/Swizzle.mm new file mode 100644 index 000000000..abc784471 --- /dev/null +++ b/Tests/BugsnagTests/Swizzle.mm @@ -0,0 +1,68 @@ +// +// Swizzle.mm +// Bugsnag +// +// Created by Karl Stenerud on 21.04.23. +// Copyright © 2023 Bugsnag. All rights reserved. +// + +#import "Swizzle.h" +#import + +namespace bugsnag { + +IMP ObjCSwizzle::setClassMethodImplementation(Class _Nonnull clazz, SEL selector, id _Nonnull implementationBlock) noexcept { + Method method = class_getClassMethod(clazz, selector); + if (method) { + return method_setImplementation(method, imp_implementationWithBlock(implementationBlock)); + } else { + NSLog(@"Could not set IMP for selector %s on class %@", sel_getName(selector), clazz); + return nil; + } +} + +IMP ObjCSwizzle::replaceInstanceMethodOverride(Class clazz, SEL selector, id block) noexcept { + Method method = nullptr; + + // Not using class_getInstanceMethod because we don't want to modify the + // superclass's implementation. + auto methodCount = 0U; + Method *methods = class_copyMethodList(clazz, &methodCount); + if (methods) { + for (auto i = 0U; i < methodCount; i++) { + if (sel_isEqual(method_getName(methods[i]), selector)) { + method = methods[i]; + break; + } + } + free(methods); + } + + if (!method) { + // This is not considered an error. + return nil; + } + + return method_setImplementation(method, imp_implementationWithBlock(block)); +} + +NSArray *ObjCSwizzle::getClassesWithSelector(Class cls, SEL selector) noexcept { + NSMutableArray *result = [NSMutableArray new]; + for (; class_getInstanceMethod(cls, selector); cls = [cls superclass]) { + if (!cls) { + break; + } + Class superCls = [cls superclass]; + Method classMethod = class_getInstanceMethod(cls, selector); + Method superMethod = class_getInstanceMethod(superCls, selector); + IMP classIMP = classMethod ? method_getImplementation(classMethod) : nil; + IMP superIMP = superMethod ? method_getImplementation(superMethod) : nil; + if (classIMP != superIMP) { + [result addObject:(Class _Nonnull)cls]; + } + } + return result; +}; + + +} diff --git a/Tests/BugsnagTests/Tests-Bridging-Header.h b/Tests/BugsnagTests/Tests-Bridging-Header.h index c54081022..3603229d8 100644 --- a/Tests/BugsnagTests/Tests-Bridging-Header.h +++ b/Tests/BugsnagTests/Tests-Bridging-Header.h @@ -5,3 +5,4 @@ #import #import "BugsnagTestConstants.h" +#import "BSGTestCase.h" diff --git a/Tests/KSCrashTests/BSG_KSFileTests.m b/Tests/KSCrashTests/BSG_KSFileTests.m index 622563519..f4ad55f71 100644 --- a/Tests/KSCrashTests/BSG_KSFileTests.m +++ b/Tests/KSCrashTests/BSG_KSFileTests.m @@ -20,6 +20,7 @@ @interface BSG_KSFileTests : XCTestCase @implementation BSG_KSFileTests - (void)setUp { + [super setUp]; self.filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:[self description]]; self.fileDescriptor = open(self.filePath.fileSystemRepresentation, O_RDWR | O_CREAT | O_EXCL, 0644); } diff --git a/Tests/KSCrashTests/BSG_KSMachHeadersTests.m b/Tests/KSCrashTests/BSG_KSMachHeadersTests.m index 3d5370417..a41c082bd 100644 --- a/Tests/KSCrashTests/BSG_KSMachHeadersTests.m +++ b/Tests/KSCrashTests/BSG_KSMachHeadersTests.m @@ -53,6 +53,7 @@ @interface BSG_KSMachHeadersTests : XCTestCase @implementation BSG_KSMachHeadersTests - (void)setUp { + [super setUp]; bsg_mach_headers_initialize(); } diff --git a/Tests/KSCrashTests/KSCrashNames_Test.m b/Tests/KSCrashTests/KSCrashNames_Test.m index 01f1f17f2..77947e9fc 100644 --- a/Tests/KSCrashTests/KSCrashNames_Test.m +++ b/Tests/KSCrashTests/KSCrashNames_Test.m @@ -16,14 +16,6 @@ @interface KSCrashNames_Test : XCTestCase @implementation KSCrashNames_Test -- (void)setUp { - // Put setup code here. This method is called before the invocation of each test method in the class. -} - -- (void)tearDown { - // Put teardown code here. This method is called after the invocation of each test method in the class. -} - - (void)testValidStates { XCTAssertTrue(strcmp(bsg_kscrashthread_state_name(TH_STATE_RUNNING), "TH_STATE_RUNNING") == 0); XCTAssertTrue(strcmp(bsg_kscrashthread_state_name(TH_STATE_STOPPED), "TH_STATE_STOPPED") == 0); diff --git a/Tests/KSCrashTests/KSCrashSentry_Tests.m b/Tests/KSCrashTests/KSCrashSentry_Tests.m index c744d2370..4f6fa5365 100755 --- a/Tests/KSCrashTests/KSCrashSentry_Tests.m +++ b/Tests/KSCrashTests/KSCrashSentry_Tests.m @@ -44,6 +44,7 @@ @interface KSCrashSentry_Tests : XCTestCase @end @implementation KSCrashSentry_Tests - (void) setUp { + [super setUp]; bsg_kscrashsentry_installWithContext(&context, BSG_KSCrashTypeAll, onCrash); } From 6840c9edbb60931c373c0c0ec89f8ccdac47f6f0 Mon Sep 17 00:00:00 2001 From: Karl Stenerud Date: Wed, 1 Nov 2023 11:05:11 +0100 Subject: [PATCH 55/61] Check the app's bundle version as an extra precaution against false negatives in OOM detection --- Bugsnag/Helpers/BSGRunContext.h | 3 ++- Bugsnag/Helpers/BSGRunContext.m | 24 +++++++++++++++++++----- Bugsnag/Helpers/BSGUtils.h | 6 ++++++ Bugsnag/Helpers/BSGUtils.m | 7 +++++++ CHANGELOG.md | 8 ++++++++ Tests/BugsnagTests/BSGOutOfMemoryTests.m | 3 +++ 6 files changed, 45 insertions(+), 6 deletions(-) diff --git a/Bugsnag/Helpers/BSGRunContext.h b/Bugsnag/Helpers/BSGRunContext.h index a69fd0273..a6a02d552 100644 --- a/Bugsnag/Helpers/BSGRunContext.h +++ b/Bugsnag/Helpers/BSGRunContext.h @@ -19,7 +19,7 @@ // During development this is not strictly necessary since last run's data will // not be loaded if the struct's size has changed. // -#define BSGRUNCONTEXT_VERSION 4 +#define BSGRUNCONTEXT_VERSION 5 struct BSGRunContext { long structVersion; @@ -50,6 +50,7 @@ struct BSGRunContext { unsigned long long memoryAvailable; unsigned long long memoryFootprint; unsigned long long memoryLimit; + char bundleVersion[32]; // Won't actually get this long but just to be sure. }; /// Information about the current run of the app / process. diff --git a/Bugsnag/Helpers/BSGRunContext.m b/Bugsnag/Helpers/BSGRunContext.m index c7ce2a57b..1af6767d3 100644 --- a/Bugsnag/Helpers/BSGRunContext.m +++ b/Bugsnag/Helpers/BSGRunContext.m @@ -71,7 +71,13 @@ static void InitRunContext(void) { if (image && image->uuid) { uuid_copy(bsg_runContext->machoUUID, image->uuid); } - + + NSString *bundleVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"]; + const char *bundleVersionStr = (const char*)[bundleVersion cStringUsingEncoding:NSUTF8StringEncoding]; + if (bundleVersionStr != nil) { + bsg_safe_strncpy(bsg_runContext->bundleVersion, bundleVersionStr, sizeof(bsg_runContext->bundleVersion)); + } + if ([NSThread isMainThread]) { bsg_runContext->isActive = GetIsActive(); } else { @@ -487,8 +493,13 @@ bool BSGRunContextWasKilled(void) { if (bsg_lastRunContext->bootTime != bsg_runContext->bootTime) { return NO; // The app may have been terminated due to the reboot } - + // Ignore unexpected terminations due to the app being upgraded + if (strncmp(bsg_lastRunContext->bundleVersion, + bsg_runContext->bundleVersion, + sizeof(bsg_runContext->bundleVersion)) != 0) { + return NO; + } if (uuid_compare(bsg_lastRunContext->machoUUID, bsg_runContext->machoUUID)) { return NO; } @@ -516,10 +527,13 @@ bool BSGRunContextWasKilled(void) { #define SIZEOF_STRUCT sizeof(struct BSGRunContext) -static struct BSGRunContext fallback; -struct BSGRunContext *bsg_runContext = &fallback; +static struct BSGRunContext bsg_runContext_fallback; +struct BSGRunContext *bsg_runContext = &bsg_runContext_fallback; -const struct BSGRunContext *bsg_lastRunContext; +static struct BSGRunContext bsg_lastRunContext_fallback = { + .structVersion = ~0, +}; +const struct BSGRunContext *bsg_lastRunContext = &bsg_lastRunContext_fallback; /// Opens the file and disables content protection, returning -1 on error. static int OpenFile(NSString *_Nonnull path) { diff --git a/Bugsnag/Helpers/BSGUtils.h b/Bugsnag/Helpers/BSGUtils.h index 06cb3d473..d462290fa 100644 --- a/Bugsnag/Helpers/BSGUtils.h +++ b/Bugsnag/Helpers/BSGUtils.h @@ -39,6 +39,12 @@ static inline NSString * _Nullable BSGStringFromClass(Class _Nullable cls) { return cls ? NSStringFromClass((Class _Nonnull)cls) : nil; } +/** + * Copy characters from src to dst, up to a maximum of length bytes (including the NUL terminator). + * Unlike strncpy, this function always ensures that dst is NUL terminated (if length > 0). + */ +void bsg_safe_strncpy(char *dst, const char *src, size_t length); + NS_ASSUME_NONNULL_END __END_DECLS diff --git a/Bugsnag/Helpers/BSGUtils.m b/Bugsnag/Helpers/BSGUtils.m index ae2608ec4..04e8d9863 100644 --- a/Bugsnag/Helpers/BSGUtils.m +++ b/Bugsnag/Helpers/BSGUtils.m @@ -10,6 +10,13 @@ #import "BugsnagLogger.h" +void bsg_safe_strncpy(char *dst, const char *src, size_t length) { + if (length > 0) { + strncpy(dst, src, length); + dst[length-1] = 0; + } +} + char *_Nullable BSGCStringWithData(NSData *_Nullable data) { char *buffer; if (data.length && (buffer = calloc(1, data.length + 1))) { diff --git a/CHANGELOG.md b/CHANGELOG.md index 01df119da..df4781201 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,14 @@ Changelog ========= +## TBD + +### Bug fixes + +* Check app version to avoid detecting an app upgrade as an OOM + [1597](https://github.com/bugsnag/bugsnag-cocoa/pull/1597) + + ## 6.27.2 (2023-07-24) ### Enhancements diff --git a/Tests/BugsnagTests/BSGOutOfMemoryTests.m b/Tests/BugsnagTests/BSGOutOfMemoryTests.m index 8cafa6c4f..ca53178ba 100644 --- a/Tests/BugsnagTests/BSGOutOfMemoryTests.m +++ b/Tests/BugsnagTests/BSGOutOfMemoryTests.m @@ -133,6 +133,9 @@ - (void)testLastLaunchTerminatedUnexpectedly { XCTAssertFalse(BSGRunContextWasKilled()); uuid_copy(lastRunContext.machoUUID, bsg_runContext->machoUUID); + strncpy(lastRunContext.bundleVersion, "999.99", sizeof(lastRunContext.bundleVersion)); + XCTAssertFalse(BSGRunContextWasKilled()); + lastRunContext.bootTime = 0; XCTAssertFalse(BSGRunContextWasKilled()); lastRunContext.bootTime = bsg_runContext->bootTime; From 795dcabc3714833648485115a708a0d19c36dc33 Mon Sep 17 00:00:00 2001 From: Alex Moinet Date: Thu, 26 Oct 2023 11:45:16 +0100 Subject: [PATCH 56/61] Add release trigger for downstream targets to update --- .github/workflows/downstream_updates.yml | 31 ++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 .github/workflows/downstream_updates.yml diff --git a/.github/workflows/downstream_updates.yml b/.github/workflows/downstream_updates.yml new file mode 100644 index 000000000..e140a4f42 --- /dev/null +++ b/.github/workflows/downstream_updates.yml @@ -0,0 +1,31 @@ +name: downstream-updates + +on: + release: + types: [released] + workflow_dispatch: + inputs: + target_version: + description: 'Version of the submodule to update downstream repos to' + required: true + type: string + +jobs: + update-dependencies: + runs-on: ubuntu-latest + env: + RELEASE_VERSION: ${{ github.event_name == 'workflow_dispatch' && inputs.target_version || github.event.release.tag_name }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + matrix: + downstream_repo: ['bugsnag/bugsnag-unity'] + steps: + - name: Install libcurl4-openssl-dev and net-tools + run: | + sudo apt-get update + sudo apt-get install libcurl4-openssl-dev net-tools + + - run: > + curl -X POST https://api.github.com/repos/${{ matrix.downstream_repo }}/dispatches + -H 'Content-Type: application/json' + -H "Authorization: Bearer $GITHUB_TOKEN" + -d '{"event_type":"update-dependency","client_payload": {"target_submodule":"bugsnag-cocoa", "target_version": "$RELEASE_VERSION"}}' From 45c607939996b69795d5b88f3073d0d9f0aaa27d Mon Sep 17 00:00:00 2001 From: Alex Moinet Date: Mon, 13 Nov 2023 14:32:58 +0000 Subject: [PATCH 57/61] Rebase and fix broken yaml --- .github/workflows/downstream_updates.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/downstream_updates.yml b/.github/workflows/downstream_updates.yml index e140a4f42..a299295a4 100644 --- a/.github/workflows/downstream_updates.yml +++ b/.github/workflows/downstream_updates.yml @@ -16,8 +16,9 @@ jobs: env: RELEASE_VERSION: ${{ github.event_name == 'workflow_dispatch' && inputs.target_version || github.event.release.tag_name }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - matrix: - downstream_repo: ['bugsnag/bugsnag-unity'] + strategy: + matrix: + downstream_repo: ['bugsnag/bugsnag-unity'] steps: - name: Install libcurl4-openssl-dev and net-tools run: | From 81e4ad9260c9b016dc1fac03e12f8ffc0cb06689 Mon Sep 17 00:00:00 2001 From: Steve Kirkland-Walton Date: Mon, 13 Nov 2023 16:55:29 +0000 Subject: [PATCH 58/61] Consistently fail-fast e2e test scenarios --- .buildkite/pipeline.full.yml | 6 ++++++ .buildkite/pipeline.yml | 34 ++++++++++++++++++---------------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/.buildkite/pipeline.full.yml b/.buildkite/pipeline.full.yml index d4eea6b16..7f5571300 100644 --- a/.buildkite/pipeline.full.yml +++ b/.buildkite/pipeline.full.yml @@ -32,6 +32,7 @@ steps: - "--device=IOS_15" - "--no-tunnel" - "--aws-public-ip" + - "--fail-fast" concurrency: 25 concurrency_group: 'bitbar' concurrency_method: eager @@ -56,6 +57,7 @@ steps: - "--device=IOS_15" - "--no-tunnel" - "--aws-public-ip" + - "--fail-fast" concurrency: 25 concurrency_group: 'bitbar' concurrency_method: eager @@ -268,6 +270,7 @@ steps: - "--farm=bs" - "--device=IOS_15" - "--appium-version=1.21.0" + - "--fail-fast" - "features/app_hangs.feature" concurrency: 5 concurrency_group: 'browserstack-app' @@ -296,6 +299,7 @@ steps: - "--farm=bs" - "--device=IOS_14" - "--appium-version=1.21.0" + - "--fail-fast" - "features/app_hangs.feature" concurrency: 5 concurrency_group: 'browserstack-app' @@ -324,6 +328,7 @@ steps: - "--farm=bs" - "--device=IOS_13" - "--appium-version=1.21.0" + - "--fail-fast" - "features/app_hangs.feature" concurrency: 5 concurrency_group: 'browserstack-app' @@ -352,6 +357,7 @@ steps: - "--farm=bs" - "--device=IOS_12" - "--appium-version=1.21.0" + - "--fail-fast" - "features/app_hangs.feature" concurrency: 5 concurrency_group: 'browserstack-app' diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index ead95af6d..10b2f567d 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -376,6 +376,7 @@ steps: - "--farm=bs" - "--device=IOS_16" - "--appium-version=1.21.0" + - "--fail-fast" - "features/app_hangs.feature" concurrency: 5 concurrency_group: 'browserstack-app' @@ -523,14 +524,14 @@ steps: run: cocoa-maze-runner service-ports: true command: - - --app=@/app/build/ipa_url_bs.txt - - --farm=bs - - --device=IOS_17 - - --appium-version=1.18.0 - - --a11y-locator - - --fail-fast - - --exclude=features/[e-z].*.feature$ - - --order=random + - "--app=@/app/build/ipa_url_bs.txt" + - "--farm=bs" + - "--device=IOS_17" + - "--appium-version=1.18.0" + - "--a11y-locator" + - "--fail-fast" + - "--exclude=features/[e-z].*.feature$" + - "--order=random" concurrency: 25 concurrency_group: 'browserstack-app' concurrency_method: eager @@ -554,14 +555,14 @@ steps: run: cocoa-maze-runner service-ports: true command: - - --app=@/app/build/ipa_url_bs.txt - - --farm=bs - - --device=IOS_17 - - --appium-version=1.18.0 - - --a11y-locator - - --fail-fast - - --exclude=features/[a-d].*.feature$ - - --order=random + - "--app=@/app/build/ipa_url_bs.txt" + - "--farm=bs" + - "--device=IOS_17" + - "--appium-version=1.18.0" + - "--a11y-locator" + - "--fail-fast" + - "--exclude=features/[a-d].*.feature$" + - "--order=random" concurrency: 25 concurrency_group: 'browserstack-app' concurrency_method: eager @@ -589,6 +590,7 @@ steps: - "--farm=bs" - "--device=IOS_11_0_IPHONE_8_PLUS" - "--appium-version=1.16.0" + - "--fail-fast" - "features/barebone_tests.feature" concurrency: 5 concurrency_group: 'browserstack-app' From 97c2aa0b5fa7f261623e038cb72d7ad0bd57915a Mon Sep 17 00:00:00 2001 From: neil b Date: Fri, 3 Nov 2023 14:45:47 -0700 Subject: [PATCH 59/61] update include statements --- Bugsnag/include/Bugsnag/BSG_KSCrashReportWriter.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Bugsnag/include/Bugsnag/BSG_KSCrashReportWriter.h b/Bugsnag/include/Bugsnag/BSG_KSCrashReportWriter.h index 610eb20f1..d49ee2a35 100644 --- a/Bugsnag/include/Bugsnag/BSG_KSCrashReportWriter.h +++ b/Bugsnag/include/Bugsnag/BSG_KSCrashReportWriter.h @@ -32,12 +32,12 @@ #define HDR_BSG_KSCrashReportWriter_h #ifdef __cplusplus -extern "C" { -#endif - #include #include +extern "C" { +#endif + /** * Encapsulates report writing functionality. */ From 9b847efb2897e7c97b677cdf42f50f6677e13bf3 Mon Sep 17 00:00:00 2001 From: Karl Stenerud Date: Mon, 13 Nov 2023 11:42:22 +0100 Subject: [PATCH 60/61] Move all include directives outside of the extern C sections --- .../KSCrash/Source/KSCrash/Recording/BSG_KSCrashC.h | 8 ++++---- .../Source/KSCrash/Recording/BSG_KSCrashContext.h | 8 ++++---- .../Source/KSCrash/Recording/BSG_KSCrashIdentifier.h | 1 + .../Source/KSCrash/Recording/BSG_KSCrashNames.h | 4 ++-- .../Source/KSCrash/Recording/BSG_KSCrashReport.h | 4 ++-- .../Source/KSCrash/Recording/BSG_KSCrashState.h | 6 +++--- .../KSCrash/Recording/Sentry/BSG_KSCrashSentry.h | 8 ++++---- .../Sentry/BSG_KSCrashSentry_CPPException.h | 4 ++-- .../Sentry/BSG_KSCrashSentry_MachException.h | 12 ++++++------ .../Recording/Sentry/BSG_KSCrashSentry_NSException.h | 4 ++-- .../Recording/Sentry/BSG_KSCrashSentry_Private.h | 6 +++--- .../Recording/Sentry/BSG_KSCrashSentry_Signal.h | 8 ++++---- .../KSCrash/Recording/Tools/BSG_KSArchSpecific.h | 8 -------- .../Source/KSCrash/Recording/Tools/BSG_KSBacktrace.h | 8 ++++---- .../Recording/Tools/BSG_KSBacktrace_Private.h | 8 ++++---- .../Recording/Tools/BSG_KSCrashStringConversion.h | 7 +++---- .../Source/KSCrash/Recording/Tools/BSG_KSFileUtils.h | 8 ++++---- .../Source/KSCrash/Recording/Tools/BSG_KSJSONCodec.h | 6 +++--- .../Source/KSCrash/Recording/Tools/BSG_KSLogger.h | 8 ++++---- .../Source/KSCrash/Recording/Tools/BSG_KSMach.h | 8 ++++---- .../Source/KSCrash/Recording/Tools/BSG_KSMachApple.h | 8 ++++---- .../KSCrash/Recording/Tools/BSG_KSSignalInfo.h | 4 ++-- .../Source/KSCrash/Recording/Tools/BSG_KSSysCtl.h | 8 ++++---- .../Source/KSCrash/Recording/Tools/BSG_Symbolicate.h | 4 ++-- Bugsnag/include/Bugsnag/BSG_KSCrashReportWriter.h | 2 +- 25 files changed, 76 insertions(+), 84 deletions(-) diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashC.h b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashC.h index b21f4f7e7..a4876fb3c 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashC.h +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashC.h @@ -30,14 +30,14 @@ #ifndef HDR_BSG_KSCrashC_h #define HDR_BSG_KSCrashC_h -#ifdef __cplusplus -extern "C" { -#endif - #include "BSG_KSCrashContext.h" #include +#ifdef __cplusplus +extern "C" { +#endif + /** Initialize the KSCrash system. Call this once, before any other function. * Note: This gets called automatically by [BSG_KSCrash sharedInstance]. */ diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashContext.h b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashContext.h index d55aaa6a0..994be9355 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashContext.h +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashContext.h @@ -30,10 +30,6 @@ #ifndef HDR_BSG_KSCrashContext_h #define HDR_BSG_KSCrashContext_h -#ifdef __cplusplus -extern "C" { -#endif - #include "BSG_KSCrashReportWriter.h" #include "BSG_KSCrashSentry.h" #include "BSG_KSCrashState.h" @@ -41,6 +37,10 @@ extern "C" { #include #include +#ifdef __cplusplus +extern "C" { +#endif + typedef struct { /** A unique identifier (UUID). */ char *crashID; diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashIdentifier.h b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashIdentifier.h index 3e05a6b48..f93713dde 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashIdentifier.h +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashIdentifier.h @@ -1,5 +1,6 @@ #ifndef HDR_BSG_KSCrashIdentifier_h #define HDR_BSG_KSCrashIdentifier_h + #include #ifdef __cplusplus diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashNames.h b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashNames.h index 3b62ffe36..c2ec5e26c 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashNames.h +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashNames.h @@ -9,12 +9,12 @@ #ifndef BSG_KSCrashNames_h #define BSG_KSCrashNames_h +#include + #ifdef __cplusplus extern "C" { #endif -#include - const char *bsg_kscrashthread_state_name(integer_t state); #ifdef __cplusplus diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashReport.h b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashReport.h index a6e690ae6..adcd6531c 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashReport.h +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashReport.h @@ -30,12 +30,12 @@ #ifndef HDR_BSG_KSCrashReport_h #define HDR_BSG_KSCrashReport_h +#include "BSG_KSCrashContext.h" + #ifdef __cplusplus extern "C" { #endif -#include "BSG_KSCrashContext.h" - /** Write a standard crash report to a file. * * @param crashContext Contextual information about the crash and environment. diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashState.h b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashState.h index f65ac0b4f..06bd4b44a 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashState.h +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashState.h @@ -31,13 +31,13 @@ #ifndef HDR_BSG_KSCrashState_h #define HDR_BSG_KSCrashState_h +#include +#include + #ifdef __cplusplus extern "C" { #endif -#include -#include - typedef struct { // Saved data diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/Sentry/BSG_KSCrashSentry.h b/Bugsnag/KSCrash/Source/KSCrash/Recording/Sentry/BSG_KSCrashSentry.h index 830f1beb7..f89d0a2c8 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/Sentry/BSG_KSCrashSentry.h +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/Sentry/BSG_KSCrashSentry.h @@ -30,10 +30,6 @@ #ifndef HDR_BSG_KSCrashSentry_h #define HDR_BSG_KSCrashSentry_h -#ifdef __cplusplus -extern "C" { -#endif - #include "BSG_KSArchSpecific.h" #include "BSG_KSCrashType.h" @@ -42,6 +38,10 @@ extern "C" { #include #include +#ifdef __cplusplus +extern "C" { +#endif + // Some structures must be pre-allocated, so we must set an upper limit. // Note: Memory usage = 16 bytes per thread, pre-allocated once. #define MAX_CAPTURED_THREADS 1000 diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/Sentry/BSG_KSCrashSentry_CPPException.h b/Bugsnag/KSCrash/Source/KSCrash/Recording/Sentry/BSG_KSCrashSentry_CPPException.h index b1b007094..8c4bc7b7b 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/Sentry/BSG_KSCrashSentry_CPPException.h +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/Sentry/BSG_KSCrashSentry_CPPException.h @@ -25,12 +25,12 @@ #ifndef HDR_BSG_KSCrashSentry_CPPException_h #define HDR_BSG_KSCrashSentry_CPPException_h +#include "BSG_KSCrashSentry.h" + #ifdef __cplusplus extern "C" { #endif -#include "BSG_KSCrashSentry.h" - /** Install the C++ exception handler. * * @param context Contextual information for the crash handler. diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/Sentry/BSG_KSCrashSentry_MachException.h b/Bugsnag/KSCrash/Source/KSCrash/Recording/Sentry/BSG_KSCrashSentry_MachException.h index c933412cf..059be9bc9 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/Sentry/BSG_KSCrashSentry_MachException.h +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/Sentry/BSG_KSCrashSentry_MachException.h @@ -30,18 +30,18 @@ #ifndef HDR_BSG_KSCrashSentry_MachException_h #define HDR_BSG_KSCrashSentry_MachException_h -#ifdef __cplusplus -extern "C" { -#endif - #include "BSGDefines.h" -#if BSG_HAVE_MACH_EXCEPTIONS - #include "BSG_KSCrashSentry.h" #include #include +#if BSG_HAVE_MACH_EXCEPTIONS + +#ifdef __cplusplus +extern "C" { +#endif + /** Install our custom mach exception handler. * * @param context Contextual information for the crash handler. diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/Sentry/BSG_KSCrashSentry_NSException.h b/Bugsnag/KSCrash/Source/KSCrash/Recording/Sentry/BSG_KSCrashSentry_NSException.h index 956930485..247d0660a 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/Sentry/BSG_KSCrashSentry_NSException.h +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/Sentry/BSG_KSCrashSentry_NSException.h @@ -30,12 +30,12 @@ #ifndef HDR_BSG_KSCrashSentry_NSException_h #define HDR_BSG_KSCrashSentry_NSException_h +#include "BSG_KSCrashSentry.h" + #ifdef __cplusplus extern "C" { #endif -#include "BSG_KSCrashSentry.h" - /** Install our custom NSException handler. * * @param context The crash context to fill out when a crash occurs. diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/Sentry/BSG_KSCrashSentry_Private.h b/Bugsnag/KSCrash/Source/KSCrash/Recording/Sentry/BSG_KSCrashSentry_Private.h index d1c3dfbd9..136ac388f 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/Sentry/BSG_KSCrashSentry_Private.h +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/Sentry/BSG_KSCrashSentry_Private.h @@ -27,13 +27,13 @@ #ifndef HDR_BSG_KSCrashSentry_Private_h #define HDR_BSG_KSCrashSentry_Private_h +#include "BSG_KSCrashSentry.h" +#include "BSGDefines.h" + #ifdef __cplusplus extern "C" { #endif -#include "BSG_KSCrashSentry.h" -#include "BSGDefines.h" - #if BSG_HAVE_MACH_THREADS /** Suspend all non-reserved threads. * diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/Sentry/BSG_KSCrashSentry_Signal.h b/Bugsnag/KSCrash/Source/KSCrash/Recording/Sentry/BSG_KSCrashSentry_Signal.h index 39f72d898..a42e2b6e9 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/Sentry/BSG_KSCrashSentry_Signal.h +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/Sentry/BSG_KSCrashSentry_Signal.h @@ -30,16 +30,16 @@ #ifndef HDR_BSG_KSCrashSentry_Signal_h #define HDR_BSG_KSCrashSentry_Signal_h -#ifdef __cplusplus -extern "C" { -#endif - #include "BSGDefines.h" #if BSG_HAVE_SIGNAL #include "BSG_KSCrashSentry.h" +#ifdef __cplusplus +extern "C" { +#endif + /** Install our custom signal handler. * * @param context The crash context to fill out when a crash occurs. diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSArchSpecific.h b/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSArchSpecific.h index 7b9d3a89a..ca0cf292f 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSArchSpecific.h +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSArchSpecific.h @@ -30,10 +30,6 @@ #ifndef HDR_BSG_KSArchSpecific_h #define HDR_BSG_KSArchSpecific_h -#ifdef __cplusplus -extern "C" { -#endif - #include #ifdef __arm64__ @@ -42,8 +38,4 @@ extern "C" { #define BSG_STRUCT_MCONTEXT_L _STRUCT_MCONTEXT #endif -#ifdef __cplusplus -} -#endif - #endif // HDR_KSArchSpecific_h diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSBacktrace.h b/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSBacktrace.h index e9b169d9c..dec94f2e0 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSBacktrace.h +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSBacktrace.h @@ -30,16 +30,16 @@ #ifndef HDR_BSG_KSBacktrace_h #define HDR_BSG_KSBacktrace_h -#ifdef __cplusplus -extern "C" { -#endif - #include "BSG_Symbolicate.h" #include "BSGDefines.h" #include #include +#ifdef __cplusplus +extern "C" { +#endif + /** * Remove any pointer tagging from an instruction address * diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSBacktrace_Private.h b/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSBacktrace_Private.h index 5f83ae3e3..650fd73fd 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSBacktrace_Private.h +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSBacktrace_Private.h @@ -27,16 +27,16 @@ #ifndef HDR_BSG_KSBacktrace_private_h #define HDR_BSG_KSBacktrace_private_h -#ifdef __cplusplus -extern "C" { -#endif - #include "BSG_KSArchSpecific.h" #include "BSG_KSBacktrace.h" #include #include +#ifdef __cplusplus +extern "C" { +#endif + /** Point at which bsg_ksbt_backtraceLength() will give up trying to count. * * This really only comes into play during a stack overflow. diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSCrashStringConversion.h b/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSCrashStringConversion.h index 9c14994c3..91e051571 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSCrashStringConversion.h +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSCrashStringConversion.h @@ -9,14 +9,13 @@ #ifndef BSG_KSCrashStringConversion_h #define BSG_KSCrashStringConversion_h +#include +#include + #ifdef __cplusplus extern "C" { #endif - -#include -#include - /** * Convert an unsigned integer to a string. * This will write a maximum of 21 characters (including the NUL) to dst. diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSFileUtils.h b/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSFileUtils.h index 7ef0910a7..fa58fde0b 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSFileUtils.h +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSFileUtils.h @@ -30,14 +30,14 @@ #ifndef HDR_BSG_KSFileUtils_h #define HDR_BSG_KSFileUtils_h -#ifdef __cplusplus -extern "C" { -#endif - #include #include #include +#ifdef __cplusplus +extern "C" { +#endif + /** Get the last entry in a file path. Assumes UNIX style separators. * * @param path The file path. diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSJSONCodec.h b/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSJSONCodec.h index a7d10ffb1..b55f656b3 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSJSONCodec.h +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSJSONCodec.h @@ -30,13 +30,13 @@ #ifndef HDR_BSG_KSJSONCodec_h #define HDR_BSG_KSJSONCodec_h +#include +#include + #ifdef __cplusplus extern "C" { #endif -#include -#include - /* Tells the encoder to automatically determine the length of a field value. * Currently, this is done using strlen(). */ diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSLogger.h b/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSLogger.h index 6d9b076e6..d0273d531 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSLogger.h +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSLogger.h @@ -27,14 +27,14 @@ #ifndef HDR_BSG_KSLogger_h #define HDR_BSG_KSLogger_h -#ifdef __cplusplus -extern "C" { -#endif - #include #include "BugsnagLogger.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * Enables low-level logging. * diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSMach.h b/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSMach.h index 0f3d99e04..f856c5194 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSMach.h +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSMach.h @@ -30,10 +30,6 @@ #ifndef HDR_BSG_KSMach_h #define HDR_BSG_KSMach_h -#ifdef __cplusplus -extern "C" { -#endif - #include "BSG_KSArchSpecific.h" #include "BSGDefines.h" @@ -42,6 +38,10 @@ extern "C" { #include #include +#ifdef __cplusplus +extern "C" { +#endif + // ============================================================================ #pragma mark - General Information - // ============================================================================ diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSMachApple.h b/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSMachApple.h index 0a1a0f98f..0ac5936c0 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSMachApple.h +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSMachApple.h @@ -19,14 +19,14 @@ #ifndef HDR_BSG_KSMachApple_h #define HDR_BSG_KSMachApple_h -#ifdef __cplusplus -extern "C" { -#endif - #include #include #include +#ifdef __cplusplus +extern "C" { +#endif + // Avoid name clashes when copying structs from private headers #define pthread_t internal_pthread_t #define dispatch_queue_s internal_dispatch_queue_s diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSSignalInfo.h b/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSSignalInfo.h index ca32e9947..bf7b97db8 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSSignalInfo.h +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSSignalInfo.h @@ -30,12 +30,12 @@ #ifndef HDR_BSG_KSSignalInfo_h #define HDR_BSG_KSSignalInfo_h +#include + #ifdef __cplusplus extern "C" { #endif -#include - /** Get the name of a signal. * * @param signal The signal. diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSSysCtl.h b/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSSysCtl.h index 86b4c206b..b12e31afa 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSSysCtl.h +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSSysCtl.h @@ -30,15 +30,15 @@ #ifndef HDR_BSG_KSSysCtl_h #define HDR_BSG_KSSysCtl_h -#ifdef __cplusplus -extern "C" { -#endif - #include #include #include #include +#ifdef __cplusplus +extern "C" { +#endif + /** Get an int32 value via sysctl by name. * * @param name The name of the command. diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_Symbolicate.h b/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_Symbolicate.h index 2cd3bc53b..590e71aa8 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_Symbolicate.h +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_Symbolicate.h @@ -8,12 +8,12 @@ #ifndef BSG_Symbolicate_h #define BSG_Symbolicate_h +#include + #ifdef __cplusplus extern "C" { #endif -#include - struct bsg_symbolicate_result { struct bsg_mach_image *image; uintptr_t function_address; diff --git a/Bugsnag/include/Bugsnag/BSG_KSCrashReportWriter.h b/Bugsnag/include/Bugsnag/BSG_KSCrashReportWriter.h index d49ee2a35..f3a9cbd59 100644 --- a/Bugsnag/include/Bugsnag/BSG_KSCrashReportWriter.h +++ b/Bugsnag/include/Bugsnag/BSG_KSCrashReportWriter.h @@ -31,10 +31,10 @@ #ifndef HDR_BSG_KSCrashReportWriter_h #define HDR_BSG_KSCrashReportWriter_h -#ifdef __cplusplus #include #include +#ifdef __cplusplus extern "C" { #endif From 2405f9d50f3f9b8725ada3e5c96d1fa5380fd959 Mon Sep 17 00:00:00 2001 From: Karl Stenerud Date: Wed, 15 Nov 2023 13:18:11 +0100 Subject: [PATCH 61/61] Release v6.27.3 --- .jazzy.yaml | 4 ++-- Bugsnag.podspec.json | 4 ++-- Bugsnag/Payload/BugsnagNotifier.m | 2 +- BugsnagNetworkRequestPlugin.podspec.json | 6 +++--- CHANGELOG.md | 18 ++++++++++++++++-- Framework/Info.plist | 2 +- Tests/BugsnagTests/Info.plist | 2 +- Tests/TestHost-iOS/Info.plist | 2 +- VERSION | 2 +- 9 files changed, 28 insertions(+), 14 deletions(-) diff --git a/.jazzy.yaml b/.jazzy.yaml index 7e5b8e596..8c9ad4004 100644 --- a/.jazzy.yaml +++ b/.jazzy.yaml @@ -2,11 +2,11 @@ author_url: "https://www.bugsnag.com" author: "Bugsnag Inc" clean: false # avoid deleting docs/.git framework_root: "Bugsnag" -github_file_prefix: "https://github.com/bugsnag/bugsnag-cocoa/tree/v6.27.2/Bugsnag" +github_file_prefix: "https://github.com/bugsnag/bugsnag-cocoa/tree/v6.27.3/Bugsnag" github_url: "https://github.com/bugsnag/bugsnag-cocoa" hide_documentation_coverage: true module: "Bugsnag" -module_version: "6.27.2" +module_version: "6.27.3" objc: true output: "docs" readme: "README.md" diff --git a/Bugsnag.podspec.json b/Bugsnag.podspec.json index a4018ecd8..a63e40143 100644 --- a/Bugsnag.podspec.json +++ b/Bugsnag.podspec.json @@ -1,6 +1,6 @@ { "name": "Bugsnag", - "version": "6.27.2", + "version": "6.27.3", "summary": "The Bugsnag crash reporting framework for Apple platforms.", "homepage": "https://bugsnag.com", "license": "MIT", @@ -9,7 +9,7 @@ }, "source": { "git": "https://github.com/bugsnag/bugsnag-cocoa.git", - "tag": "v6.27.2" + "tag": "v6.27.3" }, "ios": { "frameworks": [ diff --git a/Bugsnag/Payload/BugsnagNotifier.m b/Bugsnag/Payload/BugsnagNotifier.m index 4c888aafa..4be649983 100644 --- a/Bugsnag/Payload/BugsnagNotifier.m +++ b/Bugsnag/Payload/BugsnagNotifier.m @@ -23,7 +23,7 @@ - (instancetype)init { #else _name = @"Bugsnag Objective-C"; #endif - _version = @"6.27.2"; + _version = @"6.27.3"; _url = @"https://github.com/bugsnag/bugsnag-cocoa"; _dependencies = @[]; } diff --git a/BugsnagNetworkRequestPlugin.podspec.json b/BugsnagNetworkRequestPlugin.podspec.json index fd7e80dce..9b50b097e 100644 --- a/BugsnagNetworkRequestPlugin.podspec.json +++ b/BugsnagNetworkRequestPlugin.podspec.json @@ -1,16 +1,16 @@ { "name": "BugsnagNetworkRequestPlugin", - "version": "6.27.2", + "version": "6.27.3", "summary": "Network request monitoring support for Bugsnag.", "homepage": "https://bugsnag.com", "license": "MIT", "authors": { "Bugsnag": "notifiers@bugsnag.com" }, - "readme": "https://raw.githubusercontent.com/bugsnag/bugsnag-cocoa/v6.27.2/BugsnagNetworkRequestPlugin/README.md", + "readme": "https://raw.githubusercontent.com/bugsnag/bugsnag-cocoa/v6.27.3/BugsnagNetworkRequestPlugin/README.md", "source": { "git": "https://github.com/bugsnag/bugsnag-cocoa.git", - "tag": "v6.27.2" + "tag": "v6.27.3" }, "dependencies": { "Bugsnag": "~> 6.13" diff --git a/CHANGELOG.md b/CHANGELOG.md index df4781201..63c0f7ee1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,14 +1,28 @@ Changelog ========= -## TBD +## 6.27.3 (2023-11-15) ### Bug fixes +* Remove include directives from inside of extern "C" sections because newer Xcode versions have issues with it + [1608](https://github.com/bugsnag/bugsnag-cocoa/pull/1608) + +* Setting user fields to nil will now clear them fully. + [1599](https://github.com/bugsnag/bugsnag-cocoa/pull/1599) + +* Crash fix: Detect and handle when WatchOS is running as an app rather than an extension. + [1588](https://github.com/bugsnag/bugsnag-cocoa/pull/1588) + +* Removed deprecated NXArchInfo code that was causing build issues. + [1584](https://github.com/bugsnag/bugsnag-cocoa/pull/1584) + +* Removed deprecated syscall on macos that was causing build issues. + [1577](https://github.com/bugsnag/bugsnag-cocoa/pull/1577) + * Check app version to avoid detecting an app upgrade as an OOM [1597](https://github.com/bugsnag/bugsnag-cocoa/pull/1597) - ## 6.27.2 (2023-07-24) ### Enhancements diff --git a/Framework/Info.plist b/Framework/Info.plist index e4125c7b5..b022480f9 100644 --- a/Framework/Info.plist +++ b/Framework/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 6.27.2 + 6.27.3 CFBundleVersion 1 diff --git a/Tests/BugsnagTests/Info.plist b/Tests/BugsnagTests/Info.plist index 4e9769662..7d778be1a 100644 --- a/Tests/BugsnagTests/Info.plist +++ b/Tests/BugsnagTests/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString - 6.27.2 + 6.27.3 CFBundleVersion 1 diff --git a/Tests/TestHost-iOS/Info.plist b/Tests/TestHost-iOS/Info.plist index 3037b6e45..28bed4d56 100644 --- a/Tests/TestHost-iOS/Info.plist +++ b/Tests/TestHost-iOS/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString - 6.27.2 + 6.27.3 CFBundleVersion 1 LSRequiresIPhoneOS diff --git a/VERSION b/VERSION index 5f64a2958..0fc326d66 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -6.27.2 +6.27.3