From b13081fbe862a82ea1303cccb90d024c5a6035a4 Mon Sep 17 00:00:00 2001 From: adamopolous Date: Mon, 10 Aug 2020 13:38:49 -0400 Subject: [PATCH] added task to handle targeted project testing --- gradle/root/test.gradle | 71 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/gradle/root/test.gradle b/gradle/root/test.gradle index a51bd874e5..f2b30608aa 100644 --- a/gradle/root/test.gradle +++ b/gradle/root/test.gradle @@ -89,13 +89,19 @@ project.ext.userHome = System.properties.get("user.home") // Enable this mode if 'parallelCombinedTestReport' invoked in the command line. project.ext.parallelMode = project.gradle.startParameter.taskNames.contains('parallelCombinedTestReport') +project.ext.targetMode = project.gradle.startParameter.taskNames.contains('targetedTestReport') + +project.ext.targetFiles = targetMode ? project.getProperty('targetFiles') : null + +project.ext.targetProjects = targetMode ? getTestProjects(targetFiles) : null + // 'parallelCombinedTestReport' task will parse a JUnit test report for test duration. // Specify the location of the report via cmd line using "-PtestTimeParserInputDir=". // If the location is not specified via cmd line, it will look for the latest test report // in /../reportsArchive/reports_ // If a reportsArchive path does not exist, it will assume all tests have the same duration and // continue with test task creation. - project.ext.testTimeParserInputDir = project.hasProperty('testTimeParserInputDir') ? +project.ext.testTimeParserInputDir = project.hasProperty('testTimeParserInputDir') ? project.getProperty('testTimeParserInputDir') + "/reports/classes" : getLastArchivedReport("$reportArchivesDir") + "/classes" // A port of 0 will allow the kernel to give a free port number in the set of "User" @@ -132,6 +138,39 @@ def getLogFileUrl() { throw new GradleException("Cannot find log4j properties file using path '$logFilePath'") } +/** + * Given a set of files (passed in via the -PtargetFiles command line param), this + * will search the project tree for each files' package to see if there is a test + * class defined that can be run. + * + * The param is a list of file paths created by 'git diff --names-only' + */ +def List getTestProjects(String files) { + + List projects = new ArrayList<>(); + + List paths = files.tokenize('%') + + for (String path : paths) { + File file = new File(path) // might blow up? + + // Find the project for this file + def ps + while (file.parentFile != null) { + ps = rootProject.allprojects.findAll { it.projectDir == file } + if (ps) { + ps.each { + projects.add(it) + } + break; + } + file = file.parentFile + } + } + + return projects +} + /********************************************************************************* * Creates a new debug port randomly. *********************************************************************************/ @@ -345,6 +384,36 @@ task integrationTestReport(type: TestReport) { t -> outputs.upToDateWhen {false} } +/********************************************************************************* + * TARGETED TEST REPORT + * + * Summary: Runs unit tests against a set of projects + * + * The projects to be run against are stored in the project.ext.targetProjects + * var, which is populated at the top of this file. This is currently only + * used by the runAllTests.sh script which executes this task on each commit, + * so we can run all the tests for the files contained in that commit. + * + *********************************************************************************/ +task targetedTestReport(type: TestReport) { t -> + group "test" + description "Run unit tests against a specific set of projects." + destinationDir = file("$reportDir/unitTests") + outputs.upToDateWhen {false} + dependsOn ":deleteTestTempAndReportDirs" + + // This is a bit tricky but the tasks for each project are not yet defined + // at this point, so we have to put this in an afterEvaluate block before + // we can set up the reportOn dependency + project.ext.targetProjects.each { + it.afterEvaluate { p -> + if (p.tasks.findByName('test')) { + reportOn p.test + } + } + } +} + /********************************************************************************* * Create a task of type: Test for a subproject.