Skip to content

Commit

Permalink
add flag to allow disabling building with testablity when building tests
Browse files Browse the repository at this point in the history
motivation: allow building tests without testability (testable imports), this can increase build / test cycles when tests do not require the testable imports feature since more is cachable

changes:
* add a --disable-testable-imports flag to "swift test" with which tests are build without the testablity feature
* add tests

rdar://82448144
  • Loading branch information
tomerd committed Feb 10, 2022
1 parent 7a12c5e commit 40331d1
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 15 deletions.
28 changes: 21 additions & 7 deletions Sources/Commands/SwiftTestTool.swift
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ struct TestToolOptions: ParsableArguments {
@Option(help: "Test the specified product.")
var testProduct: String?

/// Generate LinuxMain entries and exit.
@Flag(name: .customLong("testable-imports"), inversion: .prefixedEnableDisable, help: "Enable or disable testable imports. Enabled by default.")
var enableTestableImports: Bool = true

/// Returns the test case specifier if overridden in the env.
private func testCaseSkipOverride() -> TestCaseSpecifier? {
guard let override = ProcessEnv.vars["_SWIFTPM_SKIP_TESTS_LIST"] else {
Expand Down Expand Up @@ -235,7 +239,7 @@ public struct SwiftTestTool: SwiftCommand {
guard let rootManifest = rootManifests.values.first else {
throw StringError("invalid manifests at \(root.packages)")
}
let buildParameters = try swiftTool.buildParametersForTest()
let buildParameters = try swiftTool.buildParametersForTest(options: self.options)
print(codeCovAsJSONPath(buildParameters: buildParameters, packageName: rootManifest.displayName))

case .generateLinuxMain:
Expand All @@ -256,7 +260,7 @@ public struct SwiftTestTool: SwiftCommand {
case .runSerial:
let toolchain = try swiftTool.getToolchain()
let testProducts = try buildTestsIfNeeded(swiftTool: swiftTool)
let buildParameters = try swiftTool.buildParametersForTest()
let buildParameters = try swiftTool.buildParametersForTest(options: self.options)

// Clean out the code coverage directory that may contain stale
// profraw files from a previous run of the code coverage tool.
Expand Down Expand Up @@ -324,7 +328,7 @@ public struct SwiftTestTool: SwiftCommand {
let tests = try testSuites
.filteredTests(specifier: options.testCaseSpecifier)
.skippedTests(specifier: options.testCaseSkip)
let buildParameters = try swiftTool.buildParametersForTest()
let buildParameters = try swiftTool.buildParametersForTest(options: self.options)

// If there were no matches, emit a warning and exit.
if tests.isEmpty {
Expand Down Expand Up @@ -380,7 +384,7 @@ public struct SwiftTestTool: SwiftCommand {
// Merge all the profraw files to produce a single profdata file.
try mergeCodeCovRawDataFiles(swiftTool: swiftTool)

let buildParameters = try swiftTool.buildParametersForTest()
let buildParameters = try swiftTool.buildParametersForTest(options: self.options)
for product in testProducts {
// Export the codecov data as JSON.
let jsonPath = codeCovAsJSONPath(
Expand All @@ -396,7 +400,7 @@ public struct SwiftTestTool: SwiftCommand {
let llvmProf = try swiftTool.getToolchain().getLLVMProf()

// Get the profraw files.
let buildParameters = try swiftTool.buildParametersForTest()
let buildParameters = try swiftTool.buildParametersForTest(options: self.options)
let codeCovFiles = try localFileSystem.getDirectoryContents(buildParameters.codeCovPath)

// Construct arguments for invoking the llvm-prof tool.
Expand All @@ -420,7 +424,7 @@ public struct SwiftTestTool: SwiftCommand {
private func exportCodeCovAsJSON(to path: AbsolutePath, testBinary: AbsolutePath, swiftTool: SwiftTool) throws {
// Export using the llvm-cov tool.
let llvmCov = try swiftTool.getToolchain().getLLVMCov()
let buildParameters = try swiftTool.buildParametersForTest()
let buildParameters = try swiftTool.buildParametersForTest(options: self.options)
let args = [
llvmCov.pathString,
"export",
Expand All @@ -440,7 +444,8 @@ public struct SwiftTestTool: SwiftCommand {
///
/// - Returns: The paths to the build test products.
private func buildTestsIfNeeded(swiftTool: SwiftTool) throws -> [BuiltTestProduct] {
let buildSystem = try swiftTool.createBuildSystem(buildParameters: swiftTool.buildParametersForTest())
let buildParameters = try swiftTool.buildParametersForTest(options: self.options)
let buildSystem = try swiftTool.createBuildSystem(buildParameters: buildParameters)

if options.shouldBuildTests {
let subset = options.testProduct.map(BuildSubset.product) ?? .allIncludingTests
Expand Down Expand Up @@ -1016,8 +1021,17 @@ final class XUnitGenerator {
}
}

extension SwiftTool {
func buildParametersForTest(options: TestToolOptions) throws -> BuildParameters {
try self.buildParametersForTest(
enableTestability: options.enableTestableImports
)
}
}

private extension Basics.Diagnostic {
static var noMatchingTests: Self {
.warning("No matching test cases were run")
}
}

8 changes: 5 additions & 3 deletions Sources/Commands/TestingSupport.swift
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,12 @@ enum TestingSupport {
}

extension SwiftTool {
func buildParametersForTest() throws -> BuildParameters {
func buildParametersForTest(
enableTestability: Bool? = nil
) throws -> BuildParameters {
var parameters = try self.buildParameters()
// for test commands, alway enable building with testability enabled
parameters.enableTestability = true
// for test commands, we normally enable building with testability
parameters.enableTestability = enableTestability ?? true
return parameters
}
}
32 changes: 27 additions & 5 deletions Tests/CommandsTests/TestToolTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
*/

import XCTest

import SPMTestSupport
import Commands
import SPMTestSupport
import TSCBasic
import XCTest

final class TestToolTests: CommandsTestCase {

private func execute(_ args: [String]) throws -> (stdout: String, stderr: String) {
return try SwiftPMProduct.SwiftTest.execute(args)
private func execute(_ args: [String], packagePath: AbsolutePath? = nil) throws -> (stdout: String, stderr: String) {
return try SwiftPMProduct.SwiftTest.execute(args, packagePath: packagePath)
}

func testUsage() throws {
Expand Down Expand Up @@ -58,4 +58,26 @@ final class TestToolTests: CommandsTestCase {
}
#endif
}

func testEnableDisableTestability() {
fixture(name: "Miscellaneous/TestableExe") { path in
do {
let result = try execute(["--vv"], packagePath: path)
// default should run with testability
XCTAssertMatch(result.stdout, .contains("-enable-testing"))
}

do {
// disable
let result = try execute(["--disable-testable-imports", "--vv"], packagePath: path)
XCTAssertNoMatch(result.stdout, .contains("-enable-testing"))
}

do {
// enable
let result = try execute(["--enable-testable-imports", "--vv"], packagePath: path)
XCTAssertMatch(result.stdout, .contains("-enable-testing"))
}
}
}
}

0 comments on commit 40331d1

Please sign in to comment.