diff --git a/Sources/Datadog/Core/Utils/JSONEncoder.swift b/Sources/Datadog/Core/Utils/JSONEncoder.swift index ebb45e79bb..f6a2ae407b 100644 --- a/Sources/Datadog/Core/Utils/JSONEncoder.swift +++ b/Sources/Datadog/Core/Utils/JSONEncoder.swift @@ -15,25 +15,7 @@ extension JSONEncoder { try container.encode(formatted) } if #available(iOS 13.0, OSX 10.15, *) { - // NOTE: The `.sortedKeys` option was added in RUMM-776 after discovering an issue - // with backend processing of the RUM View payloads. The custom timings encoding for - // RUM views requires following structure: - // - // ``` - // { - // view: { /* serialized, auto-generated RUM view event */ }, - // view.custom_timings.: , - // view.custom_timings.: - // ... - // } - // ``` - // - // To guarantee proper backend-side processing, the `view.custom_timings` keys must be - // encoded after the `view` object. Using `.sortedKeys` enforces this order. - // - encoder.outputFormatting = [.withoutEscapingSlashes, .sortedKeys] - } else { - encoder.outputFormatting = [.sortedKeys] + encoder.outputFormatting = [.withoutEscapingSlashes] } return encoder } diff --git a/Sources/Datadog/RUM/DataModels/RUMDataModels.swift b/Sources/Datadog/RUM/DataModels/RUMDataModels.swift index 717c2c1a6a..83895fad2b 100644 --- a/Sources/Datadog/RUM/DataModels/RUMDataModels.swift +++ b/Sources/Datadog/RUM/DataModels/RUMDataModels.swift @@ -108,6 +108,9 @@ public struct RUMViewEvent: RUMDataModel { /// Total layout shift score that occured on the view public let cumulativeLayoutShift: Double? + /// User custom timings of the view. As timing name is used as facet path, it must contain only letters, digits, or the characters - _ . @ $ + public let customTimings: [String: Int64]? + /// Duration in ns to the complete parsing and loading of the document and its sub resources public let domComplete: Int64? @@ -150,6 +153,9 @@ public struct RUMViewEvent: RUMDataModel { /// Properties of the long tasks of the view public let longTask: LongTask? + /// User defined name of the view + public var name: String? + /// URL that linked to the initial view of the page public var referrer: String? @@ -166,6 +172,7 @@ public struct RUMViewEvent: RUMDataModel { case action = "action" case crash = "crash" case cumulativeLayoutShift = "cumulative_layout_shift" + case customTimings = "custom_timings" case domComplete = "dom_complete" case domContentLoaded = "dom_content_loaded" case domInteractive = "dom_interactive" @@ -180,6 +187,7 @@ public struct RUMViewEvent: RUMDataModel { case loadingTime = "loading_time" case loadingType = "loading_type" case longTask = "long_task" + case name = "name" case referrer = "referrer" case resource = "resource" case timeSpent = "time_spent" @@ -562,6 +570,9 @@ public struct RUMResourceEvent: RUMDataModel { /// UUID of the view public let id: String + /// User defined name of the view + public var name: String? + /// URL that linked to the initial view of the page public var referrer: String? @@ -570,6 +581,7 @@ public struct RUMResourceEvent: RUMDataModel { enum CodingKeys: String, CodingKey { case id = "id" + case name = "name" case referrer = "referrer" case url = "url" } @@ -769,6 +781,9 @@ public struct RUMActionEvent: RUMDataModel { /// UUID of the view public let id: String + /// User defined name of the view + public var name: String? + /// URL that linked to the initial view of the page public var referrer: String? @@ -777,6 +792,7 @@ public struct RUMActionEvent: RUMDataModel { enum CodingKeys: String, CodingKey { case id = "id" + case name = "name" case referrer = "referrer" case url = "url" } @@ -990,6 +1006,9 @@ public struct RUMErrorEvent: RUMDataModel { /// UUID of the view public let id: String + /// User defined name of the view + public var name: String? + /// URL that linked to the initial view of the page public var referrer: String? @@ -998,6 +1017,7 @@ public struct RUMErrorEvent: RUMDataModel { enum CodingKeys: String, CodingKey { case id = "id" + case name = "name" case referrer = "referrer" case url = "url" } @@ -1083,4 +1103,4 @@ public enum RUMMethod: String, Codable { case patch = "PATCH" } -// Generated from https://github.com/DataDog/rum-events-format/tree/8b955a03d0fe0b2f032a02d6800c61ef3fc9fada +// Generated from https://github.com/DataDog/rum-events-format/tree/a37c41a4ac1aa3bfdc8d1fcecb35e4d1e07adddc diff --git a/Sources/Datadog/RUM/RUMEvent/RUMEventBuilder.swift b/Sources/Datadog/RUM/RUMEvent/RUMEventBuilder.swift index eefbd566d6..8f1f5c9253 100644 --- a/Sources/Datadog/RUM/RUMEvent/RUMEventBuilder.swift +++ b/Sources/Datadog/RUM/RUMEvent/RUMEventBuilder.swift @@ -15,14 +15,12 @@ internal class RUMEventBuilder { func createRUMEvent( with model: DM, - attributes: [String: Encodable], - customTimings: [String: Int64]? = nil + attributes: [String: Encodable] ) -> RUMEvent { return RUMEvent( model: model, attributes: attributes, - userInfoAttributes: userInfoProvider.value.extraInfo, - customViewTimings: customTimings + userInfoAttributes: userInfoProvider.value.extraInfo ) } } diff --git a/Sources/Datadog/RUM/RUMEvent/RUMEventEncoder.swift b/Sources/Datadog/RUM/RUMEvent/RUMEventEncoder.swift index 1f1858d20e..b86630d4c7 100644 --- a/Sources/Datadog/RUM/RUMEvent/RUMEventEncoder.swift +++ b/Sources/Datadog/RUM/RUMEvent/RUMEventEncoder.swift @@ -16,9 +16,6 @@ internal struct RUMEvent: Encodable { var attributes: [String: Encodable] var userInfoAttributes: [String: Encodable] - /// Custom View timings (only available if `DM` is a RUM View model) - var customViewTimings: [String: Int64]? - func encode(to encoder: Encoder) throws { let sanitizedEvent = RUMEventSanitizer().sanitize(event: self) try RUMEventEncoder().encode(sanitizedEvent, to: encoder) @@ -45,9 +42,6 @@ internal struct RUMEventEncoder { try event.userInfoAttributes.forEach { attributeName, attributeValue in try attributesContainer.encode(EncodableValue(attributeValue), forKey: DynamicCodingKey("context.usr.\(attributeName)")) } - try event.customViewTimings?.forEach { timingName, timingDuration in - try attributesContainer.encode(timingDuration, forKey: DynamicCodingKey("view.custom_timings.\(timingName)")) - } // Encode `RUMDataModel` try event.model.encode(to: encoder) diff --git a/Sources/Datadog/RUM/RUMEvent/RUMEventSanitizer.swift b/Sources/Datadog/RUM/RUMEvent/RUMEventSanitizer.swift index 4f1cac7009..a94888b6b2 100644 --- a/Sources/Datadog/RUM/RUMEvent/RUMEventSanitizer.swift +++ b/Sources/Datadog/RUM/RUMEvent/RUMEventSanitizer.swift @@ -12,32 +12,24 @@ internal struct RUMEventSanitizer { func sanitize(event: RUMEvent) -> RUMEvent { // Sanitize attribute names - var sanitizedTimings = event.customViewTimings.flatMap { attributesSanitizer.sanitizeKeys(for: $0) } var sanitizedUserExtraInfo = attributesSanitizer.sanitizeKeys(for: event.userInfoAttributes) var sanitizedAttributes = attributesSanitizer.sanitizeKeys(for: event.attributes) // Limit to max number of attributes. // If any attributes need to be removed, we first reduce number of - // event attributes, then user info extra attributes, then custom timings. - sanitizedTimings = sanitizedTimings.flatMap { timings in - attributesSanitizer.limitNumberOf( - attributes: timings, - to: AttributesSanitizer.Constraints.maxNumberOfAttributes - ) - } + // event attributes, then user info extra attributes. sanitizedUserExtraInfo = attributesSanitizer.limitNumberOf( attributes: sanitizedUserExtraInfo, - to: AttributesSanitizer.Constraints.maxNumberOfAttributes - (sanitizedTimings?.count ?? 0) + to: AttributesSanitizer.Constraints.maxNumberOfAttributes ) sanitizedAttributes = attributesSanitizer.limitNumberOf( attributes: sanitizedAttributes, - to: AttributesSanitizer.Constraints.maxNumberOfAttributes - (sanitizedTimings?.count ?? 0) - sanitizedUserExtraInfo.count + to: AttributesSanitizer.Constraints.maxNumberOfAttributes - sanitizedUserExtraInfo.count ) var sanitizedEvent = event sanitizedEvent.attributes = sanitizedAttributes sanitizedEvent.userInfoAttributes = sanitizedUserExtraInfo - sanitizedEvent.customViewTimings = sanitizedTimings return sanitizedEvent } } diff --git a/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMViewScope.swift b/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMViewScope.swift index a94f399835..bd5903764c 100644 --- a/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMViewScope.swift +++ b/Sources/Datadog/RUM/RUMMonitor/Scopes/RUMViewScope.swift @@ -270,6 +270,7 @@ internal class RUMViewScope: RUMScope, RUMContextProvider { action: .init(count: actionsCount.toInt64), crash: nil, cumulativeLayoutShift: nil, + customTimings: customTimings, domComplete: nil, domContentLoaded: nil, domInteractive: nil, @@ -291,7 +292,7 @@ internal class RUMViewScope: RUMScope, RUMContextProvider { ) ) - let event = dependencies.eventBuilder.createRUMEvent(with: eventData, attributes: attributes, customTimings: customTimings) + let event = dependencies.eventBuilder.createRUMEvent(with: eventData, attributes: attributes) dependencies.eventOutput.write(rumEvent: event) } diff --git a/Sources/DatadogObjc/RUM/RUMDataModels+objc.swift b/Sources/DatadogObjc/RUM/RUMDataModels+objc.swift index 47133619fa..0bde95fa8d 100644 --- a/Sources/DatadogObjc/RUM/RUMDataModels+objc.swift +++ b/Sources/DatadogObjc/RUM/RUMDataModels+objc.swift @@ -271,6 +271,10 @@ public class DDRUMViewEventView: NSObject { root.swiftModel.view.cumulativeLayoutShift as NSNumber? } + @objc public var customTimings: [String: NSNumber]? { + root.swiftModel.view.customTimings as [String: NSNumber]? + } + @objc public var domComplete: NSNumber? { root.swiftModel.view.domComplete as NSNumber? } @@ -327,6 +331,11 @@ public class DDRUMViewEventView: NSObject { root.swiftModel.view.longTask != nil ? DDRUMViewEventViewLongTask(root: root) : nil } + @objc public var name: String? { + set { root.swiftModel.view.name = newValue } + get { root.swiftModel.view.name } + } + @objc public var referrer: String? { set { root.swiftModel.view.referrer = newValue } get { root.swiftModel.view.referrer } @@ -1056,6 +1065,11 @@ public class DDRUMResourceEventView: NSObject { root.swiftModel.view.id } + @objc public var name: String? { + set { root.swiftModel.view.name = newValue } + get { root.swiftModel.view.name } + } + @objc public var referrer: String? { set { root.swiftModel.view.referrer = newValue } get { root.swiftModel.view.referrer } @@ -1461,6 +1475,11 @@ public class DDRUMActionEventView: NSObject { root.swiftModel.view.id } + @objc public var name: String? { + set { root.swiftModel.view.name = newValue } + get { root.swiftModel.view.name } + } + @objc public var referrer: String? { set { root.swiftModel.view.referrer = newValue } get { root.swiftModel.view.referrer } @@ -1949,6 +1968,11 @@ public class DDRUMErrorEventView: NSObject { root.swiftModel.view.id } + @objc public var name: String? { + set { root.swiftModel.view.name = newValue } + get { root.swiftModel.view.name } + } + @objc public var referrer: String? { set { root.swiftModel.view.referrer = newValue } get { root.swiftModel.view.referrer } @@ -1962,4 +1986,4 @@ public class DDRUMErrorEventView: NSObject { // swiftlint:enable force_unwrapping -// Generated from https://github.com/DataDog/rum-events-format/tree/8b955a03d0fe0b2f032a02d6800c61ef3fc9fada +// Generated from https://github.com/DataDog/rum-events-format/tree/a37c41a4ac1aa3bfdc8d1fcecb35e4d1e07adddc diff --git a/Tests/DatadogBenchmarkTests/DataStorage/RUMStorageBenchmarkTests.swift b/Tests/DatadogBenchmarkTests/DataStorage/RUMStorageBenchmarkTests.swift index c9a6e6652b..5f57f35c38 100644 --- a/Tests/DatadogBenchmarkTests/DataStorage/RUMStorageBenchmarkTests.swift +++ b/Tests/DatadogBenchmarkTests/DataStorage/RUMStorageBenchmarkTests.swift @@ -99,6 +99,7 @@ class RUMStorageBenchmarkTests: XCTestCase { action: .init(count: .mockAny()), crash: .init(count: .mockAny()), cumulativeLayoutShift: nil, + customTimings: .mockAny(), domComplete: nil, domContentLoaded: nil, domInteractive: nil, @@ -120,8 +121,7 @@ class RUMStorageBenchmarkTests: XCTestCase { ) ), attributes: ["attribute": "value"], - userInfoAttributes: ["str": "value", "int": 11_235, "bool": true], - customViewTimings: nil + userInfoAttributes: ["str": "value", "int": 11_235, "bool": true] ) } } diff --git a/Tests/DatadogTests/Datadog/Core/Utils/JSONEncoderTests.swift b/Tests/DatadogTests/Datadog/Core/Utils/JSONEncoderTests.swift index dfa74a9df4..5e4fe43f8f 100644 --- a/Tests/DatadogTests/Datadog/Core/Utils/JSONEncoderTests.swift +++ b/Tests/DatadogTests/Datadog/Core/Utils/JSONEncoderTests.swift @@ -29,31 +29,4 @@ class JSONEncoderTests: XCTestCase { XCTAssertEqual(encodedURL.utf8String, #"{"value":"https:\/\/example.com\/foo"}"#) } } - - func testWhenEncoding_thenKeysFollowLexicographicOrder() throws { - struct Foo: Codable { - var one = 1 - var two = 1 - var three = 1 - var four = 1 - var five = 1 - - enum CodingKeys: String, CodingKey { - case one = "aaaaaa" - case two = "bb" - case three = "aaa" - case four = "bbb" - case five = "aaa.aaa" - } - } - - // When - let encodedFoo = try jsonEncoder.encode(Foo()) - - // Then - XCTAssertEqual( - encodedFoo.utf8String, - #"{"aaa":1,"aaa.aaa":1,"aaaaaa":1,"bb":1,"bbb":1}"# - ) - } } diff --git a/Tests/DatadogTests/Datadog/Mocks/RUMDataModelMocks.swift b/Tests/DatadogTests/Datadog/Mocks/RUMDataModelMocks.swift index 9a58bfc262..a0a15effb3 100644 --- a/Tests/DatadogTests/Datadog/Mocks/RUMDataModelMocks.swift +++ b/Tests/DatadogTests/Datadog/Mocks/RUMDataModelMocks.swift @@ -60,6 +60,7 @@ extension RUMViewEvent { action: .init(count: .mockRandom()), crash: .init(count: .mockRandom()), cumulativeLayoutShift: .mockRandom(), + customTimings: .mockAny(), domComplete: .mockRandom(), domContentLoaded: .mockRandom(), domInteractive: .mockRandom(), diff --git a/Tests/DatadogTests/Datadog/Mocks/RUMFeatureMocks.swift b/Tests/DatadogTests/Datadog/Mocks/RUMFeatureMocks.swift index 6e7ff86b73..7070bfcc18 100644 --- a/Tests/DatadogTests/Datadog/Mocks/RUMFeatureMocks.swift +++ b/Tests/DatadogTests/Datadog/Mocks/RUMFeatureMocks.swift @@ -88,14 +88,12 @@ extension RUMEvent { static func mockWith( model: DM, attributes: [String: Encodable] = [:], - userInfoAttributes: [String: Encodable] = [:], - customViewTimings: [String: Int64]? = nil + userInfoAttributes: [String: Encodable] = [:] ) -> RUMEvent { return RUMEvent( model: model, attributes: attributes, - userInfoAttributes: userInfoAttributes, - customViewTimings: customViewTimings + userInfoAttributes: userInfoAttributes ) } @@ -106,17 +104,10 @@ extension RUMEvent { return attributes } - func randomTimings() -> [String: Int64] { - var timings: [String: Int64] = [:] - (0..<10).forEach { index in timings["timing\(index)"] = .mockRandom() } - return timings - } - return RUMEvent( model: model, attributes: randomAttributes(prefixed: "event-attribute"), - userInfoAttributes: randomAttributes(prefixed: "user-attribute"), - customViewTimings: randomTimings() + userInfoAttributes: randomAttributes(prefixed: "user-attribute") ) } } @@ -502,13 +493,19 @@ extension RUMViewScope { return mockWith() } + static func randomTimings() -> [String: Int64] { + var timings: [String: Int64] = [:] + (0..<10).forEach { index in timings["timing\(index)"] = .mockRandom() } + return timings + } + static func mockWith( parent: RUMContextProvider = RUMContextProviderMock(), dependencies: RUMScopeDependencies = .mockAny(), identity: RUMViewIdentifiable = mockView, uri: String = .mockAny(), attributes: [AttributeKey: AttributeValue] = [:], - customTimings: [String: Int64] = [:], + customTimings: [String: Int64] = randomTimings(), startTime: Date = .mockAny() ) -> RUMViewScope { return RUMViewScope( diff --git a/Tests/DatadogTests/Datadog/Mocks/SystemFrameworks/FoundationMocks.swift b/Tests/DatadogTests/Datadog/Mocks/SystemFrameworks/FoundationMocks.swift index bd16b1f698..0a3f137434 100644 --- a/Tests/DatadogTests/Datadog/Mocks/SystemFrameworks/FoundationMocks.swift +++ b/Tests/DatadogTests/Datadog/Mocks/SystemFrameworks/FoundationMocks.swift @@ -33,7 +33,15 @@ import Foundation // MARK: - Basic types -extension Data { +protocol AnyMockable { + static func mockAny() -> Self +} + +protocol RandomMockable { + static func mockRandom() -> Self +} + +extension Data: AnyMockable { static func mockAny() -> Data { return Data() } @@ -71,7 +79,13 @@ extension Array { } } -extension Date { +extension Dictionary: AnyMockable where Key: AnyMockable, Value: AnyMockable { + static func mockAny() -> Dictionary { + return [Key.mockAny(): Value.mockAny()] + } +} + +extension Date: AnyMockable { static func mockAny() -> Date { return Date(timeIntervalSinceReferenceDate: 1) } @@ -99,7 +113,7 @@ extension Date { } } -extension TimeZone { +extension TimeZone: AnyMockable { static var UTC: TimeZone { TimeZone(abbreviation: "UTC")! } static var EET: TimeZone { TimeZone(abbreviation: "EET")! } static func mockAny() -> TimeZone { .EET } @@ -111,7 +125,7 @@ extension Calendar { } } -extension URL { +extension URL: AnyMockable, RandomMockable { static func mockAny() -> URL { return URL(string: "https://www.datadoghq.com")! } @@ -131,7 +145,7 @@ extension URL { } } -extension String { +extension String: AnyMockable { static func mockAny() -> String { return "abc" } @@ -153,36 +167,40 @@ extension String { } } -extension Int { +extension Int: AnyMockable { static func mockAny() -> Int { return 0 } } -extension Int64 { +extension Int64: AnyMockable, RandomMockable { static func mockAny() -> Int64 { 0 } static func mockRandom() -> Int64 { Int64.random(in: Int64.min.. UInt64 { return 0 } } -extension Bool { +extension Bool: AnyMockable { static func mockAny() -> Bool { return false } } -extension Float { +extension Float: AnyMockable { static func mockAny() -> Float { return 0 } } -extension Double { +extension Double: AnyMockable, RandomMockable { + static func mockAny() -> Float { + return 0 + } + static func mockRandom() -> Double { return Double.random(in: 0.. URLRequest { return URLRequest(url: .mockAny()) } diff --git a/Tests/DatadogTests/Datadog/RUM/RUMEvent/RUMEventSanitizerTests.swift b/Tests/DatadogTests/Datadog/RUM/RUMEvent/RUMEventSanitizerTests.swift index 749dc19cb7..8b2be3f279 100644 --- a/Tests/DatadogTests/Datadog/RUM/RUMEvent/RUMEventSanitizerTests.swift +++ b/Tests/DatadogTests/Datadog/RUM/RUMEvent/RUMEventSanitizerTests.swift @@ -44,20 +44,6 @@ class RUMEventSanitizerTests: XCTestCase { "user-info-one.two.three.four.five.six.seven.eight.nine.ten": mockValue(), "user-info-one.two.three.four.five.six.seven.eight.nine.ten.eleven": mockValue(), "user-info-one.two.three.four.five.six.seven.eight.nine.ten.eleven.twelve": mockValue(), - ], - customViewTimings: [ - "timing-one": .mockRandom(), - "timing-one.two": .mockRandom(), - "timing-one.two.three": .mockRandom(), - "timing-one.two.three.four": .mockRandom(), - "timing-one.two.three.four.five": .mockRandom(), - "timing-one.two.three.four.five.six": .mockRandom(), - "timing-one.two.three.four.five.six.seven": .mockRandom(), - "timing-one.two.three.four.five.six.seven.eight": .mockRandom(), - "timing-one.two.three.four.five.six.seven.eight.nine": .mockRandom(), - "timing-one.two.three.four.five.six.seven.eight.nine.ten": .mockRandom(), - "timing-one.two.three.four.five.six.seven.eight.nine.ten.eleven": .mockRandom(), - "timing-one.two.three.four.five.six.seven.eight.nine.ten.eleven.twelve": .mockRandom(), ] ) @@ -90,19 +76,6 @@ class RUMEventSanitizerTests: XCTestCase { XCTAssertNotNil(sanitized.userInfoAttributes["user-info-one.two.three.four.five.six.seven.eight_nine_ten"]) XCTAssertNotNil(sanitized.userInfoAttributes["user-info-one.two.three.four.five.six.seven.eight_nine_ten_eleven"]) XCTAssertNotNil(sanitized.userInfoAttributes["user-info-one.two.three.four.five.six.seven.eight_nine_ten_eleven_twelve"]) - - XCTAssertEqual(sanitized.customViewTimings?.count, 12) - XCTAssertNotNil(sanitized.customViewTimings?["timing-one"]) - XCTAssertNotNil(sanitized.customViewTimings?["timing-one.two"]) - XCTAssertNotNil(sanitized.customViewTimings?["timing-one.two.three"]) - XCTAssertNotNil(sanitized.customViewTimings?["timing-one.two.three.four"]) - XCTAssertNotNil(sanitized.customViewTimings?["timing-one.two.three.four.five"]) - XCTAssertNotNil(sanitized.customViewTimings?["timing-one.two.three.four.five.six"]) - XCTAssertNotNil(sanitized.customViewTimings?["timing-one.two.three.four.five.six.seven"]) - XCTAssertNotNil(sanitized.customViewTimings?["timing-one.two.three.four.five.six.seven.eight"]) - XCTAssertNotNil(sanitized.customViewTimings?["timing-one.two.three.four.five.six.seven.eight_nine_ten"]) - XCTAssertNotNil(sanitized.customViewTimings?["timing-one.two.three.four.five.six.seven.eight_nine_ten_eleven"]) - XCTAssertNotNil(sanitized.customViewTimings?["timing-one.two.three.four.five.six.seven.eight_nine_ten_eleven_twelve"]) } test(model: viewEvent) @@ -113,12 +86,11 @@ class RUMEventSanitizerTests: XCTestCase { func testWhenNumberOfAttributesExceedsLimit_itDropsExtraOnes() { func test(model: DM) { - let oneThirdOfTheLimit = Int(Double(AttributesSanitizer.Constraints.maxNumberOfAttributes) * 0.34) - let tripleTheLimit = AttributesSanitizer.Constraints.maxNumberOfAttributes * 3 + let oneHalfOfTheLimit = Int(Double(AttributesSanitizer.Constraints.maxNumberOfAttributes) * 0.5) + let twiceTheLimit = AttributesSanitizer.Constraints.maxNumberOfAttributes * 2 - let numberOfAttributes: Int = .random(in: oneThirdOfTheLimit...tripleTheLimit) - let numberOfUserInfoAttributes: Int = .random(in: oneThirdOfTheLimit...tripleTheLimit) - let numberOfTimings: Int = .random(in: oneThirdOfTheLimit...tripleTheLimit) + let numberOfAttributes: Int = .random(in: oneHalfOfTheLimit...twiceTheLimit) + let numberOfUserInfoAttributes: Int = .random(in: oneHalfOfTheLimit...twiceTheLimit) let mockAttributes = (0..( model: model, attributes: Dictionary(uniqueKeysWithValues: mockAttributes), - userInfoAttributes: Dictionary(uniqueKeysWithValues: mockUserInfoAttributes), - customViewTimings: Dictionary(uniqueKeysWithValues: mockTimings) + userInfoAttributes: Dictionary(uniqueKeysWithValues: mockUserInfoAttributes) ) // When @@ -142,15 +110,12 @@ class RUMEventSanitizerTests: XCTestCase { // Then var remaining = AttributesSanitizer.Constraints.maxNumberOfAttributes - let expectedSanitizedCustomTimings = min(sanitized.customViewTimings!.count, remaining) - remaining -= expectedSanitizedCustomTimings let expectedSanitizedUserInfo = min(sanitized.userInfoAttributes.count, remaining) remaining -= expectedSanitizedUserInfo let expectedSanitizedAttrs = min(sanitized.attributes.count, remaining) remaining -= expectedSanitizedAttrs XCTAssertGreaterThanOrEqual(remaining, 0) - XCTAssertEqual(sanitized.customViewTimings!.count, expectedSanitizedCustomTimings, "If number of attributes needs to be limited, `customViewTimings` are removed last") XCTAssertEqual(sanitized.userInfoAttributes.count, expectedSanitizedUserInfo, "If number of attributes needs to be limited, `userInfoAttributes` are removed second") XCTAssertEqual(sanitized.attributes.count, expectedSanitizedAttrs, "If number of attributes needs to be limited, `attributes` are removed first.") } diff --git a/Tests/DatadogTests/Datadog/RUM/RUMMonitor/Scopes/RUMViewScopeTests.swift b/Tests/DatadogTests/Datadog/RUM/RUMMonitor/Scopes/RUMViewScopeTests.swift index 35a485fade..45581d22fe 100644 --- a/Tests/DatadogTests/Datadog/RUM/RUMMonitor/Scopes/RUMViewScopeTests.swift +++ b/Tests/DatadogTests/Datadog/RUM/RUMMonitor/Scopes/RUMViewScopeTests.swift @@ -607,13 +607,13 @@ class RUMViewScopeTests: XCTestCase { let events = try XCTUnwrap(output.recordedEvents(ofType: RUMEvent.self)) XCTAssertEqual(events.count, 3, "There should be 3 View updates sent") - XCTAssertEqual(events[0].customViewTimings, [:]) + XCTAssertEqual(events[0].model.view.customTimings, [:]) XCTAssertEqual( - events[1].customViewTimings, + events[1].model.view.customTimings, ["timing-after-500000000ns": 500_000_000] ) XCTAssertEqual( - events[2].customViewTimings, + events[2].model.view.customTimings, ["timing-after-500000000ns": 500_000_000, "timing-after-1000000000ns": 1_000_000_000] ) } @@ -648,7 +648,7 @@ class RUMViewScopeTests: XCTestCase { // Then let lastEvent = try XCTUnwrap(output.recordedEvents(ofType: RUMEvent.self).last) - XCTAssertEqual(lastEvent.customViewTimings, [:]) + XCTAssertEqual(lastEvent.model.view.customTimings, [:]) } // MARK: - Dates Correction diff --git a/Tests/DatadogTests/Datadog/RUM/Scrubbing/RUMEventsMapperTests.swift b/Tests/DatadogTests/Datadog/RUM/Scrubbing/RUMEventsMapperTests.swift index eaf5f485cf..4260ddf6bd 100644 --- a/Tests/DatadogTests/Datadog/RUM/Scrubbing/RUMEventsMapperTests.swift +++ b/Tests/DatadogTests/Datadog/RUM/Scrubbing/RUMEventsMapperTests.swift @@ -76,19 +76,15 @@ class RUMEventsMapperTests: XCTestCase { // Then XCTAssertEqual(rumEvent1.attributes as! [String: String], mappedRUMEvent1.attributes as! [String: String]) XCTAssertEqual(rumEvent1.userInfoAttributes as! [String: String], mappedRUMEvent1.userInfoAttributes as! [String: String]) - XCTAssertEqual(rumEvent1.customViewTimings, mappedRUMEvent1.customViewTimings) XCTAssertEqual(rumEvent2.attributes as! [String: String], mappedRUMEvent2.attributes as! [String: String]) XCTAssertEqual(rumEvent2.userInfoAttributes as! [String: String], mappedRUMEvent2.userInfoAttributes as! [String: String]) - XCTAssertEqual(rumEvent2.customViewTimings, mappedRUMEvent2.customViewTimings) XCTAssertEqual(rumEvent3.attributes as! [String: String], mappedRUMEvent3.attributes as! [String: String]) XCTAssertEqual(rumEvent3.userInfoAttributes as! [String: String], mappedRUMEvent3.userInfoAttributes as! [String: String]) - XCTAssertEqual(rumEvent3.customViewTimings, mappedRUMEvent3.customViewTimings) XCTAssertEqual(rumEvent4.attributes as! [String: String], mappedRUMEvent4.attributes as! [String: String]) XCTAssertEqual(rumEvent4.userInfoAttributes as! [String: String], mappedRUMEvent4.userInfoAttributes as! [String: String]) - XCTAssertEqual(rumEvent4.customViewTimings, mappedRUMEvent4.customViewTimings) } func testGivenMappersEnabled_whenDroppingEvents_itReturnsNil() { diff --git a/Tests/DatadogTests/Datadog/TracerTests.swift b/Tests/DatadogTests/Datadog/TracerTests.swift index 0255a3d1fb..bb3e35eef1 100644 --- a/Tests/DatadogTests/Datadog/TracerTests.swift +++ b/Tests/DatadogTests/Datadog/TracerTests.swift @@ -583,7 +583,7 @@ class TracerTests: XCTestCase { ) XCTAssertEqual( try spanMatcher.meta.custom(keyPath: "meta.person"), - #"{"age":30,"name":"Adam","nationality":"Polish"}"# + #"{"name":"Adam","age":30,"nationality":"Polish"}"# ) XCTAssertEqual(try spanMatcher.meta.custom(keyPath: "meta.nested.string"), "hello") XCTAssertEqual(try spanMatcher.meta.custom(keyPath: "meta.url"), "https://example.com/image.png") diff --git a/tools/rum-models-generator/Sources/RUMModelsGeneratorCore/RUM/RUMSwiftTypeTransformer.swift b/tools/rum-models-generator/Sources/RUMModelsGeneratorCore/RUM/RUMSwiftTypeTransformer.swift index d6a2928ee0..62a1a83c3a 100644 --- a/tools/rum-models-generator/Sources/RUMModelsGeneratorCore/RUM/RUMSwiftTypeTransformer.swift +++ b/tools/rum-models-generator/Sources/RUMModelsGeneratorCore/RUM/RUMSwiftTypeTransformer.swift @@ -104,8 +104,6 @@ internal class RUMSwiftTypeTransformer: TypeTransformer { `struct`.name = format(structName: `struct`.name) `struct`.properties = try `struct`.properties .map { try transform(structProperty: $0) } - // TODO: RUMM-1000 should remove this filter - .filter { property in property.name != "customTimings" } if context.parent == nil { `struct`.conformance = [rumDataModelProtocol] // Conform root structs to `RUMDataModel` } else {