Я использую JSch для выполнения операции sftp get. Когда я запускаю тесты с использованием основного метода, все прекрасно, но с помощью модульных тестов я сталкиваюсь с проблемами. Вот ошибка:Согласование алгоритма JSch терпит неудачу только в модульных тестах
java.lang.RuntimeException: com.jcraft.jsch.JSchException: Algorithm negotiation fail
Вот метод, который терпит неудачу:
private ChannelSftp sftpInitKeyfile(String host, String username, String keyfile, int port) throws IOException, JSchException {
JSch jsch = new JSch();
byte[] keyBytes = Resources.toByteArray(Resources.getResource(keyfile));
jsch.addIdentity(username, keyBytes, null, null);
Session session = jsch.getSession(username, host, port);
session.setConfig("StrictHostKeyChecking", "no");
session.connect(); // This line is what's failing
ChannelSftp sftpChannel = (ChannelSftp) session.openChannel("sftp");
sftpChannel.connect();
return sftpChannel;
}
Я сделал некоторое протоколирование и обнаружил некоторые различия, которые я не могу понять. Вот журнал, когда я запускаю мой основной метод:
Connecting to (redacted) port 22
Connection established
Remote version string: SSH-2.0-OpenSSH_5.3
Local version string: SSH-2.0-JSCH-0.1.53
CheckCiphers: aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc,3des-ctr,arcfour,arcfour128,arcfour256
aes256-ctr is not available.
aes192-ctr is not available.
aes256-cbc is not available.
aes192-cbc is not available.
CheckKexes: diffie-hellman-group14-sha1,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521
diffie-hellman-group14-sha1 is not available.
CheckSignatures: ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521
SSH_MSG_KEXINIT sent
SSH_MSG_KEXINIT received
И вот бревно, когда я бегу мой модульного тестирования:
Connecting to (redacted) port 22
Connection established
Remote version string: SSH-2.0-OpenSSH_5.3
Local version string: SSH-2.0-JSCH-0.1.53
CheckCiphers: aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc,3des-ctr,arcfour,arcfour128,arcfour256
aes256-ctr is not available.
aes192-ctr is not available.
aes128-ctr is not available.
aes256-cbc is not available.
aes192-cbc is not available.
aes128-cbc is not available.
3des-ctr is not available.
CheckKexes: diffie-hellman-group14-sha1,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521
diffie-hellman-group14-sha1 is not available.
ecdh-sha2-nistp256 is not available.
ecdh-sha2-nistp384 is not available.
ecdh-sha2-nistp521 is not available.
CheckSignatures: ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521
SSH_MSG_KEXINIT sent
SSH_MSG_KEXINIT received
Извещение есть больше «нет в наличии» сообщения в 2-журнале, чем во-первых, наиболее заметно aes128-ctr под шифрами и ecdh-sha2-nistp256 под kexes. Я не понимаю, почему они оба называют один и тот же код с теми же библиотеками. Это происходит независимо от того, выполняю ли я свои модульные тесты в IntelliJ или через mvn-тест в командной строке. Что может быть причиной этого? Я запускаю JUnit 4.1.2 с powermock 1.6.2.
Вот один из тестов, который неудовлетворительные с поддерживающим кодом:
@RunWith(PowerMockRunner.class)
@PrepareForTest({DCGSGenerator.class, DocumentHelper.class, ZipFile.class, String.class, IOUtils.class, JBlocksClassificationToVisibility.class})
public class DCGSGeneratorTest {
public static Properties properties;
@BeforeClass
public static void setUp() throws Exception {
InputStream propertiesStream = DCGSGeneratorTest.class.getClassLoader().getResourceAsStream("ezbake-config.properties");
properties = new Properties();
properties.load(propertiesStream);
}
@Test
public void generateTest() throws Exception {
PowerMockito.mockStatic(DCGSGenerator.class);
PowerMockito.doNothing().when(DCGSGenerator.class, "deleteFile", any(String.class));
PowerMockito.doCallRealMethod().when(DCGSGenerator.class, "classificationFromDoc", any(Document.class));
DCGSGenerator generator = PowerMockito.spy(createGenerator("sample_data"));
PowerMockito.doNothing().when(generator, "outputToPipes", Mockito.isA(Visibility.class), Mockito.isA(String.class));
generator.generate();
PowerMockito.verifyPrivate(generator, VerificationModeFactory.times(7)).invoke("outputToPipes", Mockito.isA(Visibility.class), Mockito.isA(String.class));
}
private DCGSGenerator createGenerator(String dir) {
return new DCGSGenerator(
properties.getProperty("dcgs.input.sftp.host"),
properties.getProperty("dcgs.input.sftp.username"),
null,//properties.getProperty("dcgs.input.sftp.password", null),
properties.getProperty("dcgs.input.sftp.keyfile", null),
22,
String.format("%s/%s", properties.getProperty("dcgs.input.sftp.path"), dir)
);
}
}
Вот мой основной метод:
public static void main(String[] args) throws IOException {
InputStream propertiesStream = DCGSGenerator.class.getClassLoader().getResourceAsStream("ezbake-config.properties");
Properties properties = new Properties();
properties.load(propertiesStream);
DCGSGenerator gen = new DCGSGenerator(
properties.getProperty("dcgs.input.sftp.host"),
properties.getProperty("dcgs.input.sftp.username"),
null,//properties.getProperty("dcgs.input.sftp.password", null),
properties.getProperty("dcgs.input.sftp.keyfile", null),
22,
properties.getProperty("dcgs.input.sftp.path")
);
gen.generate();
}
И, наконец, конструктор в вопросе:
public DCGSGenerator(String sftpHost, String sftpUser, String sftpPassword, String sftpKeyfile, int sftpPort, String sftpPath) {
super();
try {
this.sftpPath = sftpPath;
if (sftpKeyfile != null) {
sftp = sftpInitKeyfile(sftpHost, sftpUser, sftpKeyfile, sftpPort);
} else {
LOGGER.error("Must specify either sftp keyfile");
throw new RuntimeException();
}
} catch (JSchException e) {
LOGGER.error("Error initializing sftp connection: {}", e.getMessage());
throw new RuntimeException(e);
} catch (IOException e) {
LOGGER.error("Error reading keyfile {}: {}", sftpKeyfile, e.getMessage());
throw new RuntimeException(e);
}
}
}
Чтобы исключить проблемы с конфигурацией на стороне сервера, можете ли вы запустить свой тест и свою обычную программу с точно такими же параметрами? Я имею в виду пользователя, пароль, ключ, работающий на одном хосте, что угодно! Очевидно, что должна быть разница – Raffaele
Параметры идентичны, за исключением последнего (пути), который даже не используется до тех пор, пока код, который бросает исключение. – Derek
Попробуйте захватить пакеты с Wireshark – Raffaele