diff options
Diffstat (limited to 'libqsystemtest/testdevicecontrol.cpp')
-rw-r--r-- | libqsystemtest/testdevicecontrol.cpp | 272 |
1 files changed, 272 insertions, 0 deletions
diff --git a/libqsystemtest/testdevicecontrol.cpp b/libqsystemtest/testdevicecontrol.cpp new file mode 100644 index 0000000..344846d --- /dev/null +++ b/libqsystemtest/testdevicecontrol.cpp @@ -0,0 +1,272 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of Qt Creator. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "testdevicecontrol.h" + +#include <coreplugin/ssh/sshremoteprocess.h> + +#include <QDebug> +#include <QRegExp> +#include <QTime> +#include <QApplication> +#include <QTimer> + +using namespace Core; + +namespace Qt4Test { + +TestDeviceControl::TestDeviceControl( Core::SshConnectionParameters &sshParam ) +{ + m_server = sshParam; + control_mode = Idle; +} + +TestDeviceControl::~TestDeviceControl() +{ +} + +bool TestDeviceControl::deviceConfiguration( QString &reply ) +{ + runBlockingCommand( ConfigCheck, "", 10000); + reply = reply_txt; + return reply_ok; +} + +bool TestDeviceControl::runCustomCommand( const QString &cmd, int timeout, QString &reply ) +{ + runBlockingCommand( CustomCommand, cmd, timeout); + reply = reply_txt; + return reply_ok; +} + +bool TestDeviceControl::runCustomBlockingCommand( const QString &cmd, int timeout, QString &reply ) +{ + runBlockingCommand( CustomBlockingCommand, cmd, timeout); + reply = reply_txt; + return reply_ok; +} + +void TestDeviceControl::runBlockingCommand( TestDeviceControlMode mode, const QString &cmd, int timeout) +{ + reply_txt = ""; + reply_ok = true; + m_cmd = cmd; + control_mode = mode; + if (initConnection()) + waitForCommandToFinish(timeout); + cleanupConnection(); +} + +bool TestDeviceControl::killApplication() +{ + if (m_testProcess) { + m_testProcess->kill(); + + QString reply; + if (!runCustomCommand( "killall testapp1", 1000, reply)) { + qDebug() << reply; + return false; + } + } + return true; +} + +void TestDeviceControl::waitForCommandToFinish(int timeout) +{ + QTime t; + t.start(); + while (t.elapsed() < 10000 && control_mode != Idle) { + qApp->processEvents(); + } + if (control_mode != Idle) { + reply_ok = false; + reply_txt += "Command timed out"; + } +} + +bool TestDeviceControl::initConnection() +{ + if (m_testProcess) { + reply_ok = false; + reply_txt = "Process existed already"; + return false; + } + + reply_ok = true; + m_deviceTestOutput = ""; + m_connection = SshConnection::create(); + connect(m_connection.data(), SIGNAL(connected()), + this, SLOT(handleConnected())); + connect(m_connection.data(), SIGNAL(error(SshError)), + this, SLOT(handleConnectionError())); + + m_connection->connectToHost(m_server); + + return true; +} + +void TestDeviceControl::handleConnected() +{ + if (!m_connection) { + reply_ok = false; + reply_txt += "Invalid connection\n"; + return; + } + + if (control_mode == ConfigCheck) { + QLatin1String sysInfoCmd("uname -rsm"); + QLatin1String qtInfoCmd("dpkg -l |grep libqt " + "|sed 's/[[:space:]][[:space:]]*/ /g' " + "|cut -d ' ' -f 2,3 |sed 's/~.*//g'"); + QString command(sysInfoCmd + " && " + qtInfoCmd); + m_testProcess = m_connection->createRemoteProcess(command.toUtf8()); + } else if (control_mode == CustomCommand || control_mode == CustomBlockingCommand) { + m_testProcess = m_connection->createRemoteProcess(m_cmd.toUtf8()); + } + + connect(m_testProcess.data(), SIGNAL(closed(int)), this, + SLOT(handleProcessFinished(int))); + connect(m_testProcess.data(), SIGNAL(outputAvailable(QByteArray)), this, + SLOT(processSshOutput(QByteArray))); + + m_testProcess->start(); + + if (control_mode == CustomCommand) + QTimer::singleShot(500,this,SLOT(cleanupConnection())); +} + +void TestDeviceControl::handleConnectionError() +{ + reply_ok = false; + + if (!m_connection) { + reply_txt += "Invalid connection\n"; + } else { + reply_txt += tr("Could not connect to host: %1:%2 %3 %4\n%5\n") + .arg(m_server.host) + .arg(m_server.port) + .arg(m_server.uname) + .arg(m_server.pwd) + .arg(m_connection->errorString()); + } + cleanupConnection(); +} + +void TestDeviceControl::handleProcessFinished(int exitStatus) +{ + Q_ASSERT(exitStatus == SshRemoteProcess::FailedToStart + || exitStatus == SshRemoteProcess::KilledBySignal + || exitStatus == SshRemoteProcess::ExitedNormally); + + if (!m_testProcess) { + reply_ok = false; + reply_txt += "Invalid process\n"; + return; + } + + if (exitStatus != SshRemoteProcess::ExitedNormally + || m_testProcess->exitCode() != 0) { + reply_ok = false; + reply_txt += tr("Remote process failed: %1\n") + .arg(m_testProcess->errorString()); + } else if (control_mode == ConfigCheck) { + const QString &output = parseOutput(); + if (!m_qtVersionOk) { + reply_txt += tr("Qt version mismatch! " + " Expected Qt on device: 4.6.2 or later.\n"); + } + reply_txt += output; + } else if (control_mode == CustomCommand || control_mode == CustomBlockingCommand) { + reply_txt += m_deviceTestOutput; + } + + cleanupConnection(); +} + +void TestDeviceControl::cleanupConnection() +{ + if (m_testProcess) + disconnect(m_testProcess.data(), 0, this, 0); + if (m_connection) + disconnect(m_connection.data(), 0, this, 0); + control_mode = Idle; + m_testProcess.clear(); + m_connection.clear(); +} + +void TestDeviceControl::processSshOutput(const QByteArray &output) +{ + m_deviceTestOutput.append(QString::fromUtf8(output)); +} + +QString TestDeviceControl::parseOutput() +{ + if (control_mode == ConfigCheck) { + m_qtVersionOk = false; + + QString output; + const QRegExp unamePattern(QLatin1String("Linux (\\S+)\\s(\\S+)")); + int index = unamePattern.indexIn(m_deviceTestOutput); + if (index == -1) { + output = tr("Device configuration test failed: Unexpected output:\n%1") + .arg(m_deviceTestOutput); + return output; + } + + output = tr("Hardware architecture: %1\n").arg(unamePattern.cap(2)); + output.append(tr("Kernel version: %1\n").arg(unamePattern.cap(1))); + const QRegExp dkpgPattern(QLatin1String("libqt\\S+ (\\d)\\.(\\d)\\.(\\d)")); + index = dkpgPattern.indexIn(m_deviceTestOutput); + if (index == -1) { + output.append(tr("No Qt packages installed.")); + return output; + } + + output.append(tr("List of installed Qt packages:") + QLatin1Char('\n')); + do { + output.append(QLatin1Char('\t') + dkpgPattern.cap(0) + + QLatin1Char('\n')); + index = dkpgPattern.indexIn(m_deviceTestOutput, index + 1); + if (!m_qtVersionOk && QT_VERSION_CHECK(dkpgPattern.cap(1).toInt(), + dkpgPattern.cap(2).toInt(), dkpgPattern.cap(3).toInt()) >= 0x040602) { + m_qtVersionOk = true; + } + } while (index != -1); + return output; + } + + return ""; +} + +} // namespace Qt4Test |