集成测试-虚拟ssh服务器未正确执行ssh命令

kcugc4gi  于 2021-07-15  发布在  Java
关注(0)|答案(2)|浏览(262)

Spring 批处理项目。sshiservice接受ssh命令并执行它们。当项目在jenkins管道中运行时,它能够创建ssh连接,而我的sshiservice运行得很好。
在为这个sshiservice服务编写集成测试时,我创建了一个虚拟ssh服务器,这个服务可以与之对话。
问题:在集成测试中,当我发送如下命令时 mkdir src/test/resources/Folder1 ; ls src/test/resources/Folder1 ; 错误是:

mkdir: ls: File exists
mkdir: src/test/resources/Folder1: File exists
mkdir: ;: File exists

该服务并不认为这些是单独的命令,而是作为 mkdir 这是错误的!这个问题不是特定于 mkdir . 每次在集成测试中执行多个由分号分隔的命令时,就会出现问题。
我不想对sshiservice进行更改,因为整个项目都在使用这种逻辑。问题似乎出现在为集成测试创建的ssh服务器中。
集成测试代码

@SpringBootTest
@ContextConfiguration(classes = {SshIService.class, SshSftpConfiguration.class})
@ActiveProfiles("test")
public class SshSftpIntegrationTest {

    @Autowired
    private SshIService SshIService;

    private SshServer dummy_sshd;

    @SneakyThrows
    @BeforeEach
    public void setUp() {
        dummy_sshd = SshServer.setUpDefaultServer();
        dummy_sshd.setPort(9999);
        dummy_sshd.setKeyPairProvider(new SimpleGeneratorHostKeyProvider());
        dummy_sshd.setPasswordAuthenticator((username, password, session) -> username.equals("someUserName") && password.equals("somePassword"));
        dummy_sshd.setSubsystemFactories(Collections.singletonList(new SftpSubsystemFactory()));
        dummy_sshd.setCommandFactory(new ProcessShellCommandFactory());
        dummy_sshd.start();
    }

    @SneakyThrows
    @AfterEach
    public void cleanup() {
        dummy_sshd.stop();
    }

    @SneakyThrows
    @Test
    public void sendCommandTest() {
        SshIService.sendCommand("mkdir src/test/resources/Folder1 ; ls src/test/resources/Folder1 ;");
        //Some assertions!
    }
}

sshiservice代码

@Slf4j
@Service
public class SshIService {
    private final SshSftpConfiguration sshSftpConfiguration;
    private final JSch sshTunnel;

    private Session sshSession;
    private ChannelSftp channelSftp;

    public SshIService(SshSftpConfiguration sshSftpConfiguration,
                          JSch sshTunnel) {
        this.sshSftpConfiguration = sshSftpConfiguration;
        this.sshTunnel = sshTunnel;
    }

    public String sendCommand(String command) throws IOException, JSchException, InterruptedException {
        try {
            connect();
            Channel channel = sshSession.openChannel("exec");
            ((ChannelExec) channel).setCommand(command);
            channel.setInputStream(null);
            ((ChannelExec) channel).setErrStream(System.err);
            InputStream in = channel.getInputStream();
            channel.connect();
            StringBuilder output = new StringBuilder();
            int bytesRead;
            byte[] buffer = new byte[1024];
            while (!channel.isClosed()) {
                while ((bytesRead = in.read(buffer, 0, buffer.length)) != -1) {
                    output.append(new String(buffer, 0, bytesRead));
                }
                Thread.sleep(100);
            }
            channel.disconnect();
            return cmdOut;
        } catch (IOException | JSchException | InterruptedException ioX) {
            log.error("Error: {}", ioX.getMessage());
            throw ioX;
        }
    }

    public String getHostAddress() throws UnknownHostException {
        return InetAddress.getLocalHost().getHostAddress();
    }

    public void connect() {
        try {
            if (sshSession == null || !sshSession.isConnected()) {
                sshSession = sshTunnel.getSession(sshSftpConfiguration.getUsername(), sshSftpConfiguration.getHost());
                sshSession.setPort(sshSftpConfiguration.getPort());
                sshSession.setPassword(sshSftpConfiguration.getPassword());
                sshSession.setConfig("StrictHostKeyChecking", "no");
            }

            if (sshSession != null && !sshSession.isConnected()) {
                sshSession.connect();
            }

            if (sshSession != null && channelSftp == null || !channelSftp.isConnected()) {
                channelSftp = (ChannelSftp) sshSession.openChannel("sftp");
                channelSftp.connect();
            }

        } catch (JSchException e) {
            log.error(ExceptionUtils.getStackTrace(e));
        }
    }

    public ChannelSftp getChannelSftp() {
        return channelSftp;
    }

    public void setChannelSftp(ChannelSftp channelSftp) {
        this.channelSftp = channelSftp;
    }

    public Session getSshSession() {
        return sshSession;
    }

    public void setSshSession(Session sshSession) {
        this.sshSession = sshSession;
    }
}

有什么建议吗?

omvjsjqw

omvjsjqw1#

您不是通过ssh连接到一个真正的服务器,而是连接到一个apacheminash服务器,只有一个sftp子系统。
这并不意味着它可以接受任意的os/shell命令。
https://mina.apache.org/sshd-project/
sshd的目标并不是真正取代unix操作系统中的ssh客户机或ssh服务器,而是为需要ssh支持的基于java的应用程序提供支持。

siotufzp

siotufzp2#

试试sshiservice.sendcommand(“mkdir src/test/resources/folder1&&ls src/test/resources/folder1”);

相关问题