Skip to content

Commit 7585499

Browse files
authored
Added special per-test only mode for code coverage (#143)
added special per-test only mode for code coverage
1 parent 8953573 commit 7585499

File tree

8 files changed

+61
-16
lines changed

8 files changed

+61
-16
lines changed

DatadogSDKTesting.xcodeproj/project.pbxproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
A76174BD2CB3E3780098CE99 /* DDXCTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = A76174BC2CB3E3780098CE99 /* DDXCTestCase.swift */; };
3737
A76174BF2CB45F9B0098CE99 /* XCTestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A76174BE2CB45F9B0098CE99 /* XCTestExtensions.swift */; };
3838
A76174C22CB685390098CE99 /* SettingsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = A76174C02CB685250098CE99 /* SettingsService.swift */; };
39-
A7A98C202C8F44BC00C93E59 /* CoveragePriority.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7A98C1F2C8F44BC00C93E59 /* CoveragePriority.swift */; };
39+
A7A98C202C8F44BC00C93E59 /* CoverageSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7A98C1F2C8F44BC00C93E59 /* CoverageSettings.swift */; };
4040
A7B39C6C2BCFC799007F98B2 /* CDatadogSDKTesting.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7E232DC2BC6E68B0087D8F8 /* CDatadogSDKTesting.framework */; };
4141
A7B39C702BCFCD77007F98B2 /* SubprocessWait.c in Sources */ = {isa = PBXBuildFile; fileRef = A7B39C6F2BCFCD77007F98B2 /* SubprocessWait.c */; };
4242
A7B39C722BCFD234007F98B2 /* SubprocessWait.h in Headers */ = {isa = PBXBuildFile; fileRef = A7B39C712BCFD234007F98B2 /* SubprocessWait.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -329,7 +329,7 @@
329329
A76174BC2CB3E3780098CE99 /* DDXCTestCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DDXCTestCase.swift; sourceTree = "<group>"; };
330330
A76174BE2CB45F9B0098CE99 /* XCTestExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCTestExtensions.swift; sourceTree = "<group>"; };
331331
A76174C02CB685250098CE99 /* SettingsService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsService.swift; sourceTree = "<group>"; };
332-
A7A98C1F2C8F44BC00C93E59 /* CoveragePriority.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoveragePriority.swift; sourceTree = "<group>"; };
332+
A7A98C1F2C8F44BC00C93E59 /* CoverageSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoverageSettings.swift; sourceTree = "<group>"; };
333333
A7B39C6F2BCFCD77007F98B2 /* SubprocessWait.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SubprocessWait.c; sourceTree = "<group>"; };
334334
A7B39C712BCFD234007F98B2 /* SubprocessWait.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SubprocessWait.h; sourceTree = "<group>"; };
335335
A7B4D4C02C21DC510059F39B /* TagsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TagsTests.swift; sourceTree = "<group>"; };
@@ -586,7 +586,7 @@
586586
children = (
587587
81EDADB2292698A200279027 /* LLVMTotalsCoverageFormat.swift */,
588588
E1C8DEF4268363EC005B5411 /* DDCoverageHelper.swift */,
589-
A7A98C1F2C8F44BC00C93E59 /* CoveragePriority.swift */,
589+
A7A98C1F2C8F44BC00C93E59 /* CoverageSettings.swift */,
590590
);
591591
path = Coverage;
592592
sourceTree = "<group>";
@@ -1539,7 +1539,7 @@
15391539
A7FC25C22BA1EAF500067E26 /* IntelligentTestRunner.swift in Sources */,
15401540
A7CC6D862C07D624003C13BC /* Tags.swift in Sources */,
15411541
A74246002BFF94FA00F7EC64 /* ITRSkippabble.swift in Sources */,
1542-
A7A98C202C8F44BC00C93E59 /* CoveragePriority.swift in Sources */,
1542+
A7A98C202C8F44BC00C93E59 /* CoverageSettings.swift in Sources */,
15431543
);
15441544
runOnlyForDeploymentPostprocessing = 0;
15451545
};

Sources/DatadogSDKTesting/Config.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ final class Config {
4444

4545
/// Intelligent test runner related environment
4646
var gitUploadEnabled: Bool = true
47-
var coverageEnabled: Bool = true
4847
var itrEnabled: Bool = true
48+
var coverageMode: CodeCoverageMode = .total
4949
var excludedBranches: Set<String> = []
5050
var codeCoveragePriority: CodeCoveragePriority = .utility
5151

@@ -124,8 +124,11 @@ final class Config {
124124
/// Intelligent test runner related configuration
125125
gitUploadEnabled = env[.enableCiVisibilityGitUpload] ?? gitUploadEnabled
126126
itrEnabled = env[.enableCiVisibilityITR] ?? itrEnabled
127-
coverageEnabled = env[.enableCiVisibilityCodeCoverage] ?? itrEnabled
128127
excludedBranches = env[.ciVisibilityExcludedBranches] ?? excludedBranches
128+
129+
let coverageEnabled = env[.enableCiVisibilityCodeCoverage] ?? itrEnabled
130+
let coveragePerTestOnly = env[.ciVisibilityCodeCoverageOnlyPerTest] ?? false
131+
coverageMode = coverageEnabled ? (coveragePerTestOnly ? .perTest : .total) : .disabled
129132

130133
/// Automatic Test Retries
131134
testRetriesEnabled = env[.enableCiVisibilityFlakyRetries] ?? testRetriesEnabled
@@ -215,7 +218,7 @@ extension Config: CustomDebugStringConvertible {
215218
Disable NTP Clock: \(disableNTPClock)
216219
Disable Git Information: \(disableGitInformation)
217220
Git Upload Enabled: \(gitUploadEnabled)
218-
Coverage Enabled: \(coverageEnabled)
221+
Coverage: \(coverageMode)
219222
ITR Enabled: \(itrEnabled)
220223
Excluded Branches: \(excludedBranches)
221224
Test Retries Enabled: \(testRetriesEnabled)

Sources/DatadogSDKTesting/Coverage/CoveragePriority.swift renamed to Sources/DatadogSDKTesting/Coverage/CoverageSettings.swift

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,38 @@ enum CodeCoveragePriority: Int, EnvironmentValue, CustomDebugStringConvertible {
4040
}
4141
}
4242
}
43+
44+
enum CodeCoverageMode {
45+
case disabled
46+
case perTest
47+
case total
48+
49+
var isTotal: Bool {
50+
switch self {
51+
case .total: return true
52+
default: return false
53+
}
54+
}
55+
56+
var isPerTest: Bool {
57+
switch self {
58+
case .perTest: return true
59+
default: return false
60+
}
61+
}
62+
63+
var isEnabled: Bool {
64+
switch self {
65+
case .disabled: return false
66+
default: return true
67+
}
68+
}
69+
70+
var debugDescription: String {
71+
switch self {
72+
case .total: return "Total"
73+
case .perTest: return "Per-Test Only"
74+
case .disabled: return "Disabled"
75+
}
76+
}
77+
}

Sources/DatadogSDKTesting/Coverage/DDCoverageHelper.swift

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@ class DDCoverageHelper {
1414
var llvmProfileURL: URL
1515
var storagePath: Directory
1616
var initialCoverageSaved: Bool
17+
let isTotal: Bool
1718
let coverageWorkQueue: OperationQueue
1819

19-
init?(storagePath: Directory, priority: CodeCoveragePriority) {
20+
init?(storagePath: Directory, total: Bool, priority: CodeCoveragePriority) {
2021
guard let profilePath = Self.profileGetFileName(), BinaryImages.profileImages.count > 0 else {
2122
Log.print("Coverage not properly enabled in project, check documentation")
2223
Log.debug("LLVM_PROFILE_FILE: \(Self.profileGetFileName() ?? "NIL")")
@@ -30,6 +31,7 @@ class DDCoverageHelper {
3031
}
3132

3233
llvmProfileURL = URL(fileURLWithPath: profilePath)
34+
isTotal = total
3335
self.storagePath = path
3436
Log.debug("LLVM Coverage location: \(llvmProfileURL.path)")
3537
Log.debug("DDCoverageHelper location: \(path.url.path)")
@@ -93,10 +95,12 @@ class DDCoverageHelper {
9395
func writeTestProfile() {
9496
// Write first to our test file
9597
Self.internalWriteProfile()
96-
97-
// Write to llvm original destination
98-
profileSetFilename(url: llvmProfileURL)
99-
Self.internalWriteProfile()
98+
if isTotal {
99+
// Switch profile to llvm original destination
100+
profileSetFilename(url: llvmProfileURL)
101+
// Write to llvm original destination
102+
Self.internalWriteProfile()
103+
}
100104
}
101105

102106
func removeStoragePath() {
@@ -140,7 +144,6 @@ class DDCoverageHelper {
140144
guard let profDataURL = DDCoverageHelper.generateProfData(profrawFile: profrawFile) else {
141145
return nil
142146
}
143-
Thread.sleep(forTimeInterval: 0.1)
144147
let covJsonURL = profDataURL.deletingLastPathComponent().appendingPathComponent("coverageFile").appendingPathExtension("json")
145148
let binariesPath = binaryImagePaths.map { #""\#($0)""# }.joined(separator: " -object ")
146149
let commandToRun = #"xcrun llvm-cov export -instr-profile "\#(profDataURL.path)" \#(binariesPath) > "\#(covJsonURL.path)""#

Sources/DatadogSDKTesting/DDTestModule.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,9 @@ public class DDTestModule: NSObject, Encodable {
148148
if itrSkipped == 0 {
149149
meta[DDItrTags.itrSkippedTests] = "false"
150150
meta[DDTestSessionTags.testItrSkipped] = "false"
151-
metrics[DDTestSessionTags.testCoverageLines] = DDCoverageHelper.getLineCodeCoverage()
151+
if !DDTestMonitor.config.coverageMode.isPerTest {
152+
metrics[DDTestSessionTags.testCoverageLines] = DDCoverageHelper.getLineCodeCoverage()
153+
}
152154
} else {
153155
meta[DDItrTags.itrSkippedTests] = "true"
154156
meta[DDTestSessionTags.testItrSkipped] = "true"

Sources/DatadogSDKTesting/DDTestMonitor.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ internal class DDTestMonitor {
317317
}
318318
}
319319

320-
if DDTestMonitor.config.coverageEnabled {
320+
if DDTestMonitor.config.coverageMode.isEnabled {
321321
let coverageSetup = BlockOperation { [self] in
322322
guard let settings = tracerBackendConfig?.itr,
323323
settings.itrEnabled && settings.codeCoverage
@@ -333,6 +333,7 @@ internal class DDTestMonitor {
333333
return
334334
}
335335
coverageHelper = DDCoverageHelper(storagePath: temp,
336+
total: DDTestMonitor.config.coverageMode.isTotal,
336337
priority: DDTestMonitor.config.codeCoveragePriority)
337338
}
338339
coverageSetup.addDependency(updateTracerConfig)

Sources/DatadogSDKTesting/Environment/EnvironmentKeys.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ internal enum EnvironmentKey: String, CaseIterable {
4141
case enableCiVisibilityGitUpload = "DD_CIVISIBILITY_GIT_UPLOAD_ENABLED"
4242
case enableCiVisibilityCodeCoverage = "DD_CIVISIBILITY_CODE_COVERAGE_ENABLED"
4343
case ciVisibilityCodeCoveragePriority = "DD_CIVISIBILITY_CODE_COVERAGE_PRIORITY"
44+
case ciVisibilityCodeCoverageOnlyPerTest = "DD_CIVISIBILITY_CODE_COVERAGE_ONLY_PER_TEST"
4445
case enableCiVisibilityITR = "DD_CIVISIBILITY_ITR_ENABLED"
4546
case ciVisibilityExcludedBranches = "DD_CIVISIBILITY_EXCLUDED_BRANCHES"
4647
case ciVisibilityReportHostname = "DD_CIVISIBILITY_REPORT_HOSTNAME"

Sources/DatadogSDKTesting/FrameworkLoadHandler.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ enum FrameworkLoadHandler {
3030
if config.isInTestMode {
3131
// When code coverage is enabled modify profile name so it disables countinuous profiling
3232
// or we cannot recover coverage manually
33-
if config.coverageEnabled || config.itrEnabled {
33+
if config.coverageMode.isEnabled || config.itrEnabled {
3434
if DDCoverageHelper.load() {
3535
DDTestMonitor.envReader = ProcessEnvironmentReader()
3636
}

0 commit comments

Comments
 (0)