Skip to content

FixTestNativeImageRun Gradle task to resolve test failures on Native Image run#787

Merged
kimeta merged 1 commit intooracle:masterfrom
kimeta:mm/introduce-fixTestNIRun-task
Nov 28, 2025
Merged

FixTestNativeImageRun Gradle task to resolve test failures on Native Image run#787
kimeta merged 1 commit intooracle:masterfrom
kimeta:mm/introduce-fixTestNIRun-task

Conversation

@kimeta
Copy link
Copy Markdown
Collaborator

@kimeta kimeta commented Nov 19, 2025

What does this PR do?

Fixes: #786

This task runs the Java agent on failed tests for a new library version, and creates a version-specific metadata directory.
It will be executed by automation script #769 to update the metadata for each failing library version.

@kimeta kimeta requested a review from vjovanov as a code owner November 19, 2025 17:04
@kimeta kimeta force-pushed the mm/introduce-fixTestNIRun-task branch from 8454626 to 0ae9765 Compare November 19, 2025 17:05
@kimeta kimeta changed the title FixTestNIRun task which fixes test Native Image run fails FixTestNIRun Gradle task to resolve test failures on Native Image run Nov 19, 2025
task.setGroup(METADATA_GROUP)
}
// gradle fixTestNIRun --testLibraryCoordinates=<maven-coordinates> --newLibraryVersion=<library version which needs fix>
tasks.register("fixTestNIRun", FixTestNativeImageRun.class) { task ->
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Give it a more descriptive name.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe fixTestNativeImageRun or fixTestNativeImageRunFailure?

import java.util.List;
import java.util.stream.Collectors;

public abstract class GenerateMetadataTask extends DefaultTask {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does it do?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Explained in the added javadoc.

import java.nio.file.Path;
import java.util.regex.Pattern;

public abstract class FixTestNativeImageRun extends DefaultTask {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Explain the usage.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.


@Option(option = "coordinates", description = "Coordinates in the form of group:artifact:version")
public void setCoordinates(String coordinates) {
this.coordinates = coordinates;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have CoordinateUtils now and they should be handled correctly.

}

@Option(option = "allowedPackages", description = "Comma separated allowed packages (or - for none)")
public void setAllowedPackages(String allowedPackages) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this set in index.json? We override here?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This name is ambiguous, this refers to packages that are ‘allowed’ in the agent filter. In ContributeTask, the variable is named packages, but perhaps we should use a more descriptive name. What about includedPackages or agentAllowedPackages, agentFilterPackages?

* Executes the given executable with arguments in an optional working directory via Gradle ExecOperations.
* Captures output and throws a RuntimeException if the exit code is non-zero.
*/
public static void invokeCommand(ExecOperations execOps, String executable, List<String> args, String errorMessage, Path workingDirectory) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are general utils. Is there a lib that can do that?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is essentially a wrapper for org.gradle.process.ExecOperations#exec, handling all similar invocation preparations. Maybe we should create a GeneralUtils class for these types of methods, including printing methods for task progress: #787 (comment)?

// Ensure the tests build.gradle has an agent block; if not, create user-code-filter.json and add the agent block.
Path buildFilePath = testsDirectory.resolve("build.gradle");
if (!Files.isRegularFile(buildFilePath)) {
throw new RuntimeException("Cannot find tests build file at: " + buildFilePath);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GradleException, we should also add this to AGENTS.md.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

throw new RuntimeException("Cannot find tests build file at: " + buildFilePath);
}
String buildGradle = Files.readString(buildFilePath, java.nio.charset.StandardCharsets.UTF_8);
boolean hasAgentBlock = Pattern.compile("(?s)\\bagent\\s*\\{").matcher(buildGradle).find();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this even happen?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, some test directories for the libraries in the repository don’t contain any files related to agent filters.

String buildGradle = Files.readString(buildFilePath, StandardCharsets.UTF_8);
boolean hasAgentBlock = Pattern.compile("(?s)\\bagent\\s*\\{").matcher(buildGradle).find();
if (hasAgentBlock) {
InteractiveTaskUtils.printUserInfo("Agent block already present in: " + BUILD_FILE + " - skipping");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe general utils?

If you already have the test project structure in this repository and need to generate or regenerate metadata, use the `generateMetadata` task:

```shell
./gradlew generateMetadata --coordinates=com.example:my-library:1.0.0
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add these to DEVELOPING.md and to testAllParallel.

/**
* Creates index.json inside the given version directory, listing all files present in that directory.
*/
public static void createIndexJsonSpecificVersion(Path metadataDirectory) throws IOException {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very useful :) \cc @jormundur00

@kimeta kimeta force-pushed the mm/introduce-fixTestNIRun-task branch from 0ae9765 to af9be21 Compare November 26, 2025 20:35
@kimeta kimeta requested a review from ban-mi as a code owner November 26, 2025 20:35
@kimeta kimeta changed the title FixTestNIRun Gradle task to resolve test failures on Native Image run FixTestNativeImageRun Gradle task to resolve test failures on Native Image run Nov 26, 2025
@kimeta kimeta force-pushed the mm/introduce-fixTestNIRun-task branch 4 times, most recently from fef6e98 to 8ded7e5 Compare November 27, 2025 00:58
AGENTS.md Outdated
- Write type annotations in all functions and most variables.
- Document code without being too verbose.
- In java, always import classes and use them without qualified names.
- Always use GradleException if possible.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, this should be in subprojects I think.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added AGENTS.md to the tests/src.

build.gradle Outdated
}

// Test metadata generation only for single coordinates (not batched like "1/64")
if (!coordinate.contains("/")) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Guard against all as well.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, don't guard. Just run this task above for a single coordinate.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, and reformatted the whole test so it is more clear and readable.

build.gradle Outdated
def artifact = parts[1]
def version = parts[2]

def versionDir = new File(tck.metadataRoot.get().asFile, "${group}/${artifact}/${version}")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do this so many times, please reuse.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

build.gradle Outdated
throw new GradleException("No metadata files found in ${versionDir} (besides index.json)")
}

def indexList = (List) new groovy.json.JsonSlurper().parse(indexFile)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need more rules for qualified names.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, and added to the AGENTS.md.

@kimeta kimeta force-pushed the mm/introduce-fixTestNIRun-task branch from 8ded7e5 to 51fb75a Compare November 28, 2025 12:36
@kimeta kimeta requested a review from a team as a code owner November 28, 2025 12:36
@kimeta kimeta requested a review from msupic November 28, 2025 12:36
@kimeta kimeta force-pushed the mm/introduce-fixTestNIRun-task branch 3 times, most recently from 7e213d9 to 9e7bdb6 Compare November 28, 2025 14:28
- Write type annotations in all functions and most variables.
- Document code without being too verbose.
- In java, always import classes and use them without qualified names.
- In Java and Groovy, always import classes and use them without qualified names.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hahaha, I did the same.

@kimeta kimeta force-pushed the mm/introduce-fixTestNIRun-task branch from 9e7bdb6 to 9dfa88e Compare November 28, 2025 14:42
@kimeta kimeta merged commit 7e9e33b into oracle:master Nov 28, 2025
43 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature: Introduce fixTestNIRun gradle task

2 participants