Fix tests on Windows

This commit is contained in:
Janek Bevendorff 2018-10-19 20:10:37 +02:00
parent 113c8eb702
commit 108e4efc8a
8 changed files with 130 additions and 22 deletions

View File

@ -95,7 +95,7 @@ set(TEST_LIBRARIES
${ZLIB_LIBRARIES} ${ZLIB_LIBRARIES}
) )
set(testsupport_SOURCES TestGlobal.h modeltest.cpp FailDevice.cpp stub/TestClock.cpp) set(testsupport_SOURCES TestGlobal.h modeltest.cpp FailDevice.cpp stub/TestClock.cpp util/TemporaryFile.cpp)
add_library(testsupport STATIC ${testsupport_SOURCES}) add_library(testsupport STATIC ${testsupport_SOURCES})
target_link_libraries(testsupport Qt5::Core Qt5::Concurrent Qt5::Widgets Qt5::Test) target_link_libraries(testsupport Qt5::Core Qt5::Concurrent Qt5::Widgets Qt5::Test)

View File

@ -71,22 +71,22 @@ void TestCli::initTestCase()
void TestCli::init() void TestCli::init()
{ {
m_dbFile.reset(new QTemporaryFile()); m_dbFile.reset(new TemporaryFile());
m_dbFile->open(); m_dbFile->open();
m_dbFile->write(m_dbData); m_dbFile->write(m_dbData);
m_dbFile->flush(); m_dbFile->close();
m_stdinFile.reset(new QTemporaryFile()); m_stdinFile.reset(new TemporaryFile());
m_stdinFile->open(); m_stdinFile->open();
m_stdinHandle = fdopen(m_stdinFile->handle(), "r+"); m_stdinHandle = fdopen(m_stdinFile->handle(), "r+");
Utils::STDIN = m_stdinHandle; Utils::STDIN = m_stdinHandle;
m_stdoutFile.reset(new QTemporaryFile()); m_stdoutFile.reset(new TemporaryFile());
m_stdoutFile->open(); m_stdoutFile->open();
m_stdoutHandle = fdopen(m_stdoutFile->handle(), "r+"); m_stdoutHandle = fdopen(m_stdoutFile->handle(), "r+");
Utils::STDOUT = m_stdoutHandle; Utils::STDOUT = m_stdoutHandle;
m_stderrFile.reset(new QTemporaryFile()); m_stderrFile.reset(new TemporaryFile());
m_stderrFile->open(); m_stderrFile->open();
m_stderrHandle = fdopen(m_stderrFile->handle(), "r+"); m_stderrHandle = fdopen(m_stderrFile->handle(), "r+");
Utils::STDERR = m_stderrHandle; Utils::STDERR = m_stderrHandle;
@ -147,6 +147,7 @@ void TestCli::testAdd()
Utils::setNextPassword("a"); Utils::setNextPassword("a");
addCmd.execute({"add", "-u", "newuser", "--url", "https://example.com/", "-g", "-l", "20", m_dbFile->fileName(), "/newuser-entry"}); addCmd.execute({"add", "-u", "newuser", "--url", "https://example.com/", "-g", "-l", "20", m_dbFile->fileName(), "/newuser-entry"});
m_stderrFile->reset();
auto db = readTestDatabase(); auto db = readTestDatabase();
auto* entry = db->rootGroup()->findEntryByPath("/newuser-entry"); auto* entry = db->rootGroup()->findEntryByPath("/newuser-entry");
@ -220,7 +221,7 @@ void TestCli::testDiceware()
passphrase = m_stdoutFile->readLine(); passphrase = m_stdoutFile->readLine();
QCOMPARE(passphrase.split(" ").size(), 10); QCOMPARE(passphrase.split(" ").size(), 10);
QTemporaryFile wordFile; TemporaryFile wordFile;
wordFile.open(); wordFile.open();
for (int i = 0; i < 4500; ++i) { for (int i = 0; i < 4500; ++i) {
wordFile.write(QString("word" + QString::number(i) + "\n").toLatin1()); wordFile.write(QString("word" + QString::number(i) + "\n").toLatin1());
@ -548,7 +549,7 @@ void TestCli::testLocate()
entry->setUuid(QUuid::createUuid()); entry->setUuid(QUuid::createUuid());
entry->setTitle("New Entry"); entry->setTitle("New Entry");
group->addEntry(entry); group->addEntry(entry);
QTemporaryFile tmpFile; TemporaryFile tmpFile;
tmpFile.open(); tmpFile.open();
Kdbx4Writer writer; Kdbx4Writer writer;
writer.writeDatabase(&tmpFile, db.data()); writer.writeDatabase(&tmpFile, db.data());
@ -581,13 +582,13 @@ void TestCli::testMerge()
// load test database and save a copy // load test database and save a copy
auto db = readTestDatabase(); auto db = readTestDatabase();
QVERIFY(db); QVERIFY(db);
QTemporaryFile targetFile1; TemporaryFile targetFile1;
targetFile1.open(); targetFile1.open();
writer.writeDatabase(&targetFile1, db.data()); writer.writeDatabase(&targetFile1, db.data());
targetFile1.close(); targetFile1.close();
// save another copy with a different password // save another copy with a different password
QTemporaryFile targetFile2; TemporaryFile targetFile2;
targetFile2.open(); targetFile2.open();
auto oldKey = db->key(); auto oldKey = db->key();
auto key = QSharedPointer<CompositeKey>::create(); auto key = QSharedPointer<CompositeKey>::create();
@ -605,7 +606,7 @@ void TestCli::testMerge()
auto* group = db->rootGroup()->findGroupByPath("/Internet/"); auto* group = db->rootGroup()->findGroupByPath("/Internet/");
QVERIFY(group); QVERIFY(group);
group->addEntry(entry); group->addEntry(entry);
QTemporaryFile sourceFile; TemporaryFile sourceFile;
sourceFile.open(); sourceFile.open();
writer.writeDatabase(&sourceFile, db.data()); writer.writeDatabase(&sourceFile, db.data());
sourceFile.close(); sourceFile.close();
@ -615,6 +616,7 @@ void TestCli::testMerge()
mergeCmd.execute({"merge", "-s", targetFile1.fileName(), sourceFile.fileName()}); mergeCmd.execute({"merge", "-s", targetFile1.fileName(), sourceFile.fileName()});
m_stdoutFile->seek(pos); m_stdoutFile->seek(pos);
m_stdoutFile->readLine(); m_stdoutFile->readLine();
m_stderrFile->reset();
QCOMPARE(m_stdoutFile->readAll(), QByteArray("Successfully merged the database files.\n")); QCOMPARE(m_stdoutFile->readAll(), QByteArray("Successfully merged the database files.\n"));
QFile readBack(targetFile1.fileName()); QFile readBack(targetFile1.fileName());
@ -660,7 +662,7 @@ void TestCli::testRemove()
// load test database and save a copy with disabled recycle bin // load test database and save a copy with disabled recycle bin
auto db = readTestDatabase(); auto db = readTestDatabase();
QVERIFY(db); QVERIFY(db);
QTemporaryFile fileCopy; TemporaryFile fileCopy;
fileCopy.open(); fileCopy.open();
db->metadata()->setRecycleBinEnabled(false); db->metadata()->setRecycleBinEnabled(false);
writer.writeDatabase(&fileCopy, db.data()); writer.writeDatabase(&fileCopy, db.data());

View File

@ -19,6 +19,7 @@
#define KEEPASSXC_TESTCLI_H #define KEEPASSXC_TESTCLI_H
#include "core/Database.h" #include "core/Database.h"
#include "util/TemporaryFile.h"
#include <QTest> #include <QTest>
#include <QTextStream> #include <QTextStream>
@ -57,10 +58,10 @@ private slots:
private: private:
QByteArray m_dbData; QByteArray m_dbData;
QScopedPointer<QTemporaryFile> m_dbFile; QScopedPointer<TemporaryFile> m_dbFile;
QScopedPointer<QTemporaryFile> m_stdoutFile; QScopedPointer<TemporaryFile> m_stdoutFile;
QScopedPointer<QTemporaryFile> m_stderrFile; QScopedPointer<TemporaryFile> m_stderrFile;
QScopedPointer<QTemporaryFile> m_stdinFile; QScopedPointer<TemporaryFile> m_stdinFile;
FILE* m_stdoutHandle = stdout; FILE* m_stdoutHandle = stdout;
FILE* m_stderrHandle = stderr; FILE* m_stderrHandle = stderr;
FILE* m_stdinHandle = stdin; FILE* m_stdinHandle = stdin;

View File

@ -15,6 +15,6 @@
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..)
add_unit_test(NAME testgui SOURCES TestGui.cpp LIBS ${TEST_LIBRARIES}) add_unit_test(NAME testgui SOURCES TestGui.cpp ../util/TemporaryFile.cpp LIBS ${TEST_LIBRARIES})
add_unit_test(NAME testguipixmaps SOURCES TestGuiPixmaps.cpp LIBS ${TEST_LIBRARIES}) add_unit_test(NAME testguipixmaps SOURCES TestGuiPixmaps.cpp LIBS ${TEST_LIBRARIES})

View File

@ -102,7 +102,7 @@ void TestGui::initTestCase()
// Every test starts with opening the temp database // Every test starts with opening the temp database
void TestGui::init() void TestGui::init()
{ {
m_dbFile.reset(new QTemporaryFile()); m_dbFile.reset(new TemporaryFile());
// Write the temp storage to a temp database file for use in our tests // Write the temp storage to a temp database file for use in our tests
QVERIFY(m_dbFile->open()); QVERIFY(m_dbFile->open());
QCOMPARE(m_dbFile->write(m_dbData), static_cast<qint64>((m_dbData.size()))); QCOMPARE(m_dbFile->write(m_dbData), static_cast<qint64>((m_dbData.size())));
@ -289,7 +289,7 @@ void TestGui::createDatabaseCallback()
QCOMPARE(fileCombo->currentText(), QString("%1/%2").arg(QString(KEEPASSX_TEST_DATA_DIR), "FileKeyHashed.key")); QCOMPARE(fileCombo->currentText(), QString("%1/%2").arg(QString(KEEPASSX_TEST_DATA_DIR), "FileKeyHashed.key"));
// save database to temporary file // save database to temporary file
QTemporaryFile tmpFile; TemporaryFile tmpFile;
QVERIFY(tmpFile.open()); QVERIFY(tmpFile.open());
tmpFile.close(); tmpFile.close();
fileDialog()->setNextFileName(tmpFile.fileName()); fileDialog()->setNextFileName(tmpFile.fileName());
@ -1071,7 +1071,7 @@ void TestGui::testSaveAs()
m_db->metadata()->setName("testSaveAs"); m_db->metadata()->setName("testSaveAs");
// open temporary file so it creates a filename // open temporary file so it creates a filename
QTemporaryFile tmpFile; TemporaryFile tmpFile;
QVERIFY(tmpFile.open()); QVERIFY(tmpFile.open());
QString tmpFileName = tmpFile.fileName(); QString tmpFileName = tmpFile.fileName();
tmpFile.remove(); tmpFile.remove();

View File

@ -20,12 +20,12 @@
#define KEEPASSX_TESTGUI_H #define KEEPASSX_TESTGUI_H
#include "gui/MainWindow.h" #include "gui/MainWindow.h"
#include "util/TemporaryFile.h"
#include <QAbstractItemModel> #include <QAbstractItemModel>
#include <QObject> #include <QObject>
#include <QPointer> #include <QPointer>
#include <QScopedPointer> #include <QScopedPointer>
#include <QTemporaryFile>
class Database; class Database;
class DatabaseTabWidget; class DatabaseTabWidget;
@ -90,7 +90,7 @@ private:
QPointer<DatabaseWidget> m_dbWidget; QPointer<DatabaseWidget> m_dbWidget;
QPointer<Database> m_db; QPointer<Database> m_db;
QByteArray m_dbData; QByteArray m_dbData;
QScopedPointer<QTemporaryFile> m_dbFile; QScopedPointer<TemporaryFile> m_dbFile;
QString m_dbFileName; QString m_dbFileName;
QString m_dbFilePath; QString m_dbFilePath;
}; };

View File

@ -0,0 +1,55 @@
/*
* Copyright (C) 2018 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 or (at your option)
* version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "TemporaryFile.h"
#ifdef Q_OS_WIN
TemporaryFile::TemporaryFile()
: TemporaryFile(nullptr)
{
}
TemporaryFile::TemporaryFile(const QString& templateName)
: TemporaryFile(templateName, nullptr)
{
}
TemporaryFile::TemporaryFile(QObject* parent)
: QFile(parent)
{
QTemporaryFile tmp;
tmp.open();
QFile::setFileName(tmp.fileName());
tmp.close();
}
TemporaryFile::TemporaryFile(const QString& templateName, QObject* parent)
: QFile(parent)
{
QTemporaryFile tmp(templateName);
tmp.open();
QFile::setFileName(tmp.fileName());
tmp.close();
}
bool TemporaryFile::open()
{
return QFile::open(QIODevice::ReadWrite);
}
#endif

View File

@ -0,0 +1,50 @@
/*
* Copyright (C) 2018 KeePassXC Team <team@keepassxc.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 or (at your option)
* version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KEEPASSXC_TEMPORARYFILE_H
#define KEEPASSXC_TEMPORARYFILE_H
#include <QTemporaryFile>
#ifdef Q_OS_WIN
/**
* QTemporaryFile does not actually close a file when close() is
* called, which causes the file to be locked on Windows.
* This class extends a QFile with the extra functionality
* of a QTemporaryFile to circumvent this problem.
*/
class TemporaryFile : public QFile
#else
class TemporaryFile : public QTemporaryFile
#endif
{
Q_OBJECT
#ifdef Q_OS_WIN
public:
TemporaryFile();
explicit TemporaryFile(const QString& templateName);
explicit TemporaryFile(QObject* parent);
TemporaryFile(const QString& templateName, QObject* parent);
~TemporaryFile() override = default;
using QFile::open;
bool open();
#endif
};
#endif //KEEPASSXC_TEMPORARYFILE_H