Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #10 from martyone/master
sandbox code/doc polishing, add ut_coreconfig, add ut_sandbox, fix debug mode, extend ut_urlresolver, add ut_deviceinfo, add ut_repomanager
  • Loading branch information
bwachter committed Apr 10, 2013
2 parents 0edb1e4 + 28fc0fd commit 01033c9
Show file tree
Hide file tree
Showing 51 changed files with 1,084 additions and 30 deletions.
50 changes: 41 additions & 9 deletions libssu/sandbox.cpp
Expand Up @@ -17,7 +17,6 @@
#include <QtCore/QSet>

#include "libssu/ssucoreconfig.h"
// TODO: rename to ssuconstants.h?
#include "constants.h"

class Sandbox::FileEngineHandler : public QAbstractFileEngineHandler {
Expand All @@ -37,20 +36,35 @@ class Sandbox::FileEngineHandler : public QAbstractFileEngineHandler {

/**
* @class Sandbox
* @brief Simple sandboxing with Qt file system abstraction.
*
* Redirects all file operations on system configuration files to files under
* sandbox directory. When constructed without arguments, the directory is get
* from @c SSU_TESTS_SANDBOX environment variable.
* Redirects all file operations on selected files to files under sandbox
* directory. The term <em>world files</em> is used to reffer files outside
* sandbox.
*
* Its effect is controlled by activate() and deactivate() calls. Only one
* Sandbox instance can be active at any time. Active sandbox is automatically
* deactivated upon destruction.
*
* When constructed without arguments, path to sandbox directory is get from
* @c SSU_TESTS_SANDBOX environment variable.
*
* @attention When constructed without arguments, it is activated automatically
* and failure to do so is reported with @c qFatal(), i.e., application will be
* abort()ed.
*
* When constructed with @a usage UseAsSkeleton, it will first make temporary
* copy of @a sandboxPath to work on and files in the original directory will
* stay untouched.
* stay untouched. Also see addWorldFiles().
*
* The argument @scopes allows to control if the sandbox will be used by this
* process, its children processes (@c SSU_TESTS_SANDBOX environment variable
* will be exported), or both.
*
* Internally it is based on QAbstractFileEngineHandler.
*
* @attention QDir lists entries presented in the world directory. The behavior
* changed with Qt 4.8.0 (Qt commit b9b55234a777c3b206332bafbe227e1355ca9186)
*/

Sandbox *Sandbox::s_activeInstance = 0;
Expand All @@ -71,15 +85,15 @@ Sandbox::Sandbox(const QString &sandboxPath, Usage usage, Scopes scopes)
}

Sandbox::~Sandbox(){
delete m_handler;
if (isActive()){
deactivate();
}

if (!m_tempDir.isEmpty() && QFileInfo(m_tempDir).exists()){
if (QProcess::execute("rm", QStringList() << "-rf" << m_tempDir) != 0){
qWarning("%s: Failed to remove temporary directory", Q_FUNC_INFO);
}
}

s_activeInstance = 0;
}

bool Sandbox::isActive() const{
Expand All @@ -105,6 +119,20 @@ bool Sandbox::activate(){
return true;
}

void Sandbox::deactivate(){
Q_ASSERT(isActive());

if (m_scopes & ThisProcess){
delete m_handler;
}

if (m_scopes & ChildProcesses){
unsetenv("SSU_TESTS_SANDBOX");
}

s_activeInstance = 0;
}

/**
* Copies selected files into sandbox. Existing files in sandbox are not overwriten.
*
Expand All @@ -119,7 +147,6 @@ bool Sandbox::addWorldFiles(const QString &directory, QDir::Filters filters,
Q_ASSERT(!directory.contains("/./") && !directory.endsWith("/.")
&& !directory.contains("/../") && !directory.endsWith("/..")
&& !directory.contains("//"));
Q_ASSERT_X(!(m_scopes & ChildProcesses), Q_FUNC_INFO, "Unimplemented case!");

if (!prepare()){
return false;
Expand Down Expand Up @@ -191,6 +218,11 @@ bool Sandbox::addWorldFiles(const QString &directory, QDir::Filters filters,
return true;
}

bool Sandbox::addWorldFile(const QString &file){
return addWorldFiles(QFileInfo(file).path(), QDir::NoFilter,
QStringList() << QFileInfo(file).fileName());
}

bool Sandbox::prepare(){
Q_ASSERT(m_defaultConstructed || !m_sandboxPath.isEmpty());

Expand Down
2 changes: 2 additions & 0 deletions libssu/sandbox_p.h
Expand Up @@ -33,10 +33,12 @@ class Sandbox {
~Sandbox();

bool activate();
void deactivate();
bool isActive() const;

bool addWorldFiles(const QString &directory, QDir::Filters filters = QDir::NoFilter,
const QStringList &filterNames = QStringList());
bool addWorldFile(const QString &file);

private:
bool prepare();
Expand Down
2 changes: 2 additions & 0 deletions libssu/ssu.h
Expand Up @@ -23,6 +23,8 @@ class QNetworkReply;
class Ssu: public QObject {
Q_OBJECT

friend class UrlResolverTest;

public:
Ssu();
/**
Expand Down
2 changes: 1 addition & 1 deletion libssu/ssuvariables.cpp
Expand Up @@ -89,7 +89,7 @@ QString SsuVariables::resolveVariable(QString variable, QHash<QString, QString>

// find the operator who's after your colon
QChar op;
if (variable.length() >= magic +1)
if (variable.length() > magic +1)
op = variable.at(magic + 1);

switch(op.toAscii()){
Expand Down
3 changes: 3 additions & 0 deletions tests/testapplication.pri
Expand Up @@ -3,6 +3,9 @@ include(tests_common.pri)

QT += testlib

test_data.path = $${TESTS_DATA_PATH}
INSTALLS += test_data

test_data_etc.path = $${TESTS_DATA_PATH}/configroot/etc/ssu
test_data_usr_share.path = $${TESTS_DATA_PATH}/configroot/usr/share/ssu
INSTALLS += test_data_etc test_data_usr_share
4 changes: 4 additions & 0 deletions tests/tests.pro
Expand Up @@ -3,7 +3,11 @@ CONFIG += ordered coverage debug
SUBDIRS = \
testutils \
testutils/sandboxhook.pro \
ut_coreconfig \
ut_deviceinfo \
ut_repomanager \
ut_rndssucli \
ut_sandbox \
ut_settings \
ut_ssuurlresolver \
ut_urlresolver \
Expand Down
20 changes: 20 additions & 0 deletions tests/tests.xml
Expand Up @@ -3,11 +3,31 @@
<!-- Test suite, name mandatory - the same as test package name -->
<suite name="sync-app-tests" domain="ssu">
<!-- At least one set per suite, name and description mandatory -->
<set name="coreconfig" description="Test to determine if code configuration file processing works properly" feature="coreconfig">
<case name="ut_coreconfig" type="Functional" description="Core config processing test" timeout="1000" subfeature="">
<step expected_result="0">/opt/tests/ssu/runtest.sh ut_coreconfig</step>
</case>
</set>
<set name="deviceinfo" description="Test to determine if device info can be retrieved properly" feature="deviceinfo">
<case name="ut_deviceinfo" type="Functional" description="Device info processing test" timeout="1000" subfeature="">
<step expected_result="0">/opt/tests/ssu/runtest.sh ut_deviceinfo</step>
</case>
</set>
<set name="repomanager" description="Test to determine if ssu repository management works properly" feature="repomanager">
<case name="ut_repomanager" type="Functional" description="SSU repo management test" timeout="1000" subfeature="">
<step expected_result="0">/opt/tests/ssu/runtest.sh ut_repomanager</step>
</case>
</set>
<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/runtest.sh ut_rndssucli</step>
</case>
</set>
<set name="sandbox" description="Test to determine if sandboxing works properly" feature="sandbox">
<case name="ut_sandbox" type="Functional" description="Sandboxing test" timeout="1000" subfeature="">
<step expected_result="0">/opt/tests/ssu/runtest.sh ut_sandbox</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/runtest.sh ut_settings</step>
Expand Down
6 changes: 4 additions & 2 deletions tests/testutils/process.cpp
Expand Up @@ -25,7 +25,7 @@ Process::Process() : m_expectFail(false), m_timedOut(false) {}

QString Process::execute(const QString &program, const QStringList &arguments,
bool expectedResult){
Q_ASSERT(processStatus() == NotRunning);
Q_ASSERT(m_process.state() == QProcess::NotRunning);
m_program = program;
m_arguments = arguments;
m_expectFail = expectedResult == ExpectFail;
Expand All @@ -42,7 +42,9 @@ bool Process::hasError(){
}

QString Process::fmtErrorMessage(){
Q_ASSERT(hasError());
if (!hasError()){
return QString();
}

QStringList reasons;
if (m_timedOut){
Expand Down
86 changes: 86 additions & 0 deletions tests/ut_coreconfig/coreconfigtest.cpp
@@ -0,0 +1,86 @@
/**
* @file coreconfigtest.cpp
* @copyright 2013 Jolla Ltd.
* @author Martin Kampas <martin.kampas@tieto.com>
* @date 2013
*/

#include "coreconfigtest.h"

#include <QtTest/QtTest>

#include "libssu/ssucoreconfig.h"

void CoreconfigTest::testCredentialsScope(){
QCOMPARE(SsuCoreConfig::instance()->credentialsScope("/*ignored*/", false), QString("example"));

}

void CoreconfigTest::testCredentials(){
QCOMPARE(SsuCoreConfig::instance()->credentials("example").first, QString("example_username"));
QCOMPARE(SsuCoreConfig::instance()->credentials("example").second, QString("example_password"));
}

void CoreconfigTest::testCredentialsUrl(){
QCOMPARE(SsuCoreConfig::instance()->credentialsUrl("example"), QString("http://creden.tia.ls/"));
}

void CoreconfigTest::testFlavour(){
QCOMPARE(SsuCoreConfig::instance()->flavour(), QString("testing"));
SsuCoreConfig::instance()->setFlavour("release");
QCOMPARE(SsuCoreConfig::instance()->flavour(), QString("release"));
}

void CoreconfigTest::testDeviceMode(){
SsuCoreConfig::instance()->remove("deviceMode");
QCOMPARE(SsuCoreConfig::instance()->deviceMode(), (int)Ssu::ReleaseMode);
SsuCoreConfig::instance()->setDeviceMode(Ssu::ReleaseMode, Ssu::Add);
QCOMPARE(SsuCoreConfig::instance()->deviceMode(), (int)Ssu::ReleaseMode);
SsuCoreConfig::instance()->setDeviceMode(Ssu::LenientMode, Ssu::Add);
QCOMPARE(SsuCoreConfig::instance()->deviceMode(), (int)Ssu::ReleaseMode | Ssu::LenientMode);
SsuCoreConfig::instance()->setDeviceMode(Ssu::ReleaseMode, Ssu::Remove);
QCOMPARE(SsuCoreConfig::instance()->deviceMode(), (int)Ssu::LenientMode);
SsuCoreConfig::instance()->setDeviceMode(Ssu::ReleaseMode, Ssu::Replace);
QCOMPARE(SsuCoreConfig::instance()->deviceMode(), (int)Ssu::ReleaseMode);
}

void CoreconfigTest::testDomain(){
QCOMPARE(SsuCoreConfig::instance()->domain(), QString(""));
SsuCoreConfig::instance()->setDomain("foo");
QCOMPARE(SsuCoreConfig::instance()->domain(), QString("foo"));
}

void CoreconfigTest::testRegistered(){
QCOMPARE(SsuCoreConfig::instance()->isRegistered(), false);
SsuCoreConfig::instance()->setValue("registered", true);
QCOMPARE(SsuCoreConfig::instance()->isRegistered(), false);
SsuCoreConfig::instance()->setValue("privateKey", "fooKey");
QCOMPARE(SsuCoreConfig::instance()->isRegistered(), false);
SsuCoreConfig::instance()->setValue("certificate", "fooCert");
QCOMPARE(SsuCoreConfig::instance()->isRegistered(), true);
}

void CoreconfigTest::testLastCredentialsUpdate(){
QCOMPARE(SsuCoreConfig::instance()->lastCredentialsUpdate(), QDateTime());
SsuCoreConfig::instance()->setValue("lastCredentialsUpdate",
QDateTime::fromString("2013-04-08", Qt::ISODate));
QCOMPARE(SsuCoreConfig::instance()->lastCredentialsUpdate(),
QDateTime::fromString("2013-04-08", Qt::ISODate));
}

void CoreconfigTest::testRelease(){
QCOMPARE(SsuCoreConfig::instance()->release(false), QString("latest"));
QCOMPARE(SsuCoreConfig::instance()->release(true), QString("next"));
SsuCoreConfig::instance()->setRelease("next", false);
QCOMPARE(SsuCoreConfig::instance()->release(false), QString("next"));
QCOMPARE(SsuCoreConfig::instance()->release(true), QString("next"));
SsuCoreConfig::instance()->setRelease("latest", true);
QCOMPARE(SsuCoreConfig::instance()->release(false), QString("next"));
QCOMPARE(SsuCoreConfig::instance()->release(true), QString("latest"));
}

void CoreconfigTest::testSslVerify(){
QCOMPARE(SsuCoreConfig::instance()->useSslVerify(), true);
SsuCoreConfig::instance()->setValue("ssl-verify", false);
QCOMPARE(SsuCoreConfig::instance()->useSslVerify(), false);
}
29 changes: 29 additions & 0 deletions tests/ut_coreconfig/coreconfigtest.h
@@ -0,0 +1,29 @@
/**
* @file coreconfigtest.h
* @copyright 2013 Jolla Ltd.
* @author Martin Kampas <martin.kampas@tieto.com>
* @date 2013
*/

#ifndef _CORECONFIGTEST_H
#define _CORECONFIGTEST_H

#include <QObject>

class CoreconfigTest: public QObject {
Q_OBJECT

private slots:
void testCredentialsScope();
void testCredentials();
void testCredentialsUrl();
void testFlavour();
void testDeviceMode();
void testDomain();
void testRegistered();
void testLastCredentialsUpdate();
void testRelease();
void testSslVerify();
};

#endif
26 changes: 26 additions & 0 deletions tests/ut_coreconfig/main.cpp
@@ -0,0 +1,26 @@
/**
* @file main.cpp
* @copyright 2012 Jolla Ltd.
* @author Martin Kampas <martin.kampas@tieto.com>
* @date 2012
*/

#include <QtTest/QtTest>

#include "libssu/sandbox_p.h"
#include "coreconfigtest.h"

int main(int argc, char **argv){
Sandbox sandbox(QString("%1/configroot").arg(TESTS_DATA_PATH),
Sandbox::UseAsSkeleton, Sandbox::ThisProcess);
if (!sandbox.activate()){
qFatal("Failed to activate sandbox");
}

CoreconfigTest coreconfigTest;

if (QTest::qExec(&coreconfigTest, argc, argv))
return 1;

return 0;
}
1 change: 1 addition & 0 deletions tests/ut_coreconfig/testdata/ssu-defaults.ini
@@ -0,0 +1 @@
# empty
18 changes: 18 additions & 0 deletions tests/ut_coreconfig/testdata/ssu.ini
@@ -0,0 +1,18 @@
[General]
initialized=true
flavour=testing
registered=false
rndRelease=next
release=latest
adaptation=
ca-certificate=
credentials-scope=example
credentials-url-example = http://creden.tia.ls/

[credentials-example]
username = example_username
password = example_password

[repository-urls]

[repository-url-variables]
16 changes: 16 additions & 0 deletions tests/ut_coreconfig/ut_coreconfig.pro
@@ -0,0 +1,16 @@
TARGET = ut_coreconfig
include(../testapplication.pri)
include(ut_coreconfig_dependencies.pri)

HEADERS = \
coreconfigtest.h \

SOURCES = \
main.cpp \
coreconfigtest.cpp \

test_data_etc.files = \
testdata/ssu.ini \

test_data_usr_share.files = \
testdata/ssu-defaults.ini \
2 changes: 2 additions & 0 deletions tests/ut_coreconfig/ut_coreconfig_dependencies.pri
@@ -0,0 +1,2 @@
include(../../libssu/libssu.pri)
include(../testutils/testutils.pri)

0 comments on commit 01033c9

Please sign in to comment.