diff options
author | Christian Kandeler <christian.kandeler@nokia.com> | 2011-11-15 17:13:02 +0100 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@nokia.com> | 2011-11-15 17:32:55 +0100 |
commit | 4c76e40617d22d3578bb95973b54b0e266591e7c (patch) | |
tree | 8b89776bde4cd291fd54db988ca5e79939ac191f | |
parent | d9dde0d5e8eedde5b82c441700babc4f2a394ce4 (diff) | |
download | qt-creator-4c76e40617d22d3578bb95973b54b0e266591e7c.tar.gz |
SSH: Derive SshRemoteProcess from QIODevice.
Now it looks even more like QProcess. Things like process channels are
still missing.
Change-Id: I3f30cd00ed4a054d02e83add9a6f4162b48f8345
Reviewed-by: Christian Kandeler <christian.kandeler@nokia.com>
-rw-r--r-- | src/libs/utils/ssh/sftpchannel.cpp | 4 | ||||
-rw-r--r-- | src/libs/utils/ssh/sftpchannel_p.h | 2 | ||||
-rw-r--r-- | src/libs/utils/ssh/sshchannel.cpp | 7 | ||||
-rw-r--r-- | src/libs/utils/ssh/sshchannel_p.h | 6 | ||||
-rw-r--r-- | src/libs/utils/ssh/sshremoteprocess.cpp | 103 | ||||
-rw-r--r-- | src/libs/utils/ssh/sshremoteprocess.h | 20 | ||||
-rw-r--r-- | src/libs/utils/ssh/sshremoteprocess_p.h | 7 | ||||
-rw-r--r-- | src/plugins/debugger/gdb/remotegdbprocess.cpp | 2 | ||||
-rw-r--r-- | src/plugins/debugger/lldb/lldbenginehost.cpp | 4 | ||||
-rw-r--r-- | src/plugins/madde/maddedevicetester.cpp | 2 | ||||
-rw-r--r-- | src/plugins/madde/maemopublisherfremantlefree.cpp | 6 | ||||
-rw-r--r-- | src/plugins/madde/maemoremotemounter.cpp | 4 | ||||
-rw-r--r-- | src/plugins/remotelinux/linuxdevicetester.cpp | 2 | ||||
-rw-r--r-- | src/plugins/remotelinux/remotelinuxcustomcommanddeployservice.cpp | 2 | ||||
-rw-r--r-- | tests/manual/ssh/remoteprocess/remoteprocesstest.cpp | 74 | ||||
-rw-r--r-- | tests/manual/ssh/remoteprocess/remoteprocesstest.h | 15 | ||||
-rw-r--r-- | tests/manual/ssh/shell/shell.cpp | 2 |
17 files changed, 171 insertions, 91 deletions
diff --git a/src/libs/utils/ssh/sftpchannel.cpp b/src/libs/utils/ssh/sftpchannel.cpp index c17ce21d19..79e1f3f2ef 100644 --- a/src/libs/utils/ssh/sftpchannel.cpp +++ b/src/libs/utils/ssh/sftpchannel.cpp @@ -821,13 +821,13 @@ void SftpChannelPrivate::handleOpenSuccessInternal() m_sftpState = SubsystemRequested; } -void SftpChannelPrivate::handleOpenFailureInternal() +void SftpChannelPrivate::handleOpenFailureInternal(const QString &reason) { if (channelState() != SessionRequested) { throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR, "Unexpected SSH_MSG_CHANNEL_OPEN_FAILURE packet."); } - emit initializationFailed(tr("Server could not start session.")); + emit initializationFailed(tr("Server could not start session: %1").arg(reason)); } void SftpChannelPrivate::sendReadRequest(const SftpDownload::Ptr &job, diff --git a/src/libs/utils/ssh/sftpchannel_p.h b/src/libs/utils/ssh/sftpchannel_p.h index 241cbb77a7..e2efd89afd 100644 --- a/src/libs/utils/ssh/sftpchannel_p.h +++ b/src/libs/utils/ssh/sftpchannel_p.h @@ -74,7 +74,7 @@ private: SftpJobId createJob(const AbstractSftpOperation::Ptr &job); virtual void handleOpenSuccessInternal(); - virtual void handleOpenFailureInternal(); + virtual void handleOpenFailureInternal(const QString &reason); virtual void handleChannelDataInternal(const QByteArray &data); virtual void handleChannelExtendedDataInternal(quint32 type, const QByteArray &data); diff --git a/src/libs/utils/ssh/sshchannel.cpp b/src/libs/utils/ssh/sshchannel.cpp index b6965da5b1..4fa68dc89e 100644 --- a/src/libs/utils/ssh/sshchannel.cpp +++ b/src/libs/utils/ssh/sshchannel.cpp @@ -84,7 +84,7 @@ void AbstractSshChannel::requestSessionStart() setChannelState(SessionRequested); m_timeoutTimer->start(ReplyTimeout); } catch (Botan::Exception &e) { - m_errorString = QString::fromAscii(e.what()); + qDebug("Botan error: %s", e.what()); closeChannel(); } } @@ -95,7 +95,7 @@ void AbstractSshChannel::sendData(const QByteArray &data) m_sendBuffer += data; flushSendBuffer(); } catch (Botan::Exception &e) { - m_errorString = QString::fromAscii(e.what()); + qDebug("Botan error: %s", e.what()); closeChannel(); } } @@ -163,8 +163,7 @@ void AbstractSshChannel::handleOpenFailure(const QString &reason) #ifdef CREATOR_SSH_DEBUG qDebug("Channel open request failed for channel %u", m_localChannel); #endif - m_errorString = reason; - handleOpenFailureInternal(); + handleOpenFailureInternal(reason); } void AbstractSshChannel::handleChannelEof() diff --git a/src/libs/utils/ssh/sshchannel_p.h b/src/libs/utils/ssh/sshchannel_p.h index 201b77b970..c6c81f5abf 100644 --- a/src/libs/utils/ssh/sshchannel_p.h +++ b/src/libs/utils/ssh/sshchannel_p.h @@ -58,9 +58,6 @@ public: ChannelState channelState() const { return m_state; } void setChannelState(ChannelState state); - void setError(const QString &error) { m_errorString = error; } - QString errorString() const { return m_errorString; } - quint32 localChannelId() const { return m_localChannel; } quint32 remoteChannel() const { return m_remoteChannel; } @@ -101,7 +98,7 @@ protected: private: virtual void handleOpenSuccessInternal() = 0; - virtual void handleOpenFailureInternal() = 0; + virtual void handleOpenFailureInternal(const QString &reason) = 0; virtual void handleChannelDataInternal(const QByteArray &data) = 0; virtual void handleChannelExtendedDataInternal(quint32 type, const QByteArray &data) = 0; @@ -119,7 +116,6 @@ private: quint32 m_remoteMaxPacketSize; ChannelState m_state; QByteArray m_sendBuffer; - QString m_errorString; }; } // namespace Internal diff --git a/src/libs/utils/ssh/sshremoteprocess.cpp b/src/libs/utils/ssh/sshremoteprocess.cpp index 90ab74735f..52068ba869 100644 --- a/src/libs/utils/ssh/sshremoteprocess.cpp +++ b/src/libs/utils/ssh/sshremoteprocess.cpp @@ -42,6 +42,8 @@ #include <QtCore/QTimer> +#include <cstring> + /*! \class Utils::SshRemoteProcess @@ -49,17 +51,10 @@ Objects are created via SshConnection::createRemoteProcess. The process is started via the start() member function. - A closeChannel() function is provided, but rarely useful, because - - \list - \i a) when the process ends, the channel is closed automatically, and - \i b) closing a channel will not necessarily kill the remote process. - \endlist - - Therefore, the only sensible use case for calling closeChannel() is to - get rid of an SshRemoteProces object before the process is actually started. If the process needs a pseudo terminal, you can request one via requestTerminal() before calling start(). + Note that this class does not support QIODevice's waitFor*() functions, i.e. it has + no synchronous mode. */ namespace Utils { @@ -99,12 +94,63 @@ SshRemoteProcess::~SshRemoteProcess() delete d; } +bool SshRemoteProcess::atEnd() const +{ + return QIODevice::atEnd() && d->m_stdout.isEmpty(); +} + +qint64 SshRemoteProcess::bytesAvailable() const +{ + return QIODevice::bytesAvailable() + d->m_stdout.count(); +} + +bool SshRemoteProcess::canReadLine() const +{ + return QIODevice::canReadLine() || d->m_stdout.contains('\n'); // TODO: Not cross-platform? +} + +QByteArray SshRemoteProcess::readAllStandardOutput() +{ + return readAll(); +} + +QByteArray SshRemoteProcess::readAllStandardError() +{ + const QByteArray data = d->m_stderr; + d->m_stderr.clear(); + return data; +} + +void SshRemoteProcess::close() +{ + d->closeChannel(); + QIODevice::close(); +} + +qint64 SshRemoteProcess::readData(char *data, qint64 maxlen) +{ + const qint64 bytesRead = qMin(qint64(d->m_stdout.count()), maxlen); + memcpy(data, d->m_stdout.constData(), bytesRead); + d->m_stdout.remove(0, bytesRead); + return bytesRead; +} + +qint64 SshRemoteProcess::writeData(const char *data, qint64 len) +{ + if (isRunning()) { + d->sendData(QByteArray(data, len)); + return len; + } + return 0; +} + void SshRemoteProcess::init() { connect(d, SIGNAL(started()), this, SIGNAL(started()), Qt::QueuedConnection); connect(d, SIGNAL(readyReadStandardOutput()), this, SIGNAL(readyReadStandardOutput()), Qt::QueuedConnection); + connect(d, SIGNAL(readyReadStandardOutput()), this, SIGNAL(readyRead()), Qt::QueuedConnection); connect(d, SIGNAL(readyReadStandardError()), this, SIGNAL(readyReadStandardError()), Qt::QueuedConnection); connect(d, SIGNAL(closed(int)), this, SIGNAL(closed(int)), Qt::QueuedConnection); @@ -129,6 +175,7 @@ void SshRemoteProcess::start() #ifdef CREATOR_SSH_DEBUG qDebug("process start requested, channel id = %u", d->localChannelId()); #endif + QIODevice::open(QIODevice::ReadWrite); d->requestSessionStart(); } } @@ -140,36 +187,19 @@ void SshRemoteProcess::sendSignal(const QByteArray &signal) d->m_sendFacility.sendChannelSignalPacket(d->remoteChannel(), signal); } catch (Botan::Exception &e) { - d->setError(QString::fromAscii(e.what())); + setErrorString(QString::fromAscii(e.what())); d->closeChannel(); } } -void SshRemoteProcess::closeChannel() -{ - d->closeChannel(); -} - -void SshRemoteProcess::sendInput(const QByteArray &data) -{ - if (isRunning()) - d->sendData(data); -} - bool SshRemoteProcess::isRunning() const { return d->m_procState == Internal::SshRemoteProcessPrivate::Running; } -QString SshRemoteProcess::errorString() const { return d->errorString(); } - int SshRemoteProcess::exitCode() const { return d->m_exitCode; } - QByteArray SshRemoteProcess::exitSignal() const { return d->m_signal; } -QByteArray SshRemoteProcess::readAllStandardOutput() { return d->readAllStandardOutput(); } -QByteArray SshRemoteProcess::readAllStandardError() { return d->readAllStandardError(); } - namespace Internal { SshRemoteProcessPrivate::SshRemoteProcessPrivate(const QByteArray &command, @@ -214,20 +244,6 @@ void SshRemoteProcessPrivate::setProcState(ProcessState newState) } } -QByteArray SshRemoteProcessPrivate::readAllStandardOutput() -{ - const QByteArray data = m_stdout; - m_stdout.clear(); - return data; -} - -QByteArray SshRemoteProcessPrivate::readAllStandardError() -{ - const QByteArray data = m_stderr; - m_stderr.clear(); - return data; -} - void SshRemoteProcessPrivate::closeHook() { if (m_wasRunning) { @@ -256,9 +272,10 @@ void SshRemoteProcessPrivate::handleOpenSuccessInternal() m_timeoutTimer->start(ReplyTimeout); } -void SshRemoteProcessPrivate::handleOpenFailureInternal() +void SshRemoteProcessPrivate::handleOpenFailureInternal(const QString &reason) { setProcState(StartFailed); + m_proc->setErrorString(reason); } void SshRemoteProcessPrivate::handleChannelSuccess() @@ -313,9 +330,9 @@ void SshRemoteProcessPrivate::handleExitSignal(const SshChannelExitSignal &signa #ifdef CREATOR_SSH_DEBUG qDebug("Exit due to signal %s", signal.signal.data()); #endif - setError(signal.error); m_signal = signal.signal; m_procState = Exited; + m_proc->setErrorString(tr("Process killed by signal")); } } // namespace Internal diff --git a/src/libs/utils/ssh/sshremoteprocess.h b/src/libs/utils/ssh/sshremoteprocess.h index 59f61385c2..fcd3f0edd5 100644 --- a/src/libs/utils/ssh/sshremoteprocess.h +++ b/src/libs/utils/ssh/sshremoteprocess.h @@ -35,7 +35,7 @@ #include <utils/utils_global.h> -#include <QtCore/QObject> +#include <QtCore/QProcess> #include <QtCore/QSharedPointer> QT_BEGIN_NAMESPACE @@ -50,7 +50,8 @@ class SshRemoteProcessPrivate; class SshSendFacility; } // namespace Internal -class QTCREATOR_UTILS_EXPORT SshRemoteProcess : public QObject +// TODO: ProcessChannel +class QTCREATOR_UTILS_EXPORT SshRemoteProcess : public QIODevice { Q_OBJECT @@ -77,6 +78,13 @@ public: ~SshRemoteProcess(); + // QIODevice stuff + bool atEnd() const; + qint64 bytesAvailable() const; + bool canReadLine() const; + void close(); + bool isSequential() const { return true; } + /* * Note that this is of limited value in practice, because servers are * usually configured to ignore such requests for security reasons. @@ -85,10 +93,8 @@ public: void requestTerminal(const SshPseudoTerminal &terminal); void start(); - void closeChannel(); bool isRunning() const; - QString errorString() const; int exitCode() const; QByteArray exitSignal() const; @@ -99,8 +105,6 @@ public: void sendSignal(const QByteArray &signal); void kill() { sendSignal(KillSignal); } - void sendInput(const QByteArray &data); // Should usually have a trailing newline. - signals: void started(); @@ -118,6 +122,10 @@ private: Internal::SshSendFacility &sendFacility); SshRemoteProcess(quint32 channelId, Internal::SshSendFacility &sendFacility); + // QIODevice stuff + qint64 readData(char *data, qint64 maxlen); + qint64 writeData(const char *data, qint64 len); + void init(); Internal::SshRemoteProcessPrivate *d; diff --git a/src/libs/utils/ssh/sshremoteprocess_p.h b/src/libs/utils/ssh/sshremoteprocess_p.h index da47927f3a..32564ef9cb 100644 --- a/src/libs/utils/ssh/sshremoteprocess_p.h +++ b/src/libs/utils/ssh/sshremoteprocess_p.h @@ -52,7 +52,7 @@ class SshRemoteProcessPrivate : public AbstractSshChannel friend class Utils::SshRemoteProcess; public: enum ProcessState { - NotYetStarted, ExecRequested, StartFailed,Running, Exited + NotYetStarted, ExecRequested, StartFailed, Running, Exited }; virtual void handleChannelSuccess(); @@ -60,9 +60,6 @@ public: virtual void closeHook(); - QByteArray readAllStandardOutput(); - QByteArray readAllStandardError(); - signals: void started(); void readyReadStandardOutput(); @@ -76,7 +73,7 @@ private: SshRemoteProcess *proc); virtual void handleOpenSuccessInternal(); - virtual void handleOpenFailureInternal(); + virtual void handleOpenFailureInternal(const QString &reason); virtual void handleChannelDataInternal(const QByteArray &data); virtual void handleChannelExtendedDataInternal(quint32 type, const QByteArray &data); diff --git a/src/plugins/debugger/gdb/remotegdbprocess.cpp b/src/plugins/debugger/gdb/remotegdbprocess.cpp index 80a1dd5837..e9bb37aefe 100644 --- a/src/plugins/debugger/gdb/remotegdbprocess.cpp +++ b/src/plugins/debugger/gdb/remotegdbprocess.cpp @@ -341,7 +341,7 @@ void RemoteGdbProcess::sendInput(const QByteArray &data) if (!isdigit(data.at(pos))) break; m_lastSeqNr = data.left(pos); - m_gdbProc->sendInput(data); + m_gdbProc->write(data); } void RemoteGdbProcess::handleAppOutput() diff --git a/src/plugins/debugger/lldb/lldbenginehost.cpp b/src/plugins/debugger/lldb/lldbenginehost.cpp index 70189a5139..d5115bbd6a 100644 --- a/src/plugins/debugger/lldb/lldbenginehost.cpp +++ b/src/plugins/debugger/lldb/lldbenginehost.cpp @@ -95,7 +95,7 @@ qint64 SshIODevice::writeData (const char * data, qint64 maxSize) startupbuffer += QByteArray::fromRawData(data, maxSize); return maxSize; } - proc->sendInput(QByteArray::fromRawData(data, maxSize)); + proc->write(data, maxSize); return maxSize; } qint64 SshIODevice::readData (char * data, qint64 maxSize) @@ -128,7 +128,7 @@ qint64 SshIODevice::readData (char * data, qint64 maxSize) void SshIODevice::processStarted() { proc = runner->process(); - proc->sendInput(startupbuffer); + proc->write(startupbuffer); } void SshIODevice::outputAvailable(const QByteArray &output) diff --git a/src/plugins/madde/maddedevicetester.cpp b/src/plugins/madde/maddedevicetester.cpp index a275971f4e..80090f07d6 100644 --- a/src/plugins/madde/maddedevicetester.cpp +++ b/src/plugins/madde/maddedevicetester.cpp @@ -89,7 +89,7 @@ void MaddeDeviceTester::stopTest() case QtTest: case MadDeveloperTest: case QmlToolingTest: - m_processRunner->process()->closeChannel(); + m_processRunner->process()->close(); break; } diff --git a/src/plugins/madde/maemopublisherfremantlefree.cpp b/src/plugins/madde/maemopublisherfremantlefree.cpp index aa85f8138b..e0cf2f7043 100644 --- a/src/plugins/madde/maemopublisherfremantlefree.cpp +++ b/src/plugins/madde/maemopublisherfremantlefree.cpp @@ -447,7 +447,7 @@ void MaemoPublisherFremantleFree::prepareToSendFile() emit progressReport(tr("Uploading file %1 ...") .arg(QDir::toNativeSeparators(nextFilePath))); QFileInfo info(nextFilePath); - m_uploader->process()->sendInput("C0644 " + QByteArray::number(info.size()) + m_uploader->process()->write("C0644 " + QByteArray::number(info.size()) + ' ' + info.fileName().toUtf8() + '\n'); } @@ -473,13 +473,13 @@ void MaemoPublisherFremantleFree::sendFile() tr("Upload failed.")); return; } - m_uploader->process()->sendInput(data); + m_uploader->process()->write(data); bytesToSend -= data.size(); QCoreApplication::processEvents(); if (m_state == Inactive) return; } - m_uploader->process()->sendInput(QByteArray(1, '\0')); + m_uploader->process()->write(QByteArray(1, '\0')); } void MaemoPublisherFremantleFree::handleScpStdOut(const QByteArray &output) diff --git a/src/plugins/madde/maemoremotemounter.cpp b/src/plugins/madde/maemoremotemounter.cpp index a151feaf3d..6144036243 100644 --- a/src/plugins/madde/maemoremotemounter.cpp +++ b/src/plugins/madde/maemoremotemounter.cpp @@ -380,11 +380,11 @@ void MaemoRemoteMounter::setState(State newState) m_utfsServerTimer->stop(); if (m_mountProcess) { disconnect(m_mountProcess.data(), 0, this, 0); - m_mountProcess->closeChannel(); + m_mountProcess->close(); } if (m_unmountProcess) { disconnect(m_unmountProcess.data(), 0, this, 0); - m_unmountProcess->closeChannel(); + m_unmountProcess->close(); } } m_state = newState; diff --git a/src/plugins/remotelinux/linuxdevicetester.cpp b/src/plugins/remotelinux/linuxdevicetester.cpp index 8c9e1cd2b9..cd9c465174 100644 --- a/src/plugins/remotelinux/linuxdevicetester.cpp +++ b/src/plugins/remotelinux/linuxdevicetester.cpp @@ -106,7 +106,7 @@ void GenericLinuxDeviceTester::stopTest() d->portsGatherer.stop(); break; case RunningUname: - d->process->closeChannel(); + d->process->close(); break; case Inactive: break; diff --git a/src/plugins/remotelinux/remotelinuxcustomcommanddeployservice.cpp b/src/plugins/remotelinux/remotelinuxcustomcommanddeployservice.cpp index 9f393b8924..d489d55030 100644 --- a/src/plugins/remotelinux/remotelinuxcustomcommanddeployservice.cpp +++ b/src/plugins/remotelinux/remotelinuxcustomcommanddeployservice.cpp @@ -115,7 +115,7 @@ void RemoteLinuxCustomCommandDeployService::stopDeployment() QTC_ASSERT(d->state == Running, return); disconnect(d->runner, 0, this, 0); - d->runner->process()->closeChannel(); + d->runner->process()->close(); d->state = Inactive; handleDeploymentDone(); } diff --git a/tests/manual/ssh/remoteprocess/remoteprocesstest.cpp b/tests/manual/ssh/remoteprocess/remoteprocesstest.cpp index d4a52340c7..dd8cfafdef 100644 --- a/tests/manual/ssh/remoteprocess/remoteprocesstest.cpp +++ b/tests/manual/ssh/remoteprocess/remoteprocesstest.cpp @@ -35,6 +35,7 @@ #include <utils/ssh/sshpseudoterminal.h> #include <QtCore/QCoreApplication> +#include <QtCore/QTextStream> #include <QtCore/QTimer> #include <iostream> @@ -75,9 +76,10 @@ void RemoteProcessTest::run() void RemoteProcessTest::handleConnectionError() { - std::cerr << "Error: Connection failure (" - << qPrintable(m_remoteRunner->lastConnectionErrorString()) << ")." - << std::endl; + const QString error = m_state == TestingIoDevice + ? m_sshConnection->errorString() : m_remoteRunner->lastConnectionErrorString(); + + std::cerr << "Error: Connection failure (" << qPrintable(error) << ")." << std::endl; qApp->quit(); } @@ -92,6 +94,11 @@ void RemoteProcessTest::handleProcessStarted() Utils::SshRemoteProcessRunner * const killer = new Utils::SshRemoteProcessRunner(this); killer->run("pkill -9 sleep", m_sshParams); + } else if (m_state == TestingIoDevice) { + connect(m_catProcess.data(), SIGNAL(readyRead()), SLOT(handleReadyRead())); + m_textStream = new QTextStream(m_catProcess.data()); + *m_textStream << testString(); + m_textStream->flush(); } } } @@ -198,10 +205,16 @@ void RemoteProcessTest::handleProcessClosed(int exitStatus) qApp->quit(); return; } - std::cout << "Ok.\nAll tests succeeded." << std::endl; - qApp->quit(); + std::cout << "Ok.\nTesting I/O device functionality... " << std::flush; + m_state = TestingIoDevice; + m_sshConnection = Utils::SshConnection::create(m_sshParams); + connect(m_sshConnection.data(), SIGNAL(connected()), SLOT(handleConnected())); + connect(m_sshConnection.data(), SIGNAL(error(Utils::SshError)), + SLOT(handleConnectionError())); + m_sshConnection->connectToHost(); break; } + case TestingIoDevice: case Inactive: Q_ASSERT(false); } @@ -216,16 +229,23 @@ void RemoteProcessTest::handleProcessClosed(int exitStatus) qApp->quit(); break; case SshRemoteProcess::KilledBySignal: - if (m_state != TestingCrash) { + switch (m_state) { + case TestingCrash: + std::cout << "Ok.\nTesting remote process with terminal... " << std::flush; + m_state = TestingTerminal; + m_started = false; + m_timeoutTimer->start(); + m_remoteRunner->runInTerminal("top -n 1", SshPseudoTerminal(), m_sshParams); + break; + case TestingIoDevice: + std::cout << "Ok.\nAll tests succeeded." << std::endl; + qApp->quit(); + break; + default: std::cerr << "Error: Unexpected crash." << std::endl; qApp->quit(); return; } - std::cout << "Ok.\nTesting remote process with terminal... " << std::flush; - m_state = TestingTerminal; - m_started = false; - m_timeoutTimer->start(); - m_remoteRunner->runInTerminal("top -n 1", SshPseudoTerminal(), m_sshParams); } } @@ -234,3 +254,35 @@ void RemoteProcessTest::handleTimeout() std::cerr << "Error: Timeout waiting for progress." << std::endl; qApp->quit(); } + +void RemoteProcessTest::handleConnected() +{ + Q_ASSERT(m_state == TestingIoDevice); + + m_catProcess = m_sshConnection->createRemoteProcess(QString::fromLocal8Bit("cat").toUtf8()); + connect(m_catProcess.data(), SIGNAL(started()), SLOT(handleProcessStarted())); + connect(m_catProcess.data(), SIGNAL(closed(int)), SLOT(handleProcessClosed(int))); + m_started = false; + m_timeoutTimer->start(); + m_catProcess->start(); +} + +QString RemoteProcessTest::testString() const +{ + return QLatin1String("x"); +} + +void RemoteProcessTest::handleReadyRead() +{ + Q_ASSERT(m_state == TestingIoDevice); + + const QString &data = QString::fromUtf8(m_catProcess->readAll()); + if (data != testString()) { + std::cerr << "Testing of QIODevice functionality failed: Expected '" + << qPrintable(testString()) << "', got '" << qPrintable(data) << "'." << std::endl; + qApp->exit(1); + } + + Utils::SshRemoteProcessRunner * const killer = new Utils::SshRemoteProcessRunner(this); + killer->run("pkill -9 cat", m_sshParams); +} diff --git a/tests/manual/ssh/remoteprocess/remoteprocesstest.h b/tests/manual/ssh/remoteprocess/remoteprocesstest.h index 46a20dd5b6..bc1a381999 100644 --- a/tests/manual/ssh/remoteprocess/remoteprocesstest.h +++ b/tests/manual/ssh/remoteprocess/remoteprocesstest.h @@ -35,9 +35,11 @@ #include <utils/ssh/sshremoteprocessrunner.h> -QT_FORWARD_DECLARE_CLASS(QTimer); #include <QtCore/QObject> +QT_FORWARD_DECLARE_CLASS(QTextStream) +QT_FORWARD_DECLARE_CLASS(QTimer) + class RemoteProcessTest : public QObject { Q_OBJECT @@ -53,13 +55,22 @@ private slots: void handleProcessStderr(const QByteArray &output); void handleProcessClosed(int exitStatus); void handleTimeout(); + void handleReadyRead(); + void handleConnected(); private: - enum State { Inactive, TestingSuccess, TestingFailure, TestingCrash, TestingTerminal }; + enum State { + Inactive, TestingSuccess, TestingFailure, TestingCrash, TestingTerminal, TestingIoDevice + }; + + QString testString() const; const Utils::SshConnectionParameters m_sshParams; QTimer * const m_timeoutTimer; + QTextStream *m_textStream; Utils::SshRemoteProcessRunner * const m_remoteRunner; + Utils::SshRemoteProcess::Ptr m_catProcess; + Utils::SshConnection::Ptr m_sshConnection; QByteArray m_remoteStdout; QByteArray m_remoteStderr; State m_state; diff --git a/tests/manual/ssh/shell/shell.cpp b/tests/manual/ssh/shell/shell.cpp index 96b59c9620..e363f9c52a 100644 --- a/tests/manual/ssh/shell/shell.cpp +++ b/tests/manual/ssh/shell/shell.cpp @@ -115,5 +115,5 @@ void Shell::handleChannelClosed(int exitStatus) void Shell::handleStdin() { - m_shell->sendInput(m_stdin->readLine()); + m_shell->write(m_stdin->readLine()); } |