Commit ea672d43 authored by Martin Kampas's avatar Martin Kampas

Sandbox: add support to work on temporary copy

parent 5f89a216
......@@ -7,7 +7,7 @@ public_headers = \
HEADERS = \
$${public_headers} \
sandboxfileenginehandler_p.h \
sandbox_p.h \
ssucoreconfig.h \
ssudeviceinfo.h \
ssulog.h \
......@@ -16,7 +16,7 @@ HEADERS = \
ssurepomanager.h \
SOURCES = \
sandboxfileenginehandler.cpp \
sandbox.cpp \
ssu.cpp \
ssucoreconfig.cpp \
ssudeviceinfo.cpp \
......
/**
* @file sandboxfileenginehandler.cpp
* @file sandbox.cpp
* @copyright 2013 Jolla Ltd.
* @author Martin Kampas <martin.kampas@tieto.com>
* @date 2013
*/
#include "sandboxfileenginehandler_p.h"
#include "sandbox_p.h"
#include <QtCore/QAbstractFileEngineHandler>
#include <QtCore/QDir>
#include <QtCore/QFSFileEngine>
#include <QtCore/QFileInfo>
......@@ -17,24 +18,50 @@
// TODO: rename to ssuconstants.h?
#include "constants.h"
class Sandbox::FileEngineHandler : public QAbstractFileEngineHandler {
public:
FileEngineHandler(const QString &sandboxPath);
QAbstractFileEngine *create(const QString &fileName) const;
private:
const QString m_sandboxPath;
};
/**
* @class SandboxFileEngineHandler
* @class Sandbox
*
* Redirects all file operations on system configuration files to files under
* directory specified by SSU_TESTS_SANDBOX environment variable.
* sandbox directory. When constructed without arguments, the directory is get
* from @c SSU_TESTS_SANDBOX environment variable.
*
* 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.
*
* Internally it is based on QAbstractFileEngineHandler.
*/
QSet<QString> SandboxFileEngineHandler::s_ssuConfigFiles = QSet<QString>()
Sandbox *Sandbox::s_instance = 0;
QSet<QString> Sandbox::s_ssuConfigFiles = QSet<QString>()
<< SSU_CONFIGURATION
<< SSU_REPO_CONFIGURATION
<< SSU_DEFAULT_CONFIGURATION
<< SSU_BOARD_MAPPING_CONFIGURATION;
QSet<QString> SandboxFileEngineHandler::s_ssuConfigDirectories = QSet<QString>()
QSet<QString> Sandbox::s_ssuConfigDirectories = QSet<QString>()
<< SSU_BOARD_MAPPING_CONFIGURATION_DIR;
SandboxFileEngineHandler::SandboxFileEngineHandler(){
m_enabled = false;
Sandbox::Sandbox(){
if (s_instance != 0){
qFatal("%s: Cannot be instantiated more than once", Q_FUNC_INFO);
}
s_instance = this;
m_handler = 0;
m_sandboxPath = QProcessEnvironment::systemEnvironment().value("SSU_TESTS_SANDBOX");
if (m_sandboxPath.isEmpty()){
......@@ -51,11 +78,18 @@ SandboxFileEngineHandler::SandboxFileEngineHandler(){
qPrintable(m_sandboxPath));
}
m_enabled = true;
m_handler = new FileEngineHandler(m_sandboxPath);
}
SandboxFileEngineHandler::SandboxFileEngineHandler(const QString &sandboxPath){
m_enabled = false;
Sandbox::Sandbox(const QString &sandboxPath, Usage usage){
if (s_instance != 0){
qFatal("%s: Cannot be instantiated more than once", Q_FUNC_INFO);
}
s_instance = this;
m_handler = 0;
m_sandboxPath = sandboxPath;
if (m_sandboxPath.isEmpty()){
......@@ -73,16 +107,54 @@ SandboxFileEngineHandler::SandboxFileEngineHandler(const QString &sandboxPath){
qPrintable(m_sandboxPath));
}
m_enabled = true;
if (usage == UseAsSkeleton){
QProcess mktemp;
mktemp.start("mktemp", QStringList() << "-t" << "-d" << "ssu-sandbox.XXX");
if (!mktemp.waitForFinished() || mktemp.exitCode() != 0){
qFatal("%s: Failed to create sandbox directory", Q_FUNC_INFO);
}
m_tempDir = mktemp.readAllStandardOutput().trimmed();
if (!QFileInfo(m_tempDir).isDir()){
qFatal("%s: Temporary directory disappeared: '%s'", Q_FUNC_INFO, qPrintable(m_tempDir));
}
const QString sandboxCopyPath = QString("%1/configroot").arg(m_tempDir);
if (QProcess::execute("cp", QStringList() << "-r" << m_sandboxPath << sandboxCopyPath) != 0){
qFatal("%s: Failed to copy sandbox directory", Q_FUNC_INFO);
}
m_sandboxPath = sandboxCopyPath;
}
m_handler = new FileEngineHandler(m_sandboxPath);
}
QAbstractFileEngine *SandboxFileEngineHandler::create(const QString &fileName) const{
Q_ASSERT(!m_enabled || !m_sandboxPath.isEmpty());
Sandbox::~Sandbox(){
delete m_handler;
if (!m_enabled){
return 0;
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_instance = 0;
}
/*
* @class Sandbox::FileEngineHandler
*/
Sandbox::FileEngineHandler::FileEngineHandler(const QString &sandboxPath):
m_sandboxPath(sandboxPath){
Q_ASSERT(!sandboxPath.isEmpty());
}
QAbstractFileEngine *Sandbox::FileEngineHandler::create(const QString &fileName) const{
Q_ASSERT(!m_sandboxPath.isEmpty());
if (!fileName.startsWith('/')){
return 0;
}
......
/**
* @file sandboxfileenginehandler_p.h
* @file sandbox_p.h
* @copyright 2013 Jolla Ltd.
* @author Martin Kampas <martin.kampas@tieto.com>
* @date 2013
*/
#ifndef _SANDBOXINGFILEENGINEHANDLER_P_H
#define _SANDBOXINGFILEENGINEHANDLER_P_H
#ifndef _SANDBOX_P_H
#define _SANDBOX_P_H
#include <QtCore/QAbstractFileEngineHandler>
#include <QtCore/QSet>
#include <QtCore/QString>
class Sandbox {
class FileEngineHandler;
class SandboxFileEngineHandler : public QAbstractFileEngineHandler {
public:
SandboxFileEngineHandler();
SandboxFileEngineHandler(const QString &sandboxPath);
enum Usage {
UseDirectly,
UseAsSkeleton,
};
QAbstractFileEngine *create(const QString &fileName) const;
public:
Sandbox();
Sandbox(const QString &sandboxPath, Usage usage);
~Sandbox();
private:
static Sandbox *s_instance;
static QSet<QString> s_ssuConfigFiles;
static QSet<QString> s_ssuConfigDirectories;
bool m_enabled;
QString m_sandboxPath;
QString m_tempDir;
FileEngineHandler *m_handler;
};
#endif
#include <dlfcn.h>
#include "libssu/sandboxfileenginehandler_p.h"
#include "libssu/sandbox_p.h"
extern "C" void qt_startup_hook()
{
SandboxFileEngineHandler *const handler = new SandboxFileEngineHandler();
Q_UNUSED(handler);
Sandbox *const sandbox = new Sandbox();
Q_UNUSED(sandbox);
static void(*next_qt_startup_hook)() = (void (*)()) dlsym(RTLD_NEXT, "qt_startup_hook");
next_qt_startup_hook();
......
......@@ -7,11 +7,11 @@
#include <QtTest/QtTest>
#include "libssu/sandboxfileenginehandler_p.h"
#include "libssu/sandbox_p.h"
#include "urlresolvertest.cpp"
int main(int argc, char **argv){
SandboxFileEngineHandler h;
Sandbox s;
UrlResolverTest urlResolverTest;
......
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