From 9a1edd7d1b3e4f4ba36471bd9a9483b4c3bb8115 Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Tue, 9 Apr 2024 08:14:38 -0500 Subject: [PATCH 01/21] feat: implement starting continuous profiling from launch --- .../Sentry/Profiling/SentryLaunchProfiling.m | 68 ++++++++++++++----- Sources/Sentry/SentrySampling.m | 12 ++++ Sources/Sentry/SentryTimeToDisplayTracker.m | 6 ++ Sources/Sentry/SentryTracer.m | 7 -- .../HybridPublic/SentryDependencyContainer.h | 1 - .../Sentry/include/SentryLaunchProfiling.h | 7 ++ Sources/Sentry/include/SentrySampling.h | 10 ++- 7 files changed, 86 insertions(+), 25 deletions(-) diff --git a/Sources/Sentry/Profiling/SentryLaunchProfiling.m b/Sources/Sentry/Profiling/SentryLaunchProfiling.m index d7edd1b860..285dcabece 100644 --- a/Sources/Sentry/Profiling/SentryLaunchProfiling.m +++ b/Sources/Sentry/Profiling/SentryLaunchProfiling.m @@ -2,13 +2,14 @@ #if SENTRY_TARGET_PROFILING_SUPPORTED +# import "SentryContinuousProfiler.h" # import "SentryDependencyContainer.h" # import "SentryDispatchQueueWrapper.h" # import "SentryFileManager.h" # import "SentryInternalDefines.h" # import "SentryLaunchProfiling.h" # import "SentryLog.h" -# import "SentryOptions.h" +# import "SentryOptions+Private.h" # import "SentryProfiler+Private.h" # import "SentryRandom.h" # import "SentrySamplerDecision.h" @@ -23,6 +24,12 @@ NS_ASSUME_NONNULL_BEGIN +BOOL isProfilingAppLaunch; +NSString *const kSentryLaunchProfileConfigKeyTracesSampleRate = @"traces"; +NSString *const kSentryLaunchProfileConfigKeyProfilesSampleRate = @"profiles"; +NSString *const kSentryLaunchProfileConfigKeyContinuousProfiling = @"continuous-profiling"; +static SentryTracer *_Nullable launchTracer; + # pragma mark - Private static SentryTracer *_Nullable sentry_launchTracer; @@ -41,6 +48,7 @@ typedef struct { BOOL shouldProfile; + /** Only needed for legacy launch profiling; unused with continuous profiling. */ SentrySamplerDecision *_Nullable tracesDecision; SentrySamplerDecision *_Nullable profilesDecision; } SentryLaunchProfileConfig; @@ -51,12 +59,15 @@ SentryLaunchProfileConfig sentry_shouldProfileNextLaunch(SentryOptions *options) { - BOOL shouldProfileNextLaunch = options.enableAppLaunchProfiling && options.enableTracing; + BOOL shouldProfileNextLaunch = options.enableAppLaunchProfiling + && (options.enableContinuousProfiling || options.enableTracing); if (!shouldProfileNextLaunch) { SENTRY_LOG_DEBUG(@"Won't profile next launch due to specified options configuration: " - @"options.enableAppLaunchProfiling: %d; options.enableTracing: %d", - options.enableAppLaunchProfiling, options.enableTracing); - return (SentryLaunchProfileConfig) { NO, nil, nil }; + @"options.enableAppLaunchProfiling: %d; options.enableTracing: %d; " + @"options.enableContinuousProfiling: %d", + options.enableAppLaunchProfiling, options.enableTracing, + options.enableContinuousProfiling); + return (SentryLaunchProfileConfig) { options.enableAppLaunchProfiling, nil, nil }; } SentryTransactionContext *transactionContext = @@ -65,6 +76,17 @@ SentrySamplingContext *context = [[SentrySamplingContext alloc] initWithTransactionContext:transactionContext]; + if (options.enableContinuousProfiling) { + SentrySamplerDecision *profilesSamplerDecision = sampleContinuousProfile(context, options); + if (profilesSamplerDecision.decision != kSentrySampleDecisionYes) { + SENTRY_LOG_DEBUG(@"Sampling out the launch continuous profile."); + return (SentryLaunchProfileConfig) { NO, nil, nil }; + } + + SENTRY_LOG_DEBUG(@"Will continuously profile the next session starting from launch."); + return (SentryLaunchProfileConfig) { YES, nil, profilesSamplerDecision }; + } + SentrySamplerDecision *tracesSamplerDecision = sentry_sampleTrace(context, options); if (tracesSamplerDecision.decision != kSentrySampleDecisionYes) { SENTRY_LOG_DEBUG(@"Sampling out the launch trace."); @@ -74,11 +96,11 @@ SentrySamplerDecision *profilesSamplerDecision = sentry_sampleTraceProfile(context, tracesSamplerDecision, options); if (profilesSamplerDecision.decision != kSentrySampleDecisionYes) { - SENTRY_LOG_DEBUG(@"Sampling out the launch profile."); + SENTRY_LOG_DEBUG(@"Sampling out the launch legacy profile."); return (SentryLaunchProfileConfig) { NO, nil, nil }; } - SENTRY_LOG_DEBUG(@"Will profile the next launch."); + SENTRY_LOG_DEBUG(@"Will start legacy profile next launch."); return (SentryLaunchProfileConfig) { YES, tracesSamplerDecision, profilesSamplerDecision }; } @@ -111,8 +133,12 @@ NSMutableDictionary *configDict = [NSMutableDictionary dictionary]; - configDict[kSentryLaunchProfileConfigKeyTracesSampleRate] - = config.tracesDecision.sampleRate; + if (options.enableContinuousProfiling) { + configDict[kSentryLaunchProfileConfigKeyContinuousProfiling] = @YES; + } else { + configDict[kSentryLaunchProfileConfigKeyTracesSampleRate] + = config.tracesDecision.sampleRate; + } configDict[kSentryLaunchProfileConfigKeyProfilesSampleRate] = config.profilesDecision.sampleRate; writeAppLaunchProfilingConfigFile(configDict); @@ -122,7 +148,6 @@ void sentry_startLaunchProfile(void) { - static dispatch_once_t onceToken; // this function is called from SentryTracer.load but in the future we may expose access // directly to customers, and we'll want to ensure it only runs once. dispatch_once is an @@ -140,12 +165,23 @@ [SentryLog configure:YES diagnosticLevel:kSentryLevelDebug]; # endif // defined(DEBUG) - NSDictionary *rates = appLaunchProfileConfiguration(); - NSNumber *profilesRate = rates[kSentryLaunchProfileConfigKeyProfilesSampleRate]; - NSNumber *tracesRate = rates[kSentryLaunchProfileConfigKeyTracesSampleRate]; - if (profilesRate == nil || tracesRate == nil) { - SENTRY_LOG_DEBUG( - @"Received a nil configured launch sample rate, will not trace or profile."); + NSDictionary *launchConfig = appLaunchProfileConfiguration(); + NSNumber *profilesRate = launchConfig[kSentryLaunchProfileConfigKeyProfilesSampleRate]; + if ([launchConfig[kSentryLaunchProfileConfigKeyContinuousProfiling] boolValue]) { + if (profilesRate == nil) { + SENTRY_LOG_DEBUG(@"Received a nil configured launch profile sample rate, will not " + @"start continuous profiler for launch."); + return; + } + + [SentryContinuousProfiler start]; + return; + } + + NSNumber *tracesRate = launchConfig[kSentryLaunchProfileConfigKeyTracesSampleRate]; + if (tracesRate == nil) { + SENTRY_LOG_DEBUG(@"Received a nil configured launch trace sample rate, will not start " + @"a profiled launch trace."); return; } diff --git a/Sources/Sentry/SentrySampling.m b/Sources/Sentry/SentrySampling.m index 4fc6de1942..1c6fa4b222 100644 --- a/Sources/Sentry/SentrySampling.m +++ b/Sources/Sentry/SentrySampling.m @@ -112,6 +112,18 @@ return calcSampleFromNumericalRate(options.profilesSampleRate); } +SentrySamplerDecision * +sampleContinuousProfile(SentrySamplingContext *context, SentryOptions *options) +{ + NSNumber *callbackRate = samplerCallbackRate( + options.profilesSampler, context, SENTRY_DEFAULT_PROFILES_SAMPLE_RATE); + if (callbackRate != nil) { + return calcSample(callbackRate); + } + + return calcSampleFromNumericalRate(options.profilesSampleRate); +} + #endif // SENTRY_TARGET_PROFILING_SUPPORTED NS_ASSUME_NONNULL_END diff --git a/Sources/Sentry/SentryTimeToDisplayTracker.m b/Sources/Sentry/SentryTimeToDisplayTracker.m index 3a2c6ac4c6..675eb1eeb8 100644 --- a/Sources/Sentry/SentryTimeToDisplayTracker.m +++ b/Sources/Sentry/SentryTimeToDisplayTracker.m @@ -140,6 +140,9 @@ - (void)framesTrackerHasNewFrame:(NSDate *)newFrameDate if (!_waitForFullDisplay) { [SentryDependencyContainer.sharedInstance.framesTracker removeListener:self]; # if SENTRY_TARGET_PROFILING_SUPPORTED + if (SentrySDK.options.enableContinuousProfiling) { + return; + } sentry_stopAndDiscardLaunchProfileTracer(); # endif // SENTRY_TARGET_PROFILING_SUPPORTED } @@ -150,6 +153,9 @@ - (void)framesTrackerHasNewFrame:(NSDate *)newFrameDate self.fullDisplaySpan.timestamp = newFrameDate; [self.fullDisplaySpan finish]; # if SENTRY_TARGET_PROFILING_SUPPORTED + if (SentrySDK.options.enableContinuousProfiling) { + return; + } sentry_stopAndDiscardLaunchProfileTracer(); # endif // SENTRY_TARGET_PROFILING_SUPPORTED } diff --git a/Sources/Sentry/SentryTracer.m b/Sources/Sentry/SentryTracer.m index 52b79bb04c..02611fc39e 100644 --- a/Sources/Sentry/SentryTracer.m +++ b/Sources/Sentry/SentryTracer.m @@ -109,13 +109,6 @@ @implementation SentryTracer { static NSObject *appStartMeasurementLock; static BOOL appStartMeasurementRead; -#if SENTRY_TARGET_PROFILING_SUPPORTED -+ (void)load -{ - sentry_startLaunchProfile(); -} -#endif // SENTRY_TARGET_PROFILING_SUPPORTED - + (void)initialize { if (self == [SentryTracer class]) { diff --git a/Sources/Sentry/include/HybridPublic/SentryDependencyContainer.h b/Sources/Sentry/include/HybridPublic/SentryDependencyContainer.h index d9552fd218..e3c5a03b59 100644 --- a/Sources/Sentry/include/HybridPublic/SentryDependencyContainer.h +++ b/Sources/Sentry/include/HybridPublic/SentryDependencyContainer.h @@ -19,7 +19,6 @@ @class SentrySystemWrapper; @class SentryThreadWrapper; @class SentryThreadInspector; -@class SentryOptions; @protocol SentryRandom; #if SENTRY_HAS_METRIC_KIT diff --git a/Sources/Sentry/include/SentryLaunchProfiling.h b/Sources/Sentry/include/SentryLaunchProfiling.h index b02e1a7742..c7d5c3d157 100644 --- a/Sources/Sentry/include/SentryLaunchProfiling.h +++ b/Sources/Sentry/include/SentryLaunchProfiling.h @@ -13,6 +13,13 @@ NS_ASSUME_NONNULL_BEGIN +/** + * Whether or not the profiler started with the app launch. With legacy profiling, this means there + * is a tracer managing the profile that will eventually need to be stopped and either discarded (in + * the case of auto performance transactions) or also transmitted. With continuous profiling, this + * indicates whether or not the profiler that's currently running was started from app launch, or + * later with a manual profiler start from the SDK consumer. + */ SENTRY_EXTERN BOOL sentry_isTracingAppLaunch; /** Try to start a profiled trace for this app launch, if the configuration allows. */ diff --git a/Sources/Sentry/include/SentrySampling.h b/Sources/Sentry/include/SentrySampling.h index a1f5f8348e..eec93f53f3 100644 --- a/Sources/Sentry/include/SentrySampling.h +++ b/Sources/Sentry/include/SentrySampling.h @@ -17,10 +17,18 @@ SENTRY_EXTERN SentrySamplerDecision *sentry_sampleTrace( #if SENTRY_TARGET_PROFILING_SUPPORTED /** * Determines whether a profile should be sampled based on the context, options, and - * whether the trace corresponding to the profile was sampled. + * whether the trace corresponding to the profile was sampled, to decide whether to configure the + * next launch to start a legacy profile. */ SENTRY_EXTERN SentrySamplerDecision *sentry_sampleTraceProfile(SentrySamplingContext *context, SentrySamplerDecision *tracesSamplerDecision, SentryOptions *options); + +/** + * Determines whether a continuous profile should be sampled based on the context and options, to + * decide whether to configure the next launch to start a continuous profile. + */ +SentrySamplerDecision *sampleContinuousProfile( + SentrySamplingContext *context, SentryOptions *options); #endif // SENTRY_TARGET_PROFILING_SUPPORTED NS_ASSUME_NONNULL_END From d46cc59be4d7926354f0d7a1d71782c1e523f5f5 Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Tue, 9 Apr 2024 16:34:48 -0500 Subject: [PATCH 02/21] wip: test case description for all option combinations --- .../SentryAppLaunchProfilingTests.m | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.m b/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.m index 1c91feea19..09d7b18531 100644 --- a/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.m +++ b/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.m @@ -9,6 +9,71 @@ #if SENTRY_TARGET_PROFILING_SUPPORTED +// Quick BDD-style tests + +// enableLaunchProfiling(F) +// enableTraces(F) +// enableContinuousProfiling(F) +// tracesSampleRate(0) +// profilesSampleRate(0): no launch profiling +// profilesSampleRate(1): no launch profiling +// tracesSampleRate(1) +// profilesSampleRate(0): no launch profiling +// profilesSampleRate(1): no launch profiling +// enableContinuousProfiling(T) +// tracesSampleRate(0) +// profilesSampleRate(0): no launch profiling +// profilesSampleRate(1): no launch profiling +// tracesSampleRate(1) +// profilesSampleRate(0): no launch profiling +// profilesSampleRate(1): no launch profiling +// enableTraces(T) +// enableContinuousProfiling(F) +// tracesSampleRate(0) +// profilesSampleRate(0): no launch profiling +// profilesSampleRate(1): no launch profiling +// tracesSampleRate(1) +// profilesSampleRate(0): no launch profiling +// profilesSampleRate(1): no launch profiling +// enableContinuousProfiling(T) +// tracesSampleRate(0) +// profilesSampleRate(0): no launch profiling +// profilesSampleRate(1): no launch profiling +// tracesSampleRate(1) +// profilesSampleRate(0): no launch profiling +// profilesSampleRate(1): no launch profiling +// enableLaunchProfiling(T) +// enableTraces(F) +// enableContinuousProfiling(F) +// tracesSampleRate(0) +// profilesSampleRate(0): no launch profiling +// profilesSampleRate(1): no launch profiling +// tracesSampleRate(1) +// profilesSampleRate(0): no launch profiling +// profilesSampleRate(1): no launch profiling +// enableContinuousProfiling(T) +// tracesSampleRate(0) +// profilesSampleRate(0): no launch profiling +// profilesSampleRate(1): continuous launch profile +// tracesSampleRate(1) +// profilesSampleRate(0): no launch profiling +// profilesSampleRate(1): continuous launch profile +// enableTraces(T) +// enableContinuousProfiling(F) +// tracesSampleRate(0) +// profilesSampleRate(0): no launch profiling +// profilesSampleRate(1): no launch profiling +// tracesSampleRate(1) +// profilesSampleRate(0): no launch profiling +// profilesSampleRate(1): legacy launch profile +// enableContinuousProfiling(T) +// tracesSampleRate(0) +// profilesSampleRate(0): no launch profiling +// profilesSampleRate(1): continuous launch profile +// tracesSampleRate(1) +// profilesSampleRate(0): no launch profiling +// profilesSampleRate(1): continuous launch profile + @interface SentryAppLaunchProfilingTests : XCTestCase @end From 3d9a8c6942d4d4c70d93efd8a53e71de4ce596a5 Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Wed, 10 Apr 2024 12:54:02 -0800 Subject: [PATCH 03/21] WIP: bdd test all option combinations --- Sentry.xcodeproj/project.pbxproj | 23 +++++++ .../SentryAppLaunchProfilingTests.m | 65 ----------------- .../SentryAppLaunchProfilingTests.swift | 69 +++++++++++++++++++ 3 files changed, 92 insertions(+), 65 deletions(-) create mode 100644 Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift diff --git a/Sentry.xcodeproj/project.pbxproj b/Sentry.xcodeproj/project.pbxproj index f9b40b3c7f..93332aa8db 100644 --- a/Sentry.xcodeproj/project.pbxproj +++ b/Sentry.xcodeproj/project.pbxproj @@ -683,6 +683,8 @@ 849AC40029E0C1FF00889C16 /* SentryFormatterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849AC3FF29E0C1FF00889C16 /* SentryFormatterTests.swift */; }; 84A305572BC9EF8C00D84283 /* SentryLegacyProfiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 84A305552BC9EF8C00D84283 /* SentryLegacyProfiler.h */; }; 84A305582BC9EF8C00D84283 /* SentryLegacyProfiler.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84A305562BC9EF8C00D84283 /* SentryLegacyProfiler.mm */; }; + 84A305462BC729E100D84283 /* Quick in Frameworks */ = {isa = PBXBuildFile; productRef = 84A305452BC729E100D84283 /* Quick */; }; + 84A305492BC7328400D84283 /* SentryAppLaunchProfilingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84A305472BC72A0A00D84283 /* SentryAppLaunchProfilingTests.swift */; }; 84A5D75B29D5170700388BFA /* TimeInterval+Sentry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84A5D75A29D5170700388BFA /* TimeInterval+Sentry.swift */; }; 84A8891C28DBD28900C51DFD /* SentryDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 84A8891A28DBD28900C51DFD /* SentryDevice.h */; }; 84A8891D28DBD28900C51DFD /* SentryDevice.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84A8891B28DBD28900C51DFD /* SentryDevice.mm */; }; @@ -1722,6 +1724,7 @@ 849472842971C41A002603DE /* SentryNSTimerFactoryTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryNSTimerFactoryTest.swift; sourceTree = ""; }; 849AC3FF29E0C1FF00889C16 /* SentryFormatterTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SentryFormatterTests.swift; sourceTree = ""; }; 84A305552BC9EF8C00D84283 /* SentryLegacyProfiler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryLegacyProfiler.h; path = ../include/SentryLegacyProfiler.h; sourceTree = ""; }; + 84A305472BC72A0A00D84283 /* SentryAppLaunchProfilingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryAppLaunchProfilingTests.swift; sourceTree = ""; }; 84A305562BC9EF8C00D84283 /* SentryLegacyProfiler.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = SentryLegacyProfiler.mm; sourceTree = ""; }; 84A305592BC9FD1600D84283 /* SentryLegacyProfiler+Test.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SentryLegacyProfiler+Test.h"; sourceTree = ""; }; 84A5D75A29D5170700388BFA /* TimeInterval+Sentry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TimeInterval+Sentry.swift"; sourceTree = ""; }; @@ -1989,6 +1992,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 84A305462BC729E100D84283 /* Quick in Frameworks */, 84B7FA3D29B2879C00AD93B1 /* libSentryTestUtils.a in Frameworks */, 8431EFD129B27B1100D8DC56 /* Sentry.framework in Frameworks */, ); @@ -3405,6 +3409,7 @@ 035E73CD27D5790A005EEB11 /* SentryThreadMetadataCacheTests.mm */, 03F9D37B2819A65C00602916 /* SentryProfilerTests.mm */, 840A11092B5F47F700650D02 /* SentryAppLaunchProfilingTests.m */, + 84A305472BC72A0A00D84283 /* SentryAppLaunchProfilingTests.swift */, 8419C0C328C1889D001C8259 /* SentryLegacyProfilerTests.swift */, 8446F5182BE172290040D57E /* SentryContinuousProfilerTests.swift */, 8431D4522BE1741E009EAEC1 /* SentryProfileTestFixture.swift */, @@ -4228,6 +4233,9 @@ 8431EED229B27B1100D8DC56 /* PBXTargetDependency */, ); name = SentryProfilerTests; + packageProductDependencies = ( + 84A305452BC729E100D84283 /* Quick */, + ); productName = "Tests-iOS"; productReference = 8431EFD929B27B1100D8DC56 /* SentryProfilerTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; @@ -4336,6 +4344,7 @@ mainGroup = 6327C5C91EB8A783004E799B; packageReferences = ( 62986F012B03D250008E2D62 /* XCRemoteSwiftPackageReference "Nimble" */, + 84A305442BC729E100D84283 /* XCRemoteSwiftPackageReference "Quick" */, ); productRefGroup = 6327C5D41EB8A783004E799B /* Products */; projectDirPath = ""; @@ -4961,6 +4970,7 @@ 8431EFDF29B27B5300D8DC56 /* SentryThreadHandleTests.mm in Sources */, 840A11132B61FE5800650D02 /* SentryAppLaunchProfilingTests.m in Sources */, 8431EFE829B27BAD00D8DC56 /* SentrySystemWrapperTests.swift in Sources */, + 84A305492BC7328400D84283 /* SentryAppLaunchProfilingTests.swift in Sources */, 8431EFE529B27BAD00D8DC56 /* SentryNSProcessInfoWrapperTests.swift in Sources */, 8431EFDE29B27B5300D8DC56 /* SentryLegacyProfilerTests.swift in Sources */, ); @@ -6938,6 +6948,14 @@ version = 10.0.0; }; }; + 84A305442BC729E100D84283 /* XCRemoteSwiftPackageReference "Quick" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/Quick/Quick"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 7.5.0; + }; + }; /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ @@ -6946,6 +6964,11 @@ package = 62986F012B03D250008E2D62 /* XCRemoteSwiftPackageReference "Nimble" */; productName = Nimble; }; + 84A305452BC729E100D84283 /* Quick */ = { + isa = XCSwiftPackageProductDependency; + package = 84A305442BC729E100D84283 /* XCRemoteSwiftPackageReference "Quick" */; + productName = Quick; + }; /* End XCSwiftPackageProductDependency section */ }; rootObject = 6327C5CA1EB8A783004E799B /* Project object */; diff --git a/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.m b/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.m index 09d7b18531..1c91feea19 100644 --- a/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.m +++ b/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.m @@ -9,71 +9,6 @@ #if SENTRY_TARGET_PROFILING_SUPPORTED -// Quick BDD-style tests - -// enableLaunchProfiling(F) -// enableTraces(F) -// enableContinuousProfiling(F) -// tracesSampleRate(0) -// profilesSampleRate(0): no launch profiling -// profilesSampleRate(1): no launch profiling -// tracesSampleRate(1) -// profilesSampleRate(0): no launch profiling -// profilesSampleRate(1): no launch profiling -// enableContinuousProfiling(T) -// tracesSampleRate(0) -// profilesSampleRate(0): no launch profiling -// profilesSampleRate(1): no launch profiling -// tracesSampleRate(1) -// profilesSampleRate(0): no launch profiling -// profilesSampleRate(1): no launch profiling -// enableTraces(T) -// enableContinuousProfiling(F) -// tracesSampleRate(0) -// profilesSampleRate(0): no launch profiling -// profilesSampleRate(1): no launch profiling -// tracesSampleRate(1) -// profilesSampleRate(0): no launch profiling -// profilesSampleRate(1): no launch profiling -// enableContinuousProfiling(T) -// tracesSampleRate(0) -// profilesSampleRate(0): no launch profiling -// profilesSampleRate(1): no launch profiling -// tracesSampleRate(1) -// profilesSampleRate(0): no launch profiling -// profilesSampleRate(1): no launch profiling -// enableLaunchProfiling(T) -// enableTraces(F) -// enableContinuousProfiling(F) -// tracesSampleRate(0) -// profilesSampleRate(0): no launch profiling -// profilesSampleRate(1): no launch profiling -// tracesSampleRate(1) -// profilesSampleRate(0): no launch profiling -// profilesSampleRate(1): no launch profiling -// enableContinuousProfiling(T) -// tracesSampleRate(0) -// profilesSampleRate(0): no launch profiling -// profilesSampleRate(1): continuous launch profile -// tracesSampleRate(1) -// profilesSampleRate(0): no launch profiling -// profilesSampleRate(1): continuous launch profile -// enableTraces(T) -// enableContinuousProfiling(F) -// tracesSampleRate(0) -// profilesSampleRate(0): no launch profiling -// profilesSampleRate(1): no launch profiling -// tracesSampleRate(1) -// profilesSampleRate(0): no launch profiling -// profilesSampleRate(1): legacy launch profile -// enableContinuousProfiling(T) -// tracesSampleRate(0) -// profilesSampleRate(0): no launch profiling -// profilesSampleRate(1): continuous launch profile -// tracesSampleRate(1) -// profilesSampleRate(0): no launch profiling -// profilesSampleRate(1): continuous launch profile - @interface SentryAppLaunchProfilingTests : XCTestCase @end diff --git a/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift b/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift new file mode 100644 index 0000000000..88c7455f5c --- /dev/null +++ b/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift @@ -0,0 +1,69 @@ +import XCTest +import Quick + +final class SentryAppLaunchProfilingTests: XCTestCase { + func testAppLaunchOptions() { + // enableLaunchProfiling(F) + // enableTraces(F) + // enableContinuousProfiling(F) + // tracesSampleRate(0) + // profilesSampleRate(0): no launch profiling + // profilesSampleRate(1): no launch profiling + // tracesSampleRate(1) + // profilesSampleRate(0): no launch profiling + // profilesSampleRate(1): no launch profiling + // enableContinuousProfiling(T) + // tracesSampleRate(0) + // profilesSampleRate(0): no launch profiling + // profilesSampleRate(1): no launch profiling + // tracesSampleRate(1) + // profilesSampleRate(0): no launch profiling + // profilesSampleRate(1): no launch profiling + // enableTraces(T) + // enableContinuousProfiling(F) + // tracesSampleRate(0) + // profilesSampleRate(0): no launch profiling + // profilesSampleRate(1): no launch profiling + // tracesSampleRate(1) + // profilesSampleRate(0): no launch profiling + // profilesSampleRate(1): no launch profiling + // enableContinuousProfiling(T) + // tracesSampleRate(0) + // profilesSampleRate(0): no launch profiling + // profilesSampleRate(1): no launch profiling + // tracesSampleRate(1) + // profilesSampleRate(0): no launch profiling + // profilesSampleRate(1): no launch profiling + // enableLaunchProfiling(T) + // enableTraces(F) + // enableContinuousProfiling(F) + // tracesSampleRate(0) + // profilesSampleRate(0): no launch profiling + // profilesSampleRate(1): no launch profiling + // tracesSampleRate(1) + // profilesSampleRate(0): no launch profiling + // profilesSampleRate(1): no launch profiling + // enableContinuousProfiling(T) + // tracesSampleRate(0) + // profilesSampleRate(0): no launch profiling + // profilesSampleRate(1): continuous launch profile + // tracesSampleRate(1) + // profilesSampleRate(0): no launch profiling + // profilesSampleRate(1): continuous launch profile + // enableTraces(T) + // enableContinuousProfiling(F) + // tracesSampleRate(0) + // profilesSampleRate(0): no launch profiling + // profilesSampleRate(1): no launch profiling + // tracesSampleRate(1) + // profilesSampleRate(0): no launch profiling + // profilesSampleRate(1): legacy launch profile + // enableContinuousProfiling(T) + // tracesSampleRate(0) + // profilesSampleRate(0): no launch profiling + // profilesSampleRate(1): continuous launch profile + // tracesSampleRate(1) + // profilesSampleRate(0): no launch profiling + // profilesSampleRate(1): continuous launch profile + } +} From b440e9eff98e80097d7892bfe87107c1c8c28e89 Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Sat, 4 May 2024 18:53:27 -0800 Subject: [PATCH 04/21] WIP: writing app launch profiling option tests --- Sentry.xcodeproj/project.pbxproj | 36 +- .../SentryLaunchProfiling+Tests.h | 5 + .../SentryTestUtils-ObjC-BridgingHeader.h | 1 + .../Sentry/Profiling/SentryLaunchProfiling.m | 11 +- .../SentryAppLaunchProfilingTests.swift | 366 ++++++++++++++---- 5 files changed, 340 insertions(+), 79 deletions(-) rename {Tests/SentryTests => SentryTestUtils}/SentryLaunchProfiling+Tests.h (73%) diff --git a/Sentry.xcodeproj/project.pbxproj b/Sentry.xcodeproj/project.pbxproj index 93332aa8db..596f3b35c3 100644 --- a/Sentry.xcodeproj/project.pbxproj +++ b/Sentry.xcodeproj/project.pbxproj @@ -675,16 +675,17 @@ 8459FCBE2BD73E820038E9C9 /* SentryProfilerSerialization.h in Headers */ = {isa = PBXBuildFile; fileRef = 8459FCBD2BD73E810038E9C9 /* SentryProfilerSerialization.h */; }; 8459FCC02BD73EB20038E9C9 /* SentryProfilerSerialization.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8459FCBF2BD73EB20038E9C9 /* SentryProfilerSerialization.mm */; }; 845C16D52A622A5B00EC9519 /* SentryTracer+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 845C16D42A622A5B00EC9519 /* SentryTracer+Private.h */; }; + 847D10BD2BE6F7130048ACD9 /* Nimble in Frameworks */ = {isa = PBXBuildFile; productRef = 847D10BC2BE6F7130048ACD9 /* Nimble */; }; + 847D10C02BE728490048ACD9 /* Quick in Frameworks */ = {isa = PBXBuildFile; productRef = 847D10BF2BE728490048ACD9 /* Quick */; }; 8489B8882A5F7905009A055A /* SentryThreadWrapperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8489B8872A5F7905009A055A /* SentryThreadWrapperTests.swift */; }; 848A45192BBF8D33006AAAEC /* SentryContinuousProfiler.mm in Sources */ = {isa = PBXBuildFile; fileRef = 848A45182BBF8D33006AAAEC /* SentryContinuousProfiler.mm */; }; 848A451A2BBF8D33006AAAEC /* SentryContinuousProfiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 848A45172BBF8D33006AAAEC /* SentryContinuousProfiler.h */; }; 848A451D2BBF9504006AAAEC /* SentryProfilerTestHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = 848A451C2BBF9504006AAAEC /* SentryProfilerTestHelpers.m */; }; 848A451E2BBF9504006AAAEC /* SentryProfilerTestHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 848A451B2BBF9504006AAAEC /* SentryProfilerTestHelpers.h */; }; 849AC40029E0C1FF00889C16 /* SentryFormatterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849AC3FF29E0C1FF00889C16 /* SentryFormatterTests.swift */; }; + 84A305492BC7328400D84283 /* SentryAppLaunchProfilingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84A305472BC72A0A00D84283 /* SentryAppLaunchProfilingTests.swift */; }; 84A305572BC9EF8C00D84283 /* SentryLegacyProfiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 84A305552BC9EF8C00D84283 /* SentryLegacyProfiler.h */; }; 84A305582BC9EF8C00D84283 /* SentryLegacyProfiler.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84A305562BC9EF8C00D84283 /* SentryLegacyProfiler.mm */; }; - 84A305462BC729E100D84283 /* Quick in Frameworks */ = {isa = PBXBuildFile; productRef = 84A305452BC729E100D84283 /* Quick */; }; - 84A305492BC7328400D84283 /* SentryAppLaunchProfilingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84A305472BC72A0A00D84283 /* SentryAppLaunchProfilingTests.swift */; }; 84A5D75B29D5170700388BFA /* TimeInterval+Sentry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84A5D75A29D5170700388BFA /* TimeInterval+Sentry.swift */; }; 84A8891C28DBD28900C51DFD /* SentryDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 84A8891A28DBD28900C51DFD /* SentryDevice.h */; }; 84A8891D28DBD28900C51DFD /* SentryDevice.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84A8891B28DBD28900C51DFD /* SentryDevice.mm */; }; @@ -1723,8 +1724,8 @@ 849472822971C2CD002603DE /* SentryNSProcessInfoWrapperTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryNSProcessInfoWrapperTests.swift; sourceTree = ""; }; 849472842971C41A002603DE /* SentryNSTimerFactoryTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryNSTimerFactoryTest.swift; sourceTree = ""; }; 849AC3FF29E0C1FF00889C16 /* SentryFormatterTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SentryFormatterTests.swift; sourceTree = ""; }; - 84A305552BC9EF8C00D84283 /* SentryLegacyProfiler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryLegacyProfiler.h; path = ../include/SentryLegacyProfiler.h; sourceTree = ""; }; 84A305472BC72A0A00D84283 /* SentryAppLaunchProfilingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryAppLaunchProfilingTests.swift; sourceTree = ""; }; + 84A305552BC9EF8C00D84283 /* SentryLegacyProfiler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryLegacyProfiler.h; path = ../include/SentryLegacyProfiler.h; sourceTree = ""; }; 84A305562BC9EF8C00D84283 /* SentryLegacyProfiler.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = SentryLegacyProfiler.mm; sourceTree = ""; }; 84A305592BC9FD1600D84283 /* SentryLegacyProfiler+Test.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SentryLegacyProfiler+Test.h"; sourceTree = ""; }; 84A5D75A29D5170700388BFA /* TimeInterval+Sentry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TimeInterval+Sentry.swift"; sourceTree = ""; }; @@ -1992,8 +1993,9 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 84A305462BC729E100D84283 /* Quick in Frameworks */, + 847D10BD2BE6F7130048ACD9 /* Nimble in Frameworks */, 84B7FA3D29B2879C00AD93B1 /* libSentryTestUtils.a in Frameworks */, + 847D10C02BE728490048ACD9 /* Quick in Frameworks */, 8431EFD129B27B1100D8DC56 /* Sentry.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -4234,7 +4236,8 @@ ); name = SentryProfilerTests; packageProductDependencies = ( - 84A305452BC729E100D84283 /* Quick */, + 847D10BC2BE6F7130048ACD9 /* Nimble */, + 847D10BF2BE728490048ACD9 /* Quick */, ); productName = "Tests-iOS"; productReference = 8431EFD929B27B1100D8DC56 /* SentryProfilerTests.xctest */; @@ -4344,7 +4347,7 @@ mainGroup = 6327C5C91EB8A783004E799B; packageReferences = ( 62986F012B03D250008E2D62 /* XCRemoteSwiftPackageReference "Nimble" */, - 84A305442BC729E100D84283 /* XCRemoteSwiftPackageReference "Quick" */, + 847D10BE2BE728490048ACD9 /* XCRemoteSwiftPackageReference "Quick" */, ); productRefGroup = 6327C5D41EB8A783004E799B /* Products */; projectDirPath = ""; @@ -5669,6 +5672,7 @@ CODE_SIGN_STYLE = Manual; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = "SentryTests copy-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -5731,6 +5735,7 @@ CODE_SIGN_STYLE = Manual; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = "SentryTests copy-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -5762,6 +5767,7 @@ CODE_SIGN_STYLE = Manual; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = "SentryTests copy-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -5793,6 +5799,7 @@ CODE_SIGN_STYLE = Manual; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = "SentryTests copy-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -5824,6 +5831,7 @@ CODE_SIGN_STYLE = Manual; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = "SentryTests copy-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -6154,6 +6162,7 @@ CODE_SIGN_STYLE = Manual; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = "SentryTests copy-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -6948,12 +6957,12 @@ version = 10.0.0; }; }; - 84A305442BC729E100D84283 /* XCRemoteSwiftPackageReference "Quick" */ = { + 847D10BE2BE728490048ACD9 /* XCRemoteSwiftPackageReference "Quick" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/Quick/Quick"; requirement = { - kind = upToNextMajorVersion; - minimumVersion = 7.5.0; + branch = main; + kind = branch; }; }; /* End XCRemoteSwiftPackageReference section */ @@ -6964,9 +6973,14 @@ package = 62986F012B03D250008E2D62 /* XCRemoteSwiftPackageReference "Nimble" */; productName = Nimble; }; - 84A305452BC729E100D84283 /* Quick */ = { + 847D10BC2BE6F7130048ACD9 /* Nimble */ = { + isa = XCSwiftPackageProductDependency; + package = 62986F012B03D250008E2D62 /* XCRemoteSwiftPackageReference "Nimble" */; + productName = Nimble; + }; + 847D10BF2BE728490048ACD9 /* Quick */ = { isa = XCSwiftPackageProductDependency; - package = 84A305442BC729E100D84283 /* XCRemoteSwiftPackageReference "Quick" */; + package = 847D10BE2BE728490048ACD9 /* XCRemoteSwiftPackageReference "Quick" */; productName = Quick; }; /* End XCSwiftPackageProductDependency section */ diff --git a/Tests/SentryTests/SentryLaunchProfiling+Tests.h b/SentryTestUtils/SentryLaunchProfiling+Tests.h similarity index 73% rename from Tests/SentryTests/SentryLaunchProfiling+Tests.h rename to SentryTestUtils/SentryLaunchProfiling+Tests.h index 3dd4556eb1..54acfd08c5 100644 --- a/Tests/SentryTests/SentryLaunchProfiling+Tests.h +++ b/SentryTestUtils/SentryLaunchProfiling+Tests.h @@ -20,6 +20,11 @@ SENTRY_EXTERN NSString *const kSentryLaunchProfileConfigKeyProfilesSampleRate; SentryLaunchProfileConfig sentry_shouldProfileNextLaunch(SentryOptions *options); +/** + * `sentry_shouldProfileNextLaunch` cannot be exposed to Swift tests because its return type is not expressible in Swift. This wraps it and only returns the `BOOL shouldProfile` value in the struct. + */ +BOOL sentry_willProfileNextLaunch(SentryOptions *options); + SentryTransactionContext *sentry_context(NSNumber *tracesRate); NS_ASSUME_NONNULL_END diff --git a/SentryTestUtils/SentryTestUtils-ObjC-BridgingHeader.h b/SentryTestUtils/SentryTestUtils-ObjC-BridgingHeader.h index 7b017f8a46..1111106950 100644 --- a/SentryTestUtils/SentryTestUtils-ObjC-BridgingHeader.h +++ b/SentryTestUtils/SentryTestUtils-ObjC-BridgingHeader.h @@ -20,6 +20,7 @@ # import "SentryContinuousProfiler.h" # import "SentryLegacyProfiler+Test.h" # import "SentryProfiler+Private.h" +# import "SentryLegacyProfiler+Test.h" #endif // SENTRY_TARGET_PROFILING_SUPPORTED #import "PrivateSentrySDKOnly.h" diff --git a/Sources/Sentry/Profiling/SentryLaunchProfiling.m b/Sources/Sentry/Profiling/SentryLaunchProfiling.m index 285dcabece..7fbcdfc203 100644 --- a/Sources/Sentry/Profiling/SentryLaunchProfiling.m +++ b/Sources/Sentry/Profiling/SentryLaunchProfiling.m @@ -53,9 +53,6 @@ SentrySamplerDecision *_Nullable profilesDecision; } SentryLaunchProfileConfig; -NSString *const kSentryLaunchProfileConfigKeyTracesSampleRate = @"traces"; -NSString *const kSentryLaunchProfileConfigKeyProfilesSampleRate = @"profiles"; - SentryLaunchProfileConfig sentry_shouldProfileNextLaunch(SentryOptions *options) { @@ -117,6 +114,14 @@ return context; } +# pragma mark - Testing only + +#if defined(TEST) || defined(TESTCI) || defined(DEBUG) +BOOL sentry_willProfileNextLaunch(SentryOptions *options) { + return sentry_shouldProfileNextLaunch(options).shouldProfile; +} +#endif // defined(TEST) || defined(TESTCI) || defined(DEBUG) + # pragma mark - Public BOOL sentry_isTracingAppLaunch; diff --git a/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift b/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift index 88c7455f5c..79bb060c39 100644 --- a/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift +++ b/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift @@ -1,69 +1,305 @@ -import XCTest +import Nimble import Quick +import SentryTestUtils -final class SentryAppLaunchProfilingTests: XCTestCase { - func testAppLaunchOptions() { - // enableLaunchProfiling(F) - // enableTraces(F) - // enableContinuousProfiling(F) - // tracesSampleRate(0) - // profilesSampleRate(0): no launch profiling - // profilesSampleRate(1): no launch profiling - // tracesSampleRate(1) - // profilesSampleRate(0): no launch profiling - // profilesSampleRate(1): no launch profiling - // enableContinuousProfiling(T) - // tracesSampleRate(0) - // profilesSampleRate(0): no launch profiling - // profilesSampleRate(1): no launch profiling - // tracesSampleRate(1) - // profilesSampleRate(0): no launch profiling - // profilesSampleRate(1): no launch profiling - // enableTraces(T) - // enableContinuousProfiling(F) - // tracesSampleRate(0) - // profilesSampleRate(0): no launch profiling - // profilesSampleRate(1): no launch profiling - // tracesSampleRate(1) - // profilesSampleRate(0): no launch profiling - // profilesSampleRate(1): no launch profiling - // enableContinuousProfiling(T) - // tracesSampleRate(0) - // profilesSampleRate(0): no launch profiling - // profilesSampleRate(1): no launch profiling - // tracesSampleRate(1) - // profilesSampleRate(0): no launch profiling - // profilesSampleRate(1): no launch profiling - // enableLaunchProfiling(T) - // enableTraces(F) - // enableContinuousProfiling(F) - // tracesSampleRate(0) - // profilesSampleRate(0): no launch profiling - // profilesSampleRate(1): no launch profiling - // tracesSampleRate(1) - // profilesSampleRate(0): no launch profiling - // profilesSampleRate(1): no launch profiling - // enableContinuousProfiling(T) - // tracesSampleRate(0) - // profilesSampleRate(0): no launch profiling - // profilesSampleRate(1): continuous launch profile - // tracesSampleRate(1) - // profilesSampleRate(0): no launch profiling - // profilesSampleRate(1): continuous launch profile - // enableTraces(T) - // enableContinuousProfiling(F) - // tracesSampleRate(0) - // profilesSampleRate(0): no launch profiling - // profilesSampleRate(1): no launch profiling - // tracesSampleRate(1) - // profilesSampleRate(0): no launch profiling - // profilesSampleRate(1): legacy launch profile - // enableContinuousProfiling(T) - // tracesSampleRate(0) - // profilesSampleRate(0): no launch profiling - // profilesSampleRate(1): continuous launch profile - // tracesSampleRate(1) - // profilesSampleRate(0): no launch profiling - // profilesSampleRate(1): continuous launch profile +//swiftlint:disable todo +/** + * Test how combinations of the following options interact to return the correct value for `sentry_shouldProfileNextLaunch` + * - `enableLaunchProfiling` + * - `enableTraces` + * - `enableContinuousProfiling` + * - `tracesSampleRate` + * - `profilesSampleRate` + * + * - TODO: `profilesSampler` + * - TODO: setting `tracesSampleRate` before `enableTraces`? + */ +final class SentryAppLaunchProfilingSwiftTests: QuickSpec { + override class func spec() { + describe("With launch profiling disabled") { + let options = Options() + options.enableAppLaunchProfiling = false + describe("With tracing manually disabled") { + options.enableTracing = false + describe("With continuous profiling disabled") { + options.enableContinuousProfiling = false + describe("With traces sample rate of 0") { + options.tracesSampleRate = 0 + describe("With profiles sample rate of 0") { + options.profilesSampleRate = 0 + it("Should not enable launch profiling") { + expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + } + } + describe("With profiles sample rate of 1") { + options.profilesSampleRate = 1 + it("Should not enable launch profiling") { + expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + } + } + } + describe("With traces sample rate of 1") { + options.tracesSampleRate = 1 + describe("With profiles sample rate of 0") { + options.profilesSampleRate = 0 + it("Should not enable launch profiling") { + expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + } + } + describe("With profiles sample rate of 1") { + options.profilesSampleRate = 1 + it("Should not enable launch profiling") { + expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + } + } + } + } + describe("With continuous profiling enabled") { + options.enableContinuousProfiling = true + describe("With traces sample rate of 0") { + options.tracesSampleRate = 0 + describe("With profiles sample rate of 0") { + options.profilesSampleRate = 0 + it("Should not enable launch profiling") { + expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + } + } + describe("With profiles sample rate of 1") { + options.profilesSampleRate = 1 + it("Should not enable launch profiling") { + expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + } + } + } + describe("With traces sample rate of 1") { + options.tracesSampleRate = 1 + describe("With profiles sample rate of 0") { + options.profilesSampleRate = 0 + it("Should not enable launch profiling") { + expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + } + } + describe("With profiles sample rate of 1") { + options.profilesSampleRate = 1 + it("Should not enable launch profiling") { + expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + } + } + } + } + } + describe("With tracing manually enabled") { + options.enableTracing = true + describe("With continuous profiling disabled") { + options.enableContinuousProfiling = false + describe("With traces sample rate of 0") { + options.tracesSampleRate = 0 + describe("With profiles sample rate of 0") { + options.profilesSampleRate = 0 + it("Should not enable launch profiling") { + expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + } + } + describe("With profiles sample rate of 1") { + options.profilesSampleRate = 1 + it("Should not enable launch profiling") { + expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + } + } + } + describe("With traces sample rate of 1") { + options.tracesSampleRate = 1 + describe("With profiles sample rate of 0") { + options.profilesSampleRate = 0 + it("Should not enable launch profiling") { + expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + } + } + describe("With profiles sample rate of 1") { + options.profilesSampleRate = 1 + it("Should not enable launch profiling") { + expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + } + } + } + } + describe("With continuous profiling enabled") { + options.enableContinuousProfiling = true + describe("With traces sample rate of 0") { + options.tracesSampleRate = 0 + describe("With profiles sample rate of 0") { + options.profilesSampleRate = 0 + it("Should not enable launch profiling") { + expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + } + } + describe("With profiles sample rate of 1") { + options.profilesSampleRate = 1 + it("Should not enable launch profiling") { + expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + } + } + } + describe("With traces sample rate of 1") { + options.tracesSampleRate = 1 + describe("With profiles sample rate of 0") { + options.profilesSampleRate = 0 + it("Should not enable launch profiling") { + expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + } + } + describe("With profiles sample rate of 1") { + options.profilesSampleRate = 1 + it("Should not enable launch profiling") { + expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + } + } + } + } + } + } + describe("With launch profiling enabled") { + let options = Options() + options.enableAppLaunchProfiling = true + describe("With tracing manually disabled") { + options.enableTracing = false + describe("With continuous profiling disabled") { + options.enableContinuousProfiling = false + describe("With traces sample rate of 0") { + options.tracesSampleRate = 0 + describe("With profiles sample rate of 0") { + options.profilesSampleRate = 0 + it("Should not enable launch profiling") { + expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + } + } + describe("With profiles sample rate of 1") { + options.profilesSampleRate = 1 + it("Should not enable launch profiling") { + expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + } + } + } + describe("With traces sample rate of 1") { + options.tracesSampleRate = 1 + describe("With profiles sample rate of 0") { + options.profilesSampleRate = 0 + it("Should not enable launch profiling") { + expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + } + } + describe("With profiles sample rate of 1") { + options.profilesSampleRate = 1 + it("Should not enable launch profiling") { + expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + } + } + } + } + describe("With continuous profiling enabled") { + options.enableContinuousProfiling = true + describe("With traces sample rate of 0") { + options.tracesSampleRate = 0 + describe("With profiles sample rate of 0") { + options.profilesSampleRate = 0 + it("Should not enable launch profiling") { + expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + } + } + describe("With profiles sample rate of 1") { + options.profilesSampleRate = 1 + it("Should not enable launch profiling") { + expect(sentry_willProfileNextLaunch(options)).to(beTrue()) + } + } + } + describe("With traces sample rate of 1") { + options.tracesSampleRate = 1 + describe("With profiles sample rate of 0") { + options.profilesSampleRate = 0 + it("Should not enable launch profiling") { + expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + } + } + describe("With profiles sample rate of 1") { + options.profilesSampleRate = 1 + it("Should not enable launch profiling") { + expect(sentry_willProfileNextLaunch(options)).to(beTrue()) + } + } + } + } + } + describe("With tracing manually enabled") { + options.enableTracing = true + describe("With continuous profiling disabled") { + options.enableContinuousProfiling = false + describe("With traces sample rate of 0") { + options.tracesSampleRate = 0 + describe("With profiles sample rate of 0") { + options.profilesSampleRate = 0 + it("Should not enable launch profiling") { + expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + } + } + describe("With profiles sample rate of 1") { + options.profilesSampleRate = 1 + it("Should not enable launch profiling") { + expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + } + } + } + describe("With traces sample rate of 1") { + options.tracesSampleRate = 1 + describe("With profiles sample rate of 0") { + options.profilesSampleRate = 0 + it("Should not enable launch profiling") { + expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + } + } + describe("With profiles sample rate of 1") { + options.profilesSampleRate = 1 + it("Should not enable launch profiling") { + expect(sentry_willProfileNextLaunch(options)).to(beTrue()) + } + } + } + } + describe("With continuous profiling enabled") { + options.enableContinuousProfiling = true + describe("With traces sample rate of 0") { + options.tracesSampleRate = 0 + describe("With profiles sample rate of 0") { + options.profilesSampleRate = 0 + it("Should not enable launch profiling") { + expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + } + } + describe("With profiles sample rate of 1") { + options.profilesSampleRate = 1 + it("Should not enable launch profiling") { + expect(sentry_willProfileNextLaunch(options)).to(beTrue()) + } + } + } + describe("With traces sample rate of 1") { + options.tracesSampleRate = 1 + describe("With profiles sample rate of 0") { + options.profilesSampleRate = 0 + it("Should not enable launch profiling") { + expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + } + } + describe("With profiles sample rate of 1") { + options.profilesSampleRate = 1 + it("Should not enable launch profiling") { + expect(sentry_willProfileNextLaunch(options)).to(beTrue()) + } + } + } + } + } + } } } +//swiftlint:enable todo From 4ad43d10976498da08410adf1a521a959f1de0a7 Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Sat, 4 May 2024 19:08:09 -0800 Subject: [PATCH 05/21] got tests working --- SentryTestUtils/SentryLaunchProfiling+Tests.h | 4 +- .../SentryTestUtils-ObjC-BridgingHeader.h | 1 - .../Sentry/Profiling/SentryLaunchProfiling.m | 12 +- .../SentryAppLaunchProfilingTests.swift | 192 +++++++++--------- 4 files changed, 106 insertions(+), 103 deletions(-) diff --git a/SentryTestUtils/SentryLaunchProfiling+Tests.h b/SentryTestUtils/SentryLaunchProfiling+Tests.h index 54acfd08c5..f066dda8ac 100644 --- a/SentryTestUtils/SentryLaunchProfiling+Tests.h +++ b/SentryTestUtils/SentryLaunchProfiling+Tests.h @@ -21,7 +21,9 @@ SENTRY_EXTERN NSString *const kSentryLaunchProfileConfigKeyProfilesSampleRate; SentryLaunchProfileConfig sentry_shouldProfileNextLaunch(SentryOptions *options); /** - * `sentry_shouldProfileNextLaunch` cannot be exposed to Swift tests because its return type is not expressible in Swift. This wraps it and only returns the `BOOL shouldProfile` value in the struct. + * `sentry_shouldProfileNextLaunch` cannot be exposed to Swift tests because its return type is not + * expressible in Swift. This wraps it and only returns the `BOOL shouldProfile` value in the + * struct. */ BOOL sentry_willProfileNextLaunch(SentryOptions *options); diff --git a/SentryTestUtils/SentryTestUtils-ObjC-BridgingHeader.h b/SentryTestUtils/SentryTestUtils-ObjC-BridgingHeader.h index 1111106950..7b017f8a46 100644 --- a/SentryTestUtils/SentryTestUtils-ObjC-BridgingHeader.h +++ b/SentryTestUtils/SentryTestUtils-ObjC-BridgingHeader.h @@ -20,7 +20,6 @@ # import "SentryContinuousProfiler.h" # import "SentryLegacyProfiler+Test.h" # import "SentryProfiler+Private.h" -# import "SentryLegacyProfiler+Test.h" #endif // SENTRY_TARGET_PROFILING_SUPPORTED #import "PrivateSentrySDKOnly.h" diff --git a/Sources/Sentry/Profiling/SentryLaunchProfiling.m b/Sources/Sentry/Profiling/SentryLaunchProfiling.m index 7fbcdfc203..32827ac63d 100644 --- a/Sources/Sentry/Profiling/SentryLaunchProfiling.m +++ b/Sources/Sentry/Profiling/SentryLaunchProfiling.m @@ -64,7 +64,7 @@ @"options.enableContinuousProfiling: %d", options.enableAppLaunchProfiling, options.enableTracing, options.enableContinuousProfiling); - return (SentryLaunchProfileConfig) { options.enableAppLaunchProfiling, nil, nil }; + return (SentryLaunchProfileConfig) { NO, nil, nil }; } SentryTransactionContext *transactionContext = @@ -114,13 +114,15 @@ return context; } -# pragma mark - Testing only +# pragma mark - Testing only -#if defined(TEST) || defined(TESTCI) || defined(DEBUG) -BOOL sentry_willProfileNextLaunch(SentryOptions *options) { +# if defined(TEST) || defined(TESTCI) || defined(DEBUG) +BOOL +sentry_willProfileNextLaunch(SentryOptions *options) +{ return sentry_shouldProfileNextLaunch(options).shouldProfile; } -#endif // defined(TEST) || defined(TESTCI) || defined(DEBUG) +# endif // defined(TEST) || defined(TESTCI) || defined(DEBUG) # pragma mark - Public diff --git a/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift b/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift index 79bb060c39..1b41873f42 100644 --- a/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift +++ b/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift @@ -16,142 +16,143 @@ import SentryTestUtils */ final class SentryAppLaunchProfilingSwiftTests: QuickSpec { override class func spec() { + var options: Options! + beforeEach { options = Options() } describe("With launch profiling disabled") { - let options = Options() - options.enableAppLaunchProfiling = false + beforeEach { options.enableAppLaunchProfiling = false } describe("With tracing manually disabled") { - options.enableTracing = false + beforeEach { options.enableTracing = false } describe("With continuous profiling disabled") { - options.enableContinuousProfiling = false + beforeEach { options.enableContinuousProfiling = false } describe("With traces sample rate of 0") { - options.tracesSampleRate = 0 + beforeEach { options.tracesSampleRate = 0 } describe("With profiles sample rate of 0") { - options.profilesSampleRate = 0 + beforeEach { options.profilesSampleRate = 0 } it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + expect(sentry_willProfileNextLaunch(options)) == false } } describe("With profiles sample rate of 1") { - options.profilesSampleRate = 1 + beforeEach { options.profilesSampleRate = 1 } it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + expect(sentry_willProfileNextLaunch(options)) == false } } } describe("With traces sample rate of 1") { - options.tracesSampleRate = 1 + beforeEach { options.tracesSampleRate = 1 } describe("With profiles sample rate of 0") { - options.profilesSampleRate = 0 + beforeEach { options.profilesSampleRate = 0 } it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + expect(sentry_willProfileNextLaunch(options)) == false } } describe("With profiles sample rate of 1") { - options.profilesSampleRate = 1 + beforeEach { options.profilesSampleRate = 1 } it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + expect(sentry_willProfileNextLaunch(options)) == false } } } } describe("With continuous profiling enabled") { - options.enableContinuousProfiling = true + beforeEach { options.enableContinuousProfiling = true } describe("With traces sample rate of 0") { - options.tracesSampleRate = 0 + beforeEach { options.tracesSampleRate = 0 } describe("With profiles sample rate of 0") { - options.profilesSampleRate = 0 + beforeEach { options.profilesSampleRate = 0 } it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + expect(sentry_willProfileNextLaunch(options)) == false } } describe("With profiles sample rate of 1") { - options.profilesSampleRate = 1 + beforeEach { options.profilesSampleRate = 1 } it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + expect(sentry_willProfileNextLaunch(options)) == false } } } describe("With traces sample rate of 1") { - options.tracesSampleRate = 1 + beforeEach { options.tracesSampleRate = 1 } describe("With profiles sample rate of 0") { - options.profilesSampleRate = 0 + beforeEach { options.profilesSampleRate = 0 } it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + expect(sentry_willProfileNextLaunch(options)) == false } } describe("With profiles sample rate of 1") { - options.profilesSampleRate = 1 + beforeEach { options.profilesSampleRate = 1 } it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + expect(sentry_willProfileNextLaunch(options)) == false } } } } } describe("With tracing manually enabled") { - options.enableTracing = true + beforeEach { options.enableTracing = true } describe("With continuous profiling disabled") { - options.enableContinuousProfiling = false + beforeEach { options.enableContinuousProfiling = false } describe("With traces sample rate of 0") { - options.tracesSampleRate = 0 + beforeEach { options.tracesSampleRate = 0 } describe("With profiles sample rate of 0") { - options.profilesSampleRate = 0 + beforeEach { options.profilesSampleRate = 0 } it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + expect(sentry_willProfileNextLaunch(options)) == false } } describe("With profiles sample rate of 1") { - options.profilesSampleRate = 1 + beforeEach { options.profilesSampleRate = 1 } it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + expect(sentry_willProfileNextLaunch(options)) == false } } } describe("With traces sample rate of 1") { - options.tracesSampleRate = 1 + beforeEach { options.tracesSampleRate = 1 } describe("With profiles sample rate of 0") { - options.profilesSampleRate = 0 + beforeEach { options.profilesSampleRate = 0 } it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + expect(sentry_willProfileNextLaunch(options)) == false } } describe("With profiles sample rate of 1") { - options.profilesSampleRate = 1 + beforeEach { options.profilesSampleRate = 1 } it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + expect(sentry_willProfileNextLaunch(options)) == false } } } } describe("With continuous profiling enabled") { - options.enableContinuousProfiling = true + beforeEach { options.enableContinuousProfiling = true } describe("With traces sample rate of 0") { - options.tracesSampleRate = 0 + beforeEach { options.tracesSampleRate = 0 } describe("With profiles sample rate of 0") { - options.profilesSampleRate = 0 + beforeEach { options.profilesSampleRate = 0 } it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + expect(sentry_willProfileNextLaunch(options)) == false } } describe("With profiles sample rate of 1") { - options.profilesSampleRate = 1 + beforeEach { options.profilesSampleRate = 1 } it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + expect(sentry_willProfileNextLaunch(options)) == false } } } describe("With traces sample rate of 1") { - options.tracesSampleRate = 1 + beforeEach { options.tracesSampleRate = 1 } describe("With profiles sample rate of 0") { - options.profilesSampleRate = 0 + beforeEach { options.profilesSampleRate = 0 } it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + expect(sentry_willProfileNextLaunch(options)) == false } } describe("With profiles sample rate of 1") { - options.profilesSampleRate = 1 + beforeEach { options.profilesSampleRate = 1 } it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + expect(sentry_willProfileNextLaunch(options)) == false } } } @@ -159,141 +160,140 @@ final class SentryAppLaunchProfilingSwiftTests: QuickSpec { } } describe("With launch profiling enabled") { - let options = Options() - options.enableAppLaunchProfiling = true + beforeEach { options.enableAppLaunchProfiling = true } describe("With tracing manually disabled") { - options.enableTracing = false + beforeEach { options.enableTracing = false } describe("With continuous profiling disabled") { - options.enableContinuousProfiling = false + beforeEach { options.enableContinuousProfiling = false } describe("With traces sample rate of 0") { - options.tracesSampleRate = 0 + beforeEach { options.tracesSampleRate = 0 } describe("With profiles sample rate of 0") { - options.profilesSampleRate = 0 + beforeEach { options.profilesSampleRate = 0 } it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + expect(sentry_willProfileNextLaunch(options)) == false } } describe("With profiles sample rate of 1") { - options.profilesSampleRate = 1 + beforeEach { options.profilesSampleRate = 1 } it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + expect(sentry_willProfileNextLaunch(options)) == false } } } describe("With traces sample rate of 1") { - options.tracesSampleRate = 1 + beforeEach { options.tracesSampleRate = 1 } describe("With profiles sample rate of 0") { - options.profilesSampleRate = 0 + beforeEach { options.profilesSampleRate = 0 } it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + expect(sentry_willProfileNextLaunch(options)) == false } } describe("With profiles sample rate of 1") { - options.profilesSampleRate = 1 + beforeEach { options.profilesSampleRate = 1 } it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + expect(sentry_willProfileNextLaunch(options)) == false } } } } describe("With continuous profiling enabled") { - options.enableContinuousProfiling = true + beforeEach { options.enableContinuousProfiling = true } describe("With traces sample rate of 0") { - options.tracesSampleRate = 0 + beforeEach { options.tracesSampleRate = 0 } describe("With profiles sample rate of 0") { - options.profilesSampleRate = 0 + beforeEach { options.profilesSampleRate = 0 } it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + expect(sentry_willProfileNextLaunch(options)) == false } } describe("With profiles sample rate of 1") { - options.profilesSampleRate = 1 + beforeEach { options.profilesSampleRate = 1 } it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)).to(beTrue()) + expect(sentry_willProfileNextLaunch(options)) == true } } } describe("With traces sample rate of 1") { - options.tracesSampleRate = 1 + beforeEach { options.tracesSampleRate = 1 } describe("With profiles sample rate of 0") { - options.profilesSampleRate = 0 + beforeEach { options.profilesSampleRate = 0 } it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + expect(sentry_willProfileNextLaunch(options)) == false } } describe("With profiles sample rate of 1") { - options.profilesSampleRate = 1 + beforeEach { options.profilesSampleRate = 1 } it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)).to(beTrue()) + expect(sentry_willProfileNextLaunch(options)) == true } } } } } describe("With tracing manually enabled") { - options.enableTracing = true + beforeEach { options.enableTracing = true } describe("With continuous profiling disabled") { - options.enableContinuousProfiling = false + beforeEach { options.enableContinuousProfiling = false } describe("With traces sample rate of 0") { - options.tracesSampleRate = 0 + beforeEach { options.tracesSampleRate = 0 } describe("With profiles sample rate of 0") { - options.profilesSampleRate = 0 + beforeEach { options.profilesSampleRate = 0 } it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + expect(sentry_willProfileNextLaunch(options)) == false } } describe("With profiles sample rate of 1") { - options.profilesSampleRate = 1 + beforeEach { options.profilesSampleRate = 1 } it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + expect(sentry_willProfileNextLaunch(options)) == false } } } describe("With traces sample rate of 1") { - options.tracesSampleRate = 1 + beforeEach { options.tracesSampleRate = 1 } describe("With profiles sample rate of 0") { - options.profilesSampleRate = 0 + beforeEach { options.profilesSampleRate = 0 } it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + expect(sentry_willProfileNextLaunch(options)) == false } } describe("With profiles sample rate of 1") { - options.profilesSampleRate = 1 + beforeEach { options.profilesSampleRate = 1 } it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)).to(beTrue()) + expect(sentry_willProfileNextLaunch(options)) == true } } } } describe("With continuous profiling enabled") { - options.enableContinuousProfiling = true + beforeEach { options.enableContinuousProfiling = true } describe("With traces sample rate of 0") { - options.tracesSampleRate = 0 + beforeEach { options.tracesSampleRate = 0 } describe("With profiles sample rate of 0") { - options.profilesSampleRate = 0 + beforeEach { options.profilesSampleRate = 0 } it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + expect(sentry_willProfileNextLaunch(options)) == false } } describe("With profiles sample rate of 1") { - options.profilesSampleRate = 1 + beforeEach { options.profilesSampleRate = 1 } it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)).to(beTrue()) + expect(sentry_willProfileNextLaunch(options)) == true } } } describe("With traces sample rate of 1") { - options.tracesSampleRate = 1 + beforeEach { options.tracesSampleRate = 1 } describe("With profiles sample rate of 0") { - options.profilesSampleRate = 0 + beforeEach { options.profilesSampleRate = 0 } it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)).to(beFalse()) + expect(sentry_willProfileNextLaunch(options)) == false } } describe("With profiles sample rate of 1") { - options.profilesSampleRate = 1 + beforeEach { options.profilesSampleRate = 1 } it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)).to(beTrue()) + expect(sentry_willProfileNextLaunch(options)) == true } } } From 4981b60e16b0ff7f4fcba08bd4f80d776d38aa98 Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Sat, 4 May 2024 19:34:04 -0800 Subject: [PATCH 06/21] condense declarations --- .../SentryAppLaunchProfilingTests.swift | 311 ++++-------------- 1 file changed, 58 insertions(+), 253 deletions(-) diff --git a/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift b/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift index 1b41873f42..c288c4e851 100644 --- a/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift +++ b/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift @@ -15,149 +15,13 @@ import SentryTestUtils * - TODO: setting `tracesSampleRate` before `enableTraces`? */ final class SentryAppLaunchProfilingSwiftTests: QuickSpec { + static var options: Options! + override class func spec() { - var options: Options! beforeEach { options = Options() } describe("With launch profiling disabled") { beforeEach { options.enableAppLaunchProfiling = false } - describe("With tracing manually disabled") { - beforeEach { options.enableTracing = false } - describe("With continuous profiling disabled") { - beforeEach { options.enableContinuousProfiling = false } - describe("With traces sample rate of 0") { - beforeEach { options.tracesSampleRate = 0 } - describe("With profiles sample rate of 0") { - beforeEach { options.profilesSampleRate = 0 } - it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)) == false - } - } - describe("With profiles sample rate of 1") { - beforeEach { options.profilesSampleRate = 1 } - it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)) == false - } - } - } - describe("With traces sample rate of 1") { - beforeEach { options.tracesSampleRate = 1 } - describe("With profiles sample rate of 0") { - beforeEach { options.profilesSampleRate = 0 } - it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)) == false - } - } - describe("With profiles sample rate of 1") { - beforeEach { options.profilesSampleRate = 1 } - it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)) == false - } - } - } - } - describe("With continuous profiling enabled") { - beforeEach { options.enableContinuousProfiling = true } - describe("With traces sample rate of 0") { - beforeEach { options.tracesSampleRate = 0 } - describe("With profiles sample rate of 0") { - beforeEach { options.profilesSampleRate = 0 } - it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)) == false - } - } - describe("With profiles sample rate of 1") { - beforeEach { options.profilesSampleRate = 1 } - it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)) == false - } - } - } - describe("With traces sample rate of 1") { - beforeEach { options.tracesSampleRate = 1 } - describe("With profiles sample rate of 0") { - beforeEach { options.profilesSampleRate = 0 } - it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)) == false - } - } - describe("With profiles sample rate of 1") { - beforeEach { options.profilesSampleRate = 1 } - it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)) == false - } - } - } - } - } - describe("With tracing manually enabled") { - beforeEach { options.enableTracing = true } - describe("With continuous profiling disabled") { - beforeEach { options.enableContinuousProfiling = false } - describe("With traces sample rate of 0") { - beforeEach { options.tracesSampleRate = 0 } - describe("With profiles sample rate of 0") { - beforeEach { options.profilesSampleRate = 0 } - it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)) == false - } - } - describe("With profiles sample rate of 1") { - beforeEach { options.profilesSampleRate = 1 } - it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)) == false - } - } - } - describe("With traces sample rate of 1") { - beforeEach { options.tracesSampleRate = 1 } - describe("With profiles sample rate of 0") { - beforeEach { options.profilesSampleRate = 0 } - it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)) == false - } - } - describe("With profiles sample rate of 1") { - beforeEach { options.profilesSampleRate = 1 } - it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)) == false - } - } - } - } - describe("With continuous profiling enabled") { - beforeEach { options.enableContinuousProfiling = true } - describe("With traces sample rate of 0") { - beforeEach { options.tracesSampleRate = 0 } - describe("With profiles sample rate of 0") { - beforeEach { options.profilesSampleRate = 0 } - it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)) == false - } - } - describe("With profiles sample rate of 1") { - beforeEach { options.profilesSampleRate = 1 } - it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)) == false - } - } - } - describe("With traces sample rate of 1") { - beforeEach { options.tracesSampleRate = 1 } - describe("With profiles sample rate of 0") { - beforeEach { options.profilesSampleRate = 0 } - it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)) == false - } - } - describe("With profiles sample rate of 1") { - beforeEach { options.profilesSampleRate = 1 } - it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)) == false - } - } - } - } - } + _varying_enableTracing_neverProfilesLaunch() } describe("With launch profiling enabled") { beforeEach { options.enableAppLaunchProfiling = true } @@ -165,69 +29,11 @@ final class SentryAppLaunchProfilingSwiftTests: QuickSpec { beforeEach { options.enableTracing = false } describe("With continuous profiling disabled") { beforeEach { options.enableContinuousProfiling = false } - describe("With traces sample rate of 0") { - beforeEach { options.tracesSampleRate = 0 } - describe("With profiles sample rate of 0") { - beforeEach { options.profilesSampleRate = 0 } - it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)) == false - } - } - describe("With profiles sample rate of 1") { - beforeEach { options.profilesSampleRate = 1 } - it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)) == false - } - } - } - describe("With traces sample rate of 1") { - beforeEach { options.tracesSampleRate = 1 } - describe("With profiles sample rate of 0") { - beforeEach { options.profilesSampleRate = 0 } - it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)) == false - } - } - describe("With profiles sample rate of 1") { - beforeEach { options.profilesSampleRate = 1 } - it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)) == false - } - } - } + _varying_tracesSampleRate(when0: false, when1: false) } describe("With continuous profiling enabled") { beforeEach { options.enableContinuousProfiling = true } - describe("With traces sample rate of 0") { - beforeEach { options.tracesSampleRate = 0 } - describe("With profiles sample rate of 0") { - beforeEach { options.profilesSampleRate = 0 } - it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)) == false - } - } - describe("With profiles sample rate of 1") { - beforeEach { options.profilesSampleRate = 1 } - it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)) == true - } - } - } - describe("With traces sample rate of 1") { - beforeEach { options.tracesSampleRate = 1 } - describe("With profiles sample rate of 0") { - beforeEach { options.profilesSampleRate = 0 } - it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)) == false - } - } - describe("With profiles sample rate of 1") { - beforeEach { options.profilesSampleRate = 1 } - it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)) == true - } - } - } + _varying_tracesSampleRate(when0: false, when1: true) } } describe("With tracing manually enabled") { @@ -236,70 +42,69 @@ final class SentryAppLaunchProfilingSwiftTests: QuickSpec { beforeEach { options.enableContinuousProfiling = false } describe("With traces sample rate of 0") { beforeEach { options.tracesSampleRate = 0 } - describe("With profiles sample rate of 0") { - beforeEach { options.profilesSampleRate = 0 } - it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)) == false - } - } - describe("With profiles sample rate of 1") { - beforeEach { options.profilesSampleRate = 1 } - it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)) == false - } - } + _varying_profilesSampleRate(when0: false, when1: false) } describe("With traces sample rate of 1") { beforeEach { options.tracesSampleRate = 1 } - describe("With profiles sample rate of 0") { - beforeEach { options.profilesSampleRate = 0 } - it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)) == false - } - } - describe("With profiles sample rate of 1") { - beforeEach { options.profilesSampleRate = 1 } - it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)) == true - } - } + _varying_profilesSampleRate(when0: false, when1: true) } } describe("With continuous profiling enabled") { beforeEach { options.enableContinuousProfiling = true } - describe("With traces sample rate of 0") { - beforeEach { options.tracesSampleRate = 0 } - describe("With profiles sample rate of 0") { - beforeEach { options.profilesSampleRate = 0 } - it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)) == false - } - } - describe("With profiles sample rate of 1") { - beforeEach { options.profilesSampleRate = 1 } - it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)) == true - } - } - } - describe("With traces sample rate of 1") { - beforeEach { options.tracesSampleRate = 1 } - describe("With profiles sample rate of 0") { - beforeEach { options.profilesSampleRate = 0 } - it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)) == false - } - } - describe("With profiles sample rate of 1") { - beforeEach { options.profilesSampleRate = 1 } - it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)) == true - } - } - } + _varying_tracesSampleRate(when0: false, when1: true) } } } } } + +private extension SentryAppLaunchProfilingSwiftTests { + class func _varying_enableTracing_neverProfilesLaunch() { + describe("With tracing manually disabled") { + beforeEach { options.enableTracing = false } + _varying_enableContinuousProfiling_neverProfilesLaunch() + } + describe("With tracing manually enabled") { + beforeEach { options.enableTracing = true } + _varying_enableContinuousProfiling_neverProfilesLaunch() + } + } + + class func _varying_profilesSampleRate(when0: Bool, when1: Bool) { + describe("With profiles sample rate of 0") { + beforeEach { options.profilesSampleRate = 0 } + it("Should not enable launch profiling") { + expect(sentry_willProfileNextLaunch(options)) == when0 + } + } + describe("With profiles sample rate of 1") { + beforeEach { options.profilesSampleRate = 1 } + it("Should not enable launch profiling") { + expect(sentry_willProfileNextLaunch(options)) == when1 + } + } + } + + class func _varying_tracesSampleRate(when0: Bool, when1: Bool) { + describe("With traces sample rate of 0") { + beforeEach { options.tracesSampleRate = 0 } + _varying_profilesSampleRate(when0: when0, when1: when1) + } + describe("With traces sample rate of 1") { + beforeEach { options.tracesSampleRate = 1 } + _varying_profilesSampleRate(when0: when0, when1: when1) + } + } + + class func _varying_enableContinuousProfiling_neverProfilesLaunch() { + describe("With continuous profiling disabled") { + beforeEach { options.enableContinuousProfiling = false } + _varying_tracesSampleRate(when0: false, when1: false) + } + describe("With continuous profiling enabled") { + beforeEach { options.enableContinuousProfiling = true } + _varying_tracesSampleRate(when0: false, when1: false) + } + } +} //swiftlint:enable todo From f893978487fa5e929ffed7e2f20e8d6c3e8c32e8 Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Sat, 4 May 2024 19:52:42 -0800 Subject: [PATCH 07/21] express the same app launch options combo test in another way --- .../SentryAppLaunchProfilingTests.swift | 63 ++++++++++++++++++- 1 file changed, 61 insertions(+), 2 deletions(-) diff --git a/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift b/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift index c288c4e851..78c282e6ce 100644 --- a/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift +++ b/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift @@ -1,18 +1,77 @@ import Nimble import Quick import SentryTestUtils +import XCTest + +final class SentryAppLaunchProfilingSwiftTestsNormal: XCTestCase { + func testShouldProfileLaunchBasedOnOptionsCombinations() { + for testCase: (enableAppLaunchProfiling: Bool, enableTracing: Bool, enableContinuousProfiling: Bool, tracesSampleRate: Int, profilesSampleRate: Int, shouldProfileLaunch: Bool) in [ + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 1, shouldProfileLaunch: false), + + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 1, shouldProfileLaunch: false), + + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 1, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 1, shouldProfileLaunch: false), + + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 1, shouldProfileLaunch: false), + + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 1, shouldProfileLaunch: false), + + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 1, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 1, shouldProfileLaunch: false), + + (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 1, shouldProfileLaunch: false), + + (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 1, shouldProfileLaunch: false), + + (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 1, shouldProfileLaunch: true), + (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 1, shouldProfileLaunch: true), + + (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 1, shouldProfileLaunch: false), + + (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 1, shouldProfileLaunch: true), + + (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 1, shouldProfileLaunch: true), + (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 1, shouldProfileLaunch: true) + ] { + let options = Options() + options.enableAppLaunchProfiling = testCase.enableAppLaunchProfiling + options.enableTracing = testCase.enableTracing + options.enableContinuousProfiling = testCase.enableContinuousProfiling + options.tracesSampleRate = NSNumber(value: testCase.tracesSampleRate) + options.profilesSampleRate = NSNumber(value: testCase.profilesSampleRate) + XCTAssertEqual(sentry_willProfileNextLaunch(options), testCase.shouldProfileLaunch, "Expected \(testCase.shouldProfileLaunch ? "" : "not ")to enable app launch profiling with options: { enableAppLaunchProfiling: \(testCase.enableAppLaunchProfiling); enableTracing: \(testCase.enableTracing); enableContinuousProfiling: \(testCase.enableContinuousProfiling); tracesSampleRate: \(testCase.tracesSampleRate); profilesSampleRate: \(testCase.profilesSampleRate) }") + } + } +} //swiftlint:disable todo /** * Test how combinations of the following options interact to return the correct value for `sentry_shouldProfileNextLaunch` * - `enableLaunchProfiling` - * - `enableTraces` + * - `enableTracing` * - `enableContinuousProfiling` * - `tracesSampleRate` * - `profilesSampleRate` * * - TODO: `profilesSampler` - * - TODO: setting `tracesSampleRate` before `enableTraces`? + * - TODO: setting `tracesSampleRate` before `enableTracing`? */ final class SentryAppLaunchProfilingSwiftTests: QuickSpec { static var options: Options! From a7088fab4c934824c92a9a1aedf76633d8a81163 Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Sat, 4 May 2024 20:10:45 -0800 Subject: [PATCH 08/21] add combinations with profilesSampler --- .../SentryAppLaunchProfilingTests.swift | 123 +++++++++++------- 1 file changed, 76 insertions(+), 47 deletions(-) diff --git a/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift b/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift index 78c282e6ce..9e17eedc36 100644 --- a/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift +++ b/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift @@ -5,50 +5,79 @@ import XCTest final class SentryAppLaunchProfilingSwiftTestsNormal: XCTestCase { func testShouldProfileLaunchBasedOnOptionsCombinations() { - for testCase: (enableAppLaunchProfiling: Bool, enableTracing: Bool, enableContinuousProfiling: Bool, tracesSampleRate: Int, profilesSampleRate: Int, shouldProfileLaunch: Bool) in [ - (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 0, shouldProfileLaunch: false), - (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 1, shouldProfileLaunch: false), + for testCase: (enableAppLaunchProfiling: Bool, enableTracing: Bool, enableContinuousProfiling: Bool, tracesSampleRate: Int, profilesSampleRate: Int, profilesSamplerReturnValue: Int, shouldProfileLaunch: Bool) in [ + // everything false/0 + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + // change profilesSampleRate to 1 + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + // change tracesSampleRate to 1 + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + // change enableContinuousProfiling to true + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + // change enableTracing to true + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + // change enableAppLaunchProfiling to true + (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + // change profilesSamplerReturnValue to 1 + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), + (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), + (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), + (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), + (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), + (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: true), + (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: true), + (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: true), + (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: true), + (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), + (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), + (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: true), + (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: true), + (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: true), + (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: true), + (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: true), + (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: true) - (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 0, shouldProfileLaunch: false), - (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 1, shouldProfileLaunch: false), - - (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 0, shouldProfileLaunch: false), - (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 1, shouldProfileLaunch: false), - (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 0, shouldProfileLaunch: false), - (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 1, shouldProfileLaunch: false), - - (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 0, shouldProfileLaunch: false), - (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 1, shouldProfileLaunch: false), - - (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 0, shouldProfileLaunch: false), - (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 1, shouldProfileLaunch: false), - - (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 0, shouldProfileLaunch: false), - (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 1, shouldProfileLaunch: false), - (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 0, shouldProfileLaunch: false), - (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 1, shouldProfileLaunch: false), - - (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 0, shouldProfileLaunch: false), - (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 1, shouldProfileLaunch: false), - - (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 0, shouldProfileLaunch: false), - (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 1, shouldProfileLaunch: false), - - (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 0, shouldProfileLaunch: false), - (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 1, shouldProfileLaunch: true), - (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 0, shouldProfileLaunch: false), - (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 1, shouldProfileLaunch: true), - - (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 0, shouldProfileLaunch: false), - (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 1, shouldProfileLaunch: false), - - (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 0, shouldProfileLaunch: false), - (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 1, shouldProfileLaunch: true), - - (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 0, shouldProfileLaunch: false), - (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 1, shouldProfileLaunch: true), - (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 0, shouldProfileLaunch: false), - (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 1, shouldProfileLaunch: true) ] { let options = Options() options.enableAppLaunchProfiling = testCase.enableAppLaunchProfiling @@ -56,7 +85,10 @@ final class SentryAppLaunchProfilingSwiftTestsNormal: XCTestCase { options.enableContinuousProfiling = testCase.enableContinuousProfiling options.tracesSampleRate = NSNumber(value: testCase.tracesSampleRate) options.profilesSampleRate = NSNumber(value: testCase.profilesSampleRate) - XCTAssertEqual(sentry_willProfileNextLaunch(options), testCase.shouldProfileLaunch, "Expected \(testCase.shouldProfileLaunch ? "" : "not ")to enable app launch profiling with options: { enableAppLaunchProfiling: \(testCase.enableAppLaunchProfiling); enableTracing: \(testCase.enableTracing); enableContinuousProfiling: \(testCase.enableContinuousProfiling); tracesSampleRate: \(testCase.tracesSampleRate); profilesSampleRate: \(testCase.profilesSampleRate) }") + options.profilesSampler = { _ in + NSNumber(value: testCase.profilesSamplerReturnValue) + } + XCTAssertEqual(sentry_willProfileNextLaunch(options), testCase.shouldProfileLaunch, "Expected \(testCase.shouldProfileLaunch ? "" : "not ")to enable app launch profiling with options: { enableAppLaunchProfiling: \(testCase.enableAppLaunchProfiling), enableTracing: \(testCase.enableTracing), enableContinuousProfiling: \(testCase.enableContinuousProfiling), tracesSampleRate: \(testCase.tracesSampleRate), profilesSampleRate: \(testCase.profilesSampleRate), profilesSamplerReturnValue: \(testCase.profilesSamplerReturnValue) }") } } } @@ -69,9 +101,6 @@ final class SentryAppLaunchProfilingSwiftTestsNormal: XCTestCase { * - `enableContinuousProfiling` * - `tracesSampleRate` * - `profilesSampleRate` - * - * - TODO: `profilesSampler` - * - TODO: setting `tracesSampleRate` before `enableTracing`? */ final class SentryAppLaunchProfilingSwiftTests: QuickSpec { static var options: Options! From fec8ee78bfe846c1d0223e28999b16494bdbdfec Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Sat, 4 May 2024 20:12:44 -0800 Subject: [PATCH 09/21] clean up --- Sentry.xcodeproj/project.pbxproj | 23 ---- .../SentryAppLaunchProfilingTests.swift | 115 ++---------------- 2 files changed, 9 insertions(+), 129 deletions(-) diff --git a/Sentry.xcodeproj/project.pbxproj b/Sentry.xcodeproj/project.pbxproj index 596f3b35c3..dff551ee57 100644 --- a/Sentry.xcodeproj/project.pbxproj +++ b/Sentry.xcodeproj/project.pbxproj @@ -676,7 +676,6 @@ 8459FCC02BD73EB20038E9C9 /* SentryProfilerSerialization.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8459FCBF2BD73EB20038E9C9 /* SentryProfilerSerialization.mm */; }; 845C16D52A622A5B00EC9519 /* SentryTracer+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 845C16D42A622A5B00EC9519 /* SentryTracer+Private.h */; }; 847D10BD2BE6F7130048ACD9 /* Nimble in Frameworks */ = {isa = PBXBuildFile; productRef = 847D10BC2BE6F7130048ACD9 /* Nimble */; }; - 847D10C02BE728490048ACD9 /* Quick in Frameworks */ = {isa = PBXBuildFile; productRef = 847D10BF2BE728490048ACD9 /* Quick */; }; 8489B8882A5F7905009A055A /* SentryThreadWrapperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8489B8872A5F7905009A055A /* SentryThreadWrapperTests.swift */; }; 848A45192BBF8D33006AAAEC /* SentryContinuousProfiler.mm in Sources */ = {isa = PBXBuildFile; fileRef = 848A45182BBF8D33006AAAEC /* SentryContinuousProfiler.mm */; }; 848A451A2BBF8D33006AAAEC /* SentryContinuousProfiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 848A45172BBF8D33006AAAEC /* SentryContinuousProfiler.h */; }; @@ -1995,7 +1994,6 @@ files = ( 847D10BD2BE6F7130048ACD9 /* Nimble in Frameworks */, 84B7FA3D29B2879C00AD93B1 /* libSentryTestUtils.a in Frameworks */, - 847D10C02BE728490048ACD9 /* Quick in Frameworks */, 8431EFD129B27B1100D8DC56 /* Sentry.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -4237,7 +4235,6 @@ name = SentryProfilerTests; packageProductDependencies = ( 847D10BC2BE6F7130048ACD9 /* Nimble */, - 847D10BF2BE728490048ACD9 /* Quick */, ); productName = "Tests-iOS"; productReference = 8431EFD929B27B1100D8DC56 /* SentryProfilerTests.xctest */; @@ -4347,7 +4344,6 @@ mainGroup = 6327C5C91EB8A783004E799B; packageReferences = ( 62986F012B03D250008E2D62 /* XCRemoteSwiftPackageReference "Nimble" */, - 847D10BE2BE728490048ACD9 /* XCRemoteSwiftPackageReference "Quick" */, ); productRefGroup = 6327C5D41EB8A783004E799B /* Products */; projectDirPath = ""; @@ -5672,7 +5668,6 @@ CODE_SIGN_STYLE = Manual; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = "SentryTests copy-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -5735,7 +5730,6 @@ CODE_SIGN_STYLE = Manual; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = "SentryTests copy-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -5767,7 +5761,6 @@ CODE_SIGN_STYLE = Manual; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = "SentryTests copy-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -5799,7 +5792,6 @@ CODE_SIGN_STYLE = Manual; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = "SentryTests copy-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -5831,7 +5823,6 @@ CODE_SIGN_STYLE = Manual; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = "SentryTests copy-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -6162,7 +6153,6 @@ CODE_SIGN_STYLE = Manual; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = "SentryTests copy-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -6957,14 +6947,6 @@ version = 10.0.0; }; }; - 847D10BE2BE728490048ACD9 /* XCRemoteSwiftPackageReference "Quick" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/Quick/Quick"; - requirement = { - branch = main; - kind = branch; - }; - }; /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ @@ -6978,11 +6960,6 @@ package = 62986F012B03D250008E2D62 /* XCRemoteSwiftPackageReference "Nimble" */; productName = Nimble; }; - 847D10BF2BE728490048ACD9 /* Quick */ = { - isa = XCSwiftPackageProductDependency; - package = 847D10BE2BE728490048ACD9 /* XCRemoteSwiftPackageReference "Quick" */; - productName = Quick; - }; /* End XCSwiftPackageProductDependency section */ }; rootObject = 6327C5CA1EB8A783004E799B /* Project object */; diff --git a/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift b/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift index 9e17eedc36..ef997365ef 100644 --- a/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift +++ b/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift @@ -1,8 +1,15 @@ -import Nimble -import Quick import SentryTestUtils import XCTest +/** + * Test how combinations of the following options interact to ultimately decide whether or not to start the profiler on the next app launch.. + * - `enableLaunchProfiling` + * - `enableTracing` + * - `enableContinuousProfiling` + * - `tracesSampleRate` + * - `profilesSampleRate` + * - `profilesSampler` + */ final class SentryAppLaunchProfilingSwiftTestsNormal: XCTestCase { func testShouldProfileLaunchBasedOnOptionsCombinations() { for testCase: (enableAppLaunchProfiling: Bool, enableTracing: Bool, enableContinuousProfiling: Bool, tracesSampleRate: Int, profilesSampleRate: Int, profilesSamplerReturnValue: Int, shouldProfileLaunch: Bool) in [ @@ -92,107 +99,3 @@ final class SentryAppLaunchProfilingSwiftTestsNormal: XCTestCase { } } } - -//swiftlint:disable todo -/** - * Test how combinations of the following options interact to return the correct value for `sentry_shouldProfileNextLaunch` - * - `enableLaunchProfiling` - * - `enableTracing` - * - `enableContinuousProfiling` - * - `tracesSampleRate` - * - `profilesSampleRate` - */ -final class SentryAppLaunchProfilingSwiftTests: QuickSpec { - static var options: Options! - - override class func spec() { - beforeEach { options = Options() } - describe("With launch profiling disabled") { - beforeEach { options.enableAppLaunchProfiling = false } - _varying_enableTracing_neverProfilesLaunch() - } - describe("With launch profiling enabled") { - beforeEach { options.enableAppLaunchProfiling = true } - describe("With tracing manually disabled") { - beforeEach { options.enableTracing = false } - describe("With continuous profiling disabled") { - beforeEach { options.enableContinuousProfiling = false } - _varying_tracesSampleRate(when0: false, when1: false) - } - describe("With continuous profiling enabled") { - beforeEach { options.enableContinuousProfiling = true } - _varying_tracesSampleRate(when0: false, when1: true) - } - } - describe("With tracing manually enabled") { - beforeEach { options.enableTracing = true } - describe("With continuous profiling disabled") { - beforeEach { options.enableContinuousProfiling = false } - describe("With traces sample rate of 0") { - beforeEach { options.tracesSampleRate = 0 } - _varying_profilesSampleRate(when0: false, when1: false) - } - describe("With traces sample rate of 1") { - beforeEach { options.tracesSampleRate = 1 } - _varying_profilesSampleRate(when0: false, when1: true) - } - } - describe("With continuous profiling enabled") { - beforeEach { options.enableContinuousProfiling = true } - _varying_tracesSampleRate(when0: false, when1: true) - } - } - } - } -} - -private extension SentryAppLaunchProfilingSwiftTests { - class func _varying_enableTracing_neverProfilesLaunch() { - describe("With tracing manually disabled") { - beforeEach { options.enableTracing = false } - _varying_enableContinuousProfiling_neverProfilesLaunch() - } - describe("With tracing manually enabled") { - beforeEach { options.enableTracing = true } - _varying_enableContinuousProfiling_neverProfilesLaunch() - } - } - - class func _varying_profilesSampleRate(when0: Bool, when1: Bool) { - describe("With profiles sample rate of 0") { - beforeEach { options.profilesSampleRate = 0 } - it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)) == when0 - } - } - describe("With profiles sample rate of 1") { - beforeEach { options.profilesSampleRate = 1 } - it("Should not enable launch profiling") { - expect(sentry_willProfileNextLaunch(options)) == when1 - } - } - } - - class func _varying_tracesSampleRate(when0: Bool, when1: Bool) { - describe("With traces sample rate of 0") { - beforeEach { options.tracesSampleRate = 0 } - _varying_profilesSampleRate(when0: when0, when1: when1) - } - describe("With traces sample rate of 1") { - beforeEach { options.tracesSampleRate = 1 } - _varying_profilesSampleRate(when0: when0, when1: when1) - } - } - - class func _varying_enableContinuousProfiling_neverProfilesLaunch() { - describe("With continuous profiling disabled") { - beforeEach { options.enableContinuousProfiling = false } - _varying_tracesSampleRate(when0: false, when1: false) - } - describe("With continuous profiling enabled") { - beforeEach { options.enableContinuousProfiling = true } - _varying_tracesSampleRate(when0: false, when1: false) - } - } -} -//swiftlint:enable todo From a33651cc3a87b5e75f472190dde7bacdab94db26 Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Sat, 4 May 2024 20:28:28 -0800 Subject: [PATCH 10/21] rewrite last old app launch objc test in the new swift class --- Sentry.xcodeproj/project.pbxproj | 4 - .../SentryAppLaunchProfilingTests.m | 152 ------------------ .../SentryAppLaunchProfilingTests.swift | 25 +-- .../SentryTests/SentryTests-Bridging-Header.h | 1 + 4 files changed, 17 insertions(+), 165 deletions(-) delete mode 100644 Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.m diff --git a/Sentry.xcodeproj/project.pbxproj b/Sentry.xcodeproj/project.pbxproj index dff551ee57..5d93626ce3 100644 --- a/Sentry.xcodeproj/project.pbxproj +++ b/Sentry.xcodeproj/project.pbxproj @@ -630,7 +630,6 @@ 7DC8310A2398283C0043DD9A /* SentryCrashIntegration.h in Headers */ = {isa = PBXBuildFile; fileRef = 7DC831082398283C0043DD9A /* SentryCrashIntegration.h */; }; 7DC8310C2398283C0043DD9A /* SentryCrashIntegration.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DC831092398283C0043DD9A /* SentryCrashIntegration.m */; }; 840A11122B61E27500650D02 /* SentrySamplerDecision.m in Sources */ = {isa = PBXBuildFile; fileRef = 840A11102B61E27500650D02 /* SentrySamplerDecision.m */; }; - 840A11132B61FE5800650D02 /* SentryAppLaunchProfilingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 840A11092B5F47F700650D02 /* SentryAppLaunchProfilingTests.m */; }; 841325BC2BF4184B0029228F /* TestHub.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B944FAD2469B43700A10721 /* TestHub.swift */; }; 84281C432A578E5600EE88F2 /* SentryProfilerState.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84281C422A578E5600EE88F2 /* SentryProfilerState.mm */; }; 84281C462A57905700EE88F2 /* SentrySample.h in Headers */ = {isa = PBXBuildFile; fileRef = 84281C442A57905700EE88F2 /* SentrySample.h */; }; @@ -1646,7 +1645,6 @@ 7DC27EC423997EB7006998B5 /* SentryAutoBreadcrumbTrackingIntegration.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryAutoBreadcrumbTrackingIntegration.m; sourceTree = ""; }; 7DC831082398283C0043DD9A /* SentryCrashIntegration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryCrashIntegration.h; path = include/SentryCrashIntegration.h; sourceTree = ""; }; 7DC831092398283C0043DD9A /* SentryCrashIntegration.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryCrashIntegration.m; sourceTree = ""; }; - 840A11092B5F47F700650D02 /* SentryAppLaunchProfilingTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryAppLaunchProfilingTests.m; sourceTree = ""; }; 840A11102B61E27500650D02 /* SentrySamplerDecision.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentrySamplerDecision.m; sourceTree = ""; }; 840A11142B62041600650D02 /* SentryLaunchProfiling+Tests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "SentryLaunchProfiling+Tests.h"; path = "../Tests/SentryTests/SentryLaunchProfiling+Tests.h"; sourceTree = ""; }; 840B7EEA2BBF2ABA008B8120 /* .slather.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = .slather.yml; sourceTree = ""; }; @@ -3408,7 +3406,6 @@ 035E73CB27D575B3005EEB11 /* SentrySamplingProfilerTests.mm */, 035E73CD27D5790A005EEB11 /* SentryThreadMetadataCacheTests.mm */, 03F9D37B2819A65C00602916 /* SentryProfilerTests.mm */, - 840A11092B5F47F700650D02 /* SentryAppLaunchProfilingTests.m */, 84A305472BC72A0A00D84283 /* SentryAppLaunchProfilingTests.swift */, 8419C0C328C1889D001C8259 /* SentryLegacyProfilerTests.swift */, 8446F5182BE172290040D57E /* SentryContinuousProfilerTests.swift */, @@ -4967,7 +4964,6 @@ 8431EFE129B27B5300D8DC56 /* SentryThreadMetadataCacheTests.mm in Sources */, 8431EFE029B27B5300D8DC56 /* SentryBacktraceTests.mm in Sources */, 8431EFDF29B27B5300D8DC56 /* SentryThreadHandleTests.mm in Sources */, - 840A11132B61FE5800650D02 /* SentryAppLaunchProfilingTests.m in Sources */, 8431EFE829B27BAD00D8DC56 /* SentrySystemWrapperTests.swift in Sources */, 84A305492BC7328400D84283 /* SentryAppLaunchProfilingTests.swift in Sources */, 8431EFE529B27BAD00D8DC56 /* SentryNSProcessInfoWrapperTests.swift in Sources */, diff --git a/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.m b/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.m deleted file mode 100644 index 1c91feea19..0000000000 --- a/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.m +++ /dev/null @@ -1,152 +0,0 @@ -#import "SentryLaunchProfiling+Tests.h" -#import "SentryOptions+HybridSDKs.h" -#import "SentryOptions+Private.h" -#import "SentryProfilingConditionals.h" -#import "SentrySDK+Tests.h" -#import "SentryTraceOrigins.h" -#import "SentryTransactionContext.h" -#import - -#if SENTRY_TARGET_PROFILING_SUPPORTED - -@interface SentryAppLaunchProfilingTests : XCTestCase -@end - -@implementation SentryAppLaunchProfilingTests - -- (void)testLaunchProfileTransactionContext -{ - SentryTransactionContext *actualContext = sentry_context(@1); - XCTAssertEqual(actualContext.nameSource, kSentryTransactionNameSourceCustom); - XCTAssert([actualContext.origin isEqualToString:SentryTraceOriginAutoAppStartProfile]); - XCTAssert(actualContext.sampled); -} - -# define SENTRY_OPTION(name, value) \ - NSStringFromSelector(@selector(name)) \ - : value - -- (void)testDefaultOptionsDoNotEnableLaunchProfiling -{ - XCTAssertFalse( - sentry_shouldProfileNextLaunch([self defaultOptionsWithOverrides:nil]).shouldProfile, - @"Default options should not enable launch profiling"); -} - -- (void)testAppLaunchProfilingNotSufficientToEnableLaunchProfiling -{ - XCTAssertFalse( - sentry_shouldProfileNextLaunch( - [self defaultOptionsWithOverrides:@{ SENTRY_OPTION(enableAppLaunchProfiling, @YES) }]) - .shouldProfile, - @"Default options with only launch profiling option set is not sufficient to enable launch " - @"profiling"); -} - -- (void)testAppLaunchProfilingAndTracingOptionsNotSufficientToEnableAppLaunchProfiling -{ - XCTAssertFalse( - sentry_shouldProfileNextLaunch( - [self defaultOptionsWithOverrides:@{ SENTRY_OPTION(enableAppLaunchProfiling, @YES), - SENTRY_OPTION(enableTracing, @YES) }]) - .shouldProfile, - @"Default options with app launch profiling and tracing enabled are not sufficient to " - @"enable launch profiling"); -} - -- (void) - testAppLaunchProfilingAndTracingAndTracesSampleRateOptionsNotSufficientToEnableAppLaunchProfiling -{ - XCTAssertFalse( - sentry_shouldProfileNextLaunch( - [self defaultOptionsWithOverrides:@{ SENTRY_OPTION(enableAppLaunchProfiling, @YES), - SENTRY_OPTION(enableTracing, @YES), - SENTRY_OPTION(tracesSampleRate, @1) }]) - .shouldProfile, - @"Default options with app launch profiling and tracing enabled with traces sample rate of " - @"1 are not sufficient to enable launch profiling"); -} - -- (void)testMinimumOptionsRequiredToEnableAppLaunchProfiling -{ - XCTAssert(sentry_shouldProfileNextLaunch([self defaultLaunchProfilingOptionsWithOverrides:nil]) - .shouldProfile, - @"Default options with app launch profiling and tracing enabled and traces and profiles " - @"sample rates of 1 should enable launch profiling"); -} - -- (void)testDisablingLaunchProfilingOptionDisablesAppLaunchProfiling -{ - XCTAssertFalse( - sentry_shouldProfileNextLaunch( - [self defaultLaunchProfilingOptionsWithOverrides:@{ SENTRY_OPTION( - enableAppLaunchProfiling, @NO) }]) - .shouldProfile, - @"Default options with tracing enabled, traces and profiles sample rates of 1, but app " - @"launch profiling disabled should not enable launch profiling"); -} - -- (void)testDisablingTracingOptionDisablesAppLaunchProfiling -{ - XCTAssertFalse(sentry_shouldProfileNextLaunch( - [self defaultLaunchProfilingOptionsWithOverrides:@{ SENTRY_OPTION( - enableTracing, @NO) }]) - .shouldProfile, - @"Default options with app launch profiling enabled, traces and profiles sample rates of " - @"1, but tracing disabled should not enable launch profiling"); -} - -- (void)testSettingTracesSampleRateTo0DisablesAppLaunchProfiling -{ - XCTAssertFalse( - sentry_shouldProfileNextLaunch( - [self defaultLaunchProfilingOptionsWithOverrides:@{ SENTRY_OPTION( - tracesSampleRate, @0) }]) - .shouldProfile, - @"Default options with app launch profiling and tracing enabled, profiles sample rate of " - @"1, but traces sample rate of 0 should not enable launch profiling"); -} - -- (void)testSettingProfilesSampleRateTo0DisablesAppLaunchProfiling -{ - XCTAssertFalse( - sentry_shouldProfileNextLaunch( - [self defaultLaunchProfilingOptionsWithOverrides:@{ SENTRY_OPTION( - profilesSampleRate, @0) }]) - .shouldProfile, - @"Default options with app launch profiling and tracing enabled, traces sample rate of 1, " - @"but profiles sample rate of 0 should not enable launch profiling"); -} - -# pragma mark - Private - -- (SentryOptions *)defaultLaunchProfilingOptionsWithOverrides: - (NSDictionary *)overrides -{ - NSMutableDictionary *options = [NSMutableDictionary - dictionaryWithDictionary:@{ SENTRY_OPTION(enableAppLaunchProfiling, @YES), - SENTRY_OPTION(enableTracing, @YES), - SENTRY_OPTION(tracesSampleRate, @1), - SENTRY_OPTION(profilesSampleRate, @1) }]; - [options addEntriesFromDictionary:overrides]; - return [self defaultOptionsWithOverrides:options]; -} - -- (SentryOptions *)defaultOptionsWithOverrides:(nullable NSDictionary *)overrides -{ - NSMutableDictionary *options = [NSMutableDictionary - dictionaryWithObject:@"https://username:password@sentry.io/1" - forKey:@"dsn"]; - [options addEntriesFromDictionary:overrides]; - NSError *error; - SentryOptions *sentryOptions = [[SentryOptions alloc] initWithDict:options - didFailWithError:&error]; - XCTAssertNil(error); - return sentryOptions; -} - -# undef SENTRY_OPTION - -@end - -#endif // SENTRY_TARGET_PROFILING_SUPPORTED diff --git a/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift b/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift index ef997365ef..50127b52f9 100644 --- a/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift +++ b/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift @@ -1,16 +1,23 @@ import SentryTestUtils import XCTest -/** - * Test how combinations of the following options interact to ultimately decide whether or not to start the profiler on the next app launch.. - * - `enableLaunchProfiling` - * - `enableTracing` - * - `enableContinuousProfiling` - * - `tracesSampleRate` - * - `profilesSampleRate` - * - `profilesSampler` - */ final class SentryAppLaunchProfilingSwiftTestsNormal: XCTestCase { + func testContentsOfLegacyLaunchProfileTransactionContext() { + let context = sentry_context(NSNumber(value: 1)) + XCTAssertEqual(context.nameSource.rawValue, 0) + XCTAssertEqual(context.origin, "auto.app.start.profile") + XCTAssertEqual(context.sampled, .yes) + } + + /** + * Test how combinations of the following options interact to ultimately decide whether or not to start the profiler on the next app launch.. + * - `enableLaunchProfiling` + * - `enableTracing` + * - `enableContinuousProfiling` + * - `tracesSampleRate` + * - `profilesSampleRate` + * - `profilesSampler` + */ func testShouldProfileLaunchBasedOnOptionsCombinations() { for testCase: (enableAppLaunchProfiling: Bool, enableTracing: Bool, enableContinuousProfiling: Bool, tracesSampleRate: Int, profilesSampleRate: Int, profilesSamplerReturnValue: Int, shouldProfileLaunch: Bool) in [ // everything false/0 diff --git a/Tests/SentryTests/SentryTests-Bridging-Header.h b/Tests/SentryTests/SentryTests-Bridging-Header.h index 7001475c7e..013d595f51 100644 --- a/Tests/SentryTests/SentryTests-Bridging-Header.h +++ b/Tests/SentryTests/SentryTests-Bridging-Header.h @@ -219,6 +219,7 @@ #import "SentryTime.h" #import "SentryTimeToDisplayTracker.h" #import "SentryTraceContext.h" +#import "SentryTraceOrigins.h" #import "SentryTracer+Private.h" #import "SentryTracer+Test.h" #import "SentryTracerConfiguration.h" From 197722b6c3a2aeaf8b7056eb1f798a50cc3d9fcc Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Thu, 9 May 2024 15:48:24 -0400 Subject: [PATCH 11/21] dont sample anything related to continuous profiling --- Sentry.xcodeproj/project.pbxproj | 8 --- .../Sentry/Profiling/SentryLaunchProfiling.m | 24 +++------ Sources/Sentry/SentryOptions.m | 8 +-- Sources/Sentry/SentrySampling.m | 36 +++++-------- .../Sentry/include/SentryOptions+Private.h | 2 +- Sources/Sentry/include/SentrySampling.h | 7 --- .../SentryAppLaunchProfilingTests.swift | 53 +++++++++---------- 7 files changed, 50 insertions(+), 88 deletions(-) diff --git a/Sentry.xcodeproj/project.pbxproj b/Sentry.xcodeproj/project.pbxproj index 5d93626ce3..ffa2a9f57a 100644 --- a/Sentry.xcodeproj/project.pbxproj +++ b/Sentry.xcodeproj/project.pbxproj @@ -674,7 +674,6 @@ 8459FCBE2BD73E820038E9C9 /* SentryProfilerSerialization.h in Headers */ = {isa = PBXBuildFile; fileRef = 8459FCBD2BD73E810038E9C9 /* SentryProfilerSerialization.h */; }; 8459FCC02BD73EB20038E9C9 /* SentryProfilerSerialization.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8459FCBF2BD73EB20038E9C9 /* SentryProfilerSerialization.mm */; }; 845C16D52A622A5B00EC9519 /* SentryTracer+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 845C16D42A622A5B00EC9519 /* SentryTracer+Private.h */; }; - 847D10BD2BE6F7130048ACD9 /* Nimble in Frameworks */ = {isa = PBXBuildFile; productRef = 847D10BC2BE6F7130048ACD9 /* Nimble */; }; 8489B8882A5F7905009A055A /* SentryThreadWrapperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8489B8872A5F7905009A055A /* SentryThreadWrapperTests.swift */; }; 848A45192BBF8D33006AAAEC /* SentryContinuousProfiler.mm in Sources */ = {isa = PBXBuildFile; fileRef = 848A45182BBF8D33006AAAEC /* SentryContinuousProfiler.mm */; }; 848A451A2BBF8D33006AAAEC /* SentryContinuousProfiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 848A45172BBF8D33006AAAEC /* SentryContinuousProfiler.h */; }; @@ -1990,7 +1989,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 847D10BD2BE6F7130048ACD9 /* Nimble in Frameworks */, 84B7FA3D29B2879C00AD93B1 /* libSentryTestUtils.a in Frameworks */, 8431EFD129B27B1100D8DC56 /* Sentry.framework in Frameworks */, ); @@ -4231,7 +4229,6 @@ ); name = SentryProfilerTests; packageProductDependencies = ( - 847D10BC2BE6F7130048ACD9 /* Nimble */, ); productName = "Tests-iOS"; productReference = 8431EFD929B27B1100D8DC56 /* SentryProfilerTests.xctest */; @@ -6951,11 +6948,6 @@ package = 62986F012B03D250008E2D62 /* XCRemoteSwiftPackageReference "Nimble" */; productName = Nimble; }; - 847D10BC2BE6F7130048ACD9 /* Nimble */ = { - isa = XCSwiftPackageProductDependency; - package = 62986F012B03D250008E2D62 /* XCRemoteSwiftPackageReference "Nimble" */; - productName = Nimble; - }; /* End XCSwiftPackageProductDependency section */ }; rootObject = 6327C5CA1EB8A783004E799B /* Project object */; diff --git a/Sources/Sentry/Profiling/SentryLaunchProfiling.m b/Sources/Sentry/Profiling/SentryLaunchProfiling.m index 32827ac63d..5cd46d689c 100644 --- a/Sources/Sentry/Profiling/SentryLaunchProfiling.m +++ b/Sources/Sentry/Profiling/SentryLaunchProfiling.m @@ -56,14 +56,15 @@ SentryLaunchProfileConfig sentry_shouldProfileNextLaunch(SentryOptions *options) { - BOOL shouldProfileNextLaunch = options.enableAppLaunchProfiling - && (options.enableContinuousProfiling || options.enableTracing); + if (options.enableContinuousProfiling) { + return (SentryLaunchProfileConfig) { YES, nil, nil }; + } + + BOOL shouldProfileNextLaunch = options.enableAppLaunchProfiling && options.enableTracing; if (!shouldProfileNextLaunch) { SENTRY_LOG_DEBUG(@"Won't profile next launch due to specified options configuration: " - @"options.enableAppLaunchProfiling: %d; options.enableTracing: %d; " - @"options.enableContinuousProfiling: %d", - options.enableAppLaunchProfiling, options.enableTracing, - options.enableContinuousProfiling); + @"options.enableAppLaunchProfiling: %d; options.enableTracing: %d", + options.enableAppLaunchProfiling, options.enableTracing); return (SentryLaunchProfileConfig) { NO, nil, nil }; } @@ -73,17 +74,6 @@ SentrySamplingContext *context = [[SentrySamplingContext alloc] initWithTransactionContext:transactionContext]; - if (options.enableContinuousProfiling) { - SentrySamplerDecision *profilesSamplerDecision = sampleContinuousProfile(context, options); - if (profilesSamplerDecision.decision != kSentrySampleDecisionYes) { - SENTRY_LOG_DEBUG(@"Sampling out the launch continuous profile."); - return (SentryLaunchProfileConfig) { NO, nil, nil }; - } - - SENTRY_LOG_DEBUG(@"Will continuously profile the next session starting from launch."); - return (SentryLaunchProfileConfig) { YES, nil, profilesSamplerDecision }; - } - SentrySamplerDecision *tracesSamplerDecision = sentry_sampleTrace(context, options); if (tracesSamplerDecision.decision != kSentrySampleDecisionYes) { SENTRY_LOG_DEBUG(@"Sampling out the launch trace."); diff --git a/Sources/Sentry/SentryOptions.m b/Sources/Sentry/SentryOptions.m index e6ca2aaa6f..b74ce1620d 100644 --- a/Sources/Sentry/SentryOptions.m +++ b/Sources/Sentry/SentryOptions.m @@ -561,7 +561,7 @@ - (void)setSampleRate:(NSNumber *)sampleRate { if (sampleRate == nil) { _sampleRate = nil; - } else if (isValidSampleRate(sampleRate)) { + } else if (sentry_isValidSampleRate(sampleRate)) { _sampleRate = sampleRate; } else { _sampleRate = SENTRY_DEFAULT_SAMPLE_RATE; @@ -569,7 +569,7 @@ - (void)setSampleRate:(NSNumber *)sampleRate } BOOL -isValidSampleRate(NSNumber *sampleRate) +sentry_isValidSampleRate(NSNumber *sampleRate) { double rate = [sampleRate doubleValue]; return rate >= 0 && rate <= 1.0; @@ -592,7 +592,7 @@ - (void)setTracesSampleRate:(NSNumber *)tracesSampleRate { if (tracesSampleRate == nil) { _tracesSampleRate = nil; - } else if (isValidSampleRate(tracesSampleRate)) { + } else if (sentry_isValidSampleRate(tracesSampleRate)) { _tracesSampleRate = tracesSampleRate; if (!_enableTracingManual) { _enableTracing = YES; @@ -622,7 +622,7 @@ - (void)setProfilesSampleRate:(NSNumber *)profilesSampleRate { if (profilesSampleRate == nil) { _profilesSampleRate = nil; - } else if (isValidSampleRate(profilesSampleRate)) { + } else if (sentry_isValidSampleRate(profilesSampleRate)) { _profilesSampleRate = profilesSampleRate; } else { _profilesSampleRate = SENTRY_DEFAULT_PROFILES_SAMPLE_RATE; diff --git a/Sources/Sentry/SentrySampling.m b/Sources/Sentry/SentrySampling.m index 1c6fa4b222..01307e322b 100644 --- a/Sources/Sentry/SentrySampling.m +++ b/Sources/Sentry/SentrySampling.m @@ -17,7 +17,7 @@ * @return A sample rate if the specified sampler callback was defined on @c SentryOptions and * returned a valid value, @c nil otherwise. */ -NSNumber *_Nullable samplerCallbackRate(SentryTracesSamplerCallback _Nullable callback, +NSNumber *_Nullable _sentry_samplerCallbackRate(SentryTracesSamplerCallback _Nullable callback, SentrySamplingContext *context, NSNumber *defaultSampleRate) { if (callback == nil) { @@ -25,7 +25,7 @@ } NSNumber *callbackRate = callback(context); - if (!isValidSampleRate(callbackRate)) { + if (!sentry_isValidSampleRate(callbackRate)) { return defaultSampleRate; } @@ -33,7 +33,7 @@ } SentrySamplerDecision * -calcSample(NSNumber *rate) +_sentry_calcSample(NSNumber *rate) { double random = [SentryDependencyContainer.sharedInstance.random nextNumber]; SentrySampleDecision decision @@ -42,14 +42,14 @@ } SentrySamplerDecision * -calcSampleFromNumericalRate(NSNumber *rate) +_sentry_calcSampleFromNumericalRate(NSNumber *rate) { if (rate == nil) { return [[SentrySamplerDecision alloc] initWithDecision:kSentrySampleDecisionNo forSampleRate:nil]; } - return calcSample(rate); + return _sentry_calcSample(rate); } #pragma mark - Public @@ -64,10 +64,10 @@ forSampleRate:context.transactionContext.sampleRate]; } - NSNumber *callbackRate - = samplerCallbackRate(options.tracesSampler, context, SENTRY_DEFAULT_TRACES_SAMPLE_RATE); + NSNumber *callbackRate = _sentry_samplerCallbackRate( + options.tracesSampler, context, SENTRY_DEFAULT_TRACES_SAMPLE_RATE); if (callbackRate != nil) { - return calcSample(callbackRate); + return _sentry_calcSample(callbackRate); } // check the _parent_ transaction's sampling decision, if any @@ -77,7 +77,7 @@ forSampleRate:context.transactionContext.sampleRate]; } - return calcSampleFromNumericalRate(options.tracesSampleRate); + return _sentry_calcSampleFromNumericalRate(options.tracesSampleRate); } #if SENTRY_TARGET_PROFILING_SUPPORTED @@ -103,25 +103,13 @@ } # pragma clang diagnostic pop - NSNumber *callbackRate = samplerCallbackRate( + NSNumber *callbackRate = _sentry_samplerCallbackRate( options.profilesSampler, context, SENTRY_DEFAULT_PROFILES_SAMPLE_RATE); if (callbackRate != nil) { - return calcSample(callbackRate); + return _sentry_calcSample(callbackRate); } - return calcSampleFromNumericalRate(options.profilesSampleRate); -} - -SentrySamplerDecision * -sampleContinuousProfile(SentrySamplingContext *context, SentryOptions *options) -{ - NSNumber *callbackRate = samplerCallbackRate( - options.profilesSampler, context, SENTRY_DEFAULT_PROFILES_SAMPLE_RATE); - if (callbackRate != nil) { - return calcSample(callbackRate); - } - - return calcSampleFromNumericalRate(options.profilesSampleRate); + return _sentry_calcSampleFromNumericalRate(options.profilesSampleRate); } #endif // SENTRY_TARGET_PROFILING_SUPPORTED diff --git a/Sources/Sentry/include/SentryOptions+Private.h b/Sources/Sentry/include/SentryOptions+Private.h index 848db06b3a..57fe707685 100644 --- a/Sources/Sentry/include/SentryOptions+Private.h +++ b/Sources/Sentry/include/SentryOptions+Private.h @@ -15,7 +15,7 @@ SentryOptions () @property (nonatomic, assign) BOOL enableContinuousProfiling; #endif // SENTRY_TARGET_PROFILING_SUPPORTED -SENTRY_EXTERN BOOL isValidSampleRate(NSNumber *sampleRate); +SENTRY_EXTERN BOOL sentry_isValidSampleRate(NSNumber *sampleRate); @end diff --git a/Sources/Sentry/include/SentrySampling.h b/Sources/Sentry/include/SentrySampling.h index eec93f53f3..761b0e99f9 100644 --- a/Sources/Sentry/include/SentrySampling.h +++ b/Sources/Sentry/include/SentrySampling.h @@ -22,13 +22,6 @@ SENTRY_EXTERN SentrySamplerDecision *sentry_sampleTrace( */ SENTRY_EXTERN SentrySamplerDecision *sentry_sampleTraceProfile(SentrySamplingContext *context, SentrySamplerDecision *tracesSamplerDecision, SentryOptions *options); - -/** - * Determines whether a continuous profile should be sampled based on the context and options, to - * decide whether to configure the next launch to start a continuous profile. - */ -SentrySamplerDecision *sampleContinuousProfile( - SentrySamplingContext *context, SentryOptions *options); #endif // SENTRY_TARGET_PROFILING_SUPPORTED NS_ASSUME_NONNULL_END diff --git a/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift b/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift index 50127b52f9..bc5d69f35c 100644 --- a/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift +++ b/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift @@ -1,7 +1,7 @@ import SentryTestUtils import XCTest -final class SentryAppLaunchProfilingSwiftTestsNormal: XCTestCase { +final class SentryAppLaunchProfilingSwiftTests: XCTestCase { func testContentsOfLegacyLaunchProfileTransactionContext() { let context = sentry_context(NSNumber(value: 1)) XCTAssertEqual(context.nameSource.rawValue, 0) @@ -13,7 +13,7 @@ final class SentryAppLaunchProfilingSwiftTestsNormal: XCTestCase { * Test how combinations of the following options interact to ultimately decide whether or not to start the profiler on the next app launch.. * - `enableLaunchProfiling` * - `enableTracing` - * - `enableContinuousProfiling` + * - `enableContinuousProfiling` (always profiles regardless of sample rate or trace options) * - `tracesSampleRate` * - `profilesSampleRate` * - `profilesSampler` @@ -28,53 +28,53 @@ final class SentryAppLaunchProfilingSwiftTestsNormal: XCTestCase { (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), // change enableContinuousProfiling to true - (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), - (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), - (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), - (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: true), + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: true), + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: true), + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: true), // change enableTracing to true (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), - (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), - (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), - (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), - (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: true), + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: true), + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: true), + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: true), // change enableAppLaunchProfiling to true (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), - (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), - (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), - (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), - (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: true), + (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: true), + (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: true), + (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: true), (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), - (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), - (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), - (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), - (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: true), + (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: true), + (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: true), + (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: true), // change profilesSamplerReturnValue to 1 (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), - (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), - (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), - (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), - (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: true), + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: true), + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: true), + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: true), (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), - (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), - (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), - (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), - (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: true), + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: true), + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: true), + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: true), (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), @@ -91,7 +91,6 @@ final class SentryAppLaunchProfilingSwiftTestsNormal: XCTestCase { (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: true), (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: true), (enableAppLaunchProfiling: true, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: true) - ] { let options = Options() options.enableAppLaunchProfiling = testCase.enableAppLaunchProfiling From ac102a40891626740982ff767e91059b935a378a Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Tue, 14 May 2024 15:09:14 -0800 Subject: [PATCH 12/21] wip writing a test for launch profile configuration --- .../SentryAppLaunchProfilingTests.swift | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift b/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift index bc5d69f35c..f7af67ce92 100644 --- a/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift +++ b/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift @@ -8,7 +8,18 @@ final class SentryAppLaunchProfilingSwiftTests: XCTestCase { XCTAssertEqual(context.origin, "auto.app.start.profile") XCTAssertEqual(context.sampled, .yes) } - + + // test that after configuring launch profiling for the trace profiler, the + // file is written to disk and the file is deleted after the app is launched + func testLaunchProfileTransactionContext() { + let options = Options() + options.enableAppLaunchProfiling = true + options.profilesSampleRate = 1 + options.tracesSampleRate = 1 + sentry_manageTraceProfilerOnStartSDK(options, TestHub(client: nil, andScope: nil)) + XCTAssert(FileManager.default.fileExists(atPath: launchProfileConfigFileURL().absoluteString)) + } + /** * Test how combinations of the following options interact to ultimately decide whether or not to start the profiler on the next app launch.. * - `enableLaunchProfiling` From 39208f4b2ff96d4ff94fc96f01ee8c229266b926 Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Tue, 14 May 2024 21:49:34 -0800 Subject: [PATCH 13/21] add more tests to cover launch profiling code --- SentryTestUtils/ClearTestState.swift | 1 + SentryTestUtils/SentryLaunchProfiling+Tests.h | 9 ++ .../Sentry/Profiling/SentryLaunchProfiling.m | 84 ++++++++++--------- Sources/Sentry/SentryProfiler.mm | 22 +++-- .../SentryAppLaunchProfilingTests.swift | 82 ++++++++++++++++-- .../SentryLegacyProfilerTests.swift | 4 +- 6 files changed, 144 insertions(+), 58 deletions(-) diff --git a/SentryTestUtils/ClearTestState.swift b/SentryTestUtils/ClearTestState.swift index 465e3d45e1..cd5b73a790 100644 --- a/SentryTestUtils/ClearTestState.swift +++ b/SentryTestUtils/ClearTestState.swift @@ -42,6 +42,7 @@ class TestCleanup: NSObject { SentryLegacyProfiler.getCurrentProfiler()?.stop(for: SentryProfilerTruncationReason.normal) SentryLegacyProfiler.resetConcurrencyTracking() SentryContinuousProfiler.stop() + removeAppLaunchProfilingConfigFile() #endif // os(iOS) || os(macOS) || targetEnvironment(macCatalyst) #if os(iOS) || os(tvOS) || targetEnvironment(macCatalyst) diff --git a/SentryTestUtils/SentryLaunchProfiling+Tests.h b/SentryTestUtils/SentryLaunchProfiling+Tests.h index f066dda8ac..5a1f86a2b7 100644 --- a/SentryTestUtils/SentryLaunchProfiling+Tests.h +++ b/SentryTestUtils/SentryLaunchProfiling+Tests.h @@ -17,6 +17,7 @@ typedef struct { SENTRY_EXTERN NSString *const kSentryLaunchProfileConfigKeyTracesSampleRate; SENTRY_EXTERN NSString *const kSentryLaunchProfileConfigKeyProfilesSampleRate; +SENTRY_EXTERN NSString *const kSentryLaunchProfileConfigKeyContinuousProfiling; SentryLaunchProfileConfig sentry_shouldProfileNextLaunch(SentryOptions *options); @@ -27,6 +28,14 @@ SentryLaunchProfileConfig sentry_shouldProfileNextLaunch(SentryOptions *options) */ BOOL sentry_willProfileNextLaunch(SentryOptions *options); +/** + * Contains the logic to start a launch profile. Exposed separately from @c + * sentry_startLaunchProfile, because that function wraps everything in a @c dispatch_once , and + * that path is taken once when @c SenryProfiler.load is called at the start of the test suite, and + * can't be executed again by calling that function. + */ +void _sentry_nondeduplicated_startLaunchProfile(void); + SentryTransactionContext *sentry_context(NSNumber *tracesRate); NS_ASSUME_NONNULL_END diff --git a/Sources/Sentry/Profiling/SentryLaunchProfiling.m b/Sources/Sentry/Profiling/SentryLaunchProfiling.m index 5cd46d689c..8f9883eb58 100644 --- a/Sources/Sentry/Profiling/SentryLaunchProfiling.m +++ b/Sources/Sentry/Profiling/SentryLaunchProfiling.m @@ -114,6 +114,50 @@ } # endif // defined(TEST) || defined(TESTCI) || defined(DEBUG) +# pragma mark - Exposed only to tests + +void +_sentry_nondeduplicated_startLaunchProfile(void) +{ + sentry_isTracingAppLaunch = appLaunchProfileConfigFileExists(); + if (!sentry_isTracingAppLaunch) { + return; + } + +# if defined(DEBUG) + // quick and dirty way to get debug logging this early in the process run. this will get + // overwritten once SentrySDK.startWithOptions is called according to the values of + // SentryOptions.debug and SentryOptions.diagnosticLevel + [SentryLog configure:YES diagnosticLevel:kSentryLevelDebug]; +# endif // defined(DEBUG) + + NSDictionary *launchConfig = appLaunchProfileConfiguration(); + if ([launchConfig[kSentryLaunchProfileConfigKeyContinuousProfiling] boolValue]) { + [SentryContinuousProfiler start]; + return; + } + + NSNumber *profilesRate = launchConfig[kSentryLaunchProfileConfigKeyProfilesSampleRate]; + if (profilesRate == nil) { + SENTRY_LOG_DEBUG(@"Received a nil configured launch profile sample rate, will not " + @"start continuous profiler for launch."); + return; + } + + NSNumber *tracesRate = launchConfig[kSentryLaunchProfileConfigKeyTracesSampleRate]; + if (tracesRate == nil) { + SENTRY_LOG_DEBUG(@"Received a nil configured launch trace sample rate, will not start " + @"a profiled launch trace."); + return; + } + + SENTRY_LOG_INFO(@"Starting app launch profile at %llu.", getAbsoluteTime()); + sentry_launchTracer = + [[SentryTracer alloc] initWithTransactionContext:sentry_context(tracesRate) + hub:nil + configuration:sentry_config(profilesRate)]; +} + # pragma mark - Public BOOL sentry_isTracingAppLaunch; @@ -149,45 +193,7 @@ // this function is called from SentryTracer.load but in the future we may expose access // directly to customers, and we'll want to ensure it only runs once. dispatch_once is an // efficient operation so it's fine to leave this in the launch path in any case. - dispatch_once(&onceToken, ^{ - sentry_isTracingAppLaunch = appLaunchProfileConfigFileExists(); - if (!sentry_isTracingAppLaunch) { - return; - } - -# if defined(DEBUG) - // quick and dirty way to get debug logging this early in the process run. this will get - // overwritten once SentrySDK.startWithOptions is called according to the values of - // SentryOptions.debug and SentryOptions.diagnosticLevel - [SentryLog configure:YES diagnosticLevel:kSentryLevelDebug]; -# endif // defined(DEBUG) - - NSDictionary *launchConfig = appLaunchProfileConfiguration(); - NSNumber *profilesRate = launchConfig[kSentryLaunchProfileConfigKeyProfilesSampleRate]; - if ([launchConfig[kSentryLaunchProfileConfigKeyContinuousProfiling] boolValue]) { - if (profilesRate == nil) { - SENTRY_LOG_DEBUG(@"Received a nil configured launch profile sample rate, will not " - @"start continuous profiler for launch."); - return; - } - - [SentryContinuousProfiler start]; - return; - } - - NSNumber *tracesRate = launchConfig[kSentryLaunchProfileConfigKeyTracesSampleRate]; - if (tracesRate == nil) { - SENTRY_LOG_DEBUG(@"Received a nil configured launch trace sample rate, will not start " - @"a profiled launch trace."); - return; - } - - SENTRY_LOG_INFO(@"Starting app launch profile at %llu.", getAbsoluteTime()); - sentry_launchTracer = - [[SentryTracer alloc] initWithTransactionContext:sentry_context(tracesRate) - hub:nil - configuration:sentry_config(profilesRate)]; - }); + dispatch_once(&onceToken, ^{ _sentry_nondeduplicated_startLaunchProfile(); }); } void diff --git a/Sources/Sentry/SentryProfiler.mm b/Sources/Sentry/SentryProfiler.mm index e2bcef907c..a7e3a38867 100644 --- a/Sources/Sentry/SentryProfiler.mm +++ b/Sources/Sentry/SentryProfiler.mm @@ -40,23 +40,20 @@ void sentry_manageTraceProfilerOnStartSDK(SentryOptions *options, SentryHub *hub) { - if (!options.enableContinuousProfiling) { - BOOL shouldStopAndTransmitLaunchProfile = YES; + [SentryDependencyContainer.sharedInstance.dispatchQueueWrapper dispatchAsyncWithBlock:^{ + BOOL shouldStopAndTransmitLaunchProfile = !options.enableContinuousProfiling; # if SENTRY_HAS_UIKIT if (SentryUIViewControllerPerformanceTracker.shared.enableWaitForFullDisplay) { shouldStopAndTransmitLaunchProfile = NO; } # endif // SENTRY_HAS_UIKIT - - [SentryDependencyContainer.sharedInstance.dispatchQueueWrapper dispatchAsyncWithBlock:^{ - if (shouldStopAndTransmitLaunchProfile) { - SENTRY_LOG_DEBUG(@"Stopping launch profile in SentrySDK.start because there will " - @"be no automatic trace to attach it to."); - sentry_stopAndTransmitLaunchProfile(hub); - } - sentry_configureLaunchProfiling(options); - }]; - } + if (shouldStopAndTransmitLaunchProfile) { + SENTRY_LOG_DEBUG(@"Stopping launch profile in SentrySDK.start because there will " + @"be no automatic trace to attach it to."); + sentry_stopAndTransmitLaunchProfile(hub); + } + sentry_configureLaunchProfiling(options); + }]; } @implementation SentryProfiler { @@ -160,6 +157,7 @@ - (void)backgroundAbort - (void)stopForReason:(SentryProfilerTruncationReason)reason { + sentry_isTracingAppLaunch = NO; [_timeoutTimer invalidate]; [self.metricProfiler stop]; self.truncationReason = reason; diff --git a/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift b/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift index f7af67ce92..fff2f35aa3 100644 --- a/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift +++ b/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift @@ -2,6 +2,18 @@ import SentryTestUtils import XCTest final class SentryAppLaunchProfilingSwiftTests: XCTestCase { + var fixture: SentryProfileTestFixture? + + override func setUp() { + super.setUp() + fixture = SentryProfileTestFixture() + } + + override func tearDown() { + super.tearDown() + clearTestState() + } + func testContentsOfLegacyLaunchProfileTransactionContext() { let context = sentry_context(NSNumber(value: 1)) XCTAssertEqual(context.nameSource.rawValue, 0) @@ -9,15 +21,73 @@ final class SentryAppLaunchProfilingSwiftTests: XCTestCase { XCTAssertEqual(context.sampled, .yes) } - // test that after configuring launch profiling for the trace profiler, the - // file is written to disk and the file is deleted after the app is launched - func testLaunchProfileTransactionContext() { + func testLaunchTraceProfileConfiguration() throws { + let expectedProfilesSampleRate: NSNumber = 0.567 + let expectedTracesSampleRate: NSNumber = 0.789 let options = Options() options.enableAppLaunchProfiling = true - options.profilesSampleRate = 1 - options.tracesSampleRate = 1 + options.profilesSampleRate = expectedProfilesSampleRate + options.tracesSampleRate = expectedTracesSampleRate + XCTAssertFalse(appLaunchProfileConfigFileExists()) + sentry_manageTraceProfilerOnStartSDK(options, TestHub(client: nil, andScope: nil)) + XCTAssert(appLaunchProfileConfigFileExists()) + let dict = try XCTUnwrap(appLaunchProfileConfiguration()) + XCTAssertEqual(dict[kSentryLaunchProfileConfigKeyTracesSampleRate], expectedTracesSampleRate) + XCTAssertEqual(dict[kSentryLaunchProfileConfigKeyProfilesSampleRate], expectedProfilesSampleRate) + } + + // test that after configuring for a launch profile, a subsequent + // configuration with insufficient sample rates removes the configuration + // file + func testLaunchTraceProfileConfigurationRemoval() { + let options = Options() + options.enableAppLaunchProfiling = true + options.profilesSampleRate = 0.567 + options.tracesSampleRate = 0.789 + XCTAssertFalse(appLaunchProfileConfigFileExists()) + sentry_manageTraceProfilerOnStartSDK(options, TestHub(client: nil, andScope: nil)) + XCTAssert(appLaunchProfileConfigFileExists()) + options.profilesSampleRate = 0 + sentry_manageTraceProfilerOnStartSDK(options, TestHub(client: nil, andScope: nil)) + XCTAssertFalse(appLaunchProfileConfigFileExists()) + // ensure we get another config written, to test removal again + options.profilesSampleRate = 0.567 + sentry_manageTraceProfilerOnStartSDK(options, TestHub(client: nil, andScope: nil)) + XCTAssert(appLaunchProfileConfigFileExists()) + options.tracesSampleRate = 0 + sentry_manageTraceProfilerOnStartSDK(options, TestHub(client: nil, andScope: nil)) + XCTAssertFalse(appLaunchProfileConfigFileExists()) + } + + // test continuous launch profiling configuration + func testContinuousLaunchProfileConfiguration() throws { + let options = Options() + options.enableContinuousProfiling = true + + // sample rates are not considered for continuous profiling + options.profilesSampleRate = 0 + options.tracesSampleRate = 0 + + XCTAssertFalse(appLaunchProfileConfigFileExists()) + sentry_manageTraceProfilerOnStartSDK(options, TestHub(client: nil, andScope: nil)) + XCTAssert(appLaunchProfileConfigFileExists()) + let dict = try XCTUnwrap(appLaunchProfileConfiguration()) + XCTAssertEqual(dict[kSentryLaunchProfileConfigKeyContinuousProfiling], true) + + _sentry_nondeduplicated_startLaunchProfile() + XCTAssert(SentryContinuousProfiler.isCurrentlyProfiling()) + } + + func testTraceProfilerStartsWhenBothSampleRatesAreSet() { + let options = Options() + options.enableAppLaunchProfiling = true + options.profilesSampleRate = 0.567 + options.tracesSampleRate = 0.789 + XCTAssertFalse(appLaunchProfileConfigFileExists()) sentry_manageTraceProfilerOnStartSDK(options, TestHub(client: nil, andScope: nil)) - XCTAssert(FileManager.default.fileExists(atPath: launchProfileConfigFileURL().absoluteString)) + XCTAssertTrue(appLaunchProfileConfigFileExists()) + _sentry_nondeduplicated_startLaunchProfile() + XCTAssert(SentryLegacyProfiler.isCurrentlyProfiling()) } /** diff --git a/Tests/SentryProfilerTests/SentryLegacyProfilerTests.swift b/Tests/SentryProfilerTests/SentryLegacyProfilerTests.swift index 1ad06d96a3..1827c85ba3 100644 --- a/Tests/SentryProfilerTests/SentryLegacyProfilerTests.swift +++ b/Tests/SentryProfilerTests/SentryLegacyProfilerTests.swift @@ -624,7 +624,9 @@ private extension SentryLegacyProfilerTests { options(fixtureOptions) let span = try fixture.newTransaction() - try addMockSamples() + if expectedDecision == .yes { + try addMockSamples() + } fixture.currentDateProvider.advance(by: 5) span.finish() From de2a193b3419d04d2b36231213e5f4831581082c Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Tue, 14 May 2024 22:39:24 -0800 Subject: [PATCH 14/21] fix a couple bugs in launch profiling state mgmt, and get all tests passing again --- .../iOS-Swift-UITests/ProfilingUITests.swift | 20 ++++++++++--------- .../Profiling/ProfilingViewController.swift | 2 +- .../Sentry/Profiling/SentryLaunchProfiling.m | 12 +++++------ .../Profiling/SentryProfilerTestHelpers.m | 17 ++++------------ Sources/Sentry/SentryProfiler.mm | 2 ++ 5 files changed, 24 insertions(+), 29 deletions(-) diff --git a/Samples/iOS-Swift/iOS-Swift-UITests/ProfilingUITests.swift b/Samples/iOS-Swift/iOS-Swift-UITests/ProfilingUITests.swift index 8b5f31bb90..dc8d8c27a1 100644 --- a/Samples/iOS-Swift/iOS-Swift-UITests/ProfilingUITests.swift +++ b/Samples/iOS-Swift/iOS-Swift-UITests/ProfilingUITests.swift @@ -8,6 +8,7 @@ class ProfilingUITests: BaseUITest { func testProfiledAppLaunches() throws { if #available(iOS 16, *) { app.launchArguments.append("--io.sentry.wipe-data") + setDefaultLaunchArgs() launchApp() // First launch enables in-app profiling by setting traces/profiles sample rates to 1 (which is the default configuration in the sample app), but not launch profiling; assert that we did not write a config to allow the next launch to be profiled. @@ -162,6 +163,15 @@ extension ProfilingUITests { }) XCTAssert(try XCTUnwrap(sample["thread_id"] as? String) == "259") // the main thread is always ID 259 } + + /** + * These cause traces to run the profiler, which can overwrite the launch profile file we need to retrieve to make assertions in the UI test. + */ + func setDefaultLaunchArgs() { + app.launchArguments.append("--disable-swizzling") + app.launchArguments.append("--disable-auto-performance-tracing") + app.launchArguments.append("--disable-uiviewcontroller-tracing") + } /** * Performs the various operations for the launch profiler test case: @@ -216,16 +226,8 @@ extension ProfilingUITests { if shouldDisableTracing { app.launchArguments.append("--disable-tracing") } - if shouldDisableSwizzling { - app.launchArguments.append("--disable-swizzling") - } - if shouldDisableAutoPerformanceTracking { - app.launchArguments.append("--disable-auto-performance-tracing") - } - if shouldDisableUIViewControllerTracing { - app.launchArguments.append("--disable-uiviewcontroller-tracing") - } + setDefaultLaunchArgs() launchApp() let sdkOptionsConfigurationAllowsLaunchProfiling = !(shouldDisableTracing || shouldDisableSwizzling || shouldDisableAutoPerformanceTracking || shouldDisableUIViewControllerTracing) diff --git a/Samples/iOS-Swift/iOS-Swift/Profiling/ProfilingViewController.swift b/Samples/iOS-Swift/iOS-Swift/Profiling/ProfilingViewController.swift index bb25956119..7c0a450409 100644 --- a/Samples/iOS-Swift/iOS-Swift/Profiling/ProfilingViewController.swift +++ b/Samples/iOS-Swift/iOS-Swift/Profiling/ProfilingViewController.swift @@ -112,7 +112,7 @@ class ProfilingViewController: UIViewController, UITextFieldDelegate { @IBAction func viewLaunchProfile(_ sender: Any) { profilingUITestDataMarshalingTextField.text = "" - withProfile(fileName: "launchProfile") { file in + withProfile(fileName: "profile") { file in handleContents(file: file) } } diff --git a/Sources/Sentry/Profiling/SentryLaunchProfiling.m b/Sources/Sentry/Profiling/SentryLaunchProfiling.m index 8f9883eb58..e5f4f7eed1 100644 --- a/Sources/Sentry/Profiling/SentryLaunchProfiling.m +++ b/Sources/Sentry/Profiling/SentryLaunchProfiling.m @@ -24,7 +24,6 @@ NS_ASSUME_NONNULL_BEGIN -BOOL isProfilingAppLaunch; NSString *const kSentryLaunchProfileConfigKeyTracesSampleRate = @"traces"; NSString *const kSentryLaunchProfileConfigKeyProfilesSampleRate = @"profiles"; NSString *const kSentryLaunchProfileConfigKeyContinuousProfiling = @"continuous-profiling"; @@ -119,8 +118,7 @@ void _sentry_nondeduplicated_startLaunchProfile(void) { - sentry_isTracingAppLaunch = appLaunchProfileConfigFileExists(); - if (!sentry_isTracingAppLaunch) { + if (!appLaunchProfileConfigFileExists()) { return; } @@ -140,18 +138,19 @@ NSNumber *profilesRate = launchConfig[kSentryLaunchProfileConfigKeyProfilesSampleRate]; if (profilesRate == nil) { SENTRY_LOG_DEBUG(@"Received a nil configured launch profile sample rate, will not " - @"start continuous profiler for launch."); + @"start trace profiler for launch."); return; } NSNumber *tracesRate = launchConfig[kSentryLaunchProfileConfigKeyTracesSampleRate]; if (tracesRate == nil) { SENTRY_LOG_DEBUG(@"Received a nil configured launch trace sample rate, will not start " - @"a profiled launch trace."); + @"trace profiler for launch."); return; } - SENTRY_LOG_INFO(@"Starting app launch profile at %llu.", getAbsoluteTime()); + SENTRY_LOG_INFO(@"Starting app launch trace profile at %llu.", getAbsoluteTime()); + sentry_isTracingAppLaunch = YES; sentry_launchTracer = [[SentryTracer alloc] initWithTransactionContext:sentry_context(tracesRate) hub:nil @@ -213,6 +212,7 @@ { SENTRY_LOG_DEBUG(@"Finishing launch tracer."); [sentry_launchTracer finish]; + sentry_isTracingAppLaunch = NO; } NS_ASSUME_NONNULL_END diff --git a/Sources/Sentry/Profiling/SentryProfilerTestHelpers.m b/Sources/Sentry/Profiling/SentryProfilerTestHelpers.m index f1eb44fef1..48f76c6989 100644 --- a/Sources/Sentry/Profiling/SentryProfilerTestHelpers.m +++ b/Sources/Sentry/Profiling/SentryProfilerTestHelpers.m @@ -44,24 +44,15 @@ SENTRY_LOG_DEBUG(@"App support directory already exists."); } - NSString *pathToWrite; - if (sentry_isTracingAppLaunch) { - SENTRY_LOG_DEBUG(@"Writing app launch profile."); - pathToWrite = [appSupportDirPath stringByAppendingPathComponent:@"launchProfile"]; - } else { - SENTRY_LOG_DEBUG(@"Overwriting last non-launch profile."); - pathToWrite = [appSupportDirPath stringByAppendingPathComponent:@"profile"]; - } + NSString *pathToWrite = [appSupportDirPath stringByAppendingPathComponent:@"profile"]; if ([fm fileExistsAtPath:pathToWrite]) { - SENTRY_LOG_DEBUG(@"Already a %@ profile file present; make sure to remove them right after " + SENTRY_LOG_DEBUG(@"Already a profile file present; make sure to remove them right after " @"using them, and that tests clean state in between so there isn't " - @"leftover config producing one when it isn't expected.", - sentry_isTracingAppLaunch ? @" launch" : @""); - return; + @"leftover config producing one when it isn't expected."); } - SENTRY_LOG_DEBUG(@"Writing%@ profile to file.", sentry_isTracingAppLaunch ? @" launch" : @""); + SENTRY_LOG_DEBUG(@"Writing profile to file."); NSError *error; if (![data writeToFile:pathToWrite options:NSDataWritingAtomic error:&error]) { diff --git a/Sources/Sentry/SentryProfiler.mm b/Sources/Sentry/SentryProfiler.mm index a7e3a38867..7f0a5c6a9e 100644 --- a/Sources/Sentry/SentryProfiler.mm +++ b/Sources/Sentry/SentryProfiler.mm @@ -157,6 +157,8 @@ - (void)backgroundAbort - (void)stopForReason:(SentryProfilerTruncationReason)reason { + // the following line makes unit tests pass, but ui tests fail because sentry_writeProfileFile + // needs it to be true to write to the correct path sentry_isTracingAppLaunch = NO; [_timeoutTimer invalidate]; [self.metricProfiler stop]; From 544890d580e920b16095738428015ba99b26f4c0 Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Tue, 14 May 2024 23:19:55 -0800 Subject: [PATCH 15/21] fix tvos build --- Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift b/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift index fff2f35aa3..9f79c189b6 100644 --- a/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift +++ b/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift @@ -1,6 +1,7 @@ import SentryTestUtils import XCTest +#if os(iOS) || os(macOS) || targetEnvironment(macCatalyst) final class SentryAppLaunchProfilingSwiftTests: XCTestCase { var fixture: SentryProfileTestFixture? @@ -186,3 +187,4 @@ final class SentryAppLaunchProfilingSwiftTests: XCTestCase { } } } +#endif // os(iOS) || os(macOS) || targetEnvironment(macCatalyst) From ccf77d8ee7b84438a17c9677a76d6067910026a3 Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Tue, 14 May 2024 23:42:38 -0800 Subject: [PATCH 16/21] fix build issue --- Sentry.xcodeproj/project.pbxproj | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Sentry.xcodeproj/project.pbxproj b/Sentry.xcodeproj/project.pbxproj index ffa2a9f57a..bb5f63496b 100644 --- a/Sentry.xcodeproj/project.pbxproj +++ b/Sentry.xcodeproj/project.pbxproj @@ -631,6 +631,7 @@ 7DC8310C2398283C0043DD9A /* SentryCrashIntegration.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DC831092398283C0043DD9A /* SentryCrashIntegration.m */; }; 840A11122B61E27500650D02 /* SentrySamplerDecision.m in Sources */ = {isa = PBXBuildFile; fileRef = 840A11102B61E27500650D02 /* SentrySamplerDecision.m */; }; 841325BC2BF4184B0029228F /* TestHub.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B944FAD2469B43700A10721 /* TestHub.swift */; }; + 841325C52BF49EC40029228F /* SentryLaunchProfiling+Tests.h in Headers */ = {isa = PBXBuildFile; fileRef = 841325C42BF49EC40029228F /* SentryLaunchProfiling+Tests.h */; }; 84281C432A578E5600EE88F2 /* SentryProfilerState.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84281C422A578E5600EE88F2 /* SentryProfilerState.mm */; }; 84281C462A57905700EE88F2 /* SentrySample.h in Headers */ = {isa = PBXBuildFile; fileRef = 84281C442A57905700EE88F2 /* SentrySample.h */; }; 84281C472A57905700EE88F2 /* SentrySample.m in Sources */ = {isa = PBXBuildFile; fileRef = 84281C452A57905700EE88F2 /* SentrySample.m */; }; @@ -1645,7 +1646,6 @@ 7DC831082398283C0043DD9A /* SentryCrashIntegration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryCrashIntegration.h; path = include/SentryCrashIntegration.h; sourceTree = ""; }; 7DC831092398283C0043DD9A /* SentryCrashIntegration.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryCrashIntegration.m; sourceTree = ""; }; 840A11102B61E27500650D02 /* SentrySamplerDecision.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentrySamplerDecision.m; sourceTree = ""; }; - 840A11142B62041600650D02 /* SentryLaunchProfiling+Tests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "SentryLaunchProfiling+Tests.h"; path = "../Tests/SentryTests/SentryLaunchProfiling+Tests.h"; sourceTree = ""; }; 840B7EEA2BBF2ABA008B8120 /* .slather.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = .slather.yml; sourceTree = ""; }; 840B7EEC2BBF2AFE008B8120 /* .gitattributes */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitattributes; sourceTree = ""; }; 840B7EED2BBF2B16008B8120 /* .pre-commit-config.yaml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = ".pre-commit-config.yaml"; sourceTree = ""; }; @@ -1653,6 +1653,7 @@ 840B7EEF2BBF2B2B008B8120 /* .spi.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = .spi.yml; sourceTree = ""; }; 840B7EF02BBF2B5F008B8120 /* MIGRATION.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = MIGRATION.md; sourceTree = ""; }; 840B7EF22BBF83DF008B8120 /* SentryProfiler+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "SentryProfiler+Private.h"; path = "Sources/Sentry/include/SentryProfiler+Private.h"; sourceTree = SOURCE_ROOT; }; + 841325C42BF49EC40029228F /* SentryLaunchProfiling+Tests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SentryLaunchProfiling+Tests.h"; sourceTree = ""; }; 8419C0C328C1889D001C8259 /* SentryLegacyProfilerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryLegacyProfilerTests.swift; sourceTree = ""; }; 84281C422A578E5600EE88F2 /* SentryProfilerState.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = SentryProfilerState.mm; sourceTree = ""; }; 84281C442A57905700EE88F2 /* SentrySample.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentrySample.h; path = ../include/SentrySample.h; sourceTree = ""; }; @@ -3426,10 +3427,10 @@ 8431F00B29B284F200D8DC56 /* SentryTestUtils */ = { isa = PBXGroup; children = ( + 841325C42BF49EC40029228F /* SentryLaunchProfiling+Tests.h */, 7B4C817124D1BC2B0076ACE4 /* SentryFileManager+Test.h */, 7B944FAD2469B43700A10721 /* TestHub.swift */, 7B7A30C924B48523005A4C6E /* SentryHub+Test.h */, - 840A11142B62041600650D02 /* SentryLaunchProfiling+Tests.h */, 7BD47B4C268F0B080076A663 /* ClearTestState.swift */, 7B18DE4328D9F8F6004845C6 /* TestNSNotificationCenterWrapper.swift */, 84AC61D829F7643B009EEF61 /* TestDispatchFactory.swift */, @@ -4150,6 +4151,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 841325C52BF49EC40029228F /* SentryLaunchProfiling+Tests.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; From 8b6a180bf039f8783f0cd1304c611c22a2c55ae4 Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Wed, 15 May 2024 11:46:55 -0800 Subject: [PATCH 17/21] pr feedback --- .../Sentry/Profiling/SentryLaunchProfiling.m | 3 +- Sources/Sentry/SentryTimeToDisplayTracker.m | 10 +++--- .../SentryAppLaunchProfilingTests.swift | 33 ++++++++++--------- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/Sources/Sentry/Profiling/SentryLaunchProfiling.m b/Sources/Sentry/Profiling/SentryLaunchProfiling.m index e5f4f7eed1..a72973939e 100644 --- a/Sources/Sentry/Profiling/SentryLaunchProfiling.m +++ b/Sources/Sentry/Profiling/SentryLaunchProfiling.m @@ -55,7 +55,7 @@ SentryLaunchProfileConfig sentry_shouldProfileNextLaunch(SentryOptions *options) { - if (options.enableContinuousProfiling) { + if (options.enableAppLaunchProfiling && options.enableContinuousProfiling) { return (SentryLaunchProfileConfig) { YES, nil, nil }; } @@ -213,6 +213,7 @@ SENTRY_LOG_DEBUG(@"Finishing launch tracer."); [sentry_launchTracer finish]; sentry_isTracingAppLaunch = NO; + sentry_launchTracer = nil; } NS_ASSUME_NONNULL_END diff --git a/Sources/Sentry/SentryTimeToDisplayTracker.m b/Sources/Sentry/SentryTimeToDisplayTracker.m index 675eb1eeb8..4cdd219b22 100644 --- a/Sources/Sentry/SentryTimeToDisplayTracker.m +++ b/Sources/Sentry/SentryTimeToDisplayTracker.m @@ -140,10 +140,9 @@ - (void)framesTrackerHasNewFrame:(NSDate *)newFrameDate if (!_waitForFullDisplay) { [SentryDependencyContainer.sharedInstance.framesTracker removeListener:self]; # if SENTRY_TARGET_PROFILING_SUPPORTED - if (SentrySDK.options.enableContinuousProfiling) { - return; + if (!SentrySDK.options.enableContinuousProfiling) { + sentry_stopAndDiscardLaunchProfileTracer(); } - sentry_stopAndDiscardLaunchProfileTracer(); # endif // SENTRY_TARGET_PROFILING_SUPPORTED } } @@ -153,10 +152,9 @@ - (void)framesTrackerHasNewFrame:(NSDate *)newFrameDate self.fullDisplaySpan.timestamp = newFrameDate; [self.fullDisplaySpan finish]; # if SENTRY_TARGET_PROFILING_SUPPORTED - if (SentrySDK.options.enableContinuousProfiling) { - return; + if (!SentrySDK.options.enableContinuousProfiling) { + sentry_stopAndDiscardLaunchProfileTracer(); } - sentry_stopAndDiscardLaunchProfileTracer(); # endif // SENTRY_TARGET_PROFILING_SUPPORTED } diff --git a/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift b/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift index 9f79c189b6..62d048072d 100644 --- a/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift +++ b/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift @@ -63,6 +63,7 @@ final class SentryAppLaunchProfilingSwiftTests: XCTestCase { // test continuous launch profiling configuration func testContinuousLaunchProfileConfiguration() throws { let options = Options() + options.enableAppLaunchProfiling = true options.enableContinuousProfiling = true // sample rates are not considered for continuous profiling @@ -110,19 +111,19 @@ final class SentryAppLaunchProfilingSwiftTests: XCTestCase { (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), // change enableContinuousProfiling to true - (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: true), - (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: true), - (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: true), - (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: true), + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), // change enableTracing to true (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), - (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: true), - (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: true), - (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: true), - (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: true), + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), // change enableAppLaunchProfiling to true (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 0, shouldProfileLaunch: false), @@ -145,18 +146,18 @@ final class SentryAppLaunchProfilingSwiftTests: XCTestCase { (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), - (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: true), - (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: true), - (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: true), - (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: true), + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: false, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), - (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: true), - (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: true), - (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: true), - (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: true), + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), + (enableAppLaunchProfiling: false, enableTracing: true, enableContinuousProfiling: true, tracesSampleRate: 1, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 0, profilesSampleRate: 1, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), (enableAppLaunchProfiling: true, enableTracing: false, enableContinuousProfiling: false, tracesSampleRate: 1, profilesSampleRate: 0, profilesSamplerReturnValue: 1, shouldProfileLaunch: false), From 33c28e041b4ef0d12373e6c04f483e6faab480a6 Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Wed, 15 May 2024 14:54:54 -0800 Subject: [PATCH 18/21] fix build --- Sources/Sentry/SentryTimeToDisplayTracker.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Sources/Sentry/SentryTimeToDisplayTracker.m b/Sources/Sentry/SentryTimeToDisplayTracker.m index 4cdd219b22..dbc68ef993 100644 --- a/Sources/Sentry/SentryTimeToDisplayTracker.m +++ b/Sources/Sentry/SentryTimeToDisplayTracker.m @@ -7,7 +7,9 @@ # import "SentryFramesTracker.h" # import "SentryLog.h" # import "SentryMeasurementValue.h" +# import "SentryOptions+Private.h" # import "SentryProfilingConditionals.h" +# import "SentrySDK+Private.h" # import "SentrySpan.h" # import "SentrySpanContext.h" # import "SentrySpanId.h" From 12f039704b69767befb3c1f3def443bd2d638bf6 Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Wed, 15 May 2024 15:34:06 -0800 Subject: [PATCH 19/21] clean up launch profile state after each test --- SentryTestUtils/ClearTestState.swift | 1 + SentryTestUtils/SentryTestUtils-ObjC-BridgingHeader.h | 1 + 2 files changed, 2 insertions(+) diff --git a/SentryTestUtils/ClearTestState.swift b/SentryTestUtils/ClearTestState.swift index cd5b73a790..5852225b19 100644 --- a/SentryTestUtils/ClearTestState.swift +++ b/SentryTestUtils/ClearTestState.swift @@ -43,6 +43,7 @@ class TestCleanup: NSObject { SentryLegacyProfiler.resetConcurrencyTracking() SentryContinuousProfiler.stop() removeAppLaunchProfilingConfigFile() + sentry_stopAndDiscardLaunchProfileTracer() #endif // os(iOS) || os(macOS) || targetEnvironment(macCatalyst) #if os(iOS) || os(tvOS) || targetEnvironment(macCatalyst) diff --git a/SentryTestUtils/SentryTestUtils-ObjC-BridgingHeader.h b/SentryTestUtils/SentryTestUtils-ObjC-BridgingHeader.h index 7b017f8a46..a9197a8e94 100644 --- a/SentryTestUtils/SentryTestUtils-ObjC-BridgingHeader.h +++ b/SentryTestUtils/SentryTestUtils-ObjC-BridgingHeader.h @@ -18,6 +18,7 @@ #if SENTRY_TARGET_PROFILING_SUPPORTED # import "SentryContinuousProfiler.h" +# import "SentryLaunchProfiling.h" # import "SentryLegacyProfiler+Test.h" # import "SentryProfiler+Private.h" #endif // SENTRY_TARGET_PROFILING_SUPPORTED From 7eff3a3021c51285582b7502aefb4af629fcd7ff Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Wed, 15 May 2024 15:43:47 -0800 Subject: [PATCH 20/21] add test to ensure trace profiler is nil after stopping launch profiler --- SentryTestUtils/SentryLaunchProfiling+Tests.h | 5 ++++- Sources/Sentry/Profiling/SentryLaunchProfiling.m | 3 +-- .../SentryAppLaunchProfilingTests.swift | 15 ++++++++++++++- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/SentryTestUtils/SentryLaunchProfiling+Tests.h b/SentryTestUtils/SentryLaunchProfiling+Tests.h index 5a1f86a2b7..4403e65671 100644 --- a/SentryTestUtils/SentryLaunchProfiling+Tests.h +++ b/SentryTestUtils/SentryLaunchProfiling+Tests.h @@ -4,8 +4,9 @@ # import "SentryDefines.h" -@class SentrySamplerDecision; @class SentryOptions; +@class SentrySamplerDecision; +@class SentryTracer; NS_ASSUME_NONNULL_BEGIN @@ -19,6 +20,8 @@ SENTRY_EXTERN NSString *const kSentryLaunchProfileConfigKeyTracesSampleRate; SENTRY_EXTERN NSString *const kSentryLaunchProfileConfigKeyProfilesSampleRate; SENTRY_EXTERN NSString *const kSentryLaunchProfileConfigKeyContinuousProfiling; +SENTRY_EXTERN SentryTracer *_Nullable sentry_launchTracer; + SentryLaunchProfileConfig sentry_shouldProfileNextLaunch(SentryOptions *options); /** diff --git a/Sources/Sentry/Profiling/SentryLaunchProfiling.m b/Sources/Sentry/Profiling/SentryLaunchProfiling.m index a72973939e..61e6b4eebf 100644 --- a/Sources/Sentry/Profiling/SentryLaunchProfiling.m +++ b/Sources/Sentry/Profiling/SentryLaunchProfiling.m @@ -27,11 +27,10 @@ NSString *const kSentryLaunchProfileConfigKeyTracesSampleRate = @"traces"; NSString *const kSentryLaunchProfileConfigKeyProfilesSampleRate = @"profiles"; NSString *const kSentryLaunchProfileConfigKeyContinuousProfiling = @"continuous-profiling"; -static SentryTracer *_Nullable launchTracer; # pragma mark - Private -static SentryTracer *_Nullable sentry_launchTracer; +SentryTracer *_Nullable sentry_launchTracer; SentryTracerConfiguration * sentry_config(NSNumber *profilesRate) diff --git a/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift b/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift index 62d048072d..744fea0fa2 100644 --- a/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift +++ b/Tests/SentryProfilerTests/SentryAppLaunchProfilingTests.swift @@ -3,7 +3,7 @@ import XCTest #if os(iOS) || os(macOS) || targetEnvironment(macCatalyst) final class SentryAppLaunchProfilingSwiftTests: XCTestCase { - var fixture: SentryProfileTestFixture? + var fixture: SentryProfileTestFixture! override func setUp() { super.setUp() @@ -21,6 +21,19 @@ final class SentryAppLaunchProfilingSwiftTests: XCTestCase { XCTAssertEqual(context.origin, "auto.app.start.profile") XCTAssertEqual(context.sampled, .yes) } + + // test that the launch trace instance is nil after stopping the launch + // profiler + func testStopLaunchTraceProfile() { + fixture.options.enableAppLaunchProfiling = true + fixture.options.profilesSampleRate = 1 + fixture.options.tracesSampleRate = 1 + sentry_configureLaunchProfiling(fixture.options) + _sentry_nondeduplicated_startLaunchProfile() + XCTAssertNotNil(sentry_launchTracer) + sentry_manageTraceProfilerOnStartSDK(fixture.options, TestHub(client: nil, andScope: nil)) + XCTAssertNil(sentry_launchTracer) + } func testLaunchTraceProfileConfiguration() throws { let expectedProfilesSampleRate: NSNumber = 0.567 From 86b8815b45aaf8428ec5e4a7a2439b027424c78a Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Wed, 15 May 2024 16:54:41 -0800 Subject: [PATCH 21/21] remove comment after fixing the test situation --- Sources/Sentry/SentryProfiler.mm | 2 -- 1 file changed, 2 deletions(-) diff --git a/Sources/Sentry/SentryProfiler.mm b/Sources/Sentry/SentryProfiler.mm index 7f0a5c6a9e..a7e3a38867 100644 --- a/Sources/Sentry/SentryProfiler.mm +++ b/Sources/Sentry/SentryProfiler.mm @@ -157,8 +157,6 @@ - (void)backgroundAbort - (void)stopForReason:(SentryProfilerTruncationReason)reason { - // the following line makes unit tests pass, but ui tests fail because sentry_writeProfileFile - // needs it to be true to write to the correct path sentry_isTracingAppLaunch = NO; [_timeoutTimer invalidate]; [self.metricProfiler stop];