We are having a project that contains some integration tests, that require exclusive usage of system resources (in particular: filesystem and multicast networks).
In order to achieve that, we have a build along these lines (just paste somewhere and run):
apply plugin: 'java'
// we are generating this file just to trigger the Test task, so we can illustrate the error
file('src/test/java/foo.java').with { parentFile.mkdirs(); it.text = 'class foo {}'}
tasks.withType(Test) {
int i = 0
def singleUseTempDir = {
def temp = file("build/temp/test-${i++}")
temp.mkdirs()
return temp
}
systemProperties = [workDir: "${->singleUseTempDir()}" ]
}
Unfortunately, while the test task works great, with each spawned JVM having unique workDir, if all the tests succeed, the Gradle change detection bombs with MapSerializer$EntrySerializationException: Unable to write entry with key: 'systemProperties' and value: '{workDir=C:\sandbox\doodles\...}' .
The workaround is to disable the up-to-date check using outputs.upToDateWhen { false }, but I am wondering whether there is a way to have both dynamic resource allocation and UP-TO-DATE detection?
I don’t fully understand the details of GStrings and "${->}", but I could get it to work without it by moving i around:
apply plugin: 'java'
// we are generating this file just to trigger the Test task, so we can illustrate the error
file('src/test/java/foo.java').with { parentFile.mkdirs(); it.text = 'class foo {}'}
tasks.check.dependsOn tasks.create( 'abc', Test )
tasks.check.dependsOn tasks.create( 'def', Test )
int i = 0
tasks.withType(Test) {
def singleUseTempDir = {
def temp = file("build/temp/test-${i++}")
temp.mkdirs()
return temp
}
systemProperties = [workDir: "${singleUseTempDir()}" ]
doLast {
println systemProperties
}
}