Gradle - Test tasks results not cached - java

"Test" tasks in my multi-module build are not being cached by Gradle. Incremental build works fine and reports everything as up-to-date, but if I perform clean build tests are always executed.
I am seeing this message Non-cacheable because 'Task outputs cacheable' not satisfied [ENABLE_CONDITION_NOT_SATISFIED] for all the test tasks if org.gradle.caching.debug parameter set to true. All fingerprints are identical between executions.
Any ideas what does it mean and/or how to fix it?
P.S. Using Gradle 6.7 with Junit 5 and JaCoCo. Disabling JaCoCo does not change anything.

Related

How to build only modified modules and dependencies in Gradle

I use gitflow-incremental-builder with Maven in a monorepo model. It allows me to:
Build only these modules in feature branch that differ from main branch.
Build only these modules that changed from last successful build tag.
When a library changes, build all the modules that use it.
Build a library if needed for modules, but if nothing changed, skip tests (skipTestsForUpstreamModules)
Force build all.
Changes are resolved using git log and then it affects the reactor config.
I am looking for a similar tool that will do it for Gradle.
Gradle Build Cache will automatically track the inputs and outputs of tasks and will skip any that have not changed.
Enabling Gradle Build Cache
It can be enabled locally by adding in gradle.properties
org.gradle.caching=true
or by adding a flag to the command line
./gradlew tests --build-cache
Sharing the build cache
The build cache for a project can be shared across multiple machines over HTTP. Sharing the build cache remotely isn't necessary - it can still work, even if the cache is stored locally.
Register task inputs
Gradle needs to know about the all inputs and outputs of tasks, otherwise tasks might be skipped, so make sure they are correctly registered.
For example, if some integration tests depend on an environment variable, then register the environment variable as a test-task input.
// build.gradle.kts
tasks.named("integrationTest") {
// TEST_TASK_QUALITY is used in integration tests to change <blah blah blah>
// register it as an input so Gradle knows when to re-run the tests
inputs.property("TEST_TASK_QUALITY", providers.environmentVariable("TEST_TASK_QUALITY"))
}
Stable task outputs
Gradle will use the outputs of some tasks as the inputs of other tasks. If the outputs aren't stable, then Gradle will always re-run the dependent tasks.
For that reason, it's worth enabling reproducible builds in all projects.
// build.gradle.kts
tasks.withType<AbstractArchiveTask>().configureEach {
isPreserveFileTimestamps = false
isReproducibleFileOrder = true
}
Also, consider input normalization for any custom files your project has.

Increase the speed of Maven release prepare and perform task?

I've found some ways to increase the speed of our standard maven builds such as only building modules that have changed and utilising parallel builds. For the task:
clean release:prepare release:perform
It takes a while and I'd like to speed up. It seems the parallel builds doesn't work I get an error. Any suggestions on how to speed up? I assume I could skip tests and they're already being done on the builds on the dev branch before it's merged with master?
The error I get when running parallel builds is:
[ERROR] NullPointerException
[ERROR] java.util.concurrent.ExecutionException: java.lang.NullPointerException
This seems to be the only error I get - not sure why?

IntelliJ doesn't run updated code and runs code from previous branch

I have a project that uses a Java test framework (cucumber) to run against a Python job (does some SQL querying)
The project is build with Gradle and spins up a docker instance for the Python environment to run the tests against.
However debugging is proving difficult because When I make chances to the python code it is not picked up when rerunning the tests - resulting in the same result (failure) as the previous run.
I noticed the Build files are not being updated, but even when i have done this manually and re-ran the tests again I get the same result.
I have tried 'Invalidate Caches/Restart' but had no joy.
I have tried reimporting the project but no joy.
I then tried to swap branch back to master and ran the 'working' tests but got a failed result that would only have come from the code in the feature branch.
My knowledge is a limited but a logical guess is the code is being packaged/wrapped up somewhere and not being refreshed(cached) on each test run.
I have also tried deleting IntelliJ's run configuration for the tests.
So I am now a little lost to where it could be caching this so I can clear it and hopefully it picks up the new changes.
Thanks
Did you looked in the gradle build output? try running the gradle build with --info, that will show you if the gradle build identify the changes in the python files or not.
If not , add the python sources to jar task dependencies:
task createJar(type: Jar) {
inputs.files(myPythonfolder)
..
it can also be achieved by adding new task with input files on the python sources and adding dependency between the jar task and the python task:
jar.dependsOn myPythonTask
for more accurate details , add the build.gradle file of your project here

Run all JUnit tests with Gradle

I have a Java application which uses Gradle as build system. This is multi-project built (several Java projects).
When I run gradlew test and some of the tests are failing I've noticed not all tests actually run.
If I add the following code to build.gradle it does run all tests but of course, the built always complete successfully:
test {
ignoreFailures = true
}
I have two questions:
Does gradle stop executing tests after the first failure?
Is there a way to run all tests (even when some fail) and still have the built fail if some of them failed?
Gradle offers the --continue parameter gradlew build --continue which executes all tasks regardless of their success. However, if any executed task failed the whole build is marked as failed.
I think you are looking for that switch.
Make sure you are running tests from the root of you project.
The test task is part of Java Plugin for Gradle. As from the official documentation:
Projects with large test suites can take a long time to execute even though a failure occurred early on leading to unnecessary wait times (especially on CI). To short circuit this behavior, the Test.getFailFast() property allows you to cause the test task to fail after the first test failure instead of running all tests. When this property is true, the resulting output will only show the results of tests that have completed up to and including the failure. To enable this fail fast behavior in your build file, set the failFast property to true:
test {
failFast = true
}
The --fail-fast command line option enables the behavior from the command line. An invocation looks like:
gradle test --fail-fast
The default value for the failFast property is false.
Official documentation can be found here.
So to answer your questions:
By default, Gradle does not stop executing tests after the first failure. This behaviour can be modified using failFast property.
Default behaviour should do the trick. By running gradle test all tests will be run. If any of them fail, the build will fail. Since you have a multi-project build, make sure you are running Gradle from your root project.

Unit Tests Fails in Build Service But Not Locally

Two tests fail in my build service that will not fail when ran locally.
What I've discovered is that when I execute mvn clean test locally the sort order of my test classes are alphabetical (package and class), but when ran in the build service they're seemingly random.
It is not my intention of needing a specific "order" so I'm definitely concerned that one test prior to another is hinting at an isolation issue. However, I don't think I can just tell maven to run classes in a certain order.
What can I do to try to reproduce?
EDIT
I cloned my build plan, but pointed at a forked repo (same code) and it ran successfully with no failed tests...
You should try to execute mvn -Dsurefire.runOrder=random clean test for random order locally.
But even if your build fails locally, random order is not the best option to reproduce failures because of test order. If the tests are all green when run in alphabetical order, you might be able to make your build consistently fail with mvn -Dsurefire.runOrder=reversealphabetical clean test
There are also a couple of more options -- see runOrder documentation

Categories