**/SftpWagonTest.*
**/SshCommandExecutorTest.*
diff --git a/wagon-providers/wagon-ssh/src/main/java/org/apache/maven/wagon/providers/ssh/jsch/ScpWagon.java b/wagon-providers/wagon-ssh/src/main/java/org/apache/maven/wagon/providers/ssh/jsch/ScpWagon.java
index 978f225e7..54e3b0886 100644
--- a/wagon-providers/wagon-ssh/src/main/java/org/apache/maven/wagon/providers/ssh/jsch/ScpWagon.java
+++ b/wagon-providers/wagon-ssh/src/main/java/org/apache/maven/wagon/providers/ssh/jsch/ScpWagon.java
@@ -22,6 +22,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.util.Locale;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSchException;
@@ -54,6 +55,12 @@
public class ScpWagon extends AbstractJschWagon {
private static final char COPY_START_CHAR = 'C';
+ /** scp acknowledgement byte for a recoverable error, what OpenSSH sends for a missing file */
+ private static final int SCP_WARNING = 1;
+
+ /** scp acknowledgement byte for a fatal error */
+ private static final int SCP_ERROR = 2;
+
private static final char ACK_SEPARATOR = ' ';
private static final String END_OF_FILES_MSG = "E\n";
@@ -222,9 +229,13 @@ public void fillInputData(InputData inputData) throws TransferFailedException, R
String line = readLine(in);
if (exitCode != COPY_START_CHAR) {
- if (exitCode == 1
- && (line.contains("No such file or directory")
- || line.indexOf("no such file or directory") != 1)) {
+ // OpenSSH reports a missing file with the scp "warning" code (1); other servers - Apache MINA
+ // sshd, which the tests run against - report it with the "fatal error" code (2), so fall back on
+ // the message for those
+ if (exitCode == SCP_WARNING
+ || (exitCode == SCP_ERROR
+ && line != null
+ && line.toLowerCase(Locale.ROOT).contains("no such file or directory"))) {
throw new ResourceDoesNotExistException(line);
} else {
throw new IOException("Exit code: " + exitCode + " - " + line);
diff --git a/wagon-providers/wagon-ssh/src/test/java/org/apache/maven/wagon/providers/ssh/jsch/TestPrompter.java b/wagon-providers/wagon-ssh/src/test/java/org/apache/maven/wagon/providers/ssh/jsch/TestPrompter.java
new file mode 100644
index 000000000..8bc9577b3
--- /dev/null
+++ b/wagon-providers/wagon-ssh/src/test/java/org/apache/maven/wagon/providers/ssh/jsch/TestPrompter.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.wagon.providers.ssh.jsch;
+
+import java.util.List;
+
+import org.codehaus.plexus.components.interactivity.Prompter;
+import org.codehaus.plexus.components.interactivity.PrompterException;
+
+/**
+ * A {@link Prompter} for the tests, wired in through
+ * {@code src/test/resources/META-INF/plexus/components.xml}.
+ *
+ * {@code plexus-interactivity-api} stopped shipping a {@code META-INF/plexus/components.xml} in 1.3, so its
+ * {@code DefaultPrompter} is invisible to the {@code plexus-container-default} that {@code PlexusTestCase} runs;
+ * without a replacement every {@code lookup( Wagon.ROLE, "scp" )} fails because {@code ConsoleInteractiveUserInfo}
+ * and {@code PrompterUIKeyboardInteractive} both require one.
+ *
+ * The tests are non-interactive, so nothing should ever prompt: every method throws rather than blocking on
+ * {@code System.in}.
+ */
+public class TestPrompter implements Prompter {
+
+ public String prompt(String message) throws PrompterException {
+ throw unexpected(message);
+ }
+
+ public String prompt(String message, String defaultReply) throws PrompterException {
+ throw unexpected(message);
+ }
+
+ public String prompt(String message, List possibleValues) throws PrompterException {
+ throw unexpected(message);
+ }
+
+ public String prompt(String message, List possibleValues, String defaultReply) throws PrompterException {
+ throw unexpected(message);
+ }
+
+ public String promptForPassword(String message) throws PrompterException {
+ throw unexpected(message);
+ }
+
+ public void showMessage(String message) throws PrompterException {
+ // tests run non-interactively, but a message costs nothing and helps when a test does go interactive
+ System.out.println(message);
+ }
+
+ private PrompterException unexpected(String message) {
+ return new PrompterException("The tests are non-interactive, unexpected prompt: " + message);
+ }
+}
diff --git a/wagon-providers/wagon-ssh/src/test/resources/META-INF/plexus/components.xml b/wagon-providers/wagon-ssh/src/test/resources/META-INF/plexus/components.xml
new file mode 100644
index 000000000..5aa9211fe
--- /dev/null
+++ b/wagon-providers/wagon-ssh/src/test/resources/META-INF/plexus/components.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+ org.codehaus.plexus.components.interactivity.Prompter
+ default
+ org.apache.maven.wagon.providers.ssh.jsch.TestPrompter
+
+
+