From 0179f890e2e02424bebf99e388389b1942d31cf2 Mon Sep 17 00:00:00 2001 From: Dhiogo Ramos Brustolin Date: Wed, 23 Nov 2022 13:09:46 +0100 Subject: [PATCH 1/3] fix core data --- Sentry.xcodeproj/project.pbxproj | 4 + Sources/Sentry/SentryCoreDataTracker.m | 5 +- Tests/SentryTests/ClearTestState.swift | 53 +++++++------ .../CoreData/SentryCoreDataTrackerObjcTests.m | 76 +++++++++++++++++++ .../CoreData/SentryCoreDataTrackerTest.swift | 28 +++++++ 5 files changed, 140 insertions(+), 26 deletions(-) create mode 100644 Tests/SentryTests/Integrations/Performance/CoreData/SentryCoreDataTrackerObjcTests.m diff --git a/Sentry.xcodeproj/project.pbxproj b/Sentry.xcodeproj/project.pbxproj index 57a32a2ac09..c6ef5b63491 100644 --- a/Sentry.xcodeproj/project.pbxproj +++ b/Sentry.xcodeproj/project.pbxproj @@ -722,6 +722,7 @@ D8ACE3CF2762187D00F5A213 /* SentryFileIOTrackingIntegration.h in Headers */ = {isa = PBXBuildFile; fileRef = D8ACE3CC2762187D00F5A213 /* SentryFileIOTrackingIntegration.h */; }; D8B76B062808066D000A58C4 /* SentryScreenshotIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8B76B042808060E000A58C4 /* SentryScreenshotIntegrationTests.swift */; }; D8B76B0828081461000A58C4 /* TestSentryScreenShot.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8B76B0728081461000A58C4 /* TestSentryScreenShot.swift */; }; + D8BD2E37292E1D6B00D96C6A /* SentryCoreDataTrackerObjcTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D8BD2E36292E1D6B00D96C6A /* SentryCoreDataTrackerObjcTests.m */; }; D8C67E9B28000E24007E326E /* SentryUIApplication.h in Headers */ = {isa = PBXBuildFile; fileRef = D8C67E9928000E23007E326E /* SentryUIApplication.h */; }; D8C67E9C28000E24007E326E /* SentryScreenshot.h in Headers */ = {isa = PBXBuildFile; fileRef = D8C67E9A28000E23007E326E /* SentryScreenshot.h */; }; D8CE69BC277E39C700C6EC5C /* SentryFileIOTrackingIntegrationObjCTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D8CE69BB277E39C700C6EC5C /* SentryFileIOTrackingIntegrationObjCTests.m */; }; @@ -1523,6 +1524,7 @@ D8ACE3CC2762187D00F5A213 /* SentryFileIOTrackingIntegration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SentryFileIOTrackingIntegration.h; path = include/SentryFileIOTrackingIntegration.h; sourceTree = ""; }; D8B76B042808060E000A58C4 /* SentryScreenshotIntegrationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryScreenshotIntegrationTests.swift; sourceTree = ""; }; D8B76B0728081461000A58C4 /* TestSentryScreenShot.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestSentryScreenShot.swift; sourceTree = ""; }; + D8BD2E36292E1D6B00D96C6A /* SentryCoreDataTrackerObjcTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryCoreDataTrackerObjcTests.m; sourceTree = ""; }; D8C67E9928000E23007E326E /* SentryUIApplication.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SentryUIApplication.h; path = include/SentryUIApplication.h; sourceTree = ""; }; D8C67E9A28000E23007E326E /* SentryScreenshot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SentryScreenshot.h; path = include/SentryScreenshot.h; sourceTree = ""; }; D8CE69BB277E39C700C6EC5C /* SentryFileIOTrackingIntegrationObjCTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryFileIOTrackingIntegrationObjCTests.m; sourceTree = ""; }; @@ -2922,6 +2924,7 @@ D86F419727C8FEFA00490520 /* SentryCoreDataMiddleware+Extension.swift */, D855B3E727D652AF00BCED76 /* SentryCoreDataTrackingIntegrationTest.swift */, D855B3E927D652C700BCED76 /* TestCoreDataStack.swift */, + D8BD2E36292E1D6B00D96C6A /* SentryCoreDataTrackerObjcTests.m */, ); path = CoreData; sourceTree = ""; @@ -3716,6 +3719,7 @@ 7B34721728086A9D0041F047 /* SentrySwizzleWrapperTests.swift in Sources */, 8EC4CF5025C3A0070093DEE9 /* SentrySpanContextTests.swift in Sources */, 7BE0DC2F272ABAF6004FA8B7 /* SentryAutoBreadcrumbTrackingIntegrationTests.swift in Sources */, + D8BD2E37292E1D6B00D96C6A /* SentryCoreDataTrackerObjcTests.m in Sources */, 7BA1C51F2716DDB3005D75A4 /* Invocations.swift in Sources */, 7B869EBE249B964D004F4FDB /* SentryThreadEquality.swift in Sources */, 7BC6EBF8255C05060059822A /* TestData.swift in Sources */, diff --git a/Sources/Sentry/SentryCoreDataTracker.m b/Sources/Sentry/SentryCoreDataTracker.m index ef592ff7842..98567e4a56d 100644 --- a/Sources/Sentry/SentryCoreDataTracker.m +++ b/Sources/Sentry/SentryCoreDataTracker.m @@ -50,7 +50,7 @@ - (NSArray *)managedObjectContext:(NSManagedObjectContext *)context [fetchSpan setDataValue:[NSNumber numberWithInteger:result.count] forKey:@"read_count"]; [fetchSpan - finishWithStatus:error != nil ? kSentrySpanStatusInternalError : kSentrySpanStatusOk]; + finishWithStatus:result == nil ? kSentrySpanStatusInternalError : kSentrySpanStatusOk]; SENTRY_LOG_DEBUG(@"SentryCoreDataTracker automatically finished span with status: %@", error == nil ? @"ok" : @"error"); @@ -91,8 +91,7 @@ - (BOOL)managedObjectContext:(NSManagedObjectContext *)context BOOL result = original(error); if (fetchSpan) { - [fetchSpan - finishWithStatus:*error != nil ? kSentrySpanStatusInternalError : kSentrySpanStatusOk]; + [fetchSpan finishWithStatus:result ? kSentrySpanStatusOk : kSentrySpanStatusInternalError]; SENTRY_LOG_DEBUG(@"SentryCoreDataTracker automatically finished span with status: %@", *error == nil ? @"ok" : @"error"); diff --git a/Tests/SentryTests/ClearTestState.swift b/Tests/SentryTests/ClearTestState.swift index 02db84e1294..60b77d8f4a9 100644 --- a/Tests/SentryTests/ClearTestState.swift +++ b/Tests/SentryTests/ClearTestState.swift @@ -2,27 +2,34 @@ import Foundation import Sentry func clearTestState() { - SentrySDK.close() - SentrySDK.setCurrentHub(nil) - SentrySDK.crashedLastRunCalled = false - SentrySDK.startInvocations = 0 - - PrivateSentrySDKOnly.onAppStartMeasurementAvailable = nil - PrivateSentrySDKOnly.appStartMeasurementHybridSDKMode = false - SentrySDK.setAppStartMeasurement(nil) - CurrentDate.setCurrentDateProvider(nil) - SentryNetworkTracker.sharedInstance.disable() - - #if os(iOS) || os(tvOS) || targetEnvironment(macCatalyst) - let framesTracker = SentryFramesTracker.sharedInstance() - framesTracker.stop() - framesTracker.resetFrames() - - setenv("ActivePrewarm", "0", 1) - SentryAppStartTracker.load() - #endif - - SentryDependencyContainer.reset() - Dynamic(SentryGlobalEventProcessor.shared()).removeAllProcessors() - SentrySwizzleWrapper.sharedInstance.removeAllCallbacks() + TestCleanup.clearTestState() +} + +@objcMembers +class TestCleanup: NSObject { + static func clearTestState() { + SentrySDK.close() + SentrySDK.setCurrentHub(nil) + SentrySDK.crashedLastRunCalled = false + SentrySDK.startInvocations = 0 + + PrivateSentrySDKOnly.onAppStartMeasurementAvailable = nil + PrivateSentrySDKOnly.appStartMeasurementHybridSDKMode = false + SentrySDK.setAppStartMeasurement(nil) + CurrentDate.setCurrentDateProvider(nil) + SentryNetworkTracker.sharedInstance.disable() + + #if os(iOS) || os(tvOS) || targetEnvironment(macCatalyst) + let framesTracker = SentryFramesTracker.sharedInstance() + framesTracker.stop() + framesTracker.resetFrames() + + setenv("ActivePrewarm", "0", 1) + SentryAppStartTracker.load() + #endif + + SentryDependencyContainer.reset() + Dynamic(SentryGlobalEventProcessor.shared()).removeAllProcessors() + SentrySwizzleWrapper.sharedInstance.removeAllCallbacks() + } } diff --git a/Tests/SentryTests/Integrations/Performance/CoreData/SentryCoreDataTrackerObjcTests.m b/Tests/SentryTests/Integrations/Performance/CoreData/SentryCoreDataTrackerObjcTests.m new file mode 100644 index 00000000000..b8a5c11f261 --- /dev/null +++ b/Tests/SentryTests/Integrations/Performance/CoreData/SentryCoreDataTrackerObjcTests.m @@ -0,0 +1,76 @@ +#import "SentryTests-Swift.h" +#import +#import + +@interface SentryCoreDataTrackerObjcTests : XCTestCase + +@end + +@implementation SentryCoreDataTrackerObjcTests { + TestNSManagedObjectContext *context; +} + +- (void)setUp +{ + [super setUp]; +} + +- (void)tearDown +{ + [TestCleanup clearTestState]; + [super tearDown]; +} + +- (void)test_requestWithErrorPointer_noError +{ + TestNSManagedObjectContext *context = [[TestNSManagedObjectContext alloc] init]; + SentryCoreDataTracker *dataTracker = [[SentryCoreDataTracker alloc] init]; + + SentryTracer *tracer = [SentrySDK startTransactionWithName:@"TestTransaction" + operation:@"TestTransactionOperation" + bindToScope:true]; + + NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"TestEntity"]; + NSError *error; + NSArray *result = + [dataTracker managedObjectContext:context + executeFetchRequest:fetchRequest + error:&error + originalImp:^NSArray *( + __unused NSFetchRequest *req, __unused NSError **internalError) { + return [[NSArray alloc] initWithObjects:@"One Object", nil]; + }]; + + SentrySpan *span = tracer.children.firstObject; + + XCTAssertEqual(span.context.status, kSentrySpanStatusOk); + + XCTAssertEqual(result.count, 1); +} + +- (void)test_requestWithErrorPointer_WithError +{ + TestNSManagedObjectContext *context = [[TestNSManagedObjectContext alloc] init]; + SentryCoreDataTracker *dataTracker = [[SentryCoreDataTracker alloc] init]; + + SentryTracer *tracer = [SentrySDK startTransactionWithName:@"TestTransaction" + operation:@"TestTransactionOperation" + bindToScope:true]; + + NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"TestEntity"]; + NSError *error; + __unused NSArray *result = + [dataTracker managedObjectContext:context + executeFetchRequest:fetchRequest + error:&error + originalImp:^NSArray *( + __unused NSFetchRequest *req, __unused NSError **internalError) { + *internalError = [[NSError alloc] init]; + return nil; + }]; + + SentrySpan *span = tracer.children.firstObject; + XCTAssertEqual(span.context.status, kSentrySpanStatusInternalError); +} + +@end diff --git a/Tests/SentryTests/Integrations/Performance/CoreData/SentryCoreDataTrackerTest.swift b/Tests/SentryTests/Integrations/Performance/CoreData/SentryCoreDataTrackerTest.swift index 66303f720c2..3a3e0ff8519 100644 --- a/Tests/SentryTests/Integrations/Performance/CoreData/SentryCoreDataTrackerTest.swift +++ b/Tests/SentryTests/Integrations/Performance/CoreData/SentryCoreDataTrackerTest.swift @@ -188,6 +188,34 @@ class SentryCoreDataTrackerTests: XCTestCase { XCTAssertEqual(updated["SecondTestEntity"] as? Int, 2) } + func test_Request_with_Error() { + let fetch = NSFetchRequest(entityName: "TestEntity") + + let transaction = startTransaction() + let sut = fixture.getSut() + + let context = fixture.context + + let _ = try? sut.fetchManagedObjectContext(context, request: fetch) { _, _ in + return nil + } + + XCTAssertEqual(transaction.children.count, 1) + XCTAssertEqual(transaction.children[0].context.status, .internalError) + } + + func test_save_with_Error() { + let transaction = startTransaction() + let sut = fixture.getSut() + fixture.context.inserted = [fixture.testEntity()] + try? sut.saveManagedObjectContext(fixture.context) { _ in + return false + } + + XCTAssertEqual(transaction.children.count, 1) + XCTAssertEqual(transaction.children[0].context.status, .internalError) + } + func test_Save_NoChanges() { let sut = fixture.getSut() From 41d80a604398f6eba2f6dabad73122539f6785df Mon Sep 17 00:00:00 2001 From: Dhiogo Ramos Brustolin Date: Wed, 23 Nov 2022 17:29:39 +0100 Subject: [PATCH 2/3] Update CHANGELOG.md --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f6ca4b08dc..47db1c614c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +### Fixes + +- Core data span status with error (#2439) + ## 7.31.2 ### Fixes From 8be688630df8b4c5ba275bf88160c85bb4a8e276 Mon Sep 17 00:00:00 2001 From: Dhiogo Ramos Brustolin Date: Wed, 23 Nov 2022 17:30:21 +0100 Subject: [PATCH 3/3] remove test file --- Sentry.xcodeproj/project.pbxproj | 4 - .../CoreData/SentryCoreDataTrackerObjcTests.m | 76 ------------------- 2 files changed, 80 deletions(-) delete mode 100644 Tests/SentryTests/Integrations/Performance/CoreData/SentryCoreDataTrackerObjcTests.m diff --git a/Sentry.xcodeproj/project.pbxproj b/Sentry.xcodeproj/project.pbxproj index c6ef5b63491..57a32a2ac09 100644 --- a/Sentry.xcodeproj/project.pbxproj +++ b/Sentry.xcodeproj/project.pbxproj @@ -722,7 +722,6 @@ D8ACE3CF2762187D00F5A213 /* SentryFileIOTrackingIntegration.h in Headers */ = {isa = PBXBuildFile; fileRef = D8ACE3CC2762187D00F5A213 /* SentryFileIOTrackingIntegration.h */; }; D8B76B062808066D000A58C4 /* SentryScreenshotIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8B76B042808060E000A58C4 /* SentryScreenshotIntegrationTests.swift */; }; D8B76B0828081461000A58C4 /* TestSentryScreenShot.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8B76B0728081461000A58C4 /* TestSentryScreenShot.swift */; }; - D8BD2E37292E1D6B00D96C6A /* SentryCoreDataTrackerObjcTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D8BD2E36292E1D6B00D96C6A /* SentryCoreDataTrackerObjcTests.m */; }; D8C67E9B28000E24007E326E /* SentryUIApplication.h in Headers */ = {isa = PBXBuildFile; fileRef = D8C67E9928000E23007E326E /* SentryUIApplication.h */; }; D8C67E9C28000E24007E326E /* SentryScreenshot.h in Headers */ = {isa = PBXBuildFile; fileRef = D8C67E9A28000E23007E326E /* SentryScreenshot.h */; }; D8CE69BC277E39C700C6EC5C /* SentryFileIOTrackingIntegrationObjCTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D8CE69BB277E39C700C6EC5C /* SentryFileIOTrackingIntegrationObjCTests.m */; }; @@ -1524,7 +1523,6 @@ D8ACE3CC2762187D00F5A213 /* SentryFileIOTrackingIntegration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SentryFileIOTrackingIntegration.h; path = include/SentryFileIOTrackingIntegration.h; sourceTree = ""; }; D8B76B042808060E000A58C4 /* SentryScreenshotIntegrationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryScreenshotIntegrationTests.swift; sourceTree = ""; }; D8B76B0728081461000A58C4 /* TestSentryScreenShot.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestSentryScreenShot.swift; sourceTree = ""; }; - D8BD2E36292E1D6B00D96C6A /* SentryCoreDataTrackerObjcTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryCoreDataTrackerObjcTests.m; sourceTree = ""; }; D8C67E9928000E23007E326E /* SentryUIApplication.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SentryUIApplication.h; path = include/SentryUIApplication.h; sourceTree = ""; }; D8C67E9A28000E23007E326E /* SentryScreenshot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SentryScreenshot.h; path = include/SentryScreenshot.h; sourceTree = ""; }; D8CE69BB277E39C700C6EC5C /* SentryFileIOTrackingIntegrationObjCTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryFileIOTrackingIntegrationObjCTests.m; sourceTree = ""; }; @@ -2924,7 +2922,6 @@ D86F419727C8FEFA00490520 /* SentryCoreDataMiddleware+Extension.swift */, D855B3E727D652AF00BCED76 /* SentryCoreDataTrackingIntegrationTest.swift */, D855B3E927D652C700BCED76 /* TestCoreDataStack.swift */, - D8BD2E36292E1D6B00D96C6A /* SentryCoreDataTrackerObjcTests.m */, ); path = CoreData; sourceTree = ""; @@ -3719,7 +3716,6 @@ 7B34721728086A9D0041F047 /* SentrySwizzleWrapperTests.swift in Sources */, 8EC4CF5025C3A0070093DEE9 /* SentrySpanContextTests.swift in Sources */, 7BE0DC2F272ABAF6004FA8B7 /* SentryAutoBreadcrumbTrackingIntegrationTests.swift in Sources */, - D8BD2E37292E1D6B00D96C6A /* SentryCoreDataTrackerObjcTests.m in Sources */, 7BA1C51F2716DDB3005D75A4 /* Invocations.swift in Sources */, 7B869EBE249B964D004F4FDB /* SentryThreadEquality.swift in Sources */, 7BC6EBF8255C05060059822A /* TestData.swift in Sources */, diff --git a/Tests/SentryTests/Integrations/Performance/CoreData/SentryCoreDataTrackerObjcTests.m b/Tests/SentryTests/Integrations/Performance/CoreData/SentryCoreDataTrackerObjcTests.m deleted file mode 100644 index b8a5c11f261..00000000000 --- a/Tests/SentryTests/Integrations/Performance/CoreData/SentryCoreDataTrackerObjcTests.m +++ /dev/null @@ -1,76 +0,0 @@ -#import "SentryTests-Swift.h" -#import -#import - -@interface SentryCoreDataTrackerObjcTests : XCTestCase - -@end - -@implementation SentryCoreDataTrackerObjcTests { - TestNSManagedObjectContext *context; -} - -- (void)setUp -{ - [super setUp]; -} - -- (void)tearDown -{ - [TestCleanup clearTestState]; - [super tearDown]; -} - -- (void)test_requestWithErrorPointer_noError -{ - TestNSManagedObjectContext *context = [[TestNSManagedObjectContext alloc] init]; - SentryCoreDataTracker *dataTracker = [[SentryCoreDataTracker alloc] init]; - - SentryTracer *tracer = [SentrySDK startTransactionWithName:@"TestTransaction" - operation:@"TestTransactionOperation" - bindToScope:true]; - - NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"TestEntity"]; - NSError *error; - NSArray *result = - [dataTracker managedObjectContext:context - executeFetchRequest:fetchRequest - error:&error - originalImp:^NSArray *( - __unused NSFetchRequest *req, __unused NSError **internalError) { - return [[NSArray alloc] initWithObjects:@"One Object", nil]; - }]; - - SentrySpan *span = tracer.children.firstObject; - - XCTAssertEqual(span.context.status, kSentrySpanStatusOk); - - XCTAssertEqual(result.count, 1); -} - -- (void)test_requestWithErrorPointer_WithError -{ - TestNSManagedObjectContext *context = [[TestNSManagedObjectContext alloc] init]; - SentryCoreDataTracker *dataTracker = [[SentryCoreDataTracker alloc] init]; - - SentryTracer *tracer = [SentrySDK startTransactionWithName:@"TestTransaction" - operation:@"TestTransactionOperation" - bindToScope:true]; - - NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"TestEntity"]; - NSError *error; - __unused NSArray *result = - [dataTracker managedObjectContext:context - executeFetchRequest:fetchRequest - error:&error - originalImp:^NSArray *( - __unused NSFetchRequest *req, __unused NSError **internalError) { - *internalError = [[NSError alloc] init]; - return nil; - }]; - - SentrySpan *span = tracer.children.firstObject; - XCTAssertEqual(span.context.status, kSentrySpanStatusInternalError); -} - -@end