Skip to content

Commit

Permalink
Extract some code into libtestutils
Browse files Browse the repository at this point in the history
1. Un-inline SandboxFileEngineHandler (originally it was all implemented in
   single header file to avoid the need for a real library to be linked)
2. Extract RndSsuCliTest::Process
3. Keep all the stuff inside tests/testutils
  • Loading branch information
martyone committed Apr 3, 2013
1 parent 6213f19 commit 8cfafdf
Show file tree
Hide file tree
Showing 18 changed files with 261 additions and 163 deletions.
5 changes: 4 additions & 1 deletion buildpath.pri
Expand Up @@ -16,6 +16,9 @@ UI_HEADERS_DIR = $$BUILD
UI_SOURCES_DIR = $$BUILD
RCC_DIR = $$BUILD

# This definitely needs to be refactorized somehow (the common module{.pro,.pri,_dependencies.pri}
# approach would do a good job here)
LIBS += -L$$PWD/build/libssu
LD_LIBRARY_PATH = $$PWD/build/libssu
LIBS += -L$$PWD/build/testutils
LD_LIBRARY_PATH = $$PWD/build/libssu:$$PWD/build/testutils
INCLUDEPATH += $$PWD/libssu
90 changes: 0 additions & 90 deletions tests/sandbox/sandboxfileenginehandler.h

This file was deleted.

2 changes: 1 addition & 1 deletion tests/tests.pri
@@ -1,4 +1,4 @@
DEPENDPATH *= $${PWD}/sandbox
DEPENDPATH *= $${PWD}/testutils

TESTS_PATH = /opt/tests/ssu
DEFINES += TESTS_PATH="'\"$${TESTS_PATH}\"'"
Expand Down
3 changes: 2 additions & 1 deletion tests/tests.pro
@@ -1,7 +1,8 @@
TEMPLATE = subdirs
CONFIG += qt ordered coverage debug
SUBDIRS = \
sandbox \
testutils \
testutils/sandboxhook.pro \
ut_rndssucli \
ut_settings \
ut_ssuurlresolver \
Expand Down
10 changes: 5 additions & 5 deletions tests/tests.xml
Expand Up @@ -5,27 +5,27 @@
<!-- At least one set per suite, name and description mandatory -->
<set name="rndssucli" description="Test to determine if ssu command line tool works properly" feature="rndssucli">
<case name="ut_rndssucli" type="Functional" description="SSU command line utility test" timeout="1000" subfeature="">
<step expected_result="0">/opt/tests/ssu/ut_rndssucli</step>
<step expected_result="0">/opt/tests/ssu/runtest.sh ut_rndssucli</step>
</case>
</set>
<set name="settings" description="Test to determine if configuration files processing works properly" feature="settings">
<case name="ut_settings" type="Functional" description="Settings processing test" timeout="1000" subfeature="">
<step expected_result="0">/opt/tests/ssu/ut_settings</step>
<step expected_result="0">/opt/tests/ssu/runtest.sh ut_settings</step>
</case>
</set>
<set name="ssuurlresolver" description="Test to determine if the UrlResolverPlugin works well with installed version of libzypp" feature="ssuurlresolver">
<case name="ut_ssuurlresolver" type="Functional" description="URL resolver plugin test" timeout="1000" subfeature="">
<step expected_result="0">/opt/tests/ssu/ut_ssuurlresolver</step>
<step expected_result="0">/opt/tests/ssu/runtest.sh ut_ssuurlresolver</step>
</case>
</set>
<set name="urlresolver" description="Test to determine if URL resolving works properly" feature="urlresolver">
<case name="ut_urlresolver" type="Functional" description="URL resolver tests" timeout="1000" subfeature="">
<step expected_result="0">/opt/tests/ssu/ut_urlresolver</step>
<step expected_result="0">/opt/tests/ssu/runtest.sh ut_urlresolver</step>
</case>
</set>
<set name="variables" description="Test to determine if variable resolving works properly" feature="variables">
<case name="ut_variables" type="Functional" description="Variable resolver tests" timeout="1000" subfeature="">
<step expected_result="0">/opt/tests/ssu/ut_variables</step>
<step expected_result="0">/opt/tests/ssu/runtest.sh ut_variables</step>
</case>
</set>
</suite>
Expand Down
68 changes: 68 additions & 0 deletions tests/testutils/process.cpp
@@ -0,0 +1,68 @@
/**
* @file process.cpp
* @copyright 2013 Jolla Ltd.
* @author Martin Kampas <martin.kampas@tieto.com>
* @date 2013
*/

#include "process.h"

/**
* @class Wraps QProcess for easier use within test code
*
* Example use:
*
* @code
* Process ssu;
* const QString output = ssu.execute("ssu", QStringList() << "mode");
* QVERIFY2(!ssu.hasError(), qPrintable(ssu.fmtErrorMessage()));
*
* QCOMPARE(output, "...");
* @endcode
*/

Process::Process() : m_expectFail(false), m_timedOut(false) {}

QString Process::execute(const QString &program, const QStringList &arguments,
bool expectedResult){
Q_ASSERT(processStatus() == NotRunning);
m_program = program;
m_arguments = arguments;
m_expectFail = expectedResult == ExpectFail;
m_process.start(program, arguments);
m_timedOut = !m_process.waitForFinished();
return m_process.readAllStandardOutput();
}

bool Process::hasError(){
return m_timedOut
|| m_process.error() != QProcess::UnknownError
|| m_process.exitStatus() != QProcess::NormalExit
|| (m_process.exitCode() != 0) != m_expectFail;
}

QString Process::fmtErrorMessage(){
Q_ASSERT(hasError());

QStringList reasons;
if (m_timedOut){
reasons.append("Timed out");
}else if (m_process.exitStatus() != QProcess::NormalExit){
reasons.append("Process crashed");
}else if (m_expectFail && (m_process.exitCode() == 0)){
reasons.append("Did not fail while it was expected to");
}else{
if (m_process.error() != QProcess::UnknownError){
reasons.append(m_process.errorString());
}
const QString errorOut = m_process.readAllStandardError();
if (!errorOut.isEmpty()){
reasons.append(errorOut);
}
}

return QString("Failed to execute `%1 %2`: %3")
.arg(m_program)
.arg(QStringList(m_arguments).replaceInStrings(QRegExp("^|$"), "\"").join(" "))
.arg(reasons.join(": "));
}
36 changes: 36 additions & 0 deletions tests/testutils/process.h
@@ -0,0 +1,36 @@
/**
* @file process.h
* @copyright 2013 Jolla Ltd.
* @author Martin Kampas <martin.kampas@tieto.com>
* @date 2013
*/

#ifndef _PROCESS_H
#define _PROCESS_H

#include <QtCore/QProcess>

class Process {
public:
enum ExpectedResult {
ExpectSuccess,
ExpectFail
};

public:
Process();

QString execute(const QString &program, const QStringList &arguments,
bool expectedResult = ExpectSuccess);
bool hasError();
QString fmtErrorMessage();

private:
QProcess m_process;
QString m_program;
QStringList m_arguments;
bool m_expectFail;
bool m_timedOut;
};

#endif
4 changes: 4 additions & 0 deletions tests/testutils/runtest.sh
@@ -0,0 +1,4 @@
#!/bin/sh

export LD_LIBRARY_PATH="`dirname "$0"`:${LD_LIBRARY_PATH}"
exec "`dirname "$0"`/$1"
88 changes: 88 additions & 0 deletions tests/testutils/sandboxfileenginehandler.cpp
@@ -0,0 +1,88 @@
/**
* @file sandboxfileenginehandler.cpp
* @copyright 2013 Jolla Ltd.
* @author Martin Kampas <martin.kampas@tieto.com>
* @date 2013
*/

#include "sandboxfileenginehandler.h"

#include <QtCore/QDir>
#include <QtCore/QFSFileEngine>
#include <QtCore/QFileInfo>
#include <QtCore/QProcessEnvironment>
#include <QtCore/QSet>

#include <ssucoreconfig.h>
#include "../../constants.h"

/**
* @class SandboxFileEngineHandler
*
* Redirects all file operations on system configuration files to files under
* directory specified by SSU_TESTS_SANDBOX environment variable.
*/

SandboxFileEngineHandler::SandboxFileEngineHandler() {}

QAbstractFileEngine *SandboxFileEngineHandler::create(const QString &fileName) const{
static bool enabled = false;
static bool firstCall = true;

if (!enabled && !firstCall){
return 0;
}

static QString sandboxPath =
QProcessEnvironment::systemEnvironment().value("SSU_TESTS_SANDBOX");

if (firstCall){
firstCall = false;

if (sandboxPath.isEmpty()){
return 0;
}

if (!QFileInfo(sandboxPath).exists()){
qFatal("%s: Invalid SSU_TESTS_SANDBOX value: No such file or directory",
qPrintable(sandboxPath));
}

if (!QFileInfo(sandboxPath).isDir()){
qFatal("%s: Invalid SSU_TESTS_SANDBOX value: Not a directory",
qPrintable(sandboxPath));
}

enabled = true;
}

if (!fileName.startsWith('/')){
return 0;
}

static QSet<QString> ssuConfigFiles = QSet<QString>()
<< SSU_CONFIGURATION
<< SSU_REPO_CONFIGURATION
<< SSU_DEFAULT_CONFIGURATION
<< SSU_BOARD_MAPPING_CONFIGURATION;

static QSet<QString> ssuConfigDirectories = QSet<QString>()
<< SSU_BOARD_MAPPING_CONFIGURATION_DIR;

if (!ssuConfigFiles.contains(fileName)){
bool match = false;
foreach (const QString &ssuConfigDirectory, ssuConfigDirectories){
if (fileName.startsWith(ssuConfigDirectory + '/')){
match = true;
break;
}
}
if (!match){
return 0;
}
}

const QString fileName_ = QDir(sandboxPath).absoluteFilePath(QString(fileName).remove(0, 1));

return new QFSFileEngine(fileName_);
}
19 changes: 19 additions & 0 deletions tests/testutils/sandboxfileenginehandler.h
@@ -0,0 +1,19 @@
/**
* @file sandboxfileenginehandler.h
* @copyright 2013 Jolla Ltd.
* @author Martin Kampas <martin.kampas@tieto.com>
* @date 2013
*/

#ifndef _SANDBOXINGFILEENGINEHANDLER_H
#define _SANDBOXINGFILEENGINEHANDLER_H

#include <QtCore/QAbstractFileEngineHandler>

class SandboxFileEngineHandler : public QAbstractFileEngineHandler {
public:
SandboxFileEngineHandler();
QAbstractFileEngine *create(const QString &fileName) const;
};

#endif
File renamed without changes.
2 changes: 2 additions & 0 deletions tests/sandbox/sandbox.pro → tests/testutils/sandboxhook.pro
Expand Up @@ -7,6 +7,8 @@ CONFIG += console qtestlib
QT -= gui
QT += network testlib

LIBS += -ltestutils

!include( ../tests.pri ) { error("Unable to find tests include") }

unix:target.path = $${PREFIX}/$$TESTS_PATH
Expand Down

0 comments on commit 8cfafdf

Please sign in to comment.