Test if we correctly detect errors when writing.

This commit is contained in:
Felix Geyer 2015-07-20 21:32:07 +02:00
parent 606e36acf3
commit 2033174d95
7 changed files with 158 additions and 7 deletions

View File

@ -93,9 +93,9 @@ set(TEST_LIBRARIES
${ZLIB_LIBRARIES}
)
set(modeltest_SOURCRS modeltest.cpp)
qt4_wrap_cpp(modeltest_SOURCRS modeltest.h)
add_library(modeltest STATIC ${modeltest_SOURCRS})
set(testsupport_SOURCES modeltest.cpp FailDevice.cpp)
qt4_wrap_cpp(testsupport_SOURCES modeltest.h FailDevice.h)
add_library(testsupport STATIC ${testsupport_SOURCES})
add_unit_test(NAME testgroup SOURCES TestGroup.cpp MOCS TestGroup.h
LIBS ${TEST_LIBRARIES})
@ -110,13 +110,13 @@ add_unit_test(NAME testkeepass2reader SOURCES TestKeePass2Reader.cpp MOCS TestKe
LIBS ${TEST_LIBRARIES})
add_unit_test(NAME testkeepass2writer SOURCES TestKeePass2Writer.cpp MOCS TestKeePass2Writer.h
LIBS ${TEST_LIBRARIES})
LIBS testsupport ${TEST_LIBRARIES})
add_unit_test(NAME testgroupmodel SOURCES TestGroupModel.cpp MOCS TestGroupModel.h
LIBS modeltest ${TEST_LIBRARIES})
LIBS testsupport ${TEST_LIBRARIES})
add_unit_test(NAME testentrymodel SOURCES TestEntryModel.cpp MOCS TestEntryModel.h
LIBS modeltest ${TEST_LIBRARIES})
LIBS testsupport ${TEST_LIBRARIES})
add_unit_test(NAME testcryptohash SOURCES TestCryptoHash.cpp MOCS TestCryptoHash.h
LIBS ${TEST_LIBRARIES})
@ -125,7 +125,7 @@ add_unit_test(NAME testsymmetriccipher SOURCES TestSymmetricCipher.cpp MOCS Test
LIBS ${TEST_LIBRARIES})
add_unit_test(NAME testhashedblockstream SOURCES TestHashedBlockStream.cpp MOCS TestHashedBlockStream.h
LIBS ${TEST_LIBRARIES})
LIBS ${TEST_LIBRARIES} testsupport)
add_unit_test(NAME testkeepass2randomstream SOURCES TestKeePass2RandomStream.cpp MOCS TestKeePass2RandomStream.h
LIBS ${TEST_LIBRARIES})

63
tests/FailDevice.cpp Normal file
View File

@ -0,0 +1,63 @@
/*
* Copyright (C) 2015 Felix Geyer <debfx@fobos.de>
*
* 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 "FailDevice.h"
FailDevice::FailDevice(int failAfter, QObject* parent)
: QBuffer(parent)
, m_failAfter(failAfter)
, m_readCount(0)
, m_writeCount(0)
{
}
bool FailDevice::open(QIODevice::OpenMode openMode)
{
return QBuffer::open(openMode | QIODevice::Unbuffered);
}
qint64 FailDevice::readData(char* data, qint64 len)
{
if (m_readCount >= m_failAfter) {
setErrorString("FAILDEVICE");
return -1;
}
else {
qint64 result = QBuffer::readData(data, len);
if (result != -1) {
m_readCount += result;
}
return result;
}
}
qint64 FailDevice::writeData(const char* data, qint64 len)
{
if (m_writeCount >= m_failAfter) {
setErrorString("FAILDEVICE");
return -1;
}
else {
qint64 result = QBuffer::writeData(data, len);
if (result != -1) {
m_writeCount += result;
}
return result;
}
}

43
tests/FailDevice.h Normal file
View File

@ -0,0 +1,43 @@
/*
* Copyright (C) 2015 Felix Geyer <debfx@fobos.de>
*
* 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 KEEPASSX_FAILDEVICE_H
#define KEEPASSX_FAILDEVICE_H
#include <QBuffer>
#include "core/Global.h"
class FailDevice : public QBuffer
{
Q_OBJECT
public:
explicit FailDevice(int failAfter, QObject* parent = Q_NULLPTR);
bool open(QIODevice::OpenMode openMode) Q_DECL_OVERRIDE;
protected:
qint64 readData(char* data, qint64 len) Q_DECL_OVERRIDE;
qint64 writeData(const char* data, qint64 len) Q_DECL_OVERRIDE;
private:
int m_failAfter;
int m_readCount;
int m_writeCount;
};
#endif // KEEPASSX_FAILDEVICE_H

View File

@ -21,6 +21,7 @@
#include <QTest>
#include "tests.h"
#include "FailDevice.h"
#include "crypto/Crypto.h"
#include "streams/HashedBlockStream.h"
@ -71,3 +72,19 @@ void TestHashedBlockStream::testWriteRead()
buffer.reset();
buffer.buffer().clear();
}
void TestHashedBlockStream::testWriteFailure()
{
FailDevice failDevice(1500);
QVERIFY(failDevice.open(QIODevice::WriteOnly));
QByteArray input(2000, 'Z');
HashedBlockStream writer(&failDevice, 500);
QVERIFY(writer.open(QIODevice::WriteOnly));
QCOMPARE(writer.write(input.left(900)), qint64(900));
writer.write(input.left(900));
QVERIFY(!writer.reset());
QCOMPARE(writer.errorString(), QString("FAILDEVICE"));
}

View File

@ -27,6 +27,7 @@ class TestHashedBlockStream : public QObject
private Q_SLOTS:
void initTestCase();
void testWriteRead();
void testWriteFailure();
};
#endif // KEEPASSX_TESTHASHEDBLOCKSTREAM_H

View File

@ -21,12 +21,14 @@
#include <QTest>
#include "tests.h"
#include "FailDevice.h"
#include "core/Database.h"
#include "core/Group.h"
#include "core/Metadata.h"
#include "crypto/Crypto.h"
#include "format/KeePass2Reader.h"
#include "format/KeePass2Writer.h"
#include "format/KeePass2XmlWriter.h"
#include "keys/PasswordKey.h"
QTEST_GUILESS_MAIN(TestKeePass2Writer)
@ -101,6 +103,30 @@ void TestKeePass2Writer::testNonAsciiPasswords()
QCOMPARE(m_dbTest->rootGroup()->entries()[0]->password(), m_dbOrg->rootGroup()->entries()[0]->password());
}
void TestKeePass2Writer::testDeviceFailure()
{
CompositeKey key;
key.addKey(PasswordKey("test"));
Database* db = new Database();
db->setKey(key);
// Disable compression so we write a predictable number of bytes.
db->setCompressionAlgo(Database::CompressionNone);
Entry* entry = new Entry();
entry->setParent(db->rootGroup());
QByteArray attachment(4096, 'Z');
entry->attachments()->set("test", attachment);
FailDevice failDevice(512);
QVERIFY(failDevice.open(QIODevice::WriteOnly));
KeePass2Writer writer;
writer.writeDatabase(&failDevice, db);
QVERIFY(writer.hasError());
QCOMPARE(writer.errorString(), QString("FAILDEVICE"));
delete db;
}
void TestKeePass2Writer::cleanupTestCase()
{
delete m_dbOrg;

View File

@ -32,6 +32,7 @@ private Q_SLOTS:
void testProtectedAttributes();
void testAttachments();
void testNonAsciiPasswords();
void testDeviceFailure();
void cleanupTestCase();
private: