diff options
author | kh1 <karsten.heimrich@digia.com> | 2014-07-30 17:30:29 +0200 |
---|---|---|
committer | Karsten Heimrich <karsten.heimrich@digia.com> | 2014-08-27 13:21:56 +0200 |
commit | 554a7f108ef17d8a042f2960e0a483508ca15cd3 (patch) | |
tree | a3547db4e2e3c3375ff7e911c82b82a4f8e5149a /tests/auto/installer/binaryformat/tst_binaryformat.cpp | |
parent | 2dfa49ac79d421c87bbc1404be56d5ae37a6a2c4 (diff) |
Introduce two new functions to read and write binary content.
In addition update the auto test to test both new functions.
Change-Id: I85f1e28cf486fc381941e553dac6defa9d327117
Reviewed-by: Niels Weber <niels.weber@digia.com>
Diffstat (limited to 'tests/auto/installer/binaryformat/tst_binaryformat.cpp')
-rw-r--r-- | tests/auto/installer/binaryformat/tst_binaryformat.cpp | 325 |
1 files changed, 324 insertions, 1 deletions
diff --git a/tests/auto/installer/binaryformat/tst_binaryformat.cpp b/tests/auto/installer/binaryformat/tst_binaryformat.cpp index a17226d46..d313bbbcc 100644 --- a/tests/auto/installer/binaryformat/tst_binaryformat.cpp +++ b/tests/auto/installer/binaryformat/tst_binaryformat.cpp @@ -40,8 +40,10 @@ **************************************************************************/ #include <binarycontent.h> +#include <binaryformat.h> #include <errors.h> #include <fileio.h> +#include <kdupdaterupdateoperation.h> #include <QTest> #include <QTemporaryFile> @@ -50,11 +52,56 @@ static const qint64 scTinySize = 72704LL; static const qint64 scSmallSize = 524288LL; static const qint64 scLargeSize = 2097152LL; +using namespace QInstaller; + +struct Layout +{ + Range<qint64> metaResourceSegment; + QVector<Range<qint64> > metaResourceSegments; + + qint64 operationsCount; + Range<qint64> operationsSegment; + + qint64 collectionCount; + Range<qint64> resourceCollectionIndexSegment; + + qint64 binaryContentSize; + qint64 magicMarker; + quint64 magicCookie; + + qint64 endOfBinary; +}; + +class TestOperation : public KDUpdater::UpdateOperation +{ +public: + TestOperation(const QString &name) { setName(name); } + + virtual void backup() {} + virtual bool performOperation() { return true; } + virtual bool undoOperation() { return true; } + virtual bool testOperation() { return true; } + virtual Operation *clone() const { return 0; } +}; + class tst_BinaryFormat : public QObject { Q_OBJECT private slots: + void initTestCase() + { + TestOperation op(QLatin1String("Operation 1")); + op.setValue(QLatin1String("key"), QLatin1String("Operation 1 value.")); + op.setArguments(QStringList() << QLatin1String("arg1") << QLatin1String("arg2")); + m_operations.append(OperationBlob(op.name(), op.toXml().toString())); + + op = TestOperation(QLatin1String("Operation 2")); + op.setValue(QLatin1String("key"), QLatin1String("Operation 2 value.")); + op.setArguments(QStringList() << QLatin1String("arg1") << QLatin1String("arg2")); + m_operations.append(OperationBlob(op.name(), op.toXml().toString())); + } + void findMagicCookieSmallFile() { QTemporaryFile file; @@ -92,7 +139,7 @@ private slots: } } - void testFindMagicCookieWithError() + void findMagicCookieWithError() { QTest::ignoreMessage(QtDebugMsg, "create Error-Exception: \"No marker found, stopped after 71.00 KiB.\" "); @@ -110,6 +157,282 @@ private slots: QFAIL("Unexpected error."); } } + + void writeBinaryContent() + { + QTemporaryFile binary; + QInstaller::openForWrite(&binary); + QInstaller::blockingWrite(&binary, QByteArray(scTinySize, '1')); + + Layout layout; + layout.endOfBinary = binary.pos(); + layout.magicMarker = BinaryContent::MagicInstallerMarker; + layout.magicCookie = BinaryContent::MagicCookie; + + qint64 start = binary.pos(); // write default resource (fake) + QInstaller::blockingWrite(&binary, QByteArray("Default resource data.")); + qint64 end = binary.pos(); + layout.metaResourceSegments.append(Range<qint64>::fromStartAndEnd(start, end) + .moved(-layout.endOfBinary)); + + start = end; // // write additional resource (fake) + QInstaller::blockingWrite(&binary, QByteArray("Additional resource data.")); + end = binary.pos(); + layout.metaResourceSegments.append(Range<qint64>::fromStartAndEnd(start, end) + .moved(-layout.endOfBinary)); + layout.metaResourceSegment = Range<qint64>::fromStartAndEnd(layout.metaResourceSegments.first() + .start(), layout.metaResourceSegments.last().end()); + + start = end; + layout.operationsCount = m_operations.count(); + QInstaller::appendInt64(&binary, layout.operationsCount); + foreach (const OperationBlob &operation, m_operations) { + QInstaller::appendString(&binary, operation.name); + QInstaller::appendString(&binary, operation.xml); + } + QInstaller::appendInt64(&binary, layout.operationsCount); + end = binary.pos(); + layout.operationsSegment = Range<qint64>::fromStartAndEnd(start, end).moved(-layout + .endOfBinary); + + QTemporaryFile data; + QTemporaryFile data2; + { // put into the scope to make the temporary file auto remove feature work + + ResourceCollectionManager manager; + + QInstaller::openForWrite(&data); + QInstaller::blockingWrite(&data, QByteArray("Collection 1, Resource 1.")); + data.close(); + + ResourceCollection collection; + collection.setName(QByteArray("Collection 1")); + + QSharedPointer<Resource> resource(new Resource(data.fileName())); + resource->setName("Resource 1"); + collection.appendResource(resource); + manager.insertCollection(collection); + + QInstaller::openForWrite(&data2); + QInstaller::blockingWrite(&data2, QByteArray("Collection 2, Resource 2.")); + data2.close(); + + ResourceCollection collection2; + collection2.setName(QByteArray("Collection 2")); + + QSharedPointer<Resource> resource2(new + Resource(data2.fileName())); + resource2->setName("Resource 2"); + collection2.appendResource(resource2); + manager.insertCollection(collection2); + + layout.collectionCount = manager.collectionCount(); + layout.resourceCollectionIndexSegment = manager.write(&binary, -layout.endOfBinary) + .moved(-layout.endOfBinary); + + resource->close(); + resource2->close(); + } + + QInstaller::appendInt64Range(&binary, layout.resourceCollectionIndexSegment); + foreach (const Range<qint64> &segment, layout.metaResourceSegments) + QInstaller::appendInt64Range(&binary, segment); + QInstaller::appendInt64Range(&binary, layout.operationsSegment); + QInstaller::appendInt64(&binary, layout.metaResourceSegments.count()); + + layout.binaryContentSize = (binary.pos() + (3 * sizeof(qint64))) - layout.endOfBinary; + + QInstaller::appendInt64(&binary, layout.binaryContentSize); + QInstaller::appendInt64(&binary, layout.magicMarker); + QInstaller::appendInt64(&binary, layout.magicCookie); + + binary.close(); + binary.setAutoRemove(false); + + m_layout = layout; + m_binary = binary.fileName(); + } + + void readBinaryContent() + { + const QSharedPointer<QFile> binary(new QFile(m_binary)); + QInstaller::openForRead(binary.data()); + QCOMPARE(QInstaller::retrieveData(binary.data(), scTinySize), QByteArray(scTinySize, '1')); + + Layout layout; + layout.endOfBinary = binary->pos(); + QCOMPARE(layout.endOfBinary, m_layout.endOfBinary); + + const qint64 pos = BinaryContent::findMagicCookie(binary.data(), BinaryContent::MagicCookie); + const qint64 endOfBinaryContent = pos + sizeof(qint64); + + binary->seek(endOfBinaryContent - (4 * sizeof(qint64))); + + qint64 metaSegmentsCount = QInstaller::retrieveInt64(binary.data()); + QCOMPARE(metaSegmentsCount, m_layout.metaResourceSegments.count()); + + const qint64 offsetCollectionIndexSegments = endOfBinaryContent + - ((metaSegmentsCount * (2 * sizeof(qint64))) // minus the size of the meta segments + + (8 * sizeof(qint64))); // meta count, offset/length component index, marker, cookie... + + binary->seek(offsetCollectionIndexSegments); + + layout.resourceCollectionIndexSegment = QInstaller::retrieveInt64Range(binary.data()); + QCOMPARE(layout.resourceCollectionIndexSegment, m_layout.resourceCollectionIndexSegment); + + for (int i = 0; i < metaSegmentsCount; ++i) + layout.metaResourceSegments.append(QInstaller::retrieveInt64Range(binary.data())); + layout.metaResourceSegment = Range<qint64>::fromStartAndEnd(layout.metaResourceSegments + .first().start(), layout.metaResourceSegments.last().end()); + QCOMPARE(layout.metaResourceSegment, m_layout.metaResourceSegment); + QCOMPARE(layout.metaResourceSegments, m_layout.metaResourceSegments); + + layout.operationsSegment = QInstaller::retrieveInt64Range(binary.data()); + QCOMPARE(layout.operationsSegment, m_layout.operationsSegment); + + QCOMPARE(metaSegmentsCount, QInstaller::retrieveInt64(binary.data())); + + layout.binaryContentSize = QInstaller::retrieveInt64(binary.data()); + QCOMPARE(layout.binaryContentSize, m_layout.binaryContentSize); + QCOMPARE(layout.endOfBinary, endOfBinaryContent - layout.binaryContentSize); + + layout.magicMarker = QInstaller::retrieveInt64(binary.data()); + QCOMPARE(layout.magicMarker, m_layout.magicMarker); + + layout.magicCookie = QInstaller::retrieveInt64(binary.data()); + QCOMPARE(layout.magicCookie, m_layout.magicCookie); + + binary->seek(layout.endOfBinary + layout.operationsSegment.start()); + + layout.operationsCount = QInstaller::retrieveInt64(binary.data()); + QCOMPARE(layout.operationsCount, m_layout.operationsCount); + + for (int i = 0; i < layout.operationsCount; ++i) { + QCOMPARE(m_operations.at(i).name, QInstaller::retrieveString(binary.data())); + QCOMPARE(m_operations.at(i).xml, QInstaller::retrieveString(binary.data())); + } + + layout.operationsCount = QInstaller::retrieveInt64(binary.data()); + QCOMPARE(layout.operationsCount, m_layout.operationsCount); + + layout.collectionCount = QInstaller::retrieveInt64(binary.data()); + QCOMPARE(layout.collectionCount, m_layout.collectionCount); + + binary->seek(layout.endOfBinary + layout.resourceCollectionIndexSegment.start()); + m_manager.read(binary, layout.endOfBinary); + + const QList<ResourceCollection> components = m_manager.collections(); + QCOMPARE(components.count(), m_layout.collectionCount); + + ResourceCollection component = m_manager.collectionByName("Collection 1"); + QCOMPARE(component.resources().count(), 1); + + QSharedPointer<Resource> resource(component.resourceByName("Resource 1")); + QCOMPARE(resource.isNull(), false); + QCOMPARE(resource->isOpen(), false); + QCOMPARE(resource->open(), true); + QCOMPARE(resource->readAll(), QByteArray("Collection 1, Resource 1.")); + resource->close(); + + component = m_manager.collectionByName("Collection 2"); + QCOMPARE(component.resources().count(), 1); + + resource = component.resourceByName("Resource 2"); + QCOMPARE(resource.isNull(), false); + QCOMPARE(resource->isOpen(), false); + QCOMPARE(resource->open(), true); + QCOMPARE(resource->readAll(), QByteArray("Collection 2, Resource 2.")); + resource->close(); + } + + void testWriteBinaryContentFunction() + { + QSharedPointer<QFile> existingBinary(new QFile(m_binary)); + QInstaller::openForRead(existingBinary.data()); + + QSharedPointer<QFile> file(new QTemporaryFile); + QInstaller::openForWrite(file.data()); + QInstaller::blockingWrite(file.data(), QByteArray(scTinySize, '1')); + + ResourceCollection resources; + foreach (const Range<qint64> &segment, m_layout.metaResourceSegments) { + resources.appendResource(QSharedPointer<Resource> (new Resource(existingBinary, + segment.moved(m_layout.endOfBinary)))); + } + + QList<OperationBlob> operations; + foreach (const OperationBlob &operation, m_operations) + operations.append(operation); + + BinaryContent::writeBinaryContent(file, resources, operations, m_manager, + m_layout.magicMarker, m_layout.magicCookie); + file->close(); + existingBinary->close(); + + QInstaller::openForRead(file.data()); + QInstaller::openForRead(existingBinary.data()); + QCOMPARE(file->readAll(), existingBinary->readAll()); + } + + void testReadBinaryContentFunction() + { + QSharedPointer<QFile> file(new QFile(m_binary)); + QInstaller::openForRead(file.data()); + + qint64 magicMarker; + ResourceCollection collection; + QList<OperationBlob> operations; + ResourceCollectionManager manager; + BinaryContent::readBinaryContent(file, &collection, &operations, &manager, &magicMarker, + m_layout.magicCookie); + + QCOMPARE(magicMarker, m_layout.magicMarker); + QCOMPARE(collection.resources().count(), m_layout.metaResourceSegments.count()); + for (int i = 0; i < collection.resources().count(); ++i) { + QCOMPARE(collection.resources().at(i)->segment(), m_layout.metaResourceSegments.at(i) + .moved(m_layout.endOfBinary)); + } + + QCOMPARE(operations.count(), m_operations.count()); + for (int i = 0; i < operations.count(); ++i) { + QCOMPARE(operations.at(i).name, m_operations.at(i).name); + QCOMPARE(operations.at(i).xml, m_operations.at(i).xml); + } + + QCOMPARE(manager.collectionCount(), m_manager.collectionCount()); + + ResourceCollection component = manager.collectionByName("Collection 1"); + QCOMPARE(component.resources().count(), 1); + + QSharedPointer<Resource> resource(component.resourceByName("Resource 1")); + QCOMPARE(resource.isNull(), false); + QCOMPARE(resource->isOpen(), false); + QCOMPARE(resource->open(), true); + QCOMPARE(resource->readAll(), QByteArray("Collection 1, Resource 1.")); + resource->close(); + + component = manager.collectionByName("Collection 2"); + QCOMPARE(component.resources().count(), 1); + + resource = component.resourceByName("Resource 2"); + QCOMPARE(resource.isNull(), false); + QCOMPARE(resource->isOpen(), false); + QCOMPARE(resource->open(), true); + QCOMPARE(resource->readAll(), QByteArray("Collection 2, Resource 2.")); + resource->close(); + } + + void cleanupTestCase() + { + m_manager.reset(); + QFile::remove(m_binary); + } + +private: + Layout m_layout; + QString m_binary; + QList<OperationBlob> m_operations; + ResourceCollectionManager m_manager; }; QTEST_MAIN(tst_BinaryFormat) |