Skip to content

Commit bfe9951

Browse files
authored
[SDTEST-3738] Added framework versions (#234)
1 parent 49796c4 commit bfe9951

12 files changed

Lines changed: 65 additions & 29 deletions

Sources/DatadogSDKTesting/DDTags.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ internal enum DDTestTags {
6767
static let testSkippedByITR = "test.skipped_by_itr"
6868
static let testHasFailedAllRetries = "test.has_failed_all_retries"
6969
static let testFailureSuppressionReason = "test.failure_suppression_reason"
70-
70+
static let testFrameworkVersion = "test.framework_version"
7171
}
7272

7373
internal enum DDHostTags {

Sources/DatadogSDKTesting/DDTest.swift

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ extension Test {
143143
_ action: @Sendable (Test) async throws -> T) async rethrows -> T
144144
{
145145
let testStartTime = start ?? suite.configuration.clock.now
146-
return try await DDTestMonitor.tracer.withActiveSpan(name: "\(suite.testFramework).test",
146+
return try await DDTestMonitor.tracer.withActiveSpan(name: "\(suite.testFramework.name).test",
147147
attributes: attributes(test: name, in: suite),
148148
startTime: testStartTime) { span in
149149
let test = Self(name: name, suite: suite, span: span)
@@ -159,7 +159,7 @@ extension Test {
159159
_ action: (Test) throws -> T) rethrows -> T
160160
{
161161
let testStartTime = start ?? suite.configuration.clock.now
162-
return try DDTestMonitor.tracer.withActiveSpan(name: "\(suite.testFramework).test",
162+
return try DDTestMonitor.tracer.withActiveSpan(name: "\(suite.testFramework.name).test",
163163
attributes: attributes(test: name, in: suite),
164164
startTime: testStartTime) { span in
165165
let test = Self(name: name, suite: suite, span: span)
@@ -178,7 +178,8 @@ extension Test {
178178
DDTestTags.testName: .string(name),
179179
DDTestTags.testSuite: .string(suite.name),
180180
DDTestTags.testModule: .string(suite.module.name),
181-
DDTestTags.testFramework: .string(suite.testFramework),
181+
DDTestTags.testFramework: .string(suite.testFramework.name),
182+
DDTestTags.testFrameworkVersion: .string(suite.testFramework.version),
182183
DDTestTags.testType: .string(DDTagValues.typeTest),
183184
DDTestTags.testIsUITest: .string("false"),
184185
DDTestSuiteVisibilityTags.testSessionId: .string(suite.session.id.hexString),

Sources/DatadogSDKTesting/DDTestModule.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ public extension Module {
113113
/// - name: name of the suite
114114
/// - startTime: Optional, the time where the suite started
115115
@objc func suiteStart(name: String, startTime: Date? = nil) -> Suite {
116-
startSuite(named: name, at: startTime, framework: "SwiftManual") as! Suite
116+
startSuite(named: name, at: startTime, framework: .init(name: "SwiftManual", version: "0.0.0")) as! Suite
117117
}
118118

119119
@objc func suiteStart(name: String) -> Suite {
@@ -159,8 +159,8 @@ extension Module: TestModule {
159159
}
160160

161161
extension Module: TestSuiteProvider {
162-
func startSuite(named name: String, at start: Date?, framework: String) -> any TestRunProvider & TestSuite {
163-
addFramework(framework)
162+
func startSuite(named name: String, at start: Date?, framework: TestFramework) -> any TestRunProvider & TestSuite {
163+
addFramework(framework.name)
164164
return Suite(name: name, module: self, framework: framework, startTime: start)
165165
}
166166
}

Sources/DatadogSDKTesting/DDTestSuite.swift

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public final class Suite: NSObject, Encodable {
1818

1919
public let name: String
2020
public let startTime: Date
21-
public let testFramework: String
21+
public let testFramework: TestFramework
2222
public let localization: String
2323

2424
var duration: UInt64 { _state.value.duration }
@@ -33,7 +33,7 @@ public final class Suite: NSObject, Encodable {
3333
private let _module: Module
3434
private let _state: Synced<MutableState>
3535

36-
init(name: String, module: Module, framework: String, startTime: Date? = nil) {
36+
init(name: String, module: Module, framework: TestFramework, startTime: Date? = nil) {
3737
self.name = name
3838
self._module = module
3939
self.testFramework = framework
@@ -51,7 +51,8 @@ public final class Suite: NSObject, Encodable {
5151
state.meta[DDGenericTags.type] = DDTagValues.typeSuiteEnd
5252
state.meta[DDTestTags.testSuite] = name
5353
state.meta[DDTestTags.testModule] = module.name
54-
state.meta[DDTestTags.testFramework] = testFramework
54+
state.meta[DDTestTags.testFramework] = testFramework.name
55+
state.meta[DDTestTags.testFrameworkVersion] = testFramework.version
5556
state.meta[DDTestSuiteVisibilityTags.testSessionId] = String(module.session.id.rawValue)
5657
state.meta[DDTestSuiteVisibilityTags.testModuleId] = String(module.id.rawValue)
5758
state.meta[DDTestSuiteVisibilityTags.testSuiteId] = String(id.rawValue)

Sources/DatadogSDKTesting/Models.swift

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,11 @@ protocol TestSuite: TestContainer {
9393
var session: any TestSession { get }
9494
var module: any TestModule { get }
9595
var localization: String { get }
96-
var testFramework: String { get }
96+
var testFramework: TestFramework { get }
9797
}
9898

9999
protocol TestSuiteProvider: Sendable {
100-
func startSuite(named: String, at: Date?, framework: String) -> any TestSuite & TestRunProvider
100+
func startSuite(named: String, at: Date?, framework: TestFramework) -> any TestSuite & TestRunProvider
101101
}
102102

103103
protocol TestRunProvider: Sendable {
@@ -299,6 +299,16 @@ struct TestRunParameters: Encodable {
299299
}
300300
}
301301

302+
public struct TestFramework: Sendable {
303+
public var name: String
304+
public var version: String
305+
306+
public init(name: String, version: String) {
307+
self.name = name
308+
self.version = version
309+
}
310+
}
311+
302312
extension TestModel {
303313
internal var endTime: Date {
304314
startTime.addingTimeInterval(.fromNanoseconds(Int64(duration)))

Sources/DatadogSDKTesting/SwiftTesting/SwiftTestingContext.swift

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -502,33 +502,34 @@ struct SwiftTestingSuiteContext: Sendable {
502502
let observer: any SwiftTestingObserverType
503503
let moduleManager: any TestModuleManager
504504
let testsCount: Int
505+
let version: String
505506

506507
init(suite: any TestSuite & TestRunProvider,
507-
configuration: SessionConfig,
508+
configuration: SessionConfig, version: String,
508509
info: any SwiftTestingTestInfoType,
509510
testsCount: Int,
510511
observer: any SwiftTestingObserverType,
511512
moduleManager: any TestModuleManager)
512513
{
513-
self.init(suite: suite, configuration: configuration,
514+
self.init(suite: suite, configuration: configuration, version: version,
514515
testsCount: testsCount, state: .init(tests: []),
515516
info: info, observer: observer, moduleManager: moduleManager)
516517
}
517518

518519
init(suite: any TestSuite & TestRunProvider,
519-
configuration: SessionConfig,
520+
configuration: SessionConfig, version: String,
520521
tests: Set<String>,
521522
info: any SwiftTestingTestInfoType,
522523
observer: any SwiftTestingObserverType,
523524
moduleManager: any TestModuleManager)
524525
{
525-
self.init(suite: suite, configuration: configuration,
526+
self.init(suite: suite, configuration: configuration, version: version,
526527
testsCount: tests.count, state: .init(tests: tests),
527528
info: info, observer: observer, moduleManager: moduleManager)
528529
}
529530

530531
private init(suite: any TestSuite & TestRunProvider,
531-
configuration: SessionConfig,
532+
configuration: SessionConfig, version: String,
532533
testsCount: Int, state: State,
533534
info: any SwiftTestingTestInfoType,
534535
observer: any SwiftTestingObserverType,
@@ -541,6 +542,7 @@ struct SwiftTestingSuiteContext: Sendable {
541542
self.observer = observer
542543
self.configuration = configuration
543544
self.moduleManager = moduleManager
545+
self.version = version
544546
}
545547

546548
func withTestRun<T>(named name: String, _ action: @Sendable (any TestRun) async throws -> T) async rethrows -> T {
@@ -709,19 +711,21 @@ struct SwiftTestingSuiteProvider: SwiftTestingSuiteProviderType {
709711

710712
var registry: any SwiftTestingTestRegistryType { _state.registry }
711713
var observer: any SwiftTestingObserverType { _state.observer }
714+
let version: String
712715
private let _state: State
713716

714717
init(session: any TestSessionManager, observer: any SwiftTestingObserverType) {
715718
self._state = .init(session: session, observer: observer, registry: Registry())
719+
self.version = PlatformUtils.getSwiftTestingVersion() ?? "unknown"
716720
}
717721

718722
func with(suite info: some SwiftTestingTestInfoType,
719723
performing function: @Sendable (borrowing SwiftTestingSuiteContext) async throws -> Void) async throws
720724
{
721725
let suite = try await self._state.suite(named: info.suite, in: info.module) { (mod, manager, config) in
722726
let count = try await self.registry.count(for: info)
723-
let suite = mod.startSuite(named: info.suite, at: nil, framework: Self.framework)
724-
return .init(suite: suite, configuration: config, info: info,
727+
let suite = mod.startSuite(named: info.suite, at: nil, framework: .init(name: Self.framework, version: version))
728+
return .init(suite: suite, configuration: config, version: version, info: info,
725729
testsCount: count, observer: self.observer, moduleManager: manager)
726730
}
727731
if suite.isNew {
@@ -735,8 +739,8 @@ struct SwiftTestingSuiteProvider: SwiftTestingSuiteProviderType {
735739
{
736740
let suite = try await self._state.suite(named: test.suite, in: test.module) { (mod, manager, config) in
737741
let tests = try await self.registry.tests(for: test)
738-
let suite = mod.startSuite(named: test.suite, at: nil, framework: Self.framework)
739-
return SwiftTestingSuiteContext(suite: suite, configuration: config,
742+
let suite = mod.startSuite(named: test.suite, at: nil, framework: .init(name: Self.framework, version: version))
743+
return SwiftTestingSuiteContext(suite: suite, configuration: config, version: version,
740744
tests: tests, info: test, observer: self.observer,
741745
moduleManager: manager)
742746
}
@@ -770,7 +774,7 @@ struct SwiftTestingSuiteProvider: SwiftTestingSuiteProviderType {
770774
}
771775

772776
extension TestSuite {
773-
var isSwiftTesting: Bool { testFramework == SwiftTestingSuiteProvider.framework }
777+
var isSwiftTesting: Bool { testFramework.name == SwiftTestingSuiteProvider.framework }
774778
}
775779

776780
extension Optional where Wrapped == SwiftTestingTestStatus.Errors {

Sources/DatadogSDKTesting/Utils/PlatformUtils.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,17 @@ struct PlatformUtils {
8383
return version
8484
}
8585

86+
static func getXCTestVersion() -> String? {
87+
guard let xcTestClass = NSClassFromString("XCTest") else { return nil }
88+
return Bundle(for: xcTestClass).infoDictionary?["CFBundleShortVersionString"] as? String
89+
}
90+
91+
static func getSwiftTestingVersion() -> String? {
92+
Bundle.allFrameworks
93+
.first { $0.bundleIdentifier == "com.apple.dt.swift-testing" }
94+
.flatMap { $0.infoDictionary?["CFBundleVersion"] as? String }
95+
}
96+
8697
static func getRuntimeInfo() -> (String, String) {
8798
if NSClassFromString("XCTest") != nil {
8899
return ("Xcode", getXcodeVersion())

Sources/DatadogSDKTesting/XCTest/DDXCTestObserver.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,13 @@ internal import XCTest
1111
final class DDXCTestObserver: NSObject, XCTestObservation, DDXCTestRetryDelegate {
1212
private(set) var state: State
1313
private let log: Logger
14+
private let version: String
1415

1516
init(session: any TestSessionManager, log: Logger) {
1617
XCUIApplication.swizzleMethods
1718
state = .start(session)
1819
self.log = log
20+
self.version = PlatformUtils.getXCTestVersion() ?? "unknown"
1921
super.init()
2022
}
2123

@@ -103,7 +105,7 @@ final class DDXCTestObserver: NSObject, XCTestObservation, DDXCTestRetryDelegate
103105
let wrappedTests = tests.map { DDXCTestRetryGroup(for: $0, observer: self) }
104106
testSuite.setValue(wrappedTests, forKey: "_mutableTests")
105107

106-
let suite = module.startSuite(named: testSuite.name, at: nil, framework: "XCTest")
108+
let suite = module.startSuite(named: testSuite.name, at: nil, framework: .init(name: "XCTest", version: version))
107109
DDCrashes.setCurrent(spanData: suite.toCrashData)
108110
context.features.testSuiteWillStart(suite: suite, testsCount: UInt(wrappedTests.count))
109111

Tests/DatadogSDKTesting/DDXCTestObserverTests.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ internal class DDXCTestObserverTests: XCTestCase {
8080
XCTAssertEqual(spanData.attributes[DDTestTags.testName]?.description, testName)
8181
XCTAssertEqual(spanData.attributes[DDTestTags.testSuite]?.description, testSuite)
8282
XCTAssertEqual(spanData.attributes[DDTestTags.testFramework]?.description, "XCTest")
83+
XCTAssertEqual(spanData.attributes[DDTestTags.testFrameworkVersion]?.description, PlatformUtils.getXCTestVersion())
8384
XCTAssertEqual(spanData.attributes[DDTestTags.testType]?.description, DDTagValues.typeTest)
8485
XCTAssertEqual(spanData.attributes[DDHostTags.hostVCPUCount]?.description, String(Double(PlatformUtils.getCpuCount())))
8586
}

Tests/DatadogSDKTesting/MockTestRunner.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ extension Mocks {
174174
}
175175

176176
func _run(suite name: String, info: TestSuite, module: Module) {
177-
let suite = module.startSuite(named: name, at: nil, framework: "MockRunner") as! Mocks.Suite
177+
let suite = module.startSuite(named: name, at: nil, framework: .init(name: "MockRunner", version: "1.0.0")) as! Mocks.Suite
178178
features.testSuiteWillStart(suite: suite, testsCount: UInt(info.tests.count))
179179
for (test, method) in info.tests {
180180
_run(group: test, method: method, suite: suite)

0 commit comments

Comments
 (0)