Index: subprojects/language-native/src/integTest/groovy/org/gradle/language/LanguageTaskNames.groovy =================================================================== diff -u -N --- subprojects/language-native/src/integTest/groovy/org/gradle/language/LanguageTaskNames.groovy (revision 043fb013d8f51083f9e9c1c8bcd6d6b03a843221) +++ subprojects/language-native/src/integTest/groovy/org/gradle/language/LanguageTaskNames.groovy (revision 0) @@ -1,235 +0,0 @@ -/* - * Copyright 2018 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.gradle.language - -import org.gradle.nativeplatform.fixtures.AvailableToolChains - -abstract trait LanguageTaskNames { - private static final String DEBUG = 'Debug' - private static final String RELEASE = 'Release' - - abstract AvailableToolChains.InstalledToolChain getToolchainUnderTest() - - abstract String getLanguageTaskSuffix() - - String installTaskDebug(String project = '') { - installTask(project, DEBUG) - } - - String[] compileTasks(String project = '', String buildType) { - [compileTask(project, buildType)] as String[] - } - - String compileTask(String project = '', String buildType) { - "${project}:compile${buildType}${getLanguageTaskSuffix()}" - } - - String linkTask(String project = '', String buildType) { - "${project}:link${buildType}" - } - - String staticLinkTask(String project = '', String buildType) { - "${project}:create${buildType}" - } - - String installTask(String project = '', String buildType) { - "${project}:install${buildType}" - } - - String[] compileAndLinkTasks(List projects = [''], String buildType) { - projects.collect { project -> - [*compileTasks(project, buildType), linkTask(project, buildType)] - }.flatten() - } - - String[] compileAndStaticLinkTasks(List projects = [''], String buildType) { - projects.collect { project -> - [*compileTasks(project, buildType), staticLinkTask(project, buildType)] - }.flatten() - } - - String[] extractAndStripSymbolsTasksRelease(String project = '') { - return extractAndStripSymbolsTasks(project, RELEASE) - } - - String[] extractAndStripSymbolsTasks(String project = '', String buildType) { - if (toolchainUnderTest.visualCpp) { - return [] - } else { - return stripSymbolsTasks(project, buildType) + ["${project}:extractSymbols${buildType}"] - } - } - - String[] stripSymbolsTasksRelease(String project = '') { - return stripSymbolsTasks(project, RELEASE) - } - - String[] stripSymbolsTasks(String project = '', String buildType) { - if (toolchainUnderTest.visualCpp) { - return [] - } else { - return ["${project}:stripSymbols${buildType}"] - } - } - - String[] stripSymbolsTasks(List projects, String buildType) { - projects.collect { project -> - [*stripSymbolsTasks(project, buildType)] - }.flatten() - } - - String getDebug() { - DEBUG - } - - String getRelease() { - RELEASE - } - - String getDebugShared() { - return "${DEBUG}Shared" - } - - /** - * Returns the tasks for the project with the given path. - */ - ProjectTasks tasks(String project) { - return new ProjectTasks(project, toolchainUnderTest, languageTaskSuffix) - } - - /** - * Returns the tasks for the root project. - */ - ProjectTasks getTasks() { - return new ProjectTasks('', toolchainUnderTest, languageTaskSuffix) - } - - static class ProjectTasks { - private final String project - private final AvailableToolChains.InstalledToolChain toolChainUnderTest - private final String languageTaskSuffix - private String architecture = null - private String operatingSystemFamily = null - - ProjectTasks(String project, AvailableToolChains.InstalledToolChain toolChainUnderTest, String languageTaskSuffix) { - this.toolChainUnderTest = toolChainUnderTest - this.project = project - this.languageTaskSuffix = languageTaskSuffix - } - - ProjectTasks withArchitecture(String architecture) { - this.architecture = architecture - return this - } - - DebugTasks getDebug() { - return new DebugTasks() - } - - ReleaseTasks getRelease() { - return new ReleaseTasks() - } - - private withProject(String t) { - project + ":" + t - } - - ProjectTasks withOperatingSystemFamily(String operatingSystemFamily) { - this.operatingSystemFamily = operatingSystemFamily - return this - } - - class DebugTasks { - String getCompile() { - return withProject("compileDebug${variant}${languageTaskSuffix}") - } - - String getLink() { - return withProject("linkDebug${variant}") - } - - String getInstall() { - return withProject("installDebug${variant}") - } - - String getAssemble() { - return withProject("assembleDebug${variant}") - } - - List getAllToLink() { - return [compile, link] - } - - List getAllToInstall() { - return allToLink + [install] - } - } - - class ReleaseTasks { - String getCompile() { - return withProject("compileRelease${variant}${languageTaskSuffix}") - } - - String getLink() { - return withProject("linkRelease${variant}") - } - - String getInstall() { - return withProject("installRelease${variant}") - } - - String getAssemble() { - return withProject("assembleRelease${variant}") - } - - List getExtract() { - if (toolChainUnderTest.visualCpp) { - return [] - } else { - return [withProject("extractSymbolsRelease${variant}")] - } - } - - List getStrip() { - if (toolChainUnderTest.visualCpp) { - return [] - } else { - return [withProject("stripSymbolsRelease${variant}")] - } - } - - List getAllToLink() { - return [compile, link] + strip - } - - List getAllToInstall() { - return allToLink + [install] - } - } - - protected String getVariant() { - String result = "" - if (operatingSystemFamily != null) { - result += operatingSystemFamily.toLowerCase().capitalize() - } - if (architecture != null) { - result += architecture.toLowerCase().capitalize() - } - return result - } - } -} \ No newline at end of file Index: subprojects/language-native/src/testFixtures/groovy/org/gradle/language/LanguageTaskNames.groovy =================================================================== diff -u -N --- subprojects/language-native/src/testFixtures/groovy/org/gradle/language/LanguageTaskNames.groovy (revision 0) +++ subprojects/language-native/src/testFixtures/groovy/org/gradle/language/LanguageTaskNames.groovy (revision 3f66bf922f51cfd09a94cc0f892aa0e86ecdb483) @@ -0,0 +1,262 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.gradle.language + +import org.gradle.nativeplatform.fixtures.AvailableToolChains + +abstract trait LanguageTaskNames { + private static final String DEBUG = 'Debug' + private static final String RELEASE = 'Release' + + abstract AvailableToolChains.InstalledToolChain getToolchainUnderTest() + + abstract String getLanguageTaskSuffix() + + String installTaskDebug(String project = '') { + installTask(project, DEBUG) + } + + String[] compileTasks(String project = '', String buildType) { + [compileTask(project, buildType)] as String[] + } + + String compileTask(String project = '', String buildType) { + "${project}:compile${buildType}${getLanguageTaskSuffix()}" + } + + String linkTask(String project = '', String buildType) { + "${project}:link${buildType}" + } + + String staticLinkTask(String project = '', String buildType) { + "${project}:create${buildType}" + } + + String installTask(String project = '', String buildType) { + "${project}:install${buildType}" + } + + String[] compileAndLinkTasks(List projects = [''], String buildType) { + projects.collect { project -> + [*compileTasks(project, buildType), linkTask(project, buildType)] + }.flatten() + } + + String[] compileAndStaticLinkTasks(List projects = [''], String buildType) { + projects.collect { project -> + [*compileTasks(project, buildType), staticLinkTask(project, buildType)] + }.flatten() + } + + String[] extractAndStripSymbolsTasksRelease(String project = '') { + return extractAndStripSymbolsTasks(project, RELEASE) + } + + String[] extractAndStripSymbolsTasks(String project = '', String buildType) { + if (toolchainUnderTest.visualCpp) { + return [] + } else { + return stripSymbolsTasks(project, buildType) + ["${project}:extractSymbols${buildType}"] + } + } + + String[] stripSymbolsTasksRelease(String project = '') { + return stripSymbolsTasks(project, RELEASE) + } + + String[] stripSymbolsTasks(String project = '', String buildType) { + if (toolchainUnderTest.visualCpp) { + return [] + } else { + return ["${project}:stripSymbols${buildType}"] + } + } + + String[] stripSymbolsTasks(List projects, String buildType) { + projects.collect { project -> + [*stripSymbolsTasks(project, buildType)] + }.flatten() + } + + String getDebug() { + DEBUG + } + + String getRelease() { + RELEASE + } + + String getDebugShared() { + return "${DEBUG}Shared" + } + + /** + * Returns the tasks for the project with the given path. + */ + ProjectTasks tasks(String project) { + return new ProjectTasks(project, toolchainUnderTest, languageTaskSuffix) + } + + /** + * Returns the tasks for the root project. + */ + ProjectTasks getTasks() { + return new ProjectTasks('', toolchainUnderTest, languageTaskSuffix) + } + + static class ProjectTasks { + private final String project + private final AvailableToolChains.InstalledToolChain toolChainUnderTest + private final String languageTaskSuffix + private String architecture = null + private String operatingSystemFamily = null + + ProjectTasks(String project, AvailableToolChains.InstalledToolChain toolChainUnderTest, String languageTaskSuffix) { + this.toolChainUnderTest = toolChainUnderTest + this.project = project + this.languageTaskSuffix = languageTaskSuffix + } + + ProjectTasks withArchitecture(String architecture) { + this.architecture = architecture + return this + } + + DebugTasks getDebug() { + return new DebugTasks() + } + + ReleaseTasks getRelease() { + return new ReleaseTasks() + } + + TestTasks getTest() { + return new TestTasks() + } + + private withProject(String t) { + project + ":" + t + } + + ProjectTasks withOperatingSystemFamily(String operatingSystemFamily) { + this.operatingSystemFamily = operatingSystemFamily + return this + } + + class AbstractTasks { + final String type + + AbstractTasks(String type) { + this.type = type.capitalize() + } + + String getCompile() { + return withProject("compile${type}${variant}${languageTaskSuffix}") + } + + String getLink() { + return withProject("link${type}${variant}") + } + + String getInstall() { + return withProject("install${type}${variant}") + } + + String getAssemble() { + return withProject("assemble${type}${variant}") + } + + } + + class DebugTasks extends AbstractTasks { + DebugTasks() { + super("debug") + } + + List getAllToLink() { + return [compile, link] + } + + List getAllToInstall() { + return allToLink + [install] + } + } + + class ReleaseTasks extends AbstractTasks { + ReleaseTasks() { + super("release") + } + + List getExtract() { + if (toolChainUnderTest.visualCpp) { + return [] + } else { + return [withProject("extractSymbolsRelease${variant}")] + } + } + + List getStrip() { + if (toolChainUnderTest.visualCpp) { + return [] + } else { + return [withProject("stripSymbolsRelease${variant}")] + } + } + + List getAllToLink() { + return [compile, link] + strip + } + + List getAllToInstall() { + return allToLink + [install] + } + } + + class TestTasks extends AbstractTasks { + TestTasks() { + super("test") + } + + List getRun() { + return [withProject("runTest${variant}")] + } + + List getRelocate() { + return [withProject("relocateMainForTest${variant}")] + } + + List getAllToLink() { + return [compile, link] + } + + List getAllToInstall() { + return allToLink + [install] + } + } + + protected String getVariant() { + String result = "" + if (operatingSystemFamily != null) { + result += operatingSystemFamily.toLowerCase().capitalize() + } + if (architecture != null) { + result += architecture.toLowerCase().capitalize() + } + return result + } + } +} \ No newline at end of file Index: subprojects/platform-native/src/main/java/org/gradle/nativeplatform/internal/DefaultTargetMachineFactory.java =================================================================== diff -u -N -ra7c2b1528bece77a8bba69de17ad0bbc6608c978 -r3f66bf922f51cfd09a94cc0f892aa0e86ecdb483 --- subprojects/platform-native/src/main/java/org/gradle/nativeplatform/internal/DefaultTargetMachineFactory.java (.../DefaultTargetMachineFactory.java) (revision a7c2b1528bece77a8bba69de17ad0bbc6608c978) +++ subprojects/platform-native/src/main/java/org/gradle/nativeplatform/internal/DefaultTargetMachineFactory.java (.../DefaultTargetMachineFactory.java) (revision 3f66bf922f51cfd09a94cc0f892aa0e86ecdb483) @@ -117,5 +117,10 @@ public int hashCode() { return Objects.hash(operatingSystemFamily, architecture); } + + @Override + public String toString() { + return operatingSystemFamily.getName() + ":" + architecture.getName(); + } } } Index: subprojects/testing-native/src/integTest/groovy/org/gradle/nativeplatform/test/AbstractNativeUnitTestIntegrationTest.groovy =================================================================== diff -u -N -rf063b6e4a038f16cd75d2169feaf94bc9275916f -r3f66bf922f51cfd09a94cc0f892aa0e86ecdb483 --- subprojects/testing-native/src/integTest/groovy/org/gradle/nativeplatform/test/AbstractNativeUnitTestIntegrationTest.groovy (.../AbstractNativeUnitTestIntegrationTest.groovy) (revision f063b6e4a038f16cd75d2169feaf94bc9275916f) +++ subprojects/testing-native/src/integTest/groovy/org/gradle/nativeplatform/test/AbstractNativeUnitTestIntegrationTest.groovy (.../AbstractNativeUnitTestIntegrationTest.groovy) (revision 3f66bf922f51cfd09a94cc0f892aa0e86ecdb483) @@ -16,11 +16,15 @@ package org.gradle.nativeplatform.test +import org.gradle.language.LanguageTaskNames import org.gradle.nativeplatform.fixtures.AbstractInstalledToolChainIntegrationSpec - +import org.gradle.nativeplatform.fixtures.ToolChainRequirement +import org.junit.Assume import spock.lang.Unroll -abstract class AbstractNativeUnitTestIntegrationTest extends AbstractInstalledToolChainIntegrationSpec { +import static org.gradle.nativeplatform.MachineArchitecture.* + +abstract class AbstractNativeUnitTestIntegrationTest extends AbstractInstalledToolChainIntegrationSpec implements LanguageTaskNames { def "does nothing when no source files are present"() { given: makeSingleProject() @@ -50,9 +54,98 @@ task | expectedLifecycleTasks "test" | [":test"] "check" | [":test", ":check"] - "build" | [":test", ":check", ":build", tasksToCompileComponentUnderTest, tasksToBuildAndRunUnitTest, tasksToAssembleComponentUnderTest, ":assemble"] + "build" | [":test", ":check", ":build", tasksToAssembleComponentUnderTest, ":assemble"] } + @Unroll + def "runs tests when #task lifecycle task executes and target machines are specified on the component under test"() { + Assume.assumeFalse(toolChain.meets(ToolChainRequirement.WINDOWS_GCC)) + Assume.assumeFalse(componentUnderTestDsl == null) + + given: + makeSingleProject() + writeTests() + configureTargetMachines("machines.os('${currentOsFamilyName}').x86(), machines.os('${currentOsFamilyName}').x86_64()") + + when: + succeeds(task) + + then: + result.assertTasksExecuted(getTasksToCompileComponentUnderTest(expectedArchitecture), getTasksToBuildAndRunUnitTest(expectedArchitecture), expectedLifecycleTasks) + assertTestCasesRan() + + where: + task | expectedArchitecture | expectedLifecycleTasks + "test" | X86_64 | [":test"] + "check" | X86_64 | [":test", ":check"] + "build" | X86_64 | [":test", ":check", ":build", getTasksToAssembleComponentUnderTest(X86_64), ":assemble"] + "runTestX86" | X86 | [":runTestX86"] + } + + @Unroll + def "runs tests when #task lifecycle task executes and target machines are specified on both main component and test component"() { + Assume.assumeFalse(toolChain.meets(ToolChainRequirement.WINDOWS_GCC)) + Assume.assumeFalse(componentUnderTestDsl == null) + + given: + makeSingleProject() + writeTests() + configureTargetMachines("machines.os('${currentOsFamilyName}').x86(), machines.os('${currentOsFamilyName}').x86_64()") + configureTestTargetMachines("machines.os('${currentOsFamilyName}').x86_64()") + + when: + succeeds(task) + + then: + result.assertTasksExecuted(getTasksToCompileComponentUnderTest(expectedArchitecture), tasksToBuildAndRunUnitTest, expectedLifecycleTasks) + assertTestCasesRan() + + where: + task | expectedArchitecture | expectedLifecycleTasks + "test" | X86_64 | [":test"] + "check" | X86_64 | [":test", ":check"] + "build" | X86_64 | [":test", ":check", ":build", getTasksToAssembleComponentUnderTest(X86_64), ":assemble"] + } + + @Unroll + def "runs tests when #task lifecycle task executes and target machines are specified on the test component only"() { + given: + makeSingleProject() + writeTests() + configureTestTargetMachines("machines.os('${currentOsFamilyName}').architecture('${currentArchitecture}')") + + when: + succeeds(task) + + then: + result.assertTasksExecuted(tasksToCompileComponentUnderTest, tasksToBuildAndRunUnitTest, expectedLifecycleTasks) + assertTestCasesRan() + + where: + task | expectedLifecycleTasks + "test" | [":test"] + "check" | [":test", ":check"] + "build" | [":test", ":check", ":build", tasksToAssembleComponentUnderTest, ":assemble"] + } + + @Unroll + def "fails when target machines are specified on the test component that do not match those on the main component"() { + Assume.assumeFalse(componentUnderTestDsl == null) + + given: + makeSingleProject() + writeTests() + def otherArchitecture = currentArchitecture == 'x86' ? X86_64 : X86 + configureTargetMachines("machines.os('${currentOsFamilyName}').architecture('${currentArchitecture}')") + configureTestTargetMachines("machines.os('${currentOsFamilyName}').architecture('${otherArchitecture}')") + + expect: + fails("test") + + and: + failure.assertHasCause("The target machine ${currentOsFamilyName}:${otherArchitecture} was specified for the unit test, but this target machine was not specified on the main component.") + } + def "skips test tasks as up-to-date when nothing changes between invocation"() { given: makeSingleProject() @@ -77,6 +170,22 @@ result.assertTasksNotSkipped(tasksToBuildAndRunUnitTest, ":test") } + private void configureTargetMachines(String targetMachineDeclaration) { + buildFile << """ + ${componentUnderTestDsl} { + targetMachines = [${targetMachineDeclaration}] + } + """ + } + + private void configureTestTargetMachines(String targetMachineDeclaration) { + buildFile << """ + ${testComponentDsl} { + targetMachines = [${targetMachineDeclaration}] + } + """ + } + // Creates a single project build with no source protected abstract void makeSingleProject() @@ -89,13 +198,29 @@ // Asserts expected tests ran protected abstract void assertTestCasesRan() + // Gets the dsl extension for the component under test + protected abstract String getComponentUnderTestDsl() + + // Gets the dsl extension for the test component + protected abstract String getTestComponentDsl() + protected abstract String[] getTasksToBuildAndRunUnitTest() + protected abstract String[] getTasksToBuildAndRunUnitTest(String architecture) + protected String[] getTasksToCompileComponentUnderTest() { return [] } protected String[] getTasksToAssembleComponentUnderTest() { return [] } + + protected String[] getTasksToCompileComponentUnderTest(String architecture) { + return [] + } + + protected String[] getTasksToAssembleComponentUnderTest(String architecture) { + return [] + } } Index: subprojects/testing-native/src/integTest/groovy/org/gradle/nativeplatform/test/cpp/plugins/AbstractCppUnitTestIntegrationTest.groovy =================================================================== diff -u -N --- subprojects/testing-native/src/integTest/groovy/org/gradle/nativeplatform/test/cpp/plugins/AbstractCppUnitTestIntegrationTest.groovy (revision 0) +++ subprojects/testing-native/src/integTest/groovy/org/gradle/nativeplatform/test/cpp/plugins/AbstractCppUnitTestIntegrationTest.groovy (revision 3f66bf922f51cfd09a94cc0f892aa0e86ecdb483) @@ -0,0 +1,52 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.gradle.nativeplatform.test.cpp.plugins + +import org.gradle.nativeplatform.test.AbstractNativeUnitTestIntegrationTest + +abstract class AbstractCppUnitTestIntegrationTest extends AbstractNativeUnitTestIntegrationTest { + @Override + String getLanguageTaskSuffix() { + return "Cpp" + } + + @Override + protected String getTestComponentDsl() { + return "unitTest" + } + + @Override + String[] getTasksToBuildAndRunUnitTest() { + return getTasksToBuildAndRunUnitTest(null) + } + + @Override + protected String[] getTasksToBuildAndRunUnitTest(String architecture) { + def testTasks = tasks.withArchitecture(architecture).test + return [testTasks.compile, testTasks.link, testTasks.install] + testTasks.run + } + + @Override + protected String[] getTasksToCompileComponentUnderTest() { + return getTasksToCompileComponentUnderTest(null) + } + + @Override + protected String[] getTasksToAssembleComponentUnderTest() { + return getTasksToAssembleComponentUnderTest(null) + } +} Index: subprojects/testing-native/src/integTest/groovy/org/gradle/nativeplatform/test/cpp/plugins/CppUnitTestWithApplicationIntegrationTest.groovy =================================================================== diff -u -N -rf063b6e4a038f16cd75d2169feaf94bc9275916f -r3f66bf922f51cfd09a94cc0f892aa0e86ecdb483 --- subprojects/testing-native/src/integTest/groovy/org/gradle/nativeplatform/test/cpp/plugins/CppUnitTestWithApplicationIntegrationTest.groovy (.../CppUnitTestWithApplicationIntegrationTest.groovy) (revision f063b6e4a038f16cd75d2169feaf94bc9275916f) +++ subprojects/testing-native/src/integTest/groovy/org/gradle/nativeplatform/test/cpp/plugins/CppUnitTestWithApplicationIntegrationTest.groovy (.../CppUnitTestWithApplicationIntegrationTest.groovy) (revision 3f66bf922f51cfd09a94cc0f892aa0e86ecdb483) @@ -16,13 +16,12 @@ package org.gradle.nativeplatform.test.cpp.plugins -import org.gradle.nativeplatform.test.AbstractNativeUnitTestIntegrationTest import org.gradle.util.Requires import org.gradle.util.TestPrecondition // cpp-unit-test + cpp-application don't work together on Windows yet @Requires(TestPrecondition.NOT_WINDOWS) -class CppUnitTestWithApplicationIntegrationTest extends AbstractNativeUnitTestIntegrationTest { +class CppUnitTestWithApplicationIntegrationTest extends AbstractCppUnitTestIntegrationTest { @Override protected void makeSingleProject() { buildFile << """ @@ -69,17 +68,24 @@ } @Override - String[] getTasksToBuildAndRunUnitTest() { - return [":compileTestCpp", ":linkTest", ":installTest", ":runTest"] + protected String getComponentUnderTestDsl() { + return "application" } @Override - protected String[] getTasksToCompileComponentUnderTest() { - return [":compileDebugCpp", ":relocateMainForTest"] + protected String[] getTasksToBuildAndRunUnitTest(String architecture) { + return super.getTasksToBuildAndRunUnitTest(architecture) + tasks.withArchitecture(architecture).test.relocate } @Override - protected String[] getTasksToAssembleComponentUnderTest() { - return [":linkDebug", ":installDebug"] + protected String[] getTasksToCompileComponentUnderTest(String architecture) { + def debugTasks = tasks.withArchitecture(architecture).debug + return [debugTasks.compile] } + + @Override + protected String[] getTasksToAssembleComponentUnderTest(String architecture) { + def debugTasks = tasks.withArchitecture(architecture).debug + return [debugTasks.link, debugTasks.install] + } } Index: subprojects/testing-native/src/integTest/groovy/org/gradle/nativeplatform/test/cpp/plugins/CppUnitTestWithLibraryIntegrationTest.groovy =================================================================== diff -u -N -r2a73d216608b4811e29f6363500ebf4552b2133b -r3f66bf922f51cfd09a94cc0f892aa0e86ecdb483 --- subprojects/testing-native/src/integTest/groovy/org/gradle/nativeplatform/test/cpp/plugins/CppUnitTestWithLibraryIntegrationTest.groovy (.../CppUnitTestWithLibraryIntegrationTest.groovy) (revision 2a73d216608b4811e29f6363500ebf4552b2133b) +++ subprojects/testing-native/src/integTest/groovy/org/gradle/nativeplatform/test/cpp/plugins/CppUnitTestWithLibraryIntegrationTest.groovy (.../CppUnitTestWithLibraryIntegrationTest.groovy) (revision 3f66bf922f51cfd09a94cc0f892aa0e86ecdb483) @@ -16,9 +16,7 @@ package org.gradle.nativeplatform.test.cpp.plugins -import org.gradle.nativeplatform.test.AbstractNativeUnitTestIntegrationTest - -class CppUnitTestWithLibraryIntegrationTest extends AbstractNativeUnitTestIntegrationTest { +class CppUnitTestWithLibraryIntegrationTest extends AbstractCppUnitTestIntegrationTest { @Override protected void makeSingleProject() { buildFile << """ @@ -62,17 +60,19 @@ } @Override - String[] getTasksToBuildAndRunUnitTest() { - return [":compileTestCpp", ":linkTest", ":installTest", ":runTest"] + protected String[] getTasksToCompileComponentUnderTest(String architecture) { + def debugTasks = tasks.withArchitecture(architecture).debug + return [debugTasks.compile] } @Override - protected String[] getTasksToCompileComponentUnderTest() { - return [":compileDebugCpp"] + protected String[] getTasksToAssembleComponentUnderTest(String architecture) { + def debugTasks = tasks.withArchitecture(architecture).debug + return [debugTasks.link] } @Override - protected String[] getTasksToAssembleComponentUnderTest() { - return [":linkDebug"] + protected String getComponentUnderTestDsl() { + return "library" } } Index: subprojects/testing-native/src/integTest/groovy/org/gradle/nativeplatform/test/cpp/plugins/CppUnitTestWithoutComponentIntegrationTest.groovy =================================================================== diff -u -N -r2a73d216608b4811e29f6363500ebf4552b2133b -r3f66bf922f51cfd09a94cc0f892aa0e86ecdb483 --- subprojects/testing-native/src/integTest/groovy/org/gradle/nativeplatform/test/cpp/plugins/CppUnitTestWithoutComponentIntegrationTest.groovy (.../CppUnitTestWithoutComponentIntegrationTest.groovy) (revision 2a73d216608b4811e29f6363500ebf4552b2133b) +++ subprojects/testing-native/src/integTest/groovy/org/gradle/nativeplatform/test/cpp/plugins/CppUnitTestWithoutComponentIntegrationTest.groovy (.../CppUnitTestWithoutComponentIntegrationTest.groovy) (revision 3f66bf922f51cfd09a94cc0f892aa0e86ecdb483) @@ -16,9 +16,7 @@ package org.gradle.nativeplatform.test.cpp.plugins -import org.gradle.nativeplatform.test.AbstractNativeUnitTestIntegrationTest - -class CppUnitTestWithoutComponentIntegrationTest extends AbstractNativeUnitTestIntegrationTest { +class CppUnitTestWithoutComponentIntegrationTest extends AbstractCppUnitTestIntegrationTest { @Override protected void makeSingleProject() { buildFile << """ @@ -78,7 +76,7 @@ } @Override - String[] getTasksToBuildAndRunUnitTest() { - return [":compileTestCpp", ":linkTest", ":installTest", ":runTest"] + protected String getComponentUnderTestDsl() { + return null } } Index: subprojects/testing-native/src/integTest/groovy/org/gradle/nativeplatform/test/xctest/AbstractSwiftXCTestIntegrationTest.groovy =================================================================== diff -u -N -rf063b6e4a038f16cd75d2169feaf94bc9275916f -r3f66bf922f51cfd09a94cc0f892aa0e86ecdb483 --- subprojects/testing-native/src/integTest/groovy/org/gradle/nativeplatform/test/xctest/AbstractSwiftXCTestIntegrationTest.groovy (.../AbstractSwiftXCTestIntegrationTest.groovy) (revision f063b6e4a038f16cd75d2169feaf94bc9275916f) +++ subprojects/testing-native/src/integTest/groovy/org/gradle/nativeplatform/test/xctest/AbstractSwiftXCTestIntegrationTest.groovy (.../AbstractSwiftXCTestIntegrationTest.groovy) (revision 3f66bf922f51cfd09a94cc0f892aa0e86ecdb483) @@ -53,5 +53,30 @@ return [":compileTestSwift", ":linkTest", ":installTest", ":xcTest"] } + @Override + protected String getTestComponentDsl() { + return "xctest" + } + + @Override + protected String getComponentUnderTestDsl() { + return null + } + + @Override + protected String[] getTasksToBuildAndRunUnitTest(String architecture) { + return tasksToBuildAndRunUnitTest + } + + @Override + protected String[] getTasksToCompileComponentUnderTest(String architecture) { + return tasksToCompileComponentUnderTest + } + protected abstract XCTestSourceElement getPassingTestFixture() + + @Override + String getLanguageTaskSuffix() { + return "swift" + } } Index: subprojects/testing-native/src/integTest/groovy/org/gradle/nativeplatform/test/xctest/SwiftXCTestWithApplicationIntegrationTest.groovy =================================================================== diff -u -N -r2a73d216608b4811e29f6363500ebf4552b2133b -r3f66bf922f51cfd09a94cc0f892aa0e86ecdb483 --- subprojects/testing-native/src/integTest/groovy/org/gradle/nativeplatform/test/xctest/SwiftXCTestWithApplicationIntegrationTest.groovy (.../SwiftXCTestWithApplicationIntegrationTest.groovy) (revision 2a73d216608b4811e29f6363500ebf4552b2133b) +++ subprojects/testing-native/src/integTest/groovy/org/gradle/nativeplatform/test/xctest/SwiftXCTestWithApplicationIntegrationTest.groovy (.../SwiftXCTestWithApplicationIntegrationTest.groovy) (revision 3f66bf922f51cfd09a94cc0f892aa0e86ecdb483) @@ -48,4 +48,9 @@ apply plugin: 'swift-application' """ } + + @Override + protected String getComponentUnderTestDsl() { + return "application" + } } Index: subprojects/testing-native/src/integTest/groovy/org/gradle/nativeplatform/test/xctest/SwiftXCTestWithBothLibraryLinkageIntegrationTest.groovy =================================================================== diff -u -N -r2a73d216608b4811e29f6363500ebf4552b2133b -r3f66bf922f51cfd09a94cc0f892aa0e86ecdb483 --- subprojects/testing-native/src/integTest/groovy/org/gradle/nativeplatform/test/xctest/SwiftXCTestWithBothLibraryLinkageIntegrationTest.groovy (.../SwiftXCTestWithBothLibraryLinkageIntegrationTest.groovy) (revision 2a73d216608b4811e29f6363500ebf4552b2133b) +++ subprojects/testing-native/src/integTest/groovy/org/gradle/nativeplatform/test/xctest/SwiftXCTestWithBothLibraryLinkageIntegrationTest.groovy (.../SwiftXCTestWithBothLibraryLinkageIntegrationTest.groovy) (revision 3f66bf922f51cfd09a94cc0f892aa0e86ecdb483) @@ -48,4 +48,9 @@ library.linkage = [Linkage.SHARED, Linkage.STATIC] """ } + + @Override + protected String getComponentUnderTestDsl() { + return "library" + } } Index: subprojects/testing-native/src/integTest/groovy/org/gradle/nativeplatform/test/xctest/SwiftXCTestWithSharedLibraryLinkageIntegrationTest.groovy =================================================================== diff -u -N -r2a73d216608b4811e29f6363500ebf4552b2133b -r3f66bf922f51cfd09a94cc0f892aa0e86ecdb483 --- subprojects/testing-native/src/integTest/groovy/org/gradle/nativeplatform/test/xctest/SwiftXCTestWithSharedLibraryLinkageIntegrationTest.groovy (.../SwiftXCTestWithSharedLibraryLinkageIntegrationTest.groovy) (revision 2a73d216608b4811e29f6363500ebf4552b2133b) +++ subprojects/testing-native/src/integTest/groovy/org/gradle/nativeplatform/test/xctest/SwiftXCTestWithSharedLibraryLinkageIntegrationTest.groovy (.../SwiftXCTestWithSharedLibraryLinkageIntegrationTest.groovy) (revision 3f66bf922f51cfd09a94cc0f892aa0e86ecdb483) @@ -47,4 +47,9 @@ apply plugin: 'swift-library' """ } + + @Override + protected String getComponentUnderTestDsl() { + return "library" + } } Index: subprojects/testing-native/src/integTest/groovy/org/gradle/nativeplatform/test/xctest/SwiftXCTestWithStaticLibraryLinkageIntegrationTest.groovy =================================================================== diff -u -N -r2a73d216608b4811e29f6363500ebf4552b2133b -r3f66bf922f51cfd09a94cc0f892aa0e86ecdb483 --- subprojects/testing-native/src/integTest/groovy/org/gradle/nativeplatform/test/xctest/SwiftXCTestWithStaticLibraryLinkageIntegrationTest.groovy (.../SwiftXCTestWithStaticLibraryLinkageIntegrationTest.groovy) (revision 2a73d216608b4811e29f6363500ebf4552b2133b) +++ subprojects/testing-native/src/integTest/groovy/org/gradle/nativeplatform/test/xctest/SwiftXCTestWithStaticLibraryLinkageIntegrationTest.groovy (.../SwiftXCTestWithStaticLibraryLinkageIntegrationTest.groovy) (revision 3f66bf922f51cfd09a94cc0f892aa0e86ecdb483) @@ -48,4 +48,9 @@ library.linkage = [Linkage.STATIC] """ } + + @Override + protected String getComponentUnderTestDsl() { + return "library" + } } Index: subprojects/testing-native/src/integTest/groovy/org/gradle/nativeplatform/test/xctest/SwiftXCTestWithoutComponentIntegrationTest.groovy =================================================================== diff -u -N -r2a73d216608b4811e29f6363500ebf4552b2133b -r3f66bf922f51cfd09a94cc0f892aa0e86ecdb483 --- subprojects/testing-native/src/integTest/groovy/org/gradle/nativeplatform/test/xctest/SwiftXCTestWithoutComponentIntegrationTest.groovy (.../SwiftXCTestWithoutComponentIntegrationTest.groovy) (revision 2a73d216608b4811e29f6363500ebf4552b2133b) +++ subprojects/testing-native/src/integTest/groovy/org/gradle/nativeplatform/test/xctest/SwiftXCTestWithoutComponentIntegrationTest.groovy (.../SwiftXCTestWithoutComponentIntegrationTest.groovy) (revision 3f66bf922f51cfd09a94cc0f892aa0e86ecdb483) @@ -44,4 +44,9 @@ apply plugin: 'xctest' """ } + + @Override + protected String getComponentUnderTestDsl() { + return null + } } Index: subprojects/testing-native/src/main/java/org/gradle/nativeplatform/test/cpp/internal/DefaultCppTestSuite.java =================================================================== diff -u -N -r8926297c49e00be3062b1cbe51a325872676797b -r3f66bf922f51cfd09a94cc0f892aa0e86ecdb483 --- subprojects/testing-native/src/main/java/org/gradle/nativeplatform/test/cpp/internal/DefaultCppTestSuite.java (.../DefaultCppTestSuite.java) (revision 8926297c49e00be3062b1cbe51a325872676797b) +++ subprojects/testing-native/src/main/java/org/gradle/nativeplatform/test/cpp/internal/DefaultCppTestSuite.java (.../DefaultCppTestSuite.java) (revision 3f66bf922f51cfd09a94cc0f892aa0e86ecdb483) @@ -52,9 +52,9 @@ this.dependencies = objectFactory.newInstance(DefaultComponentDependencies.class, getNames().withSuffix("implementation")); } - public CppTestExecutable addExecutable(NativeVariantIdentity identity, CppPlatform targetPlatform, NativeToolChainInternal toolChain, PlatformToolProvider platformToolProvider) { - CppTestExecutable testBinary = objectFactory.newInstance(DefaultCppTestExecutable.class, Names.of(getName() + "Executable", getName()), getBaseName(), getCppSource(), getPrivateHeaderDirs(), getImplementationDependencies(), getTestedComponent(), targetPlatform, toolChain, platformToolProvider, identity); - this.testBinary.set(testBinary); + public CppTestExecutable addExecutable(String variantName, NativeVariantIdentity identity, CppPlatform targetPlatform, NativeToolChainInternal toolChain, PlatformToolProvider platformToolProvider) { + Names executableNames = Names.of(getName() + variantName + "Executable", getName() + variantName); + CppTestExecutable testBinary = objectFactory.newInstance(DefaultCppTestExecutable.class, executableNames, getBaseName(), getCppSource(), getPrivateHeaderDirs(), getImplementationDependencies(), getTestedComponent(), targetPlatform, toolChain, platformToolProvider, identity); getBinaries().add(testBinary); return testBinary; } Index: subprojects/testing-native/src/main/java/org/gradle/nativeplatform/test/cpp/plugins/CppUnitTestPlugin.java =================================================================== diff -u -N -r42907f59a51366a8a05bdb3b61f054906bad8fa9 -r3f66bf922f51cfd09a94cc0f892aa0e86ecdb483 --- subprojects/testing-native/src/main/java/org/gradle/nativeplatform/test/cpp/plugins/CppUnitTestPlugin.java (.../CppUnitTestPlugin.java) (revision 42907f59a51366a8a05bdb3b61f054906bad8fa9) +++ subprojects/testing-native/src/main/java/org/gradle/nativeplatform/test/cpp/plugins/CppUnitTestPlugin.java (.../CppUnitTestPlugin.java) (revision 3f66bf922f51cfd09a94cc0f892aa0e86ecdb483) @@ -31,6 +31,7 @@ import org.gradle.api.internal.project.ProjectInternal; import org.gradle.api.model.ObjectFactory; import org.gradle.api.provider.Provider; +import org.gradle.api.provider.SetProperty; import org.gradle.api.specs.Spec; import org.gradle.api.tasks.TaskContainer; import org.gradle.api.tasks.TaskProvider; @@ -46,26 +47,30 @@ import org.gradle.language.internal.NativeComponentFactory; import org.gradle.language.nativeplatform.internal.toolchains.ToolChainSelector; import org.gradle.language.swift.tasks.UnexportMainSymbol; +import org.gradle.nativeplatform.MachineArchitecture; +import org.gradle.nativeplatform.OperatingSystemFamily; import org.gradle.nativeplatform.TargetMachine; import org.gradle.nativeplatform.TargetMachineFactory; +import org.gradle.nativeplatform.internal.DefaultTargetMachineFactory; import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform; import org.gradle.nativeplatform.tasks.InstallExecutable; +import org.gradle.nativeplatform.test.cpp.CppTestExecutable; import org.gradle.nativeplatform.test.cpp.CppTestSuite; import org.gradle.nativeplatform.test.cpp.internal.DefaultCppTestExecutable; import org.gradle.nativeplatform.test.cpp.internal.DefaultCppTestSuite; import org.gradle.nativeplatform.test.plugins.NativeTestingBasePlugin; import org.gradle.nativeplatform.test.tasks.RunTestExecutable; -import org.gradle.util.CollectionUtils; +import javax.annotation.Nullable; import javax.inject.Inject; import java.util.Set; import java.util.concurrent.Callable; +import java.util.stream.Collectors; import static org.gradle.language.cpp.CppBinary.DEBUGGABLE_ATTRIBUTE; import static org.gradle.language.cpp.CppBinary.OPTIMIZED_ATTRIBUTE; -import static org.gradle.language.nativeplatform.internal.Dimensions.setDefaultAndGetTargetMachineValues; +import static org.gradle.language.nativeplatform.internal.Dimensions.createDimensionSuffix; - /** * A plugin that sets up the infrastructure for testing C++ binaries using a simple test executable. * @@ -105,21 +110,21 @@ project.afterEvaluate(new Action() { @Override public void execute(final Project project) { - Set targetMachines = setDefaultAndGetTargetMachineValues(testComponent.getTargetMachines(), targetMachineFactory); + final ProductionCppComponent mainComponent = project.getComponents().withType(ProductionCppComponent.class).findByName("main"); + + Set targetMachines; + if (mainComponent != null) { + testComponent.getTestedComponent().set(mainComponent); + targetMachines = setDefaultAndGetTargetMachineValues(testComponent.getTargetMachines(), mainComponent.getTargetMachines()); + } else { + targetMachines = setDefaultAndGetTargetMachineValues(testComponent.getTargetMachines(), null); + } + if (targetMachines.isEmpty()) { throw new IllegalArgumentException("A target machine needs to be specified for the unit test."); } - // TODO: should we not iterate over target machines? - TargetMachine targetMachine = CollectionUtils.findFirst(targetMachines, new Spec() { - @Override - public boolean isSatisfiedBy(TargetMachine targetMachine) { - return DefaultNativePlatform.getCurrentOperatingSystem().toFamilyName().equals(targetMachine.getOperatingSystemFamily().getName()); - } - }); - - if (targetMachine != null) { - String operatingSystemSuffix = ""; + for (TargetMachine targetMachine : targetMachines) { Usage runtimeUsage = objectFactory.named(Usage.class, Usage.NATIVE_RUNTIME); Provider group = project.provider(new Callable() { @Override @@ -139,95 +144,134 @@ attributesDebug.attribute(Usage.USAGE_ATTRIBUTE, runtimeUsage); attributesDebug.attribute(DEBUGGABLE_ATTRIBUTE, true); attributesDebug.attribute(OPTIMIZED_ATTRIBUTE, false); + attributesDebug.attribute(MachineArchitecture.ARCHITECTURE_ATTRIBUTE, targetMachine.getArchitecture()); + attributesDebug.attribute(OperatingSystemFamily.OPERATING_SYSTEM_ATTRIBUTE, targetMachine.getOperatingSystemFamily()); - // TODO: Fix this naming convention to follow C++ executable/library - NativeVariantIdentity debugVariant = new NativeVariantIdentity("debug" + operatingSystemSuffix, testComponent.getBaseName(), group, version, true, false, targetMachine, - null, - new DefaultUsageContext("debug" + operatingSystemSuffix + "Runtime", runtimeUsage, attributesDebug)); + String operatingSystemSuffix = createDimensionSuffix(targetMachine.getOperatingSystemFamily(), targetMachines.stream().map(TargetMachine::getOperatingSystemFamily).collect(Collectors.toSet())); + String architectureSuffix = createDimensionSuffix(targetMachine.getArchitecture(), targetMachines.stream().map(TargetMachine::getArchitecture).collect(Collectors.toSet())); + String variantName = operatingSystemSuffix + architectureSuffix; - ToolChainSelector.Result result = toolChainSelector.select(CppPlatform.class, targetMachine); - testComponent.addExecutable(debugVariant, result.getTargetPlatform(), result.getToolChain(), result.getPlatformToolProvider()); - // TODO: Publishing for test executable? + NativeVariantIdentity debugVariant = new NativeVariantIdentity("debug" + variantName, testComponent.getBaseName(), group, version, true, false, targetMachine, + null, + new DefaultUsageContext("debug" + variantName + "Runtime", runtimeUsage, attributesDebug)); - final TaskContainer tasks = project.getTasks(); - final ProductionCppComponent mainComponent = project.getComponents().withType(ProductionCppComponent.class).findByName("main"); - if (mainComponent != null) { - testComponent.getTestedComponent().set(mainComponent); + if (DefaultNativePlatform.getCurrentOperatingSystem().toFamilyName().equals(targetMachine.getOperatingSystemFamily().getName())) { + ToolChainSelector.Result result = toolChainSelector.select(CppPlatform.class, targetMachine); + CppTestExecutable testExecutable = testComponent.addExecutable(variantName, debugVariant, result.getTargetPlatform(), result.getToolChain(), result.getPlatformToolProvider()); + + // If we have a mainComponent set, we'll derive the main test binary from the main component development binary later, + // otherwise we set it to the executable that matches the current architecture. + if (mainComponent == null && DefaultNativePlatform.getCurrentArchitecture().equals(result.getTargetPlatform().getArchitecture())) { + testComponent.getTestBinary().set(testExecutable); + } + + // TODO: Publishing for test executable? } + } - testComponent.getBinaries().whenElementKnown(DefaultCppTestExecutable.class, new Action() { - @Override - public void execute(final DefaultCppTestExecutable executable) { - if (mainComponent != null) { - mainComponent.getBinaries().whenElementFinalized(new Action() { - @Override - public void execute(final CppBinary testedBinary) { - if (testedBinary != mainComponent.getDevelopmentBinary().get()) { - return; - } + final TaskContainer tasks = project.getTasks(); + testComponent.getBinaries().whenElementKnown(DefaultCppTestExecutable.class, new Action() { + @Override + public void execute(final DefaultCppTestExecutable testExecutable) { + if (mainComponent != null) { + mainComponent.getBinaries().whenElementFinalized(new Action() { + @Override + public void execute(final CppBinary testedBinary) { + // TODO: Make this more intelligent by matching the attributes of the runtime usage on the variant identities + if (testedBinary.getTargetPlatform().getOperatingSystemFamily().getName() != testExecutable.getTargetPlatform().getOperatingSystemFamily().getName() + || testedBinary.getTargetPlatform().getArchitecture().getName() != testExecutable.getTargetPlatform().getArchitecture().getName() + || testedBinary.isOptimized()) { + return; + } - // TODO - move this to a base plugin - // Setup the dependency on the main binary - // This should all be replaced by a single dependency that points at some "testable" variants of the main binary + // TODO - move this to a base plugin + // Setup the dependency on the main binary + // This should all be replaced by a single dependency that points at some "testable" variants of the main binary - // Inherit implementation dependencies - executable.getImplementationDependencies().extendsFrom(((DefaultCppBinary) testedBinary).getImplementationDependencies()); + // Inherit implementation dependencies + testExecutable.getImplementationDependencies().extendsFrom(((DefaultCppBinary) testedBinary).getImplementationDependencies()); - // Configure test binary to link against tested component compiled objects - ConfigurableFileCollection testableObjects = project.files(); - if (mainComponent instanceof CppApplication) { - TaskProvider unexportMainSymbol = tasks.register("relocateMainForTest", UnexportMainSymbol.class, new Action() { - @Override - public void execute(UnexportMainSymbol unexportMainSymbol) { - unexportMainSymbol.getOutputDirectory().set(project.getLayout().getBuildDirectory().dir("obj/main/for-test")); - unexportMainSymbol.getObjects().from(testedBinary.getObjects()); - } - }); - // TODO: builtBy unnecessary? - testableObjects.builtBy(unexportMainSymbol); - testableObjects.from(unexportMainSymbol.map(new Transformer() { - @Override - public FileCollection transform(UnexportMainSymbol unexportMainSymbol) { - return unexportMainSymbol.getRelocatedObjects(); - } - })); - } else { - testableObjects.from(testedBinary.getObjects()); - } - Dependency linkDependency = project.getDependencies().create(testableObjects); - executable.getLinkConfiguration().getDependencies().add(linkDependency); + // Configure test binary to link against tested component compiled objects + ConfigurableFileCollection testableObjects = project.files(); + if (mainComponent instanceof CppApplication) { + TaskProvider unexportMainSymbol = tasks.register(testExecutable.getNames().getTaskName("relocateMainFor"), UnexportMainSymbol.class, new Action() { + @Override + public void execute(UnexportMainSymbol unexportMainSymbol) { + unexportMainSymbol.getOutputDirectory().set(project.getLayout().getBuildDirectory().dir("obj/main/for-test")); + unexportMainSymbol.getObjects().from(testedBinary.getObjects()); + } + }); + // TODO: builtBy unnecessary? + testableObjects.builtBy(unexportMainSymbol); + testableObjects.from(unexportMainSymbol.map(new Transformer() { + @Override + public FileCollection transform(UnexportMainSymbol unexportMainSymbol) { + return unexportMainSymbol.getRelocatedObjects(); + } + })); + } else { + testableObjects.from(testedBinary.getObjects()); } - }); - } + Dependency linkDependency = project.getDependencies().create(testableObjects); + testExecutable.getLinkConfiguration().getDependencies().add(linkDependency); - // TODO: Replace with native test task - final TaskProvider testTask = tasks.register(executable.getNames().getTaskName("run"), RunTestExecutable.class, new Action() { - @Override - public void execute(RunTestExecutable testTask) { - testTask.setGroup(LifecycleBasePlugin.VERIFICATION_GROUP); - testTask.setDescription("Executes C++ unit tests."); - - final InstallExecutable installTask = executable.getInstallTask().get(); - testTask.onlyIf(new Spec() { - @Override - public boolean isSatisfiedBy(Task element) { - return executable.getInstallDirectory().get().getAsFile().exists(); - } - }); - testTask.getInputs().dir(executable.getInstallDirectory()); - testTask.setExecutable(installTask.getRunScriptFile().get().getAsFile()); - testTask.dependsOn(testComponent.getTestBinary().get().getInstallDirectory()); - // TODO: Honor changes to build directory - testTask.setOutputDir(project.getLayout().getBuildDirectory().dir("test-results/" + executable.getNames().getDirName()).get().getAsFile()); + // Set this as the main test binary if it tests the main development binary + if (testedBinary == mainComponent.getDevelopmentBinary().get()) { + testComponent.getTestBinary().set(testExecutable); + } } }); - executable.getRunTask().set(testTask); } - }); - } + // TODO: Replace with native test task + final TaskProvider testTask = tasks.register(testExecutable.getNames().getTaskName("run"), RunTestExecutable.class, new Action() { + @Override + public void execute(RunTestExecutable testTask) { + testTask.setGroup(LifecycleBasePlugin.VERIFICATION_GROUP); + testTask.setDescription("Executes C++ unit tests."); + + final InstallExecutable installTask = testExecutable.getInstallTask().get(); + testTask.onlyIf(new Spec() { + @Override + public boolean isSatisfiedBy(Task element) { + return testExecutable.getInstallDirectory().get().getAsFile().exists(); + } + }); + testTask.getInputs().dir(testExecutable.getInstallDirectory()); + testTask.setExecutable(installTask.getRunScriptFile().get().getAsFile()); + testTask.dependsOn(testExecutable.getInstallDirectory()); + // TODO: Honor changes to build directory + testTask.setOutputDir(project.getLayout().getBuildDirectory().dir("test-results/" + testExecutable.getNames().getDirName()).get().getAsFile()); + } + }); + testExecutable.getRunTask().set(testTask); + } + }); + testComponent.getBinaries().realizeNow(); } }); } + + private Set setDefaultAndGetTargetMachineValues(SetProperty testTargetMachines, @Nullable SetProperty mainTargetMachines) { + if (mainTargetMachines != null && mainTargetMachines.isPresent()) { + if (!testTargetMachines.isPresent()) { + testTargetMachines.set(mainTargetMachines); + } else { + Set mainComponentTargetMachines = mainTargetMachines.get(); + for (TargetMachine machine : testTargetMachines.get()) { + if (!mainComponentTargetMachines.contains(machine)) { + throw new IllegalArgumentException("The target machine " + machine.toString() + " was specified for the unit test, but this target machine was not specified on the main component."); + } + } + } + } else { + if (!testTargetMachines.isPresent()) { + testTargetMachines.empty().add(((DefaultTargetMachineFactory)targetMachineFactory).host()); + } + } + + testTargetMachines.finalizeValue(); + return testTargetMachines.get(); + } } Index: subprojects/testing-native/src/test/groovy/org/gradle/nativeplatform/test/cpp/internal/DefaultCppTestSuiteTest.groovy =================================================================== diff -u -N -r8926297c49e00be3062b1cbe51a325872676797b -r3f66bf922f51cfd09a94cc0f892aa0e86ecdb483 --- subprojects/testing-native/src/test/groovy/org/gradle/nativeplatform/test/cpp/internal/DefaultCppTestSuiteTest.groovy (.../DefaultCppTestSuiteTest.groovy) (revision 8926297c49e00be3062b1cbe51a325872676797b) +++ subprojects/testing-native/src/test/groovy/org/gradle/nativeplatform/test/cpp/internal/DefaultCppTestSuiteTest.groovy (.../DefaultCppTestSuiteTest.groovy) (revision 3f66bf922f51cfd09a94cc0f892aa0e86ecdb483) @@ -48,8 +48,8 @@ def "can add executable"() { expect: - def exe = testSuite.addExecutable(identity, Stub(CppPlatform), Stub(NativeToolChainInternal), Stub(PlatformToolProvider)) - exe.name == 'testExecutable' + def exe = testSuite.addExecutable("Foo", identity, Stub(CppPlatform), Stub(NativeToolChainInternal), Stub(PlatformToolProvider)) + exe.name == 'testFooExecutable' } private NativeVariantIdentity getIdentity() {