Skip to content

Commit

Permalink
Merge pull request #1899 from DataDog/release/2.13.0
Browse files Browse the repository at this point in the history
Release 2.13.0
  • Loading branch information
maciejburda authored Jun 13, 2024
2 parents 7309e5b + 602f8e8 commit a1bcf3d
Show file tree
Hide file tree
Showing 203 changed files with 4,042 additions and 1,065 deletions.
11 changes: 10 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Unreleased

# 2.13.0 / 13-06-2024

- [IMPROVEMENT] Bump `IPHONEOS_DEPLOYMENT_TARGET` and `TVOS_DEPLOYMENT_TARGET` from 11 to 12. See [#1891][]
- [IMPROVEMENT] Add `.connect`, `.trace`, `.options` values to `DDRUMMethod` type. See [#1886][]
- [FIX] Fix compilation issues on Xcode 16 beta. See [#1898][]

# 2.12.0 / 03-06-2024

- [IMPROVEMENT] Crash errors now include up-to-date global RUM attributes. See [#1834][]
Expand Down Expand Up @@ -666,6 +672,7 @@ Release `2.0` introduces breaking changes. Follow the [Migration Guide](MIGRATIO
[#1767]: https://github.com/DataDog/dd-sdk-ios/pull/1767
[#1843]: https://github.com/DataDog/dd-sdk-ios/pull/1843
[#1798]: https://github.com/DataDog/dd-sdk-ios/pull/1798
[#1891]: https://github.com/DataDog/dd-sdk-ios/pull/1891
[#1776]: https://github.com/DataDog/dd-sdk-ios/pull/1776
[#1834]: https://github.com/DataDog/dd-sdk-ios/pull/1834
[#1721]: https://github.com/DataDog/dd-sdk-ios/pull/1721
Expand All @@ -675,6 +682,8 @@ Release `2.0` introduces breaking changes. Follow the [Migration Guide](MIGRATIO
[#1854]: https://github.com/DataDog/dd-sdk-ios/pull/1854
[#1828]: https://github.com/DataDog/dd-sdk-ios/pull/1828
[#1835]: https://github.com/DataDog/dd-sdk-ios/pull/1835
[#1886]: https://github.com/DataDog/dd-sdk-ios/pull/1886
[#1898]: https://github.com/DataDog/dd-sdk-ios/pull/1898
[@00fa9a]: https://github.com/00FA9A
[@britton-earnin]: https://github.com/Britton-Earnin
[@hengyu]: https://github.com/Hengyu
Expand Down Expand Up @@ -704,4 +713,4 @@ Release `2.0` introduces breaking changes. Follow the [Migration Guide](MIGRATIO
[@dfed]: https://github.com/dfed
[@cltnschlosser]: https://github.com/cltnschlosser
[@alexfanatics]: https://github.com/alexfanatics
[@changm4n]: https://github.com/changm4n
[@changm4n]: https://github.com/changm4n
227 changes: 101 additions & 126 deletions Datadog/Datadog.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,9 @@
<Test
Identifier = "DatadogTracer_SamplingTests/testWhenRootSpanIsSampled_thenAllChildSpansMustBeSampledTheSameWay()">
</Test>
<Test
Identifier = "OTelSpanTests/testSetActive_givenParentSpan()">
</Test>
</SkippedTests>
</TestableReference>
<TestableReference
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,11 @@
BlueprintName = "DatadogTraceTests tvOS"
ReferencedContainer = "container:Datadog.xcodeproj">
</BuildableReference>
<SkippedTests>
<Test
Identifier = "OTelSpanTests/testSetActive_givenParentSpan()">
</Test>
</SkippedTests>
</TestableReference>
<TestableReference
skipped = "NO">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class CoreTelemetryIntegrationTests: XCTestCase {
core = nil
}

func testGivenRUMEnabled_telemetryEventsAreSent() {
func testGivenRUMEnabled_telemetryEventsAreSent() throws {
// Given
var config = RUM.Configuration(applicationID: .mockAny())
config.telemetrySampleRate = 100
Expand Down Expand Up @@ -57,7 +57,9 @@ class CoreTelemetryIntegrationTests: XCTestCase {

let metric = debugEvents[1]
XCTAssertEqual(metric.telemetry.message, "[Mobile Metric] Metric Name")
DDAssertReflectionEqual(metric.telemetry.telemetryInfo, ["metric.attribute": 42])

let metricAttribute = try XCTUnwrap(metric.telemetry.telemetryInfo["metric.attribute"] as? Int)
XCTAssertEqual(metricAttribute, 42)

let methodCalledMetric = debugEvents[2]
XCTAssertEqual(methodCalledMetric.telemetry.message, "[Mobile Metric] Method Called")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ class WebLogIntegrationTests: XCTestCase {
hosts: [],
hostsSanitizer: HostsSanitizer(),
logsSampleRate: 100,
sessionReplayConfiguration: nil,
in: core
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
/*
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
* This product includes software developed at Datadog (https://www.datadoghq.com/).
* Copyright 2019-Present Datadog, Inc.
*/

import XCTest
import TestUtilities
@testable import DatadogRUM

class RUMSessionEndedMetricIntegrationTests: XCTestCase {
private let dateProvider = DateProviderMock()
private var core: DatadogCoreProxy! // swiftlint:disable:this implicitly_unwrapped_optional
private var rumConfig: RUM.Configuration! // swiftlint:disable:this implicitly_unwrapped_optional

override func setUp() {
core = DatadogCoreProxy()
core.context = .mockWith(
launchTime: .mockWith(launchDate: dateProvider.now),
applicationStateHistory: .mockAppInForeground(since: dateProvider.now)
)
rumConfig = RUM.Configuration(applicationID: .mockAny())
rumConfig.telemetrySampleRate = 100
rumConfig.metricsTelemetrySampleRate = 100
rumConfig.dateProvider = dateProvider
}

override func tearDown() {
core.flushAndTearDown()
core = nil
rumConfig = nil
}

// MARK: - Conditions For Sending The Metric

func testWhenSessionEndsWithStopAPI() throws {
RUM.enable(with: rumConfig, in: core)

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

// When
monitor.stopSession()

// Then
let metricAttributes = try XCTUnwrap(core.waitAndReturnSessionEndedMetricEvent()?.attributes)
XCTAssertTrue(metricAttributes.wasStopped)
}

func testWhenSessionEndsDueToInactivityTimeout() throws {
RUM.enable(with: rumConfig, in: core)

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

// When
dateProvider.now += RUMSessionScope.Constants.sessionTimeoutDuration + 1.seconds
monitor.startView(key: "key2", name: "View2")

// Then
let metricAttributes = try XCTUnwrap(core.waitAndReturnSessionEndedMetricEvent()?.attributes)
XCTAssertFalse(metricAttributes.wasStopped)
}

func testWhenSessionReachesMaxDuration() throws {
RUM.enable(with: rumConfig, in: core)

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

// When
let deadline = dateProvider.now + RUMSessionScope.Constants.sessionMaxDuration * 1.5
while dateProvider.now < deadline {
monitor.addAction(type: .custom, name: "action")
dateProvider.now += RUMSessionScope.Constants.sessionTimeoutDuration - 1.seconds
}

// Then
let metricAttributes = try XCTUnwrap(core.waitAndReturnSessionEndedMetricEvent()?.attributes)
XCTAssertFalse(metricAttributes.wasStopped)
}

func testWhenSessionIsNotSampled_thenMetricIsNotSent() throws {
rumConfig.sessionSampleRate = 0
RUM.enable(with: rumConfig, in: core)

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

// When
monitor.stopSession()

// Then
let events = core.waitAndReturnEventsData(ofFeature: RUMFeature.name, timeout: .now() + 0.5)
XCTAssertTrue(events.isEmpty)
}

// MARK: - Reporting Session Attributes

func testReportingSessionID() throws {
var currentSessionID: String?
RUM.enable(with: rumConfig, in: core)

// Given
let monitor = RUMMonitor.shared(in: core)
monitor.startView(key: "key", name: "View")
monitor.currentSessionID { currentSessionID = $0 }
monitor.stopView(key: "key")

// When
monitor.stopSession()

// Then
let metric = try XCTUnwrap(core.waitAndReturnSessionEndedMetricEvent())
let expectedSessionID = try XCTUnwrap(currentSessionID)
XCTAssertEqual(metric.session?.id, expectedSessionID.lowercased())
}

func testTrackingSessionDuration() throws {
let startTime = dateProvider.now
RUM.enable(with: rumConfig, in: core)

// Given
let monitor = RUMMonitor.shared(in: core)
dateProvider.now += 5.seconds
monitor.startView(key: "key1", name: "View1")
dateProvider.now += 5.seconds
monitor.startView(key: "key2", name: "View2")
dateProvider.now += 5.seconds
monitor.startView(key: "key3", name: "View3")
dateProvider.now += 5.seconds
monitor.stopView(key: "key3")

// When
monitor.stopSession()

// Then
let expectedDuration = dateProvider.now.timeIntervalSince(startTime)
let metricAttributes = try XCTUnwrap(core.waitAndReturnSessionEndedMetricEvent()?.attributes)
XCTAssertEqual(metricAttributes.duration, expectedDuration.toInt64Nanoseconds)
}

func testTrackingViewsCount() throws {
rumConfig.trackBackgroundEvents = true // enable tracking "Background" view
RUM.enable(with: rumConfig, in: core)

// Given
let monitor = RUMMonitor.shared(in: core)
(0..<3).forEach { _ in
// Simulate app in foreground:
core.context = .mockWith(applicationStateHistory: .mockAppInForeground(since: dateProvider.now))

// Track 2 distinct views:
dateProvider.now += 5.seconds
monitor.startView(key: "key1", name: "View1")
dateProvider.now += 5.seconds
monitor.startView(key: "key2", name: "View2")
dateProvider.now += 5.seconds
monitor.stopView(key: "key2")

// Simulate app in background:
core.context = .mockWith(applicationStateHistory: .mockAppInBackground(since: dateProvider.now))

// Track resource without view:
dateProvider.now += 1.seconds
monitor.startResource(resourceKey: "resource", url: .mockAny())
dateProvider.now += 1.seconds
monitor.stopResource(resourceKey: "resource", response: .mockAny())
}

// When
monitor.stopSession()

// Then
let metricAttributes = try XCTUnwrap(core.waitAndReturnSessionEndedMetricEvent()?.attributes)
XCTAssertEqual(metricAttributes.viewsCount.total, 10)
XCTAssertEqual(metricAttributes.viewsCount.applicationLaunch, 1)
XCTAssertEqual(metricAttributes.viewsCount.background, 3)
}

func testTrackingSDKErrors() throws {
RUM.enable(with: rumConfig, in: core)

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

core.flush()
(0..<9).forEach { _ in core.telemetry.error(id: "id1", message: .mockAny(), kind: "kind1", stack: .mockAny()) }
(0..<8).forEach { _ in core.telemetry.error(id: "id2", message: .mockAny(), kind: "kind2", stack: .mockAny()) }
(0..<7).forEach { _ in core.telemetry.error(id: "id3", message: .mockAny(), kind: "kind3", stack: .mockAny()) }
(0..<6).forEach { _ in core.telemetry.error(id: "id4", message: .mockAny(), kind: "kind4", stack: .mockAny()) }
(0..<5).forEach { _ in core.telemetry.error(id: "id5", message: .mockAny(), kind: "kind5", stack: .mockAny()) }
(0..<4).forEach { _ in core.telemetry.error(id: "id6", message: .mockAny(), kind: "kind6", stack: .mockAny()) }
core.flush()

// When
monitor.stopSession()

// Then
let metricAttributes = try XCTUnwrap(core.waitAndReturnSessionEndedMetricEvent()?.attributes)
XCTAssertEqual(metricAttributes.sdkErrorsCount.total, 39, "It should count all SDK errors")
XCTAssertEqual(
metricAttributes.sdkErrorsCount.byKind,
["kind1": 9, "kind2": 8, "kind3": 7, "kind4": 6, "kind5": 5],
"It should report TOP 5 error kinds"
)
}
}

// MARK: - Helpers

private extension DatadogCoreProxy {
func waitAndReturnSessionEndedMetricEvent() -> TelemetryDebugEvent? {
let events = waitAndReturnEvents(ofFeature: RUMFeature.name, ofType: TelemetryDebugEvent.self)
return events.first(where: { $0.telemetry.message == "[Mobile Metric] \(SessionEndedMetric.Constants.name)" })
}
}

private extension TelemetryDebugEvent {
var attributes: SessionEndedMetric.Attributes? {
return telemetry.telemetryInfo[SessionEndedMetric.Constants.rseKey] as? SessionEndedMetric.Attributes
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ class WebEventIntegrationTests: XCTestCase {
hosts: [],
hostsSanitizer: HostsSanitizer(),
logsSampleRate: 100,
sessionReplayConfiguration: nil,
in: core
)
}
Expand Down
8 changes: 4 additions & 4 deletions DatadogAlamofireExtension.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "DatadogAlamofireExtension"
s.version = "2.12.0"
s.version = "2.13.0"
s.summary = "An Official Extensions of Datadog Swift SDK for Alamofire."

s.homepage = "https://www.datadoghq.com"
Expand All @@ -14,9 +14,9 @@ Pod::Spec.new do |s|
"Maciej Burda" => "maciej.burda@datadoghq.com"
}

s.swift_version = '5.7.1'
s.ios.deployment_target = '11.0'
s.tvos.deployment_target = '11.0'
s.swift_version = '5.9'
s.ios.deployment_target = '12.0'
s.tvos.deployment_target = '12.0'

s.source = { :git => "https://github.com/DataDog/dd-sdk-ios.git", :tag => s.version.to_s }

Expand Down
8 changes: 4 additions & 4 deletions DatadogCore.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "DatadogCore"
s.version = "2.12.0"
s.version = "2.13.0"
s.summary = "Official Datadog Swift SDK for iOS."

s.homepage = "https://www.datadoghq.com"
Expand All @@ -14,9 +14,9 @@ Pod::Spec.new do |s|
"Maciej Burda" => "maciej.burda@datadoghq.com"
}

s.swift_version = '5.7.1'
s.ios.deployment_target = '11.0'
s.tvos.deployment_target = '11.0'
s.swift_version = '5.9'
s.ios.deployment_target = '12.0'
s.tvos.deployment_target = '12.0'

s.source = { :git => "https://github.com/DataDog/dd-sdk-ios.git", :tag => s.version.to_s }

Expand Down
Loading

0 comments on commit a1bcf3d

Please sign in to comment.