com.ullink.gradle.nunit.NUnit.groovy Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gradle-nunit-plugin Show documentation
Show all versions of gradle-nunit-plugin Show documentation
gradle-nunit-plugin is a Gradle plugin that enables NUnit testing
package com.ullink.gradle.nunit
import org.gradle.api.internal.ConventionTask
import groovyx.gpars.GParsPool
import org.gradle.api.GradleException
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction
import static org.apache.tools.ant.taskdefs.condition.Os.*
class Wrapper {
def value;
Wrapper() {
value = ""
}
}
class NUnit extends ConventionTask {
def nunitHome
def nunitVersion
def nunitDownloadUrl
List testAssemblies
def framework
def verbosity
def config
def timeout
def labels
def reportFolder
boolean useX86 = false
boolean shadowCopy = false
String reportFileName = 'TestResult.xml'
static final String DEFAULT_REPORT_FILE_NAME = 'TestResult.xml'
def logFile
boolean ignoreFailures = false
boolean parallelForks = true
def test = Wrapper.newInstance()
def where = Wrapper.newInstance()
def testList
Map env = [:]
NUnit() {
conventionMapping.map "reportFolder", { new File(outputFolder, 'reports') }
inputs.files {
getTestAssemblies()
}
doFirst {
// ensure NUnit is downloaded before performing TaskAction for parallel run
ensureNunitInstalled()
}
}
boolean getIsV3() {
getIsV3(getNunitVersion())
}
static boolean getIsV3(def version) {
version.startsWith('3.')
}
boolean getIsV35OrAbove() {
def (major, minor, patch) = getNunitVersion().tokenize('.')*.toInteger()
major == 3 && minor >= 5
}
String getGitHubRepoName() {
if (isV35OrAbove) {
return 'nunit-console'
}
if (isV3) {
return 'nunit'
}
return 'nunitv2'
}
void setNunitVersion(def version) {
this.nunitVersion = version
if (getIsV3(version)) {
this.metaClass.mixin NUnit3Mixins
}
}
void setTest(def input) {
setTestInternal(test, where, input)
}
File nunitBinFile(String file) {
def nunitFolder
if (getNunitHome()) {
nunitFolder = getNunitHome()
} else {
ensureNunitInstalled()
nunitFolder = getCachedNunitDir()
}
new File(project.file(nunitFolder), "${isV35OrAbove ? '' : 'bin/'}${file}")
}
void ensureNunitInstalled() {
if (getNunitHome()) {
return;
}
def nunitCacheDir = getCacheDir()
if (!nunitCacheDir.exists()) {
nunitCacheDir.mkdirs()
}
def nunitFolder = getCachedNunitDir()
if (!nunitFolder.exists()) {
downloadNUnit()
}
}
File getCachedNunitDir() {
new File(getCacheDir(), getNunitName())
}
File getCacheDir() {
new File(new File(project.gradle.gradleUserHomeDir, 'caches'), 'nunit')
}
String getNunitName() {
if (isV35OrAbove) {
return "NUnit.Console-${getNunitVersion()}"
}
"NUnit-${getNunitVersion()}"
}
String getFixedDownloadVersion() {
def version = getNunitVersion()
if (isV35OrAbove && version.endsWith('.0')) {
return version.take(version.length() - 2)
}
version
}
void downloadNUnit() {
def NUnitZipFile = getNunitName() + '.zip'
def downloadedFile = new File(getTemporaryDir(), NUnitZipFile)
def nunitCacheDirForVersion = getCachedNunitDir()
def version = getNunitVersion()
def nunitDownloadUrl = "${getNunitDownloadUrl()}/${fixedDownloadVersion}/$NUnitZipFile"
// special handling for nunit3 flat zip file
def zipOutputDir = isV3 ? nunitCacheDirForVersion : getCacheDir();
project.logger.info "Downloading & Unpacking NUnit ${version} from ${nunitDownloadUrl}"
project.download {
src "$nunitDownloadUrl"
dest downloadedFile
}
project.copy {
from project.zipTree(downloadedFile)
into zipOutputDir
}
}
File getOutputFolder() {
new File(project.buildDir, 'nunit')
}
File getReportFolderImpl() {
project.file(getReportFolder())
}
@OutputFile
File getTestReportPath() {
// for the non-default nunit tasks, ensure we write the report in a separate file
if (reportFileName.equals(DEFAULT_REPORT_FILE_NAME)) {
def reportFileNamePrefix = name == 'nunit' ? '' : name
new File(getReportFolderImpl(), reportFileNamePrefix + reportFileName)
} else {
new File(getReportFolderImpl(), reportFileName)
}
}
File getTestLogFile() {
project.file(getLogFile())
}
@TaskAction
def build() {
decideExecutionPath(this.&singleRunExecute, this.&multipleRunsExecute)
}
def decideExecutionPath(Closure singleRunAction, Closure multipleRunsAction) {
def input = getRunActionInput();
if (!parallelForks || !input) {
return singleRunAction(input)
} else {
return multipleRunsAction(input)
}
}
def singleRunExecute(def input) {
def runs = getTestInputsAsString(input)
run(runs, getTestReportPath())
}
def multipleRunsExecute(def input) {
def intermediateReportsPath = new File(getReportFolderImpl(), "intermediate-results-" + name)
intermediateReportsPath.mkdirs()
def runs = getTestInputAsList(input)
GParsPool.withPool {
runs.eachParallel {
def fileName = toFileName(it)
logger.info("Filename generated for the \'$it\' input was \'$fileName\'")
run(it, new File(intermediateReportsPath, fileName + ".xml"))
}
}
def files = intermediateReportsPath.listFiles().toList()
def outputFile = getTestReportPath()
logger.info("Merging test reports $files into $outputFile ...")
new NUnitTestResultsMerger().merge(files, outputFile)
}
// Used by gradle-opencover-plugin
def getCommandArgs() {
def testRuns = getTestInputsAsString(getRunActionInput())
buildCommandArgs (testRuns, getTestReportPath())
}
List getTestInputAsList(def testInput) {
if (!testInput) {
return []
}
if (testInput instanceof List) {
return testInput
}
// Behave like NUnit
if (isACommaSeparatedList(testInput)) {
return testInput.tokenize(',')
}
return [testInput]
}
Boolean isACommaSeparatedList(def input) {
return input != null && input.contains(',');
}
String getTestInputsAsString(def testInput) {
if (!testInput) {
return ''
}
if (testInput instanceof String) {
return testInput
}
return combine(testInput)
}
def run(def input, def reportPath) {
def cmdLine = [getNunitExec().absolutePath, *buildCommandArgs(input, reportPath)]
if (!isFamily(FAMILY_WINDOWS)) {
cmdLine = ["mono", *cmdLine]
}
execute(cmdLine)
}
// Return values of nunit v2 and v3 are defined in
// https://github.com/nunit/nunitv2/blob/master/src/ConsoleRunner/nunit-console/ConsoleUi.cs and
// https://github.com/nunit/nunit/blob/master/src/NUnitConsole/nunit-console/ConsoleRunner.cs
def execute(commandLineExec) {
prepareExecute()
def mbr = project.exec {
if (env)
environment env
commandLine = commandLineExec
ignoreExitValue = ignoreFailures
}
int exitValue = mbr.exitValue
if (exitValue == 0) {
return
}
boolean anyTestFailing = exitValue > 0
if (anyTestFailing && ignoreFailures) {
return
}
throw new GradleException("${getNunitExec()} execution failed (ret=${mbr.exitValue})");
}
def prepareExecute() {
getReportFolderImpl().mkdirs()
if (logFile)
getTestLogFile().getParentFile().mkdirs()
}
def buildCommandArgs(def testInput, def testReportPath) {
def commandLineArgs = []
String verb = verbosity
if (!verb) {
if (logger.debugEnabled) {
verb = 'Verbose'
} else if (logger.infoEnabled) {
verb = 'Info'
} else {
// 'quiet'
verb = 'Warning'
}
}
if (verb) {
commandLineArgs += "-trace=$verb"
}
if (framework) {
commandLineArgs += "-framework:$framework"
}
if (config) {
commandLineArgs += "-config:$config"
}
if (labels) {
commandLineArgs += "-labels:$labels"
}
if (timeout) {
commandLineArgs += "-timeout:$timeout"
}
if (logFile) {
commandLineArgs += "-output:${getTestLogFile().getPath()}"
}
commandLineArgs += "-work:$outputFolder"
commandLineArgs += buildAdditionalCommandArgs(testInput, testReportPath)
getTestAssemblies().each {
def file = project.file(it)
if (file.exists())
commandLineArgs += file
else
commandLineArgs += it
}
commandLineArgs
}
}