From 831f63d0e971981b366c43972fd40aed986ad008 Mon Sep 17 00:00:00 2001 From: fractalwrench Date: Mon, 14 May 2018 15:25:25 +0100 Subject: [PATCH 01/27] feat: add setEndpoints interface to configuration --- Source/BugsnagConfiguration.h | 12 ++++++++---- Source/BugsnagConfiguration.m | 6 ++++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Source/BugsnagConfiguration.h b/Source/BugsnagConfiguration.h index 095281c5d..bd7acd015 100644 --- a/Source/BugsnagConfiguration.h +++ b/Source/BugsnagConfiguration.h @@ -70,10 +70,6 @@ typedef NSDictionary *_Nullable (^BugsnagBeforeNotifyHook)( * The API key of a Bugsnag project */ @property(readwrite, retain, nullable) NSString *apiKey; -/** - * The URL used to notify Bugsnag - */ -@property(readwrite, retain, nullable) NSURL *notifyURL; /** * The release stage of the application, such as production, development, beta * et cetera @@ -142,12 +138,20 @@ BugsnagBreadcrumbs *breadcrumbs; */ @property BOOL shouldAutoCaptureSessions; +/** + * The URL used to notify Bugsnag + */ +@property(readwrite, retain, nullable) NSURL *notifyURL; + /** * Set the endpoint to which tracked sessions reports are sent. This defaults to https://sessions.bugsnag.com, * but should be overridden if you are using Bugsnag On-premise, to point to your own Bugsnag endpoint. */ @property(readwrite, retain, nullable) NSURL *sessionURL; +- (void)setEndpointsForNotify:(NSString *_Nonnull)notify + sessions:(NSString *_Nonnull)sessions NS_SWIFT_NAME(setEndpoints(notify:sessions:)); + /** * Set user metadata * diff --git a/Source/BugsnagConfiguration.m b/Source/BugsnagConfiguration.m index 1e78ac7d7..81e21c782 100644 --- a/Source/BugsnagConfiguration.m +++ b/Source/BugsnagConfiguration.m @@ -231,4 +231,10 @@ - (NSDictionary *)sessionApiHeaders { kHeaderApiSentAt: [BSG_RFC3339DateTool stringFromDate:[NSDate new]] }; } + +- (void)setEndpointsForNotify:(NSString *_Nonnull)notify sessions:(NSString *_Nonnull)sessions { + +} + + @end From dceac81bc169253788c9f9bcb1d7ad57946c489b Mon Sep 17 00:00:00 2001 From: fractalwrench Date: Mon, 14 May 2018 15:34:09 +0100 Subject: [PATCH 02/27] test: Add test for legacy notifyURL property --- Tests/BugsnagConfigurationTests.m | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Tests/BugsnagConfigurationTests.m b/Tests/BugsnagConfigurationTests.m index 3bc751783..07998443d 100644 --- a/Tests/BugsnagConfigurationTests.m +++ b/Tests/BugsnagConfigurationTests.m @@ -87,6 +87,14 @@ - (void)testSessionEndpoints { XCTAssertEqualObjects(endpoint, config.sessionURL); } +- (void)testNotifyEndpoint { + BugsnagConfiguration *config = [BugsnagConfiguration new]; + XCTAssertEqualObjects([NSURL URLWithString:@"https://notify.bugsnag.com/"], config.notifyURL); + NSURL *endpoint = [NSURL URLWithString:@"http://localhost:8000"]; + config.notifyURL = endpoint; + XCTAssertEqualObjects(endpoint, config.notifyURL); +} + - (void)testUser { BugsnagConfiguration *config = [BugsnagConfiguration new]; XCTAssertNil(config.currentUser); From b6d16bf38e7fc8268ce8ed348f3607e055124084 Mon Sep 17 00:00:00 2001 From: fractalwrench Date: Mon, 14 May 2018 16:31:26 +0100 Subject: [PATCH 03/27] test: test setEndpoints notify url validation --- Source/BugsnagConfiguration.m | 12 +++++++-- Tests/BugsnagConfigurationTests.m | 26 +++++++++++++++++++ .../fixtures/ios-swift-cocoapods/Podfile.lock | 4 +-- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/Source/BugsnagConfiguration.m b/Source/BugsnagConfiguration.m index 81e21c782..7c9e86802 100644 --- a/Source/BugsnagConfiguration.m +++ b/Source/BugsnagConfiguration.m @@ -86,7 +86,7 @@ - (BOOL)shouldSendReports { - (void)setUser:(NSString *)userId withName:(NSString *)userName andEmail:(NSString *)userEmail { - + self.currentUser = [[BugsnagUser alloc] initWithUserId:userId name:userName emailAddress:userEmail]; [self.metaData addAttribute:BSGKeyId withValue:userId toTabWithName:BSGKeyUser]; @@ -208,7 +208,7 @@ - (BOOL)shouldAutoCaptureSessions { - (void)setShouldAutoCaptureSessions:(BOOL)shouldAutoCaptureSessions { @synchronized (self) { _shouldAutoCaptureSessions = shouldAutoCaptureSessions; - + if (shouldAutoCaptureSessions) { // track any existing sessions BugsnagSessionTracker *sessionTracker = [Bugsnag notifier].sessionTracker; [sessionTracker onAutoCaptureEnabled]; @@ -233,8 +233,16 @@ - (NSDictionary *)sessionApiHeaders { } - (void)setEndpointsForNotify:(NSString *_Nonnull)notify sessions:(NSString *_Nonnull)sessions { + _notifyURL = [NSURL URLWithString:notify]; + _sessionURL = [NSURL URLWithString:sessions]; + if (![self isValidUrl:_notifyURL]) { + [NSException raise:NSGenericException format:@"Invalid URL supplied for notify endpoint"]; + } } +- (BOOL)isValidUrl:(NSURL *)url { + return url != nil && url.scheme != nil && url.host != nil; +} @end diff --git a/Tests/BugsnagConfigurationTests.m b/Tests/BugsnagConfigurationTests.m index 07998443d..6467ba1c8 100644 --- a/Tests/BugsnagConfigurationTests.m +++ b/Tests/BugsnagConfigurationTests.m @@ -1,5 +1,6 @@ #import "Bugsnag.h" #import "BugsnagConfiguration.h" +#import "BugsnagSessionTracker.h" #import "BugsnagUser.h" #import @@ -95,6 +96,31 @@ - (void)testNotifyEndpoint { XCTAssertEqualObjects(endpoint, config.notifyURL); } +- (void)testSetEndpoints { + BugsnagConfiguration *config = [BugsnagConfiguration new]; + [config setEndpointsForNotify:@"http://notify.example.com" sessions:@"http://sessions.example.com"]; + XCTAssertEqualObjects([NSURL URLWithString:@"http://notify.example.com"], config.notifyURL); + XCTAssertEqualObjects([NSURL URLWithString:@"http://sessions.example.com"], config.sessionURL); +} + +- (void)testSetEmptyNotifyEndpoint { + @try { + BugsnagConfiguration *config = [BugsnagConfiguration new]; + [config setEndpointsForNotify:@"" sessions:@"http://sessions.example.com"]; + XCTFail(); + } @catch(NSException * e) { + } +} + +- (void)testSetMalformedNotifyEndpoint { + @try { + BugsnagConfiguration *config = [BugsnagConfiguration new]; + [config setEndpointsForNotify:@"http://f" sessions:@"http://sessions.example.com"]; + XCTFail(); + } @catch(NSException * e) { + } +} + - (void)testUser { BugsnagConfiguration *config = [BugsnagConfiguration new]; XCTAssertNil(config.currentUser); diff --git a/features/fixtures/ios-swift-cocoapods/Podfile.lock b/features/fixtures/ios-swift-cocoapods/Podfile.lock index 3ee64957e..9939ae0e6 100644 --- a/features/fixtures/ios-swift-cocoapods/Podfile.lock +++ b/features/fixtures/ios-swift-cocoapods/Podfile.lock @@ -1,5 +1,5 @@ PODS: - - Bugsnag (5.15.4) + - Bugsnag (5.15.5) DEPENDENCIES: - Bugsnag (from `../../..`) @@ -9,7 +9,7 @@ EXTERNAL SOURCES: :path: ../../.. SPEC CHECKSUMS: - Bugsnag: 904211a0230f254808b47f3adb4b684900772962 + Bugsnag: d1e6b301c819f4931d6c572da17230d8892acb65 PODFILE CHECKSUM: 4d026fb83571f098c9fb4fa71c1564c72c55ab1a From 48e267fb0176bcc88f141408b660e9d770e6d50e Mon Sep 17 00:00:00 2001 From: fractalwrench Date: Mon, 14 May 2018 16:41:37 +0100 Subject: [PATCH 04/27] feat: Ignore tracking session if invalid session URL supplied --- Source/BugsnagConfiguration.m | 3 +++ Source/BugsnagSessionTracker.m | 5 +++++ Tests/BugsnagConfigurationTests.m | 24 +++++++++++++++++++++++- 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/Source/BugsnagConfiguration.m b/Source/BugsnagConfiguration.m index 7c9e86802..5c61725d6 100644 --- a/Source/BugsnagConfiguration.m +++ b/Source/BugsnagConfiguration.m @@ -239,6 +239,9 @@ - (void)setEndpointsForNotify:(NSString *_Nonnull)notify sessions:(NSString *_No if (![self isValidUrl:_notifyURL]) { [NSException raise:NSGenericException format:@"Invalid URL supplied for notify endpoint"]; } + if (![self isValidUrl:_sessionURL]) { + _sessionURL = nil; + } } - (BOOL)isValidUrl:(NSURL *)url { diff --git a/Source/BugsnagSessionTracker.m b/Source/BugsnagSessionTracker.m index bf5a4f28c..7cc66aeb4 100644 --- a/Source/BugsnagSessionTracker.m +++ b/Source/BugsnagSessionTracker.m @@ -11,6 +11,7 @@ #import "BSG_KSLogger.h" #import "BugsnagSessionTrackingPayload.h" #import "BugsnagSessionTrackingApiClient.h" +#import "BugsnagLogger.h" @interface BugsnagSessionTracker () @property BugsnagConfiguration *config; @@ -43,6 +44,10 @@ - (instancetype)initWithConfig:(BugsnagConfiguration *)config - (void)startNewSession:(NSDate *)date withUser:(BugsnagUser *)user autoCaptured:(BOOL)autoCaptured { + if (self.config.sessionURL == nil) { + bsg_log_err(@"The session tracking endpoint has not been set. Session tracking is disabled"); + return; + } _currentSession = [[BugsnagSession alloc] initWithId:[[NSUUID UUID] UUIDString] startDate:date diff --git a/Tests/BugsnagConfigurationTests.m b/Tests/BugsnagConfigurationTests.m index 6467ba1c8..026c79757 100644 --- a/Tests/BugsnagConfigurationTests.m +++ b/Tests/BugsnagConfigurationTests.m @@ -115,12 +115,34 @@ - (void)testSetEmptyNotifyEndpoint { - (void)testSetMalformedNotifyEndpoint { @try { BugsnagConfiguration *config = [BugsnagConfiguration new]; - [config setEndpointsForNotify:@"http://f" sessions:@"http://sessions.example.com"]; + [config setEndpointsForNotify:@"http://" sessions:@"http://sessions.example.com"]; XCTFail(); } @catch(NSException * e) { } } +- (void)testSetEmptySessionsEndpoint { + BugsnagConfiguration *config = [BugsnagConfiguration new]; + [config setEndpointsForNotify:@"http://notify.example.com" sessions:@""]; + BugsnagSessionTracker *sessionTracker + = [[BugsnagSessionTracker alloc] initWithConfig:config apiClient:nil callback:nil]; + + XCTAssertNil(sessionTracker.currentSession); + [sessionTracker startNewSession:[NSDate date] withUser:nil autoCaptured:NO]; + XCTAssertNil(sessionTracker.currentSession); +} + +- (void)testSetMalformedSessionsEndpoint { + BugsnagConfiguration *config = [BugsnagConfiguration new]; + [config setEndpointsForNotify:@"http://notify.example.com" sessions:@"f"]; + BugsnagSessionTracker *sessionTracker + = [[BugsnagSessionTracker alloc] initWithConfig:config apiClient:nil callback:nil]; + + XCTAssertNil(sessionTracker.currentSession); + [sessionTracker startNewSession:[NSDate date] withUser:nil autoCaptured:NO]; + XCTAssertNil(sessionTracker.currentSession); +} + - (void)testUser { BugsnagConfiguration *config = [BugsnagConfiguration new]; XCTAssertNil(config.currentUser); From b3d5420463157f34454b61ee66727b9e8c5bb51f Mon Sep 17 00:00:00 2001 From: fractalwrench Date: Mon, 14 May 2018 16:51:28 +0100 Subject: [PATCH 05/27] feat: enable session tracking by default --- Source/BugsnagConfiguration.m | 2 ++ Tests/BugsnagConfigurationTests.m | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Source/BugsnagConfiguration.m b/Source/BugsnagConfiguration.m index 5c61725d6..a7bcfa5ef 100644 --- a/Source/BugsnagConfiguration.m +++ b/Source/BugsnagConfiguration.m @@ -64,6 +64,8 @@ - (id)init { _notifyReleaseStages = nil; _breadcrumbs = [BugsnagBreadcrumbs new]; _automaticallyCollectBreadcrumbs = YES; + _shouldAutoCaptureSessions = YES; + if ([NSURLSession class]) { _session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration diff --git a/Tests/BugsnagConfigurationTests.m b/Tests/BugsnagConfigurationTests.m index 026c79757..82041afc2 100644 --- a/Tests/BugsnagConfigurationTests.m +++ b/Tests/BugsnagConfigurationTests.m @@ -57,7 +57,7 @@ - (void)testNotifyReleaseStagesExcludedSkipsSending { - (void)testDefaultSessionConfig { BugsnagConfiguration *config = [BugsnagConfiguration new]; - XCTAssertFalse([config shouldAutoCaptureSessions]); + XCTAssertTrue([config shouldAutoCaptureSessions]); } - (void)testErrorApiHeaders { From abb08c2f124632e01f0aae4fb1ca53945538ac13 Mon Sep 17 00:00:00 2001 From: fractalwrench Date: Tue, 5 Jun 2018 15:18:13 +0100 Subject: [PATCH 06/27] refactor: use nsassert rather than nsexception.raise for endpoint configuration --- Source/BugsnagConfiguration.m | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Source/BugsnagConfiguration.m b/Source/BugsnagConfiguration.m index a7bcfa5ef..a153c1b38 100644 --- a/Source/BugsnagConfiguration.m +++ b/Source/BugsnagConfiguration.m @@ -238,9 +238,8 @@ - (void)setEndpointsForNotify:(NSString *_Nonnull)notify sessions:(NSString *_No _notifyURL = [NSURL URLWithString:notify]; _sessionURL = [NSURL URLWithString:sessions]; - if (![self isValidUrl:_notifyURL]) { - [NSException raise:NSGenericException format:@"Invalid URL supplied for notify endpoint"]; - } + NSAssert([self isValidUrl:_notifyURL], @"Invalid URL supplied for notify endpoint"); + if (![self isValidUrl:_sessionURL]) { _sessionURL = nil; } From 4b7277ddf4ffe6ea5f7301829c8448f9a1ab153b Mon Sep 17 00:00:00 2001 From: fractalwrench Date: Tue, 5 Jun 2018 15:50:09 +0100 Subject: [PATCH 07/27] test: make mazerunner scenario NOT autocapture sessions by default, which should pass existing verif --- .../ios-swift-cocoapods/iOSTestApp/scenarios/Scenario.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/Scenario.m b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/Scenario.m index 00feeff4e..05b98cfb2 100644 --- a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/Scenario.m +++ b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/Scenario.m @@ -31,10 +31,10 @@ + (Scenario *)createScenarioNamed:(NSString *)className return [(Scenario *)obj initWithConfig:config]; } - - (instancetype)initWithConfig:(BugsnagConfiguration *)config { if (self = [super init]) { self.config = config; + self.config.shouldAutoCaptureSessions = NO; } return self; } From f3922c6002e3f1fa3feef0a5760b66d9a4871bcf Mon Sep 17 00:00:00 2001 From: fractalwrench Date: Tue, 5 Jun 2018 16:19:13 +0100 Subject: [PATCH 08/27] docs: update documentation of session tracking on by default --- Source/BugsnagConfiguration.h | 2 +- .../fixtures/ios-swift-cocoapods/iOSTestApp/AppDelegate.swift | 4 ++-- .../ios-swift-cocoapods/iOSTestApp/scenarios/Scenario.m | 1 - 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Source/BugsnagConfiguration.h b/Source/BugsnagConfiguration.h index bd7acd015..073c55a8c 100644 --- a/Source/BugsnagConfiguration.h +++ b/Source/BugsnagConfiguration.h @@ -134,7 +134,7 @@ BugsnagBreadcrumbs *breadcrumbs; @property BOOL autoNotify; /** - * Determines whether app sessions should be tracked automatically. By default this value is false. + * Determines whether app sessions should be tracked automatically. By default this value is true. */ @property BOOL shouldAutoCaptureSessions; diff --git a/features/fixtures/ios-swift-cocoapods/iOSTestApp/AppDelegate.swift b/features/fixtures/ios-swift-cocoapods/iOSTestApp/AppDelegate.swift index 0e022b6ce..95eb106ed 100644 --- a/features/fixtures/ios-swift-cocoapods/iOSTestApp/AppDelegate.swift +++ b/features/fixtures/ios-swift-cocoapods/iOSTestApp/AppDelegate.swift @@ -50,8 +50,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate { let config = BugsnagConfiguration() let url = URL(string: mockAPIPath) config.apiKey = apiKey - config.notifyURL = url - config.sessionURL = url + config.setEndpoints(notify: url, sessions: url) + config.shouldAutoCaptureSessions = false; return config } diff --git a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/Scenario.m b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/Scenario.m index 05b98cfb2..f6b08c67f 100644 --- a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/Scenario.m +++ b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/Scenario.m @@ -34,7 +34,6 @@ + (Scenario *)createScenarioNamed:(NSString *)className - (instancetype)initWithConfig:(BugsnagConfiguration *)config { if (self = [super init]) { self.config = config; - self.config.shouldAutoCaptureSessions = NO; } return self; } From 26a2c3746c7ecf8f48dee777d9425b2d6bcdbd63 Mon Sep 17 00:00:00 2001 From: fractalwrench Date: Tue, 5 Jun 2018 16:49:26 +0100 Subject: [PATCH 09/27] use string rather than url for mazerunner scenario --- .../fixtures/ios-swift-cocoapods/iOSTestApp/AppDelegate.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/features/fixtures/ios-swift-cocoapods/iOSTestApp/AppDelegate.swift b/features/fixtures/ios-swift-cocoapods/iOSTestApp/AppDelegate.swift index 95eb106ed..e745a5158 100644 --- a/features/fixtures/ios-swift-cocoapods/iOSTestApp/AppDelegate.swift +++ b/features/fixtures/ios-swift-cocoapods/iOSTestApp/AppDelegate.swift @@ -48,9 +48,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate { internal func prepareConfig(apiKey: String, mockAPIPath: String) -> BugsnagConfiguration { let config = BugsnagConfiguration() - let url = URL(string: mockAPIPath) config.apiKey = apiKey - config.setEndpoints(notify: url, sessions: url) + config.setEndpoints(notify: mockAPIPath, sessions: mockAPIPath) config.shouldAutoCaptureSessions = false; return config } From 57722ed1c47cfb637c7ac8703231ed1c85f0326b Mon Sep 17 00:00:00 2001 From: fractalwrench Date: Wed, 6 Jun 2018 09:48:18 +0100 Subject: [PATCH 10/27] docs: update session tracking obd docs --- Source/BugsnagConfiguration.h | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/Source/BugsnagConfiguration.h b/Source/BugsnagConfiguration.h index 073c55a8c..24a62bb9b 100644 --- a/Source/BugsnagConfiguration.h +++ b/Source/BugsnagConfiguration.h @@ -139,16 +139,38 @@ BugsnagBreadcrumbs *breadcrumbs; @property BOOL shouldAutoCaptureSessions; /** - * The URL used to notify Bugsnag + * Retrieves the endpoint used to notify Bugsnag of errors + * + * NOTE: it is strongly recommended that you set this value via setEndpointsForNotify:sessions: instead. + * + * @see setEndpointsForNotify:sessions: */ @property(readwrite, retain, nullable) NSURL *notifyURL; /** - * Set the endpoint to which tracked sessions reports are sent. This defaults to https://sessions.bugsnag.com, - * but should be overridden if you are using Bugsnag On-premise, to point to your own Bugsnag endpoint. + * Retrieves the endpoint used to send tracked sessions to Bugsnag + * + * NOTE: it is strongly recommended that you set this value via setEndpointsForNotify:sessions: instead. + * + * @see setEndpointsForNotify:sessions */ @property(readwrite, retain, nullable) NSURL *sessionURL; +/** + * Set the endpoints to send data to. By default we'll send error reports to + * https://notify.bugsnag.com, and sessions to https://session.bugsnag.com, but you can + * override this if you are using Bugsnag Enterprise to point to your own Bugsnag endpoint. + * + * Please note that it is recommended that you set both endpoints. If the notify endpoint is + * missing, an assertion will be thrown. If the session endpoint is missing, a warning will be + * logged and sessions will not be sent automatically. + * + * @param notify the notify endpoint + * @param sessions the sessions endpoint + * + * @throws an assertion if the notify endpoint is not a valid URL + */ + - (void)setEndpointsForNotify:(NSString *_Nonnull)notify sessions:(NSString *_Nonnull)sessions NS_SWIFT_NAME(setEndpoints(notify:sessions:)); From 0645badc1aabeaa7c4820f80e5bf34d426087fb2 Mon Sep 17 00:00:00 2001 From: fractalwrench Date: Wed, 6 Jun 2018 09:59:23 +0100 Subject: [PATCH 11/27] add missing comma in method sig --- Source/BugsnagConfiguration.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/BugsnagConfiguration.h b/Source/BugsnagConfiguration.h index 24a62bb9b..3be41f439 100644 --- a/Source/BugsnagConfiguration.h +++ b/Source/BugsnagConfiguration.h @@ -152,7 +152,7 @@ BugsnagBreadcrumbs *breadcrumbs; * * NOTE: it is strongly recommended that you set this value via setEndpointsForNotify:sessions: instead. * - * @see setEndpointsForNotify:sessions + * @see setEndpointsForNotify:sessions: */ @property(readwrite, retain, nullable) NSURL *sessionURL; From 8980ea3126eae67bc850dc0e9b7b38aad6fcab6a Mon Sep 17 00:00:00 2001 From: fractalwrench Date: Wed, 6 Jun 2018 10:04:37 +0100 Subject: [PATCH 12/27] fix minor docs typo --- Source/BugsnagConfiguration.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/BugsnagConfiguration.h b/Source/BugsnagConfiguration.h index 3be41f439..e5588fad6 100644 --- a/Source/BugsnagConfiguration.h +++ b/Source/BugsnagConfiguration.h @@ -158,7 +158,7 @@ BugsnagBreadcrumbs *breadcrumbs; /** * Set the endpoints to send data to. By default we'll send error reports to - * https://notify.bugsnag.com, and sessions to https://session.bugsnag.com, but you can + * https://notify.bugsnag.com, and sessions to https://sessions.bugsnag.com, but you can * override this if you are using Bugsnag Enterprise to point to your own Bugsnag endpoint. * * Please note that it is recommended that you set both endpoints. If the notify endpoint is From 0677b662aac144367fb191e648fdffe3270c14a2 Mon Sep 17 00:00:00 2001 From: fractalwrench Date: Thu, 7 Jun 2018 11:12:37 +0100 Subject: [PATCH 13/27] test: begin porting android session tracking mazerunner scenarios to cocoa --- .../iOSTestApp.xcodeproj/project.pbxproj | 26 ++++++---- .../scenarios/ManualSessionScenario.h | 11 ++++ .../scenarios/ManualSessionScenario.m | 19 +++++++ .../iOSTestApp/scenarios/Scenario.h | 2 + .../iOSTestApp/scenarios/Scenario.m | 9 ++++ features/session_tracking.feature | 51 +++++++++++++++++++ 6 files changed, 108 insertions(+), 10 deletions(-) create mode 100644 features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/ManualSessionScenario.h create mode 100644 features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/ManualSessionScenario.m create mode 100644 features/session_tracking.feature diff --git a/features/fixtures/ios-swift-cocoapods/iOSTestApp.xcodeproj/project.pbxproj b/features/fixtures/ios-swift-cocoapods/iOSTestApp.xcodeproj/project.pbxproj index 2fca34567..ec3f03d9d 100644 --- a/features/fixtures/ios-swift-cocoapods/iOSTestApp.xcodeproj/project.pbxproj +++ b/features/fixtures/ios-swift-cocoapods/iOSTestApp.xcodeproj/project.pbxproj @@ -31,6 +31,7 @@ F429565A951303E2C3136D0D /* UserIdScenario.swift in Sources */ = {isa = PBXBuildFile; fileRef = F42957C58F98EECD3ADD84B2 /* UserIdScenario.swift */; }; F4295836C8AF75547C675E8D /* ReleasedObjectScenario.m in Sources */ = {isa = PBXBuildFile; fileRef = F4295E71D7B2DFE77057F3DA /* ReleasedObjectScenario.m */; }; F42958881D3F34A76CADE4EC /* SwiftCrash.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4295EEDC00E5ED3C166DBF0 /* SwiftCrash.swift */; }; + F42958BE5DDACDBF653CA926 /* ManualSessionScenario.m in Sources */ = {isa = PBXBuildFile; fileRef = F429570EE7A751B53D011481 /* ManualSessionScenario.m */; }; F42959124DB949EEF1420957 /* ReadOnlyPageScenario.m in Sources */ = {isa = PBXBuildFile; fileRef = F4295871D1BCF211398CAEBA /* ReadOnlyPageScenario.m */; }; F4295968571A4118D6A4606A /* UserEnabledScenario.swift in Sources */ = {isa = PBXBuildFile; fileRef = F42954E2B3FF0C5C0474DA74 /* UserEnabledScenario.swift */; }; F4295A036B228AF608641699 /* UserDisabledScenario.swift in Sources */ = {isa = PBXBuildFile; fileRef = F42951F865D328A43250640B /* UserDisabledScenario.swift */; }; @@ -78,6 +79,7 @@ F42956707AEC06754D9C2208 /* AccessNonObjectScenario.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AccessNonObjectScenario.h; sourceTree = ""; }; F42956D34274D4ED16B4D491 /* BuiltinTrapScenario.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BuiltinTrapScenario.m; sourceTree = ""; }; F4295703713DA0D0ED768230 /* MinimalCrashReportScenario.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MinimalCrashReportScenario.h; sourceTree = ""; }; + F429570EE7A751B53D011481 /* ManualSessionScenario.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ManualSessionScenario.m; sourceTree = ""; }; F42957A23DB8145B4B702F15 /* PrivilegedInstructionScenario.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrivilegedInstructionScenario.h; sourceTree = ""; }; F42957C58F98EECD3ADD84B2 /* UserIdScenario.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserIdScenario.swift; sourceTree = ""; }; F42957FA1A3724BFBDC22E14 /* NSExceptionScenario.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSExceptionScenario.swift; sourceTree = ""; }; @@ -95,6 +97,7 @@ F4295C758B89038DD3A2A198 /* CorruptMallocScenario.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CorruptMallocScenario.h; sourceTree = ""; }; F4295CA6B6792DECA15C450B /* AsyncSafeThreadScenario.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AsyncSafeThreadScenario.m; sourceTree = ""; }; F4295CD1B5437B73A7C254F7 /* ReadGarbagePointerScenario.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReadGarbagePointerScenario.h; sourceTree = ""; }; + F4295CF00D2B7AE6DE5BBFC5 /* ManualSessionScenario.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ManualSessionScenario.h; sourceTree = ""; }; F4295E2979ED53A2E82017CF /* BuiltinTrapScenario.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BuiltinTrapScenario.h; sourceTree = ""; }; F4295E71D7B2DFE77057F3DA /* ReleasedObjectScenario.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ReleasedObjectScenario.m; sourceTree = ""; }; F4295E86DC0BE9DC731B0D1C /* NullPointerScenario.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NullPointerScenario.m; sourceTree = ""; }; @@ -216,6 +219,8 @@ F42950D49A5F24FF7155EEE1 /* NonExistentMethodScenario.h */, F429566550603ECAC2875333 /* PrivilegedInstructionScenario.m */, F42957A23DB8145B4B702F15 /* PrivilegedInstructionScenario.h */, + F429570EE7A751B53D011481 /* ManualSessionScenario.m */, + F4295CF00D2B7AE6DE5BBFC5 /* ManualSessionScenario.h */, ); path = scenarios; sourceTree = ""; @@ -232,7 +237,7 @@ 8AB8865D20404DD30003E444 /* Frameworks */, 8AB8865E20404DD30003E444 /* Resources */, 4D2139E03F8B071F7DB7C7A6 /* [CP] Embed Pods Frameworks */, - 421E0803F4159BB79BC285F5 /* [CP] Copy Pods Resources */, + F4E835AC090FCF28B6B12EC4 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -310,37 +315,37 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 421E0803F4159BB79BC285F5 /* [CP] Copy Pods Resources */ = { + 4D2139E03F8B071F7DB7C7A6 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-iOSTestApp/Pods-iOSTestApp-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/Bugsnag/Bugsnag.framework", ); - name = "[CP] Copy Pods Resources"; + name = "[CP] Embed Pods Frameworks"; outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Bugsnag.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-iOSTestApp/Pods-iOSTestApp-resources.sh\"\n"; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-iOSTestApp/Pods-iOSTestApp-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - 4D2139E03F8B071F7DB7C7A6 /* [CP] Embed Pods Frameworks */ = { + F4E835AC090FCF28B6B12EC4 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-iOSTestApp/Pods-iOSTestApp-frameworks.sh", - "${BUILT_PRODUCTS_DIR}/Bugsnag/Bugsnag.framework", ); - name = "[CP] Embed Pods Frameworks"; + name = "[CP] Copy Pods Resources"; outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Bugsnag.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-iOSTestApp/Pods-iOSTestApp-frameworks.sh\"\n"; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-iOSTestApp/Pods-iOSTestApp-resources.sh\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ @@ -380,6 +385,7 @@ F42951BEB2518C610A85FE0D /* BuiltinTrapScenario.m in Sources */, F4295397AD31C1C1E64144F5 /* NonExistentMethodScenario.m in Sources */, F4295A0B0DA0AF3B5502D29C /* PrivilegedInstructionScenario.m in Sources */, + F42958BE5DDACDBF653CA926 /* ManualSessionScenario.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/ManualSessionScenario.h b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/ManualSessionScenario.h new file mode 100644 index 000000000..cda041b0c --- /dev/null +++ b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/ManualSessionScenario.h @@ -0,0 +1,11 @@ +// +// Created by Jamie Lynch on 07/06/2018. +// Copyright (c) 2018 Bugsnag. All rights reserved. +// + +#import +#import "Scenario.h" + + +@interface ManualSessionScenario : Scenario +@end diff --git a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/ManualSessionScenario.m b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/ManualSessionScenario.m new file mode 100644 index 000000000..c2dcf241c --- /dev/null +++ b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/ManualSessionScenario.m @@ -0,0 +1,19 @@ +// +// Created by Jamie Lynch on 07/06/2018. +// Copyright (c) 2018 Bugsnag. All rights reserved. +// + +#import "ManualSessionScenario.h" + +/** + * Sends a manual session payload to Bugsnag. + */ +@implementation ManualSessionScenario + +- (void)run { + [self.config setUser:@"123" withName:@"Joe Bloggs" andEmail:@"user@example.com"]; + [Bugsnag startSession]; + [self flushAllSessions]; +} + +@end diff --git a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/Scenario.h b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/Scenario.h index 58a05ae81..ea97f6495 100644 --- a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/Scenario.h +++ b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/Scenario.h @@ -22,4 +22,6 @@ - (void)startBugsnag; +- (void)flushAllSessions; + @end diff --git a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/Scenario.m b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/Scenario.m index f6b08c67f..5c070511f 100644 --- a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/Scenario.m +++ b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/Scenario.m @@ -6,6 +6,9 @@ #import "Scenario.h" +@interface Bugsnag() ++ (id) notifier; +@end @implementation Scenario @@ -45,4 +48,10 @@ - (void)startBugsnag { [Bugsnag startBugsnagWithConfiguration:self.config]; } +- (void)flushAllSessions { + id notifier = [Bugsnag notifier]; + id sessionTracker = [notifier valueForKey:@"sessionTracker"]; + [sessionTracker performSelector:@selector(send)]; +} + @end diff --git a/features/session_tracking.feature b/features/session_tracking.feature new file mode 100644 index 000000000..07561cbac --- /dev/null +++ b/features/session_tracking.feature @@ -0,0 +1,51 @@ +Feature: Session Tracking + +Scenario: Automatic Session Tracking sends + When I run "AutoSessionScenario" with the defaults on "iPhone8-11.2" + And I wait for 1 seconds + Then I should receive a request + And the request is a valid for the session tracking API + And the "Bugsnag-API-Key" header equals "a35a2a72bd230ac0aa0f52715bbdc6aa" + And the payload field "notifier.name" equals "iOS Bugsnag Notifier" + And the payload field "sessions" is an array with 1 element + And the session "user.id" equals "123" + And the session "user.email" equals "user@example.com" + And the session "user.name" equals "Joe Bloggs" + And the session "id" is not null + And the session "startedAt" is not null + +Scenario: Test cached Session sends + When I run "SessionCacheScenario" with the defaults on "iPhone8-11.2" + Then I should receive no requests + + When I force stop the "com.bugsnag.android.mazerunner" Android app + And I set environment variable "EVENT_TYPE" to "Wait" + And I start the "com.bugsnag.android.mazerunner" Android app using the "com.bugsnag.android.mazerunner.MainActivity" activity + Then I should receive a request + + And the request is a valid for the session tracking API + And the payload field "sessions" is an array with 1 element + And the session "user.id" equals "123" + And the session "user.email" equals "user@example.com" + And the session "user.name" equals "Joe Bloggs" + And the session "id" is not null + And the session "startedAt" is not null + +Scenario: Manual Session sends + When I run "ManualSessionScenario" with the defaults on "iPhone8-11.2" + Then I should receive a request + And the request is a valid for the session tracking API + And the "Bugsnag-API-Key" header equals "a35a2a72bd230ac0aa0f52715bbdc6aa" + And the payload field "notifier.name" equals "iOS Bugsnag Notifier" + And the payload field "sessions" is an array with 1 element + And the session "user.id" equals "123" + And the session "user.email" equals "user@example.com" + And the session "user.name" equals "Joe Bloggs" + And the session "id" is not null + And the session "startedAt" is not null + +Scenario: Set Auto Capture Sessions sends + When I run "SessionSetAutoCaptureScenario" with the defaults on "iPhone8-11.2" + And I wait for 60 seconds + Then I should receive a request + And the request is a valid for the session tracking API From fda541e116030d1e265057b393ad077ee346dcce Mon Sep 17 00:00:00 2001 From: fractalwrench Date: Thu, 7 Jun 2018 11:58:38 +0100 Subject: [PATCH 14/27] test: add manual and disabled session tracking scenarios --- .../iOSTestApp.xcodeproj/project.pbxproj | 12 +++++++ .../scenarios/AutoSessionScenario.h | 14 ++++++++ .../scenarios/AutoSessionScenario.m | 20 ++++++++++++ .../DisabledSessionTrackingScenario.h | 11 +++++++ .../DisabledSessionTrackingScenario.m | 15 +++++++++ .../scenarios/ManualSessionScenario.h | 4 ++- .../scenarios/ManualSessionScenario.m | 3 -- .../iOSTestApp/scenarios/Scenario.h | 4 +++ .../iOSTestApp/scenarios/Scenario.m | 4 --- features/session_tracking.feature | 32 ++++--------------- 10 files changed, 85 insertions(+), 34 deletions(-) create mode 100644 features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/AutoSessionScenario.h create mode 100644 features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/AutoSessionScenario.m create mode 100644 features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/DisabledSessionTrackingScenario.h create mode 100644 features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/DisabledSessionTrackingScenario.m diff --git a/features/fixtures/ios-swift-cocoapods/iOSTestApp.xcodeproj/project.pbxproj b/features/fixtures/ios-swift-cocoapods/iOSTestApp.xcodeproj/project.pbxproj index ec3f03d9d..34f7afc9e 100644 --- a/features/fixtures/ios-swift-cocoapods/iOSTestApp.xcodeproj/project.pbxproj +++ b/features/fixtures/ios-swift-cocoapods/iOSTestApp.xcodeproj/project.pbxproj @@ -14,8 +14,10 @@ 8AB8866E20404DD30003E444 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8AB8866C20404DD30003E444 /* LaunchScreen.storyboard */; }; C4D0B5FF8E60C0835B86DFE9 /* Pods_iOSTestApp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4994F05E0421A0B037DD2CC5 /* Pods_iOSTestApp.framework */; }; F429502603396F8671B333B3 /* HandledExceptionScenario.swift in Sources */ = {isa = PBXBuildFile; fileRef = F429526319377A8848136413 /* HandledExceptionScenario.swift */; }; + F4295109FCAB93708FDAFE12 /* DisabledSessionTrackingScenario.m in Sources */ = {isa = PBXBuildFile; fileRef = F429563584D9BC3A5B86BECF /* DisabledSessionTrackingScenario.m */; }; F42951A9FD696D9047149DA8 /* UndefinedInstructionScenario.m in Sources */ = {isa = PBXBuildFile; fileRef = F429538D19421F28D8EB0446 /* UndefinedInstructionScenario.m */; }; F42951BEB2518C610A85FE0D /* BuiltinTrapScenario.m in Sources */ = {isa = PBXBuildFile; fileRef = F42956D34274D4ED16B4D491 /* BuiltinTrapScenario.m */; }; + F42951BF19D7F35A03273CFB /* AutoSessionScenario.m in Sources */ = {isa = PBXBuildFile; fileRef = F4295EE3B0BD05E5FE513B20 /* AutoSessionScenario.m */; }; F4295218A62E41518DC3C057 /* AccessNonObjectScenario.m in Sources */ = {isa = PBXBuildFile; fileRef = F4295A20DE438C2B28167714 /* AccessNonObjectScenario.m */; }; F4295262625F84A80282E520 /* CorruptMallocScenario.m in Sources */ = {isa = PBXBuildFile; fileRef = F429581876FA1A9CFEE52615 /* CorruptMallocScenario.m */; }; F429532277D8B4DAE53F3F77 /* MinimalCrashReportScenario.m in Sources */ = {isa = PBXBuildFile; fileRef = F429514FFBD085C6FEB85BDC /* MinimalCrashReportScenario.m */; }; @@ -75,6 +77,7 @@ F42954E8B66F3FB7F5333CF7 /* Scenario.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Scenario.m; sourceTree = ""; }; F429550B682F8F9677305881 /* CxxExceptionScenario.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CxxExceptionScenario.mm; sourceTree = ""; }; F429556E677F030F72C4C5D0 /* AsyncSafeThreadScenario.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AsyncSafeThreadScenario.h; sourceTree = ""; }; + F429563584D9BC3A5B86BECF /* DisabledSessionTrackingScenario.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DisabledSessionTrackingScenario.m; sourceTree = ""; }; F429566550603ECAC2875333 /* PrivilegedInstructionScenario.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PrivilegedInstructionScenario.m; sourceTree = ""; }; F42956707AEC06754D9C2208 /* AccessNonObjectScenario.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AccessNonObjectScenario.h; sourceTree = ""; }; F42956D34274D4ED16B4D491 /* BuiltinTrapScenario.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BuiltinTrapScenario.m; sourceTree = ""; }; @@ -99,10 +102,13 @@ F4295CD1B5437B73A7C254F7 /* ReadGarbagePointerScenario.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReadGarbagePointerScenario.h; sourceTree = ""; }; F4295CF00D2B7AE6DE5BBFC5 /* ManualSessionScenario.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ManualSessionScenario.h; sourceTree = ""; }; F4295E2979ED53A2E82017CF /* BuiltinTrapScenario.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BuiltinTrapScenario.h; sourceTree = ""; }; + F4295E6960503E5BD75A2C35 /* DisabledSessionTrackingScenario.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DisabledSessionTrackingScenario.h; sourceTree = ""; }; F4295E71D7B2DFE77057F3DA /* ReleasedObjectScenario.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ReleasedObjectScenario.m; sourceTree = ""; }; F4295E86DC0BE9DC731B0D1C /* NullPointerScenario.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NullPointerScenario.m; sourceTree = ""; }; + F4295EE3B0BD05E5FE513B20 /* AutoSessionScenario.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AutoSessionScenario.m; sourceTree = ""; }; F4295EEDC00E5ED3C166DBF0 /* SwiftCrash.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftCrash.swift; sourceTree = ""; }; F4295F13EBCAC9CB0ABC4008 /* NonExistentMethodScenario.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NonExistentMethodScenario.m; sourceTree = ""; }; + F4295F22AA1863213F4A5F51 /* AutoSessionScenario.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AutoSessionScenario.h; sourceTree = ""; }; F4295F595986A279FA3BDEA7 /* UserEmailScenario.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserEmailScenario.swift; sourceTree = ""; }; F4295FA8EBBA645EECF7B483 /* HandledErrorOverrideScenario.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HandledErrorOverrideScenario.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -221,6 +227,10 @@ F42957A23DB8145B4B702F15 /* PrivilegedInstructionScenario.h */, F429570EE7A751B53D011481 /* ManualSessionScenario.m */, F4295CF00D2B7AE6DE5BBFC5 /* ManualSessionScenario.h */, + F4295EE3B0BD05E5FE513B20 /* AutoSessionScenario.m */, + F4295F22AA1863213F4A5F51 /* AutoSessionScenario.h */, + F429563584D9BC3A5B86BECF /* DisabledSessionTrackingScenario.m */, + F4295E6960503E5BD75A2C35 /* DisabledSessionTrackingScenario.h */, ); path = scenarios; sourceTree = ""; @@ -386,6 +396,8 @@ F4295397AD31C1C1E64144F5 /* NonExistentMethodScenario.m in Sources */, F4295A0B0DA0AF3B5502D29C /* PrivilegedInstructionScenario.m in Sources */, F42958BE5DDACDBF653CA926 /* ManualSessionScenario.m in Sources */, + F42951BF19D7F35A03273CFB /* AutoSessionScenario.m in Sources */, + F4295109FCAB93708FDAFE12 /* DisabledSessionTrackingScenario.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/AutoSessionScenario.h b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/AutoSessionScenario.h new file mode 100644 index 000000000..723ee933b --- /dev/null +++ b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/AutoSessionScenario.h @@ -0,0 +1,14 @@ +// +// Created by Jamie Lynch on 07/06/2018. +// Copyright (c) 2018 Bugsnag. All rights reserved. +// + +#import +#import "Scenario.h" + + +/** + * Sends an automatic session payload to Bugsnag. + */ +@interface AutoSessionScenario : Scenario +@end diff --git a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/AutoSessionScenario.m b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/AutoSessionScenario.m new file mode 100644 index 000000000..d3bb6baed --- /dev/null +++ b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/AutoSessionScenario.m @@ -0,0 +1,20 @@ +// +// Created by Jamie Lynch on 07/06/2018. +// Copyright (c) 2018 Bugsnag. All rights reserved. +// + +#import "AutoSessionScenario.h" + + +@implementation AutoSessionScenario + +- (void)startBugsnag { + self.config.shouldAutoCaptureSessions = YES; + [super startBugsnag]; +} + +- (void)run { + [self flushAllSessions]; +} + +@end diff --git a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/DisabledSessionTrackingScenario.h b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/DisabledSessionTrackingScenario.h new file mode 100644 index 000000000..66ee9b4e7 --- /dev/null +++ b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/DisabledSessionTrackingScenario.h @@ -0,0 +1,11 @@ +// +// Created by Jamie Lynch on 07/06/2018. +// Copyright (c) 2018 Bugsnag. All rights reserved. +// + +#import +#import "Scenario.h" + + +@interface DisabledSessionTrackingScenario : Scenario +@end diff --git a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/DisabledSessionTrackingScenario.m b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/DisabledSessionTrackingScenario.m new file mode 100644 index 000000000..028fdf08f --- /dev/null +++ b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/DisabledSessionTrackingScenario.m @@ -0,0 +1,15 @@ +// +// Created by Jamie Lynch on 07/06/2018. +// Copyright (c) 2018 Bugsnag. All rights reserved. +// + +#import "DisabledSessionTrackingScenario.h" + + +@implementation DisabledSessionTrackingScenario + +- (void)run { + [self flushAllSessions]; +} + +@end \ No newline at end of file diff --git a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/ManualSessionScenario.h b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/ManualSessionScenario.h index cda041b0c..64f8cc104 100644 --- a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/ManualSessionScenario.h +++ b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/ManualSessionScenario.h @@ -6,6 +6,8 @@ #import #import "Scenario.h" - +/** + * Sends a manual session payload to Bugsnag. + */ @interface ManualSessionScenario : Scenario @end diff --git a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/ManualSessionScenario.m b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/ManualSessionScenario.m index c2dcf241c..ab35ab7fa 100644 --- a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/ManualSessionScenario.m +++ b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/ManualSessionScenario.m @@ -5,9 +5,6 @@ #import "ManualSessionScenario.h" -/** - * Sends a manual session payload to Bugsnag. - */ @implementation ManualSessionScenario - (void)run { diff --git a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/Scenario.h b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/Scenario.h index ea97f6495..d5adcad60 100644 --- a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/Scenario.h +++ b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/Scenario.h @@ -6,6 +6,10 @@ #import #import +@interface Bugsnag() ++ (id) notifier; +@end + @interface Scenario : NSObject @property (strong, nonatomic, nonnull) BugsnagConfiguration *config; diff --git a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/Scenario.m b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/Scenario.m index 5c070511f..5d98afa6f 100644 --- a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/Scenario.m +++ b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/Scenario.m @@ -6,10 +6,6 @@ #import "Scenario.h" -@interface Bugsnag() -+ (id) notifier; -@end - @implementation Scenario + (Scenario *)createScenarioNamed:(NSString *)className diff --git a/features/session_tracking.feature b/features/session_tracking.feature index 07561cbac..3692e1290 100644 --- a/features/session_tracking.feature +++ b/features/session_tracking.feature @@ -2,32 +2,13 @@ Feature: Session Tracking Scenario: Automatic Session Tracking sends When I run "AutoSessionScenario" with the defaults on "iPhone8-11.2" - And I wait for 1 seconds + And I wait for 5 seconds Then I should receive a request And the request is a valid for the session tracking API And the "Bugsnag-API-Key" header equals "a35a2a72bd230ac0aa0f52715bbdc6aa" And the payload field "notifier.name" equals "iOS Bugsnag Notifier" And the payload field "sessions" is an array with 1 element - And the session "user.id" equals "123" - And the session "user.email" equals "user@example.com" - And the session "user.name" equals "Joe Bloggs" - And the session "id" is not null - And the session "startedAt" is not null - -Scenario: Test cached Session sends - When I run "SessionCacheScenario" with the defaults on "iPhone8-11.2" - Then I should receive no requests - - When I force stop the "com.bugsnag.android.mazerunner" Android app - And I set environment variable "EVENT_TYPE" to "Wait" - And I start the "com.bugsnag.android.mazerunner" Android app using the "com.bugsnag.android.mazerunner.MainActivity" activity - Then I should receive a request - - And the request is a valid for the session tracking API - And the payload field "sessions" is an array with 1 element - And the session "user.id" equals "123" - And the session "user.email" equals "user@example.com" - And the session "user.name" equals "Joe Bloggs" + And the session "user.id" is not null And the session "id" is not null And the session "startedAt" is not null @@ -44,8 +25,7 @@ Scenario: Manual Session sends And the session "id" is not null And the session "startedAt" is not null -Scenario: Set Auto Capture Sessions sends - When I run "SessionSetAutoCaptureScenario" with the defaults on "iPhone8-11.2" - And I wait for 60 seconds - Then I should receive a request - And the request is a valid for the session tracking API +Scenario: Disabled Session Tracking sends no requests + When I run "DisabledSessionTrackingScenario" with the defaults on "iPhone8-11.2" + And I wait for 5 seconds + Then I should receive 0 requests From e12ff7048639f7084ebf1f41285cd0379e82b737 Mon Sep 17 00:00:00 2001 From: fractalwrench Date: Thu, 7 Jun 2018 13:39:30 +0100 Subject: [PATCH 15/27] fix: serialise user email using 'email' key for session requests --- Source/BugsnagUser.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/BugsnagUser.m b/Source/BugsnagUser.m index 957424c8e..5e6c14e20 100644 --- a/Source/BugsnagUser.m +++ b/Source/BugsnagUser.m @@ -14,7 +14,7 @@ @implementation BugsnagUser - (instancetype)initWithDictionary:(NSDictionary *)dict { if (self = [super init]) { _userId = dict[@"id"]; - _emailAddress = dict[@"emailAddress"]; + _emailAddress = dict[@"email"]; _name = dict[@"name"]; } return self; @@ -34,12 +34,12 @@ + (instancetype)userWithUserId:(NSString *)userId name:(NSString *)name emailAdd return [[self alloc] initWithUserId:userId name:name emailAddress:emailAddress]; } - - (NSDictionary *)toJson { NSMutableDictionary *dict = [NSMutableDictionary new]; BSGDictInsertIfNotNil(dict, self.userId, @"id"); - BSGDictInsertIfNotNil(dict, self.emailAddress, @"emailAddress"); + BSGDictInsertIfNotNil(dict, self.emailAddress, @"email"); BSGDictInsertIfNotNil(dict, self.name, @"name"); return [NSDictionary dictionaryWithDictionary:dict]; } + @end From d813cefaa8a098d855828c4f78f10f46dfab9a80 Mon Sep 17 00:00:00 2001 From: fractalwrench Date: Thu, 7 Jun 2018 13:50:34 +0100 Subject: [PATCH 16/27] test: fix user serialisation test --- Tests/BugsnagUserTest.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/BugsnagUserTest.m b/Tests/BugsnagUserTest.m index 5ec80554d..5e86edd22 100644 --- a/Tests/BugsnagUserTest.m +++ b/Tests/BugsnagUserTest.m @@ -19,7 +19,7 @@ - (void)testDictDeserialisation { NSDictionary *dict = @{ @"id": @"test", - @"emailAddress": @"fake@example.com", + @"email": @"fake@example.com", @"name": @"Tom Bombadil" }; BugsnagUser *user = [[BugsnagUser alloc] initWithDictionary:dict]; @@ -41,7 +41,7 @@ - (void)testPayloadSerialisation { XCTAssertEqual(3, [rootNode count]); XCTAssertEqualObjects(@"test", rootNode[@"id"]); - XCTAssertEqualObjects(@"fake@example.com", rootNode[@"emailAddress"]); + XCTAssertEqualObjects(@"fake@example.com", rootNode[@"email"]); XCTAssertEqualObjects(@"Tom Bombadil", rootNode[@"name"]); } From ec307f190d3458222e3c08ad55b4333343eaa1d4 Mon Sep 17 00:00:00 2001 From: fractalwrench Date: Tue, 12 Jun 2018 14:55:52 +0100 Subject: [PATCH 17/27] refactor: use xctassertthrows rather than try/catch block in test assertions --- Tests/BugsnagConfigurationTests.m | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/Tests/BugsnagConfigurationTests.m b/Tests/BugsnagConfigurationTests.m index 7966e9d7e..5dcc05042 100644 --- a/Tests/BugsnagConfigurationTests.m +++ b/Tests/BugsnagConfigurationTests.m @@ -104,21 +104,15 @@ - (void)testSetEndpoints { } - (void)testSetEmptyNotifyEndpoint { - @try { - BugsnagConfiguration *config = [BugsnagConfiguration new]; - [config setEndpointsForNotify:@"" sessions:@"http://sessions.example.com"]; - XCTFail(); - } @catch(NSException * e) { - } + BugsnagConfiguration *config = [BugsnagConfiguration new]; + XCTAssertThrowsSpecificNamed([config setEndpointsForNotify:@"" sessions:@"http://sessions.example.com"], + NSException, NSInternalInconsistencyException); } - (void)testSetMalformedNotifyEndpoint { - @try { - BugsnagConfiguration *config = [BugsnagConfiguration new]; - [config setEndpointsForNotify:@"http://" sessions:@"http://sessions.example.com"]; - XCTFail(); - } @catch(NSException * e) { - } + BugsnagConfiguration *config = [BugsnagConfiguration new]; + XCTAssertThrowsSpecificNamed([config setEndpointsForNotify:@"http://" sessions:@"http://sessions.example.com"], + NSException, NSInternalInconsistencyException); } - (void)testSetEmptySessionsEndpoint { From e84d311fe91aacbcab77db8e8e763d35e615f047 Mon Sep 17 00:00:00 2001 From: fractalwrench Date: Wed, 13 Jun 2018 15:26:02 +0100 Subject: [PATCH 18/27] fix: prevent duplicate automatic session count in constructor --- Source/BugsnagNotifier.m | 3 --- examples/swift-ios/Podfile.lock | 8 ++++---- features/fixtures/ios-swift-cocoapods/Podfile.lock | 4 ++-- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/Source/BugsnagNotifier.m b/Source/BugsnagNotifier.m index 0459e4c6b..cbf4161b9 100644 --- a/Source/BugsnagNotifier.m +++ b/Source/BugsnagNotifier.m @@ -216,9 +216,6 @@ - (id)initWithConfiguration:(BugsnagConfiguration *)initConfiguration { hasRecordedSessions = true; }]; - - [self.sessionTracker startNewSession:[NSDate date] withUser:nil autoCaptured:YES]; - [self metaDataChanged:self.configuration.metaData]; [self metaDataChanged:self.configuration.config]; [self metaDataChanged:self.state]; diff --git a/examples/swift-ios/Podfile.lock b/examples/swift-ios/Podfile.lock index 7a0be889c..9aeeb27fd 100644 --- a/examples/swift-ios/Podfile.lock +++ b/examples/swift-ios/Podfile.lock @@ -1,16 +1,16 @@ PODS: - - Bugsnag (5.15.4) + - Bugsnag (5.15.6) DEPENDENCIES: - Bugsnag (from `../..`) EXTERNAL SOURCES: Bugsnag: - :path: ../.. + :path: "../.." SPEC CHECKSUMS: - Bugsnag: 904211a0230f254808b47f3adb4b684900772962 + Bugsnag: ff5f5e3059e6a9c9d27a899f3bf3774067553483 PODFILE CHECKSUM: 2107babfbfdb18f0288407b9d9ebd48cbee8661c -COCOAPODS: 1.4.0 +COCOAPODS: 1.5.0 diff --git a/features/fixtures/ios-swift-cocoapods/Podfile.lock b/features/fixtures/ios-swift-cocoapods/Podfile.lock index 9939ae0e6..9ab551a9d 100644 --- a/features/fixtures/ios-swift-cocoapods/Podfile.lock +++ b/features/fixtures/ios-swift-cocoapods/Podfile.lock @@ -1,5 +1,5 @@ PODS: - - Bugsnag (5.15.5) + - Bugsnag (5.15.6) DEPENDENCIES: - Bugsnag (from `../../..`) @@ -9,7 +9,7 @@ EXTERNAL SOURCES: :path: ../../.. SPEC CHECKSUMS: - Bugsnag: d1e6b301c819f4931d6c572da17230d8892acb65 + Bugsnag: ff5f5e3059e6a9c9d27a899f3bf3774067553483 PODFILE CHECKSUM: 4d026fb83571f098c9fb4fa71c1564c72c55ab1a From 0ff92ec412d22b7864a12d7daa12f60f1eb8947f Mon Sep 17 00:00:00 2001 From: fractalwrench Date: Wed, 13 Jun 2018 16:56:45 +0100 Subject: [PATCH 19/27] fix: ensure session is captured on notifier start --- Source/BugsnagNotifier.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/BugsnagNotifier.m b/Source/BugsnagNotifier.m index cbf4161b9..4a0525b28 100644 --- a/Source/BugsnagNotifier.m +++ b/Source/BugsnagNotifier.m @@ -353,9 +353,10 @@ - (void)start { object:nil]; #endif + _started = YES; + // notification not received in time on initial startup, so trigger manually [self willEnterForeground:self]; - _started = YES; } - (void)watchLifecycleEvents:(NSNotificationCenter *)center { From 57044dea8b1ffa34521be340ddedb6ca8581ec39 Mon Sep 17 00:00:00 2001 From: fractalwrench Date: Thu, 14 Jun 2018 15:02:48 +0100 Subject: [PATCH 20/27] fix: use semaphore to synchronise access to session flushing Adds a semaphore that synchronises sending of sessions. This prevents the potential case where a session could be sent multiple times, and passes mazerunner session count scenarios --- Source/BugsnagSessionTracker.m | 55 ++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/Source/BugsnagSessionTracker.m b/Source/BugsnagSessionTracker.m index 7cc66aeb4..53f4c6754 100644 --- a/Source/BugsnagSessionTracker.m +++ b/Source/BugsnagSessionTracker.m @@ -92,34 +92,39 @@ - (void)incrementHandledError { } - (void)send { - @synchronized (self.sessionStore) { - NSMutableArray *sessions = [NSMutableArray new]; - NSArray *fileIds = [self.sessionStore fileIds]; + NSArray *fileIds = [self.sessionStore fileIds]; - for (NSDictionary *dict in [self.sessionStore allFiles]) { - [sessions addObject:[[BugsnagSession alloc] initWithDictionary:dict]]; - } - BugsnagSessionTrackingPayload *payload = [[BugsnagSessionTrackingPayload alloc] initWithSessions:sessions]; - - if (payload.sessions.count > 0) { - [self.apiClient sendData:payload - withPayload:[payload toJson] - toURL:self.config.sessionURL - headers:self.config.sessionApiHeaders - onCompletion:^(id data, BOOL success, NSError *error) { - - if (success && error == nil) { - NSLog(@"Sent sessions to Bugsnag"); - - for (NSString *fileId in fileIds) { - [self.sessionStore deleteFileWithId:fileId]; - } - } else { - NSLog(@"Failed to send sessions to Bugsnag: %@", error); + if (fileIds.count <= 0) { + return; + } + + dispatch_semaphore_t requestSemaphore = dispatch_semaphore_create(0); + NSMutableArray *sessions = [NSMutableArray new]; + + for (NSDictionary *dict in [self.sessionStore allFiles]) { + [sessions addObject:[[BugsnagSession alloc] initWithDictionary:dict]]; + } + BugsnagSessionTrackingPayload *payload = [[BugsnagSessionTrackingPayload alloc] initWithSessions:sessions]; + + if (payload.sessions.count > 0) { + [self.apiClient sendData:payload + withPayload:[payload toJson] + toURL:self.config.sessionURL + headers:self.config.sessionApiHeaders + onCompletion:^(id data, BOOL success, NSError *error) { + if (success && error == nil) { + NSLog(@"Sent sessions to Bugsnag"); + + for (NSString *fileId in fileIds) { + [self.sessionStore deleteFileWithId:fileId]; } - }]; - } + } else { + NSLog(@"Failed to send sessions to Bugsnag: %@", error); + } + dispatch_semaphore_signal(requestSemaphore); + }]; } + dispatch_semaphore_wait(requestSemaphore, DISPATCH_TIME_FOREVER); } @end From 348e0951292c88264d6df94546c500bc93833624 Mon Sep 17 00:00:00 2001 From: fractalwrench Date: Thu, 14 Jun 2018 16:04:22 +0100 Subject: [PATCH 21/27] test: update mazerunner auto session scenario user.id assertion to reflect nil by default --- features/session_tracking.feature | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/features/session_tracking.feature b/features/session_tracking.feature index 3692e1290..27dd99d3a 100644 --- a/features/session_tracking.feature +++ b/features/session_tracking.feature @@ -8,7 +8,9 @@ Scenario: Automatic Session Tracking sends And the "Bugsnag-API-Key" header equals "a35a2a72bd230ac0aa0f52715bbdc6aa" And the payload field "notifier.name" equals "iOS Bugsnag Notifier" And the payload field "sessions" is an array with 1 element - And the session "user.id" is not null + + # N.B. user.id is null by default if not configured by the developer. + And the session "user.id" is null And the session "id" is not null And the session "startedAt" is not null From 3bf9f7210e01bbce6dd285be27c98ab56f9647be Mon Sep 17 00:00:00 2001 From: fractalwrench Date: Mon, 18 Jun 2018 11:18:08 +0100 Subject: [PATCH 22/27] fix: prevent potential deadlock when payload count == 0, by signalling semaphore --- Source/BugsnagSessionTracker.m | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Source/BugsnagSessionTracker.m b/Source/BugsnagSessionTracker.m index 53f4c6754..d7cb22361 100644 --- a/Source/BugsnagSessionTracker.m +++ b/Source/BugsnagSessionTracker.m @@ -63,7 +63,7 @@ - (void)startNewSession:(NSDate *)date - (void)trackSession { [self.sessionStore write:self.currentSession]; self.trackedFirstSession = YES; - + if (self.callback) { self.callback(self.currentSession); } @@ -123,6 +123,8 @@ - (void)send { } dispatch_semaphore_signal(requestSemaphore); }]; + } else { + dispatch_semaphore_signal(requestSemaphore); } dispatch_semaphore_wait(requestSemaphore, DISPATCH_TIME_FOREVER); } From 8a6504959be962e772c7f56a24adf6c863b3e19b Mon Sep 17 00:00:00 2001 From: fractalwrench Date: Mon, 18 Jun 2018 11:44:16 +0100 Subject: [PATCH 23/27] test: update mazerunner session scenarios to rely on automatic flushing rather than manual hooks --- .../iOSTestApp/scenarios/AutoSessionScenario.m | 1 - .../iOSTestApp/scenarios/DisabledSessionTrackingScenario.m | 3 +-- .../iOSTestApp/scenarios/ManualSessionScenario.m | 1 - features/session_tracking.feature | 5 +++-- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/AutoSessionScenario.m b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/AutoSessionScenario.m index d3bb6baed..05fc4ff60 100644 --- a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/AutoSessionScenario.m +++ b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/AutoSessionScenario.m @@ -14,7 +14,6 @@ - (void)startBugsnag { } - (void)run { - [self flushAllSessions]; } @end diff --git a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/DisabledSessionTrackingScenario.m b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/DisabledSessionTrackingScenario.m index 028fdf08f..7270a246c 100644 --- a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/DisabledSessionTrackingScenario.m +++ b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/DisabledSessionTrackingScenario.m @@ -9,7 +9,6 @@ @implementation DisabledSessionTrackingScenario - (void)run { - [self flushAllSessions]; } -@end \ No newline at end of file +@end diff --git a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/ManualSessionScenario.m b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/ManualSessionScenario.m index ab35ab7fa..dd4cb91e0 100644 --- a/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/ManualSessionScenario.m +++ b/features/fixtures/ios-swift-cocoapods/iOSTestApp/scenarios/ManualSessionScenario.m @@ -10,7 +10,6 @@ @implementation ManualSessionScenario - (void)run { [self.config setUser:@"123" withName:@"Joe Bloggs" andEmail:@"user@example.com"]; [Bugsnag startSession]; - [self flushAllSessions]; } @end diff --git a/features/session_tracking.feature b/features/session_tracking.feature index 27dd99d3a..5d09ec56b 100644 --- a/features/session_tracking.feature +++ b/features/session_tracking.feature @@ -2,7 +2,7 @@ Feature: Session Tracking Scenario: Automatic Session Tracking sends When I run "AutoSessionScenario" with the defaults on "iPhone8-11.2" - And I wait for 5 seconds + And I wait for 65 seconds Then I should receive a request And the request is a valid for the session tracking API And the "Bugsnag-API-Key" header equals "a35a2a72bd230ac0aa0f52715bbdc6aa" @@ -16,6 +16,7 @@ Scenario: Automatic Session Tracking sends Scenario: Manual Session sends When I run "ManualSessionScenario" with the defaults on "iPhone8-11.2" + And I wait for 65 seconds Then I should receive a request And the request is a valid for the session tracking API And the "Bugsnag-API-Key" header equals "a35a2a72bd230ac0aa0f52715bbdc6aa" @@ -29,5 +30,5 @@ Scenario: Manual Session sends Scenario: Disabled Session Tracking sends no requests When I run "DisabledSessionTrackingScenario" with the defaults on "iPhone8-11.2" - And I wait for 5 seconds + And I wait for 65 seconds Then I should receive 0 requests From f4bffac656adce0fbba1e0cab1d0f2b59578d227 Mon Sep 17 00:00:00 2001 From: fractalwrench Date: Mon, 18 Jun 2018 12:08:22 +0100 Subject: [PATCH 24/27] feat: make notifyURL and sessionURL readonly --- Source/BugsnagConfiguration.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Source/BugsnagConfiguration.h b/Source/BugsnagConfiguration.h index 6c4d23814..c3e905926 100644 --- a/Source/BugsnagConfiguration.h +++ b/Source/BugsnagConfiguration.h @@ -145,20 +145,20 @@ BugsnagBreadcrumbs *breadcrumbs; /** * Retrieves the endpoint used to notify Bugsnag of errors * - * NOTE: it is strongly recommended that you set this value via setEndpointsForNotify:sessions: instead. + * NOTE: If you want to set this value, you should do so via setEndpointsForNotify:sessions: instead. * * @see setEndpointsForNotify:sessions: */ -@property(readwrite, retain, nullable) NSURL *notifyURL; +@property(readonly, retain, nullable) NSURL *notifyURL; /** * Retrieves the endpoint used to send tracked sessions to Bugsnag * - * NOTE: it is strongly recommended that you set this value via setEndpointsForNotify:sessions: instead. + * NOTE: If you want to set this value, you should do so via setEndpointsForNotify:sessions: instead. * * @see setEndpointsForNotify:sessions: */ -@property(readwrite, retain, nullable) NSURL *sessionURL; +@property(readonly, retain, nullable) NSURL *sessionURL; /** * Set the endpoints to send data to. By default we'll send error reports to From 19d23a456f4a2995d312acbf9a4c35831aaa9005 Mon Sep 17 00:00:00 2001 From: fractalwrench Date: Mon, 18 Jun 2018 12:14:48 +0100 Subject: [PATCH 25/27] docs: add changelog entry for cocoa session tracking --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 536c1adfe..3ff82bb2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,15 @@ Changelog ========= +## 5.16.0 (TBD) + +**IMPORTANT NOTE**: this release alters the behaviour of the notifier to track sessions automatically. +A session will be automatically captured on each app launch and sent to [https://sessions.bugsnag.com](https://sessions.bugsnag.com). + +If you use Bugsnag On-Premise, it is now also recommended that you set your notify and session endpoints via `config.setEndpoints(notify:sessions:)`. The previous properties used to configure this, `config.notifyURL` and `config.sessionURL`, are now `readonly` and therefore no longer assignable. + +* Enable automatic session tracking by default [#286](https://github.com/bugsnag/bugsnag-cocoa/pull/286) + ## 5.15.6 (30 May 2018) ### Bug Fixes From 00bb48b6d65acd4997c442574e04ea6dd9ad0f41 Mon Sep 17 00:00:00 2001 From: fractalwrench Date: Wed, 20 Jun 2018 09:59:08 +0100 Subject: [PATCH 26/27] test: pass readonly notifyURL + sessionURL tests --- CHANGELOG.md | 2 +- Tests/BugsnagConfigurationTests.m | 10 ++++------ Tests/BugsnagSinkTests.m | 2 +- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ff82bb2d..cb202eb10 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ Changelog ## 5.16.0 (TBD) -**IMPORTANT NOTE**: this release alters the behaviour of the notifier to track sessions automatically. +This release alters the behaviour of the notifier to track sessions automatically. A session will be automatically captured on each app launch and sent to [https://sessions.bugsnag.com](https://sessions.bugsnag.com). If you use Bugsnag On-Premise, it is now also recommended that you set your notify and session endpoints via `config.setEndpoints(notify:sessions:)`. The previous properties used to configure this, `config.notifyURL` and `config.sessionURL`, are now `readonly` and therefore no longer assignable. diff --git a/Tests/BugsnagConfigurationTests.m b/Tests/BugsnagConfigurationTests.m index 5dcc05042..3e7a481ea 100644 --- a/Tests/BugsnagConfigurationTests.m +++ b/Tests/BugsnagConfigurationTests.m @@ -83,17 +83,15 @@ - (void)testSessionEndpoints { XCTAssertEqualObjects([NSURL URLWithString:@"https://sessions.bugsnag.com"], config.sessionURL); // Setting an endpoint - NSURL *endpoint = [NSURL URLWithString:@"http://localhost:8000"]; - config.sessionURL = endpoint; - XCTAssertEqualObjects(endpoint, config.sessionURL); + [config setEndpointsForNotify:@"http://localhost:1234" sessions:@"http://localhost:8000"]; + XCTAssertEqualObjects([NSURL URLWithString:@"http://localhost:8000"], config.sessionURL); } - (void)testNotifyEndpoint { BugsnagConfiguration *config = [BugsnagConfiguration new]; XCTAssertEqualObjects([NSURL URLWithString:@"https://notify.bugsnag.com/"], config.notifyURL); - NSURL *endpoint = [NSURL URLWithString:@"http://localhost:8000"]; - config.notifyURL = endpoint; - XCTAssertEqualObjects(endpoint, config.notifyURL); + [config setEndpointsForNotify:@"http://localhost:1234" sessions:@"http://localhost:8000"]; + XCTAssertEqualObjects([NSURL URLWithString:@"http://localhost:1234"], config.notifyURL); } - (void)testSetEndpoints { diff --git a/Tests/BugsnagSinkTests.m b/Tests/BugsnagSinkTests.m index afe6c3bc6..1e3ab84c3 100644 --- a/Tests/BugsnagSinkTests.m +++ b/Tests/BugsnagSinkTests.m @@ -39,7 +39,7 @@ - (void)setUp { config.autoNotify = NO; config.apiKey = @"apiKeyHere"; config.releaseStage = @"MagicalTestingTime"; - config.notifyURL = nil; + [config setEndpointsForNotify:@"http://localhost:8000" sessions:@"http://localhost:8000"]; [Bugsnag startBugsnagWithConfiguration:config]; BugsnagCrashReport *report = [[BugsnagCrashReport alloc] initWithKSReport:self.rawReportData]; From d05198d8e474af3da1ade87dfc2a5147734aeedc Mon Sep 17 00:00:00 2001 From: fractalwrench Date: Wed, 20 Jun 2018 15:45:40 +0100 Subject: [PATCH 27/27] docs: note that overriding endpoints is for test purposes only --- Tests/BugsnagConfigurationTests.m | 4 +++- Tests/BugsnagSinkTests.m | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Tests/BugsnagConfigurationTests.m b/Tests/BugsnagConfigurationTests.m index 3e7a481ea..3aadd2cc6 100644 --- a/Tests/BugsnagConfigurationTests.m +++ b/Tests/BugsnagConfigurationTests.m @@ -82,7 +82,7 @@ - (void)testSessionEndpoints { // Default endpoints XCTAssertEqualObjects([NSURL URLWithString:@"https://sessions.bugsnag.com"], config.sessionURL); - // Setting an endpoint + // Test overriding the session endpoint (use dummy endpoints to avoid hitting production) [config setEndpointsForNotify:@"http://localhost:1234" sessions:@"http://localhost:8000"]; XCTAssertEqualObjects([NSURL URLWithString:@"http://localhost:8000"], config.sessionURL); } @@ -90,6 +90,8 @@ - (void)testSessionEndpoints { - (void)testNotifyEndpoint { BugsnagConfiguration *config = [BugsnagConfiguration new]; XCTAssertEqualObjects([NSURL URLWithString:@"https://notify.bugsnag.com/"], config.notifyURL); + + // Test overriding the notify endpoint (use dummy endpoints to avoid hitting production) [config setEndpointsForNotify:@"http://localhost:1234" sessions:@"http://localhost:8000"]; XCTAssertEqualObjects([NSURL URLWithString:@"http://localhost:1234"], config.notifyURL); } diff --git a/Tests/BugsnagSinkTests.m b/Tests/BugsnagSinkTests.m index 1e3ab84c3..b00a67053 100644 --- a/Tests/BugsnagSinkTests.m +++ b/Tests/BugsnagSinkTests.m @@ -39,7 +39,9 @@ - (void)setUp { config.autoNotify = NO; config.apiKey = @"apiKeyHere"; config.releaseStage = @"MagicalTestingTime"; - [config setEndpointsForNotify:@"http://localhost:8000" sessions:@"http://localhost:8000"]; + + // set a dummy endpoint, avoid hitting production + [config setEndpointsForNotify:@"http://localhost:1234" sessions:@"http://localhost:1234"]; [Bugsnag startBugsnagWithConfiguration:config]; BugsnagCrashReport *report = [[BugsnagCrashReport alloc] initWithKSReport:self.rawReportData];