This is an automated email from the ASF dual-hosted git repository.

cstamas pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven.git


The following commit(s) were added to refs/heads/master by this push:
     new 793443920e [IT] Refactor executor (#2175)
793443920e is described below

commit 793443920ebc040aff09b90cfb002737a53aa733
Author: Tamas Cservenak <ta...@cservenak.net>
AuthorDate: Fri Mar 21 14:30:15 2025 +0100

    [IT] Refactor executor (#2175)
    
    There was overlapping concerns, so better to separate them. Also, this now 
allows to use tool with other maven that the one being tested, so result should 
not be affected.
    
    Also contains fix for ExecutorTool implementation to enforce that process 
do produce output, as under some circumstances (on Windows) the process may 
exit with 0 exit code (no error) but produce empty output
    on standard output, which should not be possible.
---
 .../maven/cling/executor/ExecutorHelper.java       |  2 +-
 .../maven/cling/executor/internal/HelperImpl.java  | 26 ----------------------
 .../maven/cling/executor/internal/ToolboxTool.java | 25 ++++++++++++++++-----
 .../{HelperImplTest.java => ToolboxToolTest.java}  | 21 +++++++++--------
 .../main/java/org/apache/maven/it/Verifier.java    | 21 ++++++++++-------
 5 files changed, 45 insertions(+), 50 deletions(-)

diff --git 
a/impl/maven-executor/src/main/java/org/apache/maven/cling/executor/ExecutorHelper.java
 
b/impl/maven-executor/src/main/java/org/apache/maven/cling/executor/ExecutorHelper.java
index 14a5e2abd2..c6dc27feb0 100644
--- 
a/impl/maven-executor/src/main/java/org/apache/maven/cling/executor/ExecutorHelper.java
+++ 
b/impl/maven-executor/src/main/java/org/apache/maven/cling/executor/ExecutorHelper.java
@@ -26,7 +26,7 @@
 /**
  * Helper class for routing Maven execution based on preferences and/or issued 
execution requests.
  */
-public interface ExecutorHelper extends ExecutorTool {
+public interface ExecutorHelper {
     /**
      * The modes of execution.
      */
diff --git 
a/impl/maven-executor/src/main/java/org/apache/maven/cling/executor/internal/HelperImpl.java
 
b/impl/maven-executor/src/main/java/org/apache/maven/cling/executor/internal/HelperImpl.java
index 4304f6d871..9a94ddc2dd 100644
--- 
a/impl/maven-executor/src/main/java/org/apache/maven/cling/executor/internal/HelperImpl.java
+++ 
b/impl/maven-executor/src/main/java/org/apache/maven/cling/executor/internal/HelperImpl.java
@@ -21,7 +21,6 @@
 import java.nio.file.Path;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.maven.api.annotations.Nullable;
@@ -29,7 +28,6 @@
 import org.apache.maven.api.cli.ExecutorException;
 import org.apache.maven.api.cli.ExecutorRequest;
 import org.apache.maven.cling.executor.ExecutorHelper;
-import org.apache.maven.cling.executor.ExecutorTool;
 
 import static java.util.Objects.requireNonNull;
 
@@ -40,7 +38,6 @@ public class HelperImpl implements ExecutorHelper {
     private final Mode defaultMode;
     private final Path installationDirectory;
     private final Path userHomeDirectory;
-    private final ExecutorTool executorTool;
     private final HashMap<Mode, Executor> executors;
 
     private final ConcurrentHashMap<String, String> cache;
@@ -58,7 +55,6 @@ public HelperImpl(
         this.userHomeDirectory = userHomeDirectory != null
                 ? ExecutorRequest.getCanonicalPath(userHomeDirectory)
                 : ExecutorRequest.discoverUserHomeDirectory();
-        this.executorTool = new ToolboxTool(this);
         this.executors = new HashMap<>();
 
         this.executors.put(Mode.EMBEDDED, requireNonNull(embedded, 
"embedded"));
@@ -89,28 +85,6 @@ public String mavenVersion() {
         });
     }
 
-    @Override
-    public Map<String, String> dump(ExecutorRequest.Builder request) throws 
ExecutorException {
-        return executorTool.dump(request);
-    }
-
-    @Override
-    public String localRepository(ExecutorRequest.Builder request) throws 
ExecutorException {
-        return executorTool.localRepository(request);
-    }
-
-    @Override
-    public String artifactPath(ExecutorRequest.Builder request, String gav, 
String repositoryId)
-            throws ExecutorException {
-        return executorTool.artifactPath(request, gav, repositoryId);
-    }
-
-    @Override
-    public String metadataPath(ExecutorRequest.Builder request, String gav, 
String repositoryId)
-            throws ExecutorException {
-        return executorTool.metadataPath(request, gav, repositoryId);
-    }
-
     protected Executor getExecutor(Mode mode, ExecutorRequest request) throws 
ExecutorException {
         return switch (mode) {
             case AUTO -> getExecutorByRequest(request);
diff --git 
a/impl/maven-executor/src/main/java/org/apache/maven/cling/executor/internal/ToolboxTool.java
 
b/impl/maven-executor/src/main/java/org/apache/maven/cling/executor/internal/ToolboxTool.java
index b23a4948a3..2c08093ce6 100644
--- 
a/impl/maven-executor/src/main/java/org/apache/maven/cling/executor/internal/ToolboxTool.java
+++ 
b/impl/maven-executor/src/main/java/org/apache/maven/cling/executor/internal/ToolboxTool.java
@@ -59,7 +59,8 @@ public Map<String, String> dump(ExecutorRequest.Builder 
executorRequest) throws
         doExecute(builder);
         try {
             Properties properties = new Properties();
-            properties.load(new ByteArrayInputStream(stdout.toByteArray()));
+            properties.load(new ByteArrayInputStream(
+                    validateOutput(false, stdout, stderr).getBytes()));
             return properties.entrySet().stream()
                     .collect(Collectors.toMap(
                             e -> String.valueOf(e.getKey()),
@@ -79,7 +80,7 @@ public String localRepository(ExecutorRequest.Builder 
executorRequest) throws Ex
                 .stdOut(stdout)
                 .stdErr(stderr);
         doExecute(builder);
-        return shaveStdout(stdout);
+        return validateOutput(true, stdout, stderr);
     }
 
     @Override
@@ -95,7 +96,7 @@ public String artifactPath(ExecutorRequest.Builder 
executorRequest, String gav,
             builder.argument("-Drepository=" + repositoryId + "::unimportant");
         }
         doExecute(builder);
-        return shaveStdout(stdout);
+        return validateOutput(true, stdout, stderr);
     }
 
     @Override
@@ -111,7 +112,7 @@ public String metadataPath(ExecutorRequest.Builder 
executorRequest, String gav,
             builder.argument("-Drepository=" + repositoryId + "::unimportant");
         }
         doExecute(builder);
-        return shaveStdout(stdout);
+        return validateOutput(true, stdout, stderr);
     }
 
     private ExecutorRequest.Builder mojo(ExecutorRequest.Builder builder, 
String mojo) {
@@ -131,7 +132,19 @@ private void doExecute(ExecutorRequest.Builder builder) {
         }
     }
 
-    private String shaveStdout(ByteArrayOutputStream stdout) {
-        return stdout.toString().replace("\n", "").replace("\r", "");
+    /**
+     * Performs "sanity check" for output, making sure no insane values like 
empty strings are returned.
+     */
+    private String validateOutput(boolean shave, ByteArrayOutputStream stdout, 
ByteArrayOutputStream stderr) {
+        String result = stdout.toString();
+        if (shave) {
+            result = result.replace("\n", "").replace("\r", "");
+        }
+        // sanity checks: stderr has any OR result is empty string (no method 
should emit empty string)
+        if (stderr.size() > 0 || result.trim().isEmpty()) {
+            throw new ExecutorException(
+                    "Unexpected stdout[" + stdout.size() + "]=" + stdout + "; 
stderr[" + stderr.size() + "]=" + stderr);
+        }
+        return result;
     }
 }
diff --git 
a/impl/maven-executor/src/test/java/org/apache/maven/cling/executor/impl/HelperImplTest.java
 
b/impl/maven-executor/src/test/java/org/apache/maven/cling/executor/impl/ToolboxToolTest.java
similarity index 88%
rename from 
impl/maven-executor/src/test/java/org/apache/maven/cling/executor/impl/HelperImplTest.java
rename to 
impl/maven-executor/src/test/java/org/apache/maven/cling/executor/impl/ToolboxToolTest.java
index ee4c70bd20..d34fc00f08 100644
--- 
a/impl/maven-executor/src/test/java/org/apache/maven/cling/executor/impl/HelperImplTest.java
+++ 
b/impl/maven-executor/src/test/java/org/apache/maven/cling/executor/impl/ToolboxToolTest.java
@@ -27,6 +27,7 @@
 import org.apache.maven.cling.executor.ExecutorHelper;
 import org.apache.maven.cling.executor.MavenExecutorTestSupport;
 import org.apache.maven.cling.executor.internal.HelperImpl;
+import org.apache.maven.cling.executor.internal.ToolboxTool;
 import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Timeout;
 import org.junit.jupiter.api.io.TempDir;
@@ -38,7 +39,7 @@
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
-public class HelperImplTest {
+public class ToolboxToolTest {
     @TempDir
     private static Path userHome;
 
@@ -52,7 +53,7 @@ void dump3(ExecutorHelper.Mode mode) throws Exception {
                 userHome,
                 MavenExecutorTestSupport.EMBEDDED_MAVEN_EXECUTOR,
                 MavenExecutorTestSupport.FORKED_MAVEN_EXECUTOR);
-        Map<String, String> dump = helper.dump(helper.executorRequest());
+        Map<String, String> dump = new 
ToolboxTool(helper).dump(helper.executorRequest());
         assertEquals(System.getProperty("maven3version"), 
dump.get("maven.version"));
     }
 
@@ -66,7 +67,7 @@ void dump4(ExecutorHelper.Mode mode) throws Exception {
                 userHome,
                 MavenExecutorTestSupport.EMBEDDED_MAVEN_EXECUTOR,
                 MavenExecutorTestSupport.FORKED_MAVEN_EXECUTOR);
-        Map<String, String> dump = helper.dump(helper.executorRequest());
+        Map<String, String> dump = new 
ToolboxTool(helper).dump(helper.executorRequest());
         assertEquals(System.getProperty("maven4version"), 
dump.get("maven.version"));
     }
 
@@ -106,7 +107,7 @@ void localRepository3(ExecutorHelper.Mode mode) {
                 userHome,
                 MavenExecutorTestSupport.EMBEDDED_MAVEN_EXECUTOR,
                 MavenExecutorTestSupport.FORKED_MAVEN_EXECUTOR);
-        String localRepository = 
helper.localRepository(helper.executorRequest());
+        String localRepository = new 
ToolboxTool(helper).localRepository(helper.executorRequest());
         Path local = Paths.get(localRepository);
         assertTrue(Files.isDirectory(local));
     }
@@ -122,7 +123,7 @@ void localRepository4(ExecutorHelper.Mode mode) {
                 userHome,
                 MavenExecutorTestSupport.EMBEDDED_MAVEN_EXECUTOR,
                 MavenExecutorTestSupport.FORKED_MAVEN_EXECUTOR);
-        String localRepository = 
helper.localRepository(helper.executorRequest());
+        String localRepository = new 
ToolboxTool(helper).localRepository(helper.executorRequest());
         Path local = Paths.get(localRepository);
         assertTrue(Files.isDirectory(local));
     }
@@ -137,7 +138,8 @@ void artifactPath3(ExecutorHelper.Mode mode) {
                 userHome,
                 MavenExecutorTestSupport.EMBEDDED_MAVEN_EXECUTOR,
                 MavenExecutorTestSupport.FORKED_MAVEN_EXECUTOR);
-        String path = helper.artifactPath(helper.executorRequest(), 
"aopalliance:aopalliance:1.0", "central");
+        String path = new ToolboxTool(helper)
+                .artifactPath(helper.executorRequest(), 
"aopalliance:aopalliance:1.0", "central");
         // split repository: assert "ends with" as split may introduce prefixes
         assertTrue(
                 path.endsWith("aopalliance" + File.separator + "aopalliance" + 
File.separator + "1.0" + File.separator
@@ -155,7 +157,8 @@ void artifactPath4(ExecutorHelper.Mode mode) {
                 userHome,
                 MavenExecutorTestSupport.EMBEDDED_MAVEN_EXECUTOR,
                 MavenExecutorTestSupport.FORKED_MAVEN_EXECUTOR);
-        String path = helper.artifactPath(helper.executorRequest(), 
"aopalliance:aopalliance:1.0", "central");
+        String path = new ToolboxTool(helper)
+                .artifactPath(helper.executorRequest(), 
"aopalliance:aopalliance:1.0", "central");
         // split repository: assert "ends with" as split may introduce prefixes
         assertTrue(
                 path.endsWith("aopalliance" + File.separator + "aopalliance" + 
File.separator + "1.0" + File.separator
@@ -173,7 +176,7 @@ void metadataPath3(ExecutorHelper.Mode mode) {
                 userHome,
                 MavenExecutorTestSupport.EMBEDDED_MAVEN_EXECUTOR,
                 MavenExecutorTestSupport.FORKED_MAVEN_EXECUTOR);
-        String path = helper.metadataPath(helper.executorRequest(), 
"aopalliance", "someremote");
+        String path = new 
ToolboxTool(helper).metadataPath(helper.executorRequest(), "aopalliance", 
"someremote");
         // split repository: assert "ends with" as split may introduce prefixes
         assertTrue(path.endsWith("aopalliance" + File.separator + 
"maven-metadata-someremote.xml"), "path=" + path);
     }
@@ -188,7 +191,7 @@ void metadataPath4(ExecutorHelper.Mode mode) {
                 userHome,
                 MavenExecutorTestSupport.EMBEDDED_MAVEN_EXECUTOR,
                 MavenExecutorTestSupport.FORKED_MAVEN_EXECUTOR);
-        String path = helper.metadataPath(helper.executorRequest(), 
"aopalliance", "someremote");
+        String path = new 
ToolboxTool(helper).metadataPath(helper.executorRequest(), "aopalliance", 
"someremote");
         // split repository: assert "ends with" as split may introduce prefixes
         assertTrue(path.endsWith("aopalliance" + File.separator + 
"maven-metadata-someremote.xml"), "path=" + path);
     }
diff --git 
a/its/core-it-support/maven-it-helper/src/main/java/org/apache/maven/it/Verifier.java
 
b/its/core-it-support/maven-it-helper/src/main/java/org/apache/maven/it/Verifier.java
index 1c9406fcc1..04be2c6dbf 100644
--- 
a/its/core-it-support/maven-it-helper/src/main/java/org/apache/maven/it/Verifier.java
+++ 
b/its/core-it-support/maven-it-helper/src/main/java/org/apache/maven/it/Verifier.java
@@ -48,9 +48,11 @@
 import org.apache.maven.api.cli.ExecutorException;
 import org.apache.maven.api.cli.ExecutorRequest;
 import org.apache.maven.cling.executor.ExecutorHelper;
+import org.apache.maven.cling.executor.ExecutorTool;
 import org.apache.maven.cling.executor.embedded.EmbeddedMavenExecutor;
 import org.apache.maven.cling.executor.forked.ForkedMavenExecutor;
 import org.apache.maven.cling.executor.internal.HelperImpl;
+import org.apache.maven.cling.executor.internal.ToolboxTool;
 import org.codehaus.plexus.util.FileUtils;
 import org.codehaus.plexus.util.StringUtils;
 
@@ -88,6 +90,8 @@ public class Verifier {
 
     private final ExecutorHelper executorHelper;
 
+    private final ExecutorTool executorTool;
+
     private final Path basedir; // the basedir of IT
 
     private final Path tempBasedir; // empty basedir for queries
@@ -145,6 +149,7 @@ public Verifier(String basedir, List<String> 
defaultCliArguments) throws Verific
                     this.userHomeDirectory,
                     EMBEDDED_MAVEN_EXECUTOR,
                     FORKED_MAVEN_EXECUTOR);
+            this.executorTool = new ToolboxTool(executorHelper);
             this.defaultCliArguments =
                     new ArrayList<>(defaultCliArguments != null ? 
defaultCliArguments : DEFAULT_CLI_ARGUMENTS);
             this.logFile = this.basedir.resolve(logFileName);
@@ -235,7 +240,7 @@ public void execute() throws VerificationException {
             if (ret > 0) {
                 String dump;
                 try {
-                    dump = executorHelper.dump(request.toBuilder()).toString();
+                    dump = executorTool.dump(request.toBuilder()).toString();
                 } catch (Exception e) {
                     dump = "FAILED: " + e.getMessage();
                 }
@@ -340,14 +345,14 @@ public String getLocalRepositoryWithSettings(String 
settingsXml) {
             if (!Files.isRegularFile(settingsFile)) {
                 throw new IllegalArgumentException("settings xml does not 
exist: " + settingsXml);
             }
-            return executorHelper.localRepository(executorHelper
+            return executorTool.localRepository(executorHelper
                     .executorRequest()
                     .cwd(tempBasedir)
                     .userHomeDirectory(userHomeDirectory)
                     .argument("-s")
                     .argument(settingsFile.toString()));
         } else {
-            return executorHelper.localRepository(
+            return executorTool.localRepository(
                     
executorHelper.executorRequest().cwd(tempBasedir).userHomeDirectory(userHomeDirectory));
         }
     }
@@ -644,7 +649,7 @@ public String getArtifactPath(String gid, String aid, 
String version, String ext
         }
         return getLocalRepository()
                 + File.separator
-                + 
executorHelper.artifactPath(executorHelper.executorRequest(), gav, null);
+                + executorTool.artifactPath(executorHelper.executorRequest(), 
gav, null);
     }
 
     private String getSupportArtifactPath(String artifact) {
@@ -701,7 +706,7 @@ public String getSupportArtifactPath(String gid, String 
aid, String version, Str
             gav = gid + ":" + aid + ":" + ext + ":" + version;
         }
         return outerLocalRepository
-                .resolve(executorHelper.artifactPath(
+                .resolve(executorTool.artifactPath(
                         
executorHelper.executorRequest().argument("-Dmaven.repo.local=" + 
outerLocalRepository),
                         gav,
                         null))
@@ -776,7 +781,7 @@ public String getArtifactMetadataPath(String gid, String 
aid, String version, St
         gav += filename;
         return getLocalRepository()
                 + File.separator
-                + 
executorHelper.metadataPath(executorHelper.executorRequest(), gav, repoId);
+                + executorTool.metadataPath(executorHelper.executorRequest(), 
gav, repoId);
     }
 
     /**
@@ -806,7 +811,7 @@ public void deleteArtifact(String org, String name, String 
version, String ext)
      * @since 1.2
      */
     public void deleteArtifacts(String gid) throws IOException {
-        String mdPath = 
executorHelper.metadataPath(executorHelper.executorRequest(), gid, null);
+        String mdPath = 
executorTool.metadataPath(executorHelper.executorRequest(), gid, null);
         Path dir = Paths.get(getLocalRepository()).resolve(mdPath).getParent();
         FileUtils.deleteDirectory(dir.toFile());
     }
@@ -826,7 +831,7 @@ public void deleteArtifacts(String gid, String aid, String 
version) throws IOExc
         requireNonNull(version, "version is null");
 
         String mdPath =
-                executorHelper.metadataPath(executorHelper.executorRequest(), 
gid + ":" + aid + ":" + version, null);
+                executorTool.metadataPath(executorHelper.executorRequest(), 
gid + ":" + aid + ":" + version, null);
         Path dir = Paths.get(getLocalRepository()).resolve(mdPath).getParent();
         FileUtils.deleteDirectory(dir.toFile());
     }

Reply via email to