diff --git a/src/libs/ssh/CMakeLists.txt b/src/libs/ssh/CMakeLists.txt index 0d38ad1de46..d4613851e68 100644 --- a/src/libs/ssh/CMakeLists.txt +++ b/src/libs/ssh/CMakeLists.txt @@ -14,6 +14,5 @@ add_qtc_library(QtcSsh sshkeycreationdialog.cpp sshkeycreationdialog.h sshkeycreationdialog.ui sshlogging.cpp sshlogging_p.h sshremoteprocess.cpp sshremoteprocess.h - sshremoteprocessrunner.cpp sshremoteprocessrunner.h sshsettings.cpp sshsettings.h ) diff --git a/src/libs/ssh/ssh.qbs b/src/libs/ssh/ssh.qbs index 526415a6172..b853cc8b660 100644 --- a/src/libs/ssh/ssh.qbs +++ b/src/libs/ssh/ssh.qbs @@ -33,8 +33,6 @@ Project { "sshlogging_p.h", "sshremoteprocess.cpp", "sshremoteprocess.h", - "sshremoteprocessrunner.cpp", - "sshremoteprocessrunner.h", "sshsettings.cpp", "sshsettings.h", ] diff --git a/src/libs/ssh/sshremoteprocessrunner.cpp b/src/libs/ssh/sshremoteprocessrunner.cpp deleted file mode 100644 index 0bf337917be..00000000000 --- a/src/libs/ssh/sshremoteprocessrunner.cpp +++ /dev/null @@ -1,214 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#include "sshremoteprocessrunner.h" - -#include "sshconnectionmanager.h" - -#include - -/*! - \class QSsh::SshRemoteProcessRunner - - \brief The SshRemoteProcessRunner class is a convenience class for - running a remote process over an SSH connection. -*/ - -using namespace Utils; - -namespace QSsh { -namespace Internal { -namespace { -enum State { Inactive, Connecting, Connected, ProcessRunning }; -} // anonymous namespace - -class SshRemoteProcessRunnerPrivate -{ -public: - SshRemoteProcessRunnerPrivate() : m_state(Inactive) {} - - SshRemoteProcessPtr m_process; - SshConnection *m_connection; - QString m_command; - QString m_lastConnectionErrorString; - QProcess::ExitStatus m_exitStatus; - int m_exitCode; - QString m_errorString; - State m_state; -}; - -} // namespace Internal - -using namespace Internal; - -SshRemoteProcessRunner::SshRemoteProcessRunner(QObject *parent) - : QObject(parent), d(new SshRemoteProcessRunnerPrivate) -{ -} - -SshRemoteProcessRunner::~SshRemoteProcessRunner() -{ - disconnect(); - setState(Inactive); - delete d; -} - -void SshRemoteProcessRunner::run(const QString &command, const SshConnectionParameters &sshParams) -{ - QTC_ASSERT(d->m_state == Inactive, return); - - runInternal(command, sshParams); -} - -void SshRemoteProcessRunner::runInternal(const QString &command, - const SshConnectionParameters &sshParams) -{ - setState(Connecting); - - d->m_lastConnectionErrorString.clear(); - d->m_errorString.clear(); - d->m_exitCode = -1; - d->m_command = command; - d->m_connection = SshConnectionManager::acquireConnection(sshParams); - connect(d->m_connection, &SshConnection::errorOccurred, - this, &SshRemoteProcessRunner::handleConnectionError); - connect(d->m_connection, &SshConnection::disconnected, - this, &SshRemoteProcessRunner::handleDisconnected); - if (d->m_connection->state() == SshConnection::Connected) { - handleConnected(); - } else { - connect(d->m_connection, &SshConnection::connected, this, &SshRemoteProcessRunner::handleConnected); - if (d->m_connection->state() == SshConnection::Unconnected) - d->m_connection->connectToHost(); - } -} - -void SshRemoteProcessRunner::handleConnected() -{ - QTC_ASSERT(d->m_state == Connecting, return); - setState(Connected); - - d->m_process = d->m_connection->createRemoteProcess(d->m_command); - connect(d->m_process.get(), &QtcProcess::started, - this, &SshRemoteProcessRunner::handleProcessStarted); - connect(d->m_process.get(), &QtcProcess::done, - this, &SshRemoteProcessRunner::handleProcessFinished); - connect(d->m_process.get(), &QtcProcess::readyReadStandardOutput, - this, &SshRemoteProcessRunner::readyReadStandardOutput); - connect(d->m_process.get(), &QtcProcess::readyReadStandardError, - this, &SshRemoteProcessRunner::readyReadStandardError); - d->m_process->start(); -} - -void SshRemoteProcessRunner::handleConnectionError() -{ - d->m_lastConnectionErrorString = d->m_connection->errorString(); - handleDisconnected(); - emit connectionError(); -} - -void SshRemoteProcessRunner::handleDisconnected() -{ - QTC_ASSERT(d->m_state == Connecting || d->m_state == Connected || d->m_state == ProcessRunning, - return); - setState(Inactive); -} - -void SshRemoteProcessRunner::handleProcessStarted() -{ - QTC_ASSERT(d->m_state == Connected, return); - - setState(ProcessRunning); - emit started(); -} - -void SshRemoteProcessRunner::handleProcessFinished() -{ - d->m_exitStatus = d->m_process->exitStatus(); - d->m_exitCode = d->m_process->exitCode(); - d->m_errorString = d->m_process->errorString(); - setState(Inactive); - emit finished(); -} - -void SshRemoteProcessRunner::setState(int newState) -{ - if (d->m_state == newState) - return; - - d->m_state = static_cast(newState); - if (d->m_state == Inactive) { - if (d->m_process) - d->m_process.release()->deleteLater(); - if (d->m_connection) { - disconnect(d->m_connection, nullptr, this, nullptr); - SshConnectionManager::releaseConnection(d->m_connection); - d->m_connection = nullptr; - } - } -} - -QString SshRemoteProcessRunner::lastConnectionErrorString() const { - return d->m_lastConnectionErrorString; -} - -bool SshRemoteProcessRunner::isRunning() const -{ - return d->m_process && d->m_process->isRunning(); -} - -QProcess::ExitStatus SshRemoteProcessRunner::exitStatus() const -{ - QTC_CHECK(!isRunning()); - return d->m_exitStatus; -} - -int SshRemoteProcessRunner::exitCode() const -{ - QTC_CHECK(exitStatus() == QProcess::NormalExit); - return d->m_exitCode; -} - -QString SshRemoteProcessRunner::errorString() const -{ - return d->m_errorString; -} - -QByteArray SshRemoteProcessRunner::readAllStandardOutput() -{ - return d->m_process.get() ? d->m_process->readAllStandardOutput() : QByteArray(); -} - -QByteArray SshRemoteProcessRunner::readAllStandardError() -{ - return d->m_process.get() ? d->m_process->readAllStandardError() : QByteArray(); -} - -void SshRemoteProcessRunner::cancel() -{ - setState(Inactive); -} - -} // namespace QSsh diff --git a/src/libs/ssh/sshremoteprocessrunner.h b/src/libs/ssh/sshremoteprocessrunner.h deleted file mode 100644 index f543424de03..00000000000 --- a/src/libs/ssh/sshremoteprocessrunner.h +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#pragma once - -#include "sshconnection.h" -#include "sshremoteprocess.h" - -namespace QSsh { -namespace Internal { class SshRemoteProcessRunnerPrivate; } - -class QSSH_EXPORT SshRemoteProcessRunner : public QObject -{ - Q_OBJECT - -public: - SshRemoteProcessRunner(QObject *parent = nullptr); - ~SshRemoteProcessRunner(); - - void run(const QString &command, const SshConnectionParameters &sshParams); - - QString lastConnectionErrorString() const; - - bool isRunning() const; - void cancel(); - QProcess::ExitStatus exitStatus() const; - int exitCode() const; - QString errorString() const; - QByteArray readAllStandardOutput(); - QByteArray readAllStandardError(); - -signals: - void connectionError(); - void started(); - void finished(); - void readyReadStandardOutput(); - void readyReadStandardError(); - -private: - void handleConnected(); - void handleConnectionError(); - void handleDisconnected(); - void handleProcessStarted(); - void handleProcessFinished(); - void runInternal(const QString &command, const QSsh::SshConnectionParameters &sshParams); - void setState(int newState); - - Internal::SshRemoteProcessRunnerPrivate * const d; -}; - -} // namespace QSsh diff --git a/tests/auto/ssh/tst_ssh.cpp b/tests/auto/ssh/tst_ssh.cpp index 73f52471527..c7c6a85249a 100644 --- a/tests/auto/ssh/tst_ssh.cpp +++ b/tests/auto/ssh/tst_ssh.cpp @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include @@ -59,8 +59,6 @@ private slots: void errorHandling_data(); void errorHandling(); void pristineConnectionObject(); - void remoteProcess_data(); - void remoteProcess(); void remoteProcessChannels(); void remoteProcessInput(); void sftp(); @@ -150,79 +148,6 @@ void tst_Ssh::pristineConnectionObject() QVERIFY(!connection.createRemoteProcess("")); } -void tst_Ssh::remoteProcess_data() -{ - QTest::addColumn("commandLine"); - QTest::addColumn("isBlocking"); - QTest::addColumn("successExpected"); - QTest::addColumn("stdoutExpected"); - QTest::addColumn("stderrExpected"); - - QTest::newRow("normal cmd") << QByteArray("ls -a /tmp") << false << true << true << false; - QTest::newRow("failing cmd") << QByteArray("top -n 1") << false << false << false << true; - QTest::newRow("blocking cmd") << QByteArray("sleep 100") << true << false << false << false; -} - -void tst_Ssh::remoteProcess() -{ - const SshConnectionParameters params = SshTest::getParameters(); - if (!SshTest::checkParameters(params)) - QSKIP("Insufficient setup - set QTC_SSH_TEST_* variables."); - - QFETCH(QByteArray, commandLine); - QFETCH(bool, isBlocking); - QFETCH(bool, successExpected); - QFETCH(bool, stdoutExpected); - QFETCH(bool, stderrExpected); - - QByteArray remoteStdout; - QByteArray remoteStderr; - SshRemoteProcessRunner runner; - QEventLoop loop; - connect(&runner, &SshRemoteProcessRunner::connectionError, &loop, &QEventLoop::quit); - connect(&runner, &SshRemoteProcessRunner::started, &loop, &QEventLoop::quit); - connect(&runner, &SshRemoteProcessRunner::finished, &loop, &QEventLoop::quit); - connect(&runner, &SshRemoteProcessRunner::readyReadStandardOutput, - [&remoteStdout, &runner] { remoteStdout += runner.readAllStandardOutput(); }); - connect(&runner, &SshRemoteProcessRunner::readyReadStandardError, - [&remoteStderr, &runner] { remoteStderr += runner.readAllStandardError(); }); - runner.run(QString::fromUtf8(commandLine), params); - QTimer timer; - QObject::connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit); - timer.setSingleShot(true); - timer.setInterval((params.timeout + 5) * 1000); - timer.start(); - loop.exec(); - QVERIFY(timer.isActive()); - timer.stop(); - QVERIFY2(runner.lastConnectionErrorString().isEmpty(), - qPrintable(runner.lastConnectionErrorString())); - QVERIFY2(runner.errorString().isEmpty(), qPrintable(runner.errorString())); - QVERIFY(runner.isRunning()); // Event loop exit should have been triggered by started(). - QVERIFY2(remoteStdout.isEmpty(), remoteStdout.constData()); - QVERIFY2(remoteStderr.isEmpty(), remoteStderr.constData()); - - SshRemoteProcessRunner killer; - if (isBlocking) - killer.run("pkill -f -9 \"" + QString::fromUtf8(commandLine) + '"', params); - - timer.start(); - loop.exec(); - QVERIFY(timer.isActive()); - timer.stop(); - QVERIFY(!runner.isRunning()); - QVERIFY2(runner.lastConnectionErrorString().isEmpty(), - qPrintable(runner.lastConnectionErrorString())); - if (isBlocking) { - QVERIFY(runner.exitStatus() == QProcess::CrashExit - || runner.exitCode() != 0); - } else { - QCOMPARE(successExpected, runner.exitCode() == 0); - } - QCOMPARE(stdoutExpected, !remoteStdout.isEmpty()); - QCOMPARE(stderrExpected, !remoteStderr.isEmpty()); -} - void tst_Ssh::remoteProcessChannels() { const SshConnectionParameters params = SshTest::getParameters(); @@ -269,41 +194,6 @@ void tst_Ssh::remoteProcessInput() QSKIP("Insufficient setup - set QTC_SSH_TEST_* variables."); SshConnection connection(params); QVERIFY(waitForConnection(connection)); - - SshRemoteProcessPtr catProcess = connection.createRemoteProcess("/bin/cat"); - catProcess->setProcessMode(ProcessMode::Writer); - QEventLoop loop; - connect(catProcess.get(), &QtcProcess::started, &loop, &QEventLoop::quit); - connect(catProcess.get(), &QtcProcess::done, &loop, &QEventLoop::quit); - QTimer timer; - QObject::connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit); - timer.setSingleShot(true); - timer.setInterval((params.timeout + 5) * 1000); - timer.start(); - catProcess->start(); - loop.exec(); - QVERIFY(timer.isActive()); - timer.stop(); - QVERIFY(catProcess->isRunning()); - - static QString testString = "x\r\n"; - connect(catProcess.get(), &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->readAllStandardOutput()); - QCOMPARE(data, testString); - SshRemoteProcessRunner * const killer = new SshRemoteProcessRunner(this); - killer->run("pkill -9 cat", params); - timer.start(); - loop.exec(); - QVERIFY(!catProcess->isRunning()); - QVERIFY(catProcess->exitCode() != 0 || catProcess->exitStatus() == QProcess::CrashExit); } void tst_Ssh::sftp()