From f72c4cb8ac61809742de9106f4c104dbf11ba9e5 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Fri, 25 Jun 2021 14:54:27 +0200 Subject: [PATCH] Ssh: Re-base SshProcess on top of QtcProcess Change-Id: I266820e0e2ea12d6e4a5a83a679a7279fab9cd83 Reviewed-by: hjk --- src/libs/ssh/sftpsession.cpp | 13 ++++--- src/libs/ssh/sftptransfer.cpp | 9 +++-- src/libs/ssh/sshconnection.cpp | 24 ++++++------ src/libs/ssh/sshconnection.h | 8 +++- src/libs/ssh/sshprocess.cpp | 36 +++--------------- src/libs/ssh/sshprocess.h | 14 ++----- src/libs/ssh/sshremoteprocess.cpp | 21 +++++----- src/libs/ssh/sshremoteprocess.h | 3 +- src/libs/ssh/sshremoteprocessrunner.cpp | 6 +-- src/libs/ssh/sshremoteprocessrunner.h | 2 +- .../devicesupport/sshdeviceprocess.cpp | 8 ++-- src/plugins/remotelinux/linuxdevicetester.cpp | 8 ++-- .../remotelinuxsignaloperation.cpp | 2 +- src/plugins/remotelinux/rsyncdeploystep.cpp | 11 +++--- tests/auto/ssh/CMakeLists.txt | 4 ++ tests/auto/ssh/ssh.pro | 4 ++ tests/auto/ssh/ssh.qbs | 10 ++++- tests/auto/ssh/tst_ssh.cpp | 38 +++++++++++++------ 18 files changed, 116 insertions(+), 105 deletions(-) diff --git a/src/libs/ssh/sftpsession.cpp b/src/libs/ssh/sftpsession.cpp index 80762a643e7..5abbe52bcc6 100644 --- a/src/libs/ssh/sftpsession.cpp +++ b/src/libs/ssh/sftpsession.cpp @@ -58,7 +58,7 @@ struct Command struct SftpSession::SftpSessionPrivate { - SshProcess sftpProc; + SshProcess sftpProc = {ProcessMode::Writer}; QStringList connectionArgs; QByteArray output; QQueue pendingCommands; @@ -112,17 +112,17 @@ static QByteArray prompt() { return "sftp> "; } SftpSession::SftpSession(const QStringList &connectionArgs) : d(new SftpSessionPrivate) { d->connectionArgs = connectionArgs; - connect(&d->sftpProc, &QProcess::started, [this] { + connect(&d->sftpProc, &QtcProcess::started, [this] { qCDebug(sshLog) << "sftp process started"; d->sftpProc.write("\n"); // Force initial prompt. }); - connect(&d->sftpProc, &QProcess::errorOccurred, [this](QProcess::ProcessError error) { + connect(&d->sftpProc, &QtcProcess::errorOccurred, [this](QProcess::ProcessError error) { if (error == QProcess::FailedToStart) { d->state = State::Inactive; emit done(tr("sftp failed to start: %1").arg(d->sftpProc.errorString())); } }); - connect(&d->sftpProc, QOverload::of(&QProcess::finished), [this] { + connect(&d->sftpProc, &QtcProcess::finished, [this] { qCDebug(sshLog) << "sftp process finished"; d->state = State::Inactive; @@ -136,7 +136,7 @@ SftpSession::SftpSession(const QStringList &connectionArgs) : d(new SftpSessionP } emit done(QString()); }); - connect(&d->sftpProc, &QProcess::readyReadStandardOutput, this, &SftpSession::handleStdout); + connect(&d->sftpProc, &QtcProcess::readyReadStandardOutput, this, &SftpSession::handleStdout); } void SftpSession::doStart() @@ -153,7 +153,8 @@ void SftpSession::doStart() d->activeCommand = Command(); const QStringList args = QStringList{"-q"} << d->connectionArgs; qCDebug(sshLog) << "starting sftp session:" << sftpBinary.toUserOutput() << args; - d->sftpProc.start(sftpBinary.toString(), args); + d->sftpProc.setCommand(CommandLine(sftpBinary, args)); + d->sftpProc.start(); } void SftpSession::handleStdout() diff --git a/src/libs/ssh/sftptransfer.cpp b/src/libs/ssh/sftptransfer.cpp index c7561e611ae..26d4306f5c7 100644 --- a/src/libs/ssh/sftptransfer.cpp +++ b/src/libs/ssh/sftptransfer.cpp @@ -113,11 +113,11 @@ SftpTransfer::SftpTransfer(const FilesToTransfer &files, Internal::FileTransferT d->transferType = type; d->errorHandlingMode = errorHandlingMode; d->connectionArgs = connectionArgs; - connect(&d->sftpProc, &QProcess::errorOccurred, [this](QProcess::ProcessError error) { + connect(&d->sftpProc, &QtcProcess::errorOccurred, [this](QProcess::ProcessError error) { if (error == QProcess::FailedToStart) emitError(tr("sftp failed to start: %1").arg(d->sftpProc.errorString())); }); - connect(&d->sftpProc, QOverload::of(&QProcess::finished), [this] { + connect(&d->sftpProc, &QtcProcess::finished, [this] { if (d->sftpProc.exitStatus() != QProcess::NormalExit) { emitError(tr("sftp crashed.")); return; @@ -128,7 +128,7 @@ SftpTransfer::SftpTransfer(const FilesToTransfer &files, Internal::FileTransferT } emit done(QString()); }); - connect(&d->sftpProc, &QProcess::readyReadStandardOutput, [this] { + connect(&d->sftpProc, &QtcProcess::readyReadStandardOutput, [this] { emit progress(QString::fromLocal8Bit(d->sftpProc.readAllStandardOutput())); }); } @@ -179,7 +179,8 @@ void SftpTransfer::doStart() + ProcessArgs::quoteArgUnix(f.targetFile).toLocal8Bit() + '\n'); } d->sftpProc.setStandardInputFile(batchFile.fileName()); - d->sftpProc.start(sftpBinary.toString(), d->connectionArgs); + d->sftpProc.setCommand(CommandLine(sftpBinary, d->connectionArgs)); + d->sftpProc.start(); emit started(); } diff --git a/src/libs/ssh/sshconnection.cpp b/src/libs/ssh/sshconnection.cpp index 00e7cc84a4f..df548099917 100644 --- a/src/libs/ssh/sshconnection.cpp +++ b/src/libs/ssh/sshconnection.cpp @@ -167,7 +167,7 @@ SshConnection::SshConnection(const SshConnectionParameters &serverInfo, QObject qRegisterMetaType("QSsh::SftpFileInfo"); qRegisterMetaType >("QList"); d->connParams = serverInfo; - connect(&d->masterProcess, &QProcess::started, [this] { + connect(&d->masterProcess, &QtcProcess::started, [this] { QFileInfo socketInfo(d->socketFilePath()); if (socketInfo.exists()) { emitConnected(); @@ -194,7 +194,7 @@ SshConnection::SshConnection(const SshConnectionParameters &serverInfo, QObject socketWatcherTimer->start(); } }); - connect(&d->masterProcess, &QProcess::errorOccurred, [this] (QProcess::ProcessError error) { + connect(&d->masterProcess, &QtcProcess::errorOccurred, [this] (QProcess::ProcessError error) { switch (error) { case QProcess::FailedToStart: emitError(tr("Cannot establish SSH connection: Control process failed to start: %1") @@ -208,7 +208,7 @@ SshConnection::SshConnection(const SshConnectionParameters &serverInfo, QObject break; // Cannot happen. } }); - connect(&d->masterProcess, QOverload::of(&QProcess::finished), [this] { + connect(&d->masterProcess, &QtcProcess::finished, [this] { if (d->state == Disconnecting) { emitDisconnected(); return; @@ -220,9 +220,9 @@ SshConnection::SshConnection(const SshConnectionParameters &serverInfo, QObject emitError(errorMsg); }); if (!d->connParams.x11DisplayName.isEmpty()) { - QProcessEnvironment env = d->masterProcess.processEnvironment(); - env.insert("DISPLAY", d->connParams.x11DisplayName); - d->masterProcess.setProcessEnvironment(env); + Environment env = d->masterProcess.environment(); + env.set("DISPLAY", d->connParams.x11DisplayName); + d->masterProcess.setEnvironment(env); } } @@ -316,16 +316,17 @@ SshConnection::~SshConnection() delete d; } -SshRemoteProcessPtr SshConnection::createRemoteProcess(const QString &command) +SshRemoteProcessPtr SshConnection::createRemoteProcess(const QString &command, ProcessMode processMode) { QTC_ASSERT(state() == Connected, return SshRemoteProcessPtr()); return SshRemoteProcessPtr(new SshRemoteProcess(command, - d->connectionArgs(SshSettings::sshFilePath()))); + d->connectionArgs(SshSettings::sshFilePath()), + processMode)); } -SshRemoteProcessPtr SshConnection::createRemoteShell() +SshRemoteProcessPtr SshConnection::createRemoteShell(ProcessMode processMode) { - return createRemoteProcess({}); + return createRemoteProcess({}, processMode); } SftpTransferPtr SshConnection::createUpload(const FilesToTransfer &files, @@ -372,7 +373,8 @@ void SshConnection::doConnectToHost() if (!d->connParams.x11DisplayName.isEmpty()) args.prepend("-X"); qCDebug(sshLog) << "establishing connection:" << sshBinary.toUserOutput() << args; - d->masterProcess.start(sshBinary.toString(), args); + d->masterProcess.setCommand(CommandLine(sshBinary, args)); + d->masterProcess.start(); } void SshConnection::emitError(const QString &reason) diff --git a/src/libs/ssh/sshconnection.h b/src/libs/ssh/sshconnection.h index f29a6d67b0c..2778be02e08 100644 --- a/src/libs/ssh/sshconnection.h +++ b/src/libs/ssh/sshconnection.h @@ -28,6 +28,8 @@ #include "sftpdefs.h" #include "ssh_global.h" +#include + #include #include #include @@ -113,8 +115,10 @@ public: bool sharingEnabled() const; ~SshConnection(); - SshRemoteProcessPtr createRemoteProcess(const QString &command); - SshRemoteProcessPtr createRemoteShell(); + SshRemoteProcessPtr createRemoteProcess(const QString &command, Utils::ProcessMode processMode + = Utils::ProcessMode::Reader); + SshRemoteProcessPtr createRemoteShell(Utils::ProcessMode processMode + = Utils::ProcessMode::Reader); SftpTransferPtr createUpload(const FilesToTransfer &files, FileTransferErrorHandling errorHandlingMode); SftpTransferPtr createDownload(const FilesToTransfer &files, diff --git a/src/libs/ssh/sshprocess.cpp b/src/libs/ssh/sshprocess.cpp index eee6253a0a7..42810356688 100644 --- a/src/libs/ssh/sshprocess.cpp +++ b/src/libs/ssh/sshprocess.cpp @@ -36,7 +36,8 @@ namespace QSsh { -SshProcess::SshProcess() +SshProcess::SshProcess(Utils::ProcessMode processMode) + : Utils::QtcProcess(processMode) { Utils::Environment env = Utils::Environment::systemEnvironment(); if (SshSettings::askpassFilePath().exists()) { @@ -46,37 +47,10 @@ SshProcess::SshProcess() if (!env.hasKey("DISPLAY")) env.set("DISPLAY", ":0"); } - setProcessEnvironment(env.toProcessEnvironment()); -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) && defined(Q_OS_UNIX) - setChildProcessModifier([this] { setupChildProcess_impl(); }); -#endif -} + setEnvironment(env); -SshProcess::~SshProcess() -{ - if (state() == QProcess::NotRunning) - return; - disconnect(); - terminate(); - waitForFinished(1000); - if (state() == QProcess::NotRunning) - return; - kill(); - waitForFinished(1000); -} - -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) -void SshProcess::setupChildProcess() -{ - setupChildProcess_impl(); -} -#endif - -void SshProcess::setupChildProcess_impl() -{ -#ifdef Q_OS_UNIX - setsid(); // Otherwise, ssh will ignore SSH_ASKPASS and read from /dev/tty directly. -#endif + // Otherwise, ssh will ignore SSH_ASKPASS and read from /dev/tty directly. + setDisableUnixTerminal(); } } // namespace QSsh diff --git a/src/libs/ssh/sshprocess.h b/src/libs/ssh/sshprocess.h index 8f85ec2cf76..00610bcd69a 100644 --- a/src/libs/ssh/sshprocess.h +++ b/src/libs/ssh/sshprocess.h @@ -27,22 +27,14 @@ #include "ssh_global.h" -#include +#include namespace QSsh { -class QSSH_EXPORT SshProcess : public QProcess +class QSSH_EXPORT SshProcess : public Utils::QtcProcess { public: - SshProcess(); - ~SshProcess() override; - -private: -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - void setupChildProcess() override; -#endif - - void setupChildProcess_impl(); + SshProcess(Utils::ProcessMode processMode = Utils::ProcessMode::Reader); }; } // namespace QSsh diff --git a/src/libs/ssh/sshremoteprocess.cpp b/src/libs/ssh/sshremoteprocess.cpp index fdfe76e9b29..1d878bc8641 100644 --- a/src/libs/ssh/sshremoteprocess.cpp +++ b/src/libs/ssh/sshremoteprocess.cpp @@ -60,13 +60,15 @@ struct SshRemoteProcess::SshRemoteProcessPrivate bool useTerminal = false; }; -SshRemoteProcess::SshRemoteProcess(const QString &command, const QStringList &connectionArgs) - : d(new SshRemoteProcessPrivate) +SshRemoteProcess::SshRemoteProcess(const QString &command, const QStringList &connectionArgs, + Utils::ProcessMode processMode) + : SshProcess(processMode) + , d(new SshRemoteProcessPrivate) { d->remoteCommand = command; d->connectionArgs = connectionArgs; - connect(this, QOverload::of(&QProcess::finished), this, [this] { + connect(this, &QtcProcess::finished, this, [this] { QString error; if (exitStatus() == QProcess::CrashExit) error = tr("The ssh process crashed: %1").arg(errorString()); @@ -74,7 +76,7 @@ SshRemoteProcess::SshRemoteProcess(const QString &command, const QStringList &co error = tr("Remote process crashed."); emit done(error); }); - connect(this, &QProcess::errorOccurred, [this](QProcess::ProcessError error) { + connect(this, &QtcProcess::errorOccurred, [this](QProcess::ProcessError error) { if (error == QProcess::FailedToStart) emit done(errorString()); }); @@ -85,12 +87,13 @@ void SshRemoteProcess::doStart() QTC_ASSERT(!isRunning(), return); const Utils::CommandLine cmd = fullLocalCommandLine(); if (!d->displayName.isEmpty()) { - QProcessEnvironment env = processEnvironment(); - env.insert("DISPLAY", d->displayName); - setProcessEnvironment(env); + Utils::Environment env = environment(); + env.set("DISPLAY", d->displayName); + setEnvironment(env); } qCDebug(sshLog) << "starting remote process:" << cmd.toUserOutput(); - QProcess::start(cmd.executable().toString(), cmd.splitArguments()); + setCommand(cmd); + QtcProcess::start(); } SshRemoteProcess::~SshRemoteProcess() @@ -110,7 +113,7 @@ void SshRemoteProcess::requestX11Forwarding(const QString &displayName) void SshRemoteProcess::start() { - QTimer::singleShot(0, this, &SshRemoteProcess::doStart); + doStart(); } bool SshRemoteProcess::isRunning() const diff --git a/src/libs/ssh/sshremoteprocess.h b/src/libs/ssh/sshremoteprocess.h index 16793d1c013..6891289669a 100644 --- a/src/libs/ssh/sshremoteprocess.h +++ b/src/libs/ssh/sshremoteprocess.h @@ -54,7 +54,8 @@ signals: void done(const QString &error); private: - SshRemoteProcess(const QString &command, const QStringList &connectionArgs); + SshRemoteProcess(const QString &command, const QStringList &connectionArgs, + Utils::ProcessMode processMode = Utils::ProcessMode::Reader); void doStart(); struct SshRemoteProcessPrivate; diff --git a/src/libs/ssh/sshremoteprocessrunner.cpp b/src/libs/ssh/sshremoteprocessrunner.cpp index 195d325bce7..b444cf52528 100644 --- a/src/libs/ssh/sshremoteprocessrunner.cpp +++ b/src/libs/ssh/sshremoteprocessrunner.cpp @@ -186,7 +186,7 @@ void SshRemoteProcessRunner::setState(int newState) if (d->m_process) { disconnect(d->m_process.get(), nullptr, this, nullptr); d->m_process->terminate(); - d->m_process.release()->deleteLater(); + d->m_process.reset(); } if (d->m_connection) { disconnect(d->m_connection, nullptr, this, nullptr); @@ -206,7 +206,7 @@ bool SshRemoteProcessRunner::isProcessRunning() const return d->m_process && d->m_process->isRunning(); } -SshRemoteProcess::ExitStatus SshRemoteProcessRunner::processExitStatus() const +QProcess::ExitStatus SshRemoteProcessRunner::processExitStatus() const { QTC_CHECK(!isProcessRunning()); return d->m_exitStatus; @@ -214,7 +214,7 @@ SshRemoteProcess::ExitStatus SshRemoteProcessRunner::processExitStatus() const int SshRemoteProcessRunner::processExitCode() const { - QTC_CHECK(processExitStatus() == SshRemoteProcess::NormalExit); + QTC_CHECK(processExitStatus() == QProcess::NormalExit); return d->m_exitCode; } diff --git a/src/libs/ssh/sshremoteprocessrunner.h b/src/libs/ssh/sshremoteprocessrunner.h index 5b3f1b05b4b..84f92e690f0 100644 --- a/src/libs/ssh/sshremoteprocessrunner.h +++ b/src/libs/ssh/sshremoteprocessrunner.h @@ -48,7 +48,7 @@ public: bool isProcessRunning() const; void writeDataToProcess(const QByteArray &data); void cancel(); - SshRemoteProcess::ExitStatus processExitStatus() const; + QProcess::ExitStatus processExitStatus() const; int processExitCode() const; QString processErrorString() const; QByteArray readAllStandardOutput(); diff --git a/src/plugins/projectexplorer/devicesupport/sshdeviceprocess.cpp b/src/plugins/projectexplorer/devicesupport/sshdeviceprocess.cpp index 5276f41e4d1..56c7a887a78 100644 --- a/src/plugins/projectexplorer/devicesupport/sshdeviceprocess.cpp +++ b/src/plugins/projectexplorer/devicesupport/sshdeviceprocess.cpp @@ -149,7 +149,7 @@ QProcess::ProcessState SshDeviceProcess::state() const QProcess::ExitStatus SshDeviceProcess::exitStatus() const { - return d->exitStatus == QSsh::SshRemoteProcess::NormalExit && d->exitCode != 255 + return d->exitStatus == QProcess::NormalExit && d->exitCode != 255 ? QProcess::NormalExit : QProcess::CrashExit; } @@ -237,7 +237,7 @@ void SshDeviceProcess::handleDisconnected() emit error(QProcess::FailedToStart); break; case SshDeviceProcessPrivate::ProcessRunning: - d->exitStatus = QSsh::SshRemoteProcess::CrashExit; + d->exitStatus = QProcess::CrashExit; emit finished(); default: break; @@ -284,7 +284,7 @@ void SshDeviceProcess::handleKillOperationFinished(const QString &errorMessage) if (errorMessage.isEmpty()) // Process will finish as expected; nothing to do here. return; - d->exitStatus = QSsh::SshRemoteProcess::CrashExit; // Not entirely true, but it will get the message across. + d->exitStatus = QProcess::CrashExit; // Not entirely true, but it will get the message across. d->errorMessage = tr("Failed to kill remote process: %1").arg(errorMessage); d->setState(SshDeviceProcessPrivate::Inactive); emit finished(); @@ -292,7 +292,7 @@ void SshDeviceProcess::handleKillOperationFinished(const QString &errorMessage) void SshDeviceProcess::handleKillOperationTimeout() { - d->exitStatus = QSsh::SshRemoteProcess::CrashExit; // Not entirely true, but it will get the message across. + d->exitStatus = QProcess::CrashExit; // Not entirely true, but it will get the message across. d->errorMessage = tr("Timeout waiting for remote process to finish."); d->setState(SshDeviceProcessPrivate::Inactive); emit finished(); diff --git a/src/plugins/remotelinux/linuxdevicetester.cpp b/src/plugins/remotelinux/linuxdevicetester.cpp index 5d7944c0c3d..1353d91764f 100644 --- a/src/plugins/remotelinux/linuxdevicetester.cpp +++ b/src/plugins/remotelinux/linuxdevicetester.cpp @@ -220,19 +220,19 @@ void GenericLinuxDeviceTester::handleSftpFinished(const QString &error) void GenericLinuxDeviceTester::testRsync() { emit progressMessage(tr("Checking whether rsync works...")); - connect(&d->rsyncProcess, &QProcess::errorOccurred, [this] { + connect(&d->rsyncProcess, &Utils::QtcProcess::errorOccurred, [this] { if (d->rsyncProcess.error() == QProcess::FailedToStart) handleRsyncFinished(); }); - connect(&d->rsyncProcess, QOverload::of(&QProcess::finished), - this, [this] { + connect(&d->rsyncProcess, &Utils::QtcProcess::finished, this, [this] { handleRsyncFinished(); }); const RsyncCommandLine cmdLine = RsyncDeployStep::rsyncCommand(*d->connection, RsyncDeployStep::defaultFlags()); const QStringList args = QStringList(cmdLine.options) << "-n" << "--exclude=*" << (cmdLine.remoteHostSpec + ":/tmp"); - d->rsyncProcess.start("rsync", args); + d->rsyncProcess.setCommand(Utils::CommandLine("rsync", args)); + d->rsyncProcess.start(); } void GenericLinuxDeviceTester::handleRsyncFinished() diff --git a/src/plugins/remotelinux/remotelinuxsignaloperation.cpp b/src/plugins/remotelinux/remotelinuxsignaloperation.cpp index b2dcdf1233b..2b582479036 100644 --- a/src/plugins/remotelinux/remotelinuxsignaloperation.cpp +++ b/src/plugins/remotelinux/remotelinuxsignaloperation.cpp @@ -119,7 +119,7 @@ void RemoteLinuxSignalOperation::interruptProcess(const QString &filePath) void RemoteLinuxSignalOperation::runnerProcessFinished() { m_errorMessage.clear(); - if (m_runner->processExitStatus() != QSsh::SshRemoteProcess::NormalExit) { + if (m_runner->processExitStatus() != QProcess::NormalExit) { m_errorMessage = m_runner->processErrorString(); } else if (m_runner->processExitCode() != 0) { m_errorMessage = tr("Exit code is %1. stderr:").arg(m_runner->processExitCode()) diff --git a/src/plugins/remotelinux/rsyncdeploystep.cpp b/src/plugins/remotelinux/rsyncdeploystep.cpp index 7005d77e9a7..c5a2840dbc7 100644 --- a/src/plugins/remotelinux/rsyncdeploystep.cpp +++ b/src/plugins/remotelinux/rsyncdeploystep.cpp @@ -123,19 +123,19 @@ void RsyncDeployService::createRemoteDirectories() void RsyncDeployService::deployFiles() { - connect(&m_rsync, &QProcess::readyReadStandardOutput, this, [this] { + connect(&m_rsync, &QtcProcess::readyReadStandardOutput, this, [this] { emit progressMessage(QString::fromLocal8Bit(m_rsync.readAllStandardOutput())); }); - connect(&m_rsync, &QProcess::readyReadStandardError, this, [this] { + connect(&m_rsync, &QtcProcess::readyReadStandardError, this, [this] { emit warningMessage(QString::fromLocal8Bit(m_rsync.readAllStandardError())); }); - connect(&m_rsync, &QProcess::errorOccurred, this, [this] { + connect(&m_rsync, &QtcProcess::errorOccurred, this, [this] { if (m_rsync.error() == QProcess::FailedToStart) { emit errorMessage(tr("rsync failed to start: %1").arg(m_rsync.errorString())); setFinished(); } }); - connect(&m_rsync, QOverload::of(&QProcess::finished), this, [this] { + connect(&m_rsync, &QtcProcess::finished, this, [this] { if (m_rsync.exitStatus() == QProcess::CrashExit) { emit errorMessage(tr("rsync crashed.")); setFinished(); @@ -173,7 +173,8 @@ void RsyncDeployService::deployNextFile() const QStringList args = QStringList(cmdLine.options) << (localFilePath + (file.localFilePath().isDir() ? "/" : QString())) << (cmdLine.remoteHostSpec + ':' + file.remoteFilePath()); - m_rsync.start("rsync", args); // TODO: Get rsync location from settings? + m_rsync.setCommand(CommandLine("rsync", args)); + m_rsync.start(); // TODO: Get rsync location from settings? } void RsyncDeployService::setFinished() diff --git a/tests/auto/ssh/CMakeLists.txt b/tests/auto/ssh/CMakeLists.txt index 590144d3bd7..2156e6d59aa 100644 --- a/tests/auto/ssh/CMakeLists.txt +++ b/tests/auto/ssh/CMakeLists.txt @@ -1,4 +1,8 @@ +file(RELATIVE_PATH RELATIVE_TEST_PATH "${PROJECT_BINARY_DIR}" "${CMAKE_CURRENT_BINARY_DIR}") +file(RELATIVE_PATH TEST_RELATIVE_LIBEXEC_PATH "/${RELATIVE_TEST_PATH}" "/${IDE_LIBEXEC_PATH}") + add_qtc_test(tst_ssh + DEFINES "TEST_RELATIVE_LIBEXEC_PATH=\"${TEST_RELATIVE_LIBEXEC_PATH}\"" DEPENDS Utils QtcSsh SOURCES tst_ssh.cpp ) diff --git a/tests/auto/ssh/ssh.pro b/tests/auto/ssh/ssh.pro index 8ba850177df..a4e519e4fbe 100644 --- a/tests/auto/ssh/ssh.pro +++ b/tests/auto/ssh/ssh.pro @@ -2,4 +2,8 @@ QT = core network QTC_LIB_DEPENDS += ssh utils include(../qttest.pri) +TEST_RELATIVE_LIBEXEC_PATH = $$relative_path($$IDE_LIBEXEC_PATH, $$OUT_PWD) +win32:TEST_RELATIVE_LIBEXEC_PATH=../$$TEST_RELATIVE_LIBEXEC_PATH +DEFINES += 'TEST_RELATIVE_LIBEXEC_PATH="\\\"$$TEST_RELATIVE_LIBEXEC_PATH\\\""' + SOURCES += tst_ssh.cpp diff --git a/tests/auto/ssh/ssh.qbs b/tests/auto/ssh/ssh.qbs index c2b7072b558..3f513cca778 100644 --- a/tests/auto/ssh/ssh.qbs +++ b/tests/auto/ssh/ssh.qbs @@ -1,8 +1,16 @@ -import qbs +import qbs.FileInfo QtcAutotest { name: "SSH autotest" Depends { name: "QtcSsh" } Depends { name: "Utils" } files: "tst_ssh.cpp" + cpp.defines: { + var defines = base; + var absLibExecPath = FileInfo.joinPaths(qbs.installRoot, qbs.installPrefix, + qtc.ide_libexec_path); + var relLibExecPath = FileInfo.relativePath(destinationDirectory, absLibExecPath); + defines.push('TEST_RELATIVE_LIBEXEC_PATH="' + relLibExecPath + '"'); + return defines; + } } diff --git a/tests/auto/ssh/tst_ssh.cpp b/tests/auto/ssh/tst_ssh.cpp index 9a56cb1b899..6f9c0a1ca09 100644 --- a/tests/auto/ssh/tst_ssh.cpp +++ b/tests/auto/ssh/tst_ssh.cpp @@ -29,8 +29,12 @@ #include #include #include + #include #include +#include +#include +#include #include #include @@ -114,14 +118,20 @@ private slots: void remoteProcessInput(); void sftp(); + void cleanupTestCase(); private: bool waitForConnection(SshConnection &connection); - SshConnectionManager sshConnectionManager; + Utils::ProcessReaper *processReaper = nullptr; + SshConnectionManager *sshConnectionManager = nullptr; }; void tst_Ssh::initTestCase() { + processReaper = new Utils::ProcessReaper(); + Utils::LauncherInterface::startLauncher(qApp->applicationDirPath() + '/' + + QLatin1String(TEST_RELATIVE_LIBEXEC_PATH)); + sshConnectionManager = new SshConnectionManager(); Utils::TemporaryDirectory::setMasterTemporaryDirectory(QDir::tempPath() + "/qtc-ssh-autotest-XXXXXX"); } @@ -269,7 +279,7 @@ void tst_Ssh::remoteProcess() QVERIFY2(runner.lastConnectionErrorString().isEmpty(), qPrintable(runner.lastConnectionErrorString())); if (isBlocking) { - QVERIFY(runner.processExitStatus() == SshRemoteProcess::CrashExit + QVERIFY(runner.processExitStatus() == QProcess::CrashExit || runner.processExitCode() != 0); } else { QCOMPARE(successExpected, runner.processExitCode() == 0); @@ -291,11 +301,10 @@ void tst_Ssh::remoteProcessChannels() QByteArray remoteData; SshRemoteProcessPtr echoProcess = connection.createRemoteProcess("printf " + QString::fromUtf8(testString) + " >&2"); - echoProcess->setReadChannel(QProcess::StandardError); QEventLoop loop; connect(echoProcess.get(), &SshRemoteProcess::done, &loop, &QEventLoop::quit); - connect(echoProcess.get(), &QIODevice::readyRead, - [&remoteData, p = echoProcess.get()] { remoteData += p->readAll(); }); + connect(echoProcess.get(), &Utils::QtcProcess::readyReadStandardError, + [&remoteData, p = echoProcess.get()] { remoteData += p->readAllStandardError(); }); connect(echoProcess.get(), &SshRemoteProcess::readyReadStandardOutput, [&remoteStdout, p = echoProcess.get()] { remoteStdout += p->readAllStandardOutput(); }); connect(echoProcess.get(), &SshRemoteProcess::readyReadStandardError, @@ -324,7 +333,8 @@ void tst_Ssh::remoteProcessInput() SshConnection connection(params); QVERIFY(waitForConnection(connection)); - SshRemoteProcessPtr catProcess = connection.createRemoteProcess("/bin/cat"); + SshRemoteProcessPtr catProcess = connection.createRemoteProcess("/bin/cat", + Utils::ProcessMode::Writer); QEventLoop loop; connect(catProcess.get(), &SshRemoteProcess::started, &loop, &QEventLoop::quit); connect(catProcess.get(), &SshRemoteProcess::done, &loop, &QEventLoop::quit); @@ -340,17 +350,16 @@ void tst_Ssh::remoteProcessInput() QVERIFY(catProcess->isRunning()); static QString testString = "x\r\n"; - connect(catProcess.get(), &QIODevice::readyRead, &loop, &QEventLoop::quit); - QTextStream stream(catProcess.get()); - stream << testString; - stream.flush(); + connect(catProcess.get(), &Utils::QtcProcess::readyReadStandardOutput, &loop, &QEventLoop::quit); + + catProcess->write(testString.toUtf8()); timer.start(); loop.exec(); QVERIFY(timer.isActive()); timer.stop(); QVERIFY(catProcess->isRunning()); - const QString data = QString::fromUtf8(catProcess->readAll()); + const QString data = QString::fromUtf8(catProcess->readAllStandardOutput()); QCOMPARE(data, testString); SshRemoteProcessRunner * const killer = new SshRemoteProcessRunner(this); killer->run("pkill -9 cat", params); @@ -623,6 +632,13 @@ void tst_Ssh::sftp() QVERIFY2(connection.errorString().isEmpty(), qPrintable(connection.errorString())); } +void tst_Ssh::cleanupTestCase() +{ + delete sshConnectionManager; + Utils::LauncherInterface::stopLauncher(); + delete processReaper; +} + bool tst_Ssh::waitForConnection(SshConnection &connection) { QEventLoop loop;