Skip to content

Commit

Permalink
Merge pull request #2141 from DataDog/release/2.21.0
Browse files Browse the repository at this point in the history
Release `2.21.0`

Co-authored-by: maxep <[email protected]>
Co-authored-by: dd-mergequeue[bot] <121105855+dd-mergequeue[bot]@users.noreply.github.com>
Co-authored-by: naftaly <[email protected]>
Co-authored-by: simaoseica-dd <[email protected]>
Co-authored-by: mariedm <[email protected]>
Co-authored-by: 0xnm <[email protected]>
Co-authored-by: xgouchet <[email protected]>
Co-authored-by: ncreated <[email protected]>
  • Loading branch information
8 people authored Dec 11, 2024
2 parents 2881108 + 2b3f960 commit f61d258
Show file tree
Hide file tree
Showing 117 changed files with 3,509 additions and 356 deletions.
6 changes: 4 additions & 2 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ Unit Tests (iOS):
script:
- ./tools/runner-setup.sh --xcode "$DEFAULT_XCODE"
- make clean repo-setup ENV=ci
- make test-ios-all OS="$DEFAULT_IOS_OS" PLATFORM="$PLATFORM" DEVICE="$DEVICE" USE_TEST_VISIBILITY=0
- make test-ios-all OS="$DEFAULT_IOS_OS" PLATFORM="$PLATFORM" DEVICE="$DEVICE" USE_TEST_VISIBILITY=1

Unit Tests (tvOS):
stage: test
Expand All @@ -116,7 +116,7 @@ Unit Tests (tvOS):
script:
- ./tools/runner-setup.sh --xcode "$DEFAULT_XCODE"
- make clean repo-setup ENV=ci
- make test-tvos-all OS="$DEFAULT_TVOS_OS" PLATFORM="$PLATFORM" DEVICE="$DEVICE" USE_TEST_VISIBILITY=0
- make test-tvos-all OS="$DEFAULT_TVOS_OS" PLATFORM="$PLATFORM" DEVICE="$DEVICE" USE_TEST_VISIBILITY=1

UI Tests:
stage: ui-test
Expand Down Expand Up @@ -359,6 +359,7 @@ Publish CP podspecs (dependent):
- !reference [.release-pipeline-20m-delayed-job, rules]
before_script:
- *export_MAKE_release_params
needs: ["Publish CP podspecs (internal)"]
script:
- ./tools/runner-setup.sh --xcode "$DEFAULT_XCODE"
- make env-check
Expand All @@ -371,6 +372,7 @@ Publish CP podspecs (legacy):
- !reference [.release-pipeline-40m-delayed-job, rules]
before_script:
- *export_MAKE_release_params
needs: ["Publish CP podspecs (dependent)"]
script:
- ./tools/runner-setup.sh --xcode "$DEFAULT_XCODE"
- make env-check
Expand Down
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Unreleased

# 2.21.0 / 11-12-2024

- [FIX] Fix sporadic file overwrite during consent change, ensuring event data integrity. See [#2113][]
- [FIX] Fix trace inconsistency when using `URLSessionInterceptor` or Alamofire extension. See [#2114][]
- [IMPROVEMENT] Add Session Replay `startRecordingImmediately` ObjC API. See [#2120][]
- [IMPROVEMENT] Expose Crash Reporter Plugin Publicly. See [#2116][] (Thanks [@naftaly][]) [#2126][]

# 2.20.0 / 14-11-2024

- [FIX] Fix race condition during consent change, preventing loss of events recorded on the current thread. See [#2063][]
Expand Down Expand Up @@ -794,6 +801,11 @@ Release `2.0` introduces breaking changes. Follow the [Migration Guide](MIGRATIO
[#2099]: https://github.com/DataDog/dd-sdk-ios/pull/2099
[#2063]: https://github.com/DataDog/dd-sdk-ios/pull/2063
[#2092]: https://github.com/DataDog/dd-sdk-ios/pull/2092
[#2113]: https://github.com/DataDog/dd-sdk-ios/pull/2113
[#2114]: https://github.com/DataDog/dd-sdk-ios/pull/2114
[#2116]: https://github.com/DataDog/dd-sdk-ios/pull/2116
[#2120]: https://github.com/DataDog/dd-sdk-ios/pull/2120
[#2126]: https://github.com/DataDog/dd-sdk-ios/pull/2126
[@00fa9a]: https://github.com/00FA9A
[@britton-earnin]: https://github.com/Britton-Earnin
[@hengyu]: https://github.com/Hengyu
Expand Down Expand Up @@ -826,3 +838,4 @@ Release `2.0` introduces breaking changes. Follow the [Migration Guide](MIGRATIO
[@changm4n]: https://github.com/changm4n
[@jfiser-paylocity]: https://github.com/jfiser-paylocity
[@Hengyu]: https://github.com/Hengyu
[@naftaly]: https://github.com/naftaly
104 changes: 103 additions & 1 deletion Datadog/Datadog.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import SwiftUI
import DatadogTrace
import DatadogInternal

@available(iOS 14, *)
internal class DebugManualTraceInjectionViewController: UIHostingController<DebugManualTraceInjectionView> {
Expand Down Expand Up @@ -42,7 +43,7 @@ internal struct DebugManualTraceInjectionView: View {
@State private var requestURL = "https://httpbin.org/get"
@State private var selectedTraceHeaderTypes: Set<TraceHeaderType> = [.datadog, .w3c]
@State private var selectedTraceContextInjection: TraceContextInjection = .all
@State private var sampleRate: Float = 100.0
@State private var sampleRate: SampleRate = .maxSampleRate
@State private var isRequestPending = false

private let session: URLSession = URLSession(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,16 @@ private class CrashReporterMock: CrashReportingPlugin {
internal var pendingCrashReport: DDCrashReport?
@ReadWriteLock
internal var injectedContext: Data? = nil
/// Custom backtrace reporter injected to the plugin.
var injectedBacktraceReporter: BacktraceReporting?

init(pendingCrashReport: DDCrashReport? = nil) {
self.pendingCrashReport = pendingCrashReport
}

func readPendingCrashReport(completion: (DDCrashReport?) -> Bool) { _ = completion(pendingCrashReport) }
func inject(context: Data) { injectedContext = context }
var backtraceReporter: BacktraceReporting? { injectedBacktraceReporter }
}

/// Covers broad scenarios of sending Crash Reports.
Expand All @@ -52,6 +55,7 @@ class SendingCrashReportTests: XCTestCase {
lastLogAttributes: .init(mockRandomAttributes())
)
let crashReport: DDCrashReport = .mockRandomWith(context: crashContext)
let crashReportAttributes: [String: Encodable] = try XCTUnwrap(crashReport.additionalAttributes.dd.decode())

// When
Logs.enable(with: .init(), in: core)
Expand All @@ -65,8 +69,8 @@ class SendingCrashReportTests: XCTestCase {
XCTAssertEqual(log.error?.message, crashReport.message)
XCTAssertEqual(log.error?.kind, crashReport.type)
XCTAssertEqual(log.error?.stack, crashReport.stack)
XCTAssertFalse(log.attributes.userAttributes.isEmpty)
DDAssertJSONEqual(log.attributes.userAttributes, crashContext.lastLogAttributes!)
let lastLogAttributes: [String: Encodable] = try XCTUnwrap(crashContext.lastLogAttributes.dd.decode())
DDAssertJSONEqual(log.attributes.userAttributes, lastLogAttributes.merging(crashReportAttributes) { $1 })
XCTAssertNotNil(log.attributes.internalAttributes?[DDError.threads])
XCTAssertNotNil(log.attributes.internalAttributes?[DDError.binaryImages])
XCTAssertNotNil(log.attributes.internalAttributes?[DDError.meta])
Expand All @@ -81,7 +85,9 @@ class SendingCrashReportTests: XCTestCase {
XCTAssertNotNil(rumEvent.error.binaryImages)
XCTAssertNotNil(rumEvent.error.meta)
XCTAssertNotNil(rumEvent.error.wasTruncated)
DDAssertJSONEqual(rumEvent.context!.contextInfo, crashContext.lastRUMAttributes!)
let contextAttributes = try XCTUnwrap(rumEvent.context?.contextInfo)
let lastRUMAttributes = try XCTUnwrap(crashContext.lastRUMAttributes?.attributes)
DDAssertJSONEqual(contextAttributes, lastRUMAttributes.merging(crashReportAttributes) { $1 })
}

func testWhenSendingCrashReportAsLog_itIsLinkedToTheRUMSessionThatHasCrashed() throws {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class CoreTelemetryIntegrationTests: XCTestCase {
func testGivenRUMEnabled_telemetryEventsAreSent() throws {
// Given
var config = RUM.Configuration(applicationID: .mockAny())
config.telemetrySampleRate = 100
config.telemetrySampleRate = .maxSampleRate
RUM.enable(with: config, in: core)

// When
Expand Down Expand Up @@ -68,7 +68,7 @@ class CoreTelemetryIntegrationTests: XCTestCase {
func testGivenRUMEnabled_whenNoViewIsActive_telemetryEventsAreLinkedToSession() throws {
// Given
var config = RUM.Configuration(applicationID: "rum-app-id")
config.telemetrySampleRate = 100
config.telemetrySampleRate = .maxSampleRate
RUM.enable(with: config, in: core)

// When
Expand Down Expand Up @@ -115,7 +115,7 @@ class CoreTelemetryIntegrationTests: XCTestCase {
func testGivenRUMEnabled_whenViewIsActive_telemetryEventsAreLinkedToView() throws {
// Given
var config = RUM.Configuration(applicationID: "rum-app-id")
config.telemetrySampleRate = 100
config.telemetrySampleRate = .maxSampleRate
RUM.enable(with: config, in: core)

// When
Expand Down Expand Up @@ -161,7 +161,7 @@ class CoreTelemetryIntegrationTests: XCTestCase {
func testGivenRUMEnabled_whenActionIsActive_telemetryEventsAreLinkedToAction() throws {
// Given
var config = RUM.Configuration(applicationID: "rum-app-id")
config.telemetrySampleRate = 100
config.telemetrySampleRate = .maxSampleRate
RUM.enable(with: config, in: core)

// When
Expand Down Expand Up @@ -204,4 +204,52 @@ class CoreTelemetryIntegrationTests: XCTestCase {
XCTAssertNotNil(methodCalledMetric.view?.id)
XCTAssertNotNil(methodCalledMetric.action?.id)
}

func testGivenRUMEnabled_effectiveSampleRateIsComposed() throws {
// Given
var config = RUM.Configuration(applicationID: .mockAny())
config.telemetrySampleRate = 90
RUM.enable(with: config, in: core)
let metricsSampleRate: SampleRate = 99
let headSampleRate: SampleRate = 80.0

// When
(0..<100).forEach { _ in
core.telemetry.debug("Debug Telemetry")
core.telemetry.error("Error Telemetry")
core.telemetry.metric(name: "Metric Name", attributes: [:], sampleRate: metricsSampleRate)
core.telemetry.send(telemetry: .usage(.init(event: .setUser, sampleRate: metricsSampleRate)))
core.telemetry.stopMethodCalled(
core.telemetry.startMethodCalled(operationName: .mockRandom(), callerClass: .mockRandom(), headSampleRate: headSampleRate),
tailSampleRate: metricsSampleRate
)
}

// Then
let debugEvents = core.waitAndReturnEvents(ofFeature: RUMFeature.name, ofType: TelemetryDebugEvent.self)
let errorEvents = core.waitAndReturnEvents(ofFeature: RUMFeature.name, ofType: TelemetryErrorEvent.self)
let usageEvents = core.waitAndReturnEvents(ofFeature: RUMFeature.name, ofType: TelemetryUsageEvent.self)

XCTAssertGreaterThan(debugEvents.count, 0)
XCTAssertGreaterThan(errorEvents.count, 0)
XCTAssertGreaterThan(usageEvents.count, 0)

let debug = try XCTUnwrap(debugEvents.first(where: { $0.telemetry.message == "Debug Telemetry" }))
XCTAssertEqual(debug.effectiveSampleRate, Int64(withNoOverflow: config.telemetrySampleRate))

let error = try XCTUnwrap(errorEvents.first(where: { $0.telemetry.message == "Error Telemetry" }))
XCTAssertEqual(error.effectiveSampleRate, Int64(withNoOverflow: config.telemetrySampleRate))

let mobileMetric = try XCTUnwrap(debugEvents.first(where: { $0.telemetry.message == "[Mobile Metric] Metric Name" }))
XCTAssertEqual(mobileMetric.effectiveSampleRate,
Int64(withNoOverflow: config.telemetrySampleRate.composed(with: metricsSampleRate)))

let methodCalledMetric = try XCTUnwrap(debugEvents.first(where: { $0.telemetry.message == "[Mobile Metric] Method Called" }))
XCTAssertEqual(methodCalledMetric.effectiveSampleRate,
Int64(withNoOverflow: config.telemetrySampleRate.composed(with: metricsSampleRate).composed(with: headSampleRate)))

let usage = try XCTUnwrap(usageEvents.first)
XCTAssertEqual(usage.effectiveSampleRate,
Int64(withNoOverflow: config.telemetrySampleRate.composed(with: metricsSampleRate)))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import XCTest
import TestUtilities
@testable import DatadogRUM
@testable import DatadogInternal

class RUMSessionEndedMetricIntegrationTests: XCTestCase {
private let dateProvider = DateProviderMock()
Expand All @@ -20,8 +21,7 @@ class RUMSessionEndedMetricIntegrationTests: XCTestCase {
applicationStateHistory: .mockAppInForeground(since: dateProvider.now)
)
rumConfig = RUM.Configuration(applicationID: .mockAny())
rumConfig.telemetrySampleRate = 100
rumConfig.sessionEndedMetricSampleRate = 100
rumConfig.telemetrySampleRate = .maxSampleRate
rumConfig.dateProvider = dateProvider
}

Expand All @@ -37,7 +37,7 @@ class RUMSessionEndedMetricIntegrationTests: XCTestCase {
RUM.enable(with: rumConfig, in: core)

// Given
let monitor = RUMMonitor.shared(in: core)
let monitor = self.rumMonitor()
monitor.startView(key: "key", name: "View")

// When
Expand All @@ -52,7 +52,7 @@ class RUMSessionEndedMetricIntegrationTests: XCTestCase {
RUM.enable(with: rumConfig, in: core)

// Given
let monitor = RUMMonitor.shared(in: core)
let monitor = self.rumMonitor()
monitor.startView(key: "key1", name: "View1")

// When
Expand All @@ -68,7 +68,7 @@ class RUMSessionEndedMetricIntegrationTests: XCTestCase {
RUM.enable(with: rumConfig, in: core)

// Given
let monitor = RUMMonitor.shared(in: core)
let monitor = self.rumMonitor()
monitor.startView(key: "key", name: "View")

// When
Expand All @@ -88,7 +88,7 @@ class RUMSessionEndedMetricIntegrationTests: XCTestCase {
RUM.enable(with: rumConfig, in: core)

// Given
let monitor = RUMMonitor.shared(in: core)
let monitor = self.rumMonitor()
monitor.startView(key: "key", name: "View")

// When
Expand All @@ -106,7 +106,7 @@ class RUMSessionEndedMetricIntegrationTests: XCTestCase {
RUM.enable(with: rumConfig, in: core)

// Given
let monitor = RUMMonitor.shared(in: core)
let monitor = self.rumMonitor()
monitor.startView(key: "key", name: "View")
monitor.currentSessionID { currentSessionID = $0 }
monitor.stopView(key: "key")
Expand All @@ -126,7 +126,7 @@ class RUMSessionEndedMetricIntegrationTests: XCTestCase {
RUM.enable(with: rumConfig, in: core)

// Given
let monitor = RUMMonitor.shared(in: core)
let monitor = self.rumMonitor()
dateProvider.now += 5.seconds
monitor.startView(key: "key1", name: "View1")
dateProvider.now += 5.seconds
Expand All @@ -150,7 +150,7 @@ class RUMSessionEndedMetricIntegrationTests: XCTestCase {
RUM.enable(with: rumConfig, in: core)

// Given
let monitor = RUMMonitor.shared(in: core)
let monitor = self.rumMonitor()
(0..<3).forEach { _ in
// Simulate app in foreground:
core.context = .mockWith(applicationStateHistory: .mockAppInForeground(since: dateProvider.now))
Expand Down Expand Up @@ -189,7 +189,7 @@ class RUMSessionEndedMetricIntegrationTests: XCTestCase {
RUM.enable(with: rumConfig, in: core)

// Given
let monitor = RUMMonitor.shared(in: core)
let monitor = self.rumMonitor()
monitor.startView(key: "key", name: "View")

core.flush()
Expand Down Expand Up @@ -222,7 +222,7 @@ class RUMSessionEndedMetricIntegrationTests: XCTestCase {
RUM.enable(with: rumConfig, in: core)

// Given
let monitor = RUMMonitor.shared(in: core)
let monitor = self.rumMonitor()
monitor.startView(key: "key", name: "View")

// When
Expand All @@ -240,7 +240,7 @@ class RUMSessionEndedMetricIntegrationTests: XCTestCase {
RUM.enable(with: rumConfig, in: core)

// Given
let monitor = RUMMonitor.shared(in: core)
let monitor = self.rumMonitor()
monitor.startView(key: "key", name: "View")
monitor.stopView(key: "key") // no active view

Expand All @@ -262,6 +262,17 @@ class RUMSessionEndedMetricIntegrationTests: XCTestCase {
}
}

private extension RUMSessionEndedMetricIntegrationTests {

func rumMonitor(with sessionEndedSampleRate: SampleRate = .maxSampleRate) -> RUMMonitorProtocol {

let monitor = RUMMonitor.shared(in: core)
monitor.dd.scopes.dependencies.sessionEndedMetric.sampleRate = sessionEndedSampleRate

return monitor
}
}

// MARK: - Helpers

private extension DatadogCoreProxy {
Expand Down
Loading

0 comments on commit f61d258

Please sign in to comment.