Commit c687b533 authored by Aard's avatar Aard

[ssu] Make it easier to run testcases in-tree, contributes to JB#31688

parent cb273412
......@@ -125,6 +125,13 @@ QString Sandbox::map(const QString &fileName)
QFileInfo(fileName).absoluteFilePath()));
}
QString Sandbox::map(const QString &pathName, const QString &fileName)
{
return effectiveRootDir().filePath(
QDir::root().relativeFilePath(
QFileInfo(pathName + fileName).absoluteFilePath()));
}
/**
* Copies selected files into sandbox. Existing files in sandbox are not overwriten.
*
......
......@@ -12,6 +12,12 @@
#include <QtCore/QSet>
#include <QtCore/QString>
// use either environment variable SSU_TESTS_DATA_PATH or compile time
// TESTS_DATA_PATH to locate test data
#define LOCATE_DATA_PATH (getenv("SSU_TESTS_DATA_PATH") ? \
getenv("SSU_TESTS_DATA_PATH") : \
TESTS_DATA_PATH)
class Sandbox {
public:
enum Usage {
......@@ -36,6 +42,7 @@ class Sandbox {
static QDir effectiveRootDir();
static QString map(const QString &fileName);
static QString map(const QString &pathName, const QString &fileName);
bool addWorldFiles(const QString &directory, QDir::Filters filters = QDir::NoFilter,
const QStringList &filterNames = QStringList(), bool recurse = true);
......
#!/bin/sh
#
# Simple script to run all tests either in-tree or after test RPM
# installation. Output will be nicely formatted if output formatter
# is available. All arguments to this script are passed to formatoutput.
prepareInTreeTestData(){
# this is a dirty hack to get most of the test data into a place
# usable for running tests without installation. Currently this
# causes some duplication
mkdir -p build/testdata
TESTDATA=`find tests -name testdata`
for t in $TESTDATA; do
test=`echo $t | sed 's,.*tests/,,' | sed 's,/.*,,'`
mkdir -p build/testdata/$test/
dirs=`find $t/* -prune -type f`
if [ -z "$dirs" ]; then
cp -a $t/* build/testdata/$test/
else
mkdir -p build/testdata/$test/configroot/usr/share/ssu/
mkdir -p build/testdata/$test/configroot/etc/ssu/
for ini in $t/*.ini; do
inifile=`echo $ini | sed 's,.*/,,'`
if [ $inifile = "ssu.ini" ]; then
cp $ini build/testdata/$test/configroot/etc/ssu/
elif [ $inifile = "board-mappings.ini" ]; then
mkdir -p build/testdata/$test/configroot/usr/share/ssu/board-mappings.d
cp $ini build/testdata/$test/configroot/usr/share/ssu/board-mappings.d/
else
cp $ini build/testdata/$test/configroot/usr/share/ssu/
fi
done
cp $t/* build/testdata/$test/configroot/
for key in $t/*.{key,crt}; do
cp $key build/testdata/$test/
done
fi
done
}
if [ -d "build" ]; then
BASE_DIR="`pwd`/build"
export LD_LIBRARY_PATH="$BASE_DIR/lib:${LD_LIBRARY_PATH}"
export SSU_SANDBOX_PATH="$BASE_DIR/lib/libsandboxhook.so"
prepareInTreeTestData
TESTS=`ls $BASE_DIR/bin/ut_*`
if [ -f "$BASE_DIR/bin/formatoutput" ]; then
FORMATOUTPUT="$BASE_DIR/bin/formatoutput"
fi
elif [ -d "/opt/tests/ssu" ]; then
BASE_DIR="/opt/tests/ssu"
export LD_LIBRARY_PATH="$BASE_DIR:${LD_LIBRARY_PATH}"
TESTS=`ls $BASE_DIR/ut_*`
if [ -f "$BASE_DIR/formatoutput" ]; then
FORMATOUTPUT="$BASE_DIR/formatoutput"
fi
else
echo "Neither ./build nor /opt/tests/ssu exist, exiting"
exit 1
fi
for test in $TESTS; do
if [ -d "./build/testdata/`basename $test`" ]; then
export SSU_TESTS_DATA_PATH="`pwd`/build/testdata/`basename $test`"
else
unset SSU_TESTS_DATA_PATH
fi
if [ -z "$FORMATOUTPUT" ]; then
$test | grep -v "^PASS"
else
$test | $FORMATOUTPUT $@
fi
done
TARGET = formatoutput
include(../testapplication.pri)
SOURCES = main.cpp
/**
* @file main.cpp
* @copyright 2015 Jolla Ltd.
* @author Bernd Wachter <bernd.wachter@jolla.com>
* @date 2015
*/
#include <QTextStream>
#include <QRegExp>
#include <getopt.h>
void usage(){
QTextStream out(stderr);
out << "Parse QTest output on STDIN and make it shiny" << endl
<< endl
<< "Usage: formatoutput [options]" << endl
<< endl
<< "\t--skip-pass <yes|no> \tSkip PASS lines [yes]" << endl
<< "\t--skip-debug <yes|no> \tSkip QDEBUG lines [yes]" << endl
<< "\t--skip-warn <yes|no> \tSkip QWARN lines [no]" << endl
<< "\t--skip-config <yes|no> \tSkip Config: lines [yes]" << endl
<< endl
<< "\t--help \tThis help text" << endl
<< endl;
}
bool isTrue(char *argument){
if (!strcasecmp(argument, "yes") ||
!strcasecmp(argument, "true") ||
!strcmp(argument, "1"))
return true;
else return false;
}
int main(int argc, char **argv){
QTextStream in(stdin);
QTextStream out(stdout);
int c, option_index;
static struct option long_options[] = {
{"skip-pass", required_argument, 0, 0 },
{"skip-debug", required_argument, 0, 0 },
{"skip-warn", required_argument, 0, 0 },
{"skip-config", required_argument, 0, 0 },
{"help", no_argument, 0, 0 }
};
struct {
bool skip_pass = true;
bool skip_debug = true;
bool skip_warn = false;
bool skip_config = true;
} options;
while ((c=getopt_long_only(argc, argv, "",
long_options, &option_index)) != EOF){
switch(c){
case 0:
if (!strcmp(long_options[option_index].name, "help")){
usage();
exit(0);
} else if (!strcmp(long_options[option_index].name, "skip-pass")){
options.skip_pass = isTrue(optarg);
} else if (!strcmp(long_options[option_index].name, "skip-debug")){
options.skip_debug = isTrue(optarg);
} else if (!strcmp(long_options[option_index].name, "skip-warn")){
options.skip_warn = isTrue(optarg);
} else if (!strcmp(long_options[option_index].name, "skip-config")){
options.skip_config = isTrue(optarg);
}
break;
default:
usage();
exit(-1);
}
}
while (!in.atEnd()){
QString line = in.readLine();
if (line.startsWith("PASS") && options.skip_pass) continue;
if (line.startsWith("QDEBUG") && options.skip_debug) continue;
if (line.startsWith("QWARN") && options.skip_warn) continue;
if (line.startsWith("Config:") && options.skip_config) continue;
line.replace(QRegExp("^(\\*{3}.*\\*{3})"), "\033[0;36m\\1\033[0;0m");
line.replace(QRegExp("^(QDEBUG .*)"), "\033[0;90m\\1\033[0;0m");
line.replace(QRegExp("^(QWARN .*)"), "\033[0;34m\\1\033[0;0m");
line.replace(QRegExp("^FAIL!"), "\033[0;31mFAIL!\033[0;0m");
line.replace(QRegExp("^PASS"), "\033[0;32mPASS\033[0;0m");
line.replace(QRegExp("^Totals: (\\d{1,} passed), (\\d{1,} failed), (\\d{1,} skipped)"),
"Totals: \033[0;32m\\1\033[0;0m, \033[0;31m\\2\033[0;0m, \033[0;33m\\3\033[0;0m");
out << line << endl;
}
}
......@@ -2,6 +2,7 @@ TEMPLATE = subdirs
CONFIG += ordered coverage debug
SUBDIRS = \
testutils \
formatoutput \
testutils/sandboxhook.pro \
ut_coreconfig \
ut_deviceinfo \
......@@ -16,4 +17,8 @@ SUBDIRS = \
include(tests_common.pri)
tests.files = tests.xml
tests.path = $$TESTS_PATH
INSTALLS += tests
scripts.files = ../run-tests
scripts.path = $$TESTS_PATH
INSTALLS += tests scripts
......@@ -11,7 +11,7 @@
#include "coreconfigtest.h"
int main(int argc, char **argv){
Sandbox sandbox(QString("%1/configroot").arg(TESTS_DATA_PATH),
Sandbox sandbox(QString("%1/configroot").arg(LOCATE_DATA_PATH),
Sandbox::UseAsSkeleton, Sandbox::ThisProcess);
if (!sandbox.activate()){
qFatal("Failed to activate sandbox");
......
......@@ -11,7 +11,7 @@
#include "deviceinfotest.h"
int main(int argc, char **argv){
Sandbox sandbox(QString("%1/configroot").arg(TESTS_DATA_PATH),
Sandbox sandbox(QString("%1/configroot").arg(LOCATE_DATA_PATH),
Sandbox::UseAsSkeleton, Sandbox::ThisProcess);
if (!sandbox.activate()){
qFatal("Failed to activate sandbox");
......
......@@ -11,7 +11,7 @@
#include "repomanagertest.h"
int main(int argc, char **argv){
Sandbox sandbox(QString("%1/configroot").arg(TESTS_DATA_PATH),
Sandbox sandbox(QString("%1/configroot").arg(LOCATE_DATA_PATH),
Sandbox::UseAsSkeleton, Sandbox::ThisProcess);
if (!sandbox.activate()){
qFatal("Failed to activate sandbox");
......
......@@ -15,55 +15,55 @@ void SandboxTest::test(){
const QDir::Filters noHidden = QDir::AllEntries | QDir::NoDotAndDotDot;
QCOMPARE(QDir(Sandbox::map(TESTS_DATA_PATH "/world")).entryList(noHidden, QDir::Name),
QCOMPARE(QDir(Sandbox::map(LOCATE_DATA_PATH, "/world")).entryList(noHidden, QDir::Name),
QStringList()
<< "world-and-sandbox"
<< "world-only"
<< "world-only-to-be-copied-into-sandbox");
QVERIFY(!QFileInfo(Sandbox::map(TESTS_DATA_PATH "/world/world-only")).isWritable());
QCOMPARE(readAll(Sandbox::map(TESTS_DATA_PATH "/world/world-only")).trimmed(),
QVERIFY(!QFileInfo(Sandbox::map(LOCATE_DATA_PATH, "/world/world-only")).isWritable());
QCOMPARE(readAll(Sandbox::map(LOCATE_DATA_PATH, "/world/world-only")).trimmed(),
QString("world/world-only"));
QVERIFY(!QFileInfo(Sandbox::map(TESTS_DATA_PATH "/world/world-and-sandbox")).isWritable());
QCOMPARE(readAll(Sandbox::map(TESTS_DATA_PATH "/world/world-and-sandbox")).trimmed(),
QVERIFY(!QFileInfo(Sandbox::map(LOCATE_DATA_PATH, "/world/world-and-sandbox")).isWritable());
QCOMPARE(readAll(Sandbox::map(LOCATE_DATA_PATH, "/world/world-and-sandbox")).trimmed(),
QString("world/world-and-sandbox"));
QVERIFY(!QFileInfo(Sandbox::map(TESTS_DATA_PATH "/world/world-only-to-be-copied-into-sandbox"))
QVERIFY(!QFileInfo(Sandbox::map(LOCATE_DATA_PATH, "/world/world-only-to-be-copied-into-sandbox"))
.isWritable());
QCOMPARE(readAll(Sandbox::map(TESTS_DATA_PATH "/world/world-only-to-be-copied-into-sandbox"))
QCOMPARE(readAll(Sandbox::map(LOCATE_DATA_PATH, "/world/world-only-to-be-copied-into-sandbox"))
.trimmed(), QString("world/world-only-to-be-copied-into-sandbox"));
QVERIFY(!QFileInfo(Sandbox::map(TESTS_DATA_PATH "/world/sandbox-only")).exists());
QVERIFY(!QFileInfo(Sandbox::map(LOCATE_DATA_PATH, "/world/sandbox-only")).exists());
Sandbox sandbox(Sandbox::map(TESTS_DATA_PATH "/sandbox"),
Sandbox sandbox(Sandbox::map(LOCATE_DATA_PATH, "/sandbox"),
Sandbox::UseAsSkeleton, Sandbox::ThisProcess | Sandbox::ChildProcesses);
sandbox.addWorldFiles(Sandbox::map(TESTS_DATA_PATH "/world"), QDir::AllEntries,
sandbox.addWorldFiles(Sandbox::map(LOCATE_DATA_PATH, "/world"), QDir::AllEntries,
QStringList() << "*-to-be-copied-into-sandbox");
QVERIFY(sandbox.activate());
QCOMPARE(QDir(Sandbox::map(TESTS_DATA_PATH "/world")).entryList(noHidden, QDir::Name),
QCOMPARE(QDir(Sandbox::map(LOCATE_DATA_PATH, "/world")).entryList(noHidden, QDir::Name),
QStringList()
<< "sandbox-only"
<< "world-and-sandbox"
<< "world-only-to-be-copied-into-sandbox");
QVERIFY(!QFileInfo(Sandbox::map(TESTS_DATA_PATH "/world/world-only")).exists());
QVERIFY(!QFileInfo(Sandbox::map(LOCATE_DATA_PATH, "/world/world-only")).exists());
QVERIFY(QFileInfo(Sandbox::map(TESTS_DATA_PATH "/world/world-and-sandbox")).isWritable());
QCOMPARE(readAll(Sandbox::map(TESTS_DATA_PATH "/world/world-and-sandbox")).trimmed(),
QVERIFY(QFileInfo(Sandbox::map(LOCATE_DATA_PATH, "/world/world-and-sandbox")).isWritable());
QCOMPARE(readAll(Sandbox::map(LOCATE_DATA_PATH, "/world/world-and-sandbox")).trimmed(),
QString("sandbox/world-and-sandbox"));
QVERIFY(QFileInfo(Sandbox::map(TESTS_DATA_PATH "/world/world-only-to-be-copied-into-sandbox"))
QVERIFY(QFileInfo(Sandbox::map(LOCATE_DATA_PATH, "/world/world-only-to-be-copied-into-sandbox"))
.isWritable());
QCOMPARE(readAll(Sandbox::map(TESTS_DATA_PATH "/world/world-only-to-be-copied-into-sandbox"))
QCOMPARE(readAll(Sandbox::map(LOCATE_DATA_PATH, "/world/world-only-to-be-copied-into-sandbox"))
.trimmed(), QString("world/world-only-to-be-copied-into-sandbox"));
QVERIFY(QFileInfo(Sandbox::map(TESTS_DATA_PATH "/world/sandbox-only")).exists());
QVERIFY(QFileInfo(Sandbox::map(TESTS_DATA_PATH "/world/sandbox-only")).isWritable());
QCOMPARE(readAll(Sandbox::map(TESTS_DATA_PATH "/world/sandbox-only")).trimmed(),
QVERIFY(QFileInfo(Sandbox::map(LOCATE_DATA_PATH, "/world/sandbox-only")).exists());
QVERIFY(QFileInfo(Sandbox::map(LOCATE_DATA_PATH, "/world/sandbox-only")).isWritable());
QCOMPARE(readAll(Sandbox::map(LOCATE_DATA_PATH, "/world/sandbox-only")).trimmed(),
QString("sandbox/sandbox-only"));
}
......
......@@ -20,12 +20,16 @@ typedef QStringList Args; // improve readability
void SsuCliTest::init(){
Q_ASSERT(m_sandbox == 0);
m_sandbox = new Sandbox(QString("%1/configroot").arg(TESTS_DATA_PATH),
m_sandbox = new Sandbox(QString("%1/configroot").arg(LOCATE_DATA_PATH),
Sandbox::UseAsSkeleton, Sandbox::ChildProcesses);
if (!m_sandbox->activate()){
QFAIL("Failed to activate sandbox");
}
setenv("LD_PRELOAD", qPrintable(QString("%1/libsandboxhook.so").arg(TESTS_PATH)), 1);
if (getenv("SSU_SANDBOX_PATH")){
qDebug() << "Using in-tree sandbox";
setenv("LD_PRELOAD", getenv("SSU_SANDBOX_PATH"), 1);
} else
setenv("LD_PRELOAD", qPrintable(QString("%1/libsandboxhook.so").arg(TESTS_PATH)), 1);
m_bus = new QProcess(this);
m_bus->start("dbus-daemon",
......
......@@ -22,12 +22,16 @@
*/
void SsuUrlResolverTest::initTestCase(){
m_sandbox = new Sandbox(QString("%1/configroot").arg(TESTS_DATA_PATH),
m_sandbox = new Sandbox(QString("%1/configroot").arg(LOCATE_DATA_PATH),
Sandbox::UseDirectly, Sandbox::ChildProcesses);
if (!m_sandbox->activate()){
QFAIL("Failed to activate sandbox");
}
setenv("LD_PRELOAD", qPrintable(QString("%1/libsandboxhook.so").arg(TESTS_PATH)), 1);
if (getenv("SSU_SANDBOX_PATH")){
qDebug() << "Using in-tree sandbox";
setenv("LD_PRELOAD", getenv("SSU_SANDBOX_PATH"), 1);
} else
setenv("LD_PRELOAD", qPrintable(QString("%1/libsandboxhook.so").arg(TESTS_PATH)), 1);
}
void SsuUrlResolverTest::cleanupTestCase(){
......
......@@ -11,7 +11,7 @@
#include "urlresolvertest.cpp"
int main(int argc, char **argv){
Sandbox sandbox(QString("%1/configroot").arg(TESTS_DATA_PATH),
Sandbox sandbox(QString("%1/configroot").arg(LOCATE_DATA_PATH),
Sandbox::UseAsSkeleton, Sandbox::ThisProcess);
if (!sandbox.activate()){
qFatal("Failed to activate sandbox");
......
......@@ -142,7 +142,7 @@ void UrlResolverTest::checkRegisterDevice(){
QVERIFY2(!ssu.registerDevice(&doc),
"Ssu::registerDevice() should fail when 'certificate' is empty");
QFile certificateFile(TESTS_DATA_PATH "/mycert.crt");
QFile certificateFile(QString("%1/mycert.crt").arg(LOCATE_DATA_PATH));
QVERIFY(certificateFile.open(QIODevice::ReadOnly));
certificate.appendChild(doc.createTextNode(certificateFile.readAll()));
......@@ -153,7 +153,7 @@ void UrlResolverTest::checkRegisterDevice(){
QVERIFY2(!ssu.registerDevice(&doc),
"Ssu::registerDevice() should fail when 'privateKey' is empty");
QFile privateKeyFile(TESTS_DATA_PATH "/mykey.key");
QFile privateKeyFile(QString("%1/mykey.key").arg(LOCATE_DATA_PATH));
QVERIFY(privateKeyFile.open(QIODevice::ReadOnly));
privateKey.appendChild(doc.createTextNode(privateKeyFile.readAll()));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment