From b9ace3053c7a8b5bec610be976a21227d41ae3b6 Mon Sep 17 00:00:00 2001 From: Jan Lahoda Date: Thu, 28 May 2026 15:42:51 +0200 Subject: [PATCH] Adding ability to run OpenJDK tests against a full image. --- .../release/scripts/build-generic.xml | 3 +- .../java/openjdk/common/BuildUtils.java | 4 +- .../openjdk/jtreg/ActionProviderImpl.java | 29 ++++++---- .../openjdk/project/ActionProviderImpl.java | 10 +--- .../java/openjdk/project/Settings.java | 9 +++ .../project/customizer/Bundle.properties | 1 + .../project/customizer/TestCategory.form | 33 ++++++++--- .../project/customizer/TestCategory.java | 31 ++++++++--- .../openjdk/jtreg/ActionProviderImplTest.java | 55 ++++++++++++++++++- 9 files changed, 134 insertions(+), 41 deletions(-) diff --git a/java/java.openjdk.project/release/scripts/build-generic.xml b/java/java.openjdk.project/release/scripts/build-generic.xml index 0150050f6068..c0958f0b7a60 100644 --- a/java/java.openjdk.project/release/scripts/build-generic.xml +++ b/java/java.openjdk.project/release/scripts/build-generic.xml @@ -24,12 +24,13 @@ SUPPORTED_ACTIONS: build,build-fast,clean,rebuild + - + diff --git a/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/common/BuildUtils.java b/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/common/BuildUtils.java index 78918fd3e71c..ddaff7453b98 100644 --- a/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/common/BuildUtils.java +++ b/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/common/BuildUtils.java @@ -38,7 +38,7 @@ public class BuildUtils { private BuildUtils() {} - public static File findTargetJavaHome(FileObject file) { + public static File findTargetJavaHome(FileObject file, boolean fullImage) { File buildDir = getBuildTargetDir(file); if (buildDir != null) { @@ -46,6 +46,8 @@ public static File findTargetJavaHome(FileObject file) { if (candidate.isDirectory()) { return candidate; + } else if (fullImage) { + return new File(new File(buildDir, "images"), "jdk"); } else { return new File(buildDir, "jdk"); } diff --git a/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/jtreg/ActionProviderImpl.java b/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/jtreg/ActionProviderImpl.java index 50e5e404476d..074325347db5 100644 --- a/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/jtreg/ActionProviderImpl.java +++ b/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/jtreg/ActionProviderImpl.java @@ -122,8 +122,8 @@ public void invokeAction(String command, Lookup context) throws IllegalArgumentE createAndRunTest(context, command); } - private static final String COMMAND_BUILD_FAST = "build-fast"; - private static final String COMMAND_BUILD_GENERIC_FAST = "build-generic-fast"; + static final String COMMAND_BUILD_FAST = "build-fast"; + static final String COMMAND_BUILD_GENERIC_FAST = "build-generic-fast"; //public for test @Messages({"# {0} - simple file name", @@ -191,12 +191,15 @@ public void run() { redebug.disable(); Project prj = FileOwnerQuery.getOwner(file); ActionProvider prjAP = prj != null ? prj.getLookup().lookup(ActionProvider.class) : null; - if (prjAP != null) { + Settings settings = prj != null ? prj.getLookup().lookup(Settings.class) : null; + boolean useAntBuild = settings != null ? settings.isUseAntBuild(): false; + boolean useFullImage = settings != null ? settings.isTestUseImage() : false; + if (prjAP != null && (settings == null || settings.getRunBuildSetting() != Settings.RunBuild.NEVER)) { Lookup targetContext = Lookup.EMPTY; Set supported = new HashSet<>(Arrays.asList(prjAP.getSupportedActions())); String toRun = null; - - for (String command : new String[] {idealBuildTarget(file), ActionProvider.COMMAND_BUILD}) { + + for (String command : beforeTestProjectBuildTargets(file, useAntBuild, useFullImage)) { if (supported.contains(command) && prjAP.isActionEnabled(command, targetContext)) { toRun = command; break; @@ -257,7 +260,7 @@ public String[] getExtraMakeTargets() { ClassPath extraSourcePath = allSources(file); final ClassPath fullSourcePath = ClassPathSupport.createProxyClassPath(testSourcePath, extraSourcePath); List options = new ArrayList<>(); - File targetJavaHome = BuildUtils.findTargetJavaHome(file); + File targetJavaHome = BuildUtils.findTargetJavaHome(file, useFullImage); options.add(new File(new File(targetJavaHome, "bin"), "java").getAbsolutePath()); options.add("-jar"); options.add(jtregJar.getAbsolutePath()); @@ -347,7 +350,6 @@ public String[] getExtraMakeTargets() { case 5: //error //check if it is a version error: if (errorOutput.toString().contains("jtreg version")) { - Settings settings = prj.getLookup().lookup(Settings.class); String jtregLocation = settings.getJTregLocation(); InputLine nd = new InputLine(Bundle.LBL_IncorrectVersionSelectJTReg(), Bundle.TITLE_IncorrectVersionSelectJTReg(), NotifyDescriptor.OK_CANCEL_OPTION, NotifyDescriptor.ERROR_MESSAGE); nd.setInputText(jtregLocation); @@ -604,14 +606,19 @@ public void outputLineCleared(OutputEvent ev) {} } } - static String idealBuildTarget(FileObject testFile) { + static String[] beforeTestProjectBuildTargets(FileObject testFile, boolean useAntBuild, boolean useFullImage) { Project prj = FileOwnerQuery.getOwner(testFile); FileObject repo = prj.getProjectDirectory().getParent().getParent(); String repoName = ShortcutUtils.getDefault().inferLegacyRepository(prj); - if (ShortcutUtils.getDefault().shouldUseCustomTest(repoName, FileUtil.getRelativePath(repo, testFile))) { - return COMMAND_BUILD_FAST; + if (ShortcutUtils.getDefault().shouldUseCustomTest(repoName, FileUtil.getRelativePath(repo, testFile)) && useAntBuild) { + //make "ant" build override the "useFullImage" w.r.t. building; + //if useFullImage == true, tests will run using a full JDK image, + //but will still patch in the custom built classes: + return new String[] {COMMAND_BUILD_FAST, COMMAND_BUILD}; + } else if (useFullImage) { + return new String[] {COMMAND_BUILD}; } else { - return COMMAND_BUILD_GENERIC_FAST; + return new String[] {COMMAND_BUILD_GENERIC_FAST, COMMAND_BUILD}; } } diff --git a/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/project/ActionProviderImpl.java b/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/project/ActionProviderImpl.java index cba40fd7d7ae..14fb9cbadb84 100644 --- a/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/project/ActionProviderImpl.java +++ b/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/project/ActionProviderImpl.java @@ -202,14 +202,6 @@ public void invokeAction(String command, Lookup context) throws IllegalArgumentE } } if (COMMAND_BUILD_GENERIC_FAST.equals(command)) { - switch (settings.getRunBuildSetting()) { - case NEVER: - ActionProgress.start(context).finished(true); - return; - case ALWAYS: - default: - break; - } scriptFO = genericScript; command = COMMAND_BUILD_FAST; //XXX: should only do this if genericScript supports it } @@ -222,7 +214,7 @@ public void invokeAction(String command, Lookup context) throws IllegalArgumentE : repository.getParent(); props.put("basedir", FileUtil.toFile(basedirFO).getAbsolutePath()); props.put("CONF", project.configurations.getActiveConfiguration().getLocation().getName()); - props.put("nb.jdk.project.target.java.home", BuildUtils.findTargetJavaHome(project.getProjectDirectory()).getAbsolutePath()); + props.put("nb.jdk.project.target.java.home", BuildUtils.findTargetJavaHome(project.getProjectDirectory(), false).getAbsolutePath()); props.put("nb.extra.make.targets", extraTargets); RootKind kind = getKind(context); RunSingleConfig singleFileProperty = command2Properties.get(Pair.of(command, kind)); diff --git a/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/project/Settings.java b/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/project/Settings.java index 01cf8b172206..a0d56e7c75cc 100644 --- a/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/project/Settings.java +++ b/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/project/Settings.java @@ -33,6 +33,7 @@ public class Settings { private static final String KEY_BUILD_BEFORE_TESTS = "build-before-test"; private static final String KEY_JTREG_LOCATION = "jtreg-location"; + private static final String KEY_TEST_USE_IMAGE = "test-use-image"; private static final String KEY_USE_ANT_BUILD = "use-langtools-ant-build"; private static final String KEY_ANT_BUILD_LOCATION = "langtools-ant-build-location"; @@ -76,6 +77,14 @@ public void setUseAntBuild(boolean useAntBuild) { getPrivatePreferences().putBoolean(KEY_USE_ANT_BUILD, useAntBuild); } + public boolean isTestUseImage() { + return getPrivatePreferences().getBoolean(KEY_TEST_USE_IMAGE, false); + } + + public void setTestUseImage(boolean useImage) { + getPrivatePreferences().putBoolean(KEY_TEST_USE_IMAGE, useImage); + } + public String getAntBuildLocation() { return getPrivatePreferences().get(KEY_ANT_BUILD_LOCATION, DEF_ANT_BUILD_LOCATION); } diff --git a/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/project/customizer/Bundle.properties b/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/project/customizer/Bundle.properties index 004a9470ef89..5884a2c4060e 100644 --- a/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/project/customizer/Bundle.properties +++ b/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/project/customizer/Bundle.properties @@ -22,3 +22,4 @@ TestCategory.jtregLocation.text= BuildCategory.antBuildLocation.text= BuildCategory.useAntBuild.text=Use ant build for langtools BuildCategory.antBuildLocationLabel.text=Ant build location: +TestCategory.useFullImage.text=Use full JDK image to run tests diff --git a/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/project/customizer/TestCategory.form b/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/project/customizer/TestCategory.form index c460f3413a5b..40f908e9e0c9 100644 --- a/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/project/customizer/TestCategory.form +++ b/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/project/customizer/TestCategory.form @@ -38,13 +38,21 @@ - - - - - - - + + + + + + + + + + + + + + + @@ -63,7 +71,9 @@ - + + + @@ -107,5 +117,12 @@ + + + + + + + diff --git a/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/project/customizer/TestCategory.java b/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/project/customizer/TestCategory.java index d1d9392aaa69..5b999bfe333b 100644 --- a/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/project/customizer/TestCategory.java +++ b/java/java.openjdk.project/src/org/netbeans/modules/java/openjdk/project/customizer/TestCategory.java @@ -45,10 +45,11 @@ public class TestCategory extends javax.swing.JPanel { /** * Creates new form TestCategory */ - public TestCategory(RunBuild runBuild, String jtregLocation) { + public TestCategory(RunBuild runBuild, String jtregLocation, boolean testUseImage) { initComponents(); this.buildBeforeTest.getModel().setSelectedItem(runBuild); this.jtregLocation.setText(jtregLocation); + this.useFullImage.setSelected(testUseImage); } /** @@ -63,6 +64,7 @@ private void initComponents() { buildBeforeTest = new javax.swing.JComboBox<>(); jLabel1 = new javax.swing.JLabel(); jtregLocation = new javax.swing.JTextField(); + useFullImage = new javax.swing.JCheckBox(); buildBeforeTestLabel.setLabelFor(buildBeforeTest); org.openide.awt.Mnemonics.setLocalizedText(buildBeforeTestLabel, org.openide.util.NbBundle.getMessage(TestCategory.class, "TestCategory.buildBeforeTestLabel.text")); // NOI18N @@ -75,6 +77,8 @@ private void initComponents() { jtregLocation.setText(org.openide.util.NbBundle.getMessage(TestCategory.class, "TestCategory.jtregLocation.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(useFullImage, org.openide.util.NbBundle.getMessage(TestCategory.class, "TestCategory.useFullImage.text")); // NOI18N + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( @@ -82,12 +86,17 @@ private void initComponents() { .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(buildBeforeTestLabel) - .addComponent(jLabel1)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(buildBeforeTest, 0, 173, Short.MAX_VALUE) - .addComponent(jtregLocation)) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(buildBeforeTestLabel) + .addComponent(jLabel1)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(buildBeforeTest, 0, 173, Short.MAX_VALUE) + .addComponent(jtregLocation))) + .addGroup(layout.createSequentialGroup() + .addComponent(useFullImage) + .addGap(0, 0, Short.MAX_VALUE))) .addContainerGap()) ); layout.setVerticalGroup( @@ -101,7 +110,9 @@ private void initComponents() { .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel1) .addComponent(jtregLocation, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addContainerGap(227, Short.MAX_VALUE)) + .addGap(18, 18, 18) + .addComponent(useFullImage) + .addContainerGap(187, Short.MAX_VALUE)) ); }// //GEN-END:initComponents @@ -111,6 +122,7 @@ private void initComponents() { private javax.swing.JLabel buildBeforeTestLabel; private javax.swing.JLabel jLabel1; private javax.swing.JTextField jtregLocation; + private javax.swing.JCheckBox useFullImage; // End of variables declaration//GEN-END:variables private ListCellRenderer runBuildRenderer() { @@ -153,10 +165,11 @@ public Category createCategory(Lookup context) { @Override public JComponent createComponent(Category category, Lookup context) { Settings settings = context.lookup(Settings.class); - TestCategory panel = new TestCategory(settings.getRunBuildSetting(), settings.getJTregLocation()); + TestCategory panel = new TestCategory(settings.getRunBuildSetting(), settings.getJTregLocation(), settings.isTestUseImage()); category.setOkButtonListener(evt -> { settings.setRunBuildSetting((RunBuild) panel.buildBeforeTest.getSelectedItem()); settings.setJTregLocation(panel.jtregLocation.getText()); + settings.setTestUseImage(panel.useFullImage.isSelected()); }); category.setStoreListener(evt -> settings.flush()); return panel; diff --git a/java/java.openjdk.project/test/unit/src/org/netbeans/modules/java/openjdk/jtreg/ActionProviderImplTest.java b/java/java.openjdk.project/test/unit/src/org/netbeans/modules/java/openjdk/jtreg/ActionProviderImplTest.java index fc04d62de2a5..2e478550d0c3 100644 --- a/java/java.openjdk.project/test/unit/src/org/netbeans/modules/java/openjdk/jtreg/ActionProviderImplTest.java +++ b/java/java.openjdk.project/test/unit/src/org/netbeans/modules/java/openjdk/jtreg/ActionProviderImplTest.java @@ -26,6 +26,7 @@ import java.util.List; import java.util.Set; import java.util.regex.Pattern; +import org.junit.Assert; import org.netbeans.api.java.classpath.ClassPath; import org.netbeans.api.project.FileOwnerQuery; @@ -153,7 +154,13 @@ public void testImages1() throws Exception { FileOwnerQuery.markExternalOwner(testFile.getParent(), FileOwnerQuery.getOwner(createDir("langtools/src/java.compiler")), FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT); - File target = BuildUtils.findTargetJavaHome(testFile); + File target; + + target = BuildUtils.findTargetJavaHome(testFile, false); + + assertEquals("/build/conf/images/j2sdk-image", target.getAbsolutePath().substring(getWorkDir().getAbsolutePath().length())); + + target = BuildUtils.findTargetJavaHome(testFile, true); assertEquals("/build/conf/images/j2sdk-image", target.getAbsolutePath().substring(getWorkDir().getAbsolutePath().length())); } @@ -170,9 +177,53 @@ public void testImages2() throws Exception { FileOwnerQuery.markExternalOwner(testFile.getParent(), FileOwnerQuery.getOwner(createDir("langtools/src/java.compiler")), FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT); - File target = BuildUtils.findTargetJavaHome(testFile); + File target; + + target = BuildUtils.findTargetJavaHome(testFile, false); assertEquals("/build/conf/jdk", target.getAbsolutePath().substring(getWorkDir().getAbsolutePath().length())); + + target = BuildUtils.findTargetJavaHome(testFile, true); + + assertEquals("/build/conf/images/jdk", target.getAbsolutePath().substring(getWorkDir().getAbsolutePath().length())); + } + + public void testBuildTargets() throws Exception { + createFile("modules.xml"); + createDir("jdk/src/java.base/share/classes"); + createDir("build/conf/jdk"); + createDir("build/conf/images/jdk"); + createDir("langtools/src/java.compiler/share/classes"); + FileObject jdkTestFile = createFile("jdk/test/Test.java"); + FileObject langtoolsTestFile = createFile("langtools/test/Test.java"); + + createDir("").setAttribute(BuildUtils.NB_JDK_PROJECT_BUILD, FileUtil.toFile(createDir("build/conf"))); + + FileOwnerQuery.markExternalOwner(langtoolsTestFile.getParent(), FileOwnerQuery.getOwner(createDir("langtools/src/java.compiler")), FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT); + FileOwnerQuery.markExternalOwner(jdkTestFile.getParent(), FileOwnerQuery.getOwner(createDir("jdk/src/java.base")), FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT); + + //for langtools tests, always use a quick build when using ant build: + Assert.assertArrayEquals(new String[] {ActionProviderImpl.COMMAND_BUILD_FAST, ActionProviderImpl.COMMAND_BUILD}, + ActionProviderImpl.beforeTestProjectBuildTargets(langtoolsTestFile, true, false)); + Assert.assertArrayEquals(new String[] {ActionProviderImpl.COMMAND_BUILD_FAST, ActionProviderImpl.COMMAND_BUILD}, + ActionProviderImpl.beforeTestProjectBuildTargets(langtoolsTestFile, true, true)); + + Assert.assertArrayEquals(new String[] {ActionProviderImpl.COMMAND_BUILD_GENERIC_FAST, ActionProviderImpl.COMMAND_BUILD}, + ActionProviderImpl.beforeTestProjectBuildTargets(langtoolsTestFile, false, false)); + Assert.assertArrayEquals(new String[] {ActionProviderImpl.COMMAND_BUILD}, + ActionProviderImpl.beforeTestProjectBuildTargets(langtoolsTestFile, false, true)); + + //for JDK tests, there's no quick ant build: + Assert.assertArrayEquals(new String[] {ActionProviderImpl.COMMAND_BUILD_GENERIC_FAST, ActionProviderImpl.COMMAND_BUILD}, + ActionProviderImpl.beforeTestProjectBuildTargets(jdkTestFile, true, false)); + Assert.assertArrayEquals(new String[] {ActionProviderImpl.COMMAND_BUILD}, + ActionProviderImpl.beforeTestProjectBuildTargets(jdkTestFile, true, true)); + + Assert.assertArrayEquals(new String[] {ActionProviderImpl.COMMAND_BUILD_GENERIC_FAST, ActionProviderImpl.COMMAND_BUILD}, + ActionProviderImpl.beforeTestProjectBuildTargets(jdkTestFile, false, false)); + Assert.assertArrayEquals(new String[] {ActionProviderImpl.COMMAND_BUILD}, + ActionProviderImpl.beforeTestProjectBuildTargets(jdkTestFile, false, true)); + } public void testStackTracePattern() {