diff --git a/tests/manual/ssh/errorhandling/errorhandling.pro b/tests/manual/ssh/errorhandling/errorhandling.pro new file mode 100644 index 0000000000000000000000000000000000000000..1161d4642da1b1d6e460403f9818986b1a4ee7b5 --- /dev/null +++ b/tests/manual/ssh/errorhandling/errorhandling.pro @@ -0,0 +1,4 @@ +include(../ssh.pri) + +TARGET=errorhandling +SOURCES=main.cpp diff --git a/tests/manual/ssh/errorhandling/main.cpp b/tests/manual/ssh/errorhandling/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..46dbac8c8567736546b96ee3883c1b2683426fa3 --- /dev/null +++ b/tests/manual/ssh/errorhandling/main.cpp @@ -0,0 +1,177 @@ +#include <coreplugin/ssh/sftpchannel.h> +#include <coreplugin/ssh/sshconnection.h> +#include <coreplugin/ssh/sshremoteprocess.h> + +#include <QtCore/QCoreApplication> +#include <QtCore/QList> +#include <QtCore/QObject> +#include <QtCore/QPair> +#include <QtCore/QTimer> + +using namespace Core; + +class Test : public QObject { + Q_OBJECT +public: + Test() + { + m_timeoutTimer.setSingleShot(true); + m_connection = SshConnection::create(); + if (m_connection->state() != SshConnection::Unconnected) { + qDebug("Error: Newly created SSH connection has state %d.", + m_connection->state()); + } + + if (m_connection->createRemoteProcess("")) + qDebug("Error: Unconnected SSH connection creates remote process."); + if (m_connection->createSftpChannel()) + qDebug("Error: Unconnected SSH connection creates SFTP channel."); + + SshConnectionParameters noHost(SshConnectionParameters::DefaultProxy); + noHost.host = QLatin1String("hgdfxgfhgxfhxgfchxgcf"); + noHost.port = 12345; + noHost.timeout = 10; + + SshConnectionParameters noUser(SshConnectionParameters::DefaultProxy);; + noUser.host = QLatin1String("localhost"); + noUser.port = 22; + noUser.timeout = 30; + noUser.authType = SshConnectionParameters::AuthByPwd; + noUser.uname = QLatin1String("dumdidumpuffpuff"); + noUser.uname = QLatin1String("whatever"); + + SshConnectionParameters wrongPwd(SshConnectionParameters::DefaultProxy);; + wrongPwd.host = QLatin1String("localhost"); + wrongPwd.port = 22; + wrongPwd.timeout = 30; + wrongPwd.authType = SshConnectionParameters::AuthByPwd; + wrongPwd.uname = QLatin1String("root"); + noUser.uname = QLatin1String("thiscantpossiblybeapasswordcanit"); + + SshConnectionParameters invalidKeyFile(SshConnectionParameters::DefaultProxy);; + invalidKeyFile.host = QLatin1String("localhost"); + invalidKeyFile.port = 22; + invalidKeyFile.timeout = 30; + invalidKeyFile.authType = SshConnectionParameters::AuthByKey; + invalidKeyFile.uname = QLatin1String("root"); + invalidKeyFile.privateKeyFile + = QLatin1String("somefilenamethatwedontexpecttocontainavalidkey"); + + // TODO: Create a valid key file and check for authentication error. + + m_testSet << TestItem("Behavior with non-existing host", + noHost, ErrorList() << SshSocketError); + m_testSet << TestItem("Behavior with non-existing user", noUser, + ErrorList() << SshSocketError << SshTimeoutError + << SshAuthenticationError); + m_testSet << TestItem("Behavior with wrong password", wrongPwd, + ErrorList() << SshSocketError << SshTimeoutError + << SshAuthenticationError); + m_testSet << TestItem("Behavior with invalid key file", invalidKeyFile, + ErrorList() << SshSocketError << SshTimeoutError + << SshKeyFileError); + + runNextTest(); + } + + ~Test(); + +private slots: + void handleConnected() + { + qDebug("Error: Received unexpected connected() signal."); + qApp->quit(); + } + + void handleDisconnected() + { + qDebug("Error: Received unexpected disconnected() signal."); + qApp->quit(); + } + + void handleDataAvailable(const QString &msg) + { + qDebug("Error: Received unexpected dataAvailable() signal. " + "Message was: '%s'.", qPrintable(msg)); + qApp->quit(); + } + + void handleError(SshError error) + { + if (m_testSet.isEmpty()) { + qDebug("Error: Received error %d, but no test was running.", error); + qApp->quit(); + } + + const TestItem testItem = m_testSet.takeFirst(); + if (testItem.allowedErrors.contains(error)) { + qDebug("Received error %d, as expected.", error); + if (m_testSet.isEmpty()) { + qDebug("All tests finished successfully."); + qApp->quit(); + } else { + runNextTest(); + } + } else { + qDebug("Received unexpected error %d.", error); + qApp->quit(); + } + } + + void handleTimeout() + { + if (m_testSet.isEmpty()) { + qDebug("Error: timeout, but no test was running."); + qApp->quit(); + } + const TestItem testItem = m_testSet.takeFirst(); + qDebug("Error: The following test timed out: %s", testItem.description); + } + +private: + void runNextTest() + { + if (m_connection) + disconnect(m_connection.data(), 0, this, 0); + m_connection = SshConnection::create(); + connect(m_connection.data(), SIGNAL(connected()), this, + SLOT(handleConnected())); + connect(m_connection.data(), SIGNAL(disconnected()), this, + SLOT(handleDisconnected())); + connect(m_connection.data(), SIGNAL(dataAvailable(QString)), this, + SLOT(handleDataAvailable(QString))); + connect(m_connection.data(), SIGNAL(error(SshError)), this, + SLOT(handleError(SshError))); + const TestItem &nextItem = m_testSet.first(); + m_timeoutTimer.stop(); + m_timeoutTimer.setInterval(qMax(10000, nextItem.params.timeout * 1000)); + qDebug("Testing: %s", nextItem.description); + m_connection->connectToHost(m_testSet.first().params); + } + + SshConnection::Ptr m_connection; + typedef QList<SshError> ErrorList; + struct TestItem { + TestItem(const char *d, const SshConnectionParameters &p, + const ErrorList &e) : description(d), params(p), allowedErrors(e) {} + + const char *description; + SshConnectionParameters params; + ErrorList allowedErrors; + }; + QList<TestItem> m_testSet; + QTimer m_timeoutTimer; +}; + +Test::~Test() {} + +int main(int argc, char *argv[]) +{ + QCoreApplication a(argc, argv); + Test t; + + return a.exec(); +} + + +#include "main.moc" diff --git a/tests/manual/ssh/sftp/argumentscollector.cpp b/tests/manual/ssh/sftp/argumentscollector.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4ed54ef320a13c8392ebb5630a469920514c2294 --- /dev/null +++ b/tests/manual/ssh/sftp/argumentscollector.cpp @@ -0,0 +1,138 @@ +#include "argumentscollector.h" + +#include <iostream> + +using namespace std; +using namespace Core; + +ArgumentsCollector::ArgumentsCollector(const QStringList &args) + : m_arguments(args) +{ +} + +Parameters ArgumentsCollector::collect(bool &success) const +{ + Parameters parameters; + try { + bool authTypeGiven = false; + bool portGiven = false; + bool timeoutGiven = false; + bool smallFileCountGiven = false; + bool bigFileSizeGiven = false; + bool proxySettingGiven = false; + int pos; + int port; + for (pos = 1; pos < m_arguments.count() - 1; ++pos) { + if (checkAndSetStringArg(pos, parameters.sshParams.host, "-h") + || checkAndSetStringArg(pos, parameters.sshParams.uname, "-u")) + continue; + if (checkAndSetIntArg(pos, port, portGiven, "-p") + || checkAndSetIntArg(pos, parameters.sshParams.timeout, timeoutGiven, "-t") + || checkAndSetIntArg(pos, parameters.smallFileCount, smallFileCountGiven, "-c") + || checkAndSetIntArg(pos, parameters.bigFileSize, bigFileSizeGiven, "-s")) + continue; + if (checkAndSetStringArg(pos, parameters.sshParams.pwd, "-pwd")) { + if (!parameters.sshParams.privateKeyFile.isEmpty()) + throw ArgumentErrorException(QLatin1String("-pwd and -k are mutually exclusive.")); + parameters.sshParams.authType + = SshConnectionParameters::AuthByPwd; + authTypeGiven = true; + continue; + } + if (checkAndSetStringArg(pos, parameters.sshParams.privateKeyFile, "-k")) { + if (!parameters.sshParams.pwd.isEmpty()) + throw ArgumentErrorException(QLatin1String("-pwd and -k are mutually exclusive.")); + parameters.sshParams.authType + = SshConnectionParameters::AuthByKey; + authTypeGiven = true; + continue; + } + if (!checkForNoProxy(pos, parameters.sshParams.proxyType, proxySettingGiven)) + throw ArgumentErrorException(QLatin1String("unknown option ") + m_arguments.at(pos)); + } + + Q_ASSERT(pos <= m_arguments.count()); + if (pos == m_arguments.count() - 1) { + if (!checkForNoProxy(pos, parameters.sshParams.proxyType, proxySettingGiven)) + throw ArgumentErrorException(QLatin1String("unknown option ") + m_arguments.at(pos)); + } + + if (!authTypeGiven) + throw ArgumentErrorException(QLatin1String("No authentication argument given.")); + if (parameters.sshParams.host.isEmpty()) + throw ArgumentErrorException(QLatin1String("No host given.")); + if (parameters.sshParams.uname.isEmpty()) + throw ArgumentErrorException(QLatin1String("No user name given.")); + + parameters.sshParams.port = portGiven ? port : 22; + if (!timeoutGiven) + parameters.sshParams.timeout = 30; + if (!smallFileCountGiven) + parameters.smallFileCount = 1000; + if (!bigFileSizeGiven) + parameters.bigFileSize = 1024; + success = true; + } catch (ArgumentErrorException &ex) { + cerr << "Error: " << qPrintable(ex.error) << endl; + printUsage(); + success = false; + } + return parameters; +} + +void ArgumentsCollector::printUsage() const +{ + cerr << "Usage: " << qPrintable(m_arguments.first()) + << " -h <host> -u <user> " + << "-pwd <password> | -k <private key file> [ -p <port> ] " + << "[ -t <timeout> ] [ -c <small file count> ] " + << "[ -s <big file size in MB> ] [ -no-proxy ]" << endl; +} + +bool ArgumentsCollector::checkAndSetStringArg(int &pos, QString &arg, const char *opt) const +{ + if (m_arguments.at(pos) == QLatin1String(opt)) { + if (!arg.isEmpty()) { + throw ArgumentErrorException(QLatin1String("option ") + opt + + QLatin1String(" was given twice.")); + } + arg = m_arguments.at(++pos); + if (arg.isEmpty() && QLatin1String(opt) != QLatin1String("-pwd")) + throw ArgumentErrorException(QLatin1String("empty argument not allowed here.")); + return true; + } + return false; +} + +bool ArgumentsCollector::checkAndSetIntArg(int &pos, int &val, + bool &alreadyGiven, const char *opt) const +{ + if (m_arguments.at(pos) == QLatin1String(opt)) { + if (alreadyGiven) { + throw ArgumentErrorException(QLatin1String("option ") + opt + + QLatin1String(" was given twice.")); + } + bool isNumber; + val = m_arguments.at(++pos).toInt(&isNumber); + if (!isNumber) { + throw ArgumentErrorException(QLatin1String("option ") + opt + + QLatin1String(" needs integer argument")); + } + alreadyGiven = true; + return true; + } + return false; +} + +bool ArgumentsCollector::checkForNoProxy(int &pos, + SshConnectionParameters::ProxyType &type, bool &alreadyGiven) const +{ + if (m_arguments.at(pos) == QLatin1String("-no-proxy")) { + if (alreadyGiven) + throw ArgumentErrorException(QLatin1String("proxy setting given twice.")); + type = SshConnectionParameters::NoProxy; + alreadyGiven = true; + return true; + } + return false; +} diff --git a/tests/manual/ssh/sftp/argumentscollector.h b/tests/manual/ssh/sftp/argumentscollector.h new file mode 100644 index 0000000000000000000000000000000000000000..9eb776714a318d8037a225899002c1f357c54c73 --- /dev/null +++ b/tests/manual/ssh/sftp/argumentscollector.h @@ -0,0 +1,31 @@ +#ifndef ARGUMENTSCOLLECTOR_H +#define ARGUMENTSCOLLECTOR_H + +#include "parameters.h" + +#include <QtCore/QStringList> + +class ArgumentsCollector +{ +public: + ArgumentsCollector(const QStringList &args); + Parameters collect(bool &success) const; +private: + struct ArgumentErrorException + { + ArgumentErrorException(const QString &error) : error(error) {} + const QString error; + }; + + void printUsage() const; + bool checkAndSetStringArg(int &pos, QString &arg, const char *opt) const; + bool checkAndSetIntArg(int &pos, int &val, bool &alreadyGiven, + const char *opt) const; + bool checkForNoProxy(int &pos, + Core::SshConnectionParameters::ProxyType &type, + bool &alreadyGiven) const; + + const QStringList m_arguments; +}; + +#endif // ARGUMENTSCOLLECTOR_H diff --git a/tests/manual/ssh/sftp/main.cpp b/tests/manual/ssh/sftp/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0b182917f1d41b82ef61f4e10aec15115ded5077 --- /dev/null +++ b/tests/manual/ssh/sftp/main.cpp @@ -0,0 +1,27 @@ +#include "argumentscollector.h" +#include "sftptest.h" + +#include <coreplugin/ssh/sftpchannel.h> +#include <coreplugin/ssh/sshconnection.h> + +#include <QtCore/QCoreApplication> +#include <QtCore/QObject> +#include <QtCore/QStringList> + +#include <cstdlib> +#include <iostream> + +using namespace Core; + +int main(int argc, char *argv[]) +{ + QCoreApplication app(argc, argv); + bool parseSuccess; + const Parameters parameters + = ArgumentsCollector(app.arguments()).collect(parseSuccess); + if (!parseSuccess) + return EXIT_FAILURE; + SftpTest sftpTest(parameters); + sftpTest.run(); + return app.exec(); +} diff --git a/tests/manual/ssh/sftp/parameters.h b/tests/manual/ssh/sftp/parameters.h new file mode 100644 index 0000000000000000000000000000000000000000..540103525ae1ce77620f171b7ee6c781ad746968 --- /dev/null +++ b/tests/manual/ssh/sftp/parameters.h @@ -0,0 +1,14 @@ +#ifndef PARAMETERS_H +#define PARAMETERS_H + +#include <coreplugin/ssh/sshconnection.h> + +struct Parameters { + Parameters() : sshParams(Core::SshConnectionParameters::DefaultProxy) {} + + Core::SshConnectionParameters sshParams; + int smallFileCount; + int bigFileSize; +}; + +#endif // PARAMETERS_H diff --git a/tests/manual/ssh/sftp/sftp.pro b/tests/manual/ssh/sftp/sftp.pro new file mode 100644 index 0000000000000000000000000000000000000000..eb5b7d8e3b82fcaacbdd3ab3b4a2f3f19b60e17d --- /dev/null +++ b/tests/manual/ssh/sftp/sftp.pro @@ -0,0 +1,6 @@ +include(../ssh.pri) + +TARGET=sftp +SOURCES=main.cpp sftptest.cpp argumentscollector.cpp +HEADERS=sftptest.h argumentscollector.h parameters.h + diff --git a/tests/manual/ssh/sftp/sftptest.cpp b/tests/manual/ssh/sftp/sftptest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..65f41262e4600d31210e2c1d07269cc6e97dc785 --- /dev/null +++ b/tests/manual/ssh/sftp/sftptest.cpp @@ -0,0 +1,20 @@ +#include "sftptest.h" + +SftpTest::SftpTest(const Parameters ¶ms) + : m_parameters(params), m_state(Inactive) +{ + +} + +void SftpTest::run() +{ +// connect to remote host +// create sftp connection +// create n 1KB files +// upload these files +// download these files +// compare the original to the downloaded files +// remove local files +// remove remote files +// then the same for a big N GB file +} diff --git a/tests/manual/ssh/sftp/sftptest.h b/tests/manual/ssh/sftp/sftptest.h new file mode 100644 index 0000000000000000000000000000000000000000..f9caf6d6abd8d70cfd8d393c5c7aad6f9021e9a9 --- /dev/null +++ b/tests/manual/ssh/sftp/sftptest.h @@ -0,0 +1,24 @@ +#ifndef SFTPTEST_H +#define SFTPTEST_H + +#include "parameters.h" + +#include <QtCore/QObject> + +class SftpTest : public QObject +{ + Q_OBJECT +public: + SftpTest(const Parameters ¶ms); + void run(); + +private: + enum State { Inactive, Connecting, UploadingSmall, DownloadingSmall, + RemovingSmall, UploadingBig, DownloadingBig, RemovingBig + }; + const Parameters m_parameters; + State m_state; +}; + + +#endif // SFTPTEST_H diff --git a/tests/manual/ssh/ssh.pri b/tests/manual/ssh/ssh.pri new file mode 100644 index 0000000000000000000000000000000000000000..cdbe6778b476133b966419ab30465391889191a3 --- /dev/null +++ b/tests/manual/ssh/ssh.pri @@ -0,0 +1,14 @@ +INCLUDEPATH += ../../../../src/plugins +CREATORLIBPATH = ../../../../lib/qtcreator +PLUGINPATH=$$CREATORLIBPATH/plugins/Nokia +LIBS *= -L$$PLUGINPATH -lCore +LIBS *= -L$$CREATORLIBPATH +include (../../../qtcreator.pri) +include (../../../src/plugins/coreplugin/coreplugin_dependencies.pri) +QT += core +QT -= gui +CONFIG += console +CONFIG -= app_bundle +TEMPLATE = app +DEPENDPATH+=. +INCLUDEPATH+=. \ No newline at end of file diff --git a/tests/manual/ssh/ssh.pro b/tests/manual/ssh/ssh.pro index 772ff2a39cb214e31c8c4f7c9ba8d3172b58c875..432f8f192b54a74555c291165b25c2fea75c7fac 100644 --- a/tests/manual/ssh/ssh.pro +++ b/tests/manual/ssh/ssh.pro @@ -4,23 +4,5 @@ # #------------------------------------------------- -INCLUDEPATH += ../../../src/plugins -CREATORLIBPATH = ../../../lib/qtcreator -PLUGINPATH=$$CREATORLIBPATH/plugins/Nokia -LIBS *= -L$$PLUGINPATH -lCore -LIBS *= -L$$CREATORLIBPATH -include (../../../qtcreator.pri) -include (../../../src/plugins/coreplugin/coreplugin_dependencies.pri) - -QT += core - -QT -= gui - -TARGET = ssh -CONFIG += console -CONFIG -= app_bundle - -TEMPLATE = app - - -SOURCES += main.cpp +TEMPLATE = subdirs +SUBDIRS = errorhandling sftp