diff options
Diffstat (limited to 'tests/auto')
571 files changed, 13025 insertions, 515 deletions
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index aed5d01af..e79e6a5d7 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -1,4 +1,5 @@ TEMPLATE = subdirs SUBDIRS += \ - installer + installer \ + tools diff --git a/tests/auto/installer/appendfileoperation/appendfileoperation.pro b/tests/auto/installer/appendfileoperation/appendfileoperation.pro new file mode 100644 index 000000000..aca9ffd36 --- /dev/null +++ b/tests/auto/installer/appendfileoperation/appendfileoperation.pro @@ -0,0 +1,10 @@ +include(../../qttest.pri) + +QT -= gui +QT += testlib + +SOURCES += tst_appendfileoperation.cpp + +RESOURCES += \ + settings.qrc \ + ../shared/config.qrc diff --git a/tests/auto/installer/appendfileoperation/data/repository/A/1.0.2-1content.7z b/tests/auto/installer/appendfileoperation/data/repository/A/1.0.2-1content.7z Binary files differnew file mode 100644 index 000000000..787e0db25 --- /dev/null +++ b/tests/auto/installer/appendfileoperation/data/repository/A/1.0.2-1content.7z diff --git a/tests/auto/installer/appendfileoperation/data/repository/A/1.0.2-1meta.7z b/tests/auto/installer/appendfileoperation/data/repository/A/1.0.2-1meta.7z Binary files differnew file mode 100644 index 000000000..946290ce4 --- /dev/null +++ b/tests/auto/installer/appendfileoperation/data/repository/A/1.0.2-1meta.7z diff --git a/tests/auto/installer/appendfileoperation/data/repository/Updates.xml b/tests/auto/installer/appendfileoperation/data/repository/Updates.xml new file mode 100644 index 000000000..f12d387a1 --- /dev/null +++ b/tests/auto/installer/appendfileoperation/data/repository/Updates.xml @@ -0,0 +1,16 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.2-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <Script>script.qs</Script> + <SHA1>750eda14d867849aeb2f47d620f6e5f32134f375</SHA1> + <DownloadableArchives>content.7z</DownloadableArchives> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/appendfileoperation/data/xmloperationrepository/A/1.0.0content.7z b/tests/auto/installer/appendfileoperation/data/xmloperationrepository/A/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..90b958cdb --- /dev/null +++ b/tests/auto/installer/appendfileoperation/data/xmloperationrepository/A/1.0.0content.7z diff --git a/tests/auto/installer/appendfileoperation/data/xmloperationrepository/Updates.xml b/tests/auto/installer/appendfileoperation/data/xmloperationrepository/Updates.xml new file mode 100644 index 000000000..708ba6539 --- /dev/null +++ b/tests/auto/installer/appendfileoperation/data/xmloperationrepository/Updates.xml @@ -0,0 +1,20 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.0</Version> + <ReleaseDate>2020-01-01</ReleaseDate> + <Default>true</Default> + <UpdateFile CompressedSize="224" OS="Any" UncompressedSize="74"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <Operations> + <Operation name="AppendFile"> + <Argument>@TargetDir@/A.txt</Argument> + <Argument>lorem ipsum</Argument> + </Operation> + </Operations> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/appendfileoperation/settings.qrc b/tests/auto/installer/appendfileoperation/settings.qrc new file mode 100644 index 000000000..66d0c8da1 --- /dev/null +++ b/tests/auto/installer/appendfileoperation/settings.qrc @@ -0,0 +1,9 @@ +<RCC> + <qresource prefix="/"> + <file>data/repository/Updates.xml</file> + <file>data/repository/A/1.0.2-1content.7z</file> + <file>data/repository/A/1.0.2-1meta.7z</file> + <file>data/xmloperationrepository/Updates.xml</file> + <file>data/xmloperationrepository/A/1.0.0content.7z</file> + </qresource> +</RCC> diff --git a/tests/auto/installer/appendfileoperation/tst_appendfileoperation.cpp b/tests/auto/installer/appendfileoperation/tst_appendfileoperation.cpp new file mode 100644 index 000000000..743e4c625 --- /dev/null +++ b/tests/auto/installer/appendfileoperation/tst_appendfileoperation.cpp @@ -0,0 +1,168 @@ +/************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ +#include "../shared/packagemanager.h" + +#include <updateoperations.h> +#include <packagemanagercore.h> + +#include <QFile> +#include <QTest> + +using namespace KDUpdater; +using namespace QInstaller; + +class tst_appendfileoperation : public QObject +{ + Q_OBJECT + +private: + void installFromCLI(const QString &repository) + { + QString installDir = QInstaller::generateTemporaryFileName(); + QVERIFY(QDir().mkpath(installDir)); + PackageManagerCore *core = PackageManager::getPackageManagerWithInit + (installDir, repository); + core->installDefaultComponentsSilently(); + + QFile file(installDir + QDir::separator() + "A.txt"); + QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text)); + QTextStream stream(&file); + QCOMPARE(stream.readAll(), QLatin1String("Appended text: lorem ipsum")); + file.close(); + + core->setPackageManager(); + core->commitSessionOperations(); + // We cannot check the file contents here as it will be deleted on + // undo Extract, but at least check that the uninstallation succeeds. + QCOMPARE(PackageManagerCore::Success, core->uninstallComponentsSilently + (QStringList()<< "A")); + + QDir dir(installDir); + QVERIFY(dir.removeRecursively()); + core->deleteLater(); + } + +private slots: + void initTestCase() + { + m_testFilePath = qApp->applicationDirPath() + QDir::toNativeSeparators("/test"); + } + + void testMissingArguments() + { + AppendFileOperation op; + + QVERIFY(op.testOperation()); + QVERIFY(!op.performOperation()); + + QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::InvalidArguments); + QCOMPARE(op.errorString(), QString("Invalid arguments in AppendFile: 0 arguments given, 2 to 4 arguments expected in the form: <filename> <text to apply> [UNDOOPERATION, \"\"].")); + + op.setArguments(QStringList() << "" << ""); + QTest::ignoreMessage(QtWarningMsg, "QFSFileEngine::open: No file name specified"); + QTest::ignoreMessage(QtWarningMsg, "QFile::rename: Empty or null file name"); + QVERIFY(!op.performOperation()); + + QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::UserDefinedError); + QCOMPARE(op.errorString(), QString("Cannot open file \"\" for writing: No file name specified")); + } + + void testAppendText_data() + { + QTest::addColumn<QString>("source"); + QTest::addColumn<QString>("append"); + QTest::addColumn<QString>("expected"); + QTest::addColumn<bool>("overrideUndo"); + QTest::newRow("newline") << "Line1\nLine2\nLine3\n" << "AppendedText" + << "Line1\nLine2\nLine3\nAppendedText" << false; + QTest::newRow("no newline") << "Lorem ipsum " << "dolore sit amet" + << "Lorem ipsum dolore sit amet" << false; + + QTest::newRow("no undo") << "Lorem ipsum " << "dolore sit amet" + << "Lorem ipsum dolore sit amet" << true; + } + + void testAppendText() + { + QFETCH(QString, source); + QFETCH(QString, append); + QFETCH(QString, expected); + QFETCH(bool, overrideUndo); + + QFile file(m_testFilePath); + QVERIFY(file.open(QIODevice::WriteOnly | QIODevice::Text)); + + QTextStream stream(&file); + stream << source << Qt::flush; + file.close(); + + AppendFileOperation *op = new AppendFileOperation(); + op->setArguments(QStringList() << m_testFilePath << append); + if (overrideUndo) + op->setArguments(op->arguments() << QLatin1String("UNDOOPERATION")); + + op->backup(); + QVERIFY(QFileInfo(op->value("backupOfFile").toString()).exists()); + + QVERIFY2(op->performOperation(), op->errorString().toLatin1()); + QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text)); + QCOMPARE(stream.readAll(), expected); + file.close(); + + QVERIFY2(op->undoOperation(), op->errorString().toLatin1()); + QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text)); + if (overrideUndo) + QCOMPARE(stream.readAll(), expected); + else + QCOMPARE(stream.readAll(), source); + QString backupFileName = op->value("backupOfFile").toString(); + delete op; + QVERIFY(!QFileInfo::exists(backupFileName)); + + file.close(); + + QVERIFY(file.remove()); + } + + void testApppendFromScript() + { + installFromCLI(":///data/repository"); + } + + void testAppendFromComponentXML() + { + installFromCLI(":///data/xmloperationrepository"); + } + +private: + QString m_testFilePath; +}; + +QTEST_MAIN(tst_appendfileoperation) + +#include "tst_appendfileoperation.moc" diff --git a/tests/auto/installer/archivefactory/archivefactory.pro b/tests/auto/installer/archivefactory/archivefactory.pro new file mode 100644 index 000000000..3d8ee90ab --- /dev/null +++ b/tests/auto/installer/archivefactory/archivefactory.pro @@ -0,0 +1,5 @@ +include(../../qttest.pri) + +QT -= gui + +SOURCES += tst_archivefactory.cpp diff --git a/tests/auto/installer/archivefactory/tst_archivefactory.cpp b/tests/auto/installer/archivefactory/tst_archivefactory.cpp new file mode 100644 index 000000000..0c1a7b6f6 --- /dev/null +++ b/tests/auto/installer/archivefactory/tst_archivefactory.cpp @@ -0,0 +1,144 @@ +/************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ + +#include <archivefactory.h> + +#include <QObject> +#include <QTest> + +using namespace QInstaller; + +class MyRarArchive : public AbstractArchive +{ + Q_OBJECT + +public: + MyRarArchive(QObject *parent = nullptr) + : AbstractArchive(parent) + {} + MyRarArchive(const QString &filename, QObject *parent = nullptr) + : AbstractArchive(parent) + { + Q_UNUSED(filename) + } + + bool open(QIODevice::OpenMode mode) + { + Q_UNUSED(mode) + return true; + }; + void close() {}; + void setFilename(const QString &filename) { Q_UNUSED(filename) }; + bool extract(const QString &dirPath) + { + Q_UNUSED(dirPath) + return true; + }; + bool extract(const QString &dirPath, const quint64 totalFiles) + { + Q_UNUSED(dirPath) + Q_UNUSED(totalFiles) + return true; + }; + bool create(const QStringList &data) + { + Q_UNUSED(data) + return true; + }; + QVector<ArchiveEntry> list() { return QVector<ArchiveEntry>(); }; + bool isSupported() { return true; }; + +public slots: + void cancel() {}; +}; + +class tst_archivefactory : public QObject +{ + Q_OBJECT + +private slots: + void testCreateDefaultArchiveHandler_data() + { + QTest::addColumn<QString>("handler"); + QTest::addColumn<QString>("filename"); + QTest::addColumn<QStringList>("types"); +#ifdef IFW_LIBARCHIVE + QTest::newRow("LibArchive") + << "LibArchive" << "myfile.zip" + << (QStringList() << "tar" << "tar.gz" << "tar.bz2" << "tar.xz" << "zip" << "7z" << "qbsp"); +#elif defined(IFW_LIB7Z) + QTest::newRow("Lib7z") + << "Lib7z" << "myfile.7z" << (QStringList() << "7z" << "qbsp"); +#endif + } + + void testCreateDefaultArchiveHandler() + { + QFETCH(QString, handler); + QFETCH(QString, filename); + QFETCH(QStringList, types); + + QVERIFY(ArchiveFactory::instance().containsProduct(handler)); + for (auto &type : types) + QVERIFY(ArchiveFactory::isSupportedType("file." + type)); + + QScopedPointer<AbstractArchive> archive(ArchiveFactory::instance().create(filename)); + QVERIFY(archive); + } + + void testCreateUnknownArchive_data() + { + QTest::addColumn<QString>("filename"); + QTest::newRow("Unknown suffix") << "invalid.file"; + QTest::newRow("Suffix with known part 1") << "myfile.7z.sha1"; + QTest::newRow("Suffix with known part 2") << "myfile.tar.gz.sha1"; + } + + void testCreateUnknownArchive() + { + QFETCH(QString, filename); + + QVERIFY(!ArchiveFactory::isSupportedType(filename)); + QScopedPointer<AbstractArchive> archive(ArchiveFactory::instance().create(filename)); + QVERIFY(!archive); + } + + void testRegisterNewHandler() + { + ArchiveFactory::instance().registerArchive<MyRarArchive>("MyRarHandler", QStringList() << "rar"); + QVERIFY(ArchiveFactory::instance().containsProduct("MyRarHandler")); + QVERIFY(ArchiveFactory::isSupportedType("file.rar")); + + QScopedPointer<AbstractArchive> archive(ArchiveFactory::instance().create("myfile.rar")); + QVERIFY(archive); + } +}; + +QTEST_MAIN(tst_archivefactory) + +#include "tst_archivefactory.moc" diff --git a/tests/auto/installer/binaryformat/tst_binaryformat.cpp b/tests/auto/installer/binaryformat/tst_binaryformat.cpp index c9cd2b00f..2fcad0b38 100644 --- a/tests/auto/installer/binaryformat/tst_binaryformat.cpp +++ b/tests/auto/installer/binaryformat/tst_binaryformat.cpp @@ -1,6 +1,6 @@ /************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2023 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Installer Framework. @@ -26,6 +26,8 @@ ** **************************************************************************/ +#include "../shared/packagemanager.h" + #include <binarycontent.h> #include <binaryformat.h> #include <errors.h> @@ -51,8 +53,8 @@ struct Layout : public QInstaller::BinaryLayout class TestOperation : public KDUpdater::UpdateOperation { public: - TestOperation(const QString &name) - : KDUpdater::UpdateOperation(nullptr) + explicit TestOperation(const QString &name, PackageManagerCore *core = nullptr) + : KDUpdater::UpdateOperation(core) { setName(name); } virtual void backup() {} @@ -392,6 +394,45 @@ private slots: resource->close(); } + void testXmlDocumentParsing() + { + PackageManagerCore core; + core.setValue(scTargetDir, QLatin1String("relocatable_targetdir")); + + TestOperation op(QLatin1String("Operation 3"), &core); + QStringList stringListValue = (QStringList() << QLatin1String("list_value1") << QLatin1String("list_value2")); + op.setValue(QLatin1String("string_list"), stringListValue); + + const QString stringValue = core.value(scTargetDir) + QLatin1String(", string_value1"); + op.setValue(QLatin1String("string"), stringValue); + + QVariantMap map; + map.insert(QLatin1String("key1"), 1); + map.insert(QLatin1String("key2"), QLatin1String("map_value2")); + op.setValue(QLatin1String("variant_map"), map); + + QDomDocument document = op.toXml(); + QVERIFY2(document.toString().contains(QLatin1String("@RELOCATABLE_PATH@")), + "TargetDir not replaced with @RELOCATABLE_PATH@"); + + op.fromXml(document); // Resets the operation values from written QDomDocuments + + QCOMPARE(op.value(QLatin1String("string_list")), stringListValue); + QVERIFY2(!op.value(QLatin1String("string")).toString().contains(QLatin1String("@RELOCATABLE_PATH@")), + "@RELOCATABLE@ not replaced with TargetDir"); + QCOMPARE(op.value(QLatin1String("variant_map")), map); + +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + QCOMPARE(op.value(QLatin1String("string_list")).metaType().id(), QMetaType::QStringList); + QCOMPARE(op.value(QLatin1String("string")).metaType().id(), QMetaType::QString); + QCOMPARE(op.value(QLatin1String("variant_map")).metaType().id(), QMetaType::QVariantMap); +#else + QCOMPARE(op.value(QLatin1String("string_list")).type(), QMetaType::QStringList); + QCOMPARE(op.value(QLatin1String("string")).type(), QMetaType::QString); + QCOMPARE(op.value(QLatin1String("variant_map")).type(), QMetaType::QVariantMap); +#endif + } + void cleanupTestCase() { m_manager.clear(); diff --git a/tests/auto/installer/brokeninstaller/tst_brokeninstaller.cpp b/tests/auto/installer/brokeninstaller/tst_brokeninstaller.cpp index 95f4ac77d..5978b3bb2 100644 --- a/tests/auto/installer/brokeninstaller/tst_brokeninstaller.cpp +++ b/tests/auto/installer/brokeninstaller/tst_brokeninstaller.cpp @@ -1,6 +1,6 @@ /************************************************************************** ** -** Copyright (C) 2018 The Qt Company Ltd. +** Copyright (C) 2023 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Installer Framework. @@ -100,7 +100,7 @@ private slots: QList<Component*> rootComponents = loadComponents(core); ComponentModel *model = new ComponentModel(1, &core); - model->setRootComponents(rootComponents); + model->reset(rootComponents); // all names should be resolvable QStringList all; all << m_checkedComponentsWithBrokenScript << m_uncheckedComponentsWithBrokenScript << m_partiallyCheckedComponentsWithBrokenScript; @@ -125,9 +125,9 @@ private slots: const QString debugMessage = QString("Exception while loading the component script"); const QRegularExpression re(debugMessage); QTest::ignoreMessage(QtWarningMsg, re); - invalidScriptComponent->loadComponentScript(":///data/broken_script.qs"); + invalidScriptComponent->evaluateComponentScript(":///data/broken_script.qs"); - model->setRootComponents(components); + model->reset(components); testModelState(model, m_checkedComponentsWithBrokenScript, m_partiallyCheckedComponentsWithBrokenScript, m_uncheckedComponentsWithBrokenScript); } @@ -145,8 +145,8 @@ private slots: Component *componentDependingOnMissingDependency = core.componentByName("componentd"); componentDependingOnMissingDependency->addDependency("componentmissingdependency"); - core.componentsToInstallNeedsRecalculation(); - model->setRootComponents(components); + core.recalculateAllComponents(); + model->reset(components); testModelState(model, m_checkedComponentsWithMissingDependency, m_partiallyCheckedComponentsWithBrokenScript, m_uncheckedComponentsWithMissingDependency); } @@ -157,6 +157,7 @@ private: { UpdatesInfo updatesInfo; updatesInfo.setFileName(":///data/updates.xml"); + updatesInfo.parseFile(); const QList<UpdateInfo> updateInfos = updatesInfo.updatesInfo(); QList <Component*> components; diff --git a/tests/auto/installer/clientserver/tst_clientserver.cpp b/tests/auto/installer/clientserver/tst_clientserver.cpp index b3e220c9f..7b3e65c4a 100644 --- a/tests/auto/installer/clientserver/tst_clientserver.cpp +++ b/tests/auto/installer/clientserver/tst_clientserver.cpp @@ -1,6 +1,6 @@ /************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2022 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Installer Framework. @@ -26,12 +26,20 @@ ** **************************************************************************/ +#include "../shared/verifyinstaller.h" +#include "../shared/packagemanager.h" + #include <protocol.h> #include <qprocesswrapper.h> #include <qsettingswrapper.h> #include <remoteclient.h> #include <remotefileengine.h> #include <remoteserver.h> +#include <fileutils.h> + +#ifdef IFW_LIBARCHIVE +#include <libarchivewrapper_p.h> +#endif #include <QBuffer> #include <QSettings> @@ -44,6 +52,17 @@ using namespace QInstaller; +class MyRemoteObject : public RemoteObject +{ +public: + MyRemoteObject() + : RemoteObject(QLatin1String("MyRemoteObject")) {}; + + ~MyRemoteObject() = default; + + bool connectToServer() { return RemoteObject::connectToServer(); } +}; + class tst_ClientServer : public QObject { Q_OBJECT @@ -71,7 +90,7 @@ private: } private slots: - void initTestCase() + void init() { RemoteClient::instance().setActive(true); } @@ -153,44 +172,42 @@ private slots: const QByteArray message(10905, '0'); QLocalServer server; - { // server - QLocalSocket *rcv = 0; - auto srvDataArrived = [&]() { - QByteArray command, message; - if (!receivePacket(rcv, &command, &message)) - return; - sendPacket(rcv, command, message); - }; - - connect(&server, &QLocalServer::newConnection, [&,srvDataArrived]() { - rcv = server.nextPendingConnection(); - connect(rcv, &QLocalSocket::readyRead, srvDataArrived); - }); + // server + QLocalSocket *rcv = 0; + auto srvDataArrived = [&]() { + QByteArray command, message; + if (!receivePacket(rcv, &command, &message)) + return; + sendPacket(rcv, command, message); + }; - server.listen(socketName); - } + connect(&server, &QLocalServer::newConnection, [&,srvDataArrived]() { + rcv = server.nextPendingConnection(); + connect(rcv, &QLocalSocket::readyRead, srvDataArrived); + }); + + server.listen(socketName); QLocalSocket snd; - { // client - auto clientDataArrived = [&]() { - QByteArray cmd, msg; - if (!receivePacket(&snd, &cmd, &msg)) - return; - QCOMPARE(cmd, command); - QCOMPARE(msg, message); - loop.exit(); - }; - - connect(&snd, &QLocalSocket::readyRead, clientDataArrived); - - QTimer::singleShot(0, [&]() { - snd.connect(&snd, &QLocalSocket::connected, [&](){ - sendPacket(&snd, command, message); - }); - snd.connectToServer(socketName); + // client + auto clientDataArrived = [&]() { + QByteArray cmd, msg; + if (!receivePacket(&snd, &cmd, &msg)) + return; + QCOMPARE(cmd, command); + QCOMPARE(msg, message); + loop.exit(); + }; + + connect(&snd, &QLocalSocket::readyRead, clientDataArrived); + + QTimer::singleShot(0, [&]() { + snd.connect(&snd, &QLocalSocket::connected, [&](){ + sendPacket(&snd, command, message); }); - } + snd.connectToServer(socketName); + }); loop.exec(); } @@ -264,8 +281,48 @@ private slots: } } + void testCreateDestroyRemoteObject() + { + RemoteServer server; + QString socketName = QUuid::createUuid().toString(); + server.init(socketName, QLatin1String("SomeKey"), Protocol::Mode::Production); + server.start(); + + RemoteClient::instance().init(socketName, QLatin1String("SomeKey"), Protocol::Mode::Debug, + Protocol::StartAs::User); + + // Look for warnings on connection and disconnection.. + qInstallMessageHandler(exitOnWarningMessageHandler); + + MyRemoteObject *object = new MyRemoteObject; + QVERIFY(!object->isConnectedToServer()); + delete object; + + object = new MyRemoteObject; + QVERIFY(object->connectToServer()); + QVERIFY(object->isConnectedToServer()); + delete object; + + object = new MyRemoteObject; + QVERIFY(object->connectToServer()); + QVERIFY(object->isConnectedToServer()); + + RemoteClient::instance().setActive(false); + QVERIFY(!object->isConnectedToServer()); + delete object; + } + + void testQSettingsWrapper_data() + { + QTest::addColumn<QSettings::Format>("format"); + QTest::newRow("Native format") << QSettings::NativeFormat; + QTest::newRow("INI format") << QSettings::IniFormat; + } + void testQSettingsWrapper() { + QFETCH(QSettings::Format, format); + RemoteServer server; QString socketName = QUuid::createUuid().toString(); server.init(socketName, QLatin1String("SomeKey"), Protocol::Mode::Production); @@ -274,14 +331,15 @@ private slots: RemoteClient::instance().init(socketName, QLatin1String("SomeKey"), Protocol::Mode::Debug, Protocol::StartAs::User); - QSettingsWrapper wrapper("digia", "clientserver"); + QSettingsWrapper wrapper(format, QSettingsWrapper::UserScope, "digia", "clientserver"); + QCOMPARE(wrapper.isConnectedToServer(), false); wrapper.clear(); QCOMPARE(wrapper.isConnectedToServer(), true); wrapper.sync(); wrapper.setFallbacksEnabled(false); - QSettings settings("digia", "clientserver"); + QSettings settings(format, QSettings::UserScope, "digia", "clientserver"); settings.setFallbacksEnabled(false); QCOMPARE(settings.fileName(), wrapper.fileName()); @@ -310,6 +368,29 @@ private slots: QCOMPARE(wrapper.contains("key"), false); QCOMPARE(settings.contains("key"), false); + const QDateTime dateTime = QDateTime::currentDateTimeUtc(); + // The wrapper does not support this method, but assume: + // QCOMPARE(wrapper.iniCodec(), QTextCodec::codecForName("UTF-8")); + wrapper.setValue("dateTime", dateTime); + wrapper.sync(); + QCOMPARE(wrapper.value("dateTime").toDateTime(), dateTime); + QCOMPARE(settings.value("dateTime").toDateTime(), dateTime); + + wrapper.remove("dateTime"); + wrapper.sync(); + QCOMPARE(wrapper.contains("dateTime"), false); + QCOMPARE(settings.contains("dateTime"), false); + + settings.setValue("dateTime", dateTime); + settings.sync(); + QCOMPARE(wrapper.value("dateTime").toDateTime(), dateTime); + QCOMPARE(settings.value("dateTime").toDateTime(), dateTime); + + settings.remove("dateTime"); + settings.sync(); + QCOMPARE(wrapper.contains("dateTime"), false); + QCOMPARE(settings.contains("dateTime"), false); + wrapper.beginGroup("group"); wrapper.setValue("key", "value"); wrapper.endGroup(); @@ -386,6 +467,9 @@ private slots: void testQProcessWrapper() { + #ifdef Q_OS_LINUX + QSKIP("This test failes in CI redhat"); + #endif RemoteServer server; QString socketName = QUuid::createUuid().toString(); server.init(socketName, QLatin1String("SomeKey"), Protocol::Mode::Production); @@ -503,7 +587,7 @@ private slots: QFile file; file.setFileName(filename); file.open(QIODevice::ReadWrite); - const QByteArray ba = file.readLine(); + file.readLine(); file.seek(0); QCOMPARE(file.atEnd(), false); @@ -515,6 +599,61 @@ private slots: QCOMPARE(file.atEnd(), true); } + void testArchiveWrapper_data() + { + QTest::addColumn<QString>("suffix"); + QTest::newRow("ZIP archive") << ".zip"; + QTest::newRow("uncompressed tar archive") << ".tar"; + QTest::newRow("gzip compressed tar archive") << ".tar.gz"; + QTest::newRow("bzip2 compressed tar archive") << ".tar.bz2"; + QTest::newRow("xz compressed tar archive") << ".tar.xz"; + QTest::newRow("7zip archive") << ".7z"; + } + + void testArchiveWrapper() + { +#ifndef IFW_LIBARCHIVE + QSKIP("Installer Framework built without libarchive support"); +#else + QFETCH(QString, suffix); + + const QString archiveName = generateTemporaryFileName() + suffix; + const QString targetName = QDir::tempPath() + "/tst_archivewrapper/"; + + QTemporaryFile source; + source.open(); + source.write("Source File"); + source.setAutoRemove(false); + + RemoteServer server; + QString socketName = QUuid::createUuid().toString(); + server.init(socketName, QLatin1String("SomeKey"), Protocol::Mode::Production); + server.start(); + + RemoteClient::instance().init(socketName, QLatin1String("SomeKey"), Protocol::Mode::Debug, + Protocol::StartAs::User); + + LibArchiveWrapperPrivate archive; + QCOMPARE(archive.isConnectedToServer(), false); + archive.setFilename(archiveName); + QCOMPARE(archive.isConnectedToServer(), true); + + QVERIFY(archive.open(QIODevice::ReadWrite)); + QVERIFY(archive.create(QStringList() << source.fileName())); + QVERIFY(QFileInfo::exists(archiveName)); + + QVERIFY(archive.extract(targetName, 1)); + const QString sourceFilename = QFileInfo(source.fileName()).fileName(); + QVERIFY(QFileInfo::exists(targetName + sourceFilename)); + VerifyInstaller::verifyFileContent(targetName + sourceFilename, source.readAll()); + archive.close(); + + QVERIFY(source.remove()); + QVERIFY(QFile::remove(archiveName)); + removeDirectory(targetName); +#endif + } + void cleanupTestCase() { RemoteClient::instance().setActive(false); diff --git a/tests/auto/installer/commandlineinstall/commandlineinstall.pro b/tests/auto/installer/commandlineinstall/commandlineinstall.pro new file mode 100644 index 000000000..891830a97 --- /dev/null +++ b/tests/auto/installer/commandlineinstall/commandlineinstall.pro @@ -0,0 +1,9 @@ +include(../../qttest.pri) + +QT += qml + +SOURCES += tst_commandlineinstall.cpp + +RESOURCES += \ + settings.qrc \ + ../shared/config.qrc diff --git a/tests/auto/installer/commandlineinstall/data/components.xml b/tests/auto/installer/commandlineinstall/data/components.xml new file mode 100644 index 000000000..d5102787f --- /dev/null +++ b/tests/auto/installer/commandlineinstall/data/components.xml @@ -0,0 +1,24 @@ +<Packages> + <ApplicationName>Online Installer Example</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Package> + <Name>A</Name> + <Title>A Title</Title> + <Description>Example component A</Description> + <Version>1.0.2-1</Version> + <LastUpdateDate></LastUpdateDate> + <InstallDate>2020-02-13</InstallDate> + <Size>74</Size> + <Checkable>true</Checkable> + </Package> + <Package> + <Name>B</Name> + <Title>B Title</Title> + <Description>Example component B</Description> + <Version>1.0.0-1</Version> + <LastUpdateDate></LastUpdateDate> + <InstallDate>2020-02-13</InstallDate> + <Size>74</Size> + <Checkable>true</Checkable> + </Package> +</Packages>
\ No newline at end of file diff --git a/tests/auto/installer/commandlineinstall/data/componentsFromInstallPackagesRepository.xml b/tests/auto/installer/commandlineinstall/data/componentsFromInstallPackagesRepository.xml new file mode 100644 index 000000000..18d6f11c3 --- /dev/null +++ b/tests/auto/installer/commandlineinstall/data/componentsFromInstallPackagesRepository.xml @@ -0,0 +1,160 @@ +<Packages> + <ApplicationName>Dependency Solving Example</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Package> + <Name>componentA</Name> + <Title>Component A</Title> + <Description>This component does not depend on any other component.</Description> + <Version>1.0.0</Version> + <LastUpdateDate></LastUpdateDate> + <InstallDate>2020-03-23</InstallDate> + <Size>158</Size> + <Checkable>true</Checkable> + </Package> + <Package> + <Name>componentB</Name> + <Title>Component B</Title> + <Description>This component does not depend on any other component.</Description> + <Version>1.0.0</Version> + <LastUpdateDate></LastUpdateDate> + <InstallDate>2020-03-23</InstallDate> + <Size>99</Size> + <Checkable>true</Checkable> + </Package> + <Package> + <Name>componentC</Name> + <Title>Component C (depends on A and B)</Title> + <Description>This component depends on Component A and Component B. Selecting this component for installation also marks Component A and Component B for installation, which in turn marks Component D, because it has an automatic dependency on Component A and Component B.</Description> + <Version>1.0.0</Version> + <LastUpdateDate></LastUpdateDate> + <InstallDate>2020-03-23</InstallDate> + <Size>99</Size> + <Dependencies>componentA,componentB</Dependencies> + <Checkable>true</Checkable> + </Package> + <Package> + <Name>componentD</Name> + <Title>Component D (auto depends on A and B)</Title> + <Description>This component has an automatic dependency on Component A and Component B. If both A and B are marked for installation, this component is also installed.</Description> + <Version>1.0.0</Version> + <LastUpdateDate></LastUpdateDate> + <InstallDate>2020-03-23</InstallDate> + <Size>99</Size> + <AutoDependOn>componentA,componentB</AutoDependOn> + <Checkable>true</Checkable> + </Package> + <Package> + <Name>componentE</Name> + <Title>Component E (forced)</Title> + <Description>This is a forced component that is always installed.</Description> + <Version>1.0.0</Version> + <LastUpdateDate></LastUpdateDate> + <InstallDate>2020-03-23</InstallDate> + <Size>99</Size> + <ForcedInstallation>true</ForcedInstallation> + </Package> + <Package> + <Name>componentF</Name> + <Title>Component F</Title> + <Description>This component contains 2 subcomponents.</Description> + <Version>1.0.0</Version> + <LastUpdateDate></LastUpdateDate> + <InstallDate>2020-03-23</InstallDate> + <Size>99</Size> + <Checkable>true</Checkable> + </Package> + <Package> + <Name>componentF.subcomponent1</Name> + <Title>Subcomponent 1</Title> + <Description>This component contains 2 leaf components.</Description> + <Version>1.0.0</Version> + <LastUpdateDate></LastUpdateDate> + <InstallDate>2020-03-23</InstallDate> + <Size>99</Size> + <Checkable>true</Checkable> + </Package> + <Package> + <Name>componentF.subcomponent1.subsubcomponent1</Name> + <Title>Subsubcomponent 1</Title> + <Description>This component does not depend on any other component.</Description> + <Version>1.0.0</Version> + <LastUpdateDate></LastUpdateDate> + <InstallDate>2020-03-23</InstallDate> + <Size>99</Size> + <Checkable>true</Checkable> + </Package> + <Package> + <Name>componentF.subcomponent1.subsubcomponent2</Name> + <Title>Subsubcomponent 2</Title> + <Description>This component does not depend on any other component.</Description> + <Version>1.0.0</Version> + <LastUpdateDate></LastUpdateDate> + <InstallDate>2020-03-23</InstallDate> + <Size>99</Size> + <Checkable>true</Checkable> + </Package> + <Package> + <Name>componentF.subcomponent2</Name> + <Title>Subcomponent 2</Title> + <Description>This component contains 2 leaf components.</Description> + <Version>1.0.0</Version> + <LastUpdateDate></LastUpdateDate> + <InstallDate>2020-03-23</InstallDate> + <Size>99</Size> + <Checkable>true</Checkable> + </Package> + <Package> + <Name>componentF.subcomponent2.subsubcomponent1</Name> + <Title>Subsubcomponent 1</Title> + <Description>This component does not depend on any other component.</Description> + <Version>1.0.0</Version> + <LastUpdateDate></LastUpdateDate> + <InstallDate>2020-03-23</InstallDate> + <Size>99</Size> + <Checkable>true</Checkable> + </Package> + <Package> + <Name>componentF.subcomponent2.subsubcomponent2</Name> + <Title>Subsubcomponent 2</Title> + <Description>This component does not depend on any other component.</Description> + <Version>1.0.0</Version> + <LastUpdateDate></LastUpdateDate> + <InstallDate>2020-03-23</InstallDate> + <Size>99</Size> + <Checkable>true</Checkable> + </Package> + <Package> + <Name>componentG</Name> + <Title>Component G (default, depends on A, dependency added dynamically)</Title> + <Description>By default, this component is selected for installation. It depends on component A. Dependency is added from inside component script.</Description> + <Version>1.0.0</Version> + <LastUpdateDate></LastUpdateDate> + <InstallDate>2020-03-23</InstallDate> + <Size>99</Size> + <Dependencies>componentA</Dependencies> + <Checkable>true</Checkable> + </Package> + <Package> + <Name>componentH</Name> + <Title>Component H</Title> + <Description>This component does not depend on any other component.</Description> + <Version>1.0.0</Version> + <LastUpdateDate></LastUpdateDate> + <InstallDate>2020-03-23</InstallDate> + <Size>99</Size> + <Virtual>true</Virtual> + <Checkable>true</Checkable> + </Package> + <Package> + <Name>componentI</Name> + <Title>Component I</Title> + <Description>This component has an automatic dependency on Component C. If C is marked for installation, this component is also installed.</Description> + <Version>1.0.0</Version> + <LastUpdateDate></LastUpdateDate> + <InstallDate>2020-03-23</InstallDate> + <Size>99</Size> + <AutoDependOn>componentC</AutoDependOn> + <Virtual>true</Virtual> + <Checkable>true</Checkable> + </Package> +</Packages> diff --git a/tests/auto/installer/commandlineinstall/data/config.xml b/tests/auto/installer/commandlineinstall/data/config.xml new file mode 100644 index 000000000..041ce5062 --- /dev/null +++ b/tests/auto/installer/commandlineinstall/data/config.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Installer> + <Name>Your application</Name> + <Version>1.2.3</Version> + <MaintenanceToolName></MaintenanceToolName> + <MaintenanceToolIniFile></MaintenanceToolIniFile> + <TargetConfigurationFile></TargetConfigurationFile> +</Installer> diff --git a/tests/auto/installer/commandlineinstall/data/filequeryrepository/A/1.0.2-1meta.7z b/tests/auto/installer/commandlineinstall/data/filequeryrepository/A/1.0.2-1meta.7z Binary files differnew file mode 100644 index 000000000..0b0b6ade6 --- /dev/null +++ b/tests/auto/installer/commandlineinstall/data/filequeryrepository/A/1.0.2-1meta.7z diff --git a/tests/auto/installer/commandlineinstall/data/filequeryrepository/Updates.xml b/tests/auto/installer/commandlineinstall/data/filequeryrepository/Updates.xml new file mode 100644 index 000000000..7957cde4e --- /dev/null +++ b/tests/auto/installer/commandlineinstall/data/filequeryrepository/Updates.xml @@ -0,0 +1,15 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>A component</Description> + <Version>1.0.2-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <Script>script.qs</Script> + <SHA1>4b124046df83fcd12fb7126b795a8b5a62602806</SHA1> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/commandlineinstall/data/installPackagesDependencyChanged/Updates.xml b/tests/auto/installer/commandlineinstall/data/installPackagesDependencyChanged/Updates.xml new file mode 100644 index 000000000..72931954a --- /dev/null +++ b/tests/auto/installer/commandlineinstall/data/installPackagesDependencyChanged/Updates.xml @@ -0,0 +1,72 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>componentA</Name> + <DisplayName>Component A</DisplayName> + <Description>New dependency added</Description> + <Version>2.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>100</SortingPriority> + <UpdateFile OS="Any" CompressedSize="299" UncompressedSize="158"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>92b02a74d0886bc1569ff8b3a7edd1f9d828e56c</SHA1> + <Dependencies>componentF</Dependencies> + </PackageUpdate> + <PackageUpdate> + <Name>componentB</Name> + <DisplayName>Component B</DisplayName> + <Description>This component does not depend on any other component.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>90</SortingPriority> + <UpdateFile OS="Any" CompressedSize="281" UncompressedSize="99"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>aedfaef53cdc0f52353a8680009be405fa767811</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentC</Name> + <DisplayName>Component C. Dependencies removed</DisplayName> + <Description>This component dependencies on Component A and Component B are removed in update.</Description> + <Dependencies></Dependencies> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>80</SortingPriority> + <UpdateFile OS="Any" CompressedSize="281" UncompressedSize="99"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>20b9463a5e06f373182b3c7c4cf879806d429409</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentD</Name> + <DisplayName>Component D (auto depends on A and B)</DisplayName> + <Description>This component has an automatic dependency on Component A and Component B. If both A and B are marked for installation, this component is also installed.</Description> + <AutoDependOn>componentA, componentB</AutoDependOn> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>70</SortingPriority> + <UpdateFile OS="Any" CompressedSize="281" UncompressedSize="99"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>99cf24c71559c75dfae9933826ed16051fca6ea1</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentF</Name> + <DisplayName>Component F</DisplayName> + <Description>This component contains 2 subcomponents.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>40</SortingPriority> + <UpdateFile OS="Any" CompressedSize="281" UncompressedSize="99"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>e6443a8b5a5651f63c0604cae6d32431ca617f1a</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentH</Name> + <Description>This component does not depend on any other component.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>50</SortingPriority> + <DownloadableArchives>content.7z</DownloadableArchives> + <Virtual>false</Virtual> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/commandlineinstall/data/installPackagesDependencyChanged/componentA/2.0.0content.7z b/tests/auto/installer/commandlineinstall/data/installPackagesDependencyChanged/componentA/2.0.0content.7z Binary files differnew file mode 100644 index 000000000..4ddbe565b --- /dev/null +++ b/tests/auto/installer/commandlineinstall/data/installPackagesDependencyChanged/componentA/2.0.0content.7z diff --git a/tests/auto/installer/commandlineinstall/data/installPackagesDependencyChanged/componentB/1.0.0content.7z b/tests/auto/installer/commandlineinstall/data/installPackagesDependencyChanged/componentB/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..f84ffcdc5 --- /dev/null +++ b/tests/auto/installer/commandlineinstall/data/installPackagesDependencyChanged/componentB/1.0.0content.7z diff --git a/tests/auto/installer/commandlineinstall/data/installPackagesDependencyChanged/componentC/1.0.0content.7z b/tests/auto/installer/commandlineinstall/data/installPackagesDependencyChanged/componentC/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..9ad11e06f --- /dev/null +++ b/tests/auto/installer/commandlineinstall/data/installPackagesDependencyChanged/componentC/1.0.0content.7z diff --git a/tests/auto/installer/commandlineinstall/data/installPackagesDependencyChanged/componentD/1.0.0content.7z b/tests/auto/installer/commandlineinstall/data/installPackagesDependencyChanged/componentD/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..0c8c52e31 --- /dev/null +++ b/tests/auto/installer/commandlineinstall/data/installPackagesDependencyChanged/componentD/1.0.0content.7z diff --git a/tests/auto/installer/commandlineinstall/data/installPackagesDependencyChanged/componentF/1.0.0content.7z b/tests/auto/installer/commandlineinstall/data/installPackagesDependencyChanged/componentF/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..4a04b1394 --- /dev/null +++ b/tests/auto/installer/commandlineinstall/data/installPackagesDependencyChanged/componentF/1.0.0content.7z diff --git a/tests/auto/installer/commandlineinstall/data/installPackagesDependencyChanged/componentH/1.0.0content.7z b/tests/auto/installer/commandlineinstall/data/installPackagesDependencyChanged/componentH/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..e1449ad29 --- /dev/null +++ b/tests/auto/installer/commandlineinstall/data/installPackagesDependencyChanged/componentH/1.0.0content.7z diff --git a/tests/auto/installer/commandlineinstall/data/installPackagesRepository/Updates.xml b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/Updates.xml new file mode 100644 index 000000000..3b5e22cc0 --- /dev/null +++ b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/Updates.xml @@ -0,0 +1,183 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>componentA</Name> + <DisplayName>Component A</DisplayName> + <Description>This component does not depend on any other component.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>100</SortingPriority> + <UpdateFile OS="Any" CompressedSize="299" UncompressedSize="158"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>92b02a74d0886bc1569ff8b3a7edd1f9d828e56c</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentB</Name> + <DisplayName>Component B</DisplayName> + <Description>This component does not depend on any other component.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>90</SortingPriority> + <UpdateFile OS="Any" CompressedSize="281" UncompressedSize="99"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>aedfaef53cdc0f52353a8680009be405fa767811</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentC</Name> + <DisplayName>Component C (depends on A and B)</DisplayName> + <Description>This component depends on Component A and Component B. Selecting this component for installation also marks Component A and Component B for installation, which in turn marks Component D, because it has an automatic dependency on Component A and Component B.</Description> + <Dependencies>componentA, componentB</Dependencies> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>80</SortingPriority> + <UpdateFile OS="Any" CompressedSize="281" UncompressedSize="99"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>20b9463a5e06f373182b3c7c4cf879806d429409</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentD</Name> + <DisplayName>Component D (auto depends on A and B)</DisplayName> + <Description>This component has an automatic dependency on Component A and Component B. If both A and B are marked for installation, this component is also installed.</Description> + <AutoDependOn>componentA, componentB</AutoDependOn> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>70</SortingPriority> + <UpdateFile OS="Any" CompressedSize="281" UncompressedSize="99"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>99cf24c71559c75dfae9933826ed16051fca6ea1</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentE</Name> + <DisplayName>Component E (forced)</DisplayName> + <Description>This is a forced component that is always installed.</Description> + <ForcedInstallation>true</ForcedInstallation> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>60</SortingPriority> + <UpdateFile OS="Any" CompressedSize="281" UncompressedSize="99"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>926bf503ccdff93351744843a95e5e2172cad5ec</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentF</Name> + <DisplayName>Component F</DisplayName> + <Description>This component contains 2 subcomponents.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>40</SortingPriority> + <UpdateFile OS="Any" CompressedSize="281" UncompressedSize="99"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>e6443a8b5a5651f63c0604cae6d32431ca617f1a</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentF.subcomponent1</Name> + <DisplayName>Subcomponent 1</DisplayName> + <Description>This component contains 2 leaf components.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>100</SortingPriority> + <UpdateFile OS="Any" CompressedSize="281" UncompressedSize="99"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>a3bc5dce1c93add30c22e46436396c66b0b51001</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentF.subcomponent1.subsubcomponent1</Name> + <DisplayName>Subsubcomponent 1</DisplayName> + <Description>This component does not depend on any other component.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>100</SortingPriority> + <UpdateFile OS="Any" CompressedSize="289" UncompressedSize="99"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>ebe4d69414a1675a7f46887e15d9bffc275b7cc4</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentF.subcomponent1.subsubcomponent2</Name> + <DisplayName>Subsubcomponent 2</DisplayName> + <Description>This component does not depend on any other component.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>50</SortingPriority> + <UpdateFile OS="Any" CompressedSize="289" UncompressedSize="99"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>e4379d20320d4c173b2d8e228f5722e3f36e3114</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentF.subcomponent2</Name> + <DisplayName>Subcomponent 2</DisplayName> + <Description>This component contains 2 leaf components.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>50</SortingPriority> + <UpdateFile OS="Any" CompressedSize="281" UncompressedSize="99"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>6462be25912c490569a7c4f3931d978e78c69dc4</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentF.subcomponent2.subsubcomponent1</Name> + <DisplayName>Subsubcomponent 1</DisplayName> + <Description>This component does not depend on any other component.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>100</SortingPriority> + <UpdateFile OS="Any" CompressedSize="289" UncompressedSize="99"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>72b224bc8f3431210834ce6db373fc8d638a3546</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentF.subcomponent2.subsubcomponent2</Name> + <DisplayName>Subsubcomponent 2</DisplayName> + <Description>This component does not depend on any other component.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>50</SortingPriority> + <UpdateFile OS="Any" CompressedSize="289" UncompressedSize="99"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>3e2744edaef06af75b3248d5935523a6e2e61551</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentG</Name> + <DisplayName>Component G (default, depends on A, dependency added dynamically)</DisplayName> + <Description>By default, this component is selected for installation. It depends on component A. Dependency is added from inside component script.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <Script>installscript.js</Script> + <SortingPriority>30</SortingPriority> + <UpdateFile OS="Any" CompressedSize="281" UncompressedSize="99"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>8cba36dd589492c28e0d04942b4f8aa0a09f59cc</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentH</Name> + <DisplayName>component H</DisplayName> + <Description>This component does not depend on any other component.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>50</SortingPriority> + <DownloadableArchives>content.7z</DownloadableArchives> + <Virtual>true</Virtual> + </PackageUpdate> + <PackageUpdate> + <Name>componentI</Name> + <DisplayName>component I</DisplayName> + <Description>This component has an automatic dependency on Component C. If C is marked for installation, this component is also installed.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>50</SortingPriority> + <AutoDependOn>componentC</AutoDependOn> + <DownloadableArchives>content.7z</DownloadableArchives> + <Virtual>true</Virtual> + </PackageUpdate> + <PackageUpdate> + <Name>componentJ</Name> + <DisplayName>component J</DisplayName> + <Description>This component has post install script.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>50</SortingPriority> + <DownloadableArchives>content.7z</DownloadableArchives> + <Script postLoad="True">postLoadscript.js</Script> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentA/1.0.0content.7z b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentA/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..4ddbe565b --- /dev/null +++ b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentA/1.0.0content.7z diff --git a/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentB/1.0.0content.7z b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentB/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..f84ffcdc5 --- /dev/null +++ b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentB/1.0.0content.7z diff --git a/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentC/1.0.0content.7z b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentC/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..9ad11e06f --- /dev/null +++ b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentC/1.0.0content.7z diff --git a/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentD/1.0.0content.7z b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentD/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..0c8c52e31 --- /dev/null +++ b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentD/1.0.0content.7z diff --git a/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentE/1.0.0content.7z b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentE/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..f5abacf81 --- /dev/null +++ b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentE/1.0.0content.7z diff --git a/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentF.subcomponent1.subsubcomponent1/1.0.0content.7z b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentF.subcomponent1.subsubcomponent1/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..3aced680f --- /dev/null +++ b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentF.subcomponent1.subsubcomponent1/1.0.0content.7z diff --git a/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentF.subcomponent1.subsubcomponent2/1.0.0content.7z b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentF.subcomponent1.subsubcomponent2/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..e5385a163 --- /dev/null +++ b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentF.subcomponent1.subsubcomponent2/1.0.0content.7z diff --git a/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentF.subcomponent1/1.0.0content.7z b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentF.subcomponent1/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..5bc549863 --- /dev/null +++ b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentF.subcomponent1/1.0.0content.7z diff --git a/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentF.subcomponent2.subsubcomponent1/1.0.0content.7z b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentF.subcomponent2.subsubcomponent1/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..da9e9f340 --- /dev/null +++ b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentF.subcomponent2.subsubcomponent1/1.0.0content.7z diff --git a/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentF.subcomponent2.subsubcomponent2/1.0.0content.7z b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentF.subcomponent2.subsubcomponent2/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..d0b013706 --- /dev/null +++ b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentF.subcomponent2.subsubcomponent2/1.0.0content.7z diff --git a/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentF.subcomponent2/1.0.0content.7z b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentF.subcomponent2/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..74ab44033 --- /dev/null +++ b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentF.subcomponent2/1.0.0content.7z diff --git a/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentF/1.0.0content.7z b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentF/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..4a04b1394 --- /dev/null +++ b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentF/1.0.0content.7z diff --git a/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentG/1.0.0content.7z b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentG/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..81fc02052 --- /dev/null +++ b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentG/1.0.0content.7z diff --git a/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentG/1.0.0meta.7z b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentG/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..90bfe33a2 --- /dev/null +++ b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentG/1.0.0meta.7z diff --git a/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentH/1.0.0content.7z b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentH/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..e1449ad29 --- /dev/null +++ b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentH/1.0.0content.7z diff --git a/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentI/1.0.0content.7z b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentI/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..651a29f94 --- /dev/null +++ b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentI/1.0.0content.7z diff --git a/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentJ/1.0.0content.7z b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentJ/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..58ff52baa --- /dev/null +++ b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentJ/1.0.0content.7z diff --git a/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentJ/1.0.0meta.7z b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentJ/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..be99410a8 --- /dev/null +++ b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentJ/1.0.0meta.7z diff --git a/tests/auto/installer/commandlineinstall/data/repository/Updates.xml b/tests/auto/installer/commandlineinstall/data/repository/Updates.xml new file mode 100644 index 000000000..52707d09d --- /dev/null +++ b/tests/auto/installer/commandlineinstall/data/repository/Updates.xml @@ -0,0 +1,69 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>true</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.2-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <UpdateFile CompressedSize="222" OS="Any" UncompressedSize="72"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>9d54e3a5adf3563913feee8ba23a99fb80d46590</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>B</Name> + <DisplayName>B</DisplayName> + <Description>Example component B</Description> + <Version>1.0.0-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>false</Default> + <UpdateFile CompressedSize="222" OS="Any" UncompressedSize="72"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>9170d55a6af81c1a6a63d708a4ab6ed359775cd9</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>C</Name> + <DisplayName>C</DisplayName> + <Description>Example component C</Description> + <Version>1.0.0-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <UpdateFile CompressedSize="222" OS="Any" UncompressedSize="72"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>5b3939da1af492382c68388fc796837e4c36b876</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>C.virt</Name> + <DisplayName>Virtual subcomponent of C</DisplayName> + <Description>Example virtual component</Description> + <Version>1.0.0-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Virtual>true</Virtual> + <UpdateFile CompressedSize="222" OS="Any" UncompressedSize="72"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>5b3939da1af492382c68388fc796837e4c36b876</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>C.virt.subcomponent</Name> + <DisplayName>Subcomponent of virtual component</DisplayName> + <Description>Example subcomponent of virtual component</Description> + <Version>1.0.0-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <UpdateFile CompressedSize="222" OS="Any" UncompressedSize="72"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>5b3939da1af492382c68388fc796837e4c36b876</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>AB</Name> + <DisplayName>AB</DisplayName> + <Description>Example component AB</Description> + <Version>1.0.2-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <UpdateFile UncompressedSize="0" OS="Any" CompressedSize="0"/> + <SHA1>f75e65b1a0f68abb77fc41da08fc26dda5409a18</SHA1> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/commandlineinstall/data/uninstallableComponentsRepository/Updates.xml b/tests/auto/installer/commandlineinstall/data/uninstallableComponentsRepository/Updates.xml new file mode 100644 index 000000000..f0c724db8 --- /dev/null +++ b/tests/auto/installer/commandlineinstall/data/uninstallableComponentsRepository/Updates.xml @@ -0,0 +1,50 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>true</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>2.0.0</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <UpdateFile CompressedSize="224" OS="Any" UncompressedSize="74"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>c1f340c9a7ad1edbef4cb6288c83c646211e5ccd</SHA1> + <AutoDependOn>autoDep</AutoDependOn> + </PackageUpdate> + <PackageUpdate> + <Name>AB</Name> + <DisplayName>AB</DisplayName> + <Description>Example component AB</Description> + <Version>1.0.2-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <UpdateFile CompressedSize="0" OS="Any" UncompressedSize="0"/> + <SHA1>3c1470896a9db84092e00806b1303f3b5fa4f7ad</SHA1> + <Checkable>false</Checkable> + </PackageUpdate> + <PackageUpdate> + <Name>B</Name> + <DisplayName>B</DisplayName> + <Description>Example component B</Description> + <Version>2.0.0</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <UpdateFile CompressedSize="224" OS="Any" UncompressedSize="74"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>cfa136fa1d7a4196896c90af72d510727ba799ae</SHA1> + <Virtual>true</Virtual> + </PackageUpdate> + <PackageUpdate> + <Name>B.subcomponent</Name> + <DisplayName>Subcomponent of B</DisplayName> + <Description>Example non-virtual subcomponent of B</Description> + <Version>2.0.0</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <UpdateFile CompressedSize="224" OS="Any" UncompressedSize="74"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>cfa136fa1d7a4196896c90af72d510727ba799ae</SHA1> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/commandlineinstall/settings.qrc b/tests/auto/installer/commandlineinstall/settings.qrc new file mode 100644 index 000000000..992dbfd58 --- /dev/null +++ b/tests/auto/installer/commandlineinstall/settings.qrc @@ -0,0 +1,37 @@ +<RCC> + <qresource prefix="/"> + <file>data/config.xml</file> + <file>data/repository/Updates.xml</file> + <file>data/uninstallableComponentsRepository/Updates.xml</file> + <file>data/components.xml</file> + <file>data/installPackagesRepository/Updates.xml</file> + <file>data/installPackagesRepository/componentA/1.0.0content.7z</file> + <file>data/installPackagesRepository/componentB/1.0.0content.7z</file> + <file>data/installPackagesRepository/componentC/1.0.0content.7z</file> + <file>data/installPackagesRepository/componentD/1.0.0content.7z</file> + <file>data/installPackagesRepository/componentE/1.0.0content.7z</file> + <file>data/installPackagesRepository/componentF/1.0.0content.7z</file> + <file>data/installPackagesRepository/componentG/1.0.0content.7z</file> + <file>data/installPackagesRepository/componentH/1.0.0content.7z</file> + <file>data/installPackagesRepository/componentI/1.0.0content.7z</file> + <file>data/installPackagesRepository/componentJ/1.0.0content.7z</file> + <file>data/installPackagesRepository/componentJ/1.0.0meta.7z</file> + <file>data/installPackagesRepository/componentG/1.0.0meta.7z</file> + <file>data/installPackagesRepository/componentF.subcomponent1/1.0.0content.7z</file> + <file>data/installPackagesRepository/componentF.subcomponent2/1.0.0content.7z</file> + <file>data/installPackagesRepository/componentF.subcomponent1.subsubcomponent1/1.0.0content.7z</file> + <file>data/installPackagesRepository/componentF.subcomponent1.subsubcomponent2/1.0.0content.7z</file> + <file>data/installPackagesRepository/componentF.subcomponent2.subsubcomponent1/1.0.0content.7z</file> + <file>data/installPackagesRepository/componentF.subcomponent2.subsubcomponent2/1.0.0content.7z</file> + <file>data/installPackagesDependencyChanged/Updates.xml</file> + <file>data/installPackagesDependencyChanged/componentA/2.0.0content.7z</file> + <file>data/installPackagesDependencyChanged/componentB/1.0.0content.7z</file> + <file>data/installPackagesDependencyChanged/componentC/1.0.0content.7z</file> + <file>data/installPackagesDependencyChanged/componentD/1.0.0content.7z</file> + <file>data/installPackagesDependencyChanged/componentF/1.0.0content.7z</file> + <file>data/installPackagesDependencyChanged/componentH/1.0.0content.7z</file> + <file>data/filequeryrepository/Updates.xml</file> + <file>data/filequeryrepository/A/1.0.2-1meta.7z</file> + <file>data/componentsFromInstallPackagesRepository.xml</file> + </qresource> +</RCC> diff --git a/tests/auto/installer/commandlineinstall/tst_commandlineinstall.cpp b/tests/auto/installer/commandlineinstall/tst_commandlineinstall.cpp new file mode 100644 index 000000000..4dfadbad6 --- /dev/null +++ b/tests/auto/installer/commandlineinstall/tst_commandlineinstall.cpp @@ -0,0 +1,813 @@ +/************************************************************************** +** +** Copyright (C) 2024 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ +#include "../shared/packagemanager.h" +#include "../shared/verifyinstaller.h" + +#include <component.h> +#include <packagemanagercore.h> + +#include <QLoggingCategory> +#include <QTest> +#include <QRegularExpression> +#include <QSignalSpy> + +using namespace QInstaller; + +typedef QList<QPair<QString, QString> > ComponentResourceHash; +typedef QPair<QString, QString> ComponentResource; + +class tst_CommandLineInstall : public QObject +{ + Q_OBJECT + +public: + void ignoreAvailablePackagesMissingMessages() + { + QTest::ignoreMessage(QtDebugMsg, QRegularExpression("Searching packages with regular expression:")); + QTest::ignoreMessage(QtDebugMsg, "No matching packages found."); + } + + void ignoreInstallPackageFailsMessages(const QRegularExpression ®Exp) + { + QTest::ignoreMessage(QtDebugMsg, "Fetching latest update information..."); + QTest::ignoreMessage(QtDebugMsg, regExp); + } + +private slots: + void testListAvailablePackages() + { + QString loggingRules = (QLatin1String("ifw.* = false\n")); + + QLoggingCategory::setFilterRules(loggingRules); + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManager + (m_installDir, ":///data/repository")); + + auto func = &PackageManagerCore::listAvailablePackages; + VerifyInstaller::verifyListPackagesMessage(core.get(), QLatin1String("<?xml version=\"1.0\"?>\n" + "<availablepackages>\n" + " <package name=\"AB\" displayname=\"AB\" version=\"1.0.2-1\"/>\n" + " <package name=\"A\" displayname=\"A\" version=\"1.0.2-1\"/>\n" + " <package name=\"B\" displayname=\"B\" version=\"1.0.0-1\"/>\n" + " <package name=\"C\" displayname=\"C\" version=\"1.0.0-1\"/>\n" + "</availablepackages>\n"), func, QLatin1String("."), QHash<QString, QString>()); + + VerifyInstaller::verifyListPackagesMessage(core.get(), QLatin1String("<?xml version=\"1.0\"?>\n" + "<availablepackages>\n" + " <package name=\"AB\" displayname=\"AB\" version=\"1.0.2-1\"/>\n" + " <package name=\"A\" displayname=\"A\" version=\"1.0.2-1\"/>\n" + "</availablepackages>\n"), func, QLatin1String("A"), QHash<QString, QString>()); + + VerifyInstaller::verifyListPackagesMessage(core.get(), QLatin1String("<?xml version=\"1.0\"?>\n" + "<availablepackages>\n" + " <package name=\"AB\" displayname=\"AB\" version=\"1.0.2-1\"/>\n" + " <package name=\"A\" displayname=\"A\" version=\"1.0.2-1\"/>\n" + "</availablepackages>\n"), func, QLatin1String("A.*"), QHash<QString, QString>()); + + VerifyInstaller::verifyListPackagesMessage(core.get(), QLatin1String("<?xml version=\"1.0\"?>\n" + "<availablepackages>\n" + " <package name=\"B\" displayname=\"B\" version=\"1.0.0-1\"/>\n" + "</availablepackages>\n"), func, QLatin1String("^B"), QHash<QString, QString>()); + + VerifyInstaller::verifyListPackagesMessage(core.get(), QLatin1String("<?xml version=\"1.0\"?>\n" + "<availablepackages>\n" + " <package name=\"B\" displayname=\"B\" version=\"1.0.0-1\"/>\n" + "</availablepackages>\n"), func, QLatin1String("^B.*"), QHash<QString, QString>()); + + VerifyInstaller::verifyListPackagesMessage(core.get(), QLatin1String("<?xml version=\"1.0\"?>\n" + "<availablepackages>\n" + " <package name=\"C\" displayname=\"C\" version=\"1.0.0-1\"/>\n" + "</availablepackages>\n"), func, QLatin1String("^C"), QHash<QString, QString>()); + + // Test with filters + QHash<QString, QString> searchHash { + { "Version", "1.0.2" }, + { "DisplayName", "A" } + }; + VerifyInstaller::verifyListPackagesMessage(core.get(), QLatin1String("<?xml version=\"1.0\"?>\n" + "<availablepackages>\n" + " <package name=\"AB\" displayname=\"AB\" version=\"1.0.2-1\"/>\n" + " <package name=\"A\" displayname=\"A\" version=\"1.0.2-1\"/>\n" + "</availablepackages>\n"), func, QString(), searchHash); + + searchHash.clear(); + searchHash.insert("Default", "false"); + VerifyInstaller::verifyListPackagesMessage(core.get(), QLatin1String("<?xml version=\"1.0\"?>\n" + "<availablepackages>\n" + " <package name=\"B\" displayname=\"B\" version=\"1.0.0-1\"/>\n" + "</availablepackages>\n"), func, QString(), searchHash); + + QLoggingCategory::setFilterRules("ifw.* = true\n"); + ignoreAvailablePackagesMissingMessages(); + core->listAvailablePackages(QLatin1String("C.virt")); + + ignoreAvailablePackagesMissingMessages(); + core->listAvailablePackages(QLatin1String("C.virt.subcomponent")); + } + + void testInstallPackageFails() + { + QString loggingRules = (QLatin1String("ifw.* = false\n" + "ifw.installer.installlog = true\n")); + + QLoggingCategory::setFilterRules(loggingRules); + QTest::ignoreMessage(QtDebugMsg, "Operations sanity check succeeded."); + QTest::ignoreMessage(QtDebugMsg, QRegularExpression("Using metadata cache from ")); + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManager + (m_installDir, ":///data/uninstallableComponentsRepository")); + + ignoreInstallPackageFailsMessages(QRegularExpression("Cannot install component A. Component " + "is installed only as automatic dependency to autoDep.\n")); + QCOMPARE(PackageManagerCore::Canceled, core->installSelectedComponentsSilently(QStringList() + << QLatin1String("A"))); + + ignoreInstallPackageFailsMessages(QRegularExpression("Cannot install component AB. Component " + "is not checkable, meaning you have to select one of the subcomponents.\n")); + QCOMPARE(PackageManagerCore::Canceled, core->installSelectedComponentsSilently(QStringList() + << QLatin1String("AB"))); + + ignoreInstallPackageFailsMessages(QRegularExpression("Cannot install B. Component is virtual.\n")); + QCOMPARE(PackageManagerCore::Canceled, core->installSelectedComponentsSilently(QStringList() + << QLatin1String("B"))); + + ignoreInstallPackageFailsMessages(QRegularExpression("Cannot install B.subcomponent. Component " + "is a descendant of a virtual component B.\n")); + QCOMPARE(PackageManagerCore::Canceled, core->installSelectedComponentsSilently(QStringList() + << QLatin1String("B.subcomponent"))); + + QCOMPARE(PackageManagerCore::Canceled, core->installSelectedComponentsSilently(QStringList() + << QLatin1String("MissingComponent"))); + QCOMPARE(PackageManagerCore::Canceled, core->status()); + } + + void testUninstallPackageFails() + { + QString loggingRules = (QLatin1String("ifw.installer.installog = true\n")); + PackageManagerCore core; + core.setPackageManager(); + QLoggingCategory::setFilterRules(loggingRules); + + QVERIFY(QFile::copy(":/data/componentsFromInstallPackagesRepository.xml", m_installDir + "/components.xml")); + + core.setValue(scTargetDir, m_installDir); + QTest::ignoreMessage(QtWarningMsg, "Cannot uninstall ForcedInstallation component componentE"); + QCOMPARE(PackageManagerCore::Success, core.uninstallComponentsSilently(QStringList() + << "componentE")); + + QTest::ignoreMessage(QtWarningMsg, "Cannot uninstall component componentD because it is added as auto dependency to componentA,componentB"); + QCOMPARE(PackageManagerCore::Success, core.uninstallComponentsSilently(QStringList() + << "componentD")); + + QTest::ignoreMessage(QtWarningMsg, "Cannot uninstall component MissingComponent. Component not found in install tree."); + QCOMPARE(PackageManagerCore::Success, core.uninstallComponentsSilently(QStringList() + << "MissingComponent")); + + QTest::ignoreMessage(QtWarningMsg, "Cannot uninstall virtual component componentH"); + QCOMPARE(PackageManagerCore::Success, core.uninstallComponentsSilently(QStringList() + << "componentH")); + + QCOMPARE(PackageManagerCore::Success, core.status()); + } + + void testListInstalledPackages() + { + QString loggingRules = (QLatin1String("ifw.* = false\n")); + PackageManagerCore core; + core.setPackageManager(); + QLoggingCategory::setFilterRules(loggingRules); + auto func = &PackageManagerCore::listInstalledPackages; + + const QString testDirectory = QInstaller::generateTemporaryFileName(); + QVERIFY(QDir().mkpath(testDirectory)); + QVERIFY(QFile::copy(":/data/components.xml", testDirectory + "/components.xml")); + + core.setValue(scTargetDir, testDirectory); + + VerifyInstaller::verifyListPackagesMessage(&core, QLatin1String("<?xml version=\"1.0\"?>\n" + "<localpackages>\n" + " <package name=\"A\" displayname=\"A Title\" version=\"1.0.2-1\"/>\n" + " <package name=\"B\" displayname=\"B Title\" version=\"1.0.0-1\"/>\n" + "</localpackages>\n"), func, QString()); + + VerifyInstaller::verifyListPackagesMessage(&core, QLatin1String("<?xml version=\"1.0\"?>\n" + "<localpackages>\n" + " <package name=\"A\" displayname=\"A Title\" version=\"1.0.2-1\"/>\n" + "</localpackages>\n"), func, QLatin1String("A")); + + QDir dir(testDirectory); + QVERIFY(dir.removeRecursively()); + } + + void testCategoryInstall_data() + { + QTest::addColumn<QString>("repository"); + QTest::addColumn<QStringList>("installComponents"); + QTest::addColumn<PackageManagerCore::Status>("status"); + + + QTest::newRow("Category installation") + << ":///data/installPackagesRepository" + << (QStringList() << "componentE") + << PackageManagerCore::Success; + } + + void testCategoryInstall() + { + QFETCH(QString, repository); + QFETCH(QStringList, installComponents); + QFETCH(PackageManagerCore::Status, status); + + + QString loggingRules = (QLatin1String("ifw.* = true\n")); + QLoggingCategory::setFilterRules(loggingRules); + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (m_installDir)); + + RepositoryCategory category; + category.setEnabled(false); + category.setDisplayName(QLatin1String("category")); + + Repository repo = Repository::fromUserInput(repository); + category.addRepository(repo); + + QSet<RepositoryCategory> categories; + categories.insert(category); + + core->settings().addRepositoryCategories(categories); + + QSignalSpy spy(core.data(), &PackageManagerCore::statusChanged); + QCOMPARE(core->installSelectedComponentsSilently(QStringList() << installComponents), status); + + QList<int> statusArguments; + + for (qsizetype i = 0; i < spy.size(); ++i) { + QList<QVariant> tempList = spy.at(i); + statusArguments << tempList.at(0).toInt(); + } + + QVERIFY(statusArguments.contains(PackageManagerCore::NoPackagesFound)); + QVERIFY(statusArguments.contains(PackageManagerCore::Success)); + } + + void testInstall_data() + { + QTest::addColumn<QString>("repository"); + QTest::addColumn<QStringList>("installComponents"); + QTest::addColumn<PackageManagerCore::Status>("status"); + QTest::addColumn<ComponentResourceHash>("componentResources"); + QTest::addColumn<QStringList >("installedFiles"); + + /*********** Forced installation **********/ + ComponentResourceHash componentResources; + componentResources.append(ComponentResource("componentA", "1.0.0content.txt")); + componentResources.append(ComponentResource("componentE", "1.0.0content.txt")); //ForcedInstall + componentResources.append(ComponentResource("componentG", "1.0.0content.txt")); //Depends on componentA + + QTest::newRow("Forced installation") + << ":///data/installPackagesRepository" + << (QStringList() << "componentE") + << PackageManagerCore::Success + << componentResources + << (QStringList() << "components.xml" << "installcontent.txt" + << "installcontentA.txt" << "installcontentE.txt" << "installcontentG.txt"); + + /*********** Simple installation **********/ + componentResources.clear(); + componentResources.append(ComponentResource("componentA", "1.0.0content.txt")); + componentResources.append(ComponentResource("componentE", "1.0.0content.txt")); //ForcedInstall + componentResources.append(ComponentResource("componentG", "1.0.0content.txt")); //Depends on componentA + + QTest::newRow("Simple installation") + << ":///data/installPackagesRepository" + << (QStringList() << "componentA") + << PackageManagerCore::Success + << componentResources + << (QStringList() << "components.xml" << "installcontent.txt" + << "installcontentA.txt" << "installcontentE.txt" << "installcontentG.txt"); + + /*********** Install with dependency **********/ + componentResources.clear(); + componentResources.append(ComponentResource("componentA", "1.0.0content.txt")); //Dependency for componentC + componentResources.append(ComponentResource("componentB", "1.0.0content.txt")); //Dependency for componentC + componentResources.append(ComponentResource("componentE", "1.0.0content.txt")); //ForcedInstall + componentResources.append(ComponentResource("componentG", "1.0.0content.txt")); //Depends on componentA + componentResources.append(ComponentResource("componentI", "1.0.0content.txt")); //Virtual, depends on componentC + componentResources.append(ComponentResource("componentD", "1.0.0content.txt")); //Autodepend on componentA and componentB + + QTest::newRow("Install with dependency") + << ":///data/installPackagesRepository" + << (QStringList() << "componentC") + << PackageManagerCore::Success + << componentResources + << (QStringList() << "components.xml" << "installcontentC.txt" + << "installcontent.txt" << "installcontentA.txt" << "installcontentB.txt" + << "installcontentD.txt"<< "installcontentE.txt" << "installcontentG.txt" + << "installcontentI.txt"); + + /*********** Install with subcomponents **********/ + componentResources.clear(); + componentResources.append(ComponentResource("componentF.subcomponent2.subsubcomponent2", "1.0.0content.txt")); + componentResources.append(ComponentResource("componentF.subcomponent2", "1.0.0content.txt")); + componentResources.append(ComponentResource("componentF", "1.0.0content.txt")); + componentResources.append(ComponentResource("componentA", "1.0.0content.txt")); //Dependency for componentG + componentResources.append(ComponentResource("componentE", "1.0.0content.txt")); //ForcedInstall + componentResources.append(ComponentResource("componentG", "1.0.0content.txt")); //Default install + + QTest::newRow("Install with subcomponents") + << ":///data/installPackagesRepository" + << (QStringList() << "componentF.subcomponent2.subsubcomponent2") + << PackageManagerCore::Success + << componentResources + << (QStringList() << "components.xml" << "installcontentF.txt" + << "installcontentF_2.txt" << "installcontentF_2_2.txt" + << "installcontent.txt" << "installcontentA.txt" + << "installcontentE.txt" << "installcontentG.txt"); + } + + void testInstall() + { + QFETCH(QString, repository); + QFETCH(QStringList, installComponents); + QFETCH(PackageManagerCore::Status, status); + QFETCH(ComponentResourceHash, componentResources); + QFETCH(QStringList, installedFiles); + + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (m_installDir, repository)); + + QCOMPARE(status, core->installSelectedComponentsSilently(QStringList() << installComponents)); + for (const ComponentResource &resource : componentResources) + VerifyInstaller::verifyInstallerResources(m_installDir, resource.first, resource.second); + VerifyInstaller::verifyFileExistence(m_installDir, installedFiles); + } + + void testUninstall_data() + { + QTest::addColumn<QString>("repository"); + QTest::addColumn<QStringList>("installComponents"); + QTest::addColumn<PackageManagerCore::Status>("status"); + QTest::addColumn<ComponentResourceHash>("componentResources"); + QTest::addColumn<QStringList >("installedFiles"); + QTest::addColumn<QStringList>("uninstallComponents"); + QTest::addColumn<PackageManagerCore::Status>("uninstallStatus"); + QTest::addColumn<ComponentResourceHash>("componentResourcesAfterUninstall"); + QTest::addColumn<QStringList >("installedFilesAfterUninstall"); + QTest::addColumn<ComponentResourceHash >("deletedComponentResources"); + QTest::addColumn<bool >("virtualSetVisible"); + + /*********** Uninstallation **********/ + ComponentResourceHash componentResourcesAfterUninstall; + componentResourcesAfterUninstall.append(ComponentResource("componentE", "1.0.0content.txt")); //ForcedInstall + + ComponentResourceHash deletedComponentResources; + deletedComponentResources.append(ComponentResource("componentA", "1.0.0content.txt")); + deletedComponentResources.append(ComponentResource("componentG", "1.0.0content.txt")); + + ComponentResourceHash componentResourceAfterInstall; + componentResourceAfterInstall << deletedComponentResources << componentResourcesAfterUninstall; + + QStringList filesAfterUninstall; + filesAfterUninstall << "components.xml" << "installcontentE.txt"; + + QStringList filesAfterInstall; + filesAfterInstall << filesAfterUninstall << "installcontent.txt" + << "installcontentA.txt" << "installcontentG.txt"; + + QTest::newRow("Test uninstall") + << ":///data/installPackagesRepository" + << (QStringList() << "componentA") + << PackageManagerCore::Success + << componentResourceAfterInstall + << filesAfterInstall + << (QStringList() << "componentA") + << PackageManagerCore::Success + << componentResourcesAfterUninstall + << filesAfterUninstall + << deletedComponentResources; + + /*********** Uninstall with dependency **********/ + componentResourcesAfterUninstall.clear(); + componentResourcesAfterUninstall.append(ComponentResource("componentA", "1.0.0content.txt")); + componentResourcesAfterUninstall.append(ComponentResource("componentB", "1.0.0content.txt")); + componentResourcesAfterUninstall.append(ComponentResource("componentE", "1.0.0content.txt")); + componentResourcesAfterUninstall.append(ComponentResource("componentG", "1.0.0content.txt")); + componentResourcesAfterUninstall.append(ComponentResource("componentD", "1.0.0content.txt")); + + deletedComponentResources.clear(); + deletedComponentResources.append(ComponentResource("componentC", "1.0.0content.txt")); //Unselected + deletedComponentResources.append(ComponentResource("componentI", "1.0.0content.txt")); //Autodepends on componentC + + componentResourceAfterInstall.clear(); + componentResourceAfterInstall << deletedComponentResources << componentResourcesAfterUninstall; + + filesAfterUninstall.clear(); + filesAfterUninstall << "components.xml" + << "installcontent.txt" << "installcontentA.txt" << "installcontentB.txt" + << "installcontentD.txt"<< "installcontentE.txt" << "installcontentG.txt"; + + filesAfterInstall.clear(); + filesAfterInstall << filesAfterUninstall << "installcontentC.txt" + << "installcontentI.txt"; + + + QTest::newRow("Uninstall with dependency") + << ":///data/installPackagesRepository" + << (QStringList() << "componentC") + << PackageManagerCore::Success + << componentResourceAfterInstall + << filesAfterInstall + << (QStringList() << "componentC") + << PackageManagerCore::Success + << componentResourcesAfterUninstall + << filesAfterUninstall + << deletedComponentResources; + + /*********** Uninstall with subcomponents **********/ + componentResourcesAfterUninstall.clear(); + componentResourcesAfterUninstall.append(ComponentResource("componentA", "1.0.0content.txt")); + componentResourcesAfterUninstall.append(ComponentResource("componentE", "1.0.0content.txt")); + componentResourcesAfterUninstall.append(ComponentResource("componentG", "1.0.0content.txt")); + + deletedComponentResources.clear(); + deletedComponentResources.append(ComponentResource("componentF.subcomponent2.subsubcomponent2", "1.0.0content.txt")); + deletedComponentResources.append(ComponentResource("componentF.subcomponent2", "1.0.0content.txt")); + deletedComponentResources.append(ComponentResource("componentF", "1.0.0content.txt")); + + componentResourceAfterInstall.clear(); + componentResourceAfterInstall << deletedComponentResources << componentResourcesAfterUninstall; + + filesAfterInstall.clear(); + filesAfterInstall << "components.xml" << "installcontentF.txt" + << "installcontentF_2.txt" << "installcontentF_2_2.txt" + << "installcontent.txt" << "installcontentA.txt" + << "installcontentE.txt" << "installcontentG.txt"; + + filesAfterUninstall.clear(); + filesAfterUninstall << "components.xml" + << "installcontent.txt" << "installcontentA.txt" + << "installcontentE.txt" << "installcontentG.txt"; + + QTest::newRow("Uninstall with subcomponents") + << ":///data/installPackagesRepository" + << (QStringList() << "componentF.subcomponent2.subsubcomponent2") + << PackageManagerCore::Success + << componentResourceAfterInstall + << filesAfterInstall + << (QStringList() << "componentF.subcomponent2") + << PackageManagerCore::Success + << componentResourcesAfterUninstall + << filesAfterUninstall + << deletedComponentResources; + + /*********** Uninstall forced packages **********/ + componentResourceAfterInstall.clear(); + componentResourceAfterInstall.append(ComponentResource("componentA", "1.0.0content.txt")); //ComponentG depends + componentResourceAfterInstall.append(ComponentResource("componentE", "1.0.0content.txt")); //ForcedInstall + componentResourceAfterInstall.append(ComponentResource("componentG", "1.0.0content.txt")); //Default + + componentResourcesAfterUninstall.clear(); + componentResourcesAfterUninstall = componentResourceAfterInstall; //forced packages cannot be uninstalled + + deletedComponentResources.clear(); + + filesAfterInstall.clear(); + filesAfterInstall << "components.xml" << "installcontent.txt" + << "installcontentA.txt" << "installcontentE.txt" << "installcontentG.txt"; + + filesAfterUninstall.clear(); + filesAfterUninstall = filesAfterInstall; + + QTest::newRow("Uninstall forced packages") + << ":///data/installPackagesRepository" + << (QStringList() << "componentG") + << PackageManagerCore::Success + << componentResourceAfterInstall + << filesAfterInstall + << (QStringList() << "componentE") + << PackageManagerCore::Success + << componentResourceAfterInstall + << filesAfterUninstall + << deletedComponentResources; + + /*********** Uninstall autodependency packages **********/ + componentResourceAfterInstall.clear(); + componentResourceAfterInstall.append(ComponentResource("componentA", "1.0.0content.txt")); //ComponentG depends + componentResourceAfterInstall.append(ComponentResource("componentB", "1.0.0content.txt")); //Dependency for componentC + componentResourceAfterInstall.append(ComponentResource("componentD", "1.0.0content.txt")); //Autodepend on componentA and componentB + componentResourceAfterInstall.append(ComponentResource("componentE", "1.0.0content.txt")); //ForcedInstall + componentResourceAfterInstall.append(ComponentResource("componentG", "1.0.0content.txt")); //Default + + componentResourcesAfterUninstall.clear(); + componentResourcesAfterUninstall = componentResourceAfterInstall; //autodependency packages cannot be uninstalled + + deletedComponentResources.clear(); + + filesAfterInstall.clear(); + filesAfterInstall << "components.xml" << "installcontent.txt" + << "installcontentA.txt" << "installcontentE.txt" << "installcontentG.txt" + << "installcontentB.txt" << "installcontentD.txt"; + filesAfterUninstall.clear(); + filesAfterUninstall = filesAfterInstall; + + QTest::newRow("Uninstall autodependency packages") + << ":///data/installPackagesRepository" + << (QStringList() << "componentA" << "componentB") + << PackageManagerCore::Success + << componentResourceAfterInstall + << filesAfterInstall + << (QStringList() << "componentD") + << PackageManagerCore::Success + << componentResourceAfterInstall + << filesAfterUninstall + << deletedComponentResources; + } + + void testUninstall() + { + QFETCH(QString, repository); + QFETCH(QStringList, installComponents); + QFETCH(PackageManagerCore::Status, status); + QFETCH(ComponentResourceHash, componentResources); + QFETCH(QStringList, installedFiles); + QFETCH(QStringList, uninstallComponents); + QFETCH(PackageManagerCore::Status, uninstallStatus); + QFETCH(ComponentResourceHash, componentResourcesAfterUninstall); + QFETCH(QStringList, installedFilesAfterUninstall); + QFETCH(ComponentResourceHash, deletedComponentResources); + + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (m_installDir, repository)); + + QCOMPARE(status, core->installSelectedComponentsSilently(QStringList() << installComponents)); + for (const ComponentResource &resource : componentResources) + VerifyInstaller::verifyInstallerResources(m_installDir, resource.first, resource.second); + VerifyInstaller::verifyFileExistence(m_installDir, installedFiles); + core->commitSessionOperations(); + core->setPackageManager(); + + QCOMPARE(uninstallStatus, core->uninstallComponentsSilently(QStringList() + << uninstallComponents)); + QCOMPARE(uninstallStatus, core->status()); + for (const ComponentResource &resource : componentResourcesAfterUninstall) + VerifyInstaller::verifyInstallerResources(m_installDir, resource.first, resource.second); + for (const ComponentResource &resource : deletedComponentResources) + VerifyInstaller::verifyInstallerResourceFileDeletion(m_installDir, resource.first, resource.second); + VerifyInstaller::verifyFileExistence(m_installDir, installedFilesAfterUninstall); + } + + void addToExistingInstall_data() + { + QTest::addColumn<QString>("repository"); + QTest::addColumn<QStringList>("installComponents"); + QTest::addColumn<PackageManagerCore::Status>("status"); + QTest::addColumn<ComponentResourceHash>("componentResources"); + QTest::addColumn<QStringList >("installedFiles"); + QTest::addColumn<QString>("newRepository"); + QTest::addColumn<QStringList>("installNewComponents"); + QTest::addColumn<PackageManagerCore::Status>("reinstallStatus"); + QTest::addColumn<ComponentResourceHash>("componentResourcesAfterReinstall"); + QTest::addColumn<QStringList >("installedFilesAfterReinstall"); + QTest::addColumn<ComponentResourceHash >("deletedComponentResources"); + + /*********** New dependency in repository **********/ + ComponentResourceHash componentResourceAfterInstall; + componentResourceAfterInstall.append(ComponentResource("componentA", "1.0.0content.txt")); //ComponentC depends on + componentResourceAfterInstall.append(ComponentResource("componentB", "1.0.0content.txt")); //ComponentC depends on + componentResourceAfterInstall.append(ComponentResource("componentC", "1.0.0content.txt")); //Selected + componentResourceAfterInstall.append(ComponentResource("componentD", "1.0.0content.txt")); //Autodepend on componentA,componentB + componentResourceAfterInstall.append(ComponentResource("componentE", "1.0.0content.txt")); //Forced + componentResourceAfterInstall.append(ComponentResource("componentG", "1.0.0content.txt")); //Default + componentResourceAfterInstall.append(ComponentResource("componentI", "1.0.0content.txt")); //Autodepend componentC + + ComponentResourceHash componentResourcesAfterReinstall; + componentResourcesAfterReinstall = componentResourceAfterInstall; + componentResourcesAfterReinstall.append(ComponentResource("componentH", "1.0.0content.txt")); + + ComponentResourceHash deletedComponentResources; + // New dependency is added in repository from componentA to componentF, check that it is not installed + deletedComponentResources.append(ComponentResource("componentF", "1.0.0content.txt")); + + QStringList filesAfterInstall; + filesAfterInstall << "components.xml" + << "installcontent.txt" << "installcontentA.txt" << "installcontentB.txt" + << "installcontentC.txt" << "installcontentD.txt" << "installcontentE.txt" + << "installcontentG.txt" << "installcontentI.txt"; + + QStringList filesAfterReinstall; + filesAfterReinstall = filesAfterInstall; + filesAfterReinstall << "installcontentH.txt"; + + QTest::newRow("New dependency in repository") + << ":///data/installPackagesRepository" + << (QStringList() << "componentC") + << PackageManagerCore::Success + << componentResourceAfterInstall + << filesAfterInstall + << ":///data/installPackagesDependencyChanged" + << (QStringList() << "componentH") + << PackageManagerCore::Success + << componentResourcesAfterReinstall + << filesAfterReinstall + << deletedComponentResources; + } + + void addToExistingInstall() + { + QFETCH(QString, repository); + QFETCH(QStringList, installComponents); + QFETCH(PackageManagerCore::Status, status); + QFETCH(ComponentResourceHash, componentResources); + QFETCH(QStringList, installedFiles); + QFETCH(QString, newRepository); + QFETCH(QStringList, installNewComponents); + QFETCH(PackageManagerCore::Status, reinstallStatus); + QFETCH(ComponentResourceHash, componentResourcesAfterReinstall); + QFETCH(QStringList, installedFilesAfterReinstall); + QFETCH(ComponentResourceHash, deletedComponentResources); + + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (m_installDir, repository)); + QCOMPARE(status, core->installSelectedComponentsSilently(installComponents)); + QCOMPARE(status, core->status()); + + for (const ComponentResource &resource : componentResources) + VerifyInstaller::verifyInstallerResources(m_installDir, resource.first, resource.second); + VerifyInstaller::verifyFileExistence(m_installDir, installedFiles); + + core->reset(); + core->cancelMetaInfoJob(); //Call cancel to reset metadata so that update repositories are fetched + + QSet<Repository> repoList; + Repository repo = Repository::fromUserInput(newRepository); + repoList.insert(repo); + core->settings().setDefaultRepositories(repoList); + + QCOMPARE(reinstallStatus, core->installSelectedComponentsSilently(installNewComponents)); + + for (const ComponentResource &resource : deletedComponentResources) + VerifyInstaller::verifyInstallerResourceFileDeletion(m_installDir, resource.first, resource.second); + for (const ComponentResource &resource : componentResourcesAfterReinstall) + VerifyInstaller::verifyInstallerResources(m_installDir, resource.first, resource.second); + VerifyInstaller::verifyFileExistence(m_installDir, installedFilesAfterReinstall); + } + + void testInstallDefaultPackagesSilently() + { + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (m_installDir, ":///data/installPackagesRepository")); + QCOMPARE(PackageManagerCore::Success, core->installDefaultComponentsSilently()); + QCOMPARE(PackageManagerCore::Success, core->status()); + VerifyInstaller::verifyInstallerResources(m_installDir, "componentA", "1.0.0content.txt"); //Dependency for componentG + VerifyInstaller::verifyInstallerResources(m_installDir, "componentE", "1.0.0content.txt"); //ForcedInstall + VerifyInstaller::verifyInstallerResources(m_installDir, "componentG", "1.0.0content.txt"); //Default + VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" << "installcontent.txt" + << "installcontentA.txt" << "installcontentE.txt" << "installcontentG.txt"); + } + + + void testNoDefaultInstallations() + { + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (m_installDir, ":///data/installPackagesRepository")); + core->setNoDefaultInstallation(true); + QCOMPARE(PackageManagerCore::Success, core->installDefaultComponentsSilently()); + QCOMPARE(PackageManagerCore::Success, core->status()); + VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" + << "installcontentE.txt"); + core->setNoDefaultInstallation(false); + } + + void testRemoveAllSilently() + { + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (m_installDir, ":///data/installPackagesRepository")); + QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() + << QLatin1String("componentA"))); + VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" << "installcontentE.txt" + << "installcontentA.txt" << "installcontent.txt" << "installcontentG.txt"); + + core->commitSessionOperations(); + core->setUninstaller(); + QCOMPARE(PackageManagerCore::Success, core->removeInstallationSilently()); + QCOMPARE(PackageManagerCore::Success, core->status()); + VerifyInstaller::verifyInstallerResourcesDeletion(m_installDir, "componentA"); + VerifyInstaller::verifyInstallerResourcesDeletion(m_installDir, "componentE"); + VerifyInstaller::verifyInstallerResourcesDeletion(m_installDir, "componentG"); + + // On Windows we have to settle for the resources check above as maintenance + // tool (if it would exists) and target directory are only removed later via + // started VBScript process. On Unix platforms the target directory should + // be removed in PackageManagerCorePrivate::runUninstaller(). +#if defined(Q_OS_UNIX) + QVERIFY(!QDir(m_installDir).exists()); +#endif + } + + void testUninstallVirtualSetVisibleSilently() + { + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (m_installDir, ":///data/installPackagesRepository")); + core->setVirtualComponentsVisible(true); + QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() + <<"componentH")); + QCOMPARE(PackageManagerCore::Success, core->status()); + VerifyInstaller::verifyInstallerResources(m_installDir, "componentH", "1.0.0content.txt"); + + core->commitSessionOperations(); + core->setPackageManager(); + QCOMPARE(PackageManagerCore::Success, core->uninstallComponentsSilently(QStringList() + << "componentH")); + QCOMPARE(PackageManagerCore::Success, core->status()); + VerifyInstaller::verifyInstallerResourcesDeletion(m_installDir, "componentH"); + } + + void testFileQuery() + { + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit(m_installDir, + ":///data/filequeryrepository")); + core->setCommandLineInstance(true); + core->setFileDialogAutomaticAnswer("ValidDirectory", m_installDir); + + QString testFile = qApp->applicationDirPath() + QDir::toNativeSeparators("/test"); + QFile file(testFile); + QVERIFY(file.open(QIODevice::WriteOnly)); + core->setFileDialogAutomaticAnswer("ValidFile", testFile); + + //File dialog launched without ID + core->setFileDialogAutomaticAnswer("GetExistingDirectory", m_installDir); + core->setFileDialogAutomaticAnswer("GetExistingFile", testFile); + + QCOMPARE(PackageManagerCore::Success, core->installDefaultComponentsSilently()); + QCOMPARE(PackageManagerCore::Success, core->status()); + + QVERIFY(core->containsFileDialogAutomaticAnswer("ValidFile")); + core->removeFileDialogAutomaticAnswer("ValidFile"); + QVERIFY(!core->containsFileDialogAutomaticAnswer("ValidFile")); + + QVERIFY(file.remove()); + } + + void testPostScript() + { + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (m_installDir, ":///data/installPackagesRepository")); + QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() << QLatin1String("componentJ"))); + VerifyInstaller::verifyInstallerResources(m_installDir, "componentJ", "1.0.0content.txt"); //Selected + VerifyInstaller::verifyInstallerResources(m_installDir, "componentA", "1.0.0content.txt"); //Dependency for componentG + VerifyInstaller::verifyInstallerResources(m_installDir, "componentE", "1.0.0content.txt"); //ForcedInstall + VerifyInstaller::verifyInstallerResources(m_installDir, "componentG", "1.0.0content.txt"); //Default + + //componentJ is extracted to "extractToAnotherPath" -folder in post install script + bool fileExists = QFileInfo::exists(m_installDir + QDir::separator() + "extractToAnotherPath" + QDir::separator() + "installcontentJ.txt"); + QVERIFY2(fileExists, QString("File \"%1\" does not exist.").arg("installcontentJ.txt").toLatin1()); + } + + void init() + { + m_installDir = QInstaller::generateTemporaryFileName(); + QVERIFY(QDir().mkpath(m_installDir)); + } + + void initTestCase() + { + qSetGlobalQHashSeed(0); //Ensures the dom document deterministic behavior + } + + void cleanup() + { + QDir dir(m_installDir); + QVERIFY(dir.removeRecursively()); + } + +private: + QString m_installDir; +}; + + +QTEST_MAIN(tst_CommandLineInstall) + +#include "tst_commandlineinstall.moc" diff --git a/tests/auto/installer/commandlineupdate/commandlineupdate.pro b/tests/auto/installer/commandlineupdate/commandlineupdate.pro new file mode 100644 index 000000000..543ec8b23 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/commandlineupdate.pro @@ -0,0 +1,9 @@ +include(../../qttest.pri) + +QT += qml + +SOURCES += tst_commandlineupdate.cpp + +RESOURCES += \ + settings.qrc \ + ../shared/config.qrc diff --git a/tests/auto/installer/commandlineupdate/data/config.xml b/tests/auto/installer/commandlineupdate/data/config.xml new file mode 100644 index 000000000..041ce5062 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/config.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Installer> + <Name>Your application</Name> + <Version>1.2.3</Version> + <MaintenanceToolName></MaintenanceToolName> + <MaintenanceToolIniFile></MaintenanceToolIniFile> + <TargetConfigurationFile></TargetConfigurationFile> +</Installer> diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepository/Updates.xml b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/Updates.xml new file mode 100644 index 000000000..de6e66525 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/Updates.xml @@ -0,0 +1,179 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>componentA</Name> + <DisplayName>Component A</DisplayName> + <Description>This component does not depend on any other component.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>100</SortingPriority> + <UpdateFile OS="Any" CompressedSize="299" UncompressedSize="158"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>92b02a74d0886bc1569ff8b3a7edd1f9d828e56c</SHA1> + <Essential>true</Essential> + </PackageUpdate> + <PackageUpdate> + <Name>componentB</Name> + <DisplayName>Component B</DisplayName> + <Description>This component does not depend on any other component.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>90</SortingPriority> + <UpdateFile OS="Any" CompressedSize="281" UncompressedSize="99"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>aedfaef53cdc0f52353a8680009be405fa767811</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentC</Name> + <DisplayName>Component C (depends on A and B)</DisplayName> + <Description>This component depends on Component A and Component B. Selecting this component for installation also marks Component A and Component B for installation, which in turn marks Component D, because it has an automatic dependency on Component A and Component B.</Description> + <Dependencies>componentA, componentB</Dependencies> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>80</SortingPriority> + <UpdateFile OS="Any" CompressedSize="281" UncompressedSize="99"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>20b9463a5e06f373182b3c7c4cf879806d429409</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentD</Name> + <DisplayName>Component D (auto depends on A and B)</DisplayName> + <Description>This component has an automatic dependency on Component A and Component B. If both A and B are marked for installation, this component is also installed.</Description> + <AutoDependOn>componentA, componentB</AutoDependOn> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>70</SortingPriority> + <UpdateFile OS="Any" CompressedSize="281" UncompressedSize="99"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>99cf24c71559c75dfae9933826ed16051fca6ea1</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentE</Name> + <DisplayName>Component E (forced)</DisplayName> + <Description>This is a forced component that is always installed.</Description> + <ForcedInstallation>true</ForcedInstallation> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>60</SortingPriority> + <UpdateFile OS="Any" CompressedSize="281" UncompressedSize="99"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>926bf503ccdff93351744843a95e5e2172cad5ec</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentF</Name> + <DisplayName>Component F</DisplayName> + <Description>This component contains 2 subcomponents.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>40</SortingPriority> + <UpdateFile OS="Any" CompressedSize="281" UncompressedSize="99"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>e6443a8b5a5651f63c0604cae6d32431ca617f1a</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentF.subcomponent1</Name> + <DisplayName>Subcomponent 1</DisplayName> + <Description>This component contains 2 leaf components.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>100</SortingPriority> + <UpdateFile OS="Any" CompressedSize="281" UncompressedSize="99"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>a3bc5dce1c93add30c22e46436396c66b0b51001</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentF.subcomponent1.subsubcomponent1</Name> + <DisplayName>Subsubcomponent 1</DisplayName> + <Description>This component does not depend on any other component.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>100</SortingPriority> + <UpdateFile OS="Any" CompressedSize="289" UncompressedSize="99"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>ebe4d69414a1675a7f46887e15d9bffc275b7cc4</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentF.subcomponent1.subsubcomponent2</Name> + <DisplayName>Subsubcomponent 2</DisplayName> + <Description>This component does not depend on any other component.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>50</SortingPriority> + <UpdateFile OS="Any" CompressedSize="289" UncompressedSize="99"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>e4379d20320d4c173b2d8e228f5722e3f36e3114</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentF.subcomponent2</Name> + <DisplayName>Subcomponent 2</DisplayName> + <Description>This component contains 2 leaf components.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>50</SortingPriority> + <UpdateFile OS="Any" CompressedSize="281" UncompressedSize="99"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>6462be25912c490569a7c4f3931d978e78c69dc4</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentF.subcomponent2.subsubcomponent1</Name> + <DisplayName>Subsubcomponent 1</DisplayName> + <Description>This component does not depend on any other component.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>100</SortingPriority> + <UpdateFile OS="Any" CompressedSize="289" UncompressedSize="99"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>72b224bc8f3431210834ce6db373fc8d638a3546</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentF.subcomponent2.subsubcomponent2</Name> + <DisplayName>Subsubcomponent 2</DisplayName> + <Description>This component does not depend on any other component.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>50</SortingPriority> + <UpdateFile OS="Any" CompressedSize="289" UncompressedSize="99"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>3e2744edaef06af75b3248d5935523a6e2e61551</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentG</Name> + <DisplayName>Component G (default, depends on A, dependency added dynamically)</DisplayName> + <Description>By default, this component is selected for installation. It depends on component A. Dependency is added from inside component script.</Description> + <Default>true</Default> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <Script>installscript.js</Script> + <SortingPriority>30</SortingPriority> + <UpdateFile OS="Any" CompressedSize="281" UncompressedSize="99"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>8cba36dd589492c28e0d04942b4f8aa0a09f59cc</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentH</Name> + <DisplayName>Component H. ForcedUpdate</DisplayName> + <Description>Component H. ForcedUpdate</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <ForcedUpdate>true</ForcedUpdate> + <DownloadableArchives>content.7z</DownloadableArchives> + </PackageUpdate> + <PackageUpdate> + <Name>qt.tools.qtcreator</Name> + <DisplayName>Component qtcreator. Depends on virtual component</DisplayName> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <Dependencies>qt.tools.qtcreator.enterprise.plugins</Dependencies> + <DownloadableArchives>content.7z</DownloadableArchives> + </PackageUpdate> + <PackageUpdate> + <Name>qt.tools.qtcreator.enterprise.plugins</Name> + <DisplayName>enterprise plugin component</DisplayName> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <DownloadableArchives>content.7z</DownloadableArchives> + <Virtual>true</Virtual> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentA/1.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentA/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..4ddbe565b --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentA/1.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentB/1.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentB/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..f84ffcdc5 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentB/1.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentC/1.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentC/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..9ad11e06f --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentC/1.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentD/1.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentD/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..0c8c52e31 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentD/1.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentE/1.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentE/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..f5abacf81 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentE/1.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentF.subcomponent1.subsubcomponent1/1.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentF.subcomponent1.subsubcomponent1/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..3aced680f --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentF.subcomponent1.subsubcomponent1/1.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentF.subcomponent1.subsubcomponent2/1.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentF.subcomponent1.subsubcomponent2/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..e5385a163 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentF.subcomponent1.subsubcomponent2/1.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentF.subcomponent1/1.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentF.subcomponent1/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..5bc549863 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentF.subcomponent1/1.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentF.subcomponent2.subsubcomponent1/1.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentF.subcomponent2.subsubcomponent1/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..da9e9f340 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentF.subcomponent2.subsubcomponent1/1.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentF.subcomponent2.subsubcomponent2/1.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentF.subcomponent2.subsubcomponent2/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..d0b013706 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentF.subcomponent2.subsubcomponent2/1.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentF.subcomponent2/1.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentF.subcomponent2/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..74ab44033 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentF.subcomponent2/1.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentF/1.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentF/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..4a04b1394 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentF/1.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentG/1.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentG/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..81fc02052 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentG/1.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentG/1.0.0meta.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentG/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..e5c446f64 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentG/1.0.0meta.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentH/1.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentH/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..e1449ad29 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/componentH/1.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepository/qt.tools.qtcreator.enterprise.plugins/1.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/qt.tools.qtcreator.enterprise.plugins/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..5c7c4f37d --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/qt.tools.qtcreator.enterprise.plugins/1.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepository/qt.tools.qtcreator/1.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/qt.tools.qtcreator/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..e5e4178a4 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/qt.tools.qtcreator/1.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/Updates.xml b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/Updates.xml new file mode 100644 index 000000000..5fbfaa5e9 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/Updates.xml @@ -0,0 +1,163 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>componentA</Name> + <DisplayName>Component A</DisplayName> + <Description>This component does not depend on any other component.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2015-08-25</ReleaseDate> + <SortingPriority>100</SortingPriority> + <UpdateFile CompressedSize="297" UncompressedSize="99" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>43c8fcc544ea6d35fe5180a50d4764dcf9fd7473</SHA1> + <Essential>true</Essential> + </PackageUpdate> + <PackageUpdate> + <Name>componentB</Name> + <DisplayName>Component B</DisplayName> + <Description>This component does not depend on any other component.</Description> + <Version>2.0.0</Version> + <ReleaseDate>2015-08-25</ReleaseDate> + <SortingPriority>90</SortingPriority> + <UpdateFile CompressedSize="297" UncompressedSize="99" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>c360591443f4f46c14cd05b0e7f93a105857b563</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentC</Name> + <DisplayName>Component C (depends on A and B)</DisplayName> + <Description>This component depends on Component A and Component B. Selecting this component for installation also marks Component A and Component B for installation, which in turn marks Component D, because it has an automatic dependency on Component A and Component B.</Description> + <Dependencies>componentA, componentB</Dependencies> + <Version>2.0.0</Version> + <ReleaseDate>2015-08-25</ReleaseDate> + <SortingPriority>80</SortingPriority> + <UpdateFile CompressedSize="297" UncompressedSize="99" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>3c5acf95ad15a2ea6e2baaf55dd79053ca439668</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentD</Name> + <DisplayName>Component D (auto depends on A and B)</DisplayName> + <Description>This component has an automatic dependency on Component A and Component B. If both A and B are marked for installation, this component is also installed.</Description> + <AutoDependOn>componentA, componentB</AutoDependOn> + <Version>2.0.0</Version> + <ReleaseDate>2015-08-25</ReleaseDate> + <SortingPriority>70</SortingPriority> + <UpdateFile CompressedSize="297" UncompressedSize="99" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>5b014c99bf083377024f3de42553faad0c69ebbb</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentE</Name> + <DisplayName>Component E (forced)</DisplayName> + <Description>This is a forced component that is always installed.</Description> + <ForcedInstallation>true</ForcedInstallation> + <Version>2.0.0</Version> + <ReleaseDate>2015-08-25</ReleaseDate> + <SortingPriority>60</SortingPriority> + <UpdateFile CompressedSize="297" UncompressedSize="99" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>bf312c4593abaa8f6d18a1504c411e5ec8130860</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentF</Name> + <DisplayName>Component F</DisplayName> + <Description>This component contains 2 subcomponents.</Description> + <Version>2.0.0</Version> + <ReleaseDate>2015-08-25</ReleaseDate> + <SortingPriority>40</SortingPriority> + <UpdateFile CompressedSize="297" UncompressedSize="99" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>d8764d228cc32be0959b286cf57a30252082d2dc</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentF.subcomponent1</Name> + <DisplayName>Subcomponent 1</DisplayName> + <Description>This component contains 2 leaf components.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>100</SortingPriority> + <UpdateFile CompressedSize="281" UncompressedSize="99" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>fbdd255c25820331ffea46c9a80905580fb8ad4f</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentF.subcomponent1.subsubcomponent1</Name> + <DisplayName>Subsubcomponent 1</DisplayName> + <Description>This component does not depend on any other component.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>100</SortingPriority> + <UpdateFile CompressedSize="289" UncompressedSize="99" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>c96ddbefa66f5a3400e0c2f3a458c0f619d99690</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentF.subcomponent1.subsubcomponent2</Name> + <DisplayName>Subsubcomponent 2</DisplayName> + <Description>This component does not depend on any other component.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>50</SortingPriority> + <UpdateFile CompressedSize="289" UncompressedSize="99" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>c88f52f11f22089d7efc3b65394e96ee1656702e</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentF.subcomponent2</Name> + <DisplayName>Subcomponent 2</DisplayName> + <Description>This component contains 2 leaf components.</Description> + <Version>2.0.0</Version> + <ReleaseDate>2015-08-25</ReleaseDate> + <SortingPriority>50</SortingPriority> + <UpdateFile CompressedSize="297" UncompressedSize="99" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>57120d69b22e013666b80d3954b1ee65eb37891f</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentF.subcomponent2.subsubcomponent1</Name> + <DisplayName>Subsubcomponent 1</DisplayName> + <Description>This component does not depend on any other component.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>100</SortingPriority> + <UpdateFile CompressedSize="289" UncompressedSize="99" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>3844dc1b4805050f34b483661843a8f8a4e97864</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentF.subcomponent2.subsubcomponent2</Name> + <DisplayName>Subsubcomponent 2</DisplayName> + <Description>This component does not depend on any other component.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>50</SortingPriority> + <UpdateFile CompressedSize="289" UncompressedSize="99" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>e1d988818cb8fd89e8863b5699b19823e38f0919</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentG</Name> + <DisplayName>Component G (default, depends on A, dependency added dynamically)</DisplayName> + <Description>By default, this component is selected for installation. It depends on component A. Dependency is added from inside component script.</Description> + <Default>true</Default> + <Version>2.0.0</Version> + <ReleaseDate>2015-08-25</ReleaseDate> + <Script>installscript.js</Script> + <SortingPriority>30</SortingPriority> + <UpdateFile CompressedSize="297" UncompressedSize="99" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>098b5ecafe8853371fd608acd9b1ccab252ef5df</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentH</Name> + <DisplayName>Component H. ForcedUpdate</DisplayName> + <Description>Component H. ForcedUpdate</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <ForcedUpdate>true</ForcedUpdate> + <DownloadableArchives>content.7z</DownloadableArchives> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentA/1.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentA/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..4ddbe565b --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentA/1.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentA/2.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentA/2.0.0content.7z Binary files differnew file mode 100644 index 000000000..9e947f5f7 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentA/2.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentB/2.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentB/2.0.0content.7z Binary files differnew file mode 100644 index 000000000..08f7ad70d --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentB/2.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentC/2.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentC/2.0.0content.7z Binary files differnew file mode 100644 index 000000000..3cd9e94fe --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentC/2.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentD/2.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentD/2.0.0content.7z Binary files differnew file mode 100644 index 000000000..992b756d2 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentD/2.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentE/2.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentE/2.0.0content.7z Binary files differnew file mode 100644 index 000000000..d6e7562b1 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentE/2.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentF.subcomponent1.subsubcomponent1/1.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentF.subcomponent1.subsubcomponent1/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..b559dd72f --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentF.subcomponent1.subsubcomponent1/1.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentF.subcomponent1.subsubcomponent2/1.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentF.subcomponent1.subsubcomponent2/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..a2109e812 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentF.subcomponent1.subsubcomponent2/1.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentF.subcomponent1/1.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentF.subcomponent1/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..55655d1d3 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentF.subcomponent1/1.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentF.subcomponent2.subsubcomponent1/1.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentF.subcomponent2.subsubcomponent1/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..c469c39a9 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentF.subcomponent2.subsubcomponent1/1.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentF.subcomponent2.subsubcomponent2/1.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentF.subcomponent2.subsubcomponent2/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..164348ac9 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentF.subcomponent2.subsubcomponent2/1.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentF.subcomponent2/2.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentF.subcomponent2/2.0.0content.7z Binary files differnew file mode 100644 index 000000000..921c501cd --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentF.subcomponent2/2.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentF/2.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentF/2.0.0content.7z Binary files differnew file mode 100644 index 000000000..6973624df --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentF/2.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentG/2.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentG/2.0.0content.7z Binary files differnew file mode 100644 index 000000000..a3d72046e --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentG/2.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentG/2.0.0meta.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentG/2.0.0meta.7z Binary files differnew file mode 100644 index 000000000..a34fd36f1 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentG/2.0.0meta.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentH/1.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentH/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..e1449ad29 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentH/1.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentH/2.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentH/2.0.0content.7z Binary files differnew file mode 100644 index 000000000..f74b8da68 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/componentH/2.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/Updates.xml b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/Updates.xml new file mode 100644 index 000000000..f56888022 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/Updates.xml @@ -0,0 +1,163 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>componentA</Name> + <DisplayName>Component A</DisplayName> + <Description>This component does not depend on any other component.</Description> + <Version>2.0.0</Version> + <ReleaseDate>2015-08-25</ReleaseDate> + <SortingPriority>100</SortingPriority> + <UpdateFile CompressedSize="297" UncompressedSize="99" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>43c8fcc544ea6d35fe5180a50d4764dcf9fd7473</SHA1> + <Essential>true</Essential> + </PackageUpdate> + <PackageUpdate> + <Name>componentB</Name> + <DisplayName>Component B</DisplayName> + <Description>This component does not depend on any other component.</Description> + <Version>2.0.0</Version> + <ReleaseDate>2015-08-25</ReleaseDate> + <SortingPriority>90</SortingPriority> + <UpdateFile CompressedSize="297" UncompressedSize="99" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>c360591443f4f46c14cd05b0e7f93a105857b563</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentC</Name> + <DisplayName>Component C (depends on A and B)</DisplayName> + <Description>This component depends on Component A and Component B. Selecting this component for installation also marks Component A and Component B for installation, which in turn marks Component D, because it has an automatic dependency on Component A and Component B.</Description> + <Dependencies>componentA, componentB</Dependencies> + <Version>2.0.0</Version> + <ReleaseDate>2015-08-25</ReleaseDate> + <SortingPriority>80</SortingPriority> + <UpdateFile CompressedSize="297" UncompressedSize="99" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>3c5acf95ad15a2ea6e2baaf55dd79053ca439668</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentD</Name> + <DisplayName>Component D (auto depends on A and B)</DisplayName> + <Description>This component has an automatic dependency on Component A and Component B. If both A and B are marked for installation, this component is also installed.</Description> + <AutoDependOn>componentA, componentB</AutoDependOn> + <Version>2.0.0</Version> + <ReleaseDate>2015-08-25</ReleaseDate> + <SortingPriority>70</SortingPriority> + <UpdateFile CompressedSize="297" UncompressedSize="99" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>5b014c99bf083377024f3de42553faad0c69ebbb</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentE</Name> + <DisplayName>Component E (forced)</DisplayName> + <Description>This is a forced component that is always installed.</Description> + <ForcedInstallation>true</ForcedInstallation> + <Version>2.0.0</Version> + <ReleaseDate>2015-08-25</ReleaseDate> + <SortingPriority>60</SortingPriority> + <UpdateFile CompressedSize="297" UncompressedSize="99" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>bf312c4593abaa8f6d18a1504c411e5ec8130860</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentF</Name> + <DisplayName>Component F</DisplayName> + <Description>This component contains 2 subcomponents.</Description> + <Version>2.0.0</Version> + <ReleaseDate>2015-08-25</ReleaseDate> + <SortingPriority>40</SortingPriority> + <UpdateFile CompressedSize="297" UncompressedSize="99" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>d8764d228cc32be0959b286cf57a30252082d2dc</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentF.subcomponent1</Name> + <DisplayName>Subcomponent 1</DisplayName> + <Description>This component contains 2 leaf components.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>100</SortingPriority> + <UpdateFile CompressedSize="281" UncompressedSize="99" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>fbdd255c25820331ffea46c9a80905580fb8ad4f</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentF.subcomponent1.subsubcomponent1</Name> + <DisplayName>Subsubcomponent 1</DisplayName> + <Description>This component does not depend on any other component.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>100</SortingPriority> + <UpdateFile CompressedSize="289" UncompressedSize="99" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>c96ddbefa66f5a3400e0c2f3a458c0f619d99690</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentF.subcomponent1.subsubcomponent2</Name> + <DisplayName>Subsubcomponent 2</DisplayName> + <Description>This component does not depend on any other component.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>50</SortingPriority> + <UpdateFile CompressedSize="289" UncompressedSize="99" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>c88f52f11f22089d7efc3b65394e96ee1656702e</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentF.subcomponent2</Name> + <DisplayName>Subcomponent 2</DisplayName> + <Description>This component contains 2 leaf components.</Description> + <Version>2.0.0</Version> + <ReleaseDate>2015-08-25</ReleaseDate> + <SortingPriority>50</SortingPriority> + <UpdateFile CompressedSize="297" UncompressedSize="99" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>57120d69b22e013666b80d3954b1ee65eb37891f</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentF.subcomponent2.subsubcomponent1</Name> + <DisplayName>Subsubcomponent 1</DisplayName> + <Description>This component does not depend on any other component.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>100</SortingPriority> + <UpdateFile CompressedSize="289" UncompressedSize="99" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>3844dc1b4805050f34b483661843a8f8a4e97864</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentF.subcomponent2.subsubcomponent2</Name> + <DisplayName>Subsubcomponent 2</DisplayName> + <Description>This component does not depend on any other component.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>50</SortingPriority> + <UpdateFile CompressedSize="289" UncompressedSize="99" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>e1d988818cb8fd89e8863b5699b19823e38f0919</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentG</Name> + <DisplayName>Component G (default, depends on A, dependency added dynamically)</DisplayName> + <Description>By default, this component is selected for installation. It depends on component A. Dependency is added from inside component script.</Description> + <Default>true</Default> + <Version>2.0.0</Version> + <ReleaseDate>2015-08-25</ReleaseDate> + <Script>installscript.js</Script> + <SortingPriority>30</SortingPriority> + <UpdateFile CompressedSize="297" UncompressedSize="99" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>098b5ecafe8853371fd608acd9b1ccab252ef5df</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentH</Name> + <DisplayName>Component H. ForcedUpdate</DisplayName> + <Description>Component H. ForcedUpdate</Description> + <Version>2.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <ForcedUpdate>true</ForcedUpdate> + <DownloadableArchives>content.7z</DownloadableArchives> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentA/2.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentA/2.0.0content.7z Binary files differnew file mode 100644 index 000000000..9e947f5f7 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentA/2.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentB/2.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentB/2.0.0content.7z Binary files differnew file mode 100644 index 000000000..08f7ad70d --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentB/2.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentC/2.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentC/2.0.0content.7z Binary files differnew file mode 100644 index 000000000..3cd9e94fe --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentC/2.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentD/2.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentD/2.0.0content.7z Binary files differnew file mode 100644 index 000000000..992b756d2 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentD/2.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentE/2.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentE/2.0.0content.7z Binary files differnew file mode 100644 index 000000000..d6e7562b1 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentE/2.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentF.subcomponent1.subsubcomponent1/1.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentF.subcomponent1.subsubcomponent1/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..b559dd72f --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentF.subcomponent1.subsubcomponent1/1.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentF.subcomponent1.subsubcomponent2/1.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentF.subcomponent1.subsubcomponent2/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..a2109e812 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentF.subcomponent1.subsubcomponent2/1.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentF.subcomponent1/1.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentF.subcomponent1/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..55655d1d3 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentF.subcomponent1/1.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentF.subcomponent2.subsubcomponent1/1.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentF.subcomponent2.subsubcomponent1/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..c469c39a9 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentF.subcomponent2.subsubcomponent1/1.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentF.subcomponent2.subsubcomponent2/1.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentF.subcomponent2.subsubcomponent2/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..164348ac9 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentF.subcomponent2.subsubcomponent2/1.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentF.subcomponent2/2.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentF.subcomponent2/2.0.0content.7z Binary files differnew file mode 100644 index 000000000..921c501cd --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentF.subcomponent2/2.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentF/2.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentF/2.0.0content.7z Binary files differnew file mode 100644 index 000000000..6973624df --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentF/2.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentG/2.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentG/2.0.0content.7z Binary files differnew file mode 100644 index 000000000..a3d72046e --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentG/2.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentG/2.0.0meta.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentG/2.0.0meta.7z Binary files differnew file mode 100644 index 000000000..a34fd36f1 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentG/2.0.0meta.7z diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentH/2.0.0content.7z b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentH/2.0.0content.7z Binary files differnew file mode 100644 index 000000000..f74b8da68 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdateWithEssential/componentH/2.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/repositoryUpdateWithReplacements/Updates.xml b/tests/auto/installer/commandlineupdate/data/repositoryUpdateWithReplacements/Updates.xml new file mode 100644 index 000000000..f55998c48 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/repositoryUpdateWithReplacements/Updates.xml @@ -0,0 +1,32 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>qt.tools.qtcreator</Name> + <DisplayName>Component qtcreator. Dependency removed</DisplayName> + <Version>2.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <DownloadableArchives>content.7z</DownloadableArchives> + </PackageUpdate> + <PackageUpdate> + <Name>qt.tools.qtcreator_gui</Name> + <DisplayName>Component K. Autodepends on componentJ</DisplayName> + <Description>Component K. Autodepends on componentJ</Description> + <Version>2.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <AutoDependOn>qt.tools.qtcreator</AutoDependOn> + <DownloadableArchives>content.7z</DownloadableArchives> + </PackageUpdate> + <PackageUpdate> + <Name>qt.tools.qtcreator_gui.enterprise.plugins</Name> + <DisplayName>enterprise plugins, replaces another component</DisplayName> + <Version>2.0.0</Version> + <ReleaseDate>2018-03-14</ReleaseDate> + <Virtual>true</Virtual> + <Replaces>qt.tools.qtcreator.enterprise.plugins</Replaces> + <AutoDependOn>qt.tools.qtcreator</AutoDependOn> + <UpdateFile UncompressedSize="99" OS="Any" CompressedSize="305"/> + <DownloadableArchives>content.7z</DownloadableArchives> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/commandlineupdate/data/repositoryUpdateWithReplacements/qt.tools.qtcreator/2.0.0content.7z b/tests/auto/installer/commandlineupdate/data/repositoryUpdateWithReplacements/qt.tools.qtcreator/2.0.0content.7z Binary files differnew file mode 100644 index 000000000..f2b69fc13 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/repositoryUpdateWithReplacements/qt.tools.qtcreator/2.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/repositoryUpdateWithReplacements/qt.tools.qtcreator_gui.enterprise.plugins/2.0.0content.7z b/tests/auto/installer/commandlineupdate/data/repositoryUpdateWithReplacements/qt.tools.qtcreator_gui.enterprise.plugins/2.0.0content.7z Binary files differnew file mode 100644 index 000000000..03d191cb5 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/repositoryUpdateWithReplacements/qt.tools.qtcreator_gui.enterprise.plugins/2.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/repositoryUpdateWithReplacements/qt.tools.qtcreator_gui/2.0.0content.7z b/tests/auto/installer/commandlineupdate/data/repositoryUpdateWithReplacements/qt.tools.qtcreator_gui/2.0.0content.7z Binary files differnew file mode 100644 index 000000000..515c3a5cf --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/repositoryUpdateWithReplacements/qt.tools.qtcreator_gui/2.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/repositoryWithDependencyToEssential/Updates.xml b/tests/auto/installer/commandlineupdate/data/repositoryWithDependencyToEssential/Updates.xml new file mode 100644 index 000000000..1729f5732 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/repositoryWithDependencyToEssential/Updates.xml @@ -0,0 +1,26 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>componentA</Name> + <DisplayName>Component A</DisplayName> + <Description>This component does not depend on any other component.</Description> + <Version>3.0.0</Version> + <ReleaseDate>2015-08-25</ReleaseDate> + <SortingPriority>100</SortingPriority> + <Essential>true</Essential> + <UpdateFile UncompressedSize="99" OS="Any" CompressedSize="297"/> + <DownloadableArchives>content.7z</DownloadableArchives> + </PackageUpdate> + <PackageUpdate> + <Name>componentAutoDependOnA</Name> + <DisplayName>Component, autodepends on A</DisplayName> + <Description>Component, autodepends on A</Description> + <Version>1.0</Version> + <ReleaseDate>2018-03-14</ReleaseDate> + <AutoDependOn>componentA</AutoDependOn> + <UpdateFile UncompressedSize="99" OS="Any" CompressedSize="305"/> + <DownloadableArchives>content.7z</DownloadableArchives> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/commandlineupdate/data/repositoryWithDependencyToEssential/componentA/3.0.0content.7z b/tests/auto/installer/commandlineupdate/data/repositoryWithDependencyToEssential/componentA/3.0.0content.7z Binary files differnew file mode 100644 index 000000000..e8c35fdea --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/repositoryWithDependencyToEssential/componentA/3.0.0content.7z diff --git a/tests/auto/installer/commandlineupdate/data/repositoryWithDependencyToEssential/componentAutoDependOnA/1.0content.7z b/tests/auto/installer/commandlineupdate/data/repositoryWithDependencyToEssential/componentAutoDependOnA/1.0content.7z Binary files differnew file mode 100644 index 000000000..0f3b123e0 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/data/repositoryWithDependencyToEssential/componentAutoDependOnA/1.0content.7z diff --git a/tests/auto/installer/commandlineupdate/settings.qrc b/tests/auto/installer/commandlineupdate/settings.qrc new file mode 100644 index 000000000..c8f328d6b --- /dev/null +++ b/tests/auto/installer/commandlineupdate/settings.qrc @@ -0,0 +1,62 @@ +<RCC> + <qresource prefix="/"> + <file>data/config.xml</file> + <file>data/installPackagesRepository/Updates.xml</file> + <file>data/installPackagesRepository/componentA/1.0.0content.7z</file> + <file>data/installPackagesRepository/componentB/1.0.0content.7z</file> + <file>data/installPackagesRepository/componentC/1.0.0content.7z</file> + <file>data/installPackagesRepository/componentD/1.0.0content.7z</file> + <file>data/installPackagesRepository/componentE/1.0.0content.7z</file> + <file>data/installPackagesRepository/componentF/1.0.0content.7z</file> + <file>data/installPackagesRepository/componentG/1.0.0content.7z</file> + <file>data/installPackagesRepository/componentG/1.0.0meta.7z</file> + <file>data/installPackagesRepository/componentH/1.0.0content.7z</file> + <file>data/installPackagesRepository/componentF.subcomponent1/1.0.0content.7z</file> + <file>data/installPackagesRepository/componentF.subcomponent2/1.0.0content.7z</file> + <file>data/installPackagesRepository/componentF.subcomponent1.subsubcomponent1/1.0.0content.7z</file> + <file>data/installPackagesRepository/componentF.subcomponent1.subsubcomponent2/1.0.0content.7z</file> + <file>data/installPackagesRepository/componentF.subcomponent2.subsubcomponent1/1.0.0content.7z</file> + <file>data/installPackagesRepository/componentF.subcomponent2.subsubcomponent2/1.0.0content.7z</file> + <file>data/installPackagesRepository/qt.tools.qtcreator/1.0.0content.7z</file> + <file>data/installPackagesRepository/qt.tools.qtcreator.enterprise.plugins/1.0.0content.7z</file> + <file>data/installPackagesRepositoryUpdate/Updates.xml</file> + <file>data/installPackagesRepositoryUpdate/componentA/1.0.0content.7z</file> + <file>data/installPackagesRepositoryUpdate/componentB/2.0.0content.7z</file> + <file>data/installPackagesRepositoryUpdate/componentC/2.0.0content.7z</file> + <file>data/installPackagesRepositoryUpdate/componentD/2.0.0content.7z</file> + <file>data/installPackagesRepositoryUpdate/componentE/2.0.0content.7z</file> + <file>data/installPackagesRepositoryUpdate/componentF/2.0.0content.7z</file> + <file>data/installPackagesRepositoryUpdate/componentG/2.0.0content.7z</file> + <file>data/installPackagesRepositoryUpdate/componentG/2.0.0meta.7z</file> + <file>data/installPackagesRepositoryUpdate/componentH/1.0.0content.7z</file> + <file>data/installPackagesRepositoryUpdate/componentF.subcomponent1/1.0.0content.7z</file> + <file>data/installPackagesRepositoryUpdate/componentF.subcomponent2/2.0.0content.7z</file> + <file>data/installPackagesRepositoryUpdate/componentF.subcomponent1.subsubcomponent1/1.0.0content.7z</file> + <file>data/installPackagesRepositoryUpdate/componentF.subcomponent1.subsubcomponent2/1.0.0content.7z</file> + <file>data/installPackagesRepositoryUpdate/componentF.subcomponent2.subsubcomponent1/1.0.0content.7z</file> + <file>data/installPackagesRepositoryUpdate/componentF.subcomponent2.subsubcomponent2/1.0.0content.7z</file> + <file>data/installPackagesRepositoryUpdateWithEssential/Updates.xml</file> + <file>data/installPackagesRepositoryUpdateWithEssential/componentA/2.0.0content.7z</file> + <file>data/installPackagesRepositoryUpdateWithEssential/componentB/2.0.0content.7z</file> + <file>data/installPackagesRepositoryUpdateWithEssential/componentC/2.0.0content.7z</file> + <file>data/installPackagesRepositoryUpdateWithEssential/componentD/2.0.0content.7z</file> + <file>data/installPackagesRepositoryUpdateWithEssential/componentE/2.0.0content.7z</file> + <file>data/installPackagesRepositoryUpdateWithEssential/componentF/2.0.0content.7z</file> + <file>data/installPackagesRepositoryUpdateWithEssential/componentG/2.0.0content.7z</file> + <file>data/installPackagesRepositoryUpdateWithEssential/componentG/2.0.0meta.7z</file> + <file>data/installPackagesRepositoryUpdateWithEssential/componentH/2.0.0content.7z</file> + <file>data/installPackagesRepositoryUpdateWithEssential/componentF.subcomponent1/1.0.0content.7z</file> + <file>data/installPackagesRepositoryUpdateWithEssential/componentF.subcomponent2/2.0.0content.7z</file> + <file>data/installPackagesRepositoryUpdateWithEssential/componentF.subcomponent1.subsubcomponent1/1.0.0content.7z</file> + <file>data/installPackagesRepositoryUpdateWithEssential/componentF.subcomponent1.subsubcomponent2/1.0.0content.7z</file> + <file>data/installPackagesRepositoryUpdateWithEssential/componentF.subcomponent2.subsubcomponent1/1.0.0content.7z</file> + <file>data/installPackagesRepositoryUpdateWithEssential/componentF.subcomponent2.subsubcomponent2/1.0.0content.7z</file> + <file>data/repositoryWithDependencyToEssential/Updates.xml</file> + <file>data/repositoryWithDependencyToEssential/componentAutoDependOnA/1.0content.7z</file> + <file>data/repositoryWithDependencyToEssential/componentA/3.0.0content.7z</file> + <file>data/repositoryUpdateWithReplacements/Updates.xml</file> + <file>data/repositoryUpdateWithReplacements/qt.tools.qtcreator/2.0.0content.7z</file> + <file>data/repositoryUpdateWithReplacements/qt.tools.qtcreator_gui/2.0.0content.7z</file> + <file>data/repositoryUpdateWithReplacements/qt.tools.qtcreator_gui.enterprise.plugins/2.0.0content.7z</file> + </qresource> +</RCC> diff --git a/tests/auto/installer/commandlineupdate/tst_commandlineupdate.cpp b/tests/auto/installer/commandlineupdate/tst_commandlineupdate.cpp new file mode 100644 index 000000000..0faeecf74 --- /dev/null +++ b/tests/auto/installer/commandlineupdate/tst_commandlineupdate.cpp @@ -0,0 +1,418 @@ +/************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ + +#include "../shared/packagemanager.h" +#include "../shared/verifyinstaller.h" + +#include <component.h> +#include <packagemanagercore.h> + +#include <QLoggingCategory> +#include <QTest> + +using namespace QInstaller; + +typedef QList<QPair<QString, QString> > ComponentResourceHash; +typedef QPair<QString, QString> ComponentResource; + +class tst_CommandLineUpdate : public QObject +{ + Q_OBJECT + +private: + void setRepository(const QString &repository, PackageManagerCore *core) + { + core->reset(); + core->cancelMetaInfoJob(); //Call cancel to reset metadata so that update repositories are fetched + + QSet<Repository> repoList; + Repository repo = Repository::fromUserInput(repository); + repoList.insert(repo); + core->settings().setDefaultRepositories(repoList); + } + +private slots: + + void testUpdate_data() + { + QTest::addColumn<QString>("repository"); + QTest::addColumn<QStringList>("installComponents"); + QTest::addColumn<PackageManagerCore::Status>("status"); + QTest::addColumn<ComponentResourceHash>("componentResources"); + QTest::addColumn<QStringList >("installedFiles"); + QTest::addColumn<QString>("updateRepository"); + QTest::addColumn<QStringList>("updateComponents"); + QTest::addColumn<PackageManagerCore::Status>("updateStatus"); + QTest::addColumn<ComponentResourceHash>("componentResourcesAfterUpdate"); + QTest::addColumn<QStringList >("installedFilesAfterUpdate"); + QTest::addColumn<ComponentResourceHash >("deletedComponentResources"); + + /*********** Update essential packages **********/ + ComponentResourceHash componentResources; + componentResources.append(ComponentResource("componentA", "1.0.0content.txt")); + componentResources.append(ComponentResource("componentE", "1.0.0content.txt")); + + ComponentResourceHash componentResourcesAfterUpdate; + componentResourcesAfterUpdate.append(ComponentResource("componentA", "2.0.0content.txt")); + componentResourcesAfterUpdate.append(ComponentResource("componentE", "1.0.0content.txt")); + + ComponentResourceHash deletedComponentResources; + deletedComponentResources.append(ComponentResource("componentA", "1.0.0content.txt")); + + QTest::newRow("Update essential packages") + << ":///data/installPackagesRepository" + << (QStringList() << "componentA") + << PackageManagerCore::Success + << componentResources + << (QStringList() << "components.xml" << "installcontent.txt" + << "installcontentA.txt" << "installcontentE.txt" << "installcontentG.txt") + << ":///data/installPackagesRepositoryUpdateWithEssential" + << (QStringList() << "componentB") + << PackageManagerCore::EssentialUpdated + << componentResourcesAfterUpdate + << (QStringList() << "components.xml" + << "installcontentA_update.txt" << "installcontentE.txt" << "installcontentG.txt") + << deletedComponentResources; + + /*********** Update essential with autodependon**********/ + componentResourcesAfterUpdate.clear(); + componentResourcesAfterUpdate.append(ComponentResource("componentA", "3.0.0content.txt")); + componentResourcesAfterUpdate.append(ComponentResource("componentAutoDependOnA", "1.0content.txt")); + + QTest::newRow("Update essential with autodependon") + << ":///data/installPackagesRepository" + << (QStringList() << "componentA") + << PackageManagerCore::Success + << componentResources + << (QStringList() << "components.xml" << "installcontent.txt" + << "installcontentA.txt" << "installcontentE.txt" << "installcontentG.txt") + << ":///data/repositoryWithDependencyToEssential" + << (QStringList()) + << PackageManagerCore::EssentialUpdated + << componentResourcesAfterUpdate + << (QStringList() << "components.xml" + << "installcontentA_update.txt" << "installcontentE.txt" << "installcontentG.txt" + << "installContentAutoDependOnA.txt") + << deletedComponentResources; + + + /*********** Update force update packages **********/ + componentResources.clear(); + componentResources.append(ComponentResource("componentH", "1.0.0content.txt")); + componentResources.append(ComponentResource("componentE", "1.0.0content.txt")); + + componentResourcesAfterUpdate.clear(); + componentResourcesAfterUpdate.append(ComponentResource("componentH", "2.0.0content.txt")); + componentResourcesAfterUpdate.append(ComponentResource("componentE", "1.0.0content.txt")); + + deletedComponentResources.clear(); + deletedComponentResources.append(ComponentResource("componentH", "1.0.0content.txt")); + + QTest::newRow("Update force update packages") + << ":///data/installPackagesRepository" + << (QStringList() << "componentH") + << PackageManagerCore::Success + << componentResources + << (QStringList() << "components.xml" << "installcontent.txt" + << "installcontentA.txt" << "installcontentE.txt" << "installcontentG.txt" + << "installcontentH.txt") + << ":///data/installPackagesRepositoryUpdateWithEssential" + << (QStringList()) + << PackageManagerCore::EssentialUpdated + << componentResourcesAfterUpdate + << (QStringList() << "components.xml" << "installcontentA_update.txt" + << "installcontentE.txt" << "installcontentG.txt" + << "installcontentH_update.txt") + << deletedComponentResources; + + /*********** Update packages **********/ + componentResources.clear(); + componentResources.append(ComponentResource("componentA", "1.0.0content.txt")); + componentResources.append(ComponentResource("componentB", "1.0.0content.txt")); + componentResources.append(ComponentResource("componentD", "1.0.0content.txt")); + + componentResourcesAfterUpdate.clear(); + componentResourcesAfterUpdate.append(ComponentResource("componentA", "1.0.0content.txt")); + componentResourcesAfterUpdate.append(ComponentResource("componentB", "2.0.0content.txt")); + componentResourcesAfterUpdate.append(ComponentResource("componentD", "2.0.0content.txt")); + componentResourcesAfterUpdate.append(ComponentResource("componentE", "2.0.0content.txt")); + + deletedComponentResources.clear(); + deletedComponentResources.append(ComponentResource("componentB", "1.0.0content.txt")); + deletedComponentResources.append(ComponentResource("componentD", "1.0.0content.txt")); + deletedComponentResources.append(ComponentResource("componentE", "1.0.0content.txt")); + + QTest::newRow("Update packages") + << ":///data/installPackagesRepository" + << (QStringList() << "componentC" << "componentH") + << PackageManagerCore::Success + << componentResources + << (QStringList() << "components.xml" << "installcontent.txt" + << "installcontentA.txt" << "installcontentB.txt" << "installcontentC.txt" << "installcontentD.txt" + << "installcontentE.txt" << "installcontentG.txt" << "installcontentH.txt") + << ":///data/installPackagesRepositoryUpdate" + << (QStringList()) + << PackageManagerCore::Success + << componentResourcesAfterUpdate + << (QStringList() << "components.xml" << "installcontent.txt" + << "installcontentA.txt" << "installcontentB_update.txt" << "installcontentC_update.txt" << "installcontentD_update.txt" + << "installcontentE_update.txt" << "installcontentG_update.txt" << "installcontentH.txt") + << deletedComponentResources; + + /*********** Update two packages **********/ + componentResources.clear(); + componentResources.append(ComponentResource("componentA", "1.0.0content.txt")); + componentResources.append(ComponentResource("componentB", "1.0.0content.txt")); + componentResources.append(ComponentResource("componentD", "1.0.0content.txt")); + componentResources.append(ComponentResource("componentE", "1.0.0content.txt")); + componentResources.append(ComponentResource("componentG", "1.0.0content.txt")); + + componentResourcesAfterUpdate.clear(); + componentResourcesAfterUpdate.append(ComponentResource("componentA", "1.0.0content.txt")); + componentResourcesAfterUpdate.append(ComponentResource("componentB", "1.0.0content.txt")); + componentResourcesAfterUpdate.append(ComponentResource("componentD", "1.0.0content.txt"));//AutodepenOn componentA,componentB + componentResourcesAfterUpdate.append(ComponentResource("componentE", "2.0.0content.txt")); + componentResourcesAfterUpdate.append(ComponentResource("componentG", "2.0.0content.txt")); + + deletedComponentResources.clear(); + deletedComponentResources.append(ComponentResource("componentE", "1.0.0content.txt")); + deletedComponentResources.append(ComponentResource("componentG", "1.0.0content.txt")); + + QTest::newRow("Update two packages") + << ":///data/installPackagesRepository" + << (QStringList()<< "componentA" << "componentB" << "componentE" << "componentG") + << PackageManagerCore::Success + << componentResources + << (QStringList() << "components.xml" << "installcontent.txt" << "installcontentA.txt" + << "installcontentD.txt" << "installcontentB.txt" << "installcontentE.txt" + << "installcontentG.txt") + << ":///data/installPackagesRepositoryUpdate" + << (QStringList() << "componentE" << "componentG") + << PackageManagerCore::Success + << componentResourcesAfterUpdate + << (QStringList() << "components.xml" << "installcontent.txt" << "installcontentA.txt" + << "installcontentD.txt" << "installcontentB.txt" + << "installcontentE_update.txt" << "installcontentG_update.txt") + << deletedComponentResources; + + /*********** Update all packages **********/ + componentResources.clear(); + componentResources.append(ComponentResource("componentA", "1.0.0content.txt")); + componentResources.append(ComponentResource("componentB", "1.0.0content.txt")); + componentResources.append(ComponentResource("componentC", "1.0.0content.txt")); + componentResources.append(ComponentResource("componentD", "1.0.0content.txt")); + componentResources.append(ComponentResource("componentE", "1.0.0content.txt")); + componentResources.append(ComponentResource("componentF", "1.0.0content.txt")); + componentResources.append(ComponentResource("componentF.subcomponent1", "1.0.0content.txt")); + componentResources.append(ComponentResource("componentF.subcomponent1.subsubcomponent1", "1.0.0content.txt")); + componentResources.append(ComponentResource("componentF.subcomponent1.subsubcomponent2", "1.0.0content.txt")); + componentResources.append(ComponentResource("componentF.subcomponent2", "1.0.0content.txt")); + componentResources.append(ComponentResource("componentF.subcomponent2.subsubcomponent1", "1.0.0content.txt")); + componentResources.append(ComponentResource("componentF.subcomponent2.subsubcomponent2", "1.0.0content.txt")); + componentResources.append(ComponentResource("componentG", "1.0.0content.txt")); + componentResources.append(ComponentResource("componentH", "1.0.0content.txt")); + + componentResourcesAfterUpdate.clear(); + componentResourcesAfterUpdate.append(ComponentResource("componentA", "1.0.0content.txt")); + componentResourcesAfterUpdate.append(ComponentResource("componentB", "2.0.0content.txt")); + componentResourcesAfterUpdate.append(ComponentResource("componentC", "2.0.0content.txt")); + componentResourcesAfterUpdate.append(ComponentResource("componentD", "2.0.0content.txt")); + componentResourcesAfterUpdate.append(ComponentResource("componentE", "2.0.0content.txt")); + componentResourcesAfterUpdate.append(ComponentResource("componentF", "2.0.0content.txt")); + componentResourcesAfterUpdate.append(ComponentResource("componentF.subcomponent1", "1.0.0content.txt")); + componentResourcesAfterUpdate.append(ComponentResource("componentF.subcomponent1.subsubcomponent1", "1.0.0content.txt")); + componentResourcesAfterUpdate.append(ComponentResource("componentF.subcomponent1.subsubcomponent2", "1.0.0content.txt")); + componentResourcesAfterUpdate.append(ComponentResource("componentF.subcomponent2", "2.0.0content.txt")); + componentResourcesAfterUpdate.append(ComponentResource("componentF.subcomponent2.subsubcomponent1", "1.0.0content.txt")); + componentResourcesAfterUpdate.append(ComponentResource("componentF.subcomponent2.subsubcomponent2", "1.0.0content.txt")); + componentResourcesAfterUpdate.append(ComponentResource("componentG", "2.0.0content.txt")); + componentResourcesAfterUpdate.append(ComponentResource("componentH", "1.0.0content.txt")); + + deletedComponentResources.clear(); + deletedComponentResources.append(ComponentResource("componentB", "1.0.0content.txt")); + deletedComponentResources.append(ComponentResource("componentD", "1.0.0content.txt")); + deletedComponentResources.append(ComponentResource("componentE", "1.0.0content.txt")); + deletedComponentResources.append(ComponentResource("componentF", "1.0.0content.txt")); + deletedComponentResources.append(ComponentResource("componentF.subcomponent2", "1.0.0content.txt")); + deletedComponentResources.append(ComponentResource("componentG", "1.0.0content.txt")); + + QTest::newRow("Update all packages") + << ":///data/installPackagesRepository" + << (QStringList() << "componentA" << "componentB" << "componentC" << "componentD" << "componentE" + << "componentF" << "componentG" << "componentH") + << PackageManagerCore::Success + << componentResources + << (QStringList() << "components.xml" << "installcontent.txt" << "installcontentA.txt" + << "installcontentB.txt" << "installcontentC.txt" << "installcontentD.txt" + << "installcontentE.txt" << "installcontentF.txt" << "installcontentF_1.txt" << "installcontentF_1_1.txt" + << "installcontentF_1_2.txt" << "installcontentF_2.txt" << "installcontentF_2_1.txt" << "installcontentF_2_2.txt" + << "installcontentG.txt" << "installcontentH.txt") + << ":///data/installPackagesRepositoryUpdate" + << (QStringList()) + << PackageManagerCore::Success + << componentResourcesAfterUpdate + << (QStringList() << "components.xml" << "installcontent.txt" << "installcontentA.txt" + << "installcontentB_update.txt" << "installcontentC_update.txt" << "installcontentD_update.txt" + << "installcontentE_update.txt" << "installcontentF_update.txt" << "installcontentF_1.txt" << "installcontentF_1_1.txt" + << "installcontentF_1_2.txt" << "installcontentF_2_update.txt" << "installcontentF_2_1.txt" << "installcontentF_2_2.txt" + << "installcontentG_update.txt" << "installcontentH.txt") + << deletedComponentResources; + + /*********** Update packages with AutoDependOn **********/ + componentResources.clear(); + componentResources.append(ComponentResource("componentA", "1.0.0content.txt")); + componentResources.append(ComponentResource("componentB", "1.0.0content.txt")); + componentResources.append(ComponentResource("componentD", "1.0.0content.txt")); + componentResources.append(ComponentResource("componentE", "1.0.0content.txt")); + componentResources.append(ComponentResource("componentG", "1.0.0content.txt")); + + componentResourcesAfterUpdate.clear(); + componentResourcesAfterUpdate.append(ComponentResource("componentA", "1.0.0content.txt")); + componentResourcesAfterUpdate.append(ComponentResource("componentB", "2.0.0content.txt")); + componentResourcesAfterUpdate.append(ComponentResource("componentD", "2.0.0content.txt"));//AutodepenOn componentA,componentB + componentResourcesAfterUpdate.append(ComponentResource("componentE", "1.0.0content.txt"));//ForcedInstall, not updated without user selection + componentResourcesAfterUpdate.append(ComponentResource("componentG", "1.0.0content.txt")); + + deletedComponentResources.clear(); + deletedComponentResources.append(ComponentResource("componentB", "1.0.0content.txt")); + deletedComponentResources.append(ComponentResource("componentD", "1.0.0content.txt")); + + QTest::newRow("Update packages with AutoDependOn") + << ":///data/installPackagesRepository" + << (QStringList()<< "componentA" << "componentB" << "componentE" << "componentG") + << PackageManagerCore::Success + << componentResources + << (QStringList() << "components.xml" << "installcontent.txt" << "installcontentA.txt" + << "installcontentD.txt" << "installcontentB.txt" << "installcontentE.txt" + << "installcontentG.txt") + << ":///data/installPackagesRepositoryUpdate" + << (QStringList() << "componentB") + << PackageManagerCore::Success + << componentResourcesAfterUpdate + << (QStringList() << "components.xml" << "installcontent.txt" << "installcontentA.txt" + << "installcontentD_update.txt" << "installcontentB_update.txt" + << "installcontentE.txt" << "installcontentG.txt") + << deletedComponentResources; + + /*********** Update packages with replacements **********/ + componentResources.clear(); + componentResources.append(ComponentResource("qt.tools.qtcreator", "1.0.0content.txt")); + componentResources.append(ComponentResource("qt.tools.qtcreator.enterprise.plugins", "1.0.0content.txt")); + componentResources.append(ComponentResource("componentE", "1.0.0content.txt")); + + componentResourcesAfterUpdate.clear(); + componentResourcesAfterUpdate.append(ComponentResource("qt.tools.qtcreator", "2.0.0content.txt")); + componentResourcesAfterUpdate.append(ComponentResource("qt.tools.qtcreator_gui", "2.0.0content.txt")); + componentResourcesAfterUpdate.append(ComponentResource("qt.tools.qtcreator_gui.enterprise.plugins", "2.0.0content.txt")); + componentResourcesAfterUpdate.append(ComponentResource("componentE", "1.0.0content.txt")); + + deletedComponentResources.clear(); + deletedComponentResources.append(ComponentResource("qt.tools.qtcreator.enterprise.plugins", "1.0.0content.txt")); + + QTest::newRow("Update packages with replacements") + << ":///data/installPackagesRepository" + << (QStringList()<< "qt.tools.qtcreator") + << PackageManagerCore::Success + << componentResources + << (QStringList() << "components.xml" << "installcontentA.txt" << "installcontentE.txt" << "installcontentG.txt" + << "installcontent.txt" << "qtcreator.txt" << "plugins.txt") + << ":///data/repositoryUpdateWithReplacements" + << (QStringList() << "qt.tools.qtcreator") + << PackageManagerCore::Success + << componentResourcesAfterUpdate + << (QStringList() << "components.xml" << "installcontentA.txt" << "installcontentE.txt" << "installcontentG.txt" + << "installcontent.txt" << "gui.txt" << "qtcreator2.txt" << "gui_plugins.txt") + << deletedComponentResources; + } + + void testUpdate() + { + QFETCH(QString, repository); + QFETCH(QStringList, installComponents); + QFETCH(PackageManagerCore::Status, status); + QFETCH(ComponentResourceHash, componentResources); + QFETCH(QStringList, installedFiles); + QFETCH(QString, updateRepository); + QFETCH(QStringList, updateComponents); + QFETCH(PackageManagerCore::Status, updateStatus); + QFETCH(ComponentResourceHash, componentResourcesAfterUpdate); + QFETCH(QStringList, installedFilesAfterUpdate); + QFETCH(ComponentResourceHash, deletedComponentResources); + + PackageManagerCore *core = PackageManager::getPackageManagerWithInit(m_installDir, repository); + + QCOMPARE(status, core->installSelectedComponentsSilently(QStringList() << installComponents)); + for (const ComponentResource &resource : componentResources) { + VerifyInstaller::verifyInstallerResources(m_installDir, resource.first, resource.second); + } + VerifyInstaller::verifyFileExistence(m_installDir, installedFiles); + + core->commitSessionOperations(); + core->setPackageManager(); + setRepository(updateRepository, core); + QCOMPARE(updateStatus, core->updateComponentsSilently(updateComponents)); + + for (const ComponentResource &resource : componentResourcesAfterUpdate) { + VerifyInstaller::verifyInstallerResources(m_installDir, resource.first, resource.second); + } + for (const ComponentResource &resource : deletedComponentResources) { + VerifyInstaller::verifyInstallerResourceFileDeletion(m_installDir, resource.first, resource.second); + } + VerifyInstaller::verifyFileExistence(m_installDir, installedFilesAfterUpdate); + delete core; + } + + void testUpdateNoUpdatesForSelectedPackage() + { + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (m_installDir, ":///data/installPackagesRepositoryUpdate")); + // No updates available for component so nothing to do + QCOMPARE(PackageManagerCore::Canceled, core->updateComponentsSilently(QStringList() + << "componentInvalid")); + } + + void init() + { + m_installDir = QInstaller::generateTemporaryFileName(); + QVERIFY(QDir().mkpath(m_installDir)); + } + + void cleanup() + { + QDir dir(m_installDir); + QVERIFY(dir.removeRecursively()); + } + +private: + QString m_installDir; +}; + + +QTEST_MAIN(tst_CommandLineUpdate) + +#include "tst_commandlineupdate.moc" diff --git a/tests/auto/installer/componentalias/componentalias.pro b/tests/auto/installer/componentalias/componentalias.pro new file mode 100644 index 000000000..efbc0268f --- /dev/null +++ b/tests/auto/installer/componentalias/componentalias.pro @@ -0,0 +1,8 @@ +include(../../qttest.pri) + +QT -= gui +QT += testlib + +SOURCES = tst_componentalias.cpp + +RESOURCES += settings.qrc diff --git a/tests/auto/installer/componentalias/data/aliases-optional.xml b/tests/auto/installer/componentalias/data/aliases-optional.xml new file mode 100644 index 000000000..2016592c1 --- /dev/null +++ b/tests/auto/installer/componentalias/data/aliases-optional.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="utf-8"?> +<Aliases> + <Alias> + <Name>set-A</Name> + <DisplayName>Installation A (optional component requirement)</DisplayName> + <Description>Installs component A</Description> + <Version>2.0.0</Version> + <Virtual>false</Virtual> + <RequiredComponents>A</RequiredComponents> + <OptionalComponents>component-nonexistent,B</OptionalComponents> + </Alias> + <Alias> + <Name>set-full</Name> + <DisplayName>Full installation (optional alias requirement)</DisplayName> + <Description>Installs all components</Description> + <Version>2.0.0</Version> + <Virtual>false</Virtual> + <OptionalAliases>set-A,set-nonexistent</OptionalAliases> + </Alias> + <Alias> + <Name>set-optional-broken</Name> + <DisplayName>Optionally requires broken alias</DisplayName> + <Description>Optionally requires broken alias</Description> + <Version>2.0.0</Version> + <Virtual>false</Virtual> + <OptionalAliases>set-broken</OptionalAliases> + </Alias> + <Alias> + <Name>set-broken</Name> + <DisplayName>Requires non-existent alias</DisplayName> + <Description>Requires non-existent alias</Description> + <Version>2.0.0</Version> + <Virtual>false</Virtual> + <RequiredAliases>set-nonexistent</RequiredAliases> + </Alias> + <Alias> + <Name>set-optional-broken-component</Name> + <DisplayName>Dependency to optional unstable component</DisplayName> + <Description>Dependency to optional unstable component</Description> + <Version>2.0.0</Version> + <Virtual>false</Virtual> + <OptionalComponents>UnstableComponent</OptionalComponents> + </Alias> +</Aliases> diff --git a/tests/auto/installer/componentalias/data/aliases-priority.xml b/tests/auto/installer/componentalias/data/aliases-priority.xml new file mode 100644 index 000000000..f90d006b2 --- /dev/null +++ b/tests/auto/installer/componentalias/data/aliases-priority.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8"?> +<Aliases> + <Alias> + <Name>set-A</Name> + <DisplayName>Installation A (priority)</DisplayName> + <Description>Installs component A</Description> + <Version>1.0.0</Version> + <Virtual>false</Virtual> + <RequiredComponents>A</RequiredComponents> + </Alias> + <Alias> + <Name>set-B</Name> + <DisplayName>Virtual installation B (priority)</DisplayName> + <Description>Installs component B</Description> + <Version>1.0.0</Version> + <Virtual>true</Virtual> + <RequiredComponents>B</RequiredComponents> + </Alias> + <Alias> + <Name>set-D</Name> + <DisplayName>Installation D (Unstable) (priority)</DisplayName> + <Description>Installs missing component D</Description> + <Version>1.0.0</Version> + <Virtual>false</Virtual> + <RequiredComponents>D</RequiredComponents> + </Alias> + <Alias> + <Name>set-full</Name> + <DisplayName>Full installation (priority)</DisplayName> + <Description>Installs all components</Description> + <Version>1.0.0</Version> + <Virtual>false</Virtual> + <RequiredAliases>set-A,set-B</RequiredAliases> + <RequiredComponents>C</RequiredComponents> + </Alias> +</Aliases> diff --git a/tests/auto/installer/componentalias/data/aliases-versions.xml b/tests/auto/installer/componentalias/data/aliases-versions.xml new file mode 100644 index 000000000..993e14673 --- /dev/null +++ b/tests/auto/installer/componentalias/data/aliases-versions.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8"?> +<Aliases> + <Alias> + <Name>set-A</Name> + <DisplayName>Installation A (updated)</DisplayName> + <Description>Installs component A</Description> + <Version>2.0.0</Version> + <Virtual>false</Virtual> + <RequiredComponents>A</RequiredComponents> + </Alias> + <Alias> + <Name>set-B</Name> + <DisplayName>Virtual installation B (updated)</DisplayName> + <Description>Installs component B</Description> + <Version>1.1.0</Version> + <Virtual>true</Virtual> + <RequiredComponents>B</RequiredComponents> + </Alias> + <Alias> + <Name>set-D</Name> + <DisplayName>Installation D (Unstable) (updated)</DisplayName> + <Description>Installs missing component D</Description> + <Version>1.2.0</Version> + <Virtual>false</Virtual> + <RequiredComponents>D</RequiredComponents> + </Alias> + <Alias> + <Name>set-full</Name> + <DisplayName>Full installation (updated)</DisplayName> + <Description>Installs all components</Description> + <Version>3.0.0</Version> + <Virtual>false</Virtual> + <RequiredAliases>set-A,set-B</RequiredAliases> + <RequiredComponents>C</RequiredComponents> + </Alias> +</Aliases> diff --git a/tests/auto/installer/componentalias/data/aliases.json b/tests/auto/installer/componentalias/data/aliases.json new file mode 100644 index 000000000..4c78e20d2 --- /dev/null +++ b/tests/auto/installer/componentalias/data/aliases.json @@ -0,0 +1,38 @@ +{ + "alias-packages": [ + { + "Description": "Installs component A", + "DisplayName": "Installation A (JSON)", + "Name": "set-A-json", + "RequiredComponents": [ + "A" + ], + "Version": "1.0.0", + "Virtual": false + }, + { + "Description": "Installs component B", + "DisplayName": "Virtual installation B (JSON)", + "Name": "set-B-json", + "RequiredComponents": [ + "B" + ], + "Version": "1.0.0", + "Virtual": true + }, + { + "Description": "Installs all components", + "DisplayName": "Full installation (JSON)", + "Name": "set-full-json", + "RequiredAliases": [ + "set-A-json", + "set-B-json" + ], + "RequiredComponents": [ + "C" + ], + "Version": "1.0.0", + "Virtual": false + } + ] +} diff --git a/tests/auto/installer/componentalias/data/repository/Updates.xml b/tests/auto/installer/componentalias/data/repository/Updates.xml new file mode 100644 index 000000000..64950244f --- /dev/null +++ b/tests/auto/installer/componentalias/data/repository/Updates.xml @@ -0,0 +1,51 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>true</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.2-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>false</Default> + </PackageUpdate> + <PackageUpdate> + <Name>B</Name> + <DisplayName>B</DisplayName> + <Description>Example component B</Description> + <Version>1.0.0-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>false</Default> + </PackageUpdate> + <PackageUpdate> + <Name>C</Name> + <DisplayName>C</DisplayName> + <Description>Example component C</Description> + <Version>1.0.0-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>false</Default> + </PackageUpdate> + <PackageUpdate> + <Name>C.subcomponent</Name> + <DisplayName>Subcomponent of C</DisplayName> + <Description>Example subcomponent</Description> + <Version>1.0.0-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + </PackageUpdate> + <PackageUpdate> + <Name>C.subcomponent.subcomponent</Name> + <DisplayName>Subcomponent of subcomponent component</DisplayName> + <Description>Example subcomponent of subcomponent</Description> + <Version>1.0.0-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + </PackageUpdate> + <PackageUpdate> + <Name>UnstableComponent</Name> + <DisplayName>Subcomponent of subcomponent component</DisplayName> + <Description>Example subcomponent of subcomponent</Description> + <Version>1.0.0-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Dependencies>missing.component</Dependencies> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/componentalias/metadata/installer-config/aliases.xml b/tests/auto/installer/componentalias/metadata/installer-config/aliases.xml new file mode 100644 index 000000000..2362e51c7 --- /dev/null +++ b/tests/auto/installer/componentalias/metadata/installer-config/aliases.xml @@ -0,0 +1,84 @@ +<?xml version="1.0" encoding="utf-8"?> +<Aliases> + <Alias> + <Name>set-A</Name> + <DisplayName>Installation A</DisplayName> + <Description>Installs component A</Description> + <Version>1.0.0</Version> + <Virtual>false</Virtual> + <RequiredComponents>A</RequiredComponents> + </Alias> + <Alias> + <Name>set-B</Name> + <DisplayName>Virtual installation B</DisplayName> + <Description>Installs component B</Description> + <Version>1.0.0</Version> + <Virtual>true</Virtual> + <RequiredComponents>B</RequiredComponents> + </Alias> + <Alias> + <Name>set-D</Name> + <DisplayName>Installation D (Unstable)</DisplayName> + <Description>Installs missing component D</Description> + <Version>1.0.0</Version> + <Virtual>false</Virtual> + <RequiredComponents>D</RequiredComponents> + </Alias> + <Alias> + <Name>set-E</Name> + <DisplayName>Installation E (Requires unstable)</DisplayName> + <Description>Installs set E</Description> + <Version>1.0.0</Version> + <Virtual>false</Virtual> + <RequiredAliases>set-D</RequiredAliases> + </Alias> + <Alias> + <Name>set-F</Name> + <DisplayName>Installation F (Requires alias that refers another unstable)</DisplayName> + <Description>Installs set F</Description> + <Version>1.0.0</Version> + <Virtual>false</Virtual> + <RequiredAliases>set-E</RequiredAliases> + </Alias> + <Alias> + <Name>set-full</Name> + <DisplayName>Full installation</DisplayName> + <Description>Installs all components</Description> + <Version>1.0.0</Version> + <Virtual>false</Virtual> + <RequiredAliases>set-A,set-B</RequiredAliases> + <RequiredComponents>C</RequiredComponents> + </Alias> + <Alias> + <Name>set-required-component-from-fallback</Name> + <DisplayName>Installation (fetches component from fallback repository)</DisplayName> + <Description>Installs component</Description> + <Version>1.0.0</Version> + <Virtual>false</Virtual> + <RequiredComponents>A</RequiredComponents> + </Alias> + <Alias> + <Name>set-optional-component-from-fallback</Name> + <DisplayName>Installation (fetches optional component from fallback repository)</DisplayName> + <Description>Installs component</Description> + <Version>1.0.0</Version> + <Virtual>false</Virtual> + <OptionalComponents>A</OptionalComponents> + </Alias> + <Alias> + <Name>set-optional-broken-component-from-fallback</Name> + <DisplayName>Installation (fetches optional component from fallback repository)</DisplayName> + <Description>Installs component</Description> + <Version>1.0.0</Version> + <Virtual>false</Virtual> + <OptionalComponents>UnstableComponent</OptionalComponents> + </Alias> + <Alias> + <Name>set-required-broken-component-from-fallback</Name> + <DisplayName>Installation (fetches optional component from fallback repository)</DisplayName> + <Description>Installs component</Description> + <Version>1.0.0</Version> + <Virtual>false</Virtual> + <RequiredComponents>UnstableComponent</RequiredComponents> + </Alias> +</Aliases> diff --git a/tests/auto/installer/componentalias/metadata/installer-config/config.xml b/tests/auto/installer/componentalias/metadata/installer-config/config.xml new file mode 100644 index 000000000..9e2b5af55 --- /dev/null +++ b/tests/auto/installer/componentalias/metadata/installer-config/config.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<Installer> + <Name>test</Name> + <Version>1.0.0</Version> + <AliasDefinitionsFile>aliases.xml</AliasDefinitionsFile> +</Installer> diff --git a/tests/auto/installer/componentalias/settings.qrc b/tests/auto/installer/componentalias/settings.qrc new file mode 100644 index 000000000..771586edd --- /dev/null +++ b/tests/auto/installer/componentalias/settings.qrc @@ -0,0 +1,11 @@ +<RCC> + <qresource prefix="/"> + <file>data/repository/Updates.xml</file> + <file>data/aliases.json</file> + <file>data/aliases-priority.xml</file> + <file>data/aliases-versions.xml</file> + <file>data/aliases-optional.xml</file> + <file>metadata/installer-config/config.xml</file> + <file>metadata/installer-config/aliases.xml</file> + </qresource> +</RCC> diff --git a/tests/auto/installer/componentalias/tst_componentalias.cpp b/tests/auto/installer/componentalias/tst_componentalias.cpp new file mode 100644 index 000000000..51f6ca635 --- /dev/null +++ b/tests/auto/installer/componentalias/tst_componentalias.cpp @@ -0,0 +1,433 @@ +/************************************************************************** +** +** Copyright (C) 2023 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ + +#include "../shared/packagemanager.h" +#include "../shared/verifyinstaller.h" + +#include <packagemanagercore.h> +#include <componentalias.h> + +#include <QTest> +#include <QLoggingCategory> + +using namespace QInstaller; + +class tst_ComponentAlias : public QObject +{ + Q_OBJECT + +private slots: + void init() + { + m_installDir = QInstaller::generateTemporaryFileName(); + QVERIFY(QDir().mkpath(m_installDir)); + m_fallbackRepositoryData = QLatin1String("========================================\n" + "Name: set-optional-broken-component-from-fallback\n" + "Display name: Installation (fetches optional component from fallback repository)\n" + "Description: Installs component\n" + "Version: 1.0.0\n" + "Components: \n" + "Required aliases: \n" + "Optional components: UnstableComponent\n" + "Optional aliases: \n" + "========================================\n" + "Name: set-optional-component-from-fallback\n" + "Display name: Installation (fetches optional component from fallback repository)\n" + "Description: Installs component\n" + "Version: 1.0.0\nComponents: \n" + "Required aliases: \n" + "Optional components: A\n" + "Optional aliases: \n" + "========================================\n" + "Name: set-required-broken-component-from-fallback\n" + "Display name: Installation (fetches optional component from fallback repository)\n" + "Description: Installs component\n" + "Version: 1.0.0\n" + "Components: UnstableComponent\n" + "Required aliases: \n" + "Optional components: \n" + "Optional aliases: \n" + "========================================\n" + "Name: set-required-component-from-fallback\n" + "Display name: Installation (fetches component from fallback repository)\n" + "Description: Installs component\n" + "Version: 1.0.0\nComponents: A\n" + "Required aliases: \n" + "Optional components: \n" + "Optional aliases: \n"); + } + + void cleanup() + { + QDir dir(m_installDir); + QVERIFY(dir.removeRecursively()); + } + + void testSearchAlias() + { + QString loggingRules = (QLatin1String("ifw.* = false\n")); + + QLoggingCategory::setFilterRules(loggingRules); + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManager + (m_installDir, ":///data/repository")); + + core->setCommandLineInstance(true); + + auto listMethod = &PackageManagerCore::listAvailableAliases; + + VerifyInstaller::verifyListPackagesMessage(core.get(), QLatin1String("\n" + "Name: set-A\n" + "Display name: Installation A\n" + "Description: Installs component A\n" + "Version: 1.0.0\n" + "Components: A\n" + "Required aliases: \n" + "Optional components: \n" + "Optional aliases: \n" + "========================================\n" + "Name: set-D\n" + "Display name: Installation D (Unstable)\n" + "Description: Installs missing component D\n" + "Version: 1.0.0\nComponents: D\n" + "Required aliases: \n" + "Optional components: \n" + "Optional aliases: \n" + "========================================\n" + "Name: set-E\n" + "Display name: Installation E (Requires unstable)\n" + "Description: Installs set E\nVersion: 1.0.0\nComponents: \n" + "Required aliases: set-D\n" + "Optional components: \n" + "Optional aliases: \n" + "========================================\n" + "Name: set-F\n" + "Display name: Installation F (Requires alias that refers another unstable)\n" + "Description: Installs set F\n" + "Version: 1.0.0\n" + "Components: \n" + "Required aliases: set-E\nOptional components: \n" + "Optional aliases: \n" + "========================================\n" + "Name: set-full\n" + "Display name: Full installation\n" + "Description: Installs all components\n" + "Version: 1.0.0\n" + "Components: C\n" + "Required aliases: set-A,set-B\n" + "Optional components: \n" + "Optional aliases: \n") + m_fallbackRepositoryData, listMethod, QString()); + + VerifyInstaller::verifyListPackagesMessage(core.get(), QLatin1String("\n" + "Name: set-A\n" + "Display name: Installation A\n" + "Description: Installs component A\n" + "Version: 1.0.0\n" + "Components: A\n" + "Required aliases: \n" + "Optional components: \n" + "Optional aliases: \n"), listMethod, QLatin1String("-A")); + } + + void testAliasSourceWithPriority() + { + QString loggingRules = (QLatin1String("ifw.* = false\n")); + + QLoggingCategory::setFilterRules(loggingRules); + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManager + (m_installDir, ":///data/repository")); + + core->setCommandLineInstance(true); + core->addAliasSource(AliasSource(AliasSource::SourceFileFormat::Xml, + ":///data/aliases-priority.xml", 1)); + + auto listMethod = &PackageManagerCore::listAvailableAliases; + + VerifyInstaller::verifyListPackagesMessage(core.get(), QLatin1String("\n" + "Name: set-A\n" + "Display name: Installation A (priority)\n" + "Description: Installs component A\n" + "Version: 1.0.0\n" + "Components: A\n" + "Required aliases: \n" + "Optional components: \n" + "Optional aliases: \n" + "========================================\n" + "Name: set-D\n" + "Display name: Installation D (Unstable) (priority)\n" + "Description: Installs missing component D\n" + "Version: 1.0.0\n" + "Components: D\n" + "Required aliases: \n" + "Optional components: \n" + "Optional aliases: \n" + "========================================\n" + "Name: set-E\n" + "Display name: Installation E (Requires unstable)\n" + "Description: Installs set E\n" + "Version: 1.0.0\n" + "Components: \n" + "Required aliases: set-D\n" + "Optional components: \n" + "Optional aliases: \n" + "========================================\n" + "Name: set-F\n" + "Display name: Installation F (Requires alias that refers another unstable)\n" + "Description: Installs set F\n" + "Version: 1.0.0\n" + "Components: \n" + "Required aliases: set-E\n" + "Optional components: \n" + "Optional aliases: \n" + "========================================\n" + "Name: set-full\n" + "Display name: Full installation (priority)\n" + "Description: Installs all components\n" + "Version: 1.0.0\n" + "Components: C\n" + "Required aliases: set-A,set-B\n" + "Optional components: \n" + "Optional aliases: \n") + m_fallbackRepositoryData, listMethod, QString()); + } + + void testAliasSourceWithVersionCompare() + { + QString loggingRules = (QLatin1String("ifw.* = false\n")); + + QLoggingCategory::setFilterRules(loggingRules); + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManager + (m_installDir, ":///data/repository")); + + core->setCommandLineInstance(true); + core->addAliasSource(AliasSource(AliasSource::SourceFileFormat::Xml, + ":///data/aliases-versions.xml", -1)); + + auto listMethod = &PackageManagerCore::listAvailableAliases; + + VerifyInstaller::verifyListPackagesMessage(core.get(), QLatin1String("\n" + "Name: set-A\n" + "Display name: Installation A (updated)\n" + "Description: Installs component A\n" + "Version: 2.0.0\n" + "Components: A\n" + "Required aliases: \n" + "Optional components: \n" + "Optional aliases: \n" + "========================================\n" + "Name: set-D\n" + "Display name: Installation D (Unstable) (updated)\n" + "Description: Installs missing component D\n" + "Version: 1.2.0\n" + "Components: D\n" + "Required aliases: \n" + "Optional components: \n" + "Optional aliases: \n" + "========================================\n" + "Name: set-E\n" + "Display name: Installation E (Requires unstable)\n" + "Description: Installs set E\n" + "Version: 1.0.0\n" + "Components: \n" + "Required aliases: set-D\n" + "Optional components: \n" + "Optional aliases: \n" + "========================================\n" + "Name: set-F\n" + "Display name: Installation F (Requires alias that refers another unstable)\n" + "Description: Installs set F\n" + "Version: 1.0.0\n" + "Components: \n" + "Required aliases: set-E\n" + "Optional components: \n" + "Optional aliases: \n" + "========================================\n" + "Name: set-full\n" + "Display name: Full installation (updated)\n" + "Description: Installs all components\n" + "Version: 3.0.0\n" + "Components: C\n" + "Required aliases: set-A,set-B\n" + "Optional components: \n" + "Optional aliases: \n") + m_fallbackRepositoryData, listMethod, QString()); + } + + void testInstallAlias_data() + { + QTest::addColumn<AliasSource>("additionalSource"); + QTest::addColumn<QStringList>("selectedAliases"); + QTest::addColumn<PackageManagerCore::Status>("status"); + QTest::addColumn<QStringList>("installedComponents"); + + QTest::newRow("Simple alias") + << AliasSource() + << (QStringList() << "set-A") + << PackageManagerCore::Success + << (QStringList() << "A"); + + QTest::newRow("Alias with dependencies") + << AliasSource() + << (QStringList() << "set-full") + << PackageManagerCore::Success + << (QStringList() << "A" << "B" << "C" << "C.subcomponent" << "C.subcomponent.subcomponent"); + + QTest::newRow("Alias with dependencies (JSON source)") + << AliasSource(AliasSource::SourceFileFormat::Json, ":///data/aliases.json", -1) + << (QStringList() << "set-full-json") + << PackageManagerCore::Success + << (QStringList() << "A" << "B" << "C" << "C.subcomponent" << "C.subcomponent.subcomponent"); + + QTest::newRow("Alias with optional components (existent and non-existent)") + << AliasSource(AliasSource::SourceFileFormat::Xml, ":///data/aliases-optional.xml", -1) + << (QStringList() << "set-A") + << PackageManagerCore::Success + << (QStringList() << "A" << "B"); + + QTest::newRow("Alias with optional aliases (existent and non-existent)") + << AliasSource(AliasSource::SourceFileFormat::Xml, ":///data/aliases-optional.xml", -1) + << (QStringList() << "set-full") + << PackageManagerCore::Success + << (QStringList() << "A" << "B"); + + QTest::newRow("Alias with optional broken alias (will install)") + << AliasSource(AliasSource::SourceFileFormat::Xml, ":///data/aliases-optional.xml", -1) + << (QStringList() << "set-optional-broken") + << PackageManagerCore::Success + << QStringList(); + + QTest::newRow("Alias with optional broken component (will install)") + << AliasSource(AliasSource::SourceFileFormat::Xml, ":///data/aliases-optional.xml", -1) + << (QStringList() << "set-optional-broken-component") + << PackageManagerCore::Success + << QStringList(); + } + + void testInstallAlias() + { + QFETCH(AliasSource, additionalSource); + QFETCH(QStringList, selectedAliases); + QFETCH(PackageManagerCore::Status, status); + QFETCH(QStringList, installedComponents); + + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (m_installDir, ":///data/repository")); + + core->setCommandLineInstance(true); + + if (!additionalSource.filename.isEmpty()) + core->addAliasSource(additionalSource); + core->settings().setAllowUnstableComponents(true); + QCOMPARE(core->installSelectedComponentsSilently(selectedAliases), status); + + for (const QString &component : installedComponents) + QVERIFY(core->componentByName(component)->isInstalled()); + } + + void testInstallAliasFails_data() + { + QTest::addColumn<QStringList>("selectedAliases"); + QTest::addColumn<PackageManagerCore::Status>("status"); + + QTest::newRow("Virtual alias") + << (QStringList() << "set-B") + << PackageManagerCore::Canceled; + + QTest::newRow("Unstable alias") + << (QStringList() << "set-D") + << PackageManagerCore::Canceled; + + QTest::newRow("Nested reference to unstable alias") + << (QStringList() << "set-F") + << PackageManagerCore::Canceled; + } + + void testInstallAliasFails() + { + QFETCH(QStringList, selectedAliases); + QFETCH(PackageManagerCore::Status, status); + + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (m_installDir, ":///data/repository")); + + core->setCommandLineInstance(true); + + QCOMPARE(core->installSelectedComponentsSilently(selectedAliases), status); + } + + void testInstallAliasWithFallbackRepositories_data() + { + QTest::addColumn<QStringList>("selectedAliases"); + QTest::addColumn<PackageManagerCore::Status>("status"); + QTest::addColumn<QStringList>("installedComponents"); + + QTest::newRow("Component from fallback") + << (QStringList() << "set-required-component-from-fallback") + << PackageManagerCore::Success + << (QStringList() << "A"); + QTest::newRow("Optional component from fallback") + << (QStringList() << "set-optional-component-from-fallback") + << PackageManagerCore::Success + << (QStringList() << "A"); + QTest::newRow("Optional broken component from fallback") + << (QStringList() << "set-optional-broken-component-from-fallback") + << PackageManagerCore::Success + << (QStringList()); + QTest::newRow("Required broke component from fallback") + << (QStringList() << "set-required-broken-component-from-fallback") + << PackageManagerCore::Canceled + << (QStringList()); + } + + void testInstallAliasWithFallbackRepositories() + { + QFETCH(QStringList, selectedAliases); + QFETCH(PackageManagerCore::Status, status); + QFETCH(QStringList, installedComponents); + + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit(m_installDir)); + + core->setCommandLineInstance(true); + core->settings().setAllowUnstableComponents(true); + QSet<RepositoryCategory> repositoryCategories; + RepositoryCategory repositoryCategory; + repositoryCategory.setEnabled(false); + repositoryCategory.addRepository(Repository::fromUserInput(":///data/repository")); + repositoryCategories.insert(repositoryCategory); + core->settings().addRepositoryCategories(repositoryCategories); + QCOMPARE(core->installSelectedComponentsSilently(selectedAliases), status); + + for (const QString &component : installedComponents) + QVERIFY(core->componentByName(component)->isInstalled()); + } + +private: + QString m_installDir; + QString m_fallbackRepositoryData; +}; + +QTEST_GUILESS_MAIN(tst_ComponentAlias) + +#include "tst_componentalias.moc" diff --git a/tests/auto/installer/componentmodel/data/updates.xml b/tests/auto/installer/componentmodel/data/updates.xml index 2341866ee..cc2da0f8e 100644 --- a/tests/auto/installer/componentmodel/data/updates.xml +++ b/tests/auto/installer/componentmodel/data/updates.xml @@ -8,6 +8,8 @@ <DisplayName xml:lang="ru_RU">Корневая компонента</DisplayName> <DisplayName xml:lang="de_DE">Wurzel Komponente</DisplayName> <Description>Install this example.</Description> + <Description xml:lang="ru_RU">Установите этот пример.</Description> + <Description xml:lang="de_DE">Installieren Sie dieses Beispiel.</Description> <Version>0.1.0-1</Version> <ReleaseDate>2010-09-21</ReleaseDate> <Default>true</Default> @@ -177,4 +179,14 @@ file="license.txt"/> </Licenses> </PackageUpdate> + <PackageUpdate> + <Name>com.vendor.fifth.product.noncheckable.sub2</Name> + <DisplayName>A sub component, moved to top level</DisplayName> + <Description>Install this example.</Description> + <Version>0.1.0-1</Version> + <ReleaseDate>2010-09-21</ReleaseDate> + <SortingPriority>0</SortingPriority> + <UpdateFile UncompressedSize="61" CompressedSize="61"/> + <TreeName>moved_with_treename</TreeName> + </PackageUpdate> </Updates> diff --git a/tests/auto/installer/componentmodel/tst_componentmodel.cpp b/tests/auto/installer/componentmodel/tst_componentmodel.cpp index d5cae916c..276292233 100644 --- a/tests/auto/installer/componentmodel/tst_componentmodel.cpp +++ b/tests/auto/installer/componentmodel/tst_componentmodel.cpp @@ -1,3 +1,31 @@ +/************************************************************************** +** +** Copyright (C) 2023 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ + #include "component.h" #include "componentmodel.h" #include "updatesinfo_p.h" @@ -9,8 +37,8 @@ using namespace KDUpdater; using namespace QInstaller; -#define EXPECTED_COUNT_VIRTUALS_VISIBLE 11 -#define EXPECTED_COUNT_VIRTUALS_INVISIBLE 10 +#define EXPECTED_COUNT_VIRTUALS_VISIBLE 12 +#define EXPECTED_COUNT_VIRTUALS_INVISIBLE 11 static const char vendorProduct[] = "com.vendor.product"; static const char vendorSecondProduct[] = "com.vendor.second.product"; @@ -23,6 +51,7 @@ static const char vendorThirdProductVirtual[] = "com.vendor.third.product.virtua static const char vendorFourthProductCheckable[] = "com.vendor.fourth.product.checkable"; static const char vendorFifthProductNonCheckable[] = "com.vendor.fifth.product.noncheckable"; static const char vendorFifthProductSub[] = "com.vendor.fifth.product.noncheckable.sub"; +static const char vendorFifthProductSubWithTreeName[] = "moved_with_treename"; static const QMap<QString, QString> rootComponentDisplayNames = { {"", QLatin1String("The root component")}, @@ -30,6 +59,12 @@ static const QMap<QString, QString> rootComponentDisplayNames = { {"de_de", QString::fromUtf8("Wurzel Komponente")} }; +static const QMap<QString, QString> rootComponentDescriptions = { + {"", QLatin1String("Install this example.")}, + {"ru_ru", QString::fromUtf8("Установите этот пример.")}, + {"de_de", QString::fromUtf8("Installieren Sie dieses Beispiel.")} +}; + class tst_ComponentModel : public QObject { Q_OBJECT @@ -38,7 +73,8 @@ public: enum Option { NoFlags = 0x00, VirtualsVisible = 0x01, - NoForcedInstallation = 0x02 + NoForcedInstallation = 0x02, + NoDefaultInstallation = 0x04 }; Q_DECLARE_FLAGS(Options, Option); @@ -49,7 +85,7 @@ private slots: m_defaultPartially << vendorSecondProduct; m_defaultUnchecked << vendorSecondProductSub1 << vendorSecondProductSubnode << vendorSecondProductSubnodeSub << vendorFourthProductCheckable - << vendorFifthProductSub; + << vendorFifthProductSub << vendorFifthProductSubWithTreeName; m_uncheckable << vendorFifthProductNonCheckable; } @@ -62,7 +98,7 @@ private slots: // setup the model with 1 column ComponentModel model(1, &m_core); - model.setRootComponents(rootComponents); + model.reset(rootComponents); // all names should be resolvable, virtual components are not indexed if they are not visible QStringList all; @@ -70,7 +106,7 @@ private slots: foreach (const QString &name, all) { QVERIFY(model.indexFromComponentName(name).isValid()); QVERIFY(model.componentFromIndex(model.indexFromComponentName(name)) != 0); - QCOMPARE(model.componentFromIndex(model.indexFromComponentName(name))->name(), name); + QCOMPARE(model.componentFromIndex(model.indexFromComponentName(name))->treeName(), name); } foreach (Component *const component, rootComponents) @@ -86,7 +122,7 @@ private slots: // setup the model with 1 column ComponentModel model(1, &m_core); - model.setRootComponents(rootComponents); + model.reset(rootComponents); // all names should be resolvable, including virtual components QStringList all; @@ -95,7 +131,7 @@ private slots: foreach (const QString &name, all) { QVERIFY(model.indexFromComponentName(name).isValid()); QVERIFY(model.componentFromIndex(model.indexFromComponentName(name)) != 0); - QCOMPARE(model.componentFromIndex(model.indexFromComponentName(name))->name(), name); + QCOMPARE(model.componentFromIndex(model.indexFromComponentName(name))->treeName(), name); } foreach (Component *const component, rootComponents) @@ -111,7 +147,7 @@ private slots: // setup the model with 1 column ComponentModel model(1, &m_core); - model.setRootComponents(rootComponents); + model.reset(rootComponents); testDefaultInheritedModelBehavior(&model, 1); QCOMPARE(model.core(), &m_core); @@ -132,7 +168,7 @@ private slots: // setup the model with 1 column ComponentModel model(1, &m_core); - model.setRootComponents(rootComponents); + model.reset(rootComponents); testDefaultInheritedModelBehavior(&model, 1); QCOMPARE(model.checkedState(), ComponentModel::DefaultChecked); @@ -154,7 +190,7 @@ private slots: // setup the model with 1 column ComponentModel model(1, &m_core); - model.setRootComponents(rootComponents); + model.reset(rootComponents); testDefaultInheritedModelBehavior(&model, 1); QCOMPARE(model.checkedState(), ComponentModel::DefaultChecked); @@ -174,7 +210,7 @@ private slots: // setup the model with 1 column ComponentModel model(1, &m_core); - model.setRootComponents(rootComponents); + model.reset(rootComponents); testDefaultInheritedModelBehavior(&model, 1); QCOMPARE(model.checkedState(), ComponentModel::DefaultChecked); @@ -196,7 +232,7 @@ private slots: // setup the model with 1 column ComponentModel model(1, &m_core); - model.setRootComponents(rootComponents); + model.reset(rootComponents); testDefaultInheritedModelBehavior(&model, 1); // select all possible components. @@ -232,7 +268,7 @@ private slots: // setup the model with 1 column ComponentModel model(1, &m_core); - model.setRootComponents(rootComponents); + model.reset(rootComponents); testDefaultInheritedModelBehavior(&model, 1); // select all possible components. @@ -270,7 +306,7 @@ private slots: // setup the model with 1 column ComponentModel model(1, &m_core); - model.setRootComponents(rootComponents); + model.reset(rootComponents); testDefaultInheritedModelBehavior(&model, 1); // select all possible components. @@ -305,7 +341,7 @@ private slots: // setup the model with 1 column ComponentModel model(1, &m_core); - model.setRootComponents(rootComponents); + model.reset(rootComponents); testDefaultInheritedModelBehavior(&model, 1); // select all possible components. @@ -337,11 +373,19 @@ private slots: { QStringList localesToTest = { "en_US", "ru_RU", "de_DE", "fr_FR" }; foreach (const QString &localeToTest, localesToTest) { +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + QLocale::setDefault(QLocale(localeToTest)); +#else QLocale::setDefault(localeToTest); +#endif QString expectedName = rootComponentDisplayNames.contains(localeToTest.toLower()) ? rootComponentDisplayNames[localeToTest.toLower()] : rootComponentDisplayNames[QString()]; + QString expectedDescription = rootComponentDescriptions.contains(localeToTest.toLower()) + ? rootComponentDescriptions[localeToTest.toLower()] + : rootComponentDescriptions[QString()]; + setPackageManagerOptions(NoFlags); QList<Component*> rootComponents = loadComponents(); @@ -349,26 +393,48 @@ private slots: // setup the model with 1 column ComponentModel model(1, &m_core); - model.setRootComponents(rootComponents); + model.reset(rootComponents); const QModelIndex root = model.indexFromComponentName(vendorProduct); QCOMPARE(model.data(root, Qt::DisplayRole).toString(), expectedName); + Component *comp = model.componentFromIndex(root); + QCOMPARE(comp->value("Description"), expectedDescription); + qDeleteAll(rootComponents); } } + void testNoDefaultInstallation() + { + setPackageManagerOptions(NoDefaultInstallation); + + QList<Component*> rootComponents = loadComponents(); + testComponentsLoaded(rootComponents); + + // setup the model with 1 column + ComponentModel model(1, &m_core); + model.reset(rootComponents); + testDefaultInheritedModelBehavior(&model, 1); + + model.setCheckedState(ComponentModel::DefaultChecked); + QCOMPARE(model.checkedState(), ComponentModel::DefaultChecked); + testModelState(&model, QStringList() << vendorProduct, QStringList(), m_defaultUnchecked + + m_uncheckable + m_defaultPartially + QStringList() << vendorSecondProductSub); + } + private: void setPackageManagerOptions(Options flags) const { m_core.setNoForceInstallation(flags.testFlag(NoForcedInstallation)); m_core.setVirtualComponentsVisible(flags.testFlag(VirtualsVisible)); + m_core.setNoDefaultInstallation(flags.testFlag(NoDefaultInstallation)); } void testComponentsLoaded(const QList<Component *> &rootComponents) const { - // we need to have five root components - QCOMPARE(rootComponents.count(), 5); + // we need to have six root components + QCOMPARE(rootComponents.count(), 6); QList<Component*> components = rootComponents; foreach (Component *const component, rootComponents) @@ -383,9 +449,9 @@ private: { // row count with invalid model index should return: if (m_core.virtualComponentsVisible()) - QCOMPARE(model->rowCount(), 5); // 5 (4 non virtual and 1 virtual root component) + QCOMPARE(model->rowCount(), 6); // 6 (5 non virtual and 1 virtual root component) else - QCOMPARE(model->rowCount(), 4); // 4 (the 4 non virtual root components) + QCOMPARE(model->rowCount(), 5); // 5 (the 5 non virtual root components) QCOMPARE(model->columnCount(), columnCount); const QModelIndex firstParent = model->indexFromComponentName(vendorProduct); @@ -449,21 +515,22 @@ private: // these components should have checked state foreach (Component *const component, model->checked()) - QVERIFY(checked.contains(component->name())); + QVERIFY(checked.contains(component->treeName())); // these components should not have partially checked state foreach (Component *const component, model->partially()) - QVERIFY(partially.contains(component->name())); + QVERIFY(partially.contains(component->treeName())); // these components should not have checked state foreach (Component *const component, model->unchecked()) - QVERIFY(unchecked.contains(component->name())); + QVERIFY(unchecked.contains(component->treeName())); } QList<Component*> loadComponents() const { UpdatesInfo updatesInfo; updatesInfo.setFileName(":///data/updates.xml"); + updatesInfo.parseFile(); const QList<UpdateInfo> updateInfos = updatesInfo.updatesInfo(); QHash<QString, Component*> components; @@ -472,10 +539,15 @@ private: // we need at least these to be able to test the model component->setValue("Name", info.data.value("Name").toString()); - component->setValue("Default", info.data.value("Default").toString()); + component->setValue("TreeName", info.data.value("TreeName").value<QPair<QString, bool>>().first); + QString isDefault = info.data.value("Default").toString(); + if (m_core.noDefaultInstallation()) + isDefault = scFalse; + component->setValue("Default", isDefault); component->setValue("Virtual", info.data.value("Virtual").toString()); component->setValue("DisplayName", info.data.value("DisplayName").toString()); component->setValue("Checkable", info.data.value("Checkable").toString()); + component->setValue("Description", info.data.value("Description").toString()); QString forced = info.data.value("ForcedInstallation", scFalse).toString().toLower(); if (m_core.noForceInstallation()) @@ -486,7 +558,7 @@ private: component->setCheckable(false); component->setCheckState(Qt::Checked); } - components.insert(component->name(), component); + components.insert(component->treeName(), component); } QList <Component*> rootComponents; @@ -516,6 +588,7 @@ private: QStringList m_defaultPartially; QStringList m_defaultUnchecked; QStringList m_uncheckable; + QStringList m_defaultNoChecked; }; Q_DECLARE_OPERATORS_FOR_FLAGS(tst_ComponentModel::Options) diff --git a/tests/auto/installer/componentreplace/componentreplace.pro b/tests/auto/installer/componentreplace/componentreplace.pro new file mode 100644 index 000000000..9df6f81ca --- /dev/null +++ b/tests/auto/installer/componentreplace/componentreplace.pro @@ -0,0 +1,9 @@ +include(../../qttest.pri) + +QT += qml + +SOURCES += tst_componentreplace.cpp + +RESOURCES += \ + settings.qrc \ + ../shared/config.qrc diff --git a/tests/auto/installer/componentreplace/data/installPackagesRepository/A.sub1/1.0.0content.7z b/tests/auto/installer/componentreplace/data/installPackagesRepository/A.sub1/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..adcc21ad7 --- /dev/null +++ b/tests/auto/installer/componentreplace/data/installPackagesRepository/A.sub1/1.0.0content.7z diff --git a/tests/auto/installer/componentreplace/data/installPackagesRepository/A/1.0.0content.7z b/tests/auto/installer/componentreplace/data/installPackagesRepository/A/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..916fdd1d0 --- /dev/null +++ b/tests/auto/installer/componentreplace/data/installPackagesRepository/A/1.0.0content.7z diff --git a/tests/auto/installer/componentreplace/data/installPackagesRepository/B.sub1/1.0.0content.7z b/tests/auto/installer/componentreplace/data/installPackagesRepository/B.sub1/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..ab63152f8 --- /dev/null +++ b/tests/auto/installer/componentreplace/data/installPackagesRepository/B.sub1/1.0.0content.7z diff --git a/tests/auto/installer/componentreplace/data/installPackagesRepository/B/1.0.0content.7z b/tests/auto/installer/componentreplace/data/installPackagesRepository/B/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..7b957b077 --- /dev/null +++ b/tests/auto/installer/componentreplace/data/installPackagesRepository/B/1.0.0content.7z diff --git a/tests/auto/installer/componentreplace/data/installPackagesRepository/C/1.0.0content.7z b/tests/auto/installer/componentreplace/data/installPackagesRepository/C/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..d498f1900 --- /dev/null +++ b/tests/auto/installer/componentreplace/data/installPackagesRepository/C/1.0.0content.7z diff --git a/tests/auto/installer/componentreplace/data/installPackagesRepository/Updates.xml b/tests/auto/installer/componentreplace/data/installPackagesRepository/Updates.xml new file mode 100644 index 000000000..e77207777 --- /dev/null +++ b/tests/auto/installer/componentreplace/data/installPackagesRepository/Updates.xml @@ -0,0 +1,55 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.0</Version> + <ReleaseDate>2021-01-01</ReleaseDate> + <UpdateFile UncompressedSize="74" CompressedSize="224" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>53892cfe4d5f5b978553d3aa172944117604ef9c</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>A.sub1</Name> + <DisplayName>A subcomponent 1</DisplayName> + <Description>Subcomponent of component A</Description> + <Version>1.0.0</Version> + <ReleaseDate>2021-01-01</ReleaseDate> + <UpdateFile UncompressedSize="89" CompressedSize="247" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>8bd5a1d2525cfdfb690a3c80165aeed44a17795f</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>B</Name> + <DisplayName>B</DisplayName> + <Description>Example component B</Description> + <Version>1.0.0</Version> + <ReleaseDate>2021-01-01</ReleaseDate> + <UpdateFile UncompressedSize="74" CompressedSize="224" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>b2d03273f01f45878c3f5081cc8502edc0826e08</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>B.sub1</Name> + <DisplayName>B subcomponent 1</DisplayName> + <Description>Subcomponent of component B</Description> + <Version>1.0.0</Version> + <ReleaseDate>2021-01-01</ReleaseDate> + <UpdateFile UncompressedSize="89" CompressedSize="247" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>a10463141e30ce3fede9ac84bc52a07b0c5e919e</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>C</Name> + <DisplayName>C component</DisplayName> + <Description>Component C</Description> + <Version>1.0.0</Version> + <ReleaseDate>2021-01-01</ReleaseDate> + <UpdateFile UncompressedSize="89" CompressedSize="247" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>a10463141e30ce3fede9ac84bc52a07b0c5e919e</SHA1> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/componentreplace/data/repositoryWithMultiReplace/A.sub1/1.0.0content.7z b/tests/auto/installer/componentreplace/data/repositoryWithMultiReplace/A.sub1/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..adcc21ad7 --- /dev/null +++ b/tests/auto/installer/componentreplace/data/repositoryWithMultiReplace/A.sub1/1.0.0content.7z diff --git a/tests/auto/installer/componentreplace/data/repositoryWithMultiReplace/A/1.0.0content.7z b/tests/auto/installer/componentreplace/data/repositoryWithMultiReplace/A/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..916fdd1d0 --- /dev/null +++ b/tests/auto/installer/componentreplace/data/repositoryWithMultiReplace/A/1.0.0content.7z diff --git a/tests/auto/installer/componentreplace/data/repositoryWithMultiReplace/B.sub1/1.0.0content.7z b/tests/auto/installer/componentreplace/data/repositoryWithMultiReplace/B.sub1/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..ab63152f8 --- /dev/null +++ b/tests/auto/installer/componentreplace/data/repositoryWithMultiReplace/B.sub1/1.0.0content.7z diff --git a/tests/auto/installer/componentreplace/data/repositoryWithMultiReplace/B/1.0.0content.7z b/tests/auto/installer/componentreplace/data/repositoryWithMultiReplace/B/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..7b957b077 --- /dev/null +++ b/tests/auto/installer/componentreplace/data/repositoryWithMultiReplace/B/1.0.0content.7z diff --git a/tests/auto/installer/componentreplace/data/repositoryWithMultiReplace/Updates.xml b/tests/auto/installer/componentreplace/data/repositoryWithMultiReplace/Updates.xml new file mode 100644 index 000000000..c6b85077b --- /dev/null +++ b/tests/auto/installer/componentreplace/data/repositoryWithMultiReplace/Updates.xml @@ -0,0 +1,46 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.0</Version> + <ReleaseDate>2021-01-01</ReleaseDate> + <UpdateFile UncompressedSize="74" CompressedSize="224" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>dd48e40f2f86559b20288424a6a3e2a1a05a172d</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>A.sub1</Name> + <DisplayName>A subcomponent 1</DisplayName> + <Description>Subcomponent of component A</Description> + <Version>1.0.0</Version> + <ReleaseDate>2021-01-01</ReleaseDate> + <UpdateFile UncompressedSize="89" CompressedSize="247" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>f8ff5da138516b1f800e641ab4999301dcb3c78b</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>B</Name> + <DisplayName>B</DisplayName> + <Description>Example component B</Description> + <Version>1.0.0</Version> + <ReleaseDate>2021-01-01</ReleaseDate> + <Replaces>A, A.sub1</Replaces> + <UpdateFile UncompressedSize="74" CompressedSize="224" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>8e83334a4a3c9c9d2bb6b073858d980da2c8871f</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>B.sub1</Name> + <DisplayName>B subcomponent 1</DisplayName> + <Description>Subcomponent of component B</Description> + <Version>1.0.0</Version> + <ReleaseDate>2021-01-01</ReleaseDate> + <UpdateFile UncompressedSize="89" CompressedSize="247" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>36d374bbbfbe87a18f6b308e5398360e9cc54a84</SHA1> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/componentreplace/data/repositoryWithMultiReplaceInUpdate/A.sub1/1.0.0content.7z b/tests/auto/installer/componentreplace/data/repositoryWithMultiReplaceInUpdate/A.sub1/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..adcc21ad7 --- /dev/null +++ b/tests/auto/installer/componentreplace/data/repositoryWithMultiReplaceInUpdate/A.sub1/1.0.0content.7z diff --git a/tests/auto/installer/componentreplace/data/repositoryWithMultiReplaceInUpdate/A/2.0.0content.7z b/tests/auto/installer/componentreplace/data/repositoryWithMultiReplaceInUpdate/A/2.0.0content.7z Binary files differnew file mode 100644 index 000000000..916fdd1d0 --- /dev/null +++ b/tests/auto/installer/componentreplace/data/repositoryWithMultiReplaceInUpdate/A/2.0.0content.7z diff --git a/tests/auto/installer/componentreplace/data/repositoryWithMultiReplaceInUpdate/B.sub1/1.0.0content.7z b/tests/auto/installer/componentreplace/data/repositoryWithMultiReplaceInUpdate/B.sub1/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..ab63152f8 --- /dev/null +++ b/tests/auto/installer/componentreplace/data/repositoryWithMultiReplaceInUpdate/B.sub1/1.0.0content.7z diff --git a/tests/auto/installer/componentreplace/data/repositoryWithMultiReplaceInUpdate/B/2.0.0content.7z b/tests/auto/installer/componentreplace/data/repositoryWithMultiReplaceInUpdate/B/2.0.0content.7z Binary files differnew file mode 100644 index 000000000..7b957b077 --- /dev/null +++ b/tests/auto/installer/componentreplace/data/repositoryWithMultiReplaceInUpdate/B/2.0.0content.7z diff --git a/tests/auto/installer/componentreplace/data/repositoryWithMultiReplaceInUpdate/C/2.0.0content.7z b/tests/auto/installer/componentreplace/data/repositoryWithMultiReplaceInUpdate/C/2.0.0content.7z Binary files differnew file mode 100644 index 000000000..d498f1900 --- /dev/null +++ b/tests/auto/installer/componentreplace/data/repositoryWithMultiReplaceInUpdate/C/2.0.0content.7z diff --git a/tests/auto/installer/componentreplace/data/repositoryWithMultiReplaceInUpdate/Updates.xml b/tests/auto/installer/componentreplace/data/repositoryWithMultiReplaceInUpdate/Updates.xml new file mode 100644 index 000000000..e0fb351ff --- /dev/null +++ b/tests/auto/installer/componentreplace/data/repositoryWithMultiReplaceInUpdate/Updates.xml @@ -0,0 +1,56 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>2.0.0</Version> + <ReleaseDate>2021-01-01</ReleaseDate> + <UpdateFile UncompressedSize="74" OS="Any" CompressedSize="224"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>28cd1210a590a97a9c0507cc39519b55d8f0a08b</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>A.sub1</Name> + <DisplayName>A subcomponent 1</DisplayName> + <Description>Subcomponent of component A</Description> + <Version>1.0.0</Version> + <ReleaseDate>2021-01-01</ReleaseDate> + <UpdateFile UncompressedSize="89" OS="Any" CompressedSize="247"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>9295f5a7f58c5e27a1c9ecf580f54a9328085aa5</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>B</Name> + <DisplayName>B</DisplayName> + <Description>Example component B</Description> + <Version>2.0.0</Version> + <ReleaseDate>2021-01-01</ReleaseDate> + <Replaces>A, A.sub1</Replaces> + <UpdateFile UncompressedSize="74" OS="Any" CompressedSize="224"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>b55f66866b7b909021f517941e921fd183fac7b0</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>B.sub1</Name> + <DisplayName>B subcomponent 1</DisplayName> + <Description>Subcomponent of component B</Description> + <Version>1.0.0</Version> + <ReleaseDate>2021-01-01</ReleaseDate> + <UpdateFile UncompressedSize="89" OS="Any" CompressedSize="247"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>4331736562fc047a4f47263be75f816298cbda30</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>C</Name> + <DisplayName>C component</DisplayName> + <Description>Component C</Description> + <Version>2.0.0</Version> + <ReleaseDate>2021-01-01</ReleaseDate> + <UpdateFile UncompressedSize="89" CompressedSize="247" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>a10463141e30ce3fede9ac84bc52a07b0c5e919e</SHA1> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/componentreplace/data/repositoryWithReplace/A.sub1/1.0.0content.7z b/tests/auto/installer/componentreplace/data/repositoryWithReplace/A.sub1/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..adcc21ad7 --- /dev/null +++ b/tests/auto/installer/componentreplace/data/repositoryWithReplace/A.sub1/1.0.0content.7z diff --git a/tests/auto/installer/componentreplace/data/repositoryWithReplace/A/1.0.0content.7z b/tests/auto/installer/componentreplace/data/repositoryWithReplace/A/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..916fdd1d0 --- /dev/null +++ b/tests/auto/installer/componentreplace/data/repositoryWithReplace/A/1.0.0content.7z diff --git a/tests/auto/installer/componentreplace/data/repositoryWithReplace/B.sub1/1.0.0content.7z b/tests/auto/installer/componentreplace/data/repositoryWithReplace/B.sub1/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..ab63152f8 --- /dev/null +++ b/tests/auto/installer/componentreplace/data/repositoryWithReplace/B.sub1/1.0.0content.7z diff --git a/tests/auto/installer/componentreplace/data/repositoryWithReplace/B/2.0.0content.7z b/tests/auto/installer/componentreplace/data/repositoryWithReplace/B/2.0.0content.7z Binary files differnew file mode 100644 index 000000000..7b957b077 --- /dev/null +++ b/tests/auto/installer/componentreplace/data/repositoryWithReplace/B/2.0.0content.7z diff --git a/tests/auto/installer/componentreplace/data/repositoryWithReplace/Updates.xml b/tests/auto/installer/componentreplace/data/repositoryWithReplace/Updates.xml new file mode 100644 index 000000000..ec74ac3e5 --- /dev/null +++ b/tests/auto/installer/componentreplace/data/repositoryWithReplace/Updates.xml @@ -0,0 +1,46 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.0</Version> + <ReleaseDate>2021-01-01</ReleaseDate> + <UpdateFile UncompressedSize="74" CompressedSize="224" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>dba535b00f3ee2bc8387a299940384af3af3489b</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>A.sub1</Name> + <DisplayName>A subcomponent 1</DisplayName> + <Description>Subcomponent of component A</Description> + <Version>1.0.0</Version> + <ReleaseDate>2021-01-01</ReleaseDate> + <UpdateFile UncompressedSize="89" CompressedSize="247" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>ca3e5cdf08361775f744a6d6ec1837aae03cdc28</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>B</Name> + <DisplayName>B</DisplayName> + <Description>Example component B</Description> + <Version>2.0.0</Version> + <ReleaseDate>2021-01-01</ReleaseDate> + <Replaces>A</Replaces> + <UpdateFile UncompressedSize="74" CompressedSize="224" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>c30d2146844195d27879e5360e864c4eae7b4cde</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>B.sub1</Name> + <DisplayName>B subcomponent 1</DisplayName> + <Description>Subcomponent of component B</Description> + <Version>1.0.0</Version> + <ReleaseDate>2021-01-01</ReleaseDate> + <UpdateFile UncompressedSize="89" CompressedSize="247" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>05124ea8feadb6a5d8d9222cc41898ef72d562bb</SHA1> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/componentreplace/data/repositoryWithUpdateToReplaceble/A.sub1/1.0.0content.7z b/tests/auto/installer/componentreplace/data/repositoryWithUpdateToReplaceble/A.sub1/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..adcc21ad7 --- /dev/null +++ b/tests/auto/installer/componentreplace/data/repositoryWithUpdateToReplaceble/A.sub1/1.0.0content.7z diff --git a/tests/auto/installer/componentreplace/data/repositoryWithUpdateToReplaceble/A/2.0.0content.7z b/tests/auto/installer/componentreplace/data/repositoryWithUpdateToReplaceble/A/2.0.0content.7z Binary files differnew file mode 100644 index 000000000..916fdd1d0 --- /dev/null +++ b/tests/auto/installer/componentreplace/data/repositoryWithUpdateToReplaceble/A/2.0.0content.7z diff --git a/tests/auto/installer/componentreplace/data/repositoryWithUpdateToReplaceble/B.sub1/1.0.0content.7z b/tests/auto/installer/componentreplace/data/repositoryWithUpdateToReplaceble/B.sub1/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..ab63152f8 --- /dev/null +++ b/tests/auto/installer/componentreplace/data/repositoryWithUpdateToReplaceble/B.sub1/1.0.0content.7z diff --git a/tests/auto/installer/componentreplace/data/repositoryWithUpdateToReplaceble/B/2.0.0content.7z b/tests/auto/installer/componentreplace/data/repositoryWithUpdateToReplaceble/B/2.0.0content.7z Binary files differnew file mode 100644 index 000000000..7b957b077 --- /dev/null +++ b/tests/auto/installer/componentreplace/data/repositoryWithUpdateToReplaceble/B/2.0.0content.7z diff --git a/tests/auto/installer/componentreplace/data/repositoryWithUpdateToReplaceble/Updates.xml b/tests/auto/installer/componentreplace/data/repositoryWithUpdateToReplaceble/Updates.xml new file mode 100644 index 000000000..b1846f7b1 --- /dev/null +++ b/tests/auto/installer/componentreplace/data/repositoryWithUpdateToReplaceble/Updates.xml @@ -0,0 +1,46 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>2.0.0</Version> + <ReleaseDate>2021-01-01</ReleaseDate> + <UpdateFile CompressedSize="224" OS="Any" UncompressedSize="74"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>a0dc47264727fd2e6a6cdd2fa879388eb732ac73</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>A.sub1</Name> + <DisplayName>A subcomponent 1</DisplayName> + <Description>Subcomponent of component A</Description> + <Version>1.0.0</Version> + <ReleaseDate>2021-01-01</ReleaseDate> + <UpdateFile CompressedSize="247" OS="Any" UncompressedSize="89"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>7b5fb2c36cb4a784816c34839d7ce4ac0114df50</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>B</Name> + <DisplayName>B</DisplayName> + <Description>Example component B</Description> + <Version>2.0.0</Version> + <ReleaseDate>2021-01-01</ReleaseDate> + <Replaces>A</Replaces> + <UpdateFile CompressedSize="224" OS="Any" UncompressedSize="74"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>9baaa7eaca7002ba10addc22306bb9383d2e5b46</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>B.sub1</Name> + <DisplayName>B subcomponent 1</DisplayName> + <Description>Subcomponent of component B</Description> + <Version>1.0.0</Version> + <ReleaseDate>2021-01-01</ReleaseDate> + <UpdateFile CompressedSize="247" OS="Any" UncompressedSize="89"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>f840d6cd369d9dc471f0a718ff5c8c000d07d72c</SHA1> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/componentreplace/settings.qrc b/tests/auto/installer/componentreplace/settings.qrc new file mode 100644 index 000000000..ba1b0ab98 --- /dev/null +++ b/tests/auto/installer/componentreplace/settings.qrc @@ -0,0 +1,31 @@ +<RCC> + <qresource prefix="/"> + <file>data/installPackagesRepository/Updates.xml</file> + <file>data/installPackagesRepository/A/1.0.0content.7z</file> + <file>data/installPackagesRepository/B/1.0.0content.7z</file> + <file>data/installPackagesRepository/A.sub1/1.0.0content.7z</file> + <file>data/installPackagesRepository/B.sub1/1.0.0content.7z</file> + <file>data/installPackagesRepository/C/1.0.0content.7z</file> + <file>data/repositoryWithReplace/Updates.xml</file> + <file>data/repositoryWithReplace/A/1.0.0content.7z</file> + <file>data/repositoryWithReplace/B/2.0.0content.7z</file> + <file>data/repositoryWithReplace/A.sub1/1.0.0content.7z</file> + <file>data/repositoryWithReplace/B.sub1/1.0.0content.7z</file> + <file>data/repositoryWithUpdateToReplaceble/Updates.xml</file> + <file>data/repositoryWithUpdateToReplaceble/A/2.0.0content.7z</file> + <file>data/repositoryWithUpdateToReplaceble/B/2.0.0content.7z</file> + <file>data/repositoryWithUpdateToReplaceble/A.sub1/1.0.0content.7z</file> + <file>data/repositoryWithUpdateToReplaceble/B.sub1/1.0.0content.7z</file> + <file>data/repositoryWithMultiReplace/Updates.xml</file> + <file>data/repositoryWithMultiReplace/A/1.0.0content.7z</file> + <file>data/repositoryWithMultiReplace/B/1.0.0content.7z</file> + <file>data/repositoryWithMultiReplace/A.sub1/1.0.0content.7z</file> + <file>data/repositoryWithMultiReplace/B.sub1/1.0.0content.7z</file> + <file>data/repositoryWithMultiReplaceInUpdate/Updates.xml</file> + <file>data/repositoryWithMultiReplaceInUpdate/A/2.0.0content.7z</file> + <file>data/repositoryWithMultiReplaceInUpdate/B/2.0.0content.7z</file> + <file>data/repositoryWithMultiReplaceInUpdate/A.sub1/1.0.0content.7z</file> + <file>data/repositoryWithMultiReplaceInUpdate/B.sub1/1.0.0content.7z</file> + <file>data/repositoryWithMultiReplaceInUpdate/C/2.0.0content.7z</file> + </qresource> +</RCC> diff --git a/tests/auto/installer/componentreplace/tst_componentreplace.cpp b/tests/auto/installer/componentreplace/tst_componentreplace.cpp new file mode 100644 index 000000000..98fee27d0 --- /dev/null +++ b/tests/auto/installer/componentreplace/tst_componentreplace.cpp @@ -0,0 +1,286 @@ +/************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ + +#include "../shared/packagemanager.h" +#include "../shared/verifyinstaller.h" + +#include <component.h> +#include <packagemanagercore.h> + +#include <QLoggingCategory> +#include <QTest> + +using namespace QInstaller; + +class tst_ComponentReplace : public QObject +{ + Q_OBJECT + +private: + void setRepository(const QString &repository, PackageManagerCore *core) + { + core->cancelMetaInfoJob(); //Call cancel to reset metadata so that update repositories are fetched + + QSet<Repository> repoList; + Repository repo = Repository::fromUserInput(repository); + repoList.insert(repo); + core->settings().setDefaultRepositories(repoList); + } + +private slots: + void initTestCase() + { + m_installDir = QInstaller::generateTemporaryFileName(); + } + + void replaceNonInstalledItem() + { + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (m_installDir, ":///data/repositoryWithReplace")); + QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() << "A" << "B")); + QList<Component*> installedComponents = core->orderedComponentsToInstall(); + + VerifyInstaller::verifyInstallerResources(m_installDir, "B", "2.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "B.sub1", "1.0.0content.txt"); + VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" + << "Bsub1.txt" << "B.txt"); + } + + void replaceInstalledItem() + { + PackageManagerCore *core = PackageManager::getPackageManagerWithInit + (m_installDir, ":///data/installPackagesRepository"); + QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() << "A")); + + QCOMPARE(core->orderedComponentsToInstall().count(), 2); + VerifyInstaller::verifyInstallerResources(m_installDir, "A", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "A.sub1", "1.0.0content.txt"); + VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" + << "Asub1.txt" << "A.txt"); + + core->commitSessionOperations(); + core->setPackageManager(); + setRepository(":///data/repositoryWithReplace", core); + QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() << "B")); + QCOMPARE(core->componentsToUninstall().count(), 1); + QVERIFY(core->componentByName("B.sub1") != 0); + QVERIFY(core->componentByName("B") != 0); + VerifyInstaller::verifyInstallerResourceFileDeletion(m_installDir, "A", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "A.sub1", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "B", "2.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "B.sub1", "1.0.0content.txt"); + VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" + << "Bsub1.txt" << "B.txt" << "Asub1.txt"); + delete core; + } + + void replaceInstalledItemInUpdate() + { + PackageManagerCore *core = PackageManager::getPackageManagerWithInit + (m_installDir, ":///data/installPackagesRepository"); + QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() << "A" << "B")); + + QCOMPARE(core->orderedComponentsToInstall().count(), 4); + VerifyInstaller::verifyInstallerResources(m_installDir, "A", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "A.sub1", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "B", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "B.sub1", "1.0.0content.txt"); + VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" + << "Asub1.txt" << "A.txt"<< "Bsub1.txt" << "B.txt"); + + core->commitSessionOperations(); + core->setUpdater(); + setRepository(":///data/repositoryWithReplace", core); + QCOMPARE(PackageManagerCore::Success, core->updateComponentsSilently(QStringList() << "B")); + QCOMPARE(core->componentsToUninstall().count(), 1); + VerifyInstaller::verifyInstallerResourceFileDeletion(m_installDir, "A", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "A.sub1", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "B", "2.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "B.sub1", "1.0.0content.txt"); + VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" + << "Bsub1.txt" << "B.txt" << "Asub1.txt"); + delete core; + } + + void replaceInstalledItemContainingUpdateInUpdate() + { + PackageManagerCore *core = PackageManager::getPackageManagerWithInit + (m_installDir, ":///data/installPackagesRepository"); + QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() << "A" << "B")); + + QCOMPARE(core->orderedComponentsToInstall().count(), 4); + VerifyInstaller::verifyInstallerResources(m_installDir, "A", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "A.sub1", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "B", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "B.sub1", "1.0.0content.txt"); + VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" + << "Asub1.txt" << "A.txt"<< "Bsub1.txt" << "B.txt"); + + core->commitSessionOperations(); + core->setUpdater(); + setRepository(":///data/repositoryWithUpdateToReplaceble", core); + QCOMPARE(PackageManagerCore::Success, core->updateComponentsSilently(QStringList() << "B")); + QCOMPARE(core->componentsToUninstall().count(), 1); + VerifyInstaller::verifyInstallerResourceFileDeletion(m_installDir, "A", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResourceFileDeletion(m_installDir, "A", "2.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "A.sub1", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "B", "2.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "B.sub1", "1.0.0content.txt"); + VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" + << "Bsub1.txt" << "B.txt" << "Asub1.txt"); + delete core; + } + + void replaceMultipleInstalledItems() + { + PackageManagerCore *core = PackageManager::getPackageManagerWithInit + (m_installDir, ":///data/installPackagesRepository"); + QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() << "A")); + + VerifyInstaller::verifyInstallerResources(m_installDir, "A", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "A.sub1", "1.0.0content.txt"); + VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" + << "Asub1.txt" << "A.txt"); + + core->commitSessionOperations(); + core->setPackageManager(); + setRepository(":///data/repositoryWithMultiReplace", core); + QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() << "B")); + QCOMPARE(core->componentsToUninstall().count(), 2); + VerifyInstaller::verifyInstallerResourceFileDeletion(m_installDir, "A", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResourceFileDeletion(m_installDir, "A.sub1", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "B", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "B.sub1", "1.0.0content.txt"); + VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" + << "Bsub1.txt" << "B.txt"); + delete core; + } + + void replaceMultipleInstalledItemsInUpdate() + { + PackageManagerCore *core = PackageManager::getPackageManagerWithInit + (m_installDir, ":///data/installPackagesRepository"); + QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() << "A" << "B")); + + QCOMPARE(core->orderedComponentsToInstall().count(), 4); + VerifyInstaller::verifyInstallerResources(m_installDir, "A", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "A.sub1", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "B", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "B.sub1", "1.0.0content.txt"); + VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" + << "Asub1.txt" << "A.txt"<< "Bsub1.txt" << "B.txt"); + + core->commitSessionOperations(); + core->setUpdater(); + setRepository(":///data/repositoryWithMultiReplaceInUpdate", core); + QCOMPARE(PackageManagerCore::Success, core->updateComponentsSilently(QStringList() << "B")); + QCOMPARE(core->componentsToUninstall().count(), 2); + VerifyInstaller::verifyInstallerResourceFileDeletion(m_installDir, "A", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResourceFileDeletion(m_installDir, "A.sub1", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "B", "2.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "B.sub1", "1.0.0content.txt"); + VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" + << "Bsub1.txt" << "B.txt"); + delete core; + } + + void installOtherComponentsWhileReplacementsExists() + { + PackageManagerCore *core = PackageManager::getPackageManagerWithInit + (m_installDir, ":///data/installPackagesRepository"); + QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() << "A" << "B")); + + QCOMPARE(core->orderedComponentsToInstall().count(), 4); + VerifyInstaller::verifyInstallerResources(m_installDir, "A", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "A.sub1", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "B", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "B.sub1", "1.0.0content.txt"); + VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" + << "Asub1.txt" << "A.txt"<< "Bsub1.txt" << "B.txt"); + + core->commitSessionOperations(); + core->setPackageManager(); + setRepository(":///data/repositoryWithMultiReplaceInUpdate", core); + QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() << "C")); + QCOMPARE(core->orderedComponentsToInstall().count(), 1); + QCOMPARE(core->componentsToUninstall().count(), 0); + VerifyInstaller::verifyInstallerResources(m_installDir, "A", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "A.sub1", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "B", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "B.sub1", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "C", "2.0.0content.txt"); + VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" + << "Asub1.txt" << "A.txt"<< "Bsub1.txt" << "B.txt" << "C.txt"); + + delete core; + } + + void updateOtherComponentsWhileReplacementsExists() + { + PackageManagerCore *core = PackageManager::getPackageManagerWithInit + (m_installDir, ":///data/installPackagesRepository"); + QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() << "A" << "B" << "C")); + + QCOMPARE(core->orderedComponentsToInstall().count(), 5); + VerifyInstaller::verifyInstallerResources(m_installDir, "A", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "A.sub1", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "B", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "B.sub1", "1.0.0content.txt"); + VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" + << "Asub1.txt" << "A.txt"<< "Bsub1.txt" << "B.txt" << "C.txt"); + + core->commitSessionOperations(); + core->setUpdater(); + setRepository(":///data/repositoryWithMultiReplaceInUpdate", core); + QCOMPARE(PackageManagerCore::Success, core->updateComponentsSilently(QStringList() << "C")); + QCOMPARE(core->orderedComponentsToInstall().count(), 1); + QCOMPARE(core->componentsToUninstall().count(), 0); + VerifyInstaller::verifyInstallerResources(m_installDir, "A", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "A.sub1", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "B", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "B.sub1", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "C", "2.0.0content.txt"); + VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" + << "Asub1.txt" << "A.txt"<< "Bsub1.txt" << "B.txt" << "C.txt"); + + delete core; + } + + void cleanup() + { + QDir dir(m_installDir); + QVERIFY(dir.removeRecursively()); + } +private: + QString m_installDir; +}; + + +QTEST_MAIN(tst_ComponentReplace) + +#include "tst_componentreplace.moc" diff --git a/tests/auto/installer/consumeoutputoperationtest/consumeoutputoperationtest.pro b/tests/auto/installer/consumeoutputoperationtest/consumeoutputoperationtest.pro index 3eacd46ac..30a85bdcf 100644 --- a/tests/auto/installer/consumeoutputoperationtest/consumeoutputoperationtest.pro +++ b/tests/auto/installer/consumeoutputoperationtest/consumeoutputoperationtest.pro @@ -6,3 +6,7 @@ QT += testlib qml SOURCES = tst_consumeoutputoperationtest.cpp DEFINES += "QMAKE_BINARY=$$fromNativeSeparators($$QMAKE_BINARY)" + +RESOURCES += \ + settings.qrc \ + ../shared/config.qrc diff --git a/tests/auto/installer/consumeoutputoperationtest/data/repository/A/1.0.2-1meta.7z b/tests/auto/installer/consumeoutputoperationtest/data/repository/A/1.0.2-1meta.7z Binary files differnew file mode 100644 index 000000000..5415d3b9f --- /dev/null +++ b/tests/auto/installer/consumeoutputoperationtest/data/repository/A/1.0.2-1meta.7z diff --git a/tests/auto/installer/consumeoutputoperationtest/data/repository/Updates.xml b/tests/auto/installer/consumeoutputoperationtest/data/repository/Updates.xml new file mode 100644 index 000000000..1c3caf7be --- /dev/null +++ b/tests/auto/installer/consumeoutputoperationtest/data/repository/Updates.xml @@ -0,0 +1,15 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.2-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <Script>script.qs</Script> + <SHA1>4da14562d6515590d145678d21990faa817832bb</SHA1> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/consumeoutputoperationtest/settings.qrc b/tests/auto/installer/consumeoutputoperationtest/settings.qrc new file mode 100644 index 000000000..d030220ab --- /dev/null +++ b/tests/auto/installer/consumeoutputoperationtest/settings.qrc @@ -0,0 +1,6 @@ +<RCC> + <qresource prefix="/"> + <file>data/repository/Updates.xml</file> + <file>data/repository/A/1.0.2-1meta.7z</file> + </qresource> +</RCC> diff --git a/tests/auto/installer/consumeoutputoperationtest/tst_consumeoutputoperationtest.cpp b/tests/auto/installer/consumeoutputoperationtest/tst_consumeoutputoperationtest.cpp index 8250a7dd2..c0c8d7390 100644 --- a/tests/auto/installer/consumeoutputoperationtest/tst_consumeoutputoperationtest.cpp +++ b/tests/auto/installer/consumeoutputoperationtest/tst_consumeoutputoperationtest.cpp @@ -1,6 +1,6 @@ /************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Installer Framework. @@ -25,19 +25,15 @@ ** $QT_END_LICENSE$ ** **************************************************************************/ -#include <init.h> +#include "../shared/packagemanager.h" + #include <packagemanagercore.h> #include <consumeoutputoperation.h> #include <qinstallerglobal.h> -#include <fileutils.h> #include <errors.h> -#include <QObject> #include <QTest> #include <QProcess> -#include <QDir> -#include <QEventLoop> -#include <QDebug> #define QUOTE_(x) #x #define QUOTE(x) QUOTE_(x) @@ -58,6 +54,8 @@ private slots: m_fakeQtPath = QDir::toNativeSeparators(qApp->applicationDirPath()) + QDir::separator() + "fakeQt" + QDir::separator(); QVERIFY(QDir().mkpath(m_fakeQtPath + "bin")); + m_testOutput = getOutputFrom(QUOTE(QMAKE_BINARY), QStringList("-query")); + qputenv("qmakePath", QUOTE(QMAKE_BINARY)); //Read from script } void testMissingArguments() @@ -81,15 +79,28 @@ private slots: void testGetOutputFromQmake() { - QString testOutput = getOutputFrom(QUOTE(QMAKE_BINARY), QStringList("-query")); - ConsumeOutputOperation operation(&m_core); operation.setArguments(QStringList() << "testConsumeOutputKey" << QUOTE(QMAKE_BINARY) << "-query"); QVERIFY2(operation.performOperation(), qPrintable(operation.errorString())); QCOMPARE(Operation::Error(operation.error()), Operation::NoError); - QCOMPARE(m_core.value("testConsumeOutputKey"), testOutput); + QCOMPARE(m_core.value("testConsumeOutputKey"), m_testOutput); + } + + void testPerformingFromCLI() + { + QString installDir = QInstaller::generateTemporaryFileName(); + QVERIFY(QDir().mkpath(installDir)); + PackageManagerCore *core = PackageManager::getPackageManagerWithInit + (installDir, ":///data/repository"); + + core->installDefaultComponentsSilently(); + QCOMPARE(core->value("testConsumeOutputKeyFromScript"), m_testOutput); + + QDir dir(installDir); + QVERIFY(dir.removeRecursively()); + core->deleteLater(); } void cleanupTestCase() @@ -99,6 +110,7 @@ private slots: } catch (const QInstaller::Error &error) { QFAIL(qPrintable(error.message())); } + qunsetenv("qmakePath"); } private: @@ -113,12 +125,13 @@ private: if (process.state() != QProcess::NotRunning) loop.exec(); - return process.readAllStandardOutput(); + return process.readAllStandardOutput().trimmed(); } PackageManagerCore m_core; QString m_fakeQtPath; + QString m_testOutput; }; QTEST_MAIN(tst_consumeoutputoperationtest) diff --git a/tests/auto/installer/contentsha1check/contentsha1check.pro b/tests/auto/installer/contentsha1check/contentsha1check.pro new file mode 100644 index 000000000..dd659bffa --- /dev/null +++ b/tests/auto/installer/contentsha1check/contentsha1check.pro @@ -0,0 +1,9 @@ +include(../../qttest.pri) + +QT += qml + +SOURCES += tst_contentsha1check.cpp + +RESOURCES += \ + settings.qrc \ + ../shared/config.qrc diff --git a/tests/auto/installer/contentsha1check/data/config.xml b/tests/auto/installer/contentsha1check/data/config.xml new file mode 100644 index 000000000..041ce5062 --- /dev/null +++ b/tests/auto/installer/contentsha1check/data/config.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Installer> + <Name>Your application</Name> + <Version>1.2.3</Version> + <MaintenanceToolName></MaintenanceToolName> + <MaintenanceToolIniFile></MaintenanceToolIniFile> + <TargetConfigurationFile></TargetConfigurationFile> +</Installer> diff --git a/tests/auto/installer/contentsha1check/data/repositorywithchecksumcheck/A/1.0.2-1content.7z b/tests/auto/installer/contentsha1check/data/repositorywithchecksumcheck/A/1.0.2-1content.7z Binary files differnew file mode 100644 index 000000000..9109d284f --- /dev/null +++ b/tests/auto/installer/contentsha1check/data/repositorywithchecksumcheck/A/1.0.2-1content.7z diff --git a/tests/auto/installer/contentsha1check/data/repositorywithchecksumcheck/A/1.0.2-1content.7z.sha1 b/tests/auto/installer/contentsha1check/data/repositorywithchecksumcheck/A/1.0.2-1content.7z.sha1 new file mode 100644 index 000000000..564e8290b --- /dev/null +++ b/tests/auto/installer/contentsha1check/data/repositorywithchecksumcheck/A/1.0.2-1content.7z.sha1 @@ -0,0 +1 @@ +eb5a464ab1a33bd1484e9b8f22b2c5f97abdfdf6
\ No newline at end of file diff --git a/tests/auto/installer/contentsha1check/data/repositorywithchecksumcheck/B/1.0.0-1content.7z b/tests/auto/installer/contentsha1check/data/repositorywithchecksumcheck/B/1.0.0-1content.7z Binary files differnew file mode 100644 index 000000000..947979354 --- /dev/null +++ b/tests/auto/installer/contentsha1check/data/repositorywithchecksumcheck/B/1.0.0-1content.7z diff --git a/tests/auto/installer/contentsha1check/data/repositorywithchecksumcheck/B/1.0.0-1content.7z.sha1 b/tests/auto/installer/contentsha1check/data/repositorywithchecksumcheck/B/1.0.0-1content.7z.sha1 new file mode 100644 index 000000000..0f2144f0c --- /dev/null +++ b/tests/auto/installer/contentsha1check/data/repositorywithchecksumcheck/B/1.0.0-1content.7z.sha1 @@ -0,0 +1 @@ +7e592e4b96adcefc77f2613100a3bd5e8835cce0
\ No newline at end of file diff --git a/tests/auto/installer/contentsha1check/data/repositorywithchecksumcheck/B/1.0.0-1meta.7z b/tests/auto/installer/contentsha1check/data/repositorywithchecksumcheck/B/1.0.0-1meta.7z Binary files differnew file mode 100644 index 000000000..c14f55e4a --- /dev/null +++ b/tests/auto/installer/contentsha1check/data/repositorywithchecksumcheck/B/1.0.0-1meta.7z diff --git a/tests/auto/installer/contentsha1check/data/repositorywithchecksumcheck/Updates.xml b/tests/auto/installer/contentsha1check/data/repositorywithchecksumcheck/Updates.xml new file mode 100644 index 000000000..1d2fb780b --- /dev/null +++ b/tests/auto/installer/contentsha1check/data/repositorywithchecksumcheck/Updates.xml @@ -0,0 +1,27 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>true</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.2-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <UpdateFile UncompressedSize="74" CompressedSize="215" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>dec2797a059da9303fec87cc0c1dfb0866afeb8f</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>B</Name> + <DisplayName>B</DisplayName> + <Description>Example component B</Description> + <Version>1.0.0-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <UpdateFile UncompressedSize="74" CompressedSize="215" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>2370e0b7dae861088c056d2de40c7ab7051bda13</SHA1> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/contentsha1check/data/repositorywithinvalidchecksum/E/1.0.2-1content.7z b/tests/auto/installer/contentsha1check/data/repositorywithinvalidchecksum/E/1.0.2-1content.7z Binary files differnew file mode 100644 index 000000000..793ce161c --- /dev/null +++ b/tests/auto/installer/contentsha1check/data/repositorywithinvalidchecksum/E/1.0.2-1content.7z diff --git a/tests/auto/installer/contentsha1check/data/repositorywithinvalidchecksum/E/1.0.2-1content.7z.sha1 b/tests/auto/installer/contentsha1check/data/repositorywithinvalidchecksum/E/1.0.2-1content.7z.sha1 new file mode 100644 index 000000000..641396e0f --- /dev/null +++ b/tests/auto/installer/contentsha1check/data/repositorywithinvalidchecksum/E/1.0.2-1content.7z.sha1 @@ -0,0 +1 @@ +2c185d45cb84cec7a71e317f8cfc64dd23094c32
\ No newline at end of file diff --git a/tests/auto/installer/contentsha1check/data/repositorywithinvalidchecksum/E/1.0.2-1meta.7z b/tests/auto/installer/contentsha1check/data/repositorywithinvalidchecksum/E/1.0.2-1meta.7z Binary files differnew file mode 100644 index 000000000..4feab5c34 --- /dev/null +++ b/tests/auto/installer/contentsha1check/data/repositorywithinvalidchecksum/E/1.0.2-1meta.7z diff --git a/tests/auto/installer/contentsha1check/data/repositorywithinvalidchecksum/F/1.0.0-1content.7z b/tests/auto/installer/contentsha1check/data/repositorywithinvalidchecksum/F/1.0.0-1content.7z Binary files differnew file mode 100644 index 000000000..f53a705dd --- /dev/null +++ b/tests/auto/installer/contentsha1check/data/repositorywithinvalidchecksum/F/1.0.0-1content.7z diff --git a/tests/auto/installer/contentsha1check/data/repositorywithinvalidchecksum/F/1.0.0-1content.7z.sha1 b/tests/auto/installer/contentsha1check/data/repositorywithinvalidchecksum/F/1.0.0-1content.7z.sha1 new file mode 100644 index 000000000..daf89acba --- /dev/null +++ b/tests/auto/installer/contentsha1check/data/repositorywithinvalidchecksum/F/1.0.0-1content.7z.sha1 @@ -0,0 +1 @@ +d33a5fb638047372e9793b48d6c5ff85da560595
\ No newline at end of file diff --git a/tests/auto/installer/contentsha1check/data/repositorywithinvalidchecksum/F/1.0.0-1meta.7z b/tests/auto/installer/contentsha1check/data/repositorywithinvalidchecksum/F/1.0.0-1meta.7z Binary files differnew file mode 100644 index 000000000..9931c0a7f --- /dev/null +++ b/tests/auto/installer/contentsha1check/data/repositorywithinvalidchecksum/F/1.0.0-1meta.7z diff --git a/tests/auto/installer/contentsha1check/data/repositorywithinvalidchecksum/Updates.xml b/tests/auto/installer/contentsha1check/data/repositorywithinvalidchecksum/Updates.xml new file mode 100644 index 000000000..bda013684 --- /dev/null +++ b/tests/auto/installer/contentsha1check/data/repositorywithinvalidchecksum/Updates.xml @@ -0,0 +1,27 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>true</Checksum> + <PackageUpdate> + <Name>E</Name> + <DisplayName>E</DisplayName> + <Description>Example component E, invalid checksum</Description> + <Version>1.0.2-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <UpdateFile CompressedSize="215" OS="Any" UncompressedSize="74"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>db7e010425aaaaaaeebc6281a9d4c91e5666fd8f</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>F</Name> + <DisplayName>F</DisplayName> + <Description>Example component F</Description> + <Version>1.0.0-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <UpdateFile CompressedSize="215" OS="Any" UncompressedSize="74"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>b69b864cef5d0aecb496273374dd24bb8cba83bd</SHA1> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/contentsha1check/data/repositorywithnochecksumcheck/C/1.0.2-1content.7z b/tests/auto/installer/contentsha1check/data/repositorywithnochecksumcheck/C/1.0.2-1content.7z Binary files differnew file mode 100644 index 000000000..f96bfa9a3 --- /dev/null +++ b/tests/auto/installer/contentsha1check/data/repositorywithnochecksumcheck/C/1.0.2-1content.7z diff --git a/tests/auto/installer/contentsha1check/data/repositorywithnochecksumcheck/C/1.0.2-1meta.7z b/tests/auto/installer/contentsha1check/data/repositorywithnochecksumcheck/C/1.0.2-1meta.7z Binary files differnew file mode 100644 index 000000000..976c57b43 --- /dev/null +++ b/tests/auto/installer/contentsha1check/data/repositorywithnochecksumcheck/C/1.0.2-1meta.7z diff --git a/tests/auto/installer/contentsha1check/data/repositorywithnochecksumcheck/D/1.0.0-1content.7z b/tests/auto/installer/contentsha1check/data/repositorywithnochecksumcheck/D/1.0.0-1content.7z Binary files differnew file mode 100644 index 000000000..015670af0 --- /dev/null +++ b/tests/auto/installer/contentsha1check/data/repositorywithnochecksumcheck/D/1.0.0-1content.7z diff --git a/tests/auto/installer/contentsha1check/data/repositorywithnochecksumcheck/D/1.0.0-1meta.7z b/tests/auto/installer/contentsha1check/data/repositorywithnochecksumcheck/D/1.0.0-1meta.7z Binary files differnew file mode 100644 index 000000000..0b36609d7 --- /dev/null +++ b/tests/auto/installer/contentsha1check/data/repositorywithnochecksumcheck/D/1.0.0-1meta.7z diff --git a/tests/auto/installer/contentsha1check/data/repositorywithnochecksumcheck/Updates.xml b/tests/auto/installer/contentsha1check/data/repositorywithnochecksumcheck/Updates.xml new file mode 100644 index 000000000..ae2ba911a --- /dev/null +++ b/tests/auto/installer/contentsha1check/data/repositorywithnochecksumcheck/Updates.xml @@ -0,0 +1,27 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>C</Name> + <DisplayName>C</DisplayName> + <Description>Example component C</Description> + <Version>1.0.2-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <UpdateFile OS="Any" UncompressedSize="74" CompressedSize="215"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>f82e1d1bbfd252715ace26db8c62595252e28a3b</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>D</Name> + <DisplayName>D</DisplayName> + <Description>Example component D</Description> + <Version>1.0.0-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <UpdateFile OS="Any" UncompressedSize="74" CompressedSize="215"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>402f299ec90f215db390b150c9429101344cf1ea</SHA1> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/contentsha1check/settings.qrc b/tests/auto/installer/contentsha1check/settings.qrc new file mode 100644 index 000000000..e150ea61e --- /dev/null +++ b/tests/auto/installer/contentsha1check/settings.qrc @@ -0,0 +1,18 @@ +<RCC> + <qresource prefix="/"> + <file>data/config.xml</file> + <file>data/repositorywithchecksumcheck/Updates.xml</file> + <file>data/repositorywithchecksumcheck/A/1.0.2-1content.7z</file> + <file>data/repositorywithchecksumcheck/A/1.0.2-1content.7z.sha1</file> + <file>data/repositorywithchecksumcheck/B/1.0.0-1content.7z</file> + <file>data/repositorywithchecksumcheck/B/1.0.0-1content.7z.sha1</file> + <file>data/repositorywithnochecksumcheck/Updates.xml</file> + <file>data/repositorywithnochecksumcheck/C/1.0.2-1content.7z</file> + <file>data/repositorywithnochecksumcheck/D/1.0.0-1content.7z</file> + <file>data/repositorywithinvalidchecksum/Updates.xml</file> + <file>data/repositorywithinvalidchecksum/E/1.0.2-1content.7z</file> + <file>data/repositorywithinvalidchecksum/E/1.0.2-1content.7z.sha1</file> + <file>data/repositorywithinvalidchecksum/F/1.0.0-1content.7z</file> + <file>data/repositorywithinvalidchecksum/F/1.0.0-1content.7z.sha1</file> + </qresource> +</RCC> diff --git a/tests/auto/installer/contentsha1check/tst_contentsha1check.cpp b/tests/auto/installer/contentsha1check/tst_contentsha1check.cpp new file mode 100644 index 000000000..e587d3011 --- /dev/null +++ b/tests/auto/installer/contentsha1check/tst_contentsha1check.cpp @@ -0,0 +1,181 @@ +/************************************************************************** +** +** Copyright (C) 2023 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ +#include "../shared/packagemanager.h" +#include "../shared/verifyinstaller.h" + +#include <component.h> +#include <packagemanagercore.h> + +#include <QLoggingCategory> +#include <QTest> +#include <QMessageBox> + +using namespace QInstaller; + +typedef QList<QPair<QString, QString> > ComponentResourceHash; +typedef QPair<QString, QString> ComponentResource; + +static QStringList expectedMessages; + +void downloadingArchiveOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) +{ + Q_UNUSED(type) + Q_UNUSED(context) + QByteArray localMsg = msg.toLocal8Bit(); + if (!msg.startsWith("Downloading archive")) + return; + if (expectedMessages.contains(msg)) + expectedMessages.removeOne(msg); +} + +class tst_ContentSha1Check : public QObject +{ + Q_OBJECT + +private slots: + + void testInstall_data() + { + QTest::addColumn<QString>("repository"); + QTest::addColumn<QStringList>("installComponents"); + QTest::addColumn<PackageManagerCore::Status>("status"); + QTest::addColumn<ComponentResourceHash>("componentResources"); + QTest::addColumn<QStringList >("installedFiles"); + QTest::addColumn<QStringList >("expectedDownloadingArchiveMessages"); + + /*********** Install with checksum check **********/ + ComponentResourceHash componentResources; + componentResources.append(ComponentResource("A", "1.0.2-1content.txt")); + componentResources.append(ComponentResource("B", "1.0.0-1content.txt")); + + QTest::newRow("Check checksum") + << ":///data/repositorywithchecksumcheck" + << (QStringList() << "A" << "B") + << PackageManagerCore::Success + << componentResources + << (QStringList() << "components.xml" << "A.txt" << "B.txt") + << (QStringList() << "Downloading archive \"1.0.2-1content.7z.sha1\" for component A." + << "Downloading archive \"1.0.2-1content.7z\" for component A." + << "Downloading archive \"1.0.0-1content.7z.sha1\" for component B." + << "Downloading archive \"1.0.0-1content.7z\" for component B."); + + /*********** Install with and without checksum check **********/ + componentResources.clear(); + componentResources.append(ComponentResource("C", "1.0.2-1content.txt")); + componentResources.append(ComponentResource("D", "1.0.0-1content.txt")); + + QTest::newRow("Without checksum check") + << ":///data/repositorywithnochecksumcheck" + << (QStringList() << "C" << "D") + << PackageManagerCore::Success + << componentResources + << (QStringList() << "components.xml" << "C.txt" << "D.txt") + << (QStringList() << "Downloading archive \"1.0.2-1content.7z\" for component C." + << "Downloading archive \"1.0.0-1content.7z\" for component D."); + + } + + void testInstallWithInvalidChecksum_data() + { + QTest::addColumn<QString>("repository"); + QTest::addColumn<QStringList>("installComponents"); + QTest::addColumn<PackageManagerCore::Status>("status"); + QTest::addColumn<ComponentResourceHash>("componentResources"); + QTest::addColumn<QStringList >("installedFiles"); + + /*********** Install with checksum check **********/ + ComponentResourceHash componentResources; + + QTest::newRow("Invalid checksum") + << ":///data/repositorywithinvalidchecksum" + << (QStringList() << "E" << "F") + << PackageManagerCore::Failure + << componentResources + << (QStringList()); + } + + void testInstall() + { + QFETCH(QString, repository); + QFETCH(QStringList, installComponents); + QFETCH(PackageManagerCore::Status, status); + QFETCH(ComponentResourceHash, componentResources); + QFETCH(QStringList, installedFiles); + QFETCH(QStringList, expectedDownloadingArchiveMessages); + + expectedMessages = expectedDownloadingArchiveMessages; + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (m_installDir, repository)); + qInstallMessageHandler(downloadingArchiveOutput); + + QCOMPARE(status, core->installSelectedComponentsSilently(QStringList() << installComponents)); + for (const ComponentResource &resource : componentResources) + VerifyInstaller::verifyInstallerResources(m_installDir, resource.first, resource.second); + VerifyInstaller::verifyFileExistence(m_installDir, installedFiles); + + QVERIFY(expectedMessages.isEmpty()); + } + + void testInstallWithInvalidChecksum() + { + QFETCH(QString, repository); + QFETCH(QStringList, installComponents); + QFETCH(PackageManagerCore::Status, status); + QFETCH(ComponentResourceHash, componentResources); + QFETCH(QStringList, installedFiles); + + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (m_installDir, repository)); + core->setMessageBoxAutomaticAnswer("DownloadError", QMessageBox::Cancel); + core->setMessageBoxAutomaticAnswer("installationError", QMessageBox::Ok); + + QCOMPARE(status, core->installSelectedComponentsSilently(QStringList() << installComponents)); + QVERIFY(!QDir().exists(m_installDir)); + } + + void init() + { + m_installDir = QInstaller::generateTemporaryFileName(); + QVERIFY(QDir().mkpath(m_installDir)); + } + + void cleanup() + { + QDir dir(m_installDir); + QVERIFY(dir.removeRecursively()); + } + +private: + QString m_installDir; + QStringList m_expectedMessages; +}; + + +QTEST_MAIN(tst_ContentSha1Check) + +#include "tst_contentsha1check.moc" diff --git a/tests/auto/installer/contentshaupdate/contentshaupdate.pro b/tests/auto/installer/contentshaupdate/contentshaupdate.pro new file mode 100644 index 000000000..dd7b885fc --- /dev/null +++ b/tests/auto/installer/contentshaupdate/contentshaupdate.pro @@ -0,0 +1,9 @@ +include(../../qttest.pri) + +QT += qml + +SOURCES += tst_contentshaupdate.cpp + +RESOURCES += \ + settings.qrc \ + ../shared/config.qrc diff --git a/tests/auto/installer/contentshaupdate/data/repository/Updates.xml b/tests/auto/installer/contentshaupdate/data/repository/Updates.xml new file mode 100644 index 000000000..a83d41384 --- /dev/null +++ b/tests/auto/installer/contentshaupdate/data/repository/Updates.xml @@ -0,0 +1,48 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>componentA</Name> + <DisplayName>Component A</DisplayName> + <Description>This component does not depend on any other component.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>100</SortingPriority> + <UpdateFile OS="Any" CompressedSize="283" UncompressedSize="101"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <ContentSha1>10</ContentSha1> + </PackageUpdate> + <PackageUpdate> + <Name>componentB</Name> + <DisplayName>Component B</DisplayName> + <Description>This component does not depend on any other component.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>90</SortingPriority> + <UpdateFile OS="Any" CompressedSize="283" UncompressedSize="101"/> + <DownloadableArchives>content.7z</DownloadableArchives> + </PackageUpdate> + <PackageUpdate> + <Name>componentC</Name> + <DisplayName>Component C</DisplayName> + <Description>Component C</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>80</SortingPriority> + <UpdateFile OS="Any" CompressedSize="283" UncompressedSize="101"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <ContentSha1>10</ContentSha1> + </PackageUpdate> + <PackageUpdate> + <Name>componentD</Name> + <DisplayName>Component D</DisplayName> + <Description>Component D</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>80</SortingPriority> + <UpdateFile CompressedSize="283" UncompressedSize="101" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <ContentSha1>10</ContentSha1> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/contentshaupdate/data/repository/componentA/1.0.0content.7z b/tests/auto/installer/contentshaupdate/data/repository/componentA/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..46a9f1d1e --- /dev/null +++ b/tests/auto/installer/contentshaupdate/data/repository/componentA/1.0.0content.7z diff --git a/tests/auto/installer/contentshaupdate/data/repository/componentB/1.0.0content.7z b/tests/auto/installer/contentshaupdate/data/repository/componentB/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..5f1fb2e1b --- /dev/null +++ b/tests/auto/installer/contentshaupdate/data/repository/componentB/1.0.0content.7z diff --git a/tests/auto/installer/contentshaupdate/data/repository/componentC/1.0.0content.7z b/tests/auto/installer/contentshaupdate/data/repository/componentC/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..83e82b5a3 --- /dev/null +++ b/tests/auto/installer/contentshaupdate/data/repository/componentC/1.0.0content.7z diff --git a/tests/auto/installer/contentshaupdate/data/repository/componentD/1.0.0content.7z b/tests/auto/installer/contentshaupdate/data/repository/componentD/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..da50742a4 --- /dev/null +++ b/tests/auto/installer/contentshaupdate/data/repository/componentD/1.0.0content.7z diff --git a/tests/auto/installer/contentshaupdate/data/repositoryUpdate/Updates.xml b/tests/auto/installer/contentshaupdate/data/repositoryUpdate/Updates.xml new file mode 100644 index 000000000..87017cf91 --- /dev/null +++ b/tests/auto/installer/contentshaupdate/data/repositoryUpdate/Updates.xml @@ -0,0 +1,48 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>componentA</Name> + <DisplayName>Component A</DisplayName> + <Description>Component A.</Description> + <Version>0.1.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>100</SortingPriority> + <UpdateFile CompressedSize="283" UncompressedSize="101" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <ContentSha1>5</ContentSha1> + </PackageUpdate> + <PackageUpdate> + <Name>componentB</Name> + <DisplayName>Component B</DisplayName> + <Description>Component B.</Description> + <Version>0.1.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>90</SortingPriority> + <UpdateFile CompressedSize="283" UncompressedSize="101" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <ContentSha1>10</ContentSha1> + </PackageUpdate> + <PackageUpdate> + <Name>componentC</Name> + <DisplayName>Component C</DisplayName> + <Description>Component C</Description> + <Version>2.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>80</SortingPriority> + <UpdateFile CompressedSize="283" UncompressedSize="101" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <ContentSha1>10</ContentSha1> + </PackageUpdate> + <PackageUpdate> + <Name>componentD</Name> + <DisplayName>Component D</DisplayName> + <Description>Component D</Description> + <Version>2.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>80</SortingPriority> + <UpdateFile UncompressedSize="101" CompressedSize="283" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/contentshaupdate/data/repositoryUpdate/componentA/0.1.0content.7z b/tests/auto/installer/contentshaupdate/data/repositoryUpdate/componentA/0.1.0content.7z Binary files differnew file mode 100644 index 000000000..bdbabc7fd --- /dev/null +++ b/tests/auto/installer/contentshaupdate/data/repositoryUpdate/componentA/0.1.0content.7z diff --git a/tests/auto/installer/contentshaupdate/data/repositoryUpdate/componentB/0.1.0content.7z b/tests/auto/installer/contentshaupdate/data/repositoryUpdate/componentB/0.1.0content.7z Binary files differnew file mode 100644 index 000000000..1c1129b9f --- /dev/null +++ b/tests/auto/installer/contentshaupdate/data/repositoryUpdate/componentB/0.1.0content.7z diff --git a/tests/auto/installer/contentshaupdate/data/repositoryUpdate/componentC/2.0.0content.7z b/tests/auto/installer/contentshaupdate/data/repositoryUpdate/componentC/2.0.0content.7z Binary files differnew file mode 100644 index 000000000..7f75bf503 --- /dev/null +++ b/tests/auto/installer/contentshaupdate/data/repositoryUpdate/componentC/2.0.0content.7z diff --git a/tests/auto/installer/contentshaupdate/data/repositoryUpdate/componentD/2.0.0content.7z b/tests/auto/installer/contentshaupdate/data/repositoryUpdate/componentD/2.0.0content.7z Binary files differnew file mode 100644 index 000000000..4207dfbf2 --- /dev/null +++ b/tests/auto/installer/contentshaupdate/data/repositoryUpdate/componentD/2.0.0content.7z diff --git a/tests/auto/installer/contentshaupdate/data/repositoryUpdateWithEssential/Updates.xml b/tests/auto/installer/contentshaupdate/data/repositoryUpdateWithEssential/Updates.xml new file mode 100644 index 000000000..fe5dc4dec --- /dev/null +++ b/tests/auto/installer/contentshaupdate/data/repositoryUpdateWithEssential/Updates.xml @@ -0,0 +1,28 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>componentA</Name> + <DisplayName>Component A</DisplayName> + <Description>Component A.</Description> + <Version>0.1.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>100</SortingPriority> + <UpdateFile CompressedSize="283" UncompressedSize="101" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <ContentSha1>5</ContentSha1> + </PackageUpdate> + <PackageUpdate> + <Name>componentEssential</Name> + <DisplayName>Component Essential</DisplayName> + <Description>Component Essential</Description> + <Essential>true</Essential> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>80</SortingPriority> + <UpdateFile UncompressedSize="101" CompressedSize="283" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <ContentSha1>10</ContentSha1> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/contentshaupdate/data/repositoryUpdateWithEssential/componentA/0.1.0content.7z b/tests/auto/installer/contentshaupdate/data/repositoryUpdateWithEssential/componentA/0.1.0content.7z Binary files differnew file mode 100644 index 000000000..bdbabc7fd --- /dev/null +++ b/tests/auto/installer/contentshaupdate/data/repositoryUpdateWithEssential/componentA/0.1.0content.7z diff --git a/tests/auto/installer/contentshaupdate/data/repositoryUpdateWithEssential/componentEssential/1.0.0content.7z b/tests/auto/installer/contentshaupdate/data/repositoryUpdateWithEssential/componentEssential/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..9c86042c0 --- /dev/null +++ b/tests/auto/installer/contentshaupdate/data/repositoryUpdateWithEssential/componentEssential/1.0.0content.7z diff --git a/tests/auto/installer/contentshaupdate/data/repositoryWithEssential/Updates.xml b/tests/auto/installer/contentshaupdate/data/repositoryWithEssential/Updates.xml new file mode 100644 index 000000000..f76c03faa --- /dev/null +++ b/tests/auto/installer/contentshaupdate/data/repositoryWithEssential/Updates.xml @@ -0,0 +1,27 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>componentA</Name> + <DisplayName>Component A</DisplayName> + <Description>This component does not depend on any other component.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>100</SortingPriority> + <UpdateFile OS="Any" CompressedSize="283" UncompressedSize="101"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <ContentSha1>10</ContentSha1> + </PackageUpdate> + <PackageUpdate> + <Name>componentEssential</Name> + <DisplayName>Component Essential</DisplayName> + <Description>Component Essential</Description> + <Essential>true</Essential> + <Version>2.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>80</SortingPriority> + <UpdateFile UncompressedSize="101" CompressedSize="283" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/contentshaupdate/data/repositoryWithEssential/componentA/1.0.0content.7z b/tests/auto/installer/contentshaupdate/data/repositoryWithEssential/componentA/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..46a9f1d1e --- /dev/null +++ b/tests/auto/installer/contentshaupdate/data/repositoryWithEssential/componentA/1.0.0content.7z diff --git a/tests/auto/installer/contentshaupdate/data/repositoryWithEssential/componentEssential/2.0.0content.7z b/tests/auto/installer/contentshaupdate/data/repositoryWithEssential/componentEssential/2.0.0content.7z Binary files differnew file mode 100644 index 000000000..435f260ee --- /dev/null +++ b/tests/auto/installer/contentshaupdate/data/repositoryWithEssential/componentEssential/2.0.0content.7z diff --git a/tests/auto/installer/contentshaupdate/settings.qrc b/tests/auto/installer/contentshaupdate/settings.qrc new file mode 100644 index 000000000..e3426be92 --- /dev/null +++ b/tests/auto/installer/contentshaupdate/settings.qrc @@ -0,0 +1,20 @@ +<RCC> + <qresource prefix="/"> + <file>data/repository/Updates.xml</file> + <file>data/repository/componentA/1.0.0content.7z</file> + <file>data/repository/componentB/1.0.0content.7z</file> + <file>data/repository/componentC/1.0.0content.7z</file> + <file>data/repository/componentD/1.0.0content.7z</file> + <file>data/repositoryWithEssential/Updates.xml</file> + <file>data/repositoryWithEssential/componentA/1.0.0content.7z</file> + <file>data/repositoryWithEssential/componentEssential/2.0.0content.7z</file> + <file>data/repositoryUpdate/Updates.xml</file> + <file>data/repositoryUpdate/componentA/0.1.0content.7z</file> + <file>data/repositoryUpdate/componentB/0.1.0content.7z</file> + <file>data/repositoryUpdate/componentC/2.0.0content.7z</file> + <file>data/repositoryUpdate/componentD/2.0.0content.7z</file> + <file>data/repositoryUpdateWithEssential/Updates.xml</file> + <file>data/repositoryUpdateWithEssential/componentA/0.1.0content.7z</file> + <file>data/repositoryUpdateWithEssential/componentEssential/1.0.0content.7z</file> + </qresource> +</RCC> diff --git a/tests/auto/installer/contentshaupdate/tst_contentshaupdate.cpp b/tests/auto/installer/contentshaupdate/tst_contentshaupdate.cpp new file mode 100644 index 000000000..5d282fe38 --- /dev/null +++ b/tests/auto/installer/contentshaupdate/tst_contentshaupdate.cpp @@ -0,0 +1,124 @@ +/************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ + +#include "../shared/packagemanager.h" +#include "../shared/verifyinstaller.h" + +#include <QTest> + +using namespace QInstaller; + +class tst_ContentSha1Update : public QObject +{ + Q_OBJECT + +private: + void setRepository(const QString &repository) + { + core->reset(); + core->cancelMetaInfoJob(); //Call cancel to reset metadata so that update repositories are fetched + + QSet<Repository> repoList; + Repository repo = Repository::fromUserInput(repository); + repoList.insert(repo); + core->settings().setDefaultRepositories(repoList); + } + +private slots: + void initTestCase() + { + m_installDir = QInstaller::generateTemporaryFileName(); + core = PackageManager::getPackageManagerWithInit(m_installDir); + } + + void updateWithContentSha1_data() + { + QTest::addColumn<QString>("repository"); + QTest::addColumn<QString>("repositoryForUpdate"); + QTest::addColumn<QString>("component"); + QTest::addColumn<QString>("content"); + QTest::addColumn<QString>("updatedContent"); + QTest::addColumn<PackageManagerCore::Status>("expectedStatusAfterInstall"); + QTest::addColumn<PackageManagerCore::Status>("expectedStatusAfterUpdate"); + + QTest::newRow("Sha1UpdateForEssential") + << ":///data/repositoryWithEssential" << ":///data/repositoryUpdateWithEssential" + << "componentEssential" << "2.0.0content.txt" << "1.0.0content.txt" + << PackageManagerCore::Success << PackageManagerCore::EssentialUpdated; + QTest::newRow("ContentSha1Change") + << ":///data/repository" << ":///data/repositoryUpdate" << "componentA" << "1.0.0content.txt" << "0.1.0content.txt" + << PackageManagerCore::Success << PackageManagerCore::Success; + QTest::newRow("NewContentSha1") + << ":///data/repository" << ":///data/repositoryUpdate" << "componentB" << "1.0.0content.txt" << "0.1.0content.txt" + << PackageManagerCore::Success << PackageManagerCore::Success; + QTest::newRow("SameContentSha1") + << ":///data/repository" << ":///data/repositoryUpdate" << "componentC" << "1.0.0content.txt" << "1.0.0content.txt" + << PackageManagerCore::Success << PackageManagerCore::Canceled; + QTest::newRow("Sha1RemovedFromRepo") + << ":///data/repository" << ":///data/repositoryUpdate" << "componentD" << "1.0.0content.txt" << "2.0.0content.txt" + << PackageManagerCore::Success << PackageManagerCore::Success; + } + + void updateWithContentSha1() + { + QFETCH(QString, repository); + QFETCH(QString, repositoryForUpdate); + QFETCH(QString, component); + QFETCH(QString, content); + QFETCH(QString, updatedContent); + QFETCH(PackageManagerCore::Status, expectedStatusAfterInstall); + QFETCH(PackageManagerCore::Status, expectedStatusAfterUpdate); + + setRepository(repository); + QCOMPARE(expectedStatusAfterInstall, core->installSelectedComponentsSilently(QStringList() << component)); + QCOMPARE(expectedStatusAfterInstall, core->status()); + VerifyInstaller::verifyInstallerResources(m_installDir, component, content); + + core->commitSessionOperations(); + core->setPackageManager(); + setRepository(repositoryForUpdate); + QCOMPARE(expectedStatusAfterUpdate, core->updateComponentsSilently(QStringList())); + VerifyInstaller::verifyInstallerResources(m_installDir, component, updatedContent); + } + + void cleanupTestCase() + { + QDir dir(m_installDir); + QVERIFY(dir.removeRecursively()); + delete core; + } + +private: + QString m_installDir; + PackageManagerCore *core; +}; + + +QTEST_MAIN(tst_ContentSha1Update) + +#include "tst_contentshaupdate.moc" diff --git a/tests/auto/installer/copydirectoryoperation/copydirectoryoperation.pro b/tests/auto/installer/copydirectoryoperation/copydirectoryoperation.pro new file mode 100644 index 000000000..c3d7d17b9 --- /dev/null +++ b/tests/auto/installer/copydirectoryoperation/copydirectoryoperation.pro @@ -0,0 +1,10 @@ +include(../../qttest.pri) + +QT -= gui +QT += testlib + +SOURCES += tst_copydirectoryoperation.cpp + +RESOURCES += \ + settings.qrc \ + ../shared/config.qrc diff --git a/tests/auto/installer/copydirectoryoperation/data/repository/A/1.0.2-1content.7z b/tests/auto/installer/copydirectoryoperation/data/repository/A/1.0.2-1content.7z Binary files differnew file mode 100644 index 000000000..920ed1d99 --- /dev/null +++ b/tests/auto/installer/copydirectoryoperation/data/repository/A/1.0.2-1content.7z diff --git a/tests/auto/installer/copydirectoryoperation/data/repository/A/1.0.2-1meta.7z b/tests/auto/installer/copydirectoryoperation/data/repository/A/1.0.2-1meta.7z Binary files differnew file mode 100644 index 000000000..7449d052b --- /dev/null +++ b/tests/auto/installer/copydirectoryoperation/data/repository/A/1.0.2-1meta.7z diff --git a/tests/auto/installer/copydirectoryoperation/data/repository/Updates.xml b/tests/auto/installer/copydirectoryoperation/data/repository/Updates.xml new file mode 100644 index 000000000..fb8c9cf1c --- /dev/null +++ b/tests/auto/installer/copydirectoryoperation/data/repository/Updates.xml @@ -0,0 +1,16 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.2-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <Script>script.qs</Script> + <SHA1>4fd4dd023111fcbbdd1221032c2984d249f4cad1</SHA1> + <DownloadableArchives>content.7z</DownloadableArchives> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/copydirectoryoperation/data/xmloperationrepository/A/1.0.2-1content.7z b/tests/auto/installer/copydirectoryoperation/data/xmloperationrepository/A/1.0.2-1content.7z Binary files differnew file mode 100644 index 000000000..920ed1d99 --- /dev/null +++ b/tests/auto/installer/copydirectoryoperation/data/xmloperationrepository/A/1.0.2-1content.7z diff --git a/tests/auto/installer/copydirectoryoperation/data/xmloperationrepository/A/1.0.2-1meta.7z b/tests/auto/installer/copydirectoryoperation/data/xmloperationrepository/A/1.0.2-1meta.7z Binary files differnew file mode 100644 index 000000000..7449d052b --- /dev/null +++ b/tests/auto/installer/copydirectoryoperation/data/xmloperationrepository/A/1.0.2-1meta.7z diff --git a/tests/auto/installer/copydirectoryoperation/data/xmloperationrepository/Updates.xml b/tests/auto/installer/copydirectoryoperation/data/xmloperationrepository/Updates.xml new file mode 100644 index 000000000..b495f3307 --- /dev/null +++ b/tests/auto/installer/copydirectoryoperation/data/xmloperationrepository/Updates.xml @@ -0,0 +1,24 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.2-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <SHA1>4fd4dd023111fcbbdd1221032c2984d249f4cad1</SHA1> + <DownloadableArchives>content.7z</DownloadableArchives> + <Operations> + <Operation name="Mkdir"> + <Argument>@TargetDir@/destination/directory</Argument> + </Operation> + <Operation name="CopyDirectory"> + <Argument>@TargetDir@/directory</Argument> + <Argument>@TargetDir@/destination/directory</Argument> + </Operation> + </Operations> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/copydirectoryoperation/settings.qrc b/tests/auto/installer/copydirectoryoperation/settings.qrc new file mode 100644 index 000000000..094bd449b --- /dev/null +++ b/tests/auto/installer/copydirectoryoperation/settings.qrc @@ -0,0 +1,9 @@ +<RCC> + <qresource prefix="/"> + <file>data/repository/Updates.xml</file> + <file>data/repository/A/1.0.2-1content.7z</file> + <file>data/repository/A/1.0.2-1meta.7z</file> + <file>data/xmloperationrepository/Updates.xml</file> + <file>data/xmloperationrepository/A/1.0.2-1content.7z</file> + </qresource> +</RCC> diff --git a/tests/auto/installer/copydirectoryoperation/tst_copydirectoryoperation.cpp b/tests/auto/installer/copydirectoryoperation/tst_copydirectoryoperation.cpp new file mode 100644 index 000000000..a1692095d --- /dev/null +++ b/tests/auto/installer/copydirectoryoperation/tst_copydirectoryoperation.cpp @@ -0,0 +1,217 @@ +/************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ + +#include "../shared/packagemanager.h" +#include "../shared/verifyinstaller.h" + +#include <copydirectoryoperation.h> +#include <packagemanagercore.h> + +#include <QDir> +#include <QFile> +#include <QTest> + +using namespace KDUpdater; +using namespace QInstaller; + +class tst_copydirectoryoperation : public QObject +{ + Q_OBJECT + +private: + void installFromCLI(const QString &repository) + { + QString installDir = QInstaller::generateTemporaryFileName(); + QVERIFY(QDir().mkpath(installDir)); + PackageManagerCore *core = PackageManager::getPackageManagerWithInit + (installDir, repository); + + core->setValue(scTargetDir, installDir); + core->installDefaultComponentsSilently(); + + // Matches path in component install script + QFileInfo targetInfo(installDir + QDir::toNativeSeparators("/directory")); + QMap<QString, QByteArray> targetMap; + VerifyInstaller::addToFileMap(QDir(targetInfo.absoluteFilePath()), targetInfo, targetMap); + + QFileInfo destinationInfo(installDir + QDir::toNativeSeparators("/destination/directory")); + QMap<QString, QByteArray> destinationMap; + VerifyInstaller::addToFileMap(QDir(destinationInfo.absoluteFilePath()), destinationInfo, destinationMap); + + QVERIFY(targetMap == destinationMap); + + core->setPackageManager(); + core->commitSessionOperations(); + core->uninstallComponentsSilently(QStringList() << "A"); + QVERIFY(!destinationInfo.exists()); + + QDir dir(installDir); + QVERIFY(dir.removeRecursively()); + core->deleteLater(); + } + + QStringList populateSourceDirectory() + { + QStringList fileEntries; + fileEntries << "file1" << "file2" << ".hidden1" << ".hidden2"; + + // Populate source directory + foreach (const QString &entry, fileEntries) { + QFile file(m_sourcePath + entry); + file.open(QFileDevice::ReadWrite); + file.close(); + } + return fileEntries; + } + +private slots: + void initTestCase() + { + m_sourcePath = qApp->applicationDirPath() + QDir::toNativeSeparators("/source/"); + m_destinationPath = generateTemporaryFileName() + QDir::toNativeSeparators("_dest/"); + } + + void init() + { + QDir sourceDir; + QVERIFY(sourceDir.mkpath(m_sourcePath)); + + QDir destinationDir; + QVERIFY(destinationDir.mkpath(m_destinationPath)); + } + + void cleanup() + { + QVERIFY(QDir(m_sourcePath).removeRecursively()); + QVERIFY(QDir(m_destinationPath).removeRecursively()); + } + + void testInvalidArguments() + { + CopyDirectoryOperation op(nullptr); + + QVERIFY(op.testOperation()); + op.backup(); + + QVERIFY(!op.performOperation()); + + QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::InvalidArguments); + QCOMPARE(op.errorString(), QString("Invalid arguments in CopyDirectory: " + "0 arguments given, 2 or 3 arguments expected in the form: " + "<source> <target> [\"forceOverwrite\"].")); + + op.setArguments(QStringList() << "" << "" << "overwrite"); + QVERIFY(!op.performOperation()); + + QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::InvalidArguments); + QCOMPARE(op.errorString(), QString("Invalid argument in CopyDirectory: " + "Third argument needs to be forceOverwrite, " + "if specified.")); + + op.setArguments(QStringList() << "" << ""); + QVERIFY(!op.performOperation()); + + QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::InvalidArguments); + QCOMPARE(op.errorString(), QString("Invalid argument in CopyDirectory: " + "Directory \"\" is invalid.")); + } + + void testCopyDirectoryWithUndo() + { + const QStringList fileEntries = populateSourceDirectory(); + + CopyDirectoryOperation op(nullptr); + op.setArguments(QStringList() << m_sourcePath << m_destinationPath); + QVERIFY2(op.performOperation(), op.errorString().toLatin1()); + + foreach (const QString &entry, fileEntries) + QVERIFY(QFile(m_destinationPath + entry).exists()); + + QVERIFY2(op.undoOperation(), op.errorString().toLatin1()); + // Undo will delete the empty destination directory here + QVERIFY(!QFileInfo(m_destinationPath).exists()); + } + + + void testCopyDirectoryNoUndo() + { + const QStringList fileEntries = populateSourceDirectory(); + + CopyDirectoryOperation op(nullptr); + op.setArguments(QStringList() << m_sourcePath << m_destinationPath << "UNDOOPERATION" << ""); + + QVERIFY2(op.performOperation(), op.errorString().toLatin1()); + + foreach (const QString &entry, fileEntries) + QVERIFY(QFile(m_destinationPath + entry).exists()); + + QVERIFY2(op.undoOperation(), op.errorString().toLatin1()); + // Undo will NOT delete the empty destination directory here + foreach (const QString &entry, fileEntries) + QVERIFY(QFile(m_destinationPath + entry).exists()); + } + + void testCopyDirectoryOverwrite() + { + QFile file(m_sourcePath + "file"); + QVERIFY(file.open(QFileDevice::ReadWrite)); + file.close(); + + file.setFileName(m_destinationPath + "file"); + QVERIFY(file.open(QFileDevice::ReadWrite)); + file.close(); + + CopyDirectoryOperation op(nullptr); + + op.setArguments(QStringList() << m_sourcePath << m_destinationPath); + QVERIFY(!op.performOperation()); + + QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::UserDefinedError); + + op.setArguments(QStringList() << m_sourcePath << m_destinationPath << "forceOverwrite"); + QVERIFY2(op.performOperation(), op.errorString().toLatin1()); + } + + void testCopyDirectoryFromScript() + { + installFromCLI(":///data/repository"); + } + + void testCopyDirectoryFromComponentXML() + { + installFromCLI(":///data/xmloperationrepository"); + } + +private: + QString m_sourcePath; + QString m_destinationPath; +}; + +QTEST_MAIN(tst_copydirectoryoperation) + +#include "tst_copydirectoryoperation.moc" diff --git a/tests/auto/installer/copyoperationtest/copyoperationtest.pro b/tests/auto/installer/copyoperationtest/copyoperationtest.pro index ce4ad42ec..a832fe295 100644 --- a/tests/auto/installer/copyoperationtest/copyoperationtest.pro +++ b/tests/auto/installer/copyoperationtest/copyoperationtest.pro @@ -4,3 +4,7 @@ QT -= gui QT += testlib SOURCES = tst_copyoperationtest.cpp + +RESOURCES += \ + settings.qrc \ + ../shared/config.qrc diff --git a/tests/auto/installer/copyoperationtest/data/repository/A/1.0.2-1content.7z b/tests/auto/installer/copyoperationtest/data/repository/A/1.0.2-1content.7z Binary files differnew file mode 100644 index 000000000..8ba90b13b --- /dev/null +++ b/tests/auto/installer/copyoperationtest/data/repository/A/1.0.2-1content.7z diff --git a/tests/auto/installer/copyoperationtest/data/repository/A/1.0.2-1meta.7z b/tests/auto/installer/copyoperationtest/data/repository/A/1.0.2-1meta.7z Binary files differnew file mode 100644 index 000000000..ae2a965bb --- /dev/null +++ b/tests/auto/installer/copyoperationtest/data/repository/A/1.0.2-1meta.7z diff --git a/tests/auto/installer/copyoperationtest/data/repository/Updates.xml b/tests/auto/installer/copyoperationtest/data/repository/Updates.xml new file mode 100644 index 000000000..0826afae8 --- /dev/null +++ b/tests/auto/installer/copyoperationtest/data/repository/Updates.xml @@ -0,0 +1,17 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.2-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <Script>script.qs</Script> + <UpdateFile CompressedSize="225" UncompressedSize="75" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>6d7a3e15d11a4d94b81452fc2aa18e705a01c922</SHA1> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/copyoperationtest/data/xmloperationrepository/A/1.0.2-1content.7z b/tests/auto/installer/copyoperationtest/data/xmloperationrepository/A/1.0.2-1content.7z Binary files differnew file mode 100644 index 000000000..8ba90b13b --- /dev/null +++ b/tests/auto/installer/copyoperationtest/data/xmloperationrepository/A/1.0.2-1content.7z diff --git a/tests/auto/installer/copyoperationtest/data/xmloperationrepository/Updates.xml b/tests/auto/installer/copyoperationtest/data/xmloperationrepository/Updates.xml new file mode 100644 index 000000000..4ad1e243b --- /dev/null +++ b/tests/auto/installer/copyoperationtest/data/xmloperationrepository/Updates.xml @@ -0,0 +1,25 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.2-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <UpdateFile CompressedSize="225" UncompressedSize="75" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>6d7a3e15d11a4d94b81452fc2aa18e705a01c922</SHA1> + <Operations> + <Operation name="Mkdir"> + <Argument>@TargetDir@/AnotherFolder</Argument> + </Operation> + <Operation name="Copy"> + <Argument>@TargetDir@/A.txt</Argument> + <Argument>@TargetDir@/AnotherFolder/A.txt</Argument> + </Operation> + </Operations> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/copyoperationtest/settings.qrc b/tests/auto/installer/copyoperationtest/settings.qrc new file mode 100644 index 000000000..094bd449b --- /dev/null +++ b/tests/auto/installer/copyoperationtest/settings.qrc @@ -0,0 +1,9 @@ +<RCC> + <qresource prefix="/"> + <file>data/repository/Updates.xml</file> + <file>data/repository/A/1.0.2-1content.7z</file> + <file>data/repository/A/1.0.2-1meta.7z</file> + <file>data/xmloperationrepository/Updates.xml</file> + <file>data/xmloperationrepository/A/1.0.2-1content.7z</file> + </qresource> +</RCC> diff --git a/tests/auto/installer/copyoperationtest/tst_copyoperationtest.cpp b/tests/auto/installer/copyoperationtest/tst_copyoperationtest.cpp index e55fc89f4..692fd86d9 100644 --- a/tests/auto/installer/copyoperationtest/tst_copyoperationtest.cpp +++ b/tests/auto/installer/copyoperationtest/tst_copyoperationtest.cpp @@ -1,6 +1,6 @@ /************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Installer Framework. @@ -25,16 +25,13 @@ ** $QT_END_LICENSE$ ** **************************************************************************/ +#include "../shared/packagemanager.h" -#include <init.h> #include <updateoperations.h> #include <utils.h> +#include <packagemanagercore.h> -#include <QDir> -#include <QObject> #include <QTest> -#include <QFile> -#include <QDebug> using namespace KDUpdater; using namespace QInstaller; @@ -43,6 +40,33 @@ class tst_copyoperationtest : public QObject { Q_OBJECT +private: + void installFromCLI(const QString &repository) + { + QString installDir = QInstaller::generateTemporaryFileName(); + QVERIFY(QDir().mkpath(installDir)); + PackageManagerCore *core = PackageManager::getPackageManagerWithInit(installDir, repository); + core->installDefaultComponentsSilently(); + + QFile copiedFile(installDir + QDir::separator() + "AnotherFolder/A.txt"); + QVERIFY(copiedFile.exists()); + QFile originalFile(installDir + QDir::separator() + "A.txt"); + QVERIFY(originalFile.exists()); + + QByteArray destinationFileHash = QInstaller::calculateHash(copiedFile.fileName(), QCryptographicHash::Sha1); + QByteArray testFileHash = QInstaller::calculateHash(originalFile.fileName(), QCryptographicHash::Sha1); + QVERIFY(testFileHash == destinationFileHash); + + core->setPackageManager(); + core->commitSessionOperations(); + core->uninstallComponentsSilently(QStringList() << "A"); + QVERIFY(!copiedFile.exists()); + + QDir dir(installDir); + QVERIFY(dir.removeRecursively()); + core->deleteLater(); + } + private slots: void initTestCase() { @@ -63,37 +87,48 @@ private slots: QVERIFY(!op.performOperation()); QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::InvalidArguments); - QCOMPARE(op.errorString(), QString("Invalid arguments in Copy: " - "0 arguments given, exactly 2 arguments expected.")); - + QCOMPARE(op.errorString(), QString("Invalid arguments in Copy: 0 arguments given, " + "2 to 4 arguments expected in the form: <source filename> <destination filename> [UNDOOPERATION, \"\"].")); } void testCopySomething_data() { - QTest::addColumn<QString>("source"); - QTest::addColumn<QString>("destination"); - QTest::newRow("full path syntax") << qApp->applicationFilePath() << m_testDestinationFilePath; - QTest::newRow("short destination syntax") << qApp->applicationFilePath() << m_testDestinationPath; - QTest::newRow("short destination syntax with ending separator") << qApp->applicationFilePath() - << m_testDestinationPath + QDir::separator(); + QTest::addColumn<QString>("source"); + QTest::addColumn<QString>("destination"); + QTest::addColumn<bool>("overrideUndo"); + QTest::newRow("full path syntax") << qApp->applicationFilePath() << m_testDestinationFilePath << false; + QTest::newRow("short destination syntax") << qApp->applicationFilePath() << m_testDestinationPath << false; + QTest::newRow("short destination syntax with ending separator") << qApp->applicationFilePath() + << m_testDestinationPath + QDir::separator() << false; + QTest::newRow("override undo") << qApp->applicationFilePath() << m_testDestinationFilePath << true; } void testCopySomething() { QFETCH(QString, source); QFETCH(QString, destination); + QFETCH(bool, overrideUndo); - QVERIFY2(QFileInfo(source).exists(), QString("Source file \"%1\" does not exist.").arg(source).toLatin1()); - CopyOperation op; - op.setArguments(QStringList() << source << destination); - op.backup(); - QVERIFY2(op.performOperation(), op.errorString().toLatin1()); + QVERIFY2(QFileInfo::exists(source), QString("Source file \"%1\" does not exist.").arg(source).toLatin1()); + CopyOperation *op = new CopyOperation(); + op->setArguments(QStringList() << source << destination); + if (overrideUndo) + op->setArguments(op->arguments() << QLatin1String("UNDOOPERATION")); + op->backup(); + QVERIFY2(op->performOperation(), op->errorString().toLatin1()); - QVERIFY2(QFileInfo(m_testDestinationFilePath).exists(), QString("Copying from \"%1\" to \"%2\" was " + QVERIFY2(QFileInfo::exists(m_testDestinationFilePath), QString("Copying from \"%1\" to \"%2\" was " "not working: '%3' does not exist").arg(source, destination, m_testDestinationFilePath).toLatin1()); - QVERIFY2(op.undoOperation(), op.errorString().toLatin1()); - QVERIFY2(!QFileInfo(m_testDestinationFilePath).exists(), QString("Undo of copying from \"%1\" to " - "\"%2\" was not working.").toLatin1()); + QVERIFY2(op->undoOperation(), op->errorString().toLatin1()); + if (!overrideUndo) { + QVERIFY2(!QFileInfo::exists(m_testDestinationFilePath), QString("Undo of copying from \"%1\" to " + "\"%2\" was not working.").toLatin1()); + } else { + QVERIFY(QFileInfo::exists(m_testDestinationFilePath)); + } + QString backupFileName = op->value("backupOfExistingDestination").toString(); + delete op; + QVERIFY(!QFileInfo::exists(backupFileName)); } void testCopyIfDestinationExist_data() @@ -134,6 +169,16 @@ private slots: currentFileHash = QInstaller::calculateHash(m_testDestinationFilePath, QCryptographicHash::Sha1); QVERIFY(testFileHash == currentFileHash); } + + void testCopyFromScript() + { + installFromCLI(":///data/repository"); + } + void testCopyFromComponentXML() + { + installFromCLI(":///data/xmloperationrepository"); + } + void init() { QVERIFY2(!QFileInfo(m_testDestinationFilePath).exists(), QString("Destination \"%1\" should not exist " diff --git a/tests/auto/installer/createdesktopentryoperation/createdesktopentryoperation.pro b/tests/auto/installer/createdesktopentryoperation/createdesktopentryoperation.pro new file mode 100644 index 000000000..1f0b98429 --- /dev/null +++ b/tests/auto/installer/createdesktopentryoperation/createdesktopentryoperation.pro @@ -0,0 +1,10 @@ +include(../../qttest.pri) + +QT -= gui +QT += testlib + +SOURCES = tst_createdesktopentryoperation.cpp + +RESOURCES += \ + settings.qrc \ + ../shared/config.qrc diff --git a/tests/auto/installer/createdesktopentryoperation/data/repository/A/1.0.2-1meta.7z b/tests/auto/installer/createdesktopentryoperation/data/repository/A/1.0.2-1meta.7z Binary files differnew file mode 100644 index 000000000..2905c12be --- /dev/null +++ b/tests/auto/installer/createdesktopentryoperation/data/repository/A/1.0.2-1meta.7z diff --git a/tests/auto/installer/createdesktopentryoperation/data/repository/Updates.xml b/tests/auto/installer/createdesktopentryoperation/data/repository/Updates.xml new file mode 100644 index 000000000..ad6c49c81 --- /dev/null +++ b/tests/auto/installer/createdesktopentryoperation/data/repository/Updates.xml @@ -0,0 +1,15 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.2-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <Script>script.qs</Script> + <SHA1>0746c8292e3799aac4a534a0a1a58d42ef24ed43</SHA1> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/createdesktopentryoperation/data/xmloperationrepository/Updates.xml b/tests/auto/installer/createdesktopentryoperation/data/xmloperationrepository/Updates.xml new file mode 100644 index 000000000..a5131552d --- /dev/null +++ b/tests/auto/installer/createdesktopentryoperation/data/xmloperationrepository/Updates.xml @@ -0,0 +1,18 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.2-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <Operations> + <Operation name="CreateDesktopEntry"> + <Argument>org.qtproject.ifw-test.desktop</Argument> + <Argument>Type=Application\nName=Test\nVersion=1.0</Argument> + </Operation> + </Operations> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/createdesktopentryoperation/settings.qrc b/tests/auto/installer/createdesktopentryoperation/settings.qrc new file mode 100644 index 000000000..04a7daf71 --- /dev/null +++ b/tests/auto/installer/createdesktopentryoperation/settings.qrc @@ -0,0 +1,7 @@ +<RCC> + <qresource prefix="/"> + <file>data/repository/Updates.xml</file> + <file>data/repository/A/1.0.2-1meta.7z</file> + <file>data/xmloperationrepository/Updates.xml</file> + </qresource> +</RCC> diff --git a/tests/auto/installer/createdesktopentryoperation/tst_createdesktopentryoperation.cpp b/tests/auto/installer/createdesktopentryoperation/tst_createdesktopentryoperation.cpp new file mode 100644 index 000000000..c73e7cc03 --- /dev/null +++ b/tests/auto/installer/createdesktopentryoperation/tst_createdesktopentryoperation.cpp @@ -0,0 +1,179 @@ +/************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ + +#include "../shared/packagemanager.h" + +#include <createdesktopentryoperation.h> + +#include <packagemanagercore.h> +#include <binarycontent.h> +#include <settings.h> +#include <fileutils.h> +#include <init.h> +#include <component.h> + +#include <QObject> +#include <QTest> +#include <QFile> + +using namespace KDUpdater; +using namespace QInstaller; + +class tst_createdesktopentryoperation : public QObject +{ + Q_OBJECT + +private: + void installFromCLI(const QString &repository) + { + QString installDir = QInstaller::generateTemporaryFileName(); + QVERIFY(QDir().mkpath(installDir)); + PackageManagerCore *core = PackageManager::getPackageManagerWithInit + (installDir, repository); + + core->installDefaultComponentsSilently(); + + CreateDesktopEntryOperation *createDesktopEntryOp = nullptr; + OperationList operations = core->componentByName("A")->operations(); + foreach (Operation *op, operations) { + if (op->name() == QLatin1String("CreateDesktopEntry")) + createDesktopEntryOp = dynamic_cast<CreateDesktopEntryOperation *>(op); + } + QVERIFY(createDesktopEntryOp); + + QString entryFileName = createDesktopEntryOp->absoluteFileName(); + QVERIFY(QFileInfo(entryFileName).exists()); + if (QFileInfo(createDesktopEntryOp->arguments().first()).isRelative()) { + QStringList directories = QString::fromLocal8Bit(qgetenv("XDG_DATA_HOME")) + .split(QLatin1Char(':'), Qt::SkipEmptyParts); + // Default path if XDG_DATA_HOME is not set + directories.append(QDir::home().absoluteFilePath(QLatin1String(".local/share"))); + // Default path if run as root + directories.append(QLatin1String("/usr/local/share")); + bool validPath = false; + foreach (const QString &dir, directories) { + // Desktop entry should be in one of the expected locations + if (QFileInfo(entryFileName).absolutePath() == QDir(dir).absoluteFilePath("applications")) { + validPath = true; + break; + } + } + QVERIFY(validPath); + } + core->setPackageManager(); + core->commitSessionOperations(); + core->uninstallComponentsSilently(QStringList() << "A"); + QVERIFY2(!QFileInfo(entryFileName).exists(), "Please make sure there " + "does not exist a desktop entry with the same name."); + + QDir dir(installDir); + QVERIFY(dir.removeRecursively()); + core->deleteLater(); + + } + +private slots: + void initTestCase() + { + m_desktopEntryContents = "Type=Application\nName=Test\nVersion=1.0"; + } + + void testMissingArguments() + { + CreateDesktopEntryOperation op(nullptr); + + QVERIFY(op.testOperation()); + QVERIFY(!op.performOperation()); + + QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::InvalidArguments); + QCOMPARE(op.errorString(), QString("Invalid arguments in CreateDesktopEntry: " + "0 arguments given, exactly 2 arguments expected.")); + } + + void testCreateDesktopEntry_data() + { + QTest::addColumn<QString>("filename"); + QTest::newRow("relative") << "entry"; + QTest::newRow("absolute") << qApp->applicationDirPath() + "/entry"; + } + + void testCreateDesktopEntry() + { + QFETCH(QString, filename); + + CreateDesktopEntryOperation op(nullptr); + op.setArguments(QStringList() << filename << m_desktopEntryContents); + + QVERIFY2(op.performOperation(), op.errorString().toLatin1()); + QVERIFY(QFileInfo().exists(op.absoluteFileName())); + + QVERIFY2(op.undoOperation(), op.errorString().toLatin1()); + QVERIFY(!QFileInfo().exists(op.absoluteFileName())); + } + + void testBackupExistingEntry() + { + QString filename = qApp->applicationDirPath() + "/entry"; + + CreateDesktopEntryOperation op(nullptr); + op.setArguments(QStringList() << filename << m_desktopEntryContents); + + op.backup(); + QVERIFY(!op.hasValue("backupOfExistingDesktopEntry")); + + QFile existingEntry(filename); + QVERIFY(existingEntry.open(QFileDevice::ReadWrite) && existingEntry.exists()); + existingEntry.close(); + + op.backup(); + QVERIFY(op.hasValue("backupOfExistingDesktopEntry")); + + QVERIFY2(op.undoOperation(), op.errorString().toLatin1()); + QVERIFY(!QFileInfo().exists(op.value("backupOfExistingDesktopEntry").toString())); + QVERIFY(QFileInfo().exists(filename)); + + QVERIFY(QFile(filename).remove()); + } + + void testDesktopEntryFromScript() + { + installFromCLI(":///data/repository"); + } + + void testDesktopEntryFromXML() + { + installFromCLI(":///data/xmloperationrepository"); + } + +private: + QString m_desktopEntryContents; +}; + +QTEST_MAIN(tst_createdesktopentryoperation) + +#include "tst_createdesktopentryoperation.moc" diff --git a/tests/auto/installer/createoffline/createoffline.pro b/tests/auto/installer/createoffline/createoffline.pro new file mode 100644 index 000000000..bdb050f4d --- /dev/null +++ b/tests/auto/installer/createoffline/createoffline.pro @@ -0,0 +1,9 @@ +include(../../qttest.pri) + +QT -= gui +QT += testlib + +SOURCES = tst_createoffline.cpp + +RESOURCES += settings.qrc \ + ../shared/config.qrc diff --git a/tests/auto/installer/createoffline/data/repository-bothmeta-license/2020-12-01-1511_meta.7z b/tests/auto/installer/createoffline/data/repository-bothmeta-license/2020-12-01-1511_meta.7z Binary files differnew file mode 100644 index 000000000..31ffc5764 --- /dev/null +++ b/tests/auto/installer/createoffline/data/repository-bothmeta-license/2020-12-01-1511_meta.7z diff --git a/tests/auto/installer/createoffline/data/repository-bothmeta-license/Updates.xml b/tests/auto/installer/createoffline/data/repository-bothmeta-license/Updates.xml new file mode 100644 index 000000000..064fc6529 --- /dev/null +++ b/tests/auto/installer/createoffline/data/repository-bothmeta-license/Updates.xml @@ -0,0 +1,22 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>true</Checksum> + <PackageUpdate> + <Name>org.qtproject.ifw.example.licenseagreement</Name> + <DisplayName>README (requires license agreement)</DisplayName> + <Description>README can only be installed if the user agrees to the licenses.</Description> + <ReleaseDate>2021-01-01</ReleaseDate> + <Version>1.0.0-1</Version> + <Default>true</Default> + <UpdateFile CompressedSize="282" OS="Any" UncompressedSize="116"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <Licenses> + <License name="Creative Commons (CC0 1.0)" file="cc0.txt"/> + <License name="GNU GENERAL PUBLIC LICENSE Version 3" file="gpl3.txt"/> + </Licenses> + <SHA1>6d6a4cead84562b7034fcf1b9975779f1f030151</SHA1> + </PackageUpdate> + <SHA1>6d6a4cead84562b7034fcf1b9975779f1f030151</SHA1> + <MetadataName>2020-12-01-1511_meta.7z</MetadataName> +</Updates> diff --git a/tests/auto/installer/createoffline/data/repository-bothmeta-license/org.qtproject.ifw.example.licenseagreement/1.0.0-1content.7z b/tests/auto/installer/createoffline/data/repository-bothmeta-license/org.qtproject.ifw.example.licenseagreement/1.0.0-1content.7z Binary files differnew file mode 100644 index 000000000..d80146aa8 --- /dev/null +++ b/tests/auto/installer/createoffline/data/repository-bothmeta-license/org.qtproject.ifw.example.licenseagreement/1.0.0-1content.7z diff --git a/tests/auto/installer/createoffline/data/repository-bothmeta-license/org.qtproject.ifw.example.licenseagreement/1.0.0-1content.7z.sha1 b/tests/auto/installer/createoffline/data/repository-bothmeta-license/org.qtproject.ifw.example.licenseagreement/1.0.0-1content.7z.sha1 new file mode 100644 index 000000000..49df32fea --- /dev/null +++ b/tests/auto/installer/createoffline/data/repository-bothmeta-license/org.qtproject.ifw.example.licenseagreement/1.0.0-1content.7z.sha1 @@ -0,0 +1 @@ +192106030e00704e880fb729c3f7bed8ced8db92
\ No newline at end of file diff --git a/tests/auto/installer/createoffline/data/repository-bothmeta-license/org.qtproject.ifw.example.licenseagreement/1.0.0-1meta.7z b/tests/auto/installer/createoffline/data/repository-bothmeta-license/org.qtproject.ifw.example.licenseagreement/1.0.0-1meta.7z Binary files differnew file mode 100644 index 000000000..31ffc5764 --- /dev/null +++ b/tests/auto/installer/createoffline/data/repository-bothmeta-license/org.qtproject.ifw.example.licenseagreement/1.0.0-1meta.7z diff --git a/tests/auto/installer/createoffline/data/repository-bothmeta-userinteface/2020-12-01-1524_meta.7z b/tests/auto/installer/createoffline/data/repository-bothmeta-userinteface/2020-12-01-1524_meta.7z Binary files differnew file mode 100644 index 000000000..93f95c1d7 --- /dev/null +++ b/tests/auto/installer/createoffline/data/repository-bothmeta-userinteface/2020-12-01-1524_meta.7z diff --git a/tests/auto/installer/createoffline/data/repository-bothmeta-userinteface/Updates.xml b/tests/auto/installer/createoffline/data/repository-bothmeta-userinteface/Updates.xml new file mode 100644 index 000000000..cc0ae0206 --- /dev/null +++ b/tests/auto/installer/createoffline/data/repository-bothmeta-userinteface/Updates.xml @@ -0,0 +1,20 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>true</Checksum> + <PackageUpdate> + <Name>or.qtproject.ifw.example.openreadme</Name> + <DisplayName>Open readme</DisplayName> + <Description>Show checkbox asking whether to open Readme at the end</Description> + <Version>1.0.0-1</Version> + <ReleaseDate>2021-01-01</ReleaseDate> + <Default>true</Default> + <Script>installscript.qs</Script> + <UpdateFile UncompressedSize="49" OS="Any" CompressedSize="215"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <UserInterfaces>readmecheckboxform.ui</UserInterfaces> + <SHA1>9b8977a50cb49a77a6ff037d776b73c341412a25</SHA1> + </PackageUpdate> + <SHA1>9b8977a50cb49a77a6ff037d776b73c341412a25</SHA1> + <MetadataName>2020-12-01-1524_meta.7z</MetadataName> +</Updates> diff --git a/tests/auto/installer/createoffline/data/repository-bothmeta-userinteface/or.qtproject.ifw.example.openreadme/1.0.0-1content.7z b/tests/auto/installer/createoffline/data/repository-bothmeta-userinteface/or.qtproject.ifw.example.openreadme/1.0.0-1content.7z Binary files differnew file mode 100644 index 000000000..98154743c --- /dev/null +++ b/tests/auto/installer/createoffline/data/repository-bothmeta-userinteface/or.qtproject.ifw.example.openreadme/1.0.0-1content.7z diff --git a/tests/auto/installer/createoffline/data/repository-bothmeta-userinteface/or.qtproject.ifw.example.openreadme/1.0.0-1content.7z.sha1 b/tests/auto/installer/createoffline/data/repository-bothmeta-userinteface/or.qtproject.ifw.example.openreadme/1.0.0-1content.7z.sha1 new file mode 100644 index 000000000..154c20383 --- /dev/null +++ b/tests/auto/installer/createoffline/data/repository-bothmeta-userinteface/or.qtproject.ifw.example.openreadme/1.0.0-1content.7z.sha1 @@ -0,0 +1 @@ +27cdf6cc53d2317aa2a869cb3f93e7a54c489b5f
\ No newline at end of file diff --git a/tests/auto/installer/createoffline/data/repository-bothmeta-userinteface/or.qtproject.ifw.example.openreadme/1.0.0-1meta.7z b/tests/auto/installer/createoffline/data/repository-bothmeta-userinteface/or.qtproject.ifw.example.openreadme/1.0.0-1meta.7z Binary files differnew file mode 100644 index 000000000..93f95c1d7 --- /dev/null +++ b/tests/auto/installer/createoffline/data/repository-bothmeta-userinteface/or.qtproject.ifw.example.openreadme/1.0.0-1meta.7z diff --git a/tests/auto/installer/createoffline/data/repository-componentmeta-emptymetafile/A/1.0.2-1content.7z b/tests/auto/installer/createoffline/data/repository-componentmeta-emptymetafile/A/1.0.2-1content.7z Binary files differnew file mode 100644 index 000000000..1c5ff001a --- /dev/null +++ b/tests/auto/installer/createoffline/data/repository-componentmeta-emptymetafile/A/1.0.2-1content.7z diff --git a/tests/auto/installer/createoffline/data/repository-componentmeta-emptymetafile/A/1.0.2-1content.7z.sha1 b/tests/auto/installer/createoffline/data/repository-componentmeta-emptymetafile/A/1.0.2-1content.7z.sha1 new file mode 100644 index 000000000..b36346655 --- /dev/null +++ b/tests/auto/installer/createoffline/data/repository-componentmeta-emptymetafile/A/1.0.2-1content.7z.sha1 @@ -0,0 +1 @@ +5097e37368b44fc5242f3bb2fce08f5ade6c4c40
\ No newline at end of file diff --git a/tests/auto/installer/createoffline/data/repository-componentmeta-emptymetafile/A/1.0.2-1meta.7z b/tests/auto/installer/createoffline/data/repository-componentmeta-emptymetafile/A/1.0.2-1meta.7z Binary files differnew file mode 100644 index 000000000..408550be6 --- /dev/null +++ b/tests/auto/installer/createoffline/data/repository-componentmeta-emptymetafile/A/1.0.2-1meta.7z diff --git a/tests/auto/installer/createoffline/data/repository-componentmeta-emptymetafile/Updates.xml b/tests/auto/installer/createoffline/data/repository-componentmeta-emptymetafile/Updates.xml new file mode 100644 index 000000000..d3b180e43 --- /dev/null +++ b/tests/auto/installer/createoffline/data/repository-componentmeta-emptymetafile/Updates.xml @@ -0,0 +1,16 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>true</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.2-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <UpdateFile UncompressedSize="72" OS="Any" CompressedSize="222"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>65c0db5bcf28139d434dce0e21674e33c87ab6d9</SHA1> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/createoffline/data/repository-componentmeta-script/Updates.xml b/tests/auto/installer/createoffline/data/repository-componentmeta-script/Updates.xml new file mode 100644 index 000000000..42458e7ce --- /dev/null +++ b/tests/auto/installer/createoffline/data/repository-componentmeta-script/Updates.xml @@ -0,0 +1,17 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>true</Checksum> + <PackageUpdate> + <Name>org.qtproject.ifw.example</Name> + <DisplayName>README.txt</DisplayName> + <Description>A README.txt, accessible through a start menu entry.</Description> + <Version>1.0.0-1</Version> + <ReleaseDate>2021-01-01</ReleaseDate> + <Default>true</Default> + <Script>installscript.qs</Script> + <UpdateFile UncompressedSize="131" CompressedSize="297" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>08c2a05d861543e88a8808f576d5c731e0301ab4</SHA1> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/createoffline/data/repository-componentmeta-script/org.qtproject.ifw.example/1.0.0-1content.7z b/tests/auto/installer/createoffline/data/repository-componentmeta-script/org.qtproject.ifw.example/1.0.0-1content.7z Binary files differnew file mode 100644 index 000000000..40ebd637a --- /dev/null +++ b/tests/auto/installer/createoffline/data/repository-componentmeta-script/org.qtproject.ifw.example/1.0.0-1content.7z diff --git a/tests/auto/installer/createoffline/data/repository-componentmeta-script/org.qtproject.ifw.example/1.0.0-1content.7z.sha1 b/tests/auto/installer/createoffline/data/repository-componentmeta-script/org.qtproject.ifw.example/1.0.0-1content.7z.sha1 new file mode 100644 index 000000000..d1c96e12b --- /dev/null +++ b/tests/auto/installer/createoffline/data/repository-componentmeta-script/org.qtproject.ifw.example/1.0.0-1content.7z.sha1 @@ -0,0 +1 @@ +d9ad62d190d93c92175741c02d17aa6c39b0e03d
\ No newline at end of file diff --git a/tests/auto/installer/createoffline/data/repository-componentmeta-script/org.qtproject.ifw.example/1.0.0-1meta.7z b/tests/auto/installer/createoffline/data/repository-componentmeta-script/org.qtproject.ifw.example/1.0.0-1meta.7z Binary files differnew file mode 100644 index 000000000..f35ec6071 --- /dev/null +++ b/tests/auto/installer/createoffline/data/repository-componentmeta-script/org.qtproject.ifw.example/1.0.0-1meta.7z diff --git a/tests/auto/installer/createoffline/data/repository-missingdependency/Updates.xml b/tests/auto/installer/createoffline/data/repository-missingdependency/Updates.xml new file mode 100644 index 000000000..2ec3a5ac4 --- /dev/null +++ b/tests/auto/installer/createoffline/data/repository-missingdependency/Updates.xml @@ -0,0 +1,22 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>true</Checksum> + <PackageUpdate> + <Name>example.with.unstable.dependency</Name> + <DisplayName>README.txt</DisplayName> + <Description>A README.txt, accessible through a start menu entry.</Description> + <Version>1.0.0-1</Version> + <ReleaseDate>2021-01-01</ReleaseDate> + <Default>false</Default> + <Dependencies>missing.dependency.component</Dependencies> + </PackageUpdate> + <PackageUpdate> + <Name>example.without.unstable.dependency</Name> + <DisplayName>README.txt</DisplayName> + <Description>A README.txt, accessible through a start menu entry.</Description> + <Version>1.0.0-1</Version> + <ReleaseDate>2013-01-01</ReleaseDate> + <Default>false</Default> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/createoffline/data/repository-unifiedmeta-script/2020-12-01-1519_meta.7z b/tests/auto/installer/createoffline/data/repository-unifiedmeta-script/2020-12-01-1519_meta.7z Binary files differnew file mode 100644 index 000000000..e96ed9ec0 --- /dev/null +++ b/tests/auto/installer/createoffline/data/repository-unifiedmeta-script/2020-12-01-1519_meta.7z diff --git a/tests/auto/installer/createoffline/data/repository-unifiedmeta-script/Updates.xml b/tests/auto/installer/createoffline/data/repository-unifiedmeta-script/Updates.xml new file mode 100644 index 000000000..e0826ae86 --- /dev/null +++ b/tests/auto/installer/createoffline/data/repository-unifiedmeta-script/Updates.xml @@ -0,0 +1,18 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>true</Checksum> + <PackageUpdate> + <Name>org.qtproject.ifw.example</Name> + <DisplayName>README.txt</DisplayName> + <Description>A README.txt, accessible through a start menu entry.</Description> + <Version>1.0.0-1</Version> + <ReleaseDate>2021-01-01</ReleaseDate> + <Default>true</Default> + <Script>installscript.qs</Script> + <UpdateFile OS="Any" CompressedSize="297" UncompressedSize="131"/> + <DownloadableArchives>content.7z</DownloadableArchives> + </PackageUpdate> + <SHA1>70ff1e1062ada01ea698a908f7549fcb826f17e1</SHA1> + <MetadataName>2020-12-01-1519_meta.7z</MetadataName> +</Updates> diff --git a/tests/auto/installer/createoffline/data/repository-unifiedmeta-script/org.qtproject.ifw.example/1.0.0-1content.7z b/tests/auto/installer/createoffline/data/repository-unifiedmeta-script/org.qtproject.ifw.example/1.0.0-1content.7z Binary files differnew file mode 100644 index 000000000..40ebd637a --- /dev/null +++ b/tests/auto/installer/createoffline/data/repository-unifiedmeta-script/org.qtproject.ifw.example/1.0.0-1content.7z diff --git a/tests/auto/installer/createoffline/data/repository-unifiedmeta-script/org.qtproject.ifw.example/1.0.0-1content.7z.sha1 b/tests/auto/installer/createoffline/data/repository-unifiedmeta-script/org.qtproject.ifw.example/1.0.0-1content.7z.sha1 new file mode 100644 index 000000000..d1c96e12b --- /dev/null +++ b/tests/auto/installer/createoffline/data/repository-unifiedmeta-script/org.qtproject.ifw.example/1.0.0-1content.7z.sha1 @@ -0,0 +1 @@ +d9ad62d190d93c92175741c02d17aa6c39b0e03d
\ No newline at end of file diff --git a/tests/auto/installer/createoffline/settings.qrc b/tests/auto/installer/createoffline/settings.qrc new file mode 100644 index 000000000..4b7666b4a --- /dev/null +++ b/tests/auto/installer/createoffline/settings.qrc @@ -0,0 +1,32 @@ +<RCC> + <qresource prefix="/"> + <file>data/repository-bothmeta-license/2020-12-01-1511_meta.7z</file> + <file>data/repository-bothmeta-license/Updates.xml</file> + <file>data/repository-bothmeta-license/org.qtproject.ifw.example.licenseagreement/1.0.0-1content.7z</file> + <file>data/repository-bothmeta-license/org.qtproject.ifw.example.licenseagreement/1.0.0-1content.7z.sha1</file> + <file>data/repository-bothmeta-license/org.qtproject.ifw.example.licenseagreement/1.0.0-1meta.7z</file> + + <file>data/repository-bothmeta-userinteface/2020-12-01-1524_meta.7z</file> + <file>data/repository-bothmeta-userinteface/Updates.xml</file> + <file>data/repository-bothmeta-userinteface/or.qtproject.ifw.example.openreadme/1.0.0-1content.7z</file> + <file>data/repository-bothmeta-userinteface/or.qtproject.ifw.example.openreadme/1.0.0-1content.7z.sha1</file> + <file>data/repository-bothmeta-userinteface/or.qtproject.ifw.example.openreadme/1.0.0-1meta.7z</file> + + <file>data/repository-componentmeta-script/Updates.xml</file> + <file>data/repository-componentmeta-script/org.qtproject.ifw.example/1.0.0-1content.7z</file> + <file>data/repository-componentmeta-script/org.qtproject.ifw.example/1.0.0-1content.7z.sha1</file> + <file>data/repository-componentmeta-script/org.qtproject.ifw.example/1.0.0-1meta.7z</file> + + <file>data/repository-missingdependency/Updates.xml</file> + + <file>data/repository-unifiedmeta-script/2020-12-01-1519_meta.7z</file> + <file>data/repository-unifiedmeta-script/Updates.xml</file> + <file>data/repository-unifiedmeta-script/org.qtproject.ifw.example/1.0.0-1content.7z</file> + <file>data/repository-unifiedmeta-script/org.qtproject.ifw.example/1.0.0-1content.7z.sha1</file> + + <file>data/repository-componentmeta-emptymetafile/Updates.xml</file> + <file>data/repository-componentmeta-emptymetafile/A/1.0.2-1content.7z</file> + <file>data/repository-componentmeta-emptymetafile/A/1.0.2-1content.7z.sha1</file> + <file>data/repository-componentmeta-emptymetafile/A/1.0.2-1meta.7z</file> + </qresource> +</RCC> diff --git a/tests/auto/installer/createoffline/tst_createoffline.cpp b/tests/auto/installer/createoffline/tst_createoffline.cpp new file mode 100644 index 000000000..607f9b7cc --- /dev/null +++ b/tests/auto/installer/createoffline/tst_createoffline.cpp @@ -0,0 +1,176 @@ +/************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ + +#include "../shared/packagemanager.h" + +#include <packagemanagercore.h> +#include <errors.h> + +#include <QFile> +#include <QTest> + +using namespace QInstaller; + +class tst_CreateOffline : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase() + { + // Need to provide a replacement base binary as we are not running actual installer +#ifdef Q_OS_WIN + m_installerBase = "../../../../bin/installerbase.exe"; +#else + m_installerBase = "../../../../bin/installerbase"; +#endif + if (!QFile(m_installerBase).exists()) { + QSKIP("No \"installerbase\" binary found in source tree. This can be " + "the case if this is an out of sources build or the binaries are " + "installed to a location with a different path prefix."); + } + } + + void init() + { + // Get new target directory for each test function + m_targetDir = QInstaller::generateTemporaryFileName(); + } + + void cleanup() + { + QDir dir(m_targetDir); + QVERIFY(dir.removeRecursively()); + } + + void testCreateOfflineInstaller_data() + { + QTest::addColumn<QString>("repository"); + QTest::addColumn<QString>("component"); + QTest::addColumn<PackageManagerCore::Status>("expectedStatus"); + QTest::newRow("Both metaformats | License") + << ":///data/repository-bothmeta-license" << "org.qtproject.ifw.example.licenseagreement" + << PackageManagerCore::Success; + QTest::newRow("Both metaformats | UserInterface") + << ":///data/repository-bothmeta-userinteface" << "or.qtproject.ifw.example.openreadme" + << PackageManagerCore::Success; + QTest::newRow("Component metaformat | Script") + << ":///data/repository-componentmeta-script" << "org.qtproject.ifw.example" + << PackageManagerCore::Success; + QTest::newRow("Unified metaformat | Script") + << ":///data/repository-unifiedmeta-script" << "org.qtproject.ifw.example" + << PackageManagerCore::Success; + QTest::newRow("Component metaformat | Empty component meta-archive") + << ":///data/repository-componentmeta-emptymetafile" << "A" + << PackageManagerCore::Success; + QTest::newRow("Non-existing component") + << ":///data/repository-unifiedmeta-script" << "a.dummy.component" + << PackageManagerCore::Canceled; + QTest::newRow("Invalid repository") + << ":///data/repository-invalid" << "a.dummy.component" + << PackageManagerCore::Canceled; + } + + void testCreateOfflineInstaller() + { + QFETCH(QString, repository); + QFETCH(QString, component); + QFETCH(PackageManagerCore::Status, expectedStatus); + + QScopedPointer<PackageManagerCore> core( + PackageManager::getPackageManagerWithInit(m_targetDir, repository)); + core->setCommandLineInstance(true); + core->setOfflineBaseBinary(m_installerBase); + core->setOfflineBinaryName("ifw_test_offline"); + core->setAutoAcceptLicenses(); + + // Replace the custom message handler installed in QInstaller::init() to suppress all output + qInstallMessageHandler(silentTestMessageHandler); + + QCOMPARE(expectedStatus, core->createOfflineInstaller(QStringList() << component)); + + if (expectedStatus == PackageManagerCore::Success) { +#ifdef Q_OS_LINUX + QVERIFY(QFile::exists(m_targetDir + QDir::separator() + "ifw_test_offline")); +#elif defined Q_OS_MACOS + QVERIFY(QFile::exists(m_targetDir + QDir::separator() + "ifw_test_offline.dmg")); +#elif defined Q_OS_WIN + QVERIFY(QFile::exists(m_targetDir + QDir::separator() + "ifw_test_offline.exe")); +#endif + } + } + + void testCreateOfflineWithUnstableComponent_data() + { + QTest::addColumn<QString>("repository"); + QTest::addColumn<QString>("component"); + QTest::addColumn<bool>("allowUnstable"); + QTest::addColumn<PackageManagerCore::Status>("expectedStatus"); + QTest::newRow("Allow unstable | Missing dependency with selected component") + << ":///data/repository-missingdependency" << "example.with.unstable.dependency" + << true << PackageManagerCore::Canceled; + QTest::newRow("Disallow unstable | Missing dependency with selected component") + << ":///data/repository-missingdependency" << "example.with.unstable.dependency" + << false << PackageManagerCore::Canceled; + QTest::newRow("Allow unstable | Missing dependency with other component") + << ":///data/repository-missingdependency" << "example.without.unstable.dependency" + << true << PackageManagerCore::Success; + QTest::newRow("Disallow unstable | Missing dependency with other component") + << ":///data/repository-missingdependency" << "example.without.unstable.dependency" + << false << PackageManagerCore::Canceled; + } + + void testCreateOfflineWithUnstableComponent() + { + QFETCH(QString, repository); + QFETCH(QString, component); + QFETCH(bool, allowUnstable); + QFETCH(PackageManagerCore::Status, expectedStatus); + + QScopedPointer<PackageManagerCore> core( + PackageManager::getPackageManagerWithInit(m_targetDir, repository)); + core->setCommandLineInstance(true); + core->setOfflineBaseBinary(m_installerBase); + core->setOfflineBinaryName("ifw_test_offline"); + core->settings().setAllowUnstableComponents(allowUnstable); + core->autoAcceptMessageBoxes(); + + // Replace the custom message handler installed in QInstaller::init() to suppress all output + qInstallMessageHandler(silentTestMessageHandler); + + QCOMPARE(expectedStatus, core->createOfflineInstaller(QStringList() << component)); + } + +private: + QString m_targetDir; + QString m_installerBase; +}; + +QTEST_GUILESS_MAIN(tst_CreateOffline) + +#include "tst_createoffline.moc" diff --git a/tests/auto/installer/createshortcutoperation/createshortcutoperation.pro b/tests/auto/installer/createshortcutoperation/createshortcutoperation.pro new file mode 100644 index 000000000..c57bcfb98 --- /dev/null +++ b/tests/auto/installer/createshortcutoperation/createshortcutoperation.pro @@ -0,0 +1,9 @@ +include(../../qttest.pri) + +QT -= gui +QT += testlib + +SOURCES = tst_createshortcutoperation.cpp + +RESOURCES += \ + settings.qrc diff --git a/tests/auto/installer/createshortcutoperation/data/repository/A/1.0.2-1content.7z b/tests/auto/installer/createshortcutoperation/data/repository/A/1.0.2-1content.7z Binary files differnew file mode 100644 index 000000000..8ba90b13b --- /dev/null +++ b/tests/auto/installer/createshortcutoperation/data/repository/A/1.0.2-1content.7z diff --git a/tests/auto/installer/createshortcutoperation/data/repository/A/1.0.2-1meta.7z b/tests/auto/installer/createshortcutoperation/data/repository/A/1.0.2-1meta.7z Binary files differnew file mode 100644 index 000000000..17eae879d --- /dev/null +++ b/tests/auto/installer/createshortcutoperation/data/repository/A/1.0.2-1meta.7z diff --git a/tests/auto/installer/createshortcutoperation/data/repository/Updates.xml b/tests/auto/installer/createshortcutoperation/data/repository/Updates.xml new file mode 100644 index 000000000..d1909d355 --- /dev/null +++ b/tests/auto/installer/createshortcutoperation/data/repository/Updates.xml @@ -0,0 +1,17 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component for CreateShortcutOperation</Description> + <Version>1.0.2-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <Script>script.qs</Script> + <UpdateFile CompressedSize="225" UncompressedSize="75" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>6d7a3e15d11a4d94b81452fc2aa18e705a01c922</SHA1> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/createshortcutoperation/data/xmloperationrepository/A/1.0.2-1content.7z b/tests/auto/installer/createshortcutoperation/data/xmloperationrepository/A/1.0.2-1content.7z Binary files differnew file mode 100644 index 000000000..8ba90b13b --- /dev/null +++ b/tests/auto/installer/createshortcutoperation/data/xmloperationrepository/A/1.0.2-1content.7z diff --git a/tests/auto/installer/createshortcutoperation/data/xmloperationrepository/Updates.xml b/tests/auto/installer/createshortcutoperation/data/xmloperationrepository/Updates.xml new file mode 100644 index 000000000..a7d287d4d --- /dev/null +++ b/tests/auto/installer/createshortcutoperation/data/xmloperationrepository/Updates.xml @@ -0,0 +1,26 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.2-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <UpdateFile CompressedSize="225" UncompressedSize="75" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>6d7a3e15d11a4d94b81452fc2aa18e705a01c922</SHA1> + <Operations> + <Operation name="CreateShortcut"> + <Argument>@TargetDir@/A.txt</Argument> + <Argument>@StartMenuDir@/A.lnk</Argument> + <Argument>workingDirectory=@TargetDir@</Argument> + <Argument>iconPath=%SystemRoot%/system32/SHELL32.dl</Argument> + <Argument>iconId=2</Argument> + <Argument>description=Open A file</Argument> + </Operation> + </Operations> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/createshortcutoperation/installer-config/config.xml b/tests/auto/installer/createshortcutoperation/installer-config/config.xml new file mode 100644 index 000000000..c201d4fa5 --- /dev/null +++ b/tests/auto/installer/createshortcutoperation/installer-config/config.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<Installer> + <Name>test</Name> + <Version>1.0.0</Version> + <StartMenuDir>Qt Installer Framework Unit Test</StartMenuDir> +</Installer> diff --git a/tests/auto/installer/createshortcutoperation/settings.qrc b/tests/auto/installer/createshortcutoperation/settings.qrc new file mode 100644 index 000000000..d2365cab3 --- /dev/null +++ b/tests/auto/installer/createshortcutoperation/settings.qrc @@ -0,0 +1,12 @@ +<RCC> + <qresource prefix="/"> + <file>data/repository/Updates.xml</file> + <file>data/repository/A/1.0.2-1content.7z</file> + <file>data/repository/A/1.0.2-1meta.7z</file> + <file>data/xmloperationrepository/Updates.xml</file> + <file>data/xmloperationrepository/A/1.0.2-1content.7z</file> + </qresource> + <qresource prefix="/metadata"> + <file>installer-config/config.xml</file> + </qresource> +</RCC> diff --git a/tests/auto/installer/createshortcutoperation/tst_createshortcutoperation.cpp b/tests/auto/installer/createshortcutoperation/tst_createshortcutoperation.cpp new file mode 100644 index 000000000..a08567d64 --- /dev/null +++ b/tests/auto/installer/createshortcutoperation/tst_createshortcutoperation.cpp @@ -0,0 +1,117 @@ +/************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ + +#include <init.h> +#include <createshortcutoperation.h> +#include <utils.h> +#include <binarycontent.h> +#include <packagemanagercore.h> +#include <settings.h> +#include <fileutils.h> + +#include <QDir> +#include <QObject> +#include <QTest> +#include <QFile> +#include <qsettingswrapper.h> +#include <QDebug> + +using namespace KDUpdater; +using namespace QInstaller; + +class tst_createshortcutoperation : public QObject +{ + Q_OBJECT + +private: + void installFromCLI(const QString &repository) + { + QInstaller::init(); + QScopedPointer<PackageManagerCore> core(new PackageManagerCore(BinaryContent::MagicInstallerMarker, + QList<OperationBlob> (), QString(), QString(), Protocol::DefaultAuthorizationKey, + Protocol::Mode::Production, QHash<QString, QString>(), true)); + + core->disableWriteMaintenanceTool(); + core->setAutoConfirmCommand(); + QSet<Repository> repoList; + Repository repo = Repository::fromUserInput(repository); + repoList.insert(repo); + core->settings().setDefaultRepositories(repoList); + + QString installDir = QInstaller::generateTemporaryFileName(); + QVERIFY(QDir().mkpath(installDir)); + core->setValue(scTargetDir, installDir); + core->installDefaultComponentsSilently(); + + QSettingsWrapper user(QLatin1String("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\" + "CurrentVersion\\Explorer\\User Shell Folders"), QSettings::NativeFormat); + //Replace %USERS% from "Programs" + const QString programs = replaceWindowsEnvironmentVariables(user.value(QLatin1String("Programs"), QString()).toString()); + const QString startMenuDir = programs + QDir::separator() + "Qt Installer Framework Unit Test"; + QCOMPARE(startMenuDir, core->value("StartMenuDir")); + + QString linkLocation = core->value("StartMenuDir") + QDir::separator() + "A.lnk"; + QFile file(linkLocation); + QVERIFY(file.open(QIODevice::ReadOnly)); + file.close(); + + core->setPackageManager(); + core->commitSessionOperations(); + core->uninstallComponentsSilently(QStringList() << "A"); + QVERIFY(!QFile::exists(linkLocation)); + } + +private slots: + void testMissingArguments() + { + CreateShortcutOperation op; + + QVERIFY(op.testOperation()); + QVERIFY(!op.performOperation()); + + QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::InvalidArguments); + QCOMPARE(op.errorString(), QString("Invalid arguments in CreateShortcut: 0 arguments given," + " 2 or 3 arguments expected in the form: <target> <link location> " + "[target arguments] [\"workingDirectory=...\"] [\"iconPath=...\"] " + "[\"iconId=...\"] [\"description=...\"].")); + } + + void testCreateShortcutFromScript() + { + installFromCLI(":///data/repository"); + } + + void testCreateShortcutFromXML() + { + installFromCLI(":///data/xmloperationrepository"); + } +}; + +QTEST_MAIN(tst_createshortcutoperation) + +#include "tst_createshortcutoperation.moc" diff --git a/tests/auto/installer/deleteoperation/data/repository/A/1.0.2-1meta.7z b/tests/auto/installer/deleteoperation/data/repository/A/1.0.2-1meta.7z Binary files differnew file mode 100644 index 000000000..c87d8642e --- /dev/null +++ b/tests/auto/installer/deleteoperation/data/repository/A/1.0.2-1meta.7z diff --git a/tests/auto/installer/deleteoperation/data/repository/Updates.xml b/tests/auto/installer/deleteoperation/data/repository/Updates.xml new file mode 100644 index 000000000..5a8b28f38 --- /dev/null +++ b/tests/auto/installer/deleteoperation/data/repository/Updates.xml @@ -0,0 +1,15 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.2-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <Script>script.qs</Script> + <SHA1>e8b8ce98862d463c855609ed8e139eda17092cc6</SHA1> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/deleteoperation/data/xmloperationrepository/Updates.xml b/tests/auto/installer/deleteoperation/data/xmloperationrepository/Updates.xml new file mode 100644 index 000000000..6856014b9 --- /dev/null +++ b/tests/auto/installer/deleteoperation/data/xmloperationrepository/Updates.xml @@ -0,0 +1,17 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.2-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <Operations> + <Operation name="Delete"> + <Argument>@TargetDir@/test</Argument> + </Operation> + </Operations> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/deleteoperation/deleteoperation.pro b/tests/auto/installer/deleteoperation/deleteoperation.pro new file mode 100644 index 000000000..f22867965 --- /dev/null +++ b/tests/auto/installer/deleteoperation/deleteoperation.pro @@ -0,0 +1,10 @@ +include(../../qttest.pri) + +QT -= gui +QT += testlib + +SOURCES += tst_deleteoperation.cpp + +RESOURCES += \ + settings.qrc \ + ../shared/config.qrc diff --git a/tests/auto/installer/deleteoperation/settings.qrc b/tests/auto/installer/deleteoperation/settings.qrc new file mode 100644 index 000000000..04a7daf71 --- /dev/null +++ b/tests/auto/installer/deleteoperation/settings.qrc @@ -0,0 +1,7 @@ +<RCC> + <qresource prefix="/"> + <file>data/repository/Updates.xml</file> + <file>data/repository/A/1.0.2-1meta.7z</file> + <file>data/xmloperationrepository/Updates.xml</file> + </qresource> +</RCC> diff --git a/tests/auto/installer/deleteoperation/tst_deleteoperation.cpp b/tests/auto/installer/deleteoperation/tst_deleteoperation.cpp new file mode 100644 index 000000000..43ea52407 --- /dev/null +++ b/tests/auto/installer/deleteoperation/tst_deleteoperation.cpp @@ -0,0 +1,153 @@ +/************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ + +#include "../shared/packagemanager.h" + +#include <updateoperations.h> +#include <packagemanagercore.h> +#include <settings.h> +#include <utils.h> + +#include <QTest> + +using namespace KDUpdater; +using namespace QInstaller; + +class tst_deleteoperation : public QObject +{ + Q_OBJECT +private: + void installFromCLI(const QString &repository) + { + QString installDir = QInstaller::generateTemporaryFileName(); + QVERIFY(QDir().mkpath(installDir)); + PackageManagerCore *core = PackageManager::getPackageManagerWithInit(installDir, repository); + + // Matches filename in component install script + QFile file(installDir + QDir::toNativeSeparators("/test")); + QVERIFY(file.open(QIODevice::ReadWrite)); + file.close(); + + core->installDefaultComponentsSilently(); + QVERIFY(!file.exists()); + + core->setPackageManager(); + core->commitSessionOperations(); + core->uninstallComponentsSilently(QStringList() << "A"); + QVERIFY(file.exists()); + + QDir dir(installDir); + QVERIFY(dir.removeRecursively()); + core->deleteLater(); + } + +private slots: + void testMissingArguments() + { + DeleteOperation op; + + QVERIFY(op.testOperation()); + QVERIFY(!op.performOperation()); + + QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::InvalidArguments); + QCOMPARE(op.errorString(), QString("Invalid arguments in Delete: 0 arguments given, 1 to 3 arguments expected in the form: <file to remove> [UNDOOPERATION, \"\"].")); + + op.setArguments(QStringList() << ""); + QTest::ignoreMessage(QtWarningMsg, "QFile::copy: Empty or null file name"); + op.backup(); + + QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::UserDefinedError); + QCOMPARE(op.errorString(), QString("Cannot create backup of file \"\": Unknown error")); + + // Returns true with empty file argument but does not do anything + QVERIFY(op.performOperation()); + } + + void testDeleteRestore_data() + { + QTest::addColumn<QString>("path"); + QTest::addColumn<bool>("overrideUndo"); + QTest::newRow("relative") << "test" << false; + QTest::newRow("absolute") << qApp->applicationDirPath() + QDir::toNativeSeparators("/test") << false; + QTest::newRow("no undo") << "test" << true; + } + + void testDeleteRestore() + { + QFETCH(QString, path); + QFETCH(bool, overrideUndo); + + QByteArray testString("Generated by QTest\n"); + QFile testFile(path); + QVERIFY(testFile.open(QIODevice::WriteOnly | QIODevice::Text)); + QTextStream out(&testFile); + out << testString; + testFile.close(); + + QVERIFY(QFileInfo::exists(path)); + QByteArray testFileHash = QInstaller::calculateHash(path, QCryptographicHash::Sha1); + + DeleteOperation *op = new DeleteOperation(); + op->setArguments(QStringList() << path); + if (overrideUndo) + op->setArguments(op->arguments() << QLatin1String("UNDOOPERATION")); + + op->backup(); + QVERIFY(QFileInfo::exists(op->value("backupOfExistingFile").toString())); + + QVERIFY2(op->performOperation(), op->errorString().toLatin1()); + QVERIFY(!QFileInfo::exists(path)); + + QVERIFY2(op->undoOperation(), op->errorString().toLatin1()); + if (!overrideUndo) { + QByteArray restoredFileHash = QInstaller::calculateHash(path, QCryptographicHash::Sha1); + QVERIFY(testFileHash == restoredFileHash); + } else { + QVERIFY(!QFileInfo::exists(path)); + } + + QString backupFileName = op->value("backupOfExistingFile").toString(); + delete op; + QVERIFY(!QFileInfo::exists(backupFileName)); + QCOMPARE(QFile(path).remove(), !overrideUndo); + } + + void testDeleteFromScript() + { + installFromCLI(":///data/repository"); + } + + void testDeleteFromXML() + { + installFromCLI(":///data/xmloperationrepository"); + } +}; + +QTEST_MAIN(tst_deleteoperation) + +#include "tst_deleteoperation.moc" diff --git a/tests/auto/installer/elevatedexecuteoperation/elevatedexecuteoperation.pro b/tests/auto/installer/elevatedexecuteoperation/elevatedexecuteoperation.pro new file mode 100644 index 000000000..9ac3f260a --- /dev/null +++ b/tests/auto/installer/elevatedexecuteoperation/elevatedexecuteoperation.pro @@ -0,0 +1,8 @@ +include(../../qttest.pri) + +QT -= gui +QT += testlib qml + +SOURCES = tst_elevatedexecuteoperation.cpp + +DEFINES += "QMAKE_BINARY=$$fromNativeSeparators($$QMAKE_BINARY)" diff --git a/tests/auto/installer/elevatedexecuteoperation/tst_elevatedexecuteoperation.cpp b/tests/auto/installer/elevatedexecuteoperation/tst_elevatedexecuteoperation.cpp new file mode 100644 index 000000000..ef185a5cf --- /dev/null +++ b/tests/auto/installer/elevatedexecuteoperation/tst_elevatedexecuteoperation.cpp @@ -0,0 +1,67 @@ +/************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ + +#include <packagemanagercore.h> +#include <elevatedexecuteoperation.h> + +#include <QTest> + +#define QUOTE_(x) #x +#define QUOTE(x) QUOTE_(x) + +using namespace QInstaller; + +class tst_elevatedexecuteoperation : public QObject +{ + Q_OBJECT + +private slots: + void testExecuteOperation() + { + m_core.setValue(QLatin1String("QMAKE_BINARY"), QUOTE(QMAKE_BINARY)); + m_core.setValue(QLatin1String("QMAKE_BINARY_OLD"), QLatin1String("FAKE_QMAKE")); + ElevatedExecuteOperation operation(&m_core); + operation.setArguments(QStringList() << QLatin1String("UNDOEXECUTE") << QLatin1String("FAKE_QMAKE") << QLatin1String("-v")); + + QTest::ignoreMessage(QtDebugMsg, "\"FAKE_QMAKE\" started, arguments: \"-v\""); + QString message = "Failed to run undo operation \"Execute\" for component . Trying again with arguments %1, -v"; + QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(QUOTE(QMAKE_BINARY)))); + message = "\"%1\" started, arguments: \"-v\""; + QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(QUOTE(QMAKE_BINARY)))); + + QCOMPARE(operation.undoOperation(), true); + QCOMPARE(Operation::Error(operation.error()), Operation::NoError); + } + +private: + PackageManagerCore m_core; +}; + +QTEST_MAIN(tst_elevatedexecuteoperation) + +#include "tst_elevatedexecuteoperation.moc" diff --git a/tests/auto/installer/environmentvariableoperation/data/repository/A/1.0.2-1meta.7z b/tests/auto/installer/environmentvariableoperation/data/repository/A/1.0.2-1meta.7z Binary files differnew file mode 100644 index 000000000..26b9ed692 --- /dev/null +++ b/tests/auto/installer/environmentvariableoperation/data/repository/A/1.0.2-1meta.7z diff --git a/tests/auto/installer/environmentvariableoperation/data/repository/Updates.xml b/tests/auto/installer/environmentvariableoperation/data/repository/Updates.xml new file mode 100644 index 000000000..5bcd58c69 --- /dev/null +++ b/tests/auto/installer/environmentvariableoperation/data/repository/Updates.xml @@ -0,0 +1,15 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.2-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <Script>script.qs</Script> + <SHA1>4b7b52af2d838389a7404c553da74705fc106493</SHA1> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/environmentvariableoperation/data/xmloperationrepository/Updates.xml b/tests/auto/installer/environmentvariableoperation/data/xmloperationrepository/Updates.xml new file mode 100644 index 000000000..9c33caf6d --- /dev/null +++ b/tests/auto/installer/environmentvariableoperation/data/xmloperationrepository/Updates.xml @@ -0,0 +1,25 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.2-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <Operations> + <Operation name="EnvironmentVariable"> + <Argument>IFW_UNIT_TEST_LOCAL</Argument> + <Argument>IFW_UNIT_TEST_VALUE</Argument> + <Argument>false</Argument> + </Operation> + <Operation name="EnvironmentVariable"> + <Argument>IFW_UNIT_TEST_PERSISTENT</Argument> + <Argument>IFW_UNIT_TEST_PERSISTENT_VALUE</Argument> + <Argument>true</Argument> + </Operation> + </Operations> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/environmentvariableoperation/environmentvariableoperation.pro b/tests/auto/installer/environmentvariableoperation/environmentvariableoperation.pro new file mode 100644 index 000000000..77f566d59 --- /dev/null +++ b/tests/auto/installer/environmentvariableoperation/environmentvariableoperation.pro @@ -0,0 +1,11 @@ +include(../../qttest.pri) + +QT -= gui +QT += testlib + +SOURCES = tst_environmentvariableoperation.cpp + +RESOURCES += \ + settings.qrc \ + ../shared/config.qrc + diff --git a/tests/auto/installer/environmentvariableoperation/settings.qrc b/tests/auto/installer/environmentvariableoperation/settings.qrc new file mode 100644 index 000000000..04a7daf71 --- /dev/null +++ b/tests/auto/installer/environmentvariableoperation/settings.qrc @@ -0,0 +1,7 @@ +<RCC> + <qresource prefix="/"> + <file>data/repository/Updates.xml</file> + <file>data/repository/A/1.0.2-1meta.7z</file> + <file>data/xmloperationrepository/Updates.xml</file> + </qresource> +</RCC> diff --git a/tests/auto/installer/environmentvariableoperation/tst_environmentvariableoperation.cpp b/tests/auto/installer/environmentvariableoperation/tst_environmentvariableoperation.cpp new file mode 100644 index 000000000..4afbc709c --- /dev/null +++ b/tests/auto/installer/environmentvariableoperation/tst_environmentvariableoperation.cpp @@ -0,0 +1,184 @@ +/************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ + +#include "../shared/packagemanager.h" + +#include <environmentvariablesoperation.h> +#include <environment.h> +#include <packagemanagercore.h> + +#include <QSettings> +#include <QTest> + +using namespace QInstaller; +using namespace KDUpdater; + +class tst_environmentvariableoperation : public QObject +{ + Q_OBJECT + +private: + void installFromCLI(const QString &repository) + { + QString installDir = QInstaller::generateTemporaryFileName(); + QVERIFY(QDir().mkpath(installDir)); + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (installDir, repository)); + core->installDefaultComponentsSilently(); + + QVERIFY(m_settings->value("IFW_UNIT_TEST_LOCAL").toString().isEmpty()); + + // Persistent is in settings in Windows platform only, otherwise it is written to local env. +#ifdef Q_OS_WIN + QCOMPARE(m_settings->value("IFW_UNIT_TEST_PERSISTENT").toString(), QLatin1String("IFW_UNIT_TEST_PERSISTENT_VALUE")); +#else + QCOMPARE(Environment::instance().value("IFW_UNIT_TEST_PERSISTENT"), QLatin1String("IFW_UNIT_TEST_PERSISTENT_VALUE")); +#endif + QCOMPARE(Environment::instance().value("IFW_UNIT_TEST_LOCAL"), QLatin1String("IFW_UNIT_TEST_VALUE")); + + core->commitSessionOperations(); + core->setPackageManager(); + core->uninstallComponentsSilently(QStringList() << "A"); + QVERIFY(m_settings->value("IFW_UNIT_TEST_PERSISTENT").toString().isEmpty()); + QVERIFY(Environment::instance().value("IFW_UNIT_TEST_LOCAL").isEmpty()); + } + +private slots: + void initTestCase() + { + m_key = "IFW_TestKey"; + m_value = "IFW_TestValue"; + m_oldValue = "IFW_TestOldValue"; + m_settings = new QSettings("HKEY_CURRENT_USER\\Environment", QSettings::NativeFormat); + } + + void cleanup() + { + m_settings->remove(m_key); + m_settings->remove("IFW_UNIT_TEST_PERSISTENT"); //Added from script + } + + void testPersistentNonSystem() + { + #ifndef Q_OS_WIN + QSKIP("This operation only works on Windows"); + #endif + EnvironmentVariableOperation op(nullptr); + op.setArguments( QStringList() << m_key + << m_value + << QLatin1String("true") + << QLatin1String("false")); + const bool ok = op.performOperation(); + + QVERIFY2(ok, qPrintable(op.errorString())); + + QCOMPARE(m_value, m_settings->value(m_key).toString()); + + QVERIFY(op.undoOperation()); + QVERIFY(m_settings->value(m_key).toString().isEmpty()); + } + + void testNonPersistentNonSystem() + { + EnvironmentVariableOperation op(nullptr); + op.setArguments( QStringList() << m_key + << m_value + << QLatin1String("false") + << QLatin1String("false")); + const bool ok = op.performOperation(); + + QVERIFY2(ok, qPrintable(op.errorString())); + + //Make sure it is not written to env variable + QString comp = QString::fromLocal8Bit(qgetenv(qPrintable(m_key))); + QVERIFY(comp.isEmpty()); + + QCOMPARE(m_value, Environment::instance().value(m_key)); + } + + void testPersistentNonSystemOldValue() + { + #ifndef Q_OS_WIN + QSKIP("This operation only works on Windows"); + #endif + m_settings->setValue(m_key, m_oldValue); + + EnvironmentVariableOperation op(nullptr); + op.setArguments( QStringList() << m_key + << m_value + << QLatin1String("true") + << QLatin1String("false")); + const bool ok = op.performOperation(); + + QVERIFY2(ok, qPrintable(op.errorString())); + + QCOMPARE(m_value, m_settings->value(m_key).toString()); + + QVERIFY(op.undoOperation()); + QCOMPARE(m_settings->value(m_key).toString(), m_oldValue); + m_settings->remove(m_key); + } + + void testNonPersistentNonSystemOldValue() + { + m_settings->setValue(m_key, m_oldValue); + Environment::instance().setTemporaryValue(m_key, m_oldValue); + EnvironmentVariableOperation op(nullptr); + op.setArguments( QStringList() << m_key + << m_value + << QLatin1String("false") + << QLatin1String("false")); + const bool ok = op.performOperation(); + + QVERIFY2(ok, qPrintable(op.errorString())); + + QVERIFY(op.undoOperation()); + QCOMPARE(m_oldValue, Environment::instance().value(m_key)); + } + + void testEnvVariableFromScript() + { + installFromCLI(":///data/repository"); + } + + void testEnvVariableFromSXML() + { + installFromCLI(":///data/xmloperationrepository"); + } + +private: + QSettings *m_settings; + QString m_key; + QString m_value; + QString m_oldValue; +}; + +QTEST_MAIN(tst_environmentvariableoperation) + +#include "tst_environmentvariableoperation.moc" + diff --git a/tests/auto/installer/extractarchiveoperationtest/data.qrc b/tests/auto/installer/extractarchiveoperationtest/data.qrc index d6453a9b3..87f648568 100644 --- a/tests/auto/installer/extractarchiveoperationtest/data.qrc +++ b/tests/auto/installer/extractarchiveoperationtest/data.qrc @@ -2,5 +2,17 @@ <qresource prefix="/"> <file>data/valid.7z</file> <file>data/invalid.7z</file> + <file>data/subdirs.7z</file> + <file>data/xmloperationrepository/Updates.xml</file> + <file>data/xmloperationrepository/A/1.0.0content.7z</file> + <file>data/xmloperationrepository/A/1.0.0content1.tar.gz</file> + <file>data/xmloperationrepository/A/1.0.0content2.tar.bz2</file> + <file>data/xmloperationrepository/A/1.0.0content3.tar.xz</file> + <file>data/xmloperationrepository/A/1.0.0content4.zip</file> + <file>data/xmloperationrepository/A/1.0.0anothercontent.7z</file> + <file>data/xmloperationrepository/A/1.0.0default.7z</file> + <file>data/installerbaserepository/Updates.xml</file> + <file>data/installerbaserepository/A/1.0.0content.7z</file> + <file>data/installerbaserepository/A/1.0.0installerbase.7z</file> </qresource> </RCC> diff --git a/tests/auto/installer/extractarchiveoperationtest/data/installerbaserepository/A/1.0.0content.7z b/tests/auto/installer/extractarchiveoperationtest/data/installerbaserepository/A/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..585f58296 --- /dev/null +++ b/tests/auto/installer/extractarchiveoperationtest/data/installerbaserepository/A/1.0.0content.7z diff --git a/tests/auto/installer/extractarchiveoperationtest/data/installerbaserepository/A/1.0.0installerbase.7z b/tests/auto/installer/extractarchiveoperationtest/data/installerbaserepository/A/1.0.0installerbase.7z Binary files differnew file mode 100644 index 000000000..c3b6aec9c --- /dev/null +++ b/tests/auto/installer/extractarchiveoperationtest/data/installerbaserepository/A/1.0.0installerbase.7z diff --git a/tests/auto/installer/extractarchiveoperationtest/data/installerbaserepository/Updates.xml b/tests/auto/installer/extractarchiveoperationtest/data/installerbaserepository/Updates.xml new file mode 100644 index 000000000..887300c97 --- /dev/null +++ b/tests/auto/installer/extractarchiveoperationtest/data/installerbaserepository/Updates.xml @@ -0,0 +1,13 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <PackageUpdate> + <Name>A</Name> + <DisplayName>InstallerBase</DisplayName> + <Description>Example component InstallerBase</Description> + <Version>1.0.0</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <DownloadableArchives>installerbase.7z,content.7z</DownloadableArchives> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/extractarchiveoperationtest/data/subdirs.7z b/tests/auto/installer/extractarchiveoperationtest/data/subdirs.7z Binary files differnew file mode 100644 index 000000000..7f93fe106 --- /dev/null +++ b/tests/auto/installer/extractarchiveoperationtest/data/subdirs.7z diff --git a/tests/auto/installer/extractarchiveoperationtest/data/xmloperationrepository/A/1.0.0anothercontent.7z b/tests/auto/installer/extractarchiveoperationtest/data/xmloperationrepository/A/1.0.0anothercontent.7z Binary files differnew file mode 100644 index 000000000..949b50689 --- /dev/null +++ b/tests/auto/installer/extractarchiveoperationtest/data/xmloperationrepository/A/1.0.0anothercontent.7z diff --git a/tests/auto/installer/extractarchiveoperationtest/data/xmloperationrepository/A/1.0.0content.7z b/tests/auto/installer/extractarchiveoperationtest/data/xmloperationrepository/A/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..585f58296 --- /dev/null +++ b/tests/auto/installer/extractarchiveoperationtest/data/xmloperationrepository/A/1.0.0content.7z diff --git a/tests/auto/installer/extractarchiveoperationtest/data/xmloperationrepository/A/1.0.0content1.tar.gz b/tests/auto/installer/extractarchiveoperationtest/data/xmloperationrepository/A/1.0.0content1.tar.gz Binary files differnew file mode 100644 index 000000000..3e494db34 --- /dev/null +++ b/tests/auto/installer/extractarchiveoperationtest/data/xmloperationrepository/A/1.0.0content1.tar.gz diff --git a/tests/auto/installer/extractarchiveoperationtest/data/xmloperationrepository/A/1.0.0content2.tar.bz2 b/tests/auto/installer/extractarchiveoperationtest/data/xmloperationrepository/A/1.0.0content2.tar.bz2 Binary files differnew file mode 100644 index 000000000..12cbef8a1 --- /dev/null +++ b/tests/auto/installer/extractarchiveoperationtest/data/xmloperationrepository/A/1.0.0content2.tar.bz2 diff --git a/tests/auto/installer/extractarchiveoperationtest/data/xmloperationrepository/A/1.0.0content3.tar.xz b/tests/auto/installer/extractarchiveoperationtest/data/xmloperationrepository/A/1.0.0content3.tar.xz Binary files differnew file mode 100644 index 000000000..bfa825493 --- /dev/null +++ b/tests/auto/installer/extractarchiveoperationtest/data/xmloperationrepository/A/1.0.0content3.tar.xz diff --git a/tests/auto/installer/extractarchiveoperationtest/data/xmloperationrepository/A/1.0.0content4.zip b/tests/auto/installer/extractarchiveoperationtest/data/xmloperationrepository/A/1.0.0content4.zip Binary files differnew file mode 100644 index 000000000..866bfa589 --- /dev/null +++ b/tests/auto/installer/extractarchiveoperationtest/data/xmloperationrepository/A/1.0.0content4.zip diff --git a/tests/auto/installer/extractarchiveoperationtest/data/xmloperationrepository/A/1.0.0default.7z b/tests/auto/installer/extractarchiveoperationtest/data/xmloperationrepository/A/1.0.0default.7z Binary files differnew file mode 100644 index 000000000..1c0c5ccfb --- /dev/null +++ b/tests/auto/installer/extractarchiveoperationtest/data/xmloperationrepository/A/1.0.0default.7z diff --git a/tests/auto/installer/extractarchiveoperationtest/data/xmloperationrepository/Updates.xml b/tests/auto/installer/extractarchiveoperationtest/data/xmloperationrepository/Updates.xml new file mode 100644 index 000000000..73a093725 --- /dev/null +++ b/tests/auto/installer/extractarchiveoperationtest/data/xmloperationrepository/Updates.xml @@ -0,0 +1,42 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.0</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <DownloadableArchives>content.7z,anothercontent.7z,content1.tar.gz,content2.tar.bz2,content3.tar.xz,content4.zip,default.7z</DownloadableArchives> + <Operations> + <Operation name="Extract"> + <Argument>@TargetDir@/FolderForContent</Argument> + <Argument>content.7z</Argument> + </Operation> + <Operation name="Extract"> + <Argument>@TargetDir@/FolderForAnotherContent</Argument> + <Argument>anothercontent.7z</Argument> + </Operation> + <Operation name="Extract"> + <Argument>@TargetDir@/FolderForTarGzContent</Argument> + <Argument>content1.tar.gz</Argument> + </Operation> + <Operation name="Extract"> + <Argument>@TargetDir@/FolderForTarBz2Content</Argument> + <Argument>content2.tar.bz2</Argument> + </Operation> + <Operation name="Extract"> + <Argument>@TargetDir@/FolderForTarXzContent</Argument> + <Argument>content3.tar.xz</Argument> + </Operation> + <Operation name="Extract"> + <Argument>@TargetDir@/FolderForZipContent</Argument> + <Argument>content4.zip</Argument> + </Operation> + <Operation name="Extract"> + <Argument>@TargetDir@/FolderForDefault</Argument> + </Operation> + </Operations> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/extractarchiveoperationtest/extractarchiveoperationtest.pro b/tests/auto/installer/extractarchiveoperationtest/extractarchiveoperationtest.pro index fb53c9a8a..e0da85b0a 100644 --- a/tests/auto/installer/extractarchiveoperationtest/extractarchiveoperationtest.pro +++ b/tests/auto/installer/extractarchiveoperationtest/extractarchiveoperationtest.pro @@ -3,5 +3,6 @@ include(../../qttest.pri) QT -= gui QT += testlib -RESOURCES += data.qrc +RESOURCES += data.qrc \ + ../shared/config.qrc SOURCES = tst_extractarchiveoperationtest.cpp diff --git a/tests/auto/installer/extractarchiveoperationtest/tst_extractarchiveoperationtest.cpp b/tests/auto/installer/extractarchiveoperationtest/tst_extractarchiveoperationtest.cpp index a5f38e0ea..a8a65e983 100644 --- a/tests/auto/installer/extractarchiveoperationtest/tst_extractarchiveoperationtest.cpp +++ b/tests/auto/installer/extractarchiveoperationtest/tst_extractarchiveoperationtest.cpp @@ -1,6 +1,6 @@ /************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2022 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Installer Framework. @@ -26,6 +26,9 @@ ** **************************************************************************/ +#include "../shared/packagemanager.h" + +#include "concurrentoperationrunner.h" #include "init.h" #include "extractarchiveoperation.h" @@ -40,6 +43,8 @@ class tst_extractarchiveoperationtest : public QObject { Q_OBJECT +private: + private slots: void initTestCase() { @@ -80,9 +85,133 @@ private slots: QVERIFY(op.undoOperation()); QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::UserDefinedError); - QCOMPARE(op.errorString(), QString("Error while extracting archive \":///data/invalid.7z\": " - "Cannot open archive \":///data/invalid.7z\".")); } + + void testConcurrentExtractWithCompetingData() + { + // Suppress warnings about already deleted installerResources file + qInstallMessageHandler(silentTestMessageHandler); + + const QString testDirectory = generateTemporaryFileName() + + "/subdir1/subdir2/subdir3/subdir4/subdir5/"; + + QStringList created7zList; + + OperationList operations; + for (int i = 0; i < 100; ++i) { + ExtractArchiveOperation *op = new ExtractArchiveOperation(nullptr); + // We add the same data multiple times, and extract to same directory. + // Can't open the same archive multiple times however so it needs to + // be copied to unique files. + const QString new7zPath = generateTemporaryFileName() + ".7z"; + QFile old7z(":///data/subdirs.7z"); + QVERIFY(old7z.copy(new7zPath)); + + op->setArguments(QStringList() << new7zPath << testDirectory); + operations.append(op); + } + ConcurrentOperationRunner runner(&operations, Operation::Backup); + + const QHash<Operation *, bool> backupResults = runner.run(); + const OperationList backupOperations = backupResults.keys(); + + for (auto *operation : backupOperations) + QVERIFY2((backupResults.value(operation) && operation->error() == Operation::NoError), + operation->errorString().toLatin1()); + + runner.setType(Operation::Perform); + const QHash<Operation *, bool> results = runner.run(); + const OperationList performedOperations = results.keys(); + + for (auto *operation : performedOperations) + QVERIFY2((results.value(operation) && operation->error() == Operation::NoError), + operation->errorString().toLatin1()); + + for (auto *operation : operations) + QVERIFY(operation->undoOperation()); + + qDeleteAll(operations); + + for (const QString &archive : created7zList) + QFile::remove(archive); + + QDir().rmdir(testDirectory); + } + + void testExtractArchiveFromXML() + { + m_testDirectory = QInstaller::generateTemporaryFileName(); + QVERIFY(QDir().mkpath(m_testDirectory)); + QVERIFY(QDir(m_testDirectory).exists()); + + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (m_testDirectory, ":///data/xmloperationrepository")); + core->installDefaultComponentsSilently(); + + QFile extractedFile(m_testDirectory + QDir::separator() + "FolderForContent/content.txt"); + QVERIFY(extractedFile.exists()); +#ifdef IFW_LIBARCHIVE + extractedFile.setFileName(m_testDirectory + QDir::separator() + "FolderForTarGzContent/content.txt"); + QVERIFY(extractedFile.exists()); + + extractedFile.setFileName(m_testDirectory + QDir::separator() + "FolderForTarBz2Content/content.txt"); + QVERIFY(extractedFile.exists()); + + extractedFile.setFileName(m_testDirectory + QDir::separator() + "FolderForTarXzContent/content.txt"); + QVERIFY(extractedFile.exists()); + + extractedFile.setFileName(m_testDirectory + QDir::separator() + "FolderForZipContent/content.txt"); + QVERIFY(extractedFile.exists()); +#endif + extractedFile.setFileName(m_testDirectory + QDir::separator() + "FolderForAnotherContent/anothercontent.txt"); + QVERIFY(extractedFile.exists()); + + extractedFile.setFileName(m_testDirectory + QDir::separator() + "FolderForDefault/default.txt"); + QVERIFY(extractedFile.exists()); + + core->setPackageManager(); + core->commitSessionOperations(); + + core->uninstallComponentsSilently(QStringList() << "A"); + QDir dir(m_testDirectory); + QVERIFY(dir.removeRecursively()); + } + + void testInstallerBaseBinaryExtraction() + { + m_testDirectory = QInstaller::generateTemporaryFileName(); + QVERIFY(QDir().mkpath(m_testDirectory)); + QVERIFY(QDir(m_testDirectory).exists()); + + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (m_testDirectory, ":///data/installerbaserepository")); + core->setInstallerBaseBinary(m_testDirectory + QDir::separator() + "testInstallerBase.txt"); + core->installDefaultComponentsSilently(); + + QFile contentResourceFile(m_testDirectory + QDir::separator() + "installerResources" + QDir::separator() + "A" + QDir::separator() + "1.0.0content.txt"); + QVERIFY2(contentResourceFile.open(QIODevice::ReadOnly | QIODevice::Text), "Could not open content resource file for reading."); + QTextStream fileStream(&contentResourceFile); + QString line = fileStream.readLine(); + QVERIFY2(!line.isEmpty(), "Content not written to resource file."); + contentResourceFile.close(); + + QFile installerBaseResourceFile(m_testDirectory + QDir::separator() + "installerResources" + QDir::separator() + "A" + QDir::separator() + "1.0.0installerbase.txt"); + QVERIFY2(installerBaseResourceFile.open(QIODevice::ReadOnly | QIODevice::Text), "Could not open installerbase resource file for reading."); + QTextStream fileStream2(&installerBaseResourceFile); + line = installerBaseResourceFile.readLine(); + QVERIFY2(line.isEmpty(), "Installerbase falsly written to resource file."); + installerBaseResourceFile.close(); + + core->setPackageManager(); + core->commitSessionOperations(); + + QCOMPARE(PackageManagerCore::Success, core->uninstallComponentsSilently(QStringList() << "A")); + QDir dir(m_testDirectory); + QVERIFY(dir.removeRecursively()); + } + +private: + QString m_testDirectory; }; QTEST_MAIN(tst_extractarchiveoperationtest) diff --git a/tests/auto/installer/factory/tst_factory.cpp b/tests/auto/installer/factory/tst_factory.cpp index a693a2ce6..4b6932c09 100644 --- a/tests/auto/installer/factory/tst_factory.cpp +++ b/tests/auto/installer/factory/tst_factory.cpp @@ -1,32 +1,26 @@ /************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Installer Framework. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. ** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** @@ -77,7 +71,7 @@ public: : Food(amount) , m_expireDate(expireDate) { qDebug().nospace().noquote() << "Constructor."; } - QDate expireDate() const { + QDate expireDate() const override { return m_expireDate; } private: @@ -87,7 +81,7 @@ private: class Butter : public Food { public: - QDate expireDate() const { + QDate expireDate() const override { return m_expireDate; } static Food *create(int amount, const QDate expireDate) { @@ -112,7 +106,7 @@ public: : Food(amount) , m_expireDate(expireDate) { qDebug().nospace().noquote() << "Constructor."; } - QDate expireDate() const { + QDate expireDate() const override { return m_expireDate; } diff --git a/tests/auto/installer/fileutils/fileutils.pro b/tests/auto/installer/fileutils/fileutils.pro new file mode 100644 index 000000000..eee7ec537 --- /dev/null +++ b/tests/auto/installer/fileutils/fileutils.pro @@ -0,0 +1,6 @@ +include(../../qttest.pri) + +QT -= gui +QT += testlib + +SOURCES += tst_fileutils.cpp diff --git a/tests/auto/installer/fileutils/tst_fileutils.cpp b/tests/auto/installer/fileutils/tst_fileutils.cpp new file mode 100644 index 000000000..5472e1403 --- /dev/null +++ b/tests/auto/installer/fileutils/tst_fileutils.cpp @@ -0,0 +1,135 @@ +/************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ + +#include <qinstallerglobal.h> +#include <fileutils.h> + +#include <QObject> +#include <QTest> +#include <QFile> +#include <QDir> + +using namespace QInstaller; + +class tst_fileutils : public QObject +{ + Q_OBJECT + +private slots: + void testSetDefaultFilePermissions() + { +#if defined(Q_OS_WIN) + QString fileName = QInstaller::generateTemporaryFileName(); + QFile testFile(fileName); + + QVERIFY(testFile.open(QIODevice::ReadWrite)); + QVERIFY(testFile.exists()); + testFile.close(); + + // Set permissions containing none of the Write* flags, this will cause + // the read-only flag to be set for the file + QVERIFY(testFile.setPermissions(QFileDevice::ReadOwner | QFileDevice::ReadUser + | QFileDevice::ReadGroup | QFileDevice::ReadOther)); + + // Verify that the file cannot be opened for both reading and writing, i.e. + // it should be read-only. + QVERIFY(!testFile.open(QIODevice::ReadWrite)); + + // Now try to remove the read-only flag + QVERIFY(setDefaultFilePermissions(&testFile, DefaultFilePermissions::NonExecutable)); + + // Verify that the file can now be opened for both reading and writing + QVERIFY(testFile.open(QIODevice::ReadWrite)); + testFile.close(); + + QVERIFY(testFile.setPermissions(QFileDevice::ReadOwner | QFileDevice::ReadUser + | QFileDevice::ReadGroup | QFileDevice::ReadOther)); + + // Check that the behavior is same with 'Executable' argument + QVERIFY(setDefaultFilePermissions(&testFile, DefaultFilePermissions::Executable)); + + QVERIFY(testFile.open(QIODevice::ReadWrite)); + testFile.close(); + + QVERIFY(testFile.remove()); +#elif defined(Q_OS_UNIX) + // Need to include the "user" flags here as they will be returned + // by QFile::permissions(). Same as owner permissions of the file. + QFlags<QFileDevice::Permission> permissions(QFileDevice::ReadOwner + | QFileDevice::WriteOwner | QFileDevice::ReadUser | QFileDevice::WriteUser + | QFileDevice::ReadGroup | QFileDevice::ReadOther); + + QFlags<QFileDevice::Permission> exePermissions(permissions | QFileDevice::ExeOwner + | QFileDevice::ExeUser | QFileDevice::ExeGroup | QFileDevice::ExeOther); + + QString fileName = QInstaller::generateTemporaryFileName(); + QFile testFile(fileName); + + const QString message = "Target \"%1\" does not exists."; + + // Test non-existing file + QTest::ignoreMessage(QtWarningMsg, qPrintable(message.arg(fileName))); + QVERIFY(!setDefaultFilePermissions(fileName, DefaultFilePermissions::NonExecutable)); + + QTest::ignoreMessage(QtWarningMsg, qPrintable(message.arg(testFile.fileName()))); + QVERIFY(!setDefaultFilePermissions(&testFile, DefaultFilePermissions::NonExecutable)); + + QVERIFY(testFile.open(QIODevice::ReadWrite)); + QVERIFY(testFile.exists()); + testFile.close(); + + // Test with file name + QVERIFY(setDefaultFilePermissions(fileName, DefaultFilePermissions::NonExecutable)); + QCOMPARE(QFile().permissions(fileName), permissions); + + QVERIFY(setDefaultFilePermissions(fileName, DefaultFilePermissions::Executable)); + QCOMPARE(QFile().permissions(fileName), exePermissions); + + // Test with QFile object + QVERIFY(setDefaultFilePermissions(&testFile, DefaultFilePermissions::NonExecutable)); + QCOMPARE(QFile().permissions(fileName), permissions); + + QVERIFY(setDefaultFilePermissions(&testFile, DefaultFilePermissions::Executable)); + QCOMPARE(QFile().permissions(fileName), exePermissions); + + // Test with directory path + QString testDir = QDir().tempPath() + QLatin1String("/testDir"); + QVERIFY(QDir().mkdir(testDir)); + + QVERIFY(setDefaultFilePermissions(testDir, DefaultFilePermissions::Executable)); + QCOMPARE(QFile().permissions(testDir), exePermissions); + + QVERIFY(QDir().rmdir(testDir)); + QVERIFY(testFile.remove()); +#endif + } +}; + +QTEST_MAIN(tst_fileutils) + +#include "tst_fileutils.moc" diff --git a/tests/auto/installer/globalsettingsoperation/globalsettingsoperation.pro b/tests/auto/installer/globalsettingsoperation/globalsettingsoperation.pro new file mode 100644 index 000000000..c9e959cac --- /dev/null +++ b/tests/auto/installer/globalsettingsoperation/globalsettingsoperation.pro @@ -0,0 +1,10 @@ +include(../../qttest.pri) + +QT -= gui +QT += testlib + +SOURCES = tst_globalsettingsoperation.cpp + +RESOURCES += \ + ../shared/config.qrc + diff --git a/tests/auto/installer/globalsettingsoperation/tst_globalsettingsoperation.cpp b/tests/auto/installer/globalsettingsoperation/tst_globalsettingsoperation.cpp new file mode 100644 index 000000000..009673f24 --- /dev/null +++ b/tests/auto/installer/globalsettingsoperation/tst_globalsettingsoperation.cpp @@ -0,0 +1,95 @@ +/************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ + +#include "../shared/packagemanager.h" + +#include <globalsettingsoperation.h> +#include <environment.h> +#include <packagemanagercore.h> + +#include <QSettings> +#include <QTest> + +using namespace QInstaller; +using namespace KDUpdater; + +class tst_globalsettingsoperation : public QObject +{ + Q_OBJECT + +private: + void cleanSettings() + { + QSettings testSettings("QtProject", "QtProject.QtIfwTest"); + testSettings.setValue("QtIfwTestKey", ""); + } + + +private slots: + void initTestCase() + { + cleanSettings(); + } + + void cleanupTestCase() + { + cleanSettings(); + } + + void setGlobalSettingsValue() + { + GlobalSettingsOperation settingsOperation(nullptr); + settingsOperation.setArguments(QStringList() << "QtProject" << "QtProject.QtIfwTest" << "QtIfwTestKey" << "QtIfwTestValue"); + settingsOperation.backup(); + QVERIFY2(settingsOperation.performOperation(), settingsOperation.errorString().toLatin1()); + + QSettings testSettings("QtProject", "QtProject.QtIfwTest"); + QCOMPARE("QtIfwTestValue", testSettings.value("QtIfwTestKey")); + QVERIFY2(settingsOperation.undoOperation(), settingsOperation.errorString().toLatin1()); + QCOMPARE("", testSettings.value("QtIfwTestKey")); + } + + void setGlobalSettingsValueNoUndo() + { + + GlobalSettingsOperation settingsOperation(nullptr); + settingsOperation.setArguments(QStringList() << "QtProject" << "QtProject.QtIfwTest" << "QtIfwTestKey" << "QtIfwTestValue" << "UNDOOPERATION" << ""); + settingsOperation.backup(); + QVERIFY2(settingsOperation.performOperation(), settingsOperation.errorString().toLatin1()); + + QSettings testSettings("QtProject", "QtProject.QtIfwTest"); + QCOMPARE("QtIfwTestValue", testSettings.value("QtIfwTestKey")); + QVERIFY2(settingsOperation.undoOperation(), settingsOperation.errorString().toLatin1()); + QCOMPARE("QtIfwTestValue", testSettings.value("QtIfwTestKey")); + } +}; + +QTEST_MAIN(tst_globalsettingsoperation) + +#include "tst_globalsettingsoperation.moc" + diff --git a/tests/auto/installer/installer.pro b/tests/auto/installer/installer.pro index 7081a6316..b2eb57790 100644 --- a/tests/auto/installer/installer.pro +++ b/tests/auto/installer/installer.pro @@ -1,6 +1,7 @@ TEMPLATE = subdirs SUBDIRS += \ + archivefactory \ settings \ repository \ compareversion\ @@ -9,11 +10,12 @@ SUBDIRS += \ fakestopprocessforupdateoperation \ messageboxhandler \ extractarchiveoperationtest \ - lib7zfacade \ + fileutils \ unicodeexecutable \ scriptengine \ consumeoutputoperationtest \ mkdiroperationtest \ + rmdiroperationtest \ copyoperationtest \ solver \ binaryformat \ @@ -22,9 +24,47 @@ SUBDIRS += \ task \ clientserver \ factory \ - replaceoperation + replaceoperation \ + brokeninstaller \ + commandlineinstall \ + linereplaceoperation \ + metadatajob \ + appendfileoperation \ + prependfileoperation \ + simplemovefileoperation \ + deleteoperation \ + copydirectoryoperation \ + commandlineupdate \ + moveoperation \ + environmentvariableoperation \ + licenseagreement \ + globalsettingsoperation \ + elevatedexecuteoperation \ + treename \ + createoffline \ + contentshaupdate \ + componentreplace \ + metadatacache \ + contentsha1check \ + componentalias + +CONFIG(libarchive) { + SUBDIRS += libarchivearchive +} + +CONFIG(lzmasdk) { + SUBDIRS += lib7zarchive +} win32 { - SUBDIRS += registerfiletypeoperation + SUBDIRS += registerfiletypeoperation \ + createshortcutoperation } + +linux-g++* { + SUBDIRS += \ + createdesktopentryoperation \ + installiconsoperation +} + scriptengine.depends += unicodeexecutable diff --git a/tests/auto/installer/installiconsoperation/data/repository/A/1.0.2-1content.7z b/tests/auto/installer/installiconsoperation/data/repository/A/1.0.2-1content.7z Binary files differnew file mode 100644 index 000000000..9d58b172e --- /dev/null +++ b/tests/auto/installer/installiconsoperation/data/repository/A/1.0.2-1content.7z diff --git a/tests/auto/installer/installiconsoperation/data/repository/A/1.0.2-1meta.7z b/tests/auto/installer/installiconsoperation/data/repository/A/1.0.2-1meta.7z Binary files differnew file mode 100644 index 000000000..74e201fc3 --- /dev/null +++ b/tests/auto/installer/installiconsoperation/data/repository/A/1.0.2-1meta.7z diff --git a/tests/auto/installer/installiconsoperation/data/repository/Updates.xml b/tests/auto/installer/installiconsoperation/data/repository/Updates.xml new file mode 100644 index 000000000..201e23c2d --- /dev/null +++ b/tests/auto/installer/installiconsoperation/data/repository/Updates.xml @@ -0,0 +1,16 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.2-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <Script>script.qs</Script> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>13c9e7e67c26e7fbf49cc30887d87140b65e11b5</SHA1> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/installiconsoperation/data/xmloperationrepository/A/1.0.2-1content.7z b/tests/auto/installer/installiconsoperation/data/xmloperationrepository/A/1.0.2-1content.7z Binary files differnew file mode 100644 index 000000000..9d58b172e --- /dev/null +++ b/tests/auto/installer/installiconsoperation/data/xmloperationrepository/A/1.0.2-1content.7z diff --git a/tests/auto/installer/installiconsoperation/data/xmloperationrepository/Updates.xml b/tests/auto/installer/installiconsoperation/data/xmloperationrepository/Updates.xml new file mode 100644 index 000000000..5977964f2 --- /dev/null +++ b/tests/auto/installer/installiconsoperation/data/xmloperationrepository/Updates.xml @@ -0,0 +1,18 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.2-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <DownloadableArchives>content.7z</DownloadableArchives> + <Operations> + <Operation name="InstallIcons"> + <Argument>@TargetDir@/icons</Argument> + </Operation> + </Operations> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/installiconsoperation/installiconsoperation.pro b/tests/auto/installer/installiconsoperation/installiconsoperation.pro new file mode 100644 index 000000000..be4cd0b3d --- /dev/null +++ b/tests/auto/installer/installiconsoperation/installiconsoperation.pro @@ -0,0 +1,10 @@ +include(../../qttest.pri) + +QT -= gui +QT += testlib + +SOURCES = tst_installiconsoperation.cpp + +RESOURCES += \ + settings.qrc \ + ../shared/config.qrc diff --git a/tests/auto/installer/installiconsoperation/settings.qrc b/tests/auto/installer/installiconsoperation/settings.qrc new file mode 100644 index 000000000..094bd449b --- /dev/null +++ b/tests/auto/installer/installiconsoperation/settings.qrc @@ -0,0 +1,9 @@ +<RCC> + <qresource prefix="/"> + <file>data/repository/Updates.xml</file> + <file>data/repository/A/1.0.2-1content.7z</file> + <file>data/repository/A/1.0.2-1meta.7z</file> + <file>data/xmloperationrepository/Updates.xml</file> + <file>data/xmloperationrepository/A/1.0.2-1content.7z</file> + </qresource> +</RCC> diff --git a/tests/auto/installer/installiconsoperation/tst_installiconsoperation.cpp b/tests/auto/installer/installiconsoperation/tst_installiconsoperation.cpp new file mode 100644 index 000000000..3dc981652 --- /dev/null +++ b/tests/auto/installer/installiconsoperation/tst_installiconsoperation.cpp @@ -0,0 +1,235 @@ +/************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ + +#include "../shared/packagemanager.h" +#include "../shared/verifyinstaller.h" + +#include <installiconsoperation.h> + +#include <packagemanagercore.h> +#include <component.h> + +#include <QTest> + +using namespace KDUpdater; +using namespace QInstaller; + +class tst_installiconsoperation : public QObject +{ + Q_OBJECT +private: + void installFromCLI(const QString &repository) + { + QString installDir = QInstaller::generateTemporaryFileName(); + QVERIFY(QDir().mkpath(installDir)); + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (installDir, repository)); + core->installDefaultComponentsSilently(); + + InstallIconsOperation *installIconsOp = nullptr; + OperationList operations = core->componentByName("A")->operations(); + foreach (Operation *op, operations) { + if (op->name() == QLatin1String("InstallIcons")) + installIconsOp = dynamic_cast<InstallIconsOperation *>(op); + } + QVERIFY(installIconsOp); + + // As the original directory containing icons will be deleted by the operation, + // we will use a copy with the exact same contents. + QFileInfo fakeSourceInfo(installDir + "/icons_copy/test"); + QMap<QString, QByteArray> fakeSourceMap; + VerifyInstaller::addToFileMap(QDir(fakeSourceInfo.absoluteFilePath()), fakeSourceInfo, fakeSourceMap); + + QFileInfo destinationInfo(installIconsOp->value("directory").toString() + "/test"); + QMap<QString, QByteArray> destinationMap; + VerifyInstaller::addToFileMap(QDir(destinationInfo.absoluteFilePath()), destinationInfo, destinationMap); + + QVERIFY(fakeSourceMap == destinationMap); + + core->setPackageManager(); + core->commitSessionOperations(); + core->uninstallComponentsSilently(QStringList() << "A"); + QVERIFY(!destinationInfo.exists()); + + QDir dir(installDir); + QVERIFY(dir.removeRecursively()); + } + +private slots: + void initTestCase() + { + m_testIconSourcePath = qApp->applicationDirPath() + "/icons"; + m_testIconSubdirectoryPath = m_testIconSourcePath + "/test"; + + m_testIconFilePaths.append(m_testIconSubdirectoryPath + + QDir::separator() + "vendor-icon1.png"); + m_testIconFilePaths.append(m_testIconSubdirectoryPath + + QDir::separator() + "vendor-icon2.png"); + m_testIconFilePaths.append(m_testIconSubdirectoryPath + + QDir::separator() + "vendor-icon3.png"); + } + + void testMissingArguments() + { + InstallIconsOperation op(nullptr); + + op.backup(); + QVERIFY(op.testOperation()); + QVERIFY(!op.performOperation()); + + QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::InvalidArguments); + QCOMPARE(op.errorString(), QString("Invalid arguments in InstallIcons: " + "0 arguments given, 1 or 2 arguments expected " + "in the form: <source path> [vendor prefix].")); + + op.setArguments(QStringList() << ""); + QVERIFY(!op.performOperation()); + + QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::InvalidArguments); + QCOMPARE(op.errorString(), QString("Invalid Argument: source directory must not be empty.")); + } + + void testInstallIconsFromScript() + { + installFromCLI(":///data/repository"); + } + + void testInstallIconsFromXML() + { + installFromCLI(":///data/xmloperationrepository"); + } + + void testInstallIconsWithUndo() + { + QDir testIconDir(m_testIconSourcePath); + QVERIFY(testIconDir.mkpath(m_testIconSubdirectoryPath)); + + // Populate source directory + foreach (const QString &filePath, m_testIconFilePaths) { + QFile file(filePath); + QVERIFY(file.open(QFileDevice::ReadWrite)); + file.close(); + } + + PackageManagerCore *core = new PackageManagerCore(); + InstallIconsOperation op(core); + op.setArguments(QStringList() << m_testIconSourcePath); + + QFileInfo sourceInfo(m_testIconSubdirectoryPath); + QMap<QString, QByteArray> sourceMap; + VerifyInstaller::addToFileMap(QDir(sourceInfo.absoluteFilePath()), sourceInfo, sourceMap); + + QVERIFY2(op.performOperation(), op.errorString().toLatin1()); + QVERIFY(!QFileInfo().exists(m_testIconSourcePath)); + + QFileInfo destinationInfo(op.value("directory").toString() + "/test"); + QMap<QString, QByteArray> destinationMap; + VerifyInstaller::addToFileMap(QDir(destinationInfo.absoluteFilePath()), destinationInfo, destinationMap); + + QVERIFY2(op.undoOperation(), op.errorString().toLatin1()); + QVERIFY(!QFileInfo().exists(op.value("directory").toString() + "/test")); + QVERIFY(QFileInfo().exists(m_testIconSourcePath)); + + QVERIFY(sourceMap == destinationMap); + QVERIFY(testIconDir.removeRecursively()); + + core->deleteLater(); + } + + void testChangeVendorPrefix() + { + QDir testIconDir(m_testIconSourcePath); + QVERIFY(testIconDir.mkpath(m_testIconSubdirectoryPath)); + + QFile file(m_testIconFilePaths.first()); + QVERIFY(file.open(QFileDevice::ReadWrite)); + file.close(); + + PackageManagerCore *core = new PackageManagerCore(); + InstallIconsOperation op(core); + op.setArguments(QStringList() << m_testIconSourcePath << "testVendor"); + + QVERIFY2(op.performOperation(), op.errorString().toLatin1()); + QVERIFY(!QFileInfo().exists(m_testIconSourcePath)); + QVERIFY(QFileInfo().exists(op.value("directory").toString() + "/test/testVendor-icon1.png")); + + QVERIFY2(op.undoOperation(), op.errorString().toLatin1()); + QVERIFY(!QFileInfo().exists(op.value("directory").toString() + "/test")); + QVERIFY(QFileInfo().exists(m_testIconSourcePath)); + + QVERIFY(testIconDir.removeRecursively()); + + core->deleteLater(); + } + + void testValidTargetDirectory() + { + QDir testIconDir(m_testIconSourcePath); + QVERIFY(testIconDir.mkpath(m_testIconSubdirectoryPath)); + + PackageManagerCore *core = new PackageManagerCore(); + InstallIconsOperation op(core); + op.setArguments(QStringList() << m_testIconSourcePath); + + QVERIFY2(op.performOperation(), op.errorString().toLatin1()); + QVERIFY(!QFileInfo().exists(m_testIconSourcePath)); + + QString targetIconsDirectory = op.value("directory").toString(); + QVERIFY(QFileInfo(targetIconsDirectory).exists()); + QStringList directories = QString::fromLocal8Bit(qgetenv("XDG_DATA_HOME")) + .split(QLatin1Char(':'), Qt::SkipEmptyParts); + // Default path if XDG_DATA_HOME is not set + directories.append(QDir::home().absoluteFilePath(QLatin1String(".local/share"))); + // Default path if run as root + directories.append(QLatin1String("/usr/local/share")); + bool validPath = false; + foreach (const QString &dir, directories) { + // Icon directory should be one of the expected locations + if (targetIconsDirectory == QDir(dir).absoluteFilePath("icons")) { + validPath = true; + break; + } + } + QVERIFY(validPath); + + QVERIFY2(op.undoOperation(), op.errorString().toLatin1()); + QVERIFY(!QFileInfo().exists(op.value("directory").toString() + "/test")); + + QVERIFY(testIconDir.removeRecursively()); + core->deleteLater(); + } + +private: + QString m_testIconSourcePath; + QString m_testIconSubdirectoryPath; + QStringList m_testIconFilePaths; +}; + +QTEST_MAIN(tst_installiconsoperation) + +#include "tst_installiconsoperation.moc" diff --git a/tests/auto/installer/lib7zfacade/data.qrc b/tests/auto/installer/lib7zarchive/data.qrc index d6453a9b3..d6453a9b3 100644 --- a/tests/auto/installer/lib7zfacade/data.qrc +++ b/tests/auto/installer/lib7zarchive/data.qrc diff --git a/tests/auto/installer/lib7zfacade/data/invalid.7z b/tests/auto/installer/lib7zarchive/data/invalid.7z Binary files differindex bcf81250e..bcf81250e 100644 --- a/tests/auto/installer/lib7zfacade/data/invalid.7z +++ b/tests/auto/installer/lib7zarchive/data/invalid.7z diff --git a/tests/auto/installer/lib7zfacade/data/valid.7z b/tests/auto/installer/lib7zarchive/data/valid.7z Binary files differindex e583bdf99..e583bdf99 100644 --- a/tests/auto/installer/lib7zfacade/data/valid.7z +++ b/tests/auto/installer/lib7zarchive/data/valid.7z diff --git a/tests/auto/installer/lib7zfacade/lib7zfacade.pro b/tests/auto/installer/lib7zarchive/lib7zarchive.pro index 034cf1eed..aabf724b6 100644 --- a/tests/auto/installer/lib7zfacade/lib7zfacade.pro +++ b/tests/auto/installer/lib7zarchive/lib7zarchive.pro @@ -4,4 +4,4 @@ QT -= gui QT += testlib RESOURCES += data.qrc -SOURCES = tst_lib7zfacade.cpp +SOURCES = tst_lib7zarchive.cpp diff --git a/tests/auto/installer/lib7zarchive/tst_lib7zarchive.cpp b/tests/auto/installer/lib7zarchive/tst_lib7zarchive.cpp new file mode 100644 index 000000000..a94b0f818 --- /dev/null +++ b/tests/auto/installer/lib7zarchive/tst_lib7zarchive.cpp @@ -0,0 +1,149 @@ +/************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ + +#include <lib7z_facade.h> +#include <lib7zarchive.h> +#include <fileutils.h> + +#include <QDir> +#include <QObject> +#include <QTemporaryFile> +#include <QTest> + +using namespace QInstaller; + +class tst_lib7zarchive : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase() + { + Lib7z::initSevenZ(); + + m_file.path = "valid"; + m_file.compressedSize = 836; + m_file.uncompressedSize = 5242880; + m_file.isDirectory = false; + m_file.archiveIndex = QPoint(0, 0); + m_file.utcTime = QDateTime(QDate::fromJulianDay(2456413), QTime(10, 50, 42), Qt::UTC); + } + + void testIsSupportedArchive() + { + Lib7zArchive archive(":///data/valid.7z"); + QVERIFY(archive.open(QIODevice::ReadOnly)); + QCOMPARE(archive.isSupported(), true); + archive.close(); + + archive.setFilename(":///data/invalid.7z"); + QVERIFY(archive.open(QIODevice::ReadOnly)); + QCOMPARE(archive.isSupported(), false); + } + + void testListArchive() + { + + Lib7zArchive archive(":///data/valid.7z"); + QVERIFY(archive.open(QIODevice::ReadOnly)); + + QVector<ArchiveEntry> files = archive.list(); + QCOMPARE(files.count(), 1); + QCOMPARE(files.first(), m_file); + archive.close(); + + archive.setFilename(":///data/invalid.7z"); + QVERIFY(archive.open(QIODevice::ReadOnly)); + files = archive.list(); + + QVERIFY(files.isEmpty()); + QCOMPARE(archive.errorString(), QString("Cannot open archive \":///data/invalid.7z\".")); + } + + void testCreateArchive() + { + QString path1 = tempSourceFile("Source File 1."); + QString path2 = tempSourceFile("Source File 2."); + + QString filename = generateTemporaryFileName(); + Lib7zArchive target(filename); + QVERIFY(target.open(QIODevice::ReadWrite)); + QVERIFY(target.create(QStringList() << path1 << path2)); + QCOMPARE(target.list().count(), 2); + target.close(); + QVERIFY(QFile::remove(filename)); + + + path1 = tempSourceFile( + "Source File 1.", + QDir::tempPath() + "/temp file with spaces.XXXXXX" + ); + path2 = tempSourceFile( + "Source File 2.", + QDir::tempPath() + "/temp file with spaces.XXXXXX" + ); + + filename = QDir::tempPath() + "/target file with spaces.XXXXXX"; + target.setFilename(filename); + QVERIFY(target.open(QIODevice::ReadWrite)); + QVERIFY(target.create(QStringList() << path1 << path2)); + QCOMPARE(target.list().count(), 2); + target.close(); + QVERIFY(QFile::remove(filename)); + } + + void testExtractArchive() + { + Lib7zArchive source(":///data/valid.7z"); + QVERIFY(source.open(QIODevice::ReadOnly)); + + QVERIFY(source.extract(QDir::tempPath())); + QCOMPARE(QFile::exists(QDir::tempPath() + QString("/valid")), true); + QVERIFY(QFile::remove(QDir::tempPath() + QString("/valid"))); + } + +private: + QString tempSourceFile(const QByteArray &data, const QString &templateName = QString()) + { + QTemporaryFile source; + if (!templateName.isEmpty()) { + source.setFileTemplate(templateName); + } + source.open(); + source.write(data); + source.setAutoRemove(false); + return source.fileName(); + } + +private: + ArchiveEntry m_file; +}; + +QTEST_MAIN(tst_lib7zarchive) + +#include "tst_lib7zarchive.moc" diff --git a/tests/auto/installer/lib7zfacade/tst_lib7zfacade.cpp b/tests/auto/installer/lib7zfacade/tst_lib7zfacade.cpp deleted file mode 100644 index ffc5b330a..000000000 --- a/tests/auto/installer/lib7zfacade/tst_lib7zfacade.cpp +++ /dev/null @@ -1,175 +0,0 @@ -/************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Installer Framework. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -**************************************************************************/ - -#include <lib7z_create.h> -#include <lib7z_extract.h> -#include <lib7z_facade.h> -#include <lib7z_list.h> - -#include <QDir> -#include <QObject> -#include <QTemporaryFile> -#include <QTest> - -class tst_lib7zfacade : public QObject -{ - Q_OBJECT - -private slots: - void initTestCase() - { - Lib7z::initSevenZ(); - - m_file.path = "valid"; - m_file.permissions = 0; - m_file.compressedSize = 836; - m_file.uncompressedSize = 5242880; - m_file.isDirectory = false; - m_file.archiveIndex = QPoint(0, 0); - m_file.utcTime = QDateTime(QDate::fromJulianDay(2456413), QTime(10, 50, 42), Qt::UTC); - } - - void testIsSupportedArchive() - { - QCOMPARE(Lib7z::isSupportedArchive(":///data/valid.7z"), true); - QCOMPARE(Lib7z::isSupportedArchive(":///data/invalid.7z"), false); - - try { - QFile file(":///data/valid.7z"); - QVERIFY(file.open(QIODevice::ReadOnly)); - QCOMPARE(Lib7z::isSupportedArchive(&file), true); - } catch (...) { - QFAIL("Unexpected error during Lib7z::isSupportedArchive."); - } - - try { - QFile file(":///data/invalid.7z"); - QVERIFY(file.open(QIODevice::ReadOnly)); - QCOMPARE(Lib7z::isSupportedArchive(&file), false); - } catch (...) { - QFAIL("Unexpected error during Lib7z::isSupportedArchive."); - } - } - - void testListArchive() - { - try { - QFile file(":///data/valid.7z"); - QVERIFY(file.open(QIODevice::ReadOnly)); - - QVector<Lib7z::File> files = Lib7z::listArchive(&file); - QCOMPARE(files.count(), 1); - QCOMPARE(files.first(), m_file); - } catch (...) { - QFAIL("Unexpected error during list archive."); - } - - try { - QFile file(":///data/invalid.7z"); - QVERIFY(file.open(QIODevice::ReadOnly)); - QVector<Lib7z::File> files = Lib7z::listArchive(&file); - } catch (const Lib7z::SevenZipException& e) { - QCOMPARE(e.message(), QString("Cannot open archive \":///data/invalid.7z\".")); - } catch (...) { - QFAIL("Unexpected error during list archive."); - } - } - - void testCreateArchive() - { - try { - const QString path = tempSourceFile("Source File 1."); - const QString path2 = tempSourceFile("Source File 2."); - - QTemporaryFile target; - QVERIFY(target.open()); - Lib7z::createArchive(&target, QStringList() << path << path2); - QCOMPARE(Lib7z::listArchive(&target).count(), 2); - } catch (const Lib7z::SevenZipException& e) { - QFAIL(e.message().toUtf8()); - } catch (...) { - QFAIL("Unexpected error during create archive."); - } - - try { - const QString path1 = tempSourceFile( - "Source File 1.", - QDir::tempPath() + "/temp file with spaces.XXXXXX" - ); - const QString path2 = tempSourceFile( - "Source File 2.", - QDir::tempPath() + "/temp file with spaces.XXXXXX" - ); - - QTemporaryFile target(QDir::tempPath() + "/target file with spaces.XXXXXX"); - QVERIFY(target.open()); - Lib7z::createArchive(&target, QStringList() << path1 << path2); - QCOMPARE(Lib7z::listArchive(&target).count(), 2); - } catch (const Lib7z::SevenZipException& e) { - QFAIL(e.message().toUtf8()); - } catch (...) { - QFAIL("Unexpected error during create archive."); - } - - } - - void testExtractArchive() - { - QFile source(":///data/valid.7z"); - QVERIFY(source.open(QIODevice::ReadOnly)); - - try { - Lib7z::extractArchive(&source, QDir::tempPath()); - QCOMPARE(QFile::exists(QDir::tempPath() + QString("/valid")), true); - } catch (const Lib7z::SevenZipException& e) { - QFAIL(e.message().toUtf8()); - } catch (...) { - QFAIL("Unexpected error during extract archive."); - } - } - -private: - QString tempSourceFile(const QByteArray &data, const QString &templateName = QString()) - { - QTemporaryFile source; - if (!templateName.isEmpty()) { - source.setFileTemplate(templateName); - } - source.open(); - source.write(data); - source.setAutoRemove(false); - return source.fileName(); - } - -private: - Lib7z::File m_file; -}; - -QTEST_MAIN(tst_lib7zfacade) - -#include "tst_lib7zfacade.moc" diff --git a/tests/auto/installer/libarchivearchive/data.qrc b/tests/auto/installer/libarchivearchive/data.qrc new file mode 100644 index 000000000..b3f2a1933 --- /dev/null +++ b/tests/auto/installer/libarchivearchive/data.qrc @@ -0,0 +1,10 @@ +<RCC> + <qresource prefix="/"> + <file>data/valid.zip</file> + <file>data/valid.tar.gz</file> + <file>data/valid.tar.bz2</file> + <file>data/valid.tar.xz</file> + <file>data/valid.7z</file> + <file>data/valid.qbsp</file> + </qresource> +</RCC> diff --git a/tests/auto/installer/libarchivearchive/data/valid.7z b/tests/auto/installer/libarchivearchive/data/valid.7z Binary files differnew file mode 100644 index 000000000..e583bdf99 --- /dev/null +++ b/tests/auto/installer/libarchivearchive/data/valid.7z diff --git a/tests/auto/installer/libarchivearchive/data/valid.qbsp b/tests/auto/installer/libarchivearchive/data/valid.qbsp Binary files differnew file mode 100644 index 000000000..e583bdf99 --- /dev/null +++ b/tests/auto/installer/libarchivearchive/data/valid.qbsp diff --git a/tests/auto/installer/libarchivearchive/data/valid.tar.bz2 b/tests/auto/installer/libarchivearchive/data/valid.tar.bz2 Binary files differnew file mode 100644 index 000000000..1a79b4cd4 --- /dev/null +++ b/tests/auto/installer/libarchivearchive/data/valid.tar.bz2 diff --git a/tests/auto/installer/libarchivearchive/data/valid.tar.gz b/tests/auto/installer/libarchivearchive/data/valid.tar.gz Binary files differnew file mode 100644 index 000000000..d574487d2 --- /dev/null +++ b/tests/auto/installer/libarchivearchive/data/valid.tar.gz diff --git a/tests/auto/installer/libarchivearchive/data/valid.tar.xz b/tests/auto/installer/libarchivearchive/data/valid.tar.xz Binary files differnew file mode 100644 index 000000000..4851a63b1 --- /dev/null +++ b/tests/auto/installer/libarchivearchive/data/valid.tar.xz diff --git a/tests/auto/installer/libarchivearchive/data/valid.zip b/tests/auto/installer/libarchivearchive/data/valid.zip Binary files differnew file mode 100644 index 000000000..d6923e016 --- /dev/null +++ b/tests/auto/installer/libarchivearchive/data/valid.zip diff --git a/tests/auto/installer/libarchivearchive/libarchivearchive.pro b/tests/auto/installer/libarchivearchive/libarchivearchive.pro new file mode 100644 index 000000000..ac4856ede --- /dev/null +++ b/tests/auto/installer/libarchivearchive/libarchivearchive.pro @@ -0,0 +1,7 @@ +include(../../qttest.pri) + +QT -= gui +QT += testlib + +RESOURCES += data.qrc +SOURCES = tst_libarchivearchive.cpp diff --git a/tests/auto/installer/libarchivearchive/tst_libarchivearchive.cpp b/tests/auto/installer/libarchivearchive/tst_libarchivearchive.cpp new file mode 100644 index 000000000..ab7030e2f --- /dev/null +++ b/tests/auto/installer/libarchivearchive/tst_libarchivearchive.cpp @@ -0,0 +1,338 @@ +/************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ + +#include "../shared/verifyinstaller.h" + +#include <libarchivearchive.h> +#include <fileutils.h> + +#include <QDir> +#include <QObject> +#include <QTemporaryFile> +#include <QTest> + +using namespace QInstaller; + +class tst_libarchivearchive : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase() + { + m_file.path = "valid"; + m_file.permissions_mode = 0666; + m_file.compressedSize = 0; // unused + m_file.uncompressedSize = 5242880; + m_file.isDirectory = false; + m_file.archiveIndex = QPoint(0, 0); + m_file.utcTime = QDateTime(QDate::fromJulianDay(2456413), QTime(10, 50, 42), Qt::UTC); + } + + void testIsSupportedArchive_data() + { + archiveFilenamesTestData(); + } + + void testIsSupportedArchive() + { + QFETCH(QString, filename); + + LibArchiveArchive archive(filename); + QVERIFY(archive.open(QIODevice::ReadOnly)); + QCOMPARE(archive.isSupported(), true); + } + + void testListArchive_data() + { + archiveFilenamesTestData(); + } + + void testListArchive() + { + QFETCH(QString, filename); + + LibArchiveArchive archive(filename); + QVERIFY(archive.open(QIODevice::ReadOnly)); + + QVector<ArchiveEntry> files = archive.list(); + QCOMPARE(files.count(), 1); + QCOMPARE(files.first(), m_file); + } + + void testCreateArchive_data() + { + archiveSuffixesTestData(); + } + + void testCreateArchive() + { + QFETCH(QString, suffix); + + const QString path1 = tempSourceFile("Source File 1."); + const QString path2 = tempSourceFile("Source File 2."); + + const QString filename = generateTemporaryFileName() + suffix; + LibArchiveArchive target(filename); + QVERIFY(target.open(QIODevice::WriteOnly)); + QVERIFY(target.create(QStringList() << path1 << path2)); + target.close(); + QVERIFY(target.open(QIODevice::ReadOnly)); + QCOMPARE(target.list().count(), 2); + target.close(); + QVERIFY(QFile(filename).remove()); + } + + void testCreateArchiveWithGlobPattern_data() + { + archiveSuffixesTestData(); + } + + void testCreateArchiveWithGlobPattern() + { + QFETCH(QString, suffix); + + const QString baseDir(generateTemporaryFileName(QDir::tempPath() + "/tst_libarchivearchive.XXXXXX")); + QVERIFY(QDir().mkpath(baseDir)); + + const QString path1 = tempSourceFile( + "Source File 1.", + baseDir + "/file.XXXXXX" + ); + const QString path2 = tempSourceFile( + "Source File 2.", + baseDir + "/file.XXXXXX" + ); + + const QString filename = generateTemporaryFileName() + suffix; + LibArchiveArchive target(filename); + QVERIFY(target.open(QIODevice::WriteOnly)); + QVERIFY(target.create(QStringList() << baseDir + "/*")); + target.close(); + QVERIFY(target.open(QIODevice::ReadOnly)); + QCOMPARE(target.list().count(), 2); + target.close(); + + QVERIFY(QFile(filename).remove()); + QVERIFY(QDir(baseDir).removeRecursively()); + } + + void testCreateArchiveWithSpaces_data() + { + archiveSuffixesTestData(); + } + + void testCreateArchiveWithSpaces() + { + QFETCH(QString, suffix); + + const QString path1 = tempSourceFile( + "Source File 1.", + QDir::tempPath() + "/temp file with spaces.XXXXXX" + ); + const QString path2 = tempSourceFile( + "Source File 2.", + QDir::tempPath() + "/temp file with spaces.XXXXXX" + ); + + const QString filename = QDir::tempPath() + "/target file with spaces" + suffix; + LibArchiveArchive target(filename); + target.setFilename(filename); + QVERIFY(target.open(QIODevice::WriteOnly)); + QVERIFY(target.create(QStringList() << path1 << path2)); + target.close(); + QVERIFY(target.open(QIODevice::ReadOnly)); + QCOMPARE(target.list().count(), 2); + target.close(); + QVERIFY(QFile(filename).remove()); + } + + void testExtractArchive_data() + { + archiveFilenamesTestData(); + } + + void testExtractArchive() + { + QFETCH(QString, filename); + + LibArchiveArchive source(filename); + QVERIFY(source.open(QIODevice::ReadOnly)); + + QVERIFY(source.extract(QDir::tempPath())); + QCOMPARE(QFile::exists(QDir::tempPath() + QString("/valid")), true); + QVERIFY(QFile(QDir::tempPath() + QString("/valid")).remove()); + } + + void testCreateExtractWithSymlink_data() + { + archiveSuffixesTestData(); + } + + void testCreateExtractWithSymlink() + { + QFETCH(QString, suffix); + + const QString workingDir = generateTemporaryFileName() + "/"; + const QString archiveName = workingDir + "archive" + suffix; + const QString targetName = workingDir + "target/"; +#ifdef Q_OS_WIN + const QString linkName = workingDir + "link.lnk"; +#else + const QString linkName = workingDir + "link"; +#endif + + QVERIFY(QDir().mkpath(targetName)); + + QFile source(workingDir + "file"); + QVERIFY(source.open(QIODevice::ReadWrite)); + QVERIFY(source.write("Source File")); + + // Creates a shortcut on Windows, a symbolic link on Unix + QVERIFY(QFile::link(source.fileName(), linkName)); + + LibArchiveArchive archive(archiveName); + QVERIFY(archive.open(QIODevice::WriteOnly)); + QVERIFY(archive.create(QStringList() << source.fileName() << linkName)); + QVERIFY(QFileInfo::exists(archiveName)); + archive.close(); + + QVERIFY(archive.open(QIODevice::ReadOnly)); + QVERIFY(archive.extract(targetName)); + const QString sourceFilename = QFileInfo(source.fileName()).fileName(); + const QString linkFilename = QFileInfo(linkName).fileName(); + QVERIFY(QFileInfo::exists(targetName + sourceFilename)); + QVERIFY(QFileInfo::exists(targetName + linkFilename)); + + VerifyInstaller::verifyFileContent(targetName + sourceFilename, source.readAll()); + const QString sourceFilePath = workingDir + sourceFilename; + QCOMPARE(QFile::symLinkTarget(targetName + linkFilename), sourceFilePath); + + archive.close(); + + QVERIFY(source.remove()); + QVERIFY(QFile::remove(archiveName)); + QVERIFY(QFile::remove(linkName)); + QVERIFY(QFile::remove(targetName + sourceFilename)); + QVERIFY(QFile::remove(targetName + linkFilename)); + + removeDirectory(targetName, true); + removeDirectory(workingDir, true); + } + + void testCreateExtractWithUnicodePaths_data() + { + archiveSuffixesTestData(); + } + + void testCreateExtractWithUnicodePaths() + { + QFETCH(QString, suffix); + + const QString targetName = generateTemporaryFileName() + QDir::separator(); + const QString archiveName = QDir::tempPath() + "/test_archive" + suffix; + + const QString path1 = tempSourceFile( + "Source File 1.", + QDir::tempPath() + QString::fromUtf8("/测试文件.XXXXXX") + ); + const QString path2 = tempSourceFile( + "Source File 2.", + QDir::tempPath() + QString::fromUtf8("/тестовый файл.XXXXXX") + ); + const QString path3 = tempSourceFile( + "Source File 3.", + QDir::tempPath() + QString::fromUtf8("/ملف الاختبار.XXXXXX") + ); + + LibArchiveArchive archive(archiveName); + archive.setFilename(archiveName); + QVERIFY(archive.open(QIODevice::WriteOnly)); + QVERIFY(archive.create(QStringList() << path1 << path2 << path3)); + archive.close(); + QVERIFY(archive.open(QIODevice::ReadOnly)); + QCOMPARE(archive.list().count(), 3); + + QVERIFY(archive.extract(targetName)); + + const QString targetPath1 = targetName + QFileInfo(path1).fileName(); + const QString targetPath2 = targetName + QFileInfo(path2).fileName(); + const QString targetPath3 = targetName + QFileInfo(path3).fileName(); + + QVERIFY(QFileInfo::exists(targetPath1)); + QVERIFY(QFileInfo::exists(targetPath2)); + QVERIFY(QFileInfo::exists(targetPath3)); + + archive.close(); + QVERIFY(QFile::remove(archiveName)); + QVERIFY(QDir(targetName).removeRecursively()); + } + +private: + void archiveFilenamesTestData() + { + QTest::addColumn<QString>("filename"); + QTest::newRow("ZIP archive") << ":///data/valid.zip"; + QTest::newRow("gzip compressed tar archive") << ":///data/valid.tar.gz"; + QTest::newRow("bzip2 compressed tar archive") << ":///data/valid.tar.bz2"; + QTest::newRow("xz compressed tar archive") << ":///data/valid.tar.xz"; + QTest::newRow("7zip archive") << ":///data/valid.7z"; + QTest::newRow("QBSP archive (7z)") << ":///data/valid.qbsp"; + } + + void archiveSuffixesTestData() + { + QTest::addColumn<QString>("suffix"); + QTest::newRow("ZIP archive") << ".zip"; + QTest::newRow("uncompressed tar archive") << ".tar"; + QTest::newRow("gzip compressed tar archive") << ".tar.gz"; + QTest::newRow("bzip2 compressed tar archive") << ".tar.bz2"; + QTest::newRow("xz compressed tar archive") << ".tar.xz"; + QTest::newRow("7z archive") << ".7z"; + QTest::newRow("QBSP archive") << ".qbsp"; + } + + QString tempSourceFile(const QByteArray &data, const QString &templateName = QString()) + { + QTemporaryFile source; + if (!templateName.isEmpty()) { + source.setFileTemplate(templateName); + } + source.open(); + source.write(data); + source.setAutoRemove(false); + return source.fileName(); + } + +private: + ArchiveEntry m_file; +}; + +QTEST_MAIN(tst_libarchivearchive) + +#include "tst_libarchivearchive.moc" diff --git a/tests/auto/installer/licenseagreement/data/repository/A/1.0.2-1meta.7z b/tests/auto/installer/licenseagreement/data/repository/A/1.0.2-1meta.7z Binary files differnew file mode 100644 index 000000000..d473ac487 --- /dev/null +++ b/tests/auto/installer/licenseagreement/data/repository/A/1.0.2-1meta.7z diff --git a/tests/auto/installer/licenseagreement/data/repository/Updates.xml b/tests/auto/installer/licenseagreement/data/repository/Updates.xml new file mode 100644 index 000000000..c57918162 --- /dev/null +++ b/tests/auto/installer/licenseagreement/data/repository/Updates.xml @@ -0,0 +1,17 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.2-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <SHA1>f46c677db8bc779d70d0c72fae264a321caea6f8</SHA1> + <Licenses> + <License name="GNU GENERAL PUBLIC LICENSE Version 3" file="gpl3.txt"/> + </Licenses> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/licenseagreement/licenseagreement.pro b/tests/auto/installer/licenseagreement/licenseagreement.pro new file mode 100644 index 000000000..e0d7e98d3 --- /dev/null +++ b/tests/auto/installer/licenseagreement/licenseagreement.pro @@ -0,0 +1,10 @@ +include(../../qttest.pri) + +QT -= gui +QT += testlib + +SOURCES += tst_licenseagreement.cpp + +RESOURCES += \ + settings.qrc \ + ../shared/config.qrc diff --git a/tests/auto/installer/licenseagreement/settings.qrc b/tests/auto/installer/licenseagreement/settings.qrc new file mode 100644 index 000000000..d030220ab --- /dev/null +++ b/tests/auto/installer/licenseagreement/settings.qrc @@ -0,0 +1,6 @@ +<RCC> + <qresource prefix="/"> + <file>data/repository/Updates.xml</file> + <file>data/repository/A/1.0.2-1meta.7z</file> + </qresource> +</RCC> diff --git a/tests/auto/installer/licenseagreement/tst_licenseagreement.cpp b/tests/auto/installer/licenseagreement/tst_licenseagreement.cpp new file mode 100644 index 000000000..9ba729b10 --- /dev/null +++ b/tests/auto/installer/licenseagreement/tst_licenseagreement.cpp @@ -0,0 +1,63 @@ +/************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ +#include "../shared/packagemanager.h" + +#include <packagemanagercore.h> + +#include <QFile> +#include <QTest> + +using namespace KDUpdater; +using namespace QInstaller; + +class tst_licenseagreement : public QObject +{ + Q_OBJECT + +private slots: + void testAutoAcceptFromCLI() + { + QString installDir = QInstaller::generateTemporaryFileName(); + QVERIFY(QDir().mkpath(installDir)); + PackageManagerCore *core = PackageManager::getPackageManagerWithInit + (installDir, ":///data/repository"); + + core->setAutoAcceptLicenses(); + core->installDefaultComponentsSilently(); + + QFile file(installDir + "/Licenses/gpl3.txt"); + QVERIFY(file.exists()); + QDir dir(installDir); + QVERIFY(dir.removeRecursively()); + core->deleteLater(); + } +}; + +QTEST_MAIN(tst_licenseagreement) + +#include "tst_licenseagreement.moc" diff --git a/tests/auto/installer/linereplaceoperation/data/repository/A/1.0.2-1content.7z b/tests/auto/installer/linereplaceoperation/data/repository/A/1.0.2-1content.7z Binary files differnew file mode 100644 index 000000000..8ba90b13b --- /dev/null +++ b/tests/auto/installer/linereplaceoperation/data/repository/A/1.0.2-1content.7z diff --git a/tests/auto/installer/linereplaceoperation/data/repository/A/1.0.2-1content.7z.sha1 b/tests/auto/installer/linereplaceoperation/data/repository/A/1.0.2-1content.7z.sha1 new file mode 100644 index 000000000..a5f4399b3 --- /dev/null +++ b/tests/auto/installer/linereplaceoperation/data/repository/A/1.0.2-1content.7z.sha1 @@ -0,0 +1 @@ +a0268f80fd2954271fe7d2eae584c13a6d143838
\ No newline at end of file diff --git a/tests/auto/installer/linereplaceoperation/data/repository/A/1.0.2-1meta.7z b/tests/auto/installer/linereplaceoperation/data/repository/A/1.0.2-1meta.7z Binary files differnew file mode 100644 index 000000000..d0ed97a7f --- /dev/null +++ b/tests/auto/installer/linereplaceoperation/data/repository/A/1.0.2-1meta.7z diff --git a/tests/auto/installer/linereplaceoperation/data/repository/Updates.xml b/tests/auto/installer/linereplaceoperation/data/repository/Updates.xml new file mode 100644 index 000000000..32b4e787d --- /dev/null +++ b/tests/auto/installer/linereplaceoperation/data/repository/Updates.xml @@ -0,0 +1,17 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>true</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.2-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <Script>script.qs</Script> + <UpdateFile CompressedSize="225" UncompressedSize="75" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>6d7a3e15d11a4d94b81452fc2aa18e705a01c922</SHA1> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/linereplaceoperation/data/xmloperationrepository/A/1.0.2-1content.7z b/tests/auto/installer/linereplaceoperation/data/xmloperationrepository/A/1.0.2-1content.7z Binary files differnew file mode 100644 index 000000000..8ba90b13b --- /dev/null +++ b/tests/auto/installer/linereplaceoperation/data/xmloperationrepository/A/1.0.2-1content.7z diff --git a/tests/auto/installer/linereplaceoperation/data/xmloperationrepository/A/1.0.2-1content.7z.sha1 b/tests/auto/installer/linereplaceoperation/data/xmloperationrepository/A/1.0.2-1content.7z.sha1 new file mode 100644 index 000000000..a5f4399b3 --- /dev/null +++ b/tests/auto/installer/linereplaceoperation/data/xmloperationrepository/A/1.0.2-1content.7z.sha1 @@ -0,0 +1 @@ +a0268f80fd2954271fe7d2eae584c13a6d143838
\ No newline at end of file diff --git a/tests/auto/installer/linereplaceoperation/data/xmloperationrepository/Updates.xml b/tests/auto/installer/linereplaceoperation/data/xmloperationrepository/Updates.xml new file mode 100644 index 000000000..131a2d9ff --- /dev/null +++ b/tests/auto/installer/linereplaceoperation/data/xmloperationrepository/Updates.xml @@ -0,0 +1,23 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>true</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.2-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <UpdateFile CompressedSize="225" UncompressedSize="75" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>6d7a3e15d11a4d94b81452fc2aa18e705a01c922</SHA1> + <Operations> + <Operation name="LineReplace"> + <Argument>@TargetDir@/A.txt</Argument> + <Argument>Line to replace.</Argument> + <Argument>This line was replaced.</Argument> + </Operation> + </Operations> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/linereplaceoperation/linereplaceoperation.pro b/tests/auto/installer/linereplaceoperation/linereplaceoperation.pro new file mode 100644 index 000000000..87d0c97f4 --- /dev/null +++ b/tests/auto/installer/linereplaceoperation/linereplaceoperation.pro @@ -0,0 +1,10 @@ +include(../../qttest.pri) + +QT -= gui +QT += testlib + +SOURCES += tst_linereplaceoperation.cpp + +RESOURCES += \ + settings.qrc \ + ../shared/config.qrc diff --git a/tests/auto/installer/linereplaceoperation/settings.qrc b/tests/auto/installer/linereplaceoperation/settings.qrc new file mode 100644 index 000000000..15da313dd --- /dev/null +++ b/tests/auto/installer/linereplaceoperation/settings.qrc @@ -0,0 +1,11 @@ +<RCC> + <qresource prefix="/"> + <file>data/repository/Updates.xml</file> + <file>data/repository/A/1.0.2-1content.7z</file> + <file>data/repository/A/1.0.2-1content.7z.sha1</file> + <file>data/repository/A/1.0.2-1meta.7z</file> + <file>data/xmloperationrepository/Updates.xml</file> + <file>data/xmloperationrepository/A/1.0.2-1content.7z</file> + <file>data/xmloperationrepository/A/1.0.2-1content.7z.sha1</file> + </qresource> +</RCC> diff --git a/tests/auto/installer/linereplaceoperation/tst_linereplaceoperation.cpp b/tests/auto/installer/linereplaceoperation/tst_linereplaceoperation.cpp new file mode 100644 index 000000000..5c98d7f8b --- /dev/null +++ b/tests/auto/installer/linereplaceoperation/tst_linereplaceoperation.cpp @@ -0,0 +1,153 @@ +/************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ +#include "../shared/packagemanager.h" + +#include <linereplaceoperation.h> +#include <packagemanagercore.h> + +#include <QFile> +#include <QTest> + +using namespace KDUpdater; +using namespace QInstaller; + +class tst_linereplaceoperation : public QObject +{ + Q_OBJECT + +private: + void installFromCLI(const QString &repository) + { + QString installDir = QInstaller::generateTemporaryFileName(); + QVERIFY(QDir().mkpath(installDir)); + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (installDir, repository)); + core->installDefaultComponentsSilently(); + + QFile file(installDir + QDir::separator() + "A.txt"); + QVERIFY(file.open(QIODevice::ReadOnly) | QIODevice::Text); + QTextStream stream(&file); + QCOMPARE(stream.readLine(), QLatin1String("This line was replaced.")); + QCOMPARE(stream.readLine(), QLatin1String("Another line.")); + file.close(); + QDir dir(installDir); + QVERIFY(dir.removeRecursively()); + } + +private slots: + void initTestCase() + { + m_testFilePath = qApp->applicationDirPath() + QDir::toNativeSeparators("/test"); + } + + void testMissingArguments() + { + LineReplaceOperation op(nullptr); + + op.backup(); + + QVERIFY(op.testOperation()); + QVERIFY(!op.performOperation()); + + QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::InvalidArguments); + QCOMPARE(op.errorString(), QString("Invalid arguments in LineReplace: " + "0 arguments given, exactly 3 arguments expected.")); + + op.setArguments(QStringList() << m_testFilePath << "" << "replace"); + QVERIFY(!op.performOperation()); + + QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::InvalidArguments); + QCOMPARE(op.errorString(), QString("Invalid argument in LineReplace: " + "Empty search argument is not supported.")); + + op.setArguments(QStringList() << "" << "search" << "replace"); + QTest::ignoreMessage(QtWarningMsg, "QFSFileEngine::open: No file name specified"); + QVERIFY(!op.performOperation()); + + QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::UserDefinedError); + QCOMPARE(op.errorString(), QString("Cannot open file \"\" for reading: No file name specified")); + } + + void testSearchReplace_data() + { + QTest::addColumn<QString>("source"); + QTest::addColumn<QString>("search"); + QTest::addColumn<QString>("replace"); + QTest::addColumn<QString>("expected"); + QTest::newRow("Lorem ipsum") << "Lorem ipsum dolore sit amet, consectetur adipiscing elit,\n" + "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." << "Lorem" << "Replaced" + << "Replaced\nsed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n"; + QTest::newRow(".ini syntax") << "[section]\na=x\nb=y" << "a=" << "a=y" << "[section]\na=y\nb=y\n"; + QTest::newRow(".xml syntax") << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Test>\n<Tag></Tag>\n" + "</Test>" << "<Tag></Tag>" << "<Tag>el</Tag>" << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<Test>\n<Tag>el</Tag>\n</Test>\n"; + } + + void testSearchReplace() + { + QFETCH(QString, source); + QFETCH(QString, search); + QFETCH(QString, replace); + QFETCH(QString, expected); + + QFile file(m_testFilePath); + QVERIFY(file.open(QIODevice::WriteOnly | QIODevice::Text)); + + QTextStream stream(&file); + stream << source << Qt::endl; + file.close(); + + LineReplaceOperation op(nullptr); + op.setArguments(QStringList() << m_testFilePath << search << replace); + + QVERIFY2(op.performOperation(), op.errorString().toLatin1()); + + QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text)); + QCOMPARE(stream.readAll(), expected); + + file.close(); + QVERIFY(file.remove()); + } + + void testLineReplaceFromScript() + { + installFromCLI(":///data/repository"); + } + + void testLineReplaceFromXML() + { + installFromCLI(":///data/xmloperationrepository"); + } + +private: + QString m_testFilePath; +}; + +QTEST_MAIN(tst_linereplaceoperation) + +#include "tst_linereplaceoperation.moc" diff --git a/tests/auto/installer/messageboxhandler/data/invalidhash/B/1.0.0-1content.7z b/tests/auto/installer/messageboxhandler/data/invalidhash/B/1.0.0-1content.7z Binary files differnew file mode 100644 index 000000000..4663e2b7c --- /dev/null +++ b/tests/auto/installer/messageboxhandler/data/invalidhash/B/1.0.0-1content.7z diff --git a/tests/auto/installer/messageboxhandler/data/invalidhash/B/1.0.0-1content.7z.sha1 b/tests/auto/installer/messageboxhandler/data/invalidhash/B/1.0.0-1content.7z.sha1 new file mode 100644 index 000000000..281381b97 --- /dev/null +++ b/tests/auto/installer/messageboxhandler/data/invalidhash/B/1.0.0-1content.7z.sha1 @@ -0,0 +1 @@ +1c99fe9980cb71dde6a8468c9aa09b4153bc3bff
\ No newline at end of file diff --git a/tests/auto/installer/messageboxhandler/data/invalidhash/Updates.xml b/tests/auto/installer/messageboxhandler/data/invalidhash/Updates.xml new file mode 100644 index 000000000..2dd2ca2d5 --- /dev/null +++ b/tests/auto/installer/messageboxhandler/data/invalidhash/Updates.xml @@ -0,0 +1,15 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>true</Checksum> + <PackageUpdate> + <Name>B</Name> + <DisplayName>B</DisplayName> + <Description>Example component B</Description> + <Version>1.0.0-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <UpdateFile UncompressedSize="74" OS="Any" CompressedSize="224"/> + <DownloadableArchives>content.7z</DownloadableArchives> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/messageboxhandler/data/invalidoperation/A/1.0.2-1meta.7z b/tests/auto/installer/messageboxhandler/data/invalidoperation/A/1.0.2-1meta.7z Binary files differnew file mode 100644 index 000000000..f51ed49fa --- /dev/null +++ b/tests/auto/installer/messageboxhandler/data/invalidoperation/A/1.0.2-1meta.7z diff --git a/tests/auto/installer/messageboxhandler/data/invalidoperation/Updates.xml b/tests/auto/installer/messageboxhandler/data/invalidoperation/Updates.xml new file mode 100644 index 000000000..f92211497 --- /dev/null +++ b/tests/auto/installer/messageboxhandler/data/invalidoperation/Updates.xml @@ -0,0 +1,15 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.2-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <Script>script.qs</Script> + <SHA1>c8eb49045188859100716ab084452b32fca38d5d</SHA1> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/messageboxhandler/data/messagebox/A/1.0.2-1meta.7z b/tests/auto/installer/messageboxhandler/data/messagebox/A/1.0.2-1meta.7z Binary files differnew file mode 100644 index 000000000..3c2832174 --- /dev/null +++ b/tests/auto/installer/messageboxhandler/data/messagebox/A/1.0.2-1meta.7z diff --git a/tests/auto/installer/messageboxhandler/data/messagebox/Updates.xml b/tests/auto/installer/messageboxhandler/data/messagebox/Updates.xml new file mode 100644 index 000000000..0781dcfc5 --- /dev/null +++ b/tests/auto/installer/messageboxhandler/data/messagebox/Updates.xml @@ -0,0 +1,15 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.2-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <Script>script.qs</Script> + <SHA1>ad3157ed059e3369c094e154319de1d255865de5</SHA1> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/messageboxhandler/data/missingarchive/C/1.0.0content.7z.sha1 b/tests/auto/installer/messageboxhandler/data/missingarchive/C/1.0.0content.7z.sha1 new file mode 100644 index 000000000..281381b97 --- /dev/null +++ b/tests/auto/installer/messageboxhandler/data/missingarchive/C/1.0.0content.7z.sha1 @@ -0,0 +1 @@ +1c99fe9980cb71dde6a8468c9aa09b4153bc3bff
\ No newline at end of file diff --git a/tests/auto/installer/messageboxhandler/data/missingarchive/Updates.xml b/tests/auto/installer/messageboxhandler/data/missingarchive/Updates.xml new file mode 100644 index 000000000..0c5f7e211 --- /dev/null +++ b/tests/auto/installer/messageboxhandler/data/missingarchive/Updates.xml @@ -0,0 +1,16 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>true</Checksum> + <PackageUpdate> + <Name>C</Name> + <DisplayName>C</DisplayName> + <Description>Example component C</Description> + <Version>1.0.0</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <UpdateFile CompressedSize="224" OS="Any" UncompressedSize="74"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>3c940d54a1643ae8020162797860e827f8d246ca</SHA1> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/messageboxhandler/messageboxhandler.pro b/tests/auto/installer/messageboxhandler/messageboxhandler.pro index c63b2e35b..3f42aae7b 100644 --- a/tests/auto/installer/messageboxhandler/messageboxhandler.pro +++ b/tests/auto/installer/messageboxhandler/messageboxhandler.pro @@ -1,5 +1,7 @@ include(../../qttest.pri) -QT += qml widgets - SOURCES += tst_messageboxhandler.cpp + +RESOURCES += \ + settings.qrc \ + ../shared/config.qrc diff --git a/tests/auto/installer/messageboxhandler/settings.qrc b/tests/auto/installer/messageboxhandler/settings.qrc new file mode 100644 index 000000000..2e0d88a2b --- /dev/null +++ b/tests/auto/installer/messageboxhandler/settings.qrc @@ -0,0 +1,13 @@ +<RCC> + <qresource prefix="/"> + <file>data/invalidhash/Updates.xml</file> + <file>data/invalidhash/B/1.0.0-1content.7z</file> + <file>data/invalidhash/B/1.0.0-1content.7z.sha1</file> + <file>data/invalidoperation/Updates.xml</file> + <file>data/invalidoperation/A/1.0.2-1meta.7z</file> + <file>data/missingarchive/Updates.xml</file> + <file>data/missingarchive/C/1.0.0content.7z.sha1</file> + <file>data/messagebox/Updates.xml</file> + <file>data/messagebox/A/1.0.2-1meta.7z</file> + </qresource> +</RCC> diff --git a/tests/auto/installer/messageboxhandler/tst_messageboxhandler.cpp b/tests/auto/installer/messageboxhandler/tst_messageboxhandler.cpp index dd127f626..5db79cc55 100644 --- a/tests/auto/installer/messageboxhandler/tst_messageboxhandler.cpp +++ b/tests/auto/installer/messageboxhandler/tst_messageboxhandler.cpp @@ -1,7 +1,42 @@ +/************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ + #include <messageboxhandler.h> #include <qinstallerglobal.h> #include <scriptengine.h> #include <packagemanagercore.h> +#include <component.h> +#include <utils.h> +#include <fileutils.h> +#include <binarycontent.h> +#include <packagemanagercore.h> +#include <settings.h> +#include <init.h> #include <QTest> #include <QMetaEnum> @@ -26,7 +61,15 @@ QT_END_NAMESPACE class tst_MessageBoxHandler : public QObject { Q_OBJECT -public: +private: + void setRepository(const QString &repository) { + core->cancelMetaInfoJob(); + QSet<Repository> repoList; + Repository repo = Repository::fromUserInput(repository); + repoList.insert(repo); + core->settings().setDefaultRepositories(repoList); + } + private slots: void initTestCase() { @@ -46,12 +89,22 @@ private slots: if (enumValue == QMessageBox::LastButton) break; } + + QInstaller::init(); //This will eat debug output + + core = new PackageManagerCore(BinaryContent::MagicInstallerMarker, QList<OperationBlob> (), + QString(), QString(), Protocol::DefaultAuthorizationKey, Protocol::Mode::Production, + QHash<QString, QString>(), true); + core->disableWriteMaintenanceTool(); + core->setAutoConfirmCommand(); + m_installDir = QInstaller::generateTemporaryFileName(); + QVERIFY(QDir().mkpath(m_installDir)); + core->setValue(scTargetDir, m_installDir); } void testScriptButtonValues() { - PackageManagerCore core; - ScriptEngine *scriptEngine = new ScriptEngine(&core); + ScriptEngine *scriptEngine = new ScriptEngine(core); QMapIterator<QMessageBox::StandardButton, QString> i(m_standardButtonValueMap); while (i.hasNext()) { i.next(); @@ -67,8 +120,6 @@ private slots: void testDefaultAction() { - const char ignoreMessage[] = "Created critical message box \"TestError\": \"A test error\", " - "\"This is a test error message.\""; srand(time(0)); /* initialize random seed: */ int standardButtons = QMessageBox::NoButton; @@ -82,8 +133,6 @@ private slots: // use only every 5th run to reduce the time which it takes to run this test if (iSecret > 2) continue; - - QTest::ignoreMessage(QtDebugMsg, ignoreMessage); int returnButton = MessageBoxHandler::instance()->critical(QLatin1String("TestError"), QLatin1String("A test error"), QLatin1String("This is a test error message."), static_cast<QMessageBox::StandardButton>(standardButtons)); @@ -101,11 +150,93 @@ private slots: } while (standardButtons < m_maxStandardButtons); } + void invalidOperationAutoReject() + { + setRepository(":///data/invalidoperation"); + core->autoRejectMessageBoxes(); + core->installDefaultComponentsSilently(); + QCOMPARE(PackageManagerCore::Canceled, core->status()); + } + + void invalidOperationAutoAccept() + { + setRepository(":///data/invalidoperation"); + core->autoAcceptMessageBoxes(); + core->installDefaultComponentsSilently(); + QCOMPARE(PackageManagerCore::Success, core->status()); + } + + void invalidHashAutoReject() + { + setRepository(":///data/invalidhash"); + core->autoRejectMessageBoxes(); + core->installSelectedComponentsSilently(QStringList () << "B"); + QCOMPARE(PackageManagerCore::Failure, core->status()); + } + + void invalidHashAutoAccept() + { + setRepository(":///data/invalidhash"); + core->autoAcceptMessageBoxes(); + core->installSelectedComponentsSilently(QStringList () << "B"); + QCOMPARE(PackageManagerCore::Failure, core->status()); + } + + void missingArchiveAutoReject() + { + setRepository(":///data/missingarchive"); + core->autoRejectMessageBoxes(); + core->installSelectedComponentsSilently(QStringList () << "C"); + QCOMPARE(PackageManagerCore::Canceled, core->status()); + } + + void missingArchiveAutoAccept() + { + setRepository(":///data/missingarchive"); + core->autoAcceptMessageBoxes(); + core->installSelectedComponentsSilently(QStringList () << "C"); + QCOMPARE(PackageManagerCore::Failure, core->status()); // Fails after retrying + } + + void messageBoxFromScriptDefaultAnswer() + { + setRepository(":///data/messagebox"); + core->acceptMessageBoxDefaultButton(); + core->installSelectedComponentsSilently(QStringList () << "A"); + + // These values are written in script based on default + // messagebox query results. + QCOMPARE(core->value("test.question.default.ok"), QLatin1String("Ok")); + QCOMPARE(core->value("test.question.default.cancel"), QLatin1String("Cancel")); + } + + void messageBoxFromScriptAutoAnswer() + { + setRepository(":///data/messagebox"); + core->setMessageBoxAutomaticAnswer("test.question.default.ok", QMessageBox::Cancel); + core->setMessageBoxAutomaticAnswer("test.question.default.cancel", QMessageBox::Ok); + core->installSelectedComponentsSilently(QStringList () << "A"); + + // These values are written in script based on + // messagebox query results. + QCOMPARE(core->value("test.question.default.ok"), QLatin1String("Cancel")); + QCOMPARE(core->value("test.question.default.cancel"), QLatin1String("Ok")); + } + + void cleanupTestCase() + { + core->deleteLater(); + QDir dir(m_installDir); + QVERIFY(dir.removeRecursively()); + } + private: QMap<QMessageBox::StandardButton, QString> m_standardButtonValueMap; int m_maxStandardButtons; + PackageManagerCore *core; + QString m_installDir; }; -QTEST_MAIN(tst_MessageBoxHandler) +QTEST_GUILESS_MAIN(tst_MessageBoxHandler) #include "tst_messageboxhandler.moc" diff --git a/tests/auto/installer/metadatacache/data/existing-cache/manifest.json b/tests/auto/installer/metadatacache/data/existing-cache/manifest.json new file mode 100644 index 000000000..7f30e0fc0 --- /dev/null +++ b/tests/auto/installer/metadatacache/data/existing-cache/manifest.json @@ -0,0 +1,7 @@ +{ + "items": [ + "placeholder_sha1" + ], + "type": "Metadata", + "version": "1.2.0" +} diff --git a/tests/auto/installer/metadatacache/data/existing-cache/placeholder_sha1/Updates.xml b/tests/auto/installer/metadatacache/data/existing-cache/placeholder_sha1/Updates.xml new file mode 100644 index 000000000..b0b30c9d4 --- /dev/null +++ b/tests/auto/installer/metadatacache/data/existing-cache/placeholder_sha1/Updates.xml @@ -0,0 +1,19 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>true</Checksum> + <RepositoryUpdate> + <Repository action="remove" url="../repository"/> + </RepositoryUpdate> + <PackageUpdate> + <Name>C</Name> + <DisplayName>C</DisplayName> + <Description>Example component C</Description> + <Version>1.0.0-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <UpdateFile CompressedSize="222" OS="Any" UncompressedSize="72"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>5b3939da1af492382c68388fc796837e4c36b876</SHA1> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/metadatacache/data/existing-cache/placeholder_sha1/repository.txt b/tests/auto/installer/metadatacache/data/existing-cache/placeholder_sha1/repository.txt new file mode 100644 index 000000000..7224edd52 --- /dev/null +++ b/tests/auto/installer/metadatacache/data/existing-cache/placeholder_sha1/repository.txt @@ -0,0 +1 @@ +/example-repository diff --git a/tests/auto/installer/metadatacache/data/local-temp-repository/A/example-license.txt b/tests/auto/installer/metadatacache/data/local-temp-repository/A/example-license.txt new file mode 100644 index 000000000..1ffdcc8df --- /dev/null +++ b/tests/auto/installer/metadatacache/data/local-temp-repository/A/example-license.txt @@ -0,0 +1 @@ +Example license file diff --git a/tests/auto/installer/metadatacache/data/local-temp-repository/Updates.xml b/tests/auto/installer/metadatacache/data/local-temp-repository/Updates.xml new file mode 100644 index 000000000..03e54572d --- /dev/null +++ b/tests/auto/installer/metadatacache/data/local-temp-repository/Updates.xml @@ -0,0 +1,17 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.2-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <SHA1>f46c677db8bc779d70d0c72fae264a321caea6f8</SHA1> + <Licenses> + <License name="Example license" file="example-license.txt"/> + </Licenses> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/metadatacache/metadatacache.pro b/tests/auto/installer/metadatacache/metadatacache.pro new file mode 100644 index 000000000..df1542dc7 --- /dev/null +++ b/tests/auto/installer/metadatacache/metadatacache.pro @@ -0,0 +1,8 @@ +include(../../qttest.pri) + +QT += qml + +SOURCES += tst_metadatacache.cpp + +RESOURCES += \ + settings.qrc diff --git a/tests/auto/installer/metadatacache/settings.qrc b/tests/auto/installer/metadatacache/settings.qrc new file mode 100644 index 000000000..96383fdcb --- /dev/null +++ b/tests/auto/installer/metadatacache/settings.qrc @@ -0,0 +1,9 @@ +<RCC> + <qresource prefix="/"> + <file>data/local-temp-repository/Updates.xml</file> + <file>data/local-temp-repository/A/example-license.txt</file> + <file>data/existing-cache/manifest.json</file> + <file>data/existing-cache/placeholder_sha1/repository.txt</file> + <file>data/existing-cache/placeholder_sha1/Updates.xml</file> + </qresource> +</RCC> diff --git a/tests/auto/installer/metadatacache/tst_metadatacache.cpp b/tests/auto/installer/metadatacache/tst_metadatacache.cpp new file mode 100644 index 000000000..ce97de9da --- /dev/null +++ b/tests/auto/installer/metadatacache/tst_metadatacache.cpp @@ -0,0 +1,381 @@ +/************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ + +#include "../shared/packagemanager.h" + +#include <errors.h> +#include <fileutils.h> +#include <metadatacache.h> +#include <metadata.h> +#include <repository.h> + +#include <QCryptographicHash> +#include <QDir> +#include <QFileInfo> +#include <QJsonArray> +#include <QJsonDocument> +#include <QJsonObject> +#include <QObject> +#include <QTest> + +#define QUOTE_(x) #x +#define QUOTE(x) QUOTE_(x) + +using namespace QInstaller; + +static const QByteArray scPlaceholderSha1("placeholder_sha1"); + +class tst_metadatacache : public QObject +{ + Q_OBJECT + +private: + void copyExistingCacheFromResourceTree() + { + try { + QInstaller::copyDirectoryContents(":/data/existing-cache/", m_cachePath); + + // We need to modify the test data here because the checksums of + // files may differ on Windows and Unix platforms. + QVERIFY(QDir().rename(m_cachePath + QDir::separator() + scPlaceholderSha1, + m_cachePath + QDir::separator() + m_oldMetadataItemChecksum)); + + QFile manifestFile(m_cachePath + QDir::separator() + "manifest.json"); + // The file lost the write bit after copying from resource + QInstaller::setDefaultFilePermissions(&manifestFile, QInstaller::NonExecutable); + QVERIFY2(manifestFile.open(QIODevice::ReadWrite), qPrintable(manifestFile.errorString())); + + const QByteArray manifestData = manifestFile.readAll(); + QJsonDocument manifestJsonDoc(QJsonDocument::fromJson(manifestData)); + QJsonObject docJsonObject = manifestJsonDoc.object(); + + QJsonArray itemsJsonArray; + itemsJsonArray.append(QJsonValue(QLatin1String(m_oldMetadataItemChecksum))); + + docJsonObject.insert(QLatin1String("items"), itemsJsonArray); + manifestJsonDoc.setObject(docJsonObject); + + manifestFile.seek(0); + QVERIFY(manifestFile.write(manifestJsonDoc.toJson()) != -1); + + } catch (const Error &e) { + QVERIFY2(false, QString::fromLatin1("Error while copying item to path %1: %2") + .arg(m_cachePath, e.message()).toLatin1()); + } + } + + QStringList itemsFromManifest(const QString &manifestPath) + { + QFile manifestFile(manifestPath); + if (!manifestFile.open(QIODevice::ReadOnly)) + return QStringList(); + + const QByteArray manifestData = manifestFile.readAll(); + const QJsonDocument manifestJsonDoc(QJsonDocument::fromJson(manifestData)); + const QJsonObject docJsonObject = manifestJsonDoc.object(); + const QJsonArray itemsJsonArray = docJsonObject.value(QLatin1String("items")).toArray(); + + QStringList items; + for (const auto &itemJsonValue : itemsJsonArray) + items << itemJsonValue.toString(); + + return items; + } + + QByteArray checksumFromUpdateFile(const QString &directory) + { + QFile updateFile(directory + QDir::separator() + QLatin1String("Updates.xml")); + if (!updateFile.open(QIODevice::ReadOnly)) + return QByteArray(); + + QCryptographicHash hash(QCryptographicHash::Sha1); + hash.addData(&updateFile); + return hash.result().toHex(); + } + +private slots: + void init() + { + m_cachePath = generateTemporaryFileName(); + } + + void cleanup() + { + if (QFileInfo::exists(m_cachePath)) + QInstaller::removeDirectory(m_cachePath, true); + } + + void initTestCase() + { + m_newMetadataItemChecksum = checksumFromUpdateFile(":/data/local-temp-repository"); + m_oldMetadataItemChecksum = checksumFromUpdateFile(":/data/existing-cache/" + + QLatin1String(scPlaceholderSha1)); + + QVERIFY(!m_newMetadataItemChecksum.isEmpty()); + QVERIFY(!m_oldMetadataItemChecksum.isEmpty()); + + qInstallMessageHandler(silentTestMessageHandler); + } + + void testRegisterItemToEmptyCache() + { + MetadataCache cache(m_cachePath); + Metadata *metadata = new Metadata(":/data/local-temp-repository/"); + + QVERIFY(cache.registerItem(metadata)); + metadata = cache.itemByChecksum(m_newMetadataItemChecksum); + QVERIFY(metadata); + QVERIFY(metadata->isValid()); + QVERIFY(!QFileInfo::exists(m_cachePath + "/manifest.json")); + QVERIFY(cache.sync()); + QVERIFY(itemsFromManifest(m_cachePath + "/manifest.json").contains(QLatin1String(m_newMetadataItemChecksum))); + + QVERIFY(cache.clear()); + QVERIFY(!QFileInfo::exists(m_cachePath)); + } + + void testRegisterItemToExistingCache() + { + copyExistingCacheFromResourceTree(); + + MetadataCache cache(m_cachePath); + Metadata *metadata = new Metadata(":/data/local-temp-repository/"); + QVERIFY(itemsFromManifest(m_cachePath + "/manifest.json").contains(QLatin1String(m_oldMetadataItemChecksum))); + + QVERIFY(cache.registerItem(metadata)); + metadata = cache.itemByChecksum(m_newMetadataItemChecksum); + QVERIFY(metadata); + QVERIFY(metadata->isValid()); + QVERIFY(cache.sync()); + const QStringList manifestItems = itemsFromManifest(m_cachePath + "/manifest.json"); + QVERIFY(manifestItems.contains(QLatin1String(m_oldMetadataItemChecksum))); + QVERIFY(manifestItems.contains(QLatin1String(m_newMetadataItemChecksum))); + + QVERIFY(cache.clear()); + QVERIFY(!QFileInfo::exists(m_cachePath)); + } + + void testRegisterItemFails() + { + // 1. Test fail due to invalidated cache + MetadataCache cache; + Metadata *metadata = new Metadata(":/data/local-temp-repository/"); + + QVERIFY(!cache.registerItem(metadata)); + QCOMPARE(cache.errorString(), "Cannot register item to invalidated cache."); + + delete metadata; + metadata = nullptr; + + // 2. Test fail due to null metadata + cache.setPath(m_cachePath); + cache.setType("Metadata"); + cache.setVersion(QUOTE(IFW_CACHE_FORMAT_VERSION)); + QVERIFY(cache.initialize()); + + QVERIFY(!cache.registerItem(metadata)); + QCOMPARE(cache.errorString(), "Cannot register null item."); + + // 3. Test fail due to invalid metadata + metadata = new Metadata; + QVERIFY(!cache.registerItem(metadata)); + QCOMPARE(cache.errorString(), "Cannot register invalid item with checksum "); + + // 4. Test fail due to duplicate metadata item + metadata->setPath(":/data/local-temp-repository/"); + QVERIFY(cache.registerItem(metadata)); + QVERIFY(cache.itemByChecksum(m_newMetadataItemChecksum)->isValid()); + QVERIFY(!cache.registerItem(metadata)); + QCOMPARE(cache.errorString(), QString::fromLatin1("Cannot register item with checksum " + "%1. An item with the same checksum already exists in cache.") + .arg(QString::fromLatin1(m_newMetadataItemChecksum)).toLatin1()); + + QVERIFY(cache.clear()); + QVERIFY(!QFileInfo::exists(m_cachePath)); + } + + void testInitializeExistingCache() + { + copyExistingCacheFromResourceTree(); + + MetadataCache cache(m_cachePath); + Metadata *metadata = cache.itemByChecksum(m_oldMetadataItemChecksum); + QVERIFY(metadata); + QVERIFY(metadata->isValid()); + + QVERIFY(cache.clear()); + QVERIFY(!QFileInfo::exists(m_cachePath)); + } + + void testInitializeForeignCache_data() + { + QTest::addColumn<QString>("type"); + QTest::addColumn<QString>("version"); + + QTest::newRow("Type mismatch") << "MyCacheableType" << QUOTE(IFW_CACHE_FORMAT_VERSION); + QTest::newRow("Version mismatch") << "Metadata" << "0.9.1"; + } + + void testInitializeForeignCache() + { + QFETCH(QString, type); + QFETCH(QString, version); + + copyExistingCacheFromResourceTree(); + + MetadataCache cache; + cache.setType(type); + cache.setVersion(version); + cache.setPath(m_cachePath); + QVERIFY(cache.initialize()); + + QVERIFY(cache.isValid()); + QVERIFY(!cache.itemByChecksum(m_oldMetadataItemChecksum)); + + QVERIFY(cache.clear()); + // The 'foreign' entry prevents removing the directory + QVERIFY(QFileInfo::exists(m_cachePath)); + } + + void testInitializeCacheFails() + { + MetadataCache cache; + QVERIFY(!cache.initialize()); + QCOMPARE(cache.errorString(), "Cannot initialize cache with empty path."); + } + + void testRemoveItemFromCache() + { + copyExistingCacheFromResourceTree(); + + MetadataCache cache(m_cachePath); + Metadata *metadata = cache.itemByChecksum(m_oldMetadataItemChecksum); + QVERIFY(metadata); + QVERIFY(metadata->isValid()); + QVERIFY(cache.removeItem(m_oldMetadataItemChecksum)); + + QVERIFY(cache.clear()); + QVERIFY(!QFileInfo::exists(m_cachePath)); + } + + void testRemoveItemFails() + { + copyExistingCacheFromResourceTree(); + + MetadataCache cache(m_cachePath); + QVERIFY(!cache.removeItem("12345")); + QCOMPARE(cache.errorString(), "Cannot remove item specified by checksum 12345: no such item exists."); + + QVERIFY(cache.clear()); + QVERIFY(!QFileInfo::exists(m_cachePath)); + } + + void testRetrieveItemFromCache() + { + MetadataCache cache(m_cachePath); + Metadata *metadata = new Metadata(":/data/local-temp-repository/"); + + QVERIFY(cache.registerItem(metadata)); + metadata = cache.itemByChecksum(m_newMetadataItemChecksum); + QVERIFY(metadata); + QVERIFY(metadata->isValid()); + + metadata = cache.itemByPath(metadata->path()); + QVERIFY(metadata); + QVERIFY(metadata->isValid()); + + QVERIFY(cache.clear()); + QVERIFY(!QFileInfo::exists(m_cachePath)); + } + + void testRetrieveItemFails() + { + MetadataCache cache(m_cachePath); + Metadata *metadata = new Metadata(":/data/local-temp-repository/"); + const QString metadataPath = metadata->path(); + + QVERIFY(cache.registerItem(metadata)); + QVERIFY(cache.clear()); + + QVERIFY(!cache.itemByChecksum(m_newMetadataItemChecksum)); + QVERIFY(!cache.itemByPath(metadataPath)); + QCOMPARE(cache.errorString(), "Cannot retrieve item from invalidated cache."); + + QVERIFY(!QFileInfo::exists(m_cachePath)); + } + + void testItemObsoletesOther() + { + copyExistingCacheFromResourceTree(); + + MetadataCache cache(m_cachePath); + Metadata *metadata = new Metadata(":/data/local-temp-repository/"); + + QVERIFY(cache.registerItem(metadata)); + metadata->setRepository(Repository(QUrl("file:///example-repository"), true)); + metadata->setPersistentRepositoryPath(QUrl("file:///example-repository")); + QVERIFY(metadata->isActive()); + + metadata = cache.itemByChecksum(m_newMetadataItemChecksum); + QVERIFY(metadata); + QVERIFY(metadata->isValid()); + + metadata = cache.itemByChecksum(m_oldMetadataItemChecksum); + QVERIFY(metadata); + QVERIFY(metadata->isValid()); + + Metadata *obsolete = cache.obsoleteItems().first(); + QVERIFY(!obsolete->isActive()); + QCOMPARE(obsolete->checksum(), m_oldMetadataItemChecksum); + + QVERIFY(cache.clear()); + QVERIFY(!QFileInfo::exists(m_cachePath)); + } + + void testClearCacheFails() + { + MetadataCache cache(m_cachePath); + Metadata *metadata = new Metadata(":/data/local-temp-repository/"); + + QVERIFY(cache.registerItem(metadata)); + QVERIFY(cache.clear()); + QVERIFY(!cache.clear()); + QCOMPARE(cache.errorString(), "Cannot clear invalidated cache."); + + QVERIFY(!QFileInfo::exists(m_cachePath)); + } + +private: + QString m_cachePath; + QByteArray m_newMetadataItemChecksum; + QByteArray m_oldMetadataItemChecksum; +}; + +QTEST_MAIN(tst_metadatacache) + +#include "tst_metadatacache.moc" diff --git a/tests/auto/installer/metadatajob/data/repository/C/1.0.0-1content.7z b/tests/auto/installer/metadatajob/data/repository/C/1.0.0-1content.7z Binary files differnew file mode 100644 index 000000000..7d03dca9c --- /dev/null +++ b/tests/auto/installer/metadatajob/data/repository/C/1.0.0-1content.7z diff --git a/tests/auto/installer/metadatajob/data/repository/C/1.0.0-1content.7z.sha1 b/tests/auto/installer/metadatajob/data/repository/C/1.0.0-1content.7z.sha1 new file mode 100644 index 000000000..91ead97f0 --- /dev/null +++ b/tests/auto/installer/metadatajob/data/repository/C/1.0.0-1content.7z.sha1 @@ -0,0 +1 @@ +c8b7076fabaaf6b9d27f27350c577118c24f426b
\ No newline at end of file diff --git a/tests/auto/installer/metadatajob/data/repository/C/1.0.0-1meta.7z b/tests/auto/installer/metadatajob/data/repository/C/1.0.0-1meta.7z Binary files differnew file mode 100644 index 000000000..46bae0179 --- /dev/null +++ b/tests/auto/installer/metadatajob/data/repository/C/1.0.0-1meta.7z diff --git a/tests/auto/installer/metadatajob/data/repository/Updates.xml b/tests/auto/installer/metadatajob/data/repository/Updates.xml new file mode 100644 index 000000000..17d89cda7 --- /dev/null +++ b/tests/auto/installer/metadatajob/data/repository/Updates.xml @@ -0,0 +1,16 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>true</Checksum> + <PackageUpdate> + <Name>C</Name> + <DisplayName>C</DisplayName> + <Description>Example component C</Description> + <Version>1.0.0-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <UpdateFile CompressedSize="222" OS="Any" UncompressedSize="72"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>5b3939da1af492382c68388fc796837e4c36b876</SHA1> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/metadatajob/data/repository7zInvalidMetaSha1/repository7zInvalidMetaSha1.7z b/tests/auto/installer/metadatajob/data/repository7zInvalidMetaSha1/repository7zInvalidMetaSha1.7z Binary files differnew file mode 100644 index 000000000..df1f72b51 --- /dev/null +++ b/tests/auto/installer/metadatajob/data/repository7zInvalidMetaSha1/repository7zInvalidMetaSha1.7z diff --git a/tests/auto/installer/metadatajob/data/repositoryActionAdd/A/1.0.2-1content.7z b/tests/auto/installer/metadatajob/data/repositoryActionAdd/A/1.0.2-1content.7z Binary files differnew file mode 100644 index 000000000..5a9383e7e --- /dev/null +++ b/tests/auto/installer/metadatajob/data/repositoryActionAdd/A/1.0.2-1content.7z diff --git a/tests/auto/installer/metadatajob/data/repositoryActionAdd/A/1.0.2-1content.7z.sha1 b/tests/auto/installer/metadatajob/data/repositoryActionAdd/A/1.0.2-1content.7z.sha1 new file mode 100644 index 000000000..fd0bc548c --- /dev/null +++ b/tests/auto/installer/metadatajob/data/repositoryActionAdd/A/1.0.2-1content.7z.sha1 @@ -0,0 +1 @@ +643cb71b2337d5a49d57a5bc3c636ee9b84c0802
\ No newline at end of file diff --git a/tests/auto/installer/metadatajob/data/repositoryActionAdd/A/1.0.2-1meta.7z b/tests/auto/installer/metadatajob/data/repositoryActionAdd/A/1.0.2-1meta.7z Binary files differnew file mode 100644 index 000000000..6ef0b7959 --- /dev/null +++ b/tests/auto/installer/metadatajob/data/repositoryActionAdd/A/1.0.2-1meta.7z diff --git a/tests/auto/installer/metadatajob/data/repositoryActionAdd/B/1.0.0-1content.7z b/tests/auto/installer/metadatajob/data/repositoryActionAdd/B/1.0.0-1content.7z Binary files differnew file mode 100644 index 000000000..dfe41ad15 --- /dev/null +++ b/tests/auto/installer/metadatajob/data/repositoryActionAdd/B/1.0.0-1content.7z diff --git a/tests/auto/installer/metadatajob/data/repositoryActionAdd/B/1.0.0-1content.7z.sha1 b/tests/auto/installer/metadatajob/data/repositoryActionAdd/B/1.0.0-1content.7z.sha1 new file mode 100644 index 000000000..50a632b49 --- /dev/null +++ b/tests/auto/installer/metadatajob/data/repositoryActionAdd/B/1.0.0-1content.7z.sha1 @@ -0,0 +1 @@ +c7b9ab370efe036171dda7b71cd95021747cb101
\ No newline at end of file diff --git a/tests/auto/installer/metadatajob/data/repositoryActionAdd/B/1.0.0-1meta.7z b/tests/auto/installer/metadatajob/data/repositoryActionAdd/B/1.0.0-1meta.7z Binary files differnew file mode 100644 index 000000000..12d54f94c --- /dev/null +++ b/tests/auto/installer/metadatajob/data/repositoryActionAdd/B/1.0.0-1meta.7z diff --git a/tests/auto/installer/metadatajob/data/repositoryActionAdd/Updates.xml b/tests/auto/installer/metadatajob/data/repositoryActionAdd/Updates.xml new file mode 100644 index 000000000..da842bdf7 --- /dev/null +++ b/tests/auto/installer/metadatajob/data/repositoryActionAdd/Updates.xml @@ -0,0 +1,30 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>true</Checksum> + <RepositoryUpdate> + <Repository action="add" url="../repository" displayname="Example repository"/> + </RepositoryUpdate> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.2-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <UpdateFile CompressedSize="222" OS="Any" UncompressedSize="72"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>9d54e3a5adf3563913feee8ba23a99fb80d46590</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>B</Name> + <DisplayName>B</DisplayName> + <Description>Example component B</Description> + <Version>1.0.0-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <UpdateFile CompressedSize="222" OS="Any" UncompressedSize="72"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>9170d55a6af81c1a6a63d708a4ab6ed359775cd9</SHA1> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/metadatajob/data/repositoryActionRemove/C/1.0.0-1content.7z b/tests/auto/installer/metadatajob/data/repositoryActionRemove/C/1.0.0-1content.7z Binary files differnew file mode 100644 index 000000000..7d03dca9c --- /dev/null +++ b/tests/auto/installer/metadatajob/data/repositoryActionRemove/C/1.0.0-1content.7z diff --git a/tests/auto/installer/metadatajob/data/repositoryActionRemove/C/1.0.0-1content.7z.sha1 b/tests/auto/installer/metadatajob/data/repositoryActionRemove/C/1.0.0-1content.7z.sha1 new file mode 100644 index 000000000..91ead97f0 --- /dev/null +++ b/tests/auto/installer/metadatajob/data/repositoryActionRemove/C/1.0.0-1content.7z.sha1 @@ -0,0 +1 @@ +c8b7076fabaaf6b9d27f27350c577118c24f426b
\ No newline at end of file diff --git a/tests/auto/installer/metadatajob/data/repositoryActionRemove/C/1.0.0-1meta.7z b/tests/auto/installer/metadatajob/data/repositoryActionRemove/C/1.0.0-1meta.7z Binary files differnew file mode 100644 index 000000000..46bae0179 --- /dev/null +++ b/tests/auto/installer/metadatajob/data/repositoryActionRemove/C/1.0.0-1meta.7z diff --git a/tests/auto/installer/metadatajob/data/repositoryActionRemove/Updates.xml b/tests/auto/installer/metadatajob/data/repositoryActionRemove/Updates.xml new file mode 100644 index 000000000..b0b30c9d4 --- /dev/null +++ b/tests/auto/installer/metadatajob/data/repositoryActionRemove/Updates.xml @@ -0,0 +1,19 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>true</Checksum> + <RepositoryUpdate> + <Repository action="remove" url="../repository"/> + </RepositoryUpdate> + <PackageUpdate> + <Name>C</Name> + <DisplayName>C</DisplayName> + <Description>Example component C</Description> + <Version>1.0.0-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <UpdateFile CompressedSize="222" OS="Any" UncompressedSize="72"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>5b3939da1af492382c68388fc796837e4c36b876</SHA1> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/metadatajob/data/repositoryZipped/repositoryZipped.7z b/tests/auto/installer/metadatajob/data/repositoryZipped/repositoryZipped.7z Binary files differnew file mode 100644 index 000000000..6afaae497 --- /dev/null +++ b/tests/auto/installer/metadatajob/data/repositoryZipped/repositoryZipped.7z diff --git a/tests/auto/installer/metadatajob/metadatajob.pro b/tests/auto/installer/metadatajob/metadatajob.pro new file mode 100644 index 000000000..2e4b5d2f1 --- /dev/null +++ b/tests/auto/installer/metadatajob/metadatajob.pro @@ -0,0 +1,8 @@ +include(../../qttest.pri) + +QT += qml + +SOURCES += tst_metadatajob.cpp + +RESOURCES += \ + settings.qrc diff --git a/tests/auto/installer/metadatajob/settings.qrc b/tests/auto/installer/metadatajob/settings.qrc new file mode 100644 index 000000000..5df3befd9 --- /dev/null +++ b/tests/auto/installer/metadatajob/settings.qrc @@ -0,0 +1,9 @@ +<RCC> + <qresource prefix="/"> + <file>data/repository/Updates.xml</file> + <file>data/repositoryActionAdd/Updates.xml</file> + <file>data/repositoryActionRemove/Updates.xml</file> + <file>data/repositoryZipped/repositoryZipped.7z</file> + <file>data/repository7zInvalidMetaSha1/repository7zInvalidMetaSha1.7z</file> + </qresource> +</RCC> diff --git a/tests/auto/installer/metadatajob/tst_metadatajob.cpp b/tests/auto/installer/metadatajob/tst_metadatajob.cpp new file mode 100644 index 000000000..cb974e7ad --- /dev/null +++ b/tests/auto/installer/metadatajob/tst_metadatajob.cpp @@ -0,0 +1,148 @@ +/************************************************************************** +** +** Copyright (C) 2023 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ + +#include "metadatajob.h" +#include "settings.h" + +#include <binarycontent.h> +#include <component.h> +#include <errors.h> +#include <fileutils.h> +#include <packagemanagercore.h> +#include <progresscoordinator.h> + +#include <QTest> + +using namespace QInstaller; + +class tst_MetaDataJob : public QObject +{ + Q_OBJECT + +private slots: + void testRepository() + { + PackageManagerCore core; + core.setInstaller(); + QSet<Repository> repoList; + Repository repo = Repository::fromUserInput(":///data/repository"); + repoList.insert(repo); + core.settings().setDefaultRepositories(repoList); + MetadataJob metadata; + metadata.setPackageManagerCore(&core); + metadata.start(); + metadata.waitForFinished(); + QCOMPARE(metadata.metadata().count(), 1); + } + + void testRepositoryUpdateActionAdd() + { + PackageManagerCore core; + core.setInstaller(); + QSet<Repository> repoList; + Repository repo = Repository::fromUserInput(":///data/repositoryActionAdd"); + repoList.insert(repo); + core.settings().setDefaultRepositories(repoList); + MetadataJob metadata; + metadata.setPackageManagerCore(&core); + + QTest::ignoreMessage(QtDebugMsg, "Repository to add: \"Example repository\""); + QTest::ignoreMessage(QtDebugMsg, "Repository to add: \"Example repository\""); + metadata.start(); + metadata.waitForFinished(); + QCOMPARE(metadata.metadata().count(), 2); + } + + void testRepositoryUpdateActionRemove() + { + PackageManagerCore core; + core.setInstaller(); + QSet<Repository> repoList; + Repository repo = Repository::fromUserInput(":///data/repositoryActionRemove"); + Repository repo2 = Repository::fromUserInput(":///data/repository"); + repoList.insert(repo); + repoList.insert(repo2); + core.settings().setDefaultRepositories(repoList); + MetadataJob metadata; + metadata.setPackageManagerCore(&core); + + QTest::ignoreMessage(QtDebugMsg, "Repository to remove: \"file::///data/repository\""); + QTest::ignoreMessage(QtDebugMsg, "Repository to remove: \"file::///data/repository\""); + metadata.start(); + metadata.waitForFinished(); + QCOMPARE(metadata.metadata().count(), 1); + } + + void testZippedRepository_data() + { + QTest::addColumn<QStringList>("repositories"); + QTest::addColumn<int>("metacount"); + QTest::addColumn<bool>("allowUnstable"); + + QStringList repositories; + repositories << ":///data/repositoryZipped/repositoryZipped.7z"; + QTest::newRow("7z repository") << repositories << 1 << true; + + repositories.clear(); + repositories << ":///data/repository7zInvalidMetaSha1/repository7zInvalidMetaSha1.7z"; + QTest::newRow("7z with invalid meta sha1") << repositories << 0 << true; + + repositories.clear(); + repositories << ":///data/repositoryZipped/repositoryZipped.7z" << ":///data/repository7zInvalidMetaSha1/repository7zInvalidMetaSha1.7z"; + QTest::newRow("7z with one valid repository") << repositories << 1 << true; + + repositories.clear(); + repositories << ":///data/repository7zInvalidMetaSha1/repository7zInvalidMetaSha1.7z" << ":///data/repositoryZipped/repositoryZipped.7z"; + QTest::newRow("7z with one valid repository") << repositories << 0 << false; + } + + void testZippedRepository() + { + QFETCH(QStringList, repositories); + QFETCH(int, metacount); + QFETCH(bool, allowUnstable); + + PackageManagerCore core; + core.setInstaller(); + core.setTemporaryRepositories(repositories, false, true); + core.settings().setAllowUnstableComponents(allowUnstable); + + MetadataJob metadata; + metadata.setPackageManagerCore(&core); + metadata.addDownloadType(DownloadType::CompressedPackage); + metadata.setAutoDelete(true); + metadata.start(); + metadata.waitForFinished(); + QCOMPARE(metadata.metadata().count(), metacount); + } +}; + + +QTEST_MAIN(tst_MetaDataJob) + +#include "tst_metadatajob.moc" diff --git a/tests/auto/installer/mkdiroperationtest/tst_mkdiroperationtest.cpp b/tests/auto/installer/mkdiroperationtest/tst_mkdiroperationtest.cpp index f52c27d0f..e41ba8049 100644 --- a/tests/auto/installer/mkdiroperationtest/tst_mkdiroperationtest.cpp +++ b/tests/auto/installer/mkdiroperationtest/tst_mkdiroperationtest.cpp @@ -1,6 +1,6 @@ /************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2024 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Installer Framework. @@ -60,32 +60,42 @@ private slots: QVERIFY(!op.performOperation()); QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::InvalidArguments); - QCOMPARE(op.errorString(), QString("Invalid arguments in Mkdir: " - "0 arguments given, exactly 1 arguments expected.")); - + QCOMPARE(op.errorString(), QString("Invalid arguments in Mkdir: 0 arguments given, 1 to 3 " + "arguments expected in the form: <file to remove> [UNDOOPERATION, \"\"].")); } void testCreateDirectory_data() { - QTest::addColumn<QString>("directory"); - QTest::newRow("/test") << "/test"; - QTest::newRow("/test/test") << "/test/test"; - QTest::newRow("/test/test/test") << "/test/test/test"; + QTest::addColumn<QString>("directory"); + QTest::addColumn<bool>("overrideUndo"); + QTest::newRow("/test") << "/test" << false; + QTest::newRow("/test/test") << "/test/test" << false; + QTest::newRow("/test/test/test") << "/test/test/test" << false; + QTest::newRow("no undo") << "/test" << true; } void testCreateDirectory() { QFETCH(QString, directory); + QFETCH(bool, overrideUndo); + QString path = QDir::current().path() + QDir::toNativeSeparators(directory); QVERIFY2(!QDir(path).exists(), path.toLatin1()); MkdirOperation op; op.setArguments(QStringList() << path); + if (overrideUndo) + op.setArguments(op.arguments() << QLatin1String("UNDOOPERATION")); op.backup(); QVERIFY2(op.performOperation(), op.errorString().toLatin1()); QVERIFY2(QDir(path).exists(), path.toLatin1()); QVERIFY2(op.undoOperation(), op.errorString().toLatin1()); - QVERIFY2(!QDir(path).exists(), path.toLatin1()); + if (overrideUndo) { + QVERIFY2(QDir(path).exists(), path.toLatin1()); + QVERIFY(QDir(path).removeRecursively()); + } else { + QVERIFY2(!QDir(path).exists(), path.toLatin1()); + } } void testCreateDirectory_customFile_data() diff --git a/tests/auto/installer/moveoperation/data/repository/A/1.0.2-1meta.7z b/tests/auto/installer/moveoperation/data/repository/A/1.0.2-1meta.7z Binary files differnew file mode 100644 index 000000000..bd8df91b3 --- /dev/null +++ b/tests/auto/installer/moveoperation/data/repository/A/1.0.2-1meta.7z diff --git a/tests/auto/installer/moveoperation/data/repository/Updates.xml b/tests/auto/installer/moveoperation/data/repository/Updates.xml new file mode 100644 index 000000000..5cdad4e45 --- /dev/null +++ b/tests/auto/installer/moveoperation/data/repository/Updates.xml @@ -0,0 +1,15 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.2-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <Script>script.qs</Script> + <SHA1>badc75810d399a35bae6f6b2cd8acfc1d5b1ccd2</SHA1> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/moveoperation/data/xmloperationrepository/Updates.xml b/tests/auto/installer/moveoperation/data/xmloperationrepository/Updates.xml new file mode 100644 index 000000000..6707452d8 --- /dev/null +++ b/tests/auto/installer/moveoperation/data/xmloperationrepository/Updates.xml @@ -0,0 +1,22 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.2-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <Operations> + <Operation name="Mkdir"> + <Argument>@TargetDir@/DestinationFolder</Argument> + </Operation> + <Operation name="Move"> + <Argument>@InstallerDirPath@/testFile.txt</Argument> + <Argument>@TargetDir@/DestinationFolder/testFile.txt</Argument> + </Operation> + </Operations> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/moveoperation/moveoperation.pro b/tests/auto/installer/moveoperation/moveoperation.pro new file mode 100644 index 000000000..a1195299a --- /dev/null +++ b/tests/auto/installer/moveoperation/moveoperation.pro @@ -0,0 +1,10 @@ +include(../../qttest.pri) + +QT -= gui +QT += testlib + +SOURCES = tst_moveoperation.cpp + +RESOURCES += \ + settings.qrc \ + ../shared/config.qrc diff --git a/tests/auto/installer/moveoperation/settings.qrc b/tests/auto/installer/moveoperation/settings.qrc new file mode 100644 index 000000000..04a7daf71 --- /dev/null +++ b/tests/auto/installer/moveoperation/settings.qrc @@ -0,0 +1,7 @@ +<RCC> + <qresource prefix="/"> + <file>data/repository/Updates.xml</file> + <file>data/repository/A/1.0.2-1meta.7z</file> + <file>data/xmloperationrepository/Updates.xml</file> + </qresource> +</RCC> diff --git a/tests/auto/installer/moveoperation/tst_moveoperation.cpp b/tests/auto/installer/moveoperation/tst_moveoperation.cpp new file mode 100644 index 000000000..bb391efee --- /dev/null +++ b/tests/auto/installer/moveoperation/tst_moveoperation.cpp @@ -0,0 +1,151 @@ +/************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ +#include "../shared/packagemanager.h" + +#include <updateoperations.h> +#include <packagemanagercore.h> + +#include <QTest> + +using namespace KDUpdater; +using namespace QInstaller; + +class tst_moveoperation : public QObject +{ + Q_OBJECT + +private: + void installFromCLI(const QString &repository) + { + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (m_testDirectory, repository)); + core->installDefaultComponentsSilently(); + + QFile movedFile(m_testDirectory + QDir::separator() + "DestinationFolder/testFile.txt"); + QVERIFY(movedFile.exists()); + QFile originalFile(m_sourceFile); + QVERIFY(!originalFile.exists()); + + core->setPackageManager(); + core->commitSessionOperations(); + + core->uninstallComponentsSilently(QStringList() << "A"); + + QVERIFY(!movedFile.exists()); + QVERIFY(originalFile.exists()); + } + +private slots: + void initTestCase() + { + m_testDirectory = QInstaller::generateTemporaryFileName(); + QVERIFY(QDir().mkpath(m_testDirectory)); + QVERIFY(QDir(m_testDirectory).exists()); + + QString testFile = QDir::toNativeSeparators("/testFile.txt"); + m_sourceFile = qApp->applicationDirPath() + testFile; + QFile file(m_sourceFile); + QVERIFY(file.open(QIODevice::WriteOnly)); //Generates the m_sourceFile + file.close(); + + m_destinationDirectory = m_testDirectory + QDir::toNativeSeparators("/test"); + QVERIFY(QDir().mkpath(m_destinationDirectory)); + m_destinationFile = m_destinationDirectory + QDir::toNativeSeparators(testFile); + } + + void testMissingArguments() + { + MoveOperation op; + + QVERIFY(op.testOperation()); + QVERIFY(!op.performOperation()); + + QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::InvalidArguments); + QCOMPARE(op.errorString(), QString("Invalid arguments in Move: 0 arguments given, 2 to 4 arguments " + "expected in the form: <complete source file name> <complete destination file name> [UNDOOPERATION, \"\"].")); + } + + void testMoveFile() + { + MoveOperation op; + op.setArguments(QStringList() << m_sourceFile << m_destinationFile); + op.backup(); + QVERIFY2(op.performOperation(), op.errorString().toLatin1()); + QVERIFY(!QFile::exists(m_sourceFile)); + QVERIFY(QFile::exists(m_destinationFile)); + + QVERIFY(op.undoOperation()); + QVERIFY(QFile::exists(m_sourceFile)); + QVERIFY(!QFile::exists(m_destinationFile)); + } + + void testMoveFileDestinationExists() + { + QFile file(m_destinationFile); + QVERIFY(file.open(QIODevice::WriteOnly)); //Creates the destination file + file.close(); + + MoveOperation op; + op.setArguments(QStringList() << m_sourceFile << m_destinationFile); + op.backup(); + QVERIFY2(op.performOperation(), op.errorString().toLatin1()); + QVERIFY(!QFile::exists(m_sourceFile)); + QVERIFY(QFile::exists(m_destinationFile)); + + QVERIFY(op.undoOperation()); + QVERIFY(QFile::exists(m_sourceFile)); + QVERIFY(QFile::exists(m_destinationFile)); + } + + void testMoveOperationFromScript() + { + installFromCLI(":///data/repository"); + } + + void testMoveOperationFromXML() + { + installFromCLI(":///data/xmloperationrepository"); + } + + void cleanupTestCase() + { + QDir dir(m_testDirectory); + QVERIFY(dir.removeRecursively()); + QVERIFY(QFile::remove(m_sourceFile)); + } + +private: + QString m_testDirectory; + QString m_sourceFile; + QString m_destinationDirectory; + QString m_destinationFile; +}; + +QTEST_MAIN(tst_moveoperation) + +#include "tst_moveoperation.moc" diff --git a/tests/auto/installer/packagemanagercore/installer-config/config.xml b/tests/auto/installer/packagemanagercore/installer-config/config.xml index adc24631b..5826308e1 100644 --- a/tests/auto/installer/packagemanagercore/installer-config/config.xml +++ b/tests/auto/installer/packagemanagercore/installer-config/config.xml @@ -1,5 +1,8 @@ <?xml version="1.0" encoding="utf-8"?> <Installer> - <Name>test</Name> + <Name>Unit Test Application</Name> + <Title>Unit Test Application Title</Title> <Version>1.0.0</Version> + <Publisher>The Qt Company</Publisher> + <MaintenanceToolName>UnitTestMaintenancetool</MaintenanceToolName> </Installer> diff --git a/tests/auto/installer/packagemanagercore/settings.qrc b/tests/auto/installer/packagemanagercore/settings.qrc index b25a589a3..d7dfb5ddd 100644 --- a/tests/auto/installer/packagemanagercore/settings.qrc +++ b/tests/auto/installer/packagemanagercore/settings.qrc @@ -3,3 +3,4 @@ <file>installer-config/config.xml</file> </qresource> </RCC> + diff --git a/tests/auto/installer/packagemanagercore/tst_packagemanagercore.cpp b/tests/auto/installer/packagemanagercore/tst_packagemanagercore.cpp index 67fa7e2c5..410bfb01c 100644 --- a/tests/auto/installer/packagemanagercore/tst_packagemanagercore.cpp +++ b/tests/auto/installer/packagemanagercore/tst_packagemanagercore.cpp @@ -1,6 +1,6 @@ /************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2022 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Installer Framework. @@ -32,18 +32,21 @@ #include <fileutils.h> #include <packagemanagercore.h> #include <progresscoordinator.h> +#include <init.h> +#include <settings.h> #include <QDir> #include <QFile> #include <QTemporaryFile> #include <QTest> +#include <QRegularExpression> using namespace QInstaller; class DummyComponent : public Component { public: - DummyComponent(PackageManagerCore *core) + explicit DummyComponent(PackageManagerCore *core) : Component(core) { setCheckState(Qt::Checked); @@ -257,7 +260,6 @@ private slots: root->setInstalled(); child1->setInstalled(); child2->setUninstalled(); - core.componentsToInstallNeedsRecalculation(); core.calculateComponentsToInstall(); QCOMPARE(core.requiredDiskSpace(), 250ULL); } @@ -285,33 +287,63 @@ private slots: QVERIFY(QDir().rmdir(testDirectory)); } - void testSubdirectoriesWritable() + void testCoreDataValues() { - PackageManagerCore core; - - const QString testDirectory = QInstaller::generateTemporaryFileName(); - QVERIFY(QDir().mkpath(testDirectory)); - QVERIFY(QDir(testDirectory).exists()); - - const QString testSubdirectory = testDirectory + "/" + QString::number(qrand() % 1000); - - QVERIFY(QDir().mkpath(testSubdirectory)); - QVERIFY(QDir(testSubdirectory).exists()); + QHash<QString, QString> userValues; + + PackageManagerCore *core = new PackageManagerCore(BinaryContent::MagicInstallerMarker, QList<OperationBlob> (), + QString(), QString(), Protocol::DefaultAuthorizationKey, Protocol::Mode::Production, + userValues, true); + QCOMPARE(core->value("AllUsers"), QLatin1String("")); + QCOMPARE(core->value("ProductName"), QLatin1String("Unit Test Application")); + QCOMPARE(core->value("ProductVersion"), QLatin1String("1.0.0")); + QCOMPARE(core->value("Title"), QLatin1String("Unit Test Application Title")); + QCOMPARE(core->value("RootDir"), QDir::rootPath()); + + core->deleteLater(); + core->deleteLater(); + } - // should be writable - QVERIFY(core.subdirectoriesWritable(testDirectory)); + void testOverwrittenCoreDataValues() + { + QHash<QString, QString> userValues; + userValues.insert("AllUsers", "true"); + userValues.insert("ProductName", "Overwritten ProductName"); + userValues.insert("ProductVersion", "2.0.0"); + userValues.insert("Title", "Overwritten Title"); + userValues.insert("RootDir", "Overwritten RootDir"); + + PackageManagerCore *core = new PackageManagerCore(BinaryContent::MagicInstallerMarker, QList<OperationBlob> (), + QString(), QString(), Protocol::DefaultAuthorizationKey, Protocol::Mode::Production, + userValues, true); + QCOMPARE(core->value("AllUsers"), QLatin1String("true")); + QCOMPARE(core->value("ProductName"), QLatin1String("Overwritten ProductName")); + QCOMPARE(core->value("ProductVersion"), QLatin1String("2.0.0")); + QCOMPARE(core->value("Title"), QLatin1String("Overwritten Title")); + QCOMPARE(core->value("RootDir"), QLatin1String("Overwritten RootDir")); + core->deleteLater(); + } -#if defined(Q_OS_LINUX) || defined(Q_OS_MACOS) - QFile dirDevice(testSubdirectory); - dirDevice.setPermissions(QFileDevice::ReadOwner | QFileDevice::ExeOwner); + void testToFromNativeSeparators_data() + { + QTest::addColumn<QString>("path"); + QTest::newRow("Slash separator") << "a/test/path"; + QTest::newRow("Backslash separator") << "a\\test\\path"; + QTest::newRow("Mixed separators") << "a/test\\path"; + } - // should not be writable - QVERIFY(!core.subdirectoriesWritable(testDirectory)); + void testToFromNativeSeparators() + { + QFETCH(QString, path); - dirDevice.setPermissions(QFileDevice::ReadOwner | QFileDevice::WriteOwner | QFileDevice::ExeOwner); + PackageManagerCore core; +#ifdef Q_OS_WIN + QCOMPARE(core.toNativeSeparators(path), "a\\test\\path"); + QCOMPARE(core.fromNativeSeparators(path), "a/test/path"); +#else + QCOMPARE(core.toNativeSeparators(path), path); + QCOMPARE(core.fromNativeSeparators(path), path); #endif - QVERIFY(QDir().rmdir(testSubdirectory)); - QVERIFY(QDir().rmdir(testDirectory)); } }; diff --git a/tests/auto/installer/prependfileoperation/data/repository/B/1.0.2-1content.7z b/tests/auto/installer/prependfileoperation/data/repository/B/1.0.2-1content.7z Binary files differnew file mode 100644 index 000000000..543aab656 --- /dev/null +++ b/tests/auto/installer/prependfileoperation/data/repository/B/1.0.2-1content.7z diff --git a/tests/auto/installer/prependfileoperation/data/repository/B/1.0.2-1meta.7z b/tests/auto/installer/prependfileoperation/data/repository/B/1.0.2-1meta.7z Binary files differnew file mode 100644 index 000000000..a59f269e7 --- /dev/null +++ b/tests/auto/installer/prependfileoperation/data/repository/B/1.0.2-1meta.7z diff --git a/tests/auto/installer/prependfileoperation/data/repository/Updates.xml b/tests/auto/installer/prependfileoperation/data/repository/Updates.xml new file mode 100644 index 000000000..e61d2445f --- /dev/null +++ b/tests/auto/installer/prependfileoperation/data/repository/Updates.xml @@ -0,0 +1,16 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>B</Name> + <DisplayName>A</DisplayName> + <Description>Example component B</Description> + <Version>1.0.2-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <Script>script.qs</Script> + <SHA1>750eda14d867849aeb2f47d620f6e5f32134f375</SHA1> + <DownloadableArchives>content.7z</DownloadableArchives> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/prependfileoperation/data/xmloperationrepository/C/1.0.0content.7z b/tests/auto/installer/prependfileoperation/data/xmloperationrepository/C/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..d936db354 --- /dev/null +++ b/tests/auto/installer/prependfileoperation/data/xmloperationrepository/C/1.0.0content.7z diff --git a/tests/auto/installer/prependfileoperation/data/xmloperationrepository/Updates.xml b/tests/auto/installer/prependfileoperation/data/xmloperationrepository/Updates.xml new file mode 100644 index 000000000..379fe865f --- /dev/null +++ b/tests/auto/installer/prependfileoperation/data/xmloperationrepository/Updates.xml @@ -0,0 +1,20 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <PackageUpdate> + <Name>C</Name> + <DisplayName>C</DisplayName> + <Description>Example component C</Description> + <Version>1.0.0</Version> + <ReleaseDate>2020-01-01</ReleaseDate> + <Default>true</Default> + <UpdateFile CompressedSize="224" OS="Any" UncompressedSize="74"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <Operations> + <Operation name="PrependFile"> + <Argument>@TargetDir@/C.txt</Argument> + <Argument>Prepended text: </Argument> + </Operation> + </Operations> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/prependfileoperation/prependfileoperation.pro b/tests/auto/installer/prependfileoperation/prependfileoperation.pro new file mode 100644 index 000000000..5f68385fe --- /dev/null +++ b/tests/auto/installer/prependfileoperation/prependfileoperation.pro @@ -0,0 +1,10 @@ +include(../../qttest.pri) + +QT -= gui +QT += testlib + +SOURCES += tst_prependfileoperation.cpp + +RESOURCES += \ + settings.qrc \ + ../shared/config.qrc diff --git a/tests/auto/installer/prependfileoperation/settings.qrc b/tests/auto/installer/prependfileoperation/settings.qrc new file mode 100644 index 000000000..deaeb257f --- /dev/null +++ b/tests/auto/installer/prependfileoperation/settings.qrc @@ -0,0 +1,9 @@ +<RCC> + <qresource prefix="/"> + <file>data/repository/Updates.xml</file> + <file>data/repository/B/1.0.2-1content.7z</file> + <file>data/repository/B/1.0.2-1meta.7z</file> + <file>data/xmloperationrepository/Updates.xml</file> + <file>data/xmloperationrepository/C/1.0.0content.7z</file> + </qresource> +</RCC> diff --git a/tests/auto/installer/prependfileoperation/tst_prependfileoperation.cpp b/tests/auto/installer/prependfileoperation/tst_prependfileoperation.cpp new file mode 100644 index 000000000..12f178cb4 --- /dev/null +++ b/tests/auto/installer/prependfileoperation/tst_prependfileoperation.cpp @@ -0,0 +1,180 @@ +/************************************************************************** +** +** Copyright (C) 2024 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ +#include "../shared/packagemanager.h" + +#include <updateoperations.h> +#include <packagemanagercore.h> + +#include <QFile> +#include <QTest> + +using namespace KDUpdater; +using namespace QInstaller; + +class tst_prependfileoperation : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase() + { + m_testFilePath = qApp->applicationDirPath() + QDir::toNativeSeparators("/test"); + } + + void testMissingArguments() + { + PrependFileOperation op; + + QVERIFY(op.testOperation()); + QVERIFY(!op.performOperation()); + + QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::InvalidArguments); + QCOMPARE(op.errorString(), QString("Invalid arguments in PrependFile: 0 arguments given, 2 to 4 arguments expected in the form: <filename> <text to prepend> [UNDOOPERATION, \"\"].")); + + op.setArguments(QStringList() << "" << ""); + QTest::ignoreMessage(QtWarningMsg, "QFSFileEngine::open: No file name specified"); + QVERIFY(!op.performOperation()); + + QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::UserDefinedError); + QCOMPARE(op.errorString(), QString("Cannot open file \"\" for reading: No file name specified")); + } + + void testPrependText_data() + { + QTest::addColumn<QString>("source"); + QTest::addColumn<QString>("prepend"); + QTest::addColumn<QString>("expected"); + QTest::addColumn<bool>("overrideUndo"); + QTest::newRow("newline") << "Line1\nLine2\nLine3\n" << "PrependedText" + << "PrependedTextLine1\nLine2\nLine3\n" << false; + QTest::newRow("no newline") << "dolore sit amet" << "Lorem ipsum " + << "Lorem ipsum dolore sit amet" << false; + + QTest::newRow("no undo")<< "dolore sit amet" << "Lorem ipsum " + << "Lorem ipsum dolore sit amet" << true; + } + + void testPrependText() + { + QFETCH(QString, source); + QFETCH(QString, prepend); + QFETCH(QString, expected); + QFETCH(bool, overrideUndo); + + QFile file(m_testFilePath); + QVERIFY(file.open(QIODevice::WriteOnly | QIODevice::Text)); + + QTextStream stream(&file); + stream << source << Qt::flush; + file.close(); + + PrependFileOperation *op = new PrependFileOperation(); + op->setArguments(QStringList() << m_testFilePath << prepend); + if (overrideUndo) + op->setArguments(op->arguments() << QLatin1String("UNDOOPERATION")); + + op->backup(); + QVERIFY(QFileInfo(op->value("backupOfFile").toString()).exists()); + + QVERIFY2(op->performOperation(), op->errorString().toLatin1()); + QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text)); + QCOMPARE(stream.readAll(), expected); + file.close(); + + QVERIFY2(op->undoOperation(), op->errorString().toLatin1()); + QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text)); + if (overrideUndo) + QCOMPARE(stream.readAll(), expected); + else + QCOMPARE(stream.readAll(), source); + file.close(); + + QVERIFY(file.remove()); + + QString backupFileName = op->value("backupOfFile").toString(); + delete op; + QVERIFY(!QFileInfo::exists(backupFileName)); + } + + void testPrependFromCLI_data() + { + QTest::addColumn<QString>("repository"); + QTest::addColumn<QString>("fileName"); + QTest::addColumn<QString>("componentName"); + QTest::addColumn<QString>("expected"); + + QTest::newRow("operationFromScript") + << (":///data/repository") + << ("B.txt") + << ("B") + << ("Prepended text: lorem ipsum"); + + QTest::newRow("operationFromXML") + << (":///data/xmloperationrepository") + << ("C.txt") + << ("C") + << ("Prepended text: lorem ipsum"); + } + + void testPrependFromCLI() + { + QFETCH(QString, repository); + QFETCH(QString, fileName); + QFETCH(QString, componentName); + QFETCH(QString, expected); + + QString installDir = QInstaller::generateTemporaryFileName(); + QVERIFY(QDir().mkpath(installDir)); + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (installDir, repository)); + core->installSelectedComponentsSilently(QStringList() << componentName); + + QFile file(installDir + QDir::separator() + fileName); + QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text)); + QTextStream stream(&file); + QCOMPARE(stream.readAll(), expected); + file.close(); + + core->setPackageManager(); + core->commitSessionOperations(); + // We cannot check the file contents here as it will be deleted on + // undo Extract, but at least check that the uninstallation succeeds. + QCOMPARE(PackageManagerCore::Success, core->uninstallComponentsSilently + (QStringList()<< componentName)); + + QDir dir(installDir); + QVERIFY(dir.removeRecursively()); + } + +private: + QString m_testFilePath; +}; + +QTEST_MAIN(tst_prependfileoperation) + +#include "tst_prependfileoperation.moc" diff --git a/tests/auto/installer/registerfiletypeoperation/data/repository/A/1.0.2-1content.7z b/tests/auto/installer/registerfiletypeoperation/data/repository/A/1.0.2-1content.7z Binary files differnew file mode 100644 index 000000000..8ba90b13b --- /dev/null +++ b/tests/auto/installer/registerfiletypeoperation/data/repository/A/1.0.2-1content.7z diff --git a/tests/auto/installer/registerfiletypeoperation/data/repository/A/1.0.2-1meta.7z b/tests/auto/installer/registerfiletypeoperation/data/repository/A/1.0.2-1meta.7z Binary files differnew file mode 100644 index 000000000..f3f25d357 --- /dev/null +++ b/tests/auto/installer/registerfiletypeoperation/data/repository/A/1.0.2-1meta.7z diff --git a/tests/auto/installer/registerfiletypeoperation/data/repository/Updates.xml b/tests/auto/installer/registerfiletypeoperation/data/repository/Updates.xml new file mode 100644 index 000000000..6435ae0f7 --- /dev/null +++ b/tests/auto/installer/registerfiletypeoperation/data/repository/Updates.xml @@ -0,0 +1,17 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component for RegisterFileTypeOperation</Description> + <Version>1.0.2-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <Script>script.qs</Script> + <UpdateFile CompressedSize="225" UncompressedSize="75" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>6d7a3e15d11a4d94b81452fc2aa18e705a01c922</SHA1> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/registerfiletypeoperation/registerfiletypeoperation.pro b/tests/auto/installer/registerfiletypeoperation/registerfiletypeoperation.pro index 0e541ceed..88e366b6d 100644 --- a/tests/auto/installer/registerfiletypeoperation/registerfiletypeoperation.pro +++ b/tests/auto/installer/registerfiletypeoperation/registerfiletypeoperation.pro @@ -4,3 +4,7 @@ QT -= gui QT += testlib network SOURCES = tst_registerfiletypeoperation.cpp + +RESOURCES += \ + settings.qrc \ + ..\shared\config.qrc diff --git a/tests/auto/installer/registerfiletypeoperation/settings.qrc b/tests/auto/installer/registerfiletypeoperation/settings.qrc new file mode 100644 index 000000000..10cc3c3bb --- /dev/null +++ b/tests/auto/installer/registerfiletypeoperation/settings.qrc @@ -0,0 +1,7 @@ +<RCC> + <qresource prefix="/"> + <file>data/repository/Updates.xml</file> + <file>data/repository/A/1.0.2-1content.7z</file> + <file>data/repository/A/1.0.2-1meta.7z</file> + </qresource> +</RCC> diff --git a/tests/auto/installer/registerfiletypeoperation/tst_registerfiletypeoperation.cpp b/tests/auto/installer/registerfiletypeoperation/tst_registerfiletypeoperation.cpp index 7afc372b4..2b2bfc53c 100644 --- a/tests/auto/installer/registerfiletypeoperation/tst_registerfiletypeoperation.cpp +++ b/tests/auto/installer/registerfiletypeoperation/tst_registerfiletypeoperation.cpp @@ -1,39 +1,34 @@ /************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Installer Framework. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** **************************************************************************/ +#include "../shared/packagemanager.h" -#include "init.h" -#include "registerfiletypeoperation.h" -#include "packagemanagercore.h" +#include <registerfiletypeoperation.h> +#include <packagemanagercore.h> #include <QDir> #include <QObject> @@ -41,6 +36,9 @@ #include <QFile> #include <QTextStream> #include <QSettings> +#include <QtGlobal> +#include <QRandomGenerator> + #include "qsettingswrapper.h" using namespace KDUpdater; @@ -50,15 +48,40 @@ class tst_registerfiletypeoperation : public QObject { Q_OBJECT +private: + void verifySettings() + { + QCOMPARE(m_settings->value(m_defaultKey).toString(), m_progId); + QCOMPARE(m_settings->value(m_openWithProgIdkey).toString(), QString()); + QCOMPARE(m_settings->value(m_shellKey).toString(), m_command); + QCOMPARE(m_settings->value(m_shellAppkey).toString(), m_command); + } + + void verifySettingsCleaned() + { + //Test that values have been removed after undo operation + QCOMPARE(m_settings->value(m_defaultKey).toString(), QString()); + QCOMPARE(m_settings->value(m_openWithProgIdkey).toString(), QString()); + QCOMPARE(m_settings->value(m_shellKey).toString(), QString()); + QCOMPARE(m_settings->value(m_shellAppkey).toString(), QString()); + } + + void clearSettings() + { + m_settings->setValue(m_defaultKey, QString()); + m_settings->setValue(m_openWithProgIdkey, QString()); + m_settings->setValue(m_shellKey, QString()); + m_settings->setValue(m_shellAppkey, QString()); + } + private slots: void initTestCase() { QInstaller::init(); QString randomString = ""; const QString possible = "abcdefghijklmnopqrstuvwxyz0123456789"; - qsrand(QTime::currentTime().msec()); for (int i = 0; i < 5; i++) { - int index = qrand() % possible.length(); + int index = QRandomGenerator::global()->generate() % possible.length(); QChar nextChar = possible.at(index); randomString.append(nextChar); @@ -67,7 +90,22 @@ private slots: m_command = m_core.environmentVariable("SystemRoot") + "\\notepad.exe"; m_progId = "QtProject.QtInstallerFramework." + m_fileType; + qputenv("ifw_random_filetype", m_fileType.toUtf8()); + qputenv("ifw_random_programid", m_progId.toUtf8()); + + const QString settingsPath = QString::fromLatin1("HKEY_CURRENT_USER\\Software\\Classes\\"); + m_settings = new QSettings(settingsPath, QSettings::NativeFormat); + m_defaultKey = "." + m_fileType + "/Default"; + m_openWithProgIdkey = "." + m_fileType + "/OpenWithProgIds/" + m_progId; + m_shellKey = m_progId + "/shell/Open/Command/Default/"; + m_shellAppkey = "/Applications/" + m_progId + "/shell/Open/Command/Default/"; + } + void cleanupTestCase() + { + qunsetenv("ifw_random_filetype"); + qunsetenv("ifw_random_programid"); + delete m_settings; } void testMissingArguments() @@ -87,31 +125,48 @@ private slots: RegisterFileTypeOperation op(&m_core); op.setArguments(QStringList() << m_fileType << m_command << "test filetype" << "text/plain" << 0 << "ProgId="+m_progId); - - const QString settingsPath = QString::fromLatin1("HKEY_CURRENT_USER\\Software\\Classes\\"); - QSettings settings(settingsPath, QSettings::NativeFormat); - - QVERIFY(op.testOperation()); QVERIFY(op.performOperation()); - QString defaultKey = "."+m_fileType+ "/Default"; - QString openWithProgIdkey = "." + m_fileType + "/OpenWithProgIds/" +m_progId; - QString shellKey = m_progId + "/shell/Open/Command/Default/"; - QString shellAppkey = "/Applications/" + m_progId + "/shell/Open/Command/Default/"; + verifySettings(); + QVERIFY(op.undoOperation()); + verifySettingsCleaned(); + } - QCOMPARE(settings.value(defaultKey).toString(), m_progId); - QCOMPARE(settings.value(openWithProgIdkey).toString(), QString()); - QCOMPARE(settings.value(shellKey).toString(), m_command); - QCOMPARE(settings.value(shellAppkey).toString(), m_command); + void testRegisterFileTypeNoUndo() + { + RegisterFileTypeOperation op(&m_core); + op.setArguments(QStringList() << m_fileType << m_command << "test filetype" << + "text/plain" << 0 << "ProgId="+m_progId << "UNDOOPERATION" << ""); + QVERIFY(op.testOperation()); + QVERIFY(op.performOperation()); + verifySettings(); QVERIFY(op.undoOperation()); + verifySettings(); - //Test that values have been removed after undo operation - QCOMPARE(settings.value(defaultKey).toString(), QString()); - QCOMPARE(settings.value(openWithProgIdkey).toString(), QString()); - QCOMPARE(settings.value(shellKey).toString(), QString()); - QCOMPARE(settings.value(shellAppkey).toString(), QString()); + //Clear so it does not pollute settings + clearSettings(); + } + + void testPerformingFromCLI() + { + QString installDir = QInstaller::generateTemporaryFileName(); + QVERIFY(QDir().mkpath(installDir)); + PackageManagerCore *core = PackageManager::getPackageManagerWithInit + (installDir, ":///data/repository"); + + core->installDefaultComponentsSilently(); + verifySettings(); + + core->commitSessionOperations(); + core->setPackageManager(); + core->uninstallComponentsSilently(QStringList() << "A"); + verifySettingsCleaned(); + + QDir dir(installDir); + QVERIFY(dir.removeRecursively()); + core->deleteLater(); } private: @@ -119,6 +174,11 @@ private: QString m_command; QString m_progId; PackageManagerCore m_core; + QSettings *m_settings; + QString m_defaultKey = "."+m_fileType+ "/Default"; + QString m_openWithProgIdkey = "." + m_fileType + "/OpenWithProgIds/" +m_progId; + QString m_shellKey = m_progId + "/shell/Open/Command/Default/"; + QString m_shellAppkey = "/Applications/" + m_progId + "/shell/Open/Command/Default/"; }; QTEST_MAIN(tst_registerfiletypeoperation) diff --git a/tests/auto/installer/replaceoperation/data/repository/A/1.0.2-1content.7z b/tests/auto/installer/replaceoperation/data/repository/A/1.0.2-1content.7z Binary files differnew file mode 100644 index 000000000..8ba90b13b --- /dev/null +++ b/tests/auto/installer/replaceoperation/data/repository/A/1.0.2-1content.7z diff --git a/tests/auto/installer/replaceoperation/data/repository/A/1.0.2-1meta.7z b/tests/auto/installer/replaceoperation/data/repository/A/1.0.2-1meta.7z Binary files differnew file mode 100644 index 000000000..b50c31cbd --- /dev/null +++ b/tests/auto/installer/replaceoperation/data/repository/A/1.0.2-1meta.7z diff --git a/tests/auto/installer/replaceoperation/data/repository/Updates.xml b/tests/auto/installer/replaceoperation/data/repository/Updates.xml new file mode 100644 index 000000000..7585b57a4 --- /dev/null +++ b/tests/auto/installer/replaceoperation/data/repository/Updates.xml @@ -0,0 +1,17 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.2-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <Script>script.qs</Script> + <SHA1>edb7672270729f9d34396cb70e6afd12fec90d2b</SHA1> + <UpdateFile CompressedSize="225" UncompressedSize="75" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/replaceoperation/replaceoperation.pro b/tests/auto/installer/replaceoperation/replaceoperation.pro index d2756d153..2334fd661 100644 --- a/tests/auto/installer/replaceoperation/replaceoperation.pro +++ b/tests/auto/installer/replaceoperation/replaceoperation.pro @@ -4,3 +4,7 @@ QT -= gui QT += testlib SOURCES += tst_replaceoperation.cpp + +RESOURCES += \ + settings.qrc \ + ../shared/config.qrc diff --git a/tests/auto/installer/replaceoperation/settings.qrc b/tests/auto/installer/replaceoperation/settings.qrc new file mode 100644 index 000000000..10cc3c3bb --- /dev/null +++ b/tests/auto/installer/replaceoperation/settings.qrc @@ -0,0 +1,7 @@ +<RCC> + <qresource prefix="/"> + <file>data/repository/Updates.xml</file> + <file>data/repository/A/1.0.2-1content.7z</file> + <file>data/repository/A/1.0.2-1meta.7z</file> + </qresource> +</RCC> diff --git a/tests/auto/installer/replaceoperation/tst_replaceoperation.cpp b/tests/auto/installer/replaceoperation/tst_replaceoperation.cpp index 9afd91875..488a14dd1 100644 --- a/tests/auto/installer/replaceoperation/tst_replaceoperation.cpp +++ b/tests/auto/installer/replaceoperation/tst_replaceoperation.cpp @@ -1,6 +1,6 @@ /************************************************************************** ** -** Copyright (C) 2019 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Installer Framework. @@ -25,15 +25,16 @@ ** $QT_END_LICENSE$ ** **************************************************************************/ +#include "../shared/packagemanager.h" #include <fileutils.h> #include <replaceoperation.h> -#include <qinstallerglobal.h> +#include <packagemanagercore.h> -#include <QObject> #include <QDir> #include <QFile> #include <QTest> +#include <QRandomGenerator> using namespace KDUpdater; using namespace QInstaller; @@ -46,7 +47,7 @@ private slots: void initTestCase() { m_testDirectory = QInstaller::generateTemporaryFileName(); - m_testFilePath = m_testDirectory + "/test." + QString::number(qrand() % 1000); + m_testFilePath = m_testDirectory + "/test." + QString::number(QRandomGenerator::global()->generate() % 1000); } void testWrongArguments() @@ -102,7 +103,7 @@ private slots: QTextStream stream(&file); stream << "Lorem ipsum dolore sit amet, consectetur adipiscing elit, sed do eiusmod " - "tempor incididunt ut labore et dolore magna aliqua." << endl; + "tempor incididunt ut labore et dolore magna aliqua." << Qt::endl; file.close(); ReplaceOperation searchReplaceOperation(nullptr); @@ -138,7 +139,7 @@ private slots: QTextStream stream(&file); stream << "one | 10/10/2010 | three | 1.2345 | 0.00001 " - "| 7 | A <i>bon mot</i>." << endl; + "| 7 | A <i>bon mot</i>." << Qt::endl; file.close(); ReplaceOperation searchReplaceOperation(nullptr); @@ -174,6 +175,25 @@ private slots: QVERIFY(QDir().rmdir(m_testDirectory)); } + void testPerformingFromCLI() + { + QVERIFY(QDir().mkpath(m_testDirectory)); + PackageManagerCore *core = PackageManager::getPackageManagerWithInit + (m_testDirectory, ":///data/repository"); + + core->installDefaultComponentsSilently(); + + QFile file(m_testDirectory + QDir::separator() + "A.txt"); + QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text)); + QTextStream stream(&file); + QCOMPARE(stream.readLine(), QLatin1String("text to replace.")); + QCOMPARE(stream.readLine(), QLatin1String("Another text.")); + file.close(); + QDir dir(m_testDirectory); + QVERIFY(dir.removeRecursively()); + core->deleteLater(); + } + private: QString m_testDirectory; QString m_testFilePath; diff --git a/tests/auto/installer/repository/data/compressedRepository/compressedRepository.7z b/tests/auto/installer/repository/data/compressedRepository/compressedRepository.7z Binary files differnew file mode 100644 index 000000000..335685bb0 --- /dev/null +++ b/tests/auto/installer/repository/data/compressedRepository/compressedRepository.7z diff --git a/tests/auto/installer/repository/data/repository/A/1.0.2content.7z b/tests/auto/installer/repository/data/repository/A/1.0.2content.7z Binary files differnew file mode 100644 index 000000000..5531e9072 --- /dev/null +++ b/tests/auto/installer/repository/data/repository/A/1.0.2content.7z diff --git a/tests/auto/installer/repository/data/repository/A/1.0.2meta.7z b/tests/auto/installer/repository/data/repository/A/1.0.2meta.7z Binary files differnew file mode 100644 index 000000000..6631280a7 --- /dev/null +++ b/tests/auto/installer/repository/data/repository/A/1.0.2meta.7z diff --git a/tests/auto/installer/repository/data/repository/B/1.0.0meta.7z b/tests/auto/installer/repository/data/repository/B/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..16f3a6c42 --- /dev/null +++ b/tests/auto/installer/repository/data/repository/B/1.0.0meta.7z diff --git a/tests/auto/installer/repository/data/repository/C/1.0.0meta.7z b/tests/auto/installer/repository/data/repository/C/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..37c8fffc4 --- /dev/null +++ b/tests/auto/installer/repository/data/repository/C/1.0.0meta.7z diff --git a/tests/auto/installer/repository/data/repository/Updates.xml b/tests/auto/installer/repository/data/repository/Updates.xml new file mode 100644 index 000000000..f541882c5 --- /dev/null +++ b/tests/auto/installer/repository/data/repository/Updates.xml @@ -0,0 +1,33 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.2</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>false</Default> + <DownloadableArchives>content.7z</DownloadableArchives> + <Script postLoad="true">script.qs</Script> + </PackageUpdate> + <PackageUpdate> + <Name>B</Name> + <DisplayName>B</DisplayName> + <Description>Example component B</Description> + <Version>1.0.0</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>false</Default> + <Script>script.qs</Script> + </PackageUpdate> + <PackageUpdate> + <Name>C</Name> + <DisplayName>C</DisplayName> + <Description>Example component C</Description> + <Version>1.0.0</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>false</Default> + <Script postLoad="false">script.qs</Script> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/repository/repository.pro b/tests/auto/installer/repository/repository.pro index 2d192eeaa..7603177b1 100644 --- a/tests/auto/installer/repository/repository.pro +++ b/tests/auto/installer/repository/repository.pro @@ -4,3 +4,7 @@ QT += network QT -= gui SOURCES += tst_repository.cpp + +RESOURCES += \ + settings.qrc \ + ../shared/config.qrc diff --git a/tests/auto/installer/repository/settings.qrc b/tests/auto/installer/repository/settings.qrc new file mode 100644 index 000000000..92db7e3e1 --- /dev/null +++ b/tests/auto/installer/repository/settings.qrc @@ -0,0 +1,10 @@ +<RCC> + <qresource prefix="/"> + <file>data/repository/Updates.xml</file> + <file>data/repository/A/1.0.2content.7z</file> + <file>data/repository/A/1.0.2meta.7z</file> + <file>data/repository/B/1.0.0meta.7z</file> + <file>data/repository/C/1.0.0meta.7z</file> + <file>data/compressedRepository/compressedRepository.7z</file> + </qresource> +</RCC> diff --git a/tests/auto/installer/repository/tst_repository.cpp b/tests/auto/installer/repository/tst_repository.cpp index 7b8405baf..112098130 100644 --- a/tests/auto/installer/repository/tst_repository.cpp +++ b/tests/auto/installer/repository/tst_repository.cpp @@ -1,3 +1,34 @@ +/************************************************************************** +** +** Copyright (C) 2023 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ + +#include "../shared/packagemanager.h" +#include "../shared/verifyinstaller.h" + #include "repository.h" #include "repositorycategory.h" #include "settings.h" @@ -8,6 +39,8 @@ using namespace QInstaller; +typedef QList<QPair<QString, QString>> SettingsPairList; + class tst_Repository : public QObject { Q_OBJECT @@ -137,7 +170,7 @@ private slots: categories.insert(category); settings.setRepositoryCategories(categories); - QHash<QString, QPair<Repository, Repository>> update; + QMultiHash<QString, QPair<Repository, Repository>> update; // non-empty update update.insert(QLatin1String("replace"), qMakePair(original, replacement)); @@ -161,6 +194,120 @@ private slots: update.insert(QLatin1String("replace"), qMakePair(nonMatching, replacement)); QVERIFY(settings.updateRepositoryCategories(update) == Settings::NoUpdatesApplied); } + + void testCompressedRepositoryWithPriority() + { + // Compressed repository has higher priority than normal repository. + // If the versions match, compressed repository is used instead of normal repository. + QString installDir = QInstaller::generateTemporaryFileName(); + QVERIFY(QDir().mkpath(installDir)); + + PackageManagerCore *core = PackageManager::getPackageManagerWithInit(installDir, ":///data/repository"); + core->setTemporaryRepositories(QStringList() + << ":///data/compressedRepository/compressedRepository.7z", false, true); + core->installSelectedComponentsSilently(QStringList() << "A"); + VerifyInstaller::verifyFileExistence(installDir, QStringList() << "components.xml" << "A_from_compressed.txt"); + + QDir dir(installDir); + QVERIFY(dir.removeRecursively()); + core->deleteLater(); + } + + void testPostLoadScriptFromRepository_data() + { + QTest::addColumn<QStringList>("installComponent"); + QTest::addColumn<bool>("repositoryPostLoadSetting"); + QTest::addColumn<SettingsPairList>("expectedSettingsBeforeInstall"); + QTest::addColumn<SettingsPairList>("expectedSettingsAfterInstall"); + QTest::addColumn<QStringList>("unexpectedSettings"); + + // component A has postLoad = true in component.xml + // component B has no postLoad attribute + // component C has postLoad = false in component.xml + + SettingsPairList expectedSettingsListAfterInstall; + expectedSettingsListAfterInstall.append(QPair<QString, QString>("componentAKey", "componentAValue")); + + SettingsPairList expectedSettingsListBeforeInstall; + expectedSettingsListBeforeInstall.append(QPair<QString, QString>("componentBKey", "componentBValue")); + expectedSettingsListBeforeInstall.append(QPair<QString, QString>("componentCKey", "componentCValue")); + + QTest::newRow("noRepoPostLoadComponentA") + << (QStringList() << "A") + << false + << expectedSettingsListBeforeInstall + << expectedSettingsListAfterInstall + << (QStringList()); + + // Component B is installed so values from component A and component C should not be set + expectedSettingsListAfterInstall.clear(); + expectedSettingsListAfterInstall.append(QPair<QString, QString>("componentBKey", "componentBValue")); + QTest::newRow("noRepoPostLoadComponentB") + << (QStringList() << "B") + << false + << expectedSettingsListBeforeInstall + << expectedSettingsListAfterInstall + << (QStringList() << "componentAValue" << "componentCValue"); + + // PostLoad is set to whole repository. Since only A is installed, + // values from component B and component C values are not set + expectedSettingsListBeforeInstall.clear(); + expectedSettingsListAfterInstall.clear(); + expectedSettingsListAfterInstall.append(QPair<QString, QString>("componentAKey", "componentAValue")); + QTest::newRow("repoPostLoadComponentA") << (QStringList() << "A") + << true + << expectedSettingsListBeforeInstall + << expectedSettingsListAfterInstall + << (QStringList() << "componentBValue" << "componentCValue"); + + // PostLoad is set to whole repository. Since only B is installed, + // values from component C and component A are not set. + expectedSettingsListAfterInstall.clear(); + expectedSettingsListAfterInstall.append(QPair<QString, QString>("componentBKey", "componentBValue")); + QTest::newRow("repoPostLoadComponentB") << (QStringList() << "B") + << true + << expectedSettingsListBeforeInstall + << expectedSettingsListAfterInstall + << (QStringList() << "componentCValue" << "componentAValue"); + + // PostLoad is set to whole repository. Since component C has its postload = false, + // value is set to component C before install + expectedSettingsListBeforeInstall.clear(); + expectedSettingsListAfterInstall.clear(); + expectedSettingsListBeforeInstall.append(QPair<QString, QString>("componentCKey", "componentCValue")); + QTest::newRow("repoPostLoadComponentC") << (QStringList() << "C") + << true + << expectedSettingsListBeforeInstall + << expectedSettingsListAfterInstall + << (QStringList() << "componentAValue" << "componentBValue"); + } + + void testPostLoadScriptFromRepository() + { + QFETCH(QStringList, installComponent); + QFETCH(bool, repositoryPostLoadSetting); + QFETCH(SettingsPairList, expectedSettingsBeforeInstall); + QFETCH(SettingsPairList, expectedSettingsAfterInstall); + QFETCH(QStringList, unexpectedSettings); + + QString installDir = QInstaller::generateTemporaryFileName(); + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit(installDir)); + QSet<Repository> repoList; + Repository repo = Repository::fromUserInput(":///data/repository"); + repo.setPostLoadComponentScript(repositoryPostLoadSetting); + repoList.insert(repo); + core->settings().setDefaultRepositories(repoList); + QVERIFY(core->fetchRemotePackagesTree()); + + for (const QPair<QString, QString> settingValue : expectedSettingsBeforeInstall) + QCOMPARE(core->value(settingValue.first), settingValue.second); + + core->installSelectedComponentsSilently(installComponent); + for (const QPair<QString, QString> settingValue : expectedSettingsAfterInstall) + QCOMPARE(core->value(settingValue.first), settingValue.second); + for (const QString unexpectedSetting : unexpectedSettings) + QVERIFY2(!core->containsValue(unexpectedSetting), "Core contains unexpected value"); + } }; QTEST_MAIN(tst_Repository) diff --git a/tests/auto/installer/rmdiroperationtest/rmdiroperationtest.pro b/tests/auto/installer/rmdiroperationtest/rmdiroperationtest.pro new file mode 100644 index 000000000..72e61ad80 --- /dev/null +++ b/tests/auto/installer/rmdiroperationtest/rmdiroperationtest.pro @@ -0,0 +1,6 @@ +include(../../qttest.pri) + +QT -= gui +QT += testlib + +SOURCES = tst_rmdiroperationtest.cpp diff --git a/tests/auto/installer/rmdiroperationtest/tst_rmdiroperationtest.cpp b/tests/auto/installer/rmdiroperationtest/tst_rmdiroperationtest.cpp new file mode 100644 index 000000000..bfdd5921e --- /dev/null +++ b/tests/auto/installer/rmdiroperationtest/tst_rmdiroperationtest.cpp @@ -0,0 +1,111 @@ +/************************************************************************** +** +** Copyright (C) 2024 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ + +#include "init.h" +#include "updateoperations.h" + +#include <QDir> +#include <QObject> +#include <QTest> +#include <QFile> +#include <QTextStream> + +using namespace KDUpdater; +using namespace QInstaller; + +class tst_rmdiroperationtest : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase() + { + QInstaller::init(); + QString path = QDir::current().path() + QDir::toNativeSeparators("/test"); + if (QDir(path).exists()) { + QFAIL("Remove test folder first!"); + } + } + + void testMissingArguments() + { + RmdirOperation op; + + QVERIFY(op.testOperation()); + QVERIFY(!op.performOperation()); + + QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::InvalidArguments); + QCOMPARE(op.errorString(), QLatin1String("Invalid arguments in Rmdir: 0 arguments given, 1 to 3 " + "arguments expected in the form: <file to remove> [UNDOOPERATION, \"\"].")); + } + + void testRemoveDirectory_data() + { + QTest::addColumn<QString>("directory"); + QTest::addColumn<bool>("overrideUndo"); + QTest::newRow("/test") << "/test" << false; + QTest::newRow("/test/test") << "/test/test" << false; + QTest::newRow("/test/test/test") << "/test/test/test" << false; + QTest::newRow("no undo") << "/test/test/test/test" << true; + } + + void testRemoveDirectory() + { + QFETCH(QString, directory); + QFETCH(bool, overrideUndo); + + QString path = QDir::current().path() + QDir::toNativeSeparators(directory); + //Create first the directories utilizing MkdirOperation + MkdirOperation op; + op.setArguments(QStringList() << path); + op.setArguments(op.arguments() << QLatin1String("UNDOOPERATION")); + op.backup(); + QVERIFY2(op.performOperation(), op.errorString().toLatin1()); + QVERIFY2(QDir(path).exists(), path.toLatin1()); + + RmdirOperation rmOp; + rmOp.setArguments(QStringList() << path); + if (overrideUndo) + rmOp.setArguments(op.arguments() << QLatin1String("UNDOOPERATION")); + rmOp.backup(); + rmOp.performOperation(); + QVERIFY2(!QDir(path).exists(), path.toLatin1()); + + QVERIFY2(rmOp.undoOperation(), rmOp.errorString().toLatin1()); + if (overrideUndo) { + QVERIFY2(!QDir(path).exists(), path.toLatin1()); + } else { + QVERIFY2(QDir(path).exists(), path.toLatin1()); + QVERIFY(QDir(path).removeRecursively()); + } + } +}; + +QTEST_MAIN(tst_rmdiroperationtest) + +#include "tst_rmdiroperationtest.moc" diff --git a/tests/auto/installer/scriptengine/data/addOperation.qs b/tests/auto/installer/scriptengine/data/addOperation.qs index d7d505a6b..e4a85a730 100644 --- a/tests/auto/installer/scriptengine/data/addOperation.qs +++ b/tests/auto/installer/scriptengine/data/addOperation.qs @@ -1,31 +1,26 @@ /************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Installer Framework. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/tests/auto/installer/scriptengine/data/auto-install.qs b/tests/auto/installer/scriptengine/data/auto-install.qs index 6decd31dc..4b0d28b14 100644 --- a/tests/auto/installer/scriptengine/data/auto-install.qs +++ b/tests/auto/installer/scriptengine/data/auto-install.qs @@ -50,3 +50,5 @@ Controller.prototype.FinishedPageCallback = function() { print("FinishedPageCallback - OK") } + +// Trailing comment to exercise QTIFW-1062
\ No newline at end of file diff --git a/tests/auto/installer/scriptengine/tst_scriptengine.cpp b/tests/auto/installer/scriptengine/tst_scriptengine.cpp index b7c602e26..86017a229 100644 --- a/tests/auto/installer/scriptengine/tst_scriptengine.cpp +++ b/tests/auto/installer/scriptengine/tst_scriptengine.cpp @@ -1,6 +1,6 @@ /************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2023 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Installer Framework. @@ -221,13 +221,6 @@ private slots: .hasProperty(QLatin1String("getExistingDirectory")), true); QCOMPARE(global.property(QLatin1String("QFileDialog")) .hasProperty(QLatin1String("getOpenFileName")), true); - - QCOMPARE(global.hasProperty(QLatin1String("InstallerProxy")), true); - QCOMPARE(global.property(QLatin1String("InstallerProxy")) - .hasProperty(QLatin1String("componentByName")), true); - QCOMPARE(global.property(QLatin1String("InstallerProxy")) - .hasProperty(QLatin1String("components")), true); - QCOMPARE(global.hasProperty(QLatin1String("QDesktopServices")), true); QCOMPARE(global.property(QLatin1String("QDesktopServices")) .hasProperty(QLatin1String("openUrl")), true); @@ -249,6 +242,8 @@ private slots: QJSValue sinfo = global.property(QLatin1String("systemInfo")); QCOMPARE(sinfo.property(QLatin1String("currentCpuArchitecture")).toString(), QSysInfo::currentCpuArchitecture()); + QCOMPARE(sinfo.property(QLatin1String("buildCpuArchitecture")).toString(), + QSysInfo::buildCpuArchitecture()); QCOMPARE(sinfo.property(QLatin1String("kernelType")).toString(), QSysInfo::kernelType()); QCOMPARE(sinfo.property(QLatin1String("kernelVersion")).toString(), QSysInfo::kernelVersion()); @@ -349,6 +344,21 @@ private slots: } } + void testComponentsWithRegexp() + { + const QString script = QString::fromLatin1("var components = installer.components(\"component.test.addOperation\");" + "\n" + "for (i = 0; i < components.length; i++)" + "print(components[i].name);"); + + setExpectedScriptOutput("component.test.addOperation"); + const QJSValue value = m_scriptEngine->evaluate(script); + if (value.isError()) { + QFAIL(qPrintable(QString::fromLatin1("ScriptEngine error:\n %1").arg( + value.toString()))); + } + } + void testFindFiles() { const QString expectedOutput = QString::fromLatin1("Found file %1/tst_scriptengine.moc").arg(m_applicatonDirPath); @@ -373,13 +383,24 @@ private slots: QCOMPARE(result.isError(), false); } + void loadSimpleComponentScript_data() + { + QTest::addColumn<QString>("path"); + QTest::addColumn<bool>("postLoad"); + QTest::newRow("Pre component script") << ":///data/component1.qs" << false; + QTest::newRow("Post component script") << ":///data/component1.qs" << true; + } + void loadSimpleComponentScript() { - try { - // ignore retranslateUi which is called by loadComponentScript + QFETCH(QString, path); + QFETCH(bool, postLoad); + + try { + // ignore retranslateUi which is called by evaluateComponentScript setExpectedScriptOutput("Component constructor - OK"); setExpectedScriptOutput("retranslateUi - OK"); - m_component->loadComponentScript(":///data/component1.qs"); + m_component->evaluateComponentScript(path, postLoad); setExpectedScriptOutput("retranslateUi - OK"); m_component->languageChanged(); @@ -407,8 +428,19 @@ private slots: } } + void loadBrokenComponentScript_data() + { + QTest::addColumn<QString>("path"); + QTest::addColumn<bool>("postLoad"); + QTest::newRow("Pre component script") << ":///data/component2.qs" << false; + QTest::newRow("Post component script") << ":///data/component2.qs" << true; + } + void loadBrokenComponentScript() { + QFETCH(QString, path); + QFETCH(bool, postLoad); + Component *testComponent = new Component(&m_core); testComponent->setValue(scName, "broken.component"); @@ -418,21 +450,32 @@ private slots: try { // ignore Output from script setExpectedScriptOutput("script function: Component"); - testComponent->loadComponentScript(":///data/component2.qs"); + testComponent->evaluateComponentScript(path, postLoad); } catch (const Error &error) { const QString debugMessage( - QString("create Error-Exception: \"Exception while loading the component script \"%1\": " - "ReferenceError: broken is not defined\"").arg(QDir::toNativeSeparators(":///data/component2.qs"))); + QString("Exception while loading the component script \"%1\": " + "ReferenceError: broken is not defined on line number: 33").arg(QDir::toNativeSeparators(":///data/component2.qs"))); QVERIFY2(debugMessage.contains(error.message()), "(ReferenceError: broken is not defined)"); } } + void loadComponentUserInterfaces_data() + { + QTest::addColumn<QString>("path"); + QTest::addColumn<bool>("postLoad"); + QTest::newRow("Pre component script") << ":///data/userinterface.qs" << false; + QTest::newRow("Post component script") << ":///data/userinterface.qs" << true; + } + void loadComponentUserInterfaces() { - try { + QFETCH(QString, path); + QFETCH(bool, postLoad); + try { setExpectedScriptOutput("checked: false"); + TestGui testGui(&m_core); m_component->loadUserInterfaces(QDir(":///data"), QStringList() << QLatin1String("form.ui")); - m_component->loadComponentScript(":///data/userinterface.qs"); + m_component->evaluateComponentScript(path, postLoad); } catch (const Error &error) { QFAIL(qPrintable(error.message())); } @@ -576,7 +619,7 @@ private slots: try { m_core.setPackageManager(); Component *component = m_core.componentByName("component.test.addOperation"); - component->loadComponentScript(":///data/addOperation.qs"); + component->evaluateComponentScript(":///data/addOperation.qs"); setExpectedScriptOutput("Component::createOperations()"); component->createOperations(); diff --git a/tests/auto/installer/settings/data/full_config.xml b/tests/auto/installer/settings/data/full_config.xml index 272a1b0d7..bccb6f7ca 100644 --- a/tests/auto/installer/settings/data/full_config.xml +++ b/tests/auto/installer/settings/data/full_config.xml @@ -37,7 +37,9 @@ File should contain all elements we allow in a config.xml <DependsOnLocalInstallerBinary>true</DependsOnLocalInstallerBinary> <AllowSpaceInPath>true</AllowSpaceInPath> <AllowNonAsciiCharacters>true</AllowNonAsciiCharacters> + <AllowRepositoriesForOfflineInstaller>true</AllowRepositoriesForOfflineInstaller> <DisableAuthorizationFallback>true</DisableAuthorizationFallback> + <DisableCommandLineInterface>true</DisableCommandLineInterface> <RepositorySettingsPageVisible>false</RepositorySettingsPageVisible> <CreateLocalRepository>false</CreateLocalRepository> <TargetConfigurationFile>components.xml</TargetConfigurationFile> diff --git a/tests/auto/installer/settings/data/length_units_invalid.xml b/tests/auto/installer/settings/data/length_units_invalid.xml index b1dc5aa62..7c5e99dd0 100644 --- a/tests/auto/installer/settings/data/length_units_invalid.xml +++ b/tests/auto/installer/settings/data/length_units_invalid.xml @@ -4,4 +4,6 @@ <Version>1.2.3</Version> <WizardDefaultWidth>800pt</WizardDefaultWidth> <WizardDefaultHeight>600pt</WizardDefaultHeight> + <WizardMinimumWidth>640pt</WizardMinimumWidth> + <WizardMinimumHeight>480pt</WizardMinimumHeight> </Installer> diff --git a/tests/auto/installer/settings/data/length_units_valid_em.xml b/tests/auto/installer/settings/data/length_units_valid_em.xml index af087fdfe..81eec5af7 100644 --- a/tests/auto/installer/settings/data/length_units_valid_em.xml +++ b/tests/auto/installer/settings/data/length_units_valid_em.xml @@ -4,4 +4,6 @@ <Version>1.2.3</Version> <WizardDefaultWidth>800em</WizardDefaultWidth> <WizardDefaultHeight>600em</WizardDefaultHeight> + <WizardMinimumWidth>640em</WizardMinimumWidth> + <WizardMinimumHeight>480em</WizardMinimumHeight> </Installer> diff --git a/tests/auto/installer/settings/data/length_units_valid_ex.xml b/tests/auto/installer/settings/data/length_units_valid_ex.xml index 3b39cf7a7..633a239ef 100644 --- a/tests/auto/installer/settings/data/length_units_valid_ex.xml +++ b/tests/auto/installer/settings/data/length_units_valid_ex.xml @@ -4,4 +4,6 @@ <Version>1.2.3</Version> <WizardDefaultWidth>800ex</WizardDefaultWidth> <WizardDefaultHeight>600ex</WizardDefaultHeight> + <WizardMinimumWidth>640ex</WizardMinimumWidth> + <WizardMinimumHeight>480ex</WizardMinimumHeight> </Installer> diff --git a/tests/auto/installer/settings/data/length_units_valid_px.xml b/tests/auto/installer/settings/data/length_units_valid_px.xml index 3553dd7d8..71518a71c 100644 --- a/tests/auto/installer/settings/data/length_units_valid_px.xml +++ b/tests/auto/installer/settings/data/length_units_valid_px.xml @@ -4,4 +4,6 @@ <Version>1.2.3</Version> <WizardDefaultWidth>800px</WizardDefaultWidth> <WizardDefaultHeight>600px</WizardDefaultHeight> + <WizardMinimumWidth>640px</WizardMinimumWidth> + <WizardMinimumHeight>480px</WizardMinimumHeight> </Installer> diff --git a/tests/auto/installer/settings/tst_settings.cpp b/tests/auto/installer/settings/tst_settings.cpp index ab8611e12..15dcc98a1 100644 --- a/tests/auto/installer/settings/tst_settings.cpp +++ b/tests/auto/installer/settings/tst_settings.cpp @@ -1,3 +1,31 @@ +/************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ + #include "settings.h" #include "errors.h" #include "repository.h" @@ -8,6 +36,8 @@ using namespace QInstaller; +typedef QMap<QString, QVariant> ProductImageMap; + class tst_Settings : public QObject { Q_OBJECT @@ -45,6 +75,7 @@ void tst_Settings::loadTutorialConfig() QCOMPARE(settings.watermark(), QString()); QCOMPARE(settings.banner(), QString()); QCOMPARE(settings.background(), QString()); + QCOMPARE(settings.pageListPixmap(), QString()); #if defined(Q_OS_WIN) QCOMPARE(settings.installerApplicationIcon(), QLatin1String(":/installer.ico")); QCOMPARE(settings.installerWindowIcon(), QLatin1String(":/installer.ico")); @@ -59,8 +90,12 @@ void tst_Settings::loadTutorialConfig() QCOMPARE(settings.systemIconSuffix(), QLatin1String(".png")); #endif QCOMPARE(settings.wizardStyle(), QString()); - QCOMPARE(settings.wizardDefaultWidth(), 0); + QCOMPARE(settings.wizardDefaultWidth(), settings.wizardShowPageList() ? 800 : 0); QCOMPARE(settings.wizardDefaultHeight(), 0); + QCOMPARE(settings.wizardMinimumWidth(), 0); + QCOMPARE(settings.wizardMinimumHeight(), 0); + QCOMPARE(settings.wizardShowPageList(), true); + QCOMPARE(settings.productImages(), ProductImageMap()); QCOMPARE(settings.titleColor(), QString()); QCOMPARE(settings.runProgram(), QString()); QCOMPARE(settings.runProgramArguments(), QStringList()); @@ -74,7 +109,9 @@ void tst_Settings::loadTutorialConfig() QCOMPARE(settings.repositorySettingsPageVisible(), true); QCOMPARE(settings.allowSpaceInPath(), true); QCOMPARE(settings.allowNonAsciiCharacters(), false); + QCOMPARE(settings.allowRepositoriesForOfflineInstaller(), true); QCOMPARE(settings.disableAuthorizationFallback(), false); + QCOMPARE(settings.disableCommandLineInterface(), false); QCOMPARE(settings.createLocalRepository(), false); QCOMPARE(settings.installActionColumnVisible(), false); @@ -212,6 +249,8 @@ void tst_Settings::loadConfigWithValidLengthUnits() Settings settings = Settings::fromFileAndPrefix(":///data/length_units_valid_px.xml", ":///data"); QCOMPARE(settings.wizardDefaultWidth(), 800); QCOMPARE(settings.wizardDefaultHeight(), 600); + QCOMPARE(settings.wizardMinimumWidth(), 640); + QCOMPARE(settings.wizardMinimumHeight(), 480); // Cannot test the parsed values for these units portably since the // pixel value depends on the font metrics. Let's just check for parse @@ -229,6 +268,8 @@ void tst_Settings::loadConfigWithInvalidLengthUnits() Settings settings = Settings::fromFileAndPrefix(":///data/length_units_invalid.xml", ":///data"); QCOMPARE(settings.wizardDefaultWidth(), 0); QCOMPARE(settings.wizardDefaultHeight(), 0); + QCOMPARE(settings.wizardMinimumWidth(), 0); + QCOMPARE(settings.wizardMinimumHeight(), 0); } catch (const Error &error) { QFAIL(qPrintable(QString::fromLatin1("Exception caught: %1").arg(error.message()))); } diff --git a/tests/auto/installer/settingsoperation/data/repository/A/1.0.2-1meta.7z b/tests/auto/installer/settingsoperation/data/repository/A/1.0.2-1meta.7z Binary files differnew file mode 100644 index 000000000..b283108bb --- /dev/null +++ b/tests/auto/installer/settingsoperation/data/repository/A/1.0.2-1meta.7z diff --git a/tests/auto/installer/settingsoperation/data/repository/B/1.0.0meta.7z b/tests/auto/installer/settingsoperation/data/repository/B/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..211bc0e0a --- /dev/null +++ b/tests/auto/installer/settingsoperation/data/repository/B/1.0.0meta.7z diff --git a/tests/auto/installer/settingsoperation/data/repository/C/1.0.0meta.7z b/tests/auto/installer/settingsoperation/data/repository/C/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..a990fdbf1 --- /dev/null +++ b/tests/auto/installer/settingsoperation/data/repository/C/1.0.0meta.7z diff --git a/tests/auto/installer/settingsoperation/data/repository/Updates.xml b/tests/auto/installer/settingsoperation/data/repository/Updates.xml new file mode 100644 index 000000000..3e88f849d --- /dev/null +++ b/tests/auto/installer/settingsoperation/data/repository/Updates.xml @@ -0,0 +1,33 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.2-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>false</Default> + <Script>script.qs</Script> + <SHA1>5dc8a98f591998de0c555e194e228fa740a15632</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>B</Name> + <DisplayName>B</DisplayName> + <Description>Example component B</Description> + <Version>1.0.0</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>false</Default> + <Script>script.qs</Script> + </PackageUpdate> + <PackageUpdate> + <Name>C</Name> + <DisplayName>C</DisplayName> + <Description>Example component C</Description> + <Version>1.0.0</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>false</Default> + <Script>script.qs</Script> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/settingsoperation/settings.qrc b/tests/auto/installer/settingsoperation/settings.qrc new file mode 100644 index 000000000..8da639ad6 --- /dev/null +++ b/tests/auto/installer/settingsoperation/settings.qrc @@ -0,0 +1,8 @@ +<RCC> + <qresource prefix="/"> + <file>data/repository/Updates.xml</file> + <file>data/repository/A/1.0.2-1meta.7z</file> + <file>data/repository/B/1.0.0meta.7z</file> + <file>data/repository/C/1.0.0meta.7z</file> + </qresource> +</RCC> diff --git a/tests/auto/installer/settingsoperation/settingsoperation.pro b/tests/auto/installer/settingsoperation/settingsoperation.pro index 60ddd329b..b4233f53f 100644 --- a/tests/auto/installer/settingsoperation/settingsoperation.pro +++ b/tests/auto/installer/settingsoperation/settingsoperation.pro @@ -4,3 +4,6 @@ QT -= gui QT += testlib SOURCES += tst_settingsoperation.cpp + +RESOURCES += settings.qrc\ + ../shared/config.qrc diff --git a/tests/auto/installer/settingsoperation/tst_settingsoperation.cpp b/tests/auto/installer/settingsoperation/tst_settingsoperation.cpp index ced0e6f36..2da0870c7 100644 --- a/tests/auto/installer/settingsoperation/tst_settingsoperation.cpp +++ b/tests/auto/installer/settingsoperation/tst_settingsoperation.cpp @@ -1,6 +1,6 @@ /************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Installer Framework. @@ -25,14 +25,15 @@ ** $QT_END_LICENSE$ ** **************************************************************************/ + +#include "../shared/packagemanager.h" #include <utils.h> #include <settingsoperation.h> -#include <qinstallerglobal.h> +#include <packagemanagercore.h> +#include <settings.h> -#include <QObject> #include <QTest> #include <QSettings> -#include <QDir> using namespace KDUpdater; using namespace QInstaller; @@ -89,7 +90,7 @@ private slots: UpdateOperation::InvalidArguments); compareString = "Current method argument calling \"Settings\" with arguments \"path=first; " "method=second; key=third; value=fourth\" is not supported. Please use set, remove, " - "add_array_value or remove_array_value."; + "add_array_value, or remove_array_value."; QCOMPARE(wrongMethodArgumentOperation.errorString(), compareString); // same for undo @@ -176,6 +177,7 @@ private slots: QFile testFile(testFilePath); QVERIFY2(testFile.open(QIODevice::WriteOnly | QIODevice::Text), contentFile.errorString().toLatin1()); + m_cleanupFilePaths << testFilePath; QTextStream out(&testFile); @@ -243,6 +245,7 @@ private slots: QFile testFile(testFilePath); QVERIFY2(testFile.open(QIODevice::WriteOnly | QIODevice::Text), contentFile.errorString() .toLatin1()); + m_cleanupFilePaths << testFilePath; QTextStream out(&testFile); @@ -280,6 +283,96 @@ private slots: } } + void testPerformingFromCLI() + { + QString installDir = QInstaller::generateTemporaryFileName(); + QVERIFY(QDir().mkpath(installDir)); + PackageManagerCore *core = PackageManager::getPackageManagerWithInit + (installDir, ":///data/repository"); + + QSettings testSettings(QDir(m_testSettingsDirPath).filePath(m_testSettingsFilename), + QSettings::IniFormat); + QCOMPARE(testSettings.value("testcategory/categoryarrayvalue1").toStringList(), + QStringList() << "value1" << "value2" << "value3"); + + core->installSelectedComponentsSilently(QStringList() << "A"); + + QCOMPARE(testSettings.value("testcategory/categoryarrayvalue1").toStringList(), + QStringList() << "value1" << "value2" << "value3" << "valueFromScript"); + + core->commitSessionOperations(); + core->setPackageManager(); + core->uninstallComponentsSilently(QStringList() << "A"); + + QCOMPARE(testSettings.value("testcategory/categoryarrayvalue1").toStringList(), + QStringList() << "value1" << "value2" << "value3"); + QDir dir(installDir); + QVERIFY(dir.removeRecursively()); + core->deleteLater(); + } + + void testPerformingFromCLIWithPlaceholders() + { + QString installDir = QInstaller::generateTemporaryFileName(); + QVERIFY(QDir().mkpath(installDir)); + PackageManagerCore *core = PackageManager::getPackageManagerWithInit + (installDir, ":///data/repository"); + + core->installSelectedComponentsSilently(QStringList() << "B"); + // Path is set in component constructor in install script + const QString settingsFile = core->value("SettingsPathFromVariable"); + QSettings testSettings(QDir(m_testSettingsDirPath).filePath(settingsFile), + QSettings::IniFormat); + + QCOMPARE(testSettings.value("testcategory/categoryarrayvalue1").toStringList(), + QStringList() << "ValueFromPlaceholder"); + + core->commitSessionOperations(); + core->setPackageManager(); + core->uninstallComponentsSilently(QStringList() << "B"); + + // Settings file is removed as it is empty + QVERIFY(!QFile::exists(settingsFile)); + QDir dir(installDir); + QVERIFY(dir.removeRecursively()); + core->deleteLater(); + } + + void testPerformingFromCLIWithSettingsFileMoved() + { + QString installDir = QInstaller::generateTemporaryFileName(); + QVERIFY(QDir().mkpath(installDir)); + PackageManagerCore *core = PackageManager::getPackageManagerWithInit + (installDir, ":///data/repository"); + + + core->installSelectedComponentsSilently(QStringList() << "C"); + + const QString settingsFileName = qApp->applicationDirPath() + "/oldTestSettings.ini"; + QSettings testSettings(QDir(m_testSettingsDirPath).filePath(settingsFileName), + QSettings::IniFormat); + + QCOMPARE(testSettings.value("testcategory/categoryarrayvalue1").toStringList(), + QStringList() << "valueFromScript"); + + QFile settingsFile(settingsFileName); + // Move the settings path to new location. Script has set values + // ComponentCSettingsPath (@InstallerDirPath@/newTestSettings.ini) and + // ComponentCSettingsPath_OLD (@InstallerDirPath@/oldTestSettings.ini) so + // UNDO operation should delete the moved newTestSettings.ini file instead. + QVERIFY2(settingsFile.rename(qApp->applicationDirPath() + "/newTestSettings.ini"), "Could not move settings file."); + core->commitSessionOperations(); + core->setPackageManager(); + core->uninstallComponentsSilently(QStringList() << "C"); + + // Settings file is removed in uninstall as it is empty + QVERIFY2(!QFile::exists(qApp->applicationDirPath() + "/newTestSettings.ini"), "Settings file not deleted correctly"); + + QDir dir(installDir); + QVERIFY(dir.removeRecursively()); + core->deleteLater(); + } + // called after all tests void cleanupTestCase() { diff --git a/tests/auto/installer/shared/config.qrc b/tests/auto/installer/shared/config.qrc new file mode 100644 index 000000000..b25a589a3 --- /dev/null +++ b/tests/auto/installer/shared/config.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/metadata"> + <file>installer-config/config.xml</file> + </qresource> +</RCC> diff --git a/tests/auto/installer/shared/installer-config/config.xml b/tests/auto/installer/shared/installer-config/config.xml new file mode 100644 index 000000000..adc24631b --- /dev/null +++ b/tests/auto/installer/shared/installer-config/config.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<Installer> + <Name>test</Name> + <Version>1.0.0</Version> +</Installer> diff --git a/tests/auto/installer/shared/packagemanager.h b/tests/auto/installer/shared/packagemanager.h new file mode 100644 index 000000000..9948be00a --- /dev/null +++ b/tests/auto/installer/shared/packagemanager.h @@ -0,0 +1,82 @@ +/************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ + +#ifndef PACKAGEMANAGER_H +#define PACKAGEMANAGER_H + +#include <packagemanagercore.h> +#include <binaryformatenginehandler.h> +#include <binarycontent.h> +#include <fileutils.h> +#include <settings.h> +#include <init.h> +#include <errors.h> + +#include <QTest> + +using namespace QInstaller; + +void silentTestMessageHandler(QtMsgType, const QMessageLogContext &, const QString &) {} +void exitOnWarningMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) +{ + const QByteArray localMsg = msg.toLocal8Bit(); + const char *file = context.file ? context.file : ""; + const char *function = context.function ? context.function : ""; + if (!(type == QtDebugMsg) && !(type == QtInfoMsg)) { + fprintf(stderr, "Caught message: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function); + exit(1); + } +} + +struct PackageManager +{ + static PackageManagerCore *getPackageManager(const QString &targetDir, const QString &repository = QString()) + { + BinaryFormatEngineHandler::instance()->clear(); + + PackageManagerCore *core = new PackageManagerCore(BinaryContent::MagicInstallerMarker, QList<OperationBlob> ()); + QString appFilePath = QCoreApplication::applicationFilePath(); + core->disableWriteMaintenanceTool(); + core->setAutoConfirmCommand(); + QSet<Repository> repoList; + Repository repo = Repository::fromUserInput(repository); + repoList.insert(repo); + core->settings().setDefaultRepositories(repoList); + + core->setValue(scTargetDir, targetDir); + return core; + } + + static PackageManagerCore *getPackageManagerWithInit(const QString &targetDir, const QString &repository = QString()) + { + QInstaller::init(); + qInstallMessageHandler(silentTestMessageHandler); + return getPackageManager(targetDir, repository); + } +}; +#endif diff --git a/tests/auto/installer/shared/verifyinstaller.h b/tests/auto/installer/shared/verifyinstaller.h new file mode 100644 index 000000000..e19d3fa0a --- /dev/null +++ b/tests/auto/installer/shared/verifyinstaller.h @@ -0,0 +1,139 @@ +/************************************************************************** +** +** Copyright (C) 2023 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ + +#ifndef VERIFYINSTALLER_H +#define VERIFYINSTALLER_H + +#include <packagemanagercore.h> + +#include <QString> +#include <QStringList> +#include <QCryptographicHash> +#include <QFile> +#include <QDir> +#include <QtTest/QTest> + +#include <iostream> +#include <sstream> + +struct VerifyInstaller +{ + static void verifyInstallerResources(const QString &installDir, const QString &componentName, const QString &fileName) + { + QDir dir(installDir + QDir::separator() + "installerResources" + QDir::separator() + componentName); + QVERIFY2(dir.exists(), qPrintable(QLatin1String("Directory: \"%1\" does not exist").arg(dir.absolutePath()))); + QFileInfo fileInfo; + fileInfo.setFile(dir, fileName); + QVERIFY2(fileInfo.exists(), qPrintable(QLatin1String("File: \"%1\" does not exist for \"%2\".") + .arg(fileName).arg(componentName))); + } + + static void verifyInstallerResourcesDeletion(const QString &installDir, const QString &componentName) + { + QDir dir(installDir + QDir::separator() + "installerResources" + QDir::separator() + componentName); + QVERIFY2(!dir.exists(), qPrintable(QLatin1String("Directory: \"%1\" is not deleted.").arg(dir.absolutePath()))); + } + + static void verifyInstallerResourceFileDeletion(const QString &installDir, const QString &componentName, const QString &fileName) + { + QDir dir(installDir + QDir::separator() + "installerResources" + QDir::separator() + componentName); + QFileInfo fileInfo; + fileInfo.setFile(dir, fileName); + QVERIFY2(!fileInfo.exists(), qPrintable(QLatin1String("File: \"%1\" still exists for \"%2\".") + .arg(fileName).arg(componentName))); + } + + static void verifyFileExistence(const QString &installDir, const QStringList &fileList) + { + for (int i = 0; i < fileList.count(); i++) { + bool fileExists = QFileInfo::exists(installDir + QDir::separator() + fileList.at(i)); + QVERIFY2(fileExists, QString("File \"%1\" does not exist.").arg(fileList.at(i)).toLatin1()); + } + + QDir dir(installDir); + QCOMPARE(dir.entryList(QStringList() << "*.*", QDir::Files).count(), fileList.count()); + } + + static QString fileContent(const QString &fileName) + { + QFile file(fileName); + QTextStream stream(&file); + file.open(QIODevice::ReadOnly); + QString str = stream.readAll(); + file.close(); + return str; + } + + static void verifyFileContent(const QString &fileName, const QString &content) + { + QVERIFY(fileContent(fileName).contains(content)); + } + + static void verifyFileHasNoContent(const QString &fileName, const QString &content) + { + QVERIFY(!fileContent(fileName).contains(content)); + } + + static void addToFileMap(const QDir &baseDir, const QFileInfo &fileInfo, QMap<QString, QByteArray> &map) + { + QDir directory(fileInfo.absoluteFilePath()); + directory.setFilter(QDir::NoDotAndDotDot | QDir::NoSymLinks | QDir::AllDirs | QDir::Files); + QFileInfoList fileInfoList = directory.entryInfoList(); + + foreach (const QFileInfo &info, fileInfoList) { + if (info.isDir()) { + map.insert(baseDir.relativeFilePath(info.filePath()), QByteArray()); + addToFileMap(baseDir, info, map); + } else { + QCryptographicHash hash(QCryptographicHash::Sha1); + QFile file(info.absoluteFilePath()); + QVERIFY(file.open(QIODevice::ReadOnly)); + QVERIFY(hash.addData(&file)); + map.insert(baseDir.relativeFilePath(info.filePath()), hash.result().toHex()); + file.close(); + } + } + } + + template <typename Func, typename... Args> + static void verifyListPackagesMessage(QInstaller::PackageManagerCore *core, const QString &message, + Func func, Args... args) + { + std::ostringstream stream; + std::streambuf *buf = std::cout.rdbuf(); + std::cout.rdbuf(stream.rdbuf()); + + (core->*func)(std::forward<Args>(args)...); + + std::cout.rdbuf(buf); + QVERIFY(stream && stream.tellp() == message.size()); + for (const QString &line : message.split(QLatin1String("\n"))) + QVERIFY(stream.str().find(line.toStdString()) != std::string::npos); + } +}; +#endif diff --git a/tests/auto/installer/simplemovefileoperation/data/repository/A/1.0.2-1meta.7z b/tests/auto/installer/simplemovefileoperation/data/repository/A/1.0.2-1meta.7z Binary files differnew file mode 100644 index 000000000..8749fce7f --- /dev/null +++ b/tests/auto/installer/simplemovefileoperation/data/repository/A/1.0.2-1meta.7z diff --git a/tests/auto/installer/simplemovefileoperation/data/repository/Updates.xml b/tests/auto/installer/simplemovefileoperation/data/repository/Updates.xml new file mode 100644 index 000000000..6df6a436b --- /dev/null +++ b/tests/auto/installer/simplemovefileoperation/data/repository/Updates.xml @@ -0,0 +1,15 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.2-1</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <Script>script.qs</Script> + <SHA1>8f2df84c9eada2570c02a7df573288e5cb6644e2</SHA1> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/simplemovefileoperation/settings.qrc b/tests/auto/installer/simplemovefileoperation/settings.qrc new file mode 100644 index 000000000..d030220ab --- /dev/null +++ b/tests/auto/installer/simplemovefileoperation/settings.qrc @@ -0,0 +1,6 @@ +<RCC> + <qresource prefix="/"> + <file>data/repository/Updates.xml</file> + <file>data/repository/A/1.0.2-1meta.7z</file> + </qresource> +</RCC> diff --git a/tests/auto/installer/simplemovefileoperation/simplemovefileoperation.pro b/tests/auto/installer/simplemovefileoperation/simplemovefileoperation.pro new file mode 100644 index 000000000..1cb84824f --- /dev/null +++ b/tests/auto/installer/simplemovefileoperation/simplemovefileoperation.pro @@ -0,0 +1,10 @@ +include(../../qttest.pri) + +QT -= gui +QT += testlib + +SOURCES = tst_simplemovefileoperation.cpp + +RESOURCES += \ + settings.qrc \ + ../shared/config.qrc diff --git a/tests/auto/installer/simplemovefileoperation/tst_simplemovefileoperation.cpp b/tests/auto/installer/simplemovefileoperation/tst_simplemovefileoperation.cpp new file mode 100644 index 000000000..9caf7aacf --- /dev/null +++ b/tests/auto/installer/simplemovefileoperation/tst_simplemovefileoperation.cpp @@ -0,0 +1,178 @@ +/************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ +#include "../shared/packagemanager.h" + +#include <simplemovefileoperation.h> + +#include <packagemanagercore.h> + +#include <utils.h> + +#include <QObject> +#include <QFile> +#include <QTest> + +using namespace KDUpdater; +using namespace QInstaller; + +class tst_simplemovefileoperation : public QObject +{ + Q_OBJECT + +private: + void createDummyFile(const QString &source, const QString &destination) + { + // Create dummy original file for move destination + QFile destFile(destination); + QVERIFY(destFile.open(QIODevice::WriteOnly)); + destFile.close(); + + QByteArray testString("Generated by QTest\n"); + QFile testFile(source); + QVERIFY(testFile.open(QIODevice::WriteOnly | QIODevice::Text)); + QTextStream out(&testFile); + out << testString; + testFile.close(); + QVERIFY(QFileInfo(source).exists()); + } + +private slots: + void testMissingArguments() + { + SimpleMoveFileOperation op(nullptr); + + op.backup(); + QVERIFY(op.testOperation()); + QVERIFY(!op.performOperation()); + + QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::InvalidArguments); + QCOMPARE(op.errorString(), QString("Invalid arguments in SimpleMoveFile: " + "0 arguments given, exactly 2 arguments expected.")); + + op.setArguments(QStringList() << "" << ""); + QVERIFY(!op.performOperation()); + + QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::UserDefinedError); + QCOMPARE(op.errorString(), QString("None of the arguments can be empty: " + "source \"\", target \"\".")); + } + + void initTestCase_data() + { + QTest::addColumn<QString>("source"); + QTest::addColumn<QString>("destination"); + QTest::newRow("relative") << "test1" << "test2"; + QTest::newRow("absolute") + << qApp->applicationDirPath() + QDir::toNativeSeparators("/test") + << generateTemporaryFileName(); + } + + void testMoveFileWithOverwrite() + { + QFETCH_GLOBAL(QString, source); + QFETCH_GLOBAL(QString, destination); + + createDummyFile(source, destination); + QByteArray testFileHash = QInstaller::calculateHash(source, QCryptographicHash::Sha1); + + SimpleMoveFileOperation op(nullptr); + op.setArguments(QStringList() << source << destination); + + QVERIFY2(op.performOperation(), op.errorString().toLatin1()); + + QVERIFY(!QFileInfo(source).exists()); + QByteArray destinationFileHash = QInstaller::calculateHash(destination, QCryptographicHash::Sha1); + QVERIFY(testFileHash == destinationFileHash); + + QVERIFY2(op.undoOperation(), op.errorString().toLatin1()); + + QVERIFY(!QFileInfo(destination).exists()); + QByteArray sourceFileHash = QInstaller::calculateHash(source, QCryptographicHash::Sha1); + QVERIFY(testFileHash == sourceFileHash); + + QVERIFY(QFile(source).remove()); + } + + void testMoveFileNoUndo() + { + QFETCH_GLOBAL(QString, source); + QFETCH_GLOBAL(QString, destination); + + createDummyFile(source, destination); + + QByteArray testFileHash = QInstaller::calculateHash(source, QCryptographicHash::Sha1); + + SimpleMoveFileOperation op(nullptr); + op.setArguments(QStringList() << source << destination << "UNDOOPERATION" << ""); + + QVERIFY2(op.performOperation(), op.errorString().toLatin1()); + QVERIFY(!QFileInfo(source).exists()); + QByteArray destinationFileHash = QInstaller::calculateHash(destination, QCryptographicHash::Sha1); + QVERIFY(testFileHash == destinationFileHash); + + QVERIFY2(op.undoOperation(), op.errorString().toLatin1()); + QVERIFY(QFileInfo(destination).exists()); + QVERIFY(testFileHash == destinationFileHash); + QVERIFY(QFile(destination).remove()); + } + + void testPerformingFromCLI() + { + QString installDir = QInstaller::generateTemporaryFileName(); + QVERIFY(QDir().mkpath(installDir)); + PackageManagerCore *core = PackageManager::getPackageManagerWithInit + (installDir, ":///data/repository"); + + QString destinationDir = installDir + QDir::separator() + "destination"; + QVERIFY(QDir().mkpath(destinationDir)); + + // Matches filename in component install script + QFile file(installDir + QDir::toNativeSeparators("/test")); + QVERIFY(file.open(QIODevice::ReadWrite)); + file.close(); + + core->installDefaultComponentsSilently(); + QVERIFY(!file.exists()); + + QFile movedFile(destinationDir + QDir::separator() + "test"); + QVERIFY(movedFile.exists()); + + core->setPackageManager(); + core->commitSessionOperations(); + core->uninstallComponentsSilently(QStringList() << "A"); + QVERIFY(!movedFile.exists() && file.exists()); + + QDir dir(installDir); + QVERIFY(dir.removeRecursively()); + core->deleteLater(); + } +}; + +QTEST_MAIN(tst_simplemovefileoperation) + +#include "tst_simplemovefileoperation.moc" diff --git a/tests/auto/installer/solver/tst_solver.cpp b/tests/auto/installer/solver/tst_solver.cpp index d1c3aaa14..4548af3f1 100644 --- a/tests/auto/installer/solver/tst_solver.cpp +++ b/tests/auto/installer/solver/tst_solver.cpp @@ -1,6 +1,6 @@ /************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2023 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Installer Framework. @@ -39,13 +39,16 @@ using namespace QInstaller; typedef QMap<Component *, QStringList> ComponentToStringList; +typedef QList<QPair<Component *, CalculatorBase::Resolution>> UninstallReasonList; + +Q_DECLARE_METATYPE(UninstallReasonList) class Data { public: Data() {} explicit Data(const QString &data) : m_data(data) {} - inline uint qHash(const Data &test); + inline hashValue qHash(const Data &test); QString data() const { return m_data; } bool operator==(const Data &rhs) const { return m_data == rhs.m_data; } const Data &operator=(const Data &rhs) { if (this != &rhs) { m_data = rhs.m_data; } return *this; } @@ -53,7 +56,7 @@ public: private: QString m_data; }; -inline uint qHash(const Data &data) +inline hashValue qHash(const Data &data) { return qHash(data.data()); } @@ -146,7 +149,8 @@ private slots: QTest::addColumn<PackageManagerCore *>("core"); QTest::addColumn<QList<Component *> >("selectedComponents"); QTest::addColumn<QList<Component *> >("expectedResult"); - QTest::addColumn<QList<int> >("installReason"); + QTest::addColumn<QList<CalculatorBase::Resolution> >("installReason"); + QTest::addColumn<AutoDependencyHash >("autodependencyHash"); PackageManagerCore *core = new PackageManagerCore(); core->setPackageManager(); @@ -166,14 +170,18 @@ private slots: core->appendRootComponent(componentB_NewVersion); core->appendRootComponent(componentB_Auto); + QHash<QString, QStringList> autodependencyHash; + autodependencyHash.insert(QLatin1String("B_version"), QStringList() << QLatin1String("B_auto")); + QTest::newRow("Installer resolved") << core << (QList<Component *>() << componentB) << (QList<Component *>() << componentB_NewVersion << componentAB << componentB << componentB_Auto) - << (QList<int>() - << InstallerCalculator::Dependent - << InstallerCalculator::Dependent - << InstallerCalculator::Resolved - << InstallerCalculator::Automatic); + << (QList<CalculatorBase::Resolution>() + << CalculatorBase::Resolution::Dependent + << CalculatorBase::Resolution::Dependent + << CalculatorBase::Resolution::Resolved + << CalculatorBase::Resolution::Automatic) + << autodependencyHash; } void resolveInstaller() @@ -181,16 +189,17 @@ private slots: QFETCH(PackageManagerCore *, core); QFETCH(QList<Component *> , selectedComponents); QFETCH(QList<Component *> , expectedResult); - QFETCH(QList<int>, installReason); + QFETCH(QList<CalculatorBase::Resolution>, installReason); + QFETCH(AutoDependencyHash, autodependencyHash); - InstallerCalculator calc(core->components(PackageManagerCore::ComponentType::AllNoReplacements)); - calc.appendComponentsToInstall(selectedComponents); - QList<Component *> result = calc.orderedComponentsToInstall(); + InstallerCalculator calc(core, autodependencyHash); + calc.solve(selectedComponents); + QList<Component *> result = calc.resolvedComponents(); QCOMPARE(result.count(), expectedResult.count()); for (int i = 0; i < result.count(); i++) { QCOMPARE(result.at(i), expectedResult.at(i)); - QCOMPARE((int)calc.installReasonType(result.at(i)), installReason.at(i)); + QCOMPARE(calc.resolutionType(result.at(i)), installReason.at(i)); } delete core; } @@ -218,7 +227,6 @@ private slots: << (QList<Component *>() << componentA) << (QList<Component *>()); } - } void unresolvedDependencyVersion() @@ -227,11 +235,11 @@ private slots: QFETCH(QList<Component *> , selectedComponents); QFETCH(QList<Component *> , expectedResult); - InstallerCalculator calc(core->components(PackageManagerCore::ComponentType::AllNoReplacements)); + InstallerCalculator calc(core, QHash<QString, QStringList>()); QTest::ignoreMessage(QtWarningMsg, "Cannot find missing dependency \"B->=2.0.0\" for \"A\"."); - calc.appendComponentsToInstall(selectedComponents); + calc.solve(selectedComponents); - QList<Component *> result = calc.orderedComponentsToInstall(); + QList<Component *> result = calc.resolvedComponents(); QCOMPARE(result.count(), expectedResult.count()); delete core; } @@ -240,9 +248,11 @@ private slots: { QTest::addColumn<PackageManagerCore *>("core"); QTest::addColumn<QList<Component *> >("selectedToUninstall"); - QTest::addColumn<QList<Component *> >("installedComponents"); - QTest::addColumn<QSet<Component *> >("expectedResult"); + QTest::addColumn<QList<Component *> >("expectedResult"); + QTest::addColumn<UninstallReasonList >("uninstallReasons"); + QTest::addColumn<LocalDependencyHash >("dependencyHash"); + UninstallReasonList uninstallReasonList; PackageManagerCore *core = new PackageManagerCore(); core->setPackageManager(); NamedComponent *componentA = new NamedComponent(core, QLatin1String("A")); @@ -259,11 +269,19 @@ private slots: componentB->setInstalled(); componentAB->setInstalled(); + QHash<QString, QStringList> dependencyComponentHash; + dependencyComponentHash.insert(QLatin1String("A.B"), QStringList() << QLatin1String("B")); + + uninstallReasonList.append(qMakePair(componentAB, CalculatorBase::Resolution::Selected)); + uninstallReasonList.append(qMakePair(componentB, CalculatorBase::Resolution::Dependent)); QTest::newRow("Uninstaller resolved") << core << (QList<Component *>() << componentAB) - << (QList<Component *>() << componentA << componentB) - << (QSet<Component *>() << componentAB << componentB); + << (QList<Component *>() << componentB << componentAB) + << uninstallReasonList + << dependencyComponentHash; + dependencyComponentHash.clear(); + uninstallReasonList.clear(); core = new PackageManagerCore(); core->setPackageManager(); NamedComponent *compA = new NamedComponent(core, QLatin1String("A")); @@ -277,29 +295,37 @@ private slots: compA->setInstalled(); compB->setInstalled(); + dependencyComponentHash.insert(QLatin1String("A"), QStringList() << QLatin1String("B")); + + uninstallReasonList.append(qMakePair(compA, CalculatorBase::Resolution::Selected)); + uninstallReasonList.append(qMakePair(compB, CalculatorBase::Resolution::Dependent)); QTest::newRow("Cascade dependencies") << core << (QList<Component *>() << compA) - << (QList<Component *>() << compB) - << (QSet<Component *>() << compA << compB); + << (QList<Component *>() << compB << compA) + << (uninstallReasonList) + << dependencyComponentHash; } void resolveUninstaller() { QFETCH(PackageManagerCore *, core); QFETCH(QList<Component *> , selectedToUninstall); - QFETCH(QList<Component *> , installedComponents); - QFETCH(QSet<Component *> , expectedResult); - - UninstallerCalculator calc(installedComponents); - calc.appendComponentsToUninstall(selectedToUninstall); - QSet<Component *> result = calc.componentsToUninstall(); - + QFETCH(QList<Component *> , expectedResult); + QFETCH(UninstallReasonList, uninstallReasons); + QFETCH(LocalDependencyHash, dependencyHash); + + UninstallerCalculator calc(core, QHash<QString, QStringList>(), dependencyHash, QStringList()); + calc.solve(selectedToUninstall); + QList<Component *> result = calc.resolvedComponents(); + for (auto pair : uninstallReasons) { + CalculatorBase::Resolution type = calc.resolutionType(pair.first); + QCOMPARE(pair.second, type); + } QCOMPARE(result.count(), expectedResult.count()); QCOMPARE(result, expectedResult); delete core; } - void checkComponent_data() { QTest::addColumn<QList<Component *> >("componentsToCheck"); @@ -342,7 +368,6 @@ private slots: QTest::newRow("AutoDepend and dependency") << (QList<Component *>() << componentC << componentD << componentE) << result; - } void checkComponent() diff --git a/tests/auto/installer/treename/data/components.xml b/tests/auto/installer/treename/data/components.xml new file mode 100644 index 000000000..0cb0e9826 --- /dev/null +++ b/tests/auto/installer/treename/data/components.xml @@ -0,0 +1,59 @@ +<Packages> + <ApplicationName>Test Application</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Package> + <Name>ASub2ToRoot</Name> + <Title>Root component 1</Title> + <Description>A package without treename (remote treename conflicts with local name)</Description> + <TreeName></TreeName> + <Version>1.0.0-1</Version> + <LastUpdateDate></LastUpdateDate> + <InstallDate>2021-01-01</InstallDate> + <Size>0</Size> + <Checkable>true</Checkable> + </Package> + <Package> + <Name>B</Name> + <Title>Root component 2</Title> + <Description>A package with treename (remote treename conflicts with local treename)</Description> + <TreeName>BSub2ToRoot</TreeName> + <Version>1.0.0-1</Version> + <LastUpdateDate></LastUpdateDate> + <InstallDate>2021-01-01</InstallDate> + <Size>0</Size> + <Checkable>true</Checkable> + </Package> + <Package> + <Name>componentB.sub1.sub2</Name> + <Title>Sub component</Title> + <Description>A package with treename (remote has different treename)</Description> + <TreeName>componentC.sub2</TreeName> + <Version>1.0.0-1</Version> + <LastUpdateDate></LastUpdateDate> + <InstallDate>2021-01-01</InstallDate> + <Size>0</Size> + <Checkable>true</Checkable> + </Package> + <Package> + <Name>C</Name> + <Title>Root component 3</Title> + <Description>A package with treename (remote name conflicts with local treename)</Description> + <TreeName>componentA</TreeName> + <Version>1.0.0-1</Version> + <LastUpdateDate></LastUpdateDate> + <InstallDate>2021-01-01</InstallDate> + <Size>0</Size> + <Checkable>true</Checkable> + </Package> + <Package> + <Name>componentD</Name> + <Title>Root component 4</Title> + <Description>A package with treename (remote does not have treename)</Description> + <TreeName>componentDNew</TreeName> + <Version>1.0.0-1</Version> + <LastUpdateDate></LastUpdateDate> + <InstallDate>2021-01-01</InstallDate> + <Size>0</Size> + <Checkable>true</Checkable> + </Package> +</Packages> diff --git a/tests/auto/installer/treename/data/invalid_repository/Updates.xml b/tests/auto/installer/treename/data/invalid_repository/Updates.xml new file mode 100644 index 000000000..b329bb223 --- /dev/null +++ b/tests/auto/installer/treename/data/invalid_repository/Updates.xml @@ -0,0 +1,55 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>componentA</Name> + <DisplayName>Component A</DisplayName> + <Description>This component depends on componentB.sub2.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>80</SortingPriority> + </PackageUpdate> + <PackageUpdate> + <Name>componentA.sub1</Name> + <DisplayName>Component A subcomponent 1</DisplayName> + <Description>component</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>80</SortingPriority> + </PackageUpdate> + <PackageUpdate> + <Name>componentB</Name> + <DisplayName>Component B</DisplayName> + <Description>Component B</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>40</SortingPriority> + <TreeName>componentA.sub1</TreeName> + </PackageUpdate> + <PackageUpdate> + <Name>componentC.sub1</Name> + <DisplayName>Component C subcomponent1</DisplayName> + <Description>Component</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>40</SortingPriority> + </PackageUpdate> + <PackageUpdate> + <Name>componentD</Name> + <DisplayName>Component D</DisplayName> + <Description>Component</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>40</SortingPriority> + <TreeName moveChildren="true">componentC</TreeName> + </PackageUpdate> + <PackageUpdate> + <Name>componentD.sub1</Name> + <DisplayName>Component D subcomponent 1</DisplayName> + <Description>Component</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>40</SortingPriority> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/treename/data/repository/Updates.xml b/tests/auto/installer/treename/data/repository/Updates.xml new file mode 100644 index 000000000..295f076dd --- /dev/null +++ b/tests/auto/installer/treename/data/repository/Updates.xml @@ -0,0 +1,135 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>componentA</Name> + <DisplayName>Component A</DisplayName> + <Description>This component depends on componentB.sub2.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>80</SortingPriority> + <Dependencies>componentB.sub2</Dependencies> + <UpdateFile CompressedSize="275" UncompressedSize="101" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>570dec768b1f266c66656f015e772f0e6e41b73d</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentA.sub1</Name> + <DisplayName>Component A subcomponent 1</DisplayName> + <Description>component</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>80</SortingPriority> + <UpdateFile CompressedSize="283" UncompressedSize="101" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>da5819910a7f7c95eb61a49543e273fd6e2e9aae</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentA.sub2</Name> + <DisplayName>Component A subcomponent 2</DisplayName> + <Description>component</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>80</SortingPriority> + <TreeName>ASub2ToRoot</TreeName> + <UpdateFile CompressedSize="283" UncompressedSize="101" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>73ac2c332ce01fadf0f1c7e16a27faaf0f853e18</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentB</Name> + <DisplayName>Component B</DisplayName> + <Description>Component B</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>40</SortingPriority> + <UpdateFile CompressedSize="275" UncompressedSize="101" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>72eee5304ff866e024b477d7b2432df8f2428483</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentB.sub1</Name> + <DisplayName>Component B subcomponent 2 1</DisplayName> + <Description>Subcomponent for B</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>100</SortingPriority> + <UpdateFile CompressedSize="283" UncompressedSize="101" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>e19f1a26698afe0b72c9048b403253421b8fed4b</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentB.sub1.sub1</Name> + <DisplayName>Component B sub component for sub1</DisplayName> + <Description>Subsubcomponent for B. Moved to root with treename.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>100</SortingPriority> + <TreeName>BSub1Sub1ToRoot</TreeName> + <UpdateFile CompressedSize="291" UncompressedSize="101" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>6a348979273336862c7a5e16305779e81fee1081</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentB.sub1.sub2</Name> + <DisplayName>Component B second sub component for sub1</DisplayName> + <Description>Subsubcomponent for B. Moved under componentC with treename.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>100</SortingPriority> + <TreeName>componentC.sub1</TreeName> + <UpdateFile CompressedSize="291" UncompressedSize="101" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>c1bca8944147ec64343c146f461288990268b4a9</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentB.sub2</Name> + <DisplayName>Component B subcomponent 2</DisplayName> + <Description>Subcomponent for B. Moved to root with treename.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>8000</SortingPriority> + <TreeName>BSub2ToRoot</TreeName> + <UpdateFile CompressedSize="283" UncompressedSize="101" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>bde9feba3a8134e9c1412b674ee21642938fafec</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentC</Name> + <DisplayName>Component C</DisplayName> + <Description>Component C</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <UpdateFile CompressedSize="275" UncompressedSize="101" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>cc33e730d9127e1636566ea35bbe4f186ba4bcb7</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentD</Name> + <DisplayName>Component D</DisplayName> + <Description>Component D. Autodepends on moved item componentA.sub2 </Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <AutoDependOn>componentA.sub2</AutoDependOn> + <UpdateFile CompressedSize="275" UncompressedSize="101" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>3ca69d6bb062c4442fdb20fe0e62bb0f04e8a419</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentE</Name> + <DisplayName>Component E</DisplayName> + <Description>Component with tree name, is replaced by other component.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2022-01-01</ReleaseDate> + <TreeName>EToNewRoot</TreeName> + </PackageUpdate> + <PackageUpdate> + <Name>componentF</Name> + <DisplayName>Component F</DisplayName> + <Description>Component that replaces other component</Description> + <Version>1.0.0</Version> + <ReleaseDate>2022-01-01</ReleaseDate> + <Replaces>componentE</Replaces> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/treename/data/repository/componentA.sub1/1.0.0content.7z b/tests/auto/installer/treename/data/repository/componentA.sub1/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..f7e22c055 --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentA.sub1/1.0.0content.7z diff --git a/tests/auto/installer/treename/data/repository/componentA.sub1/1.0.0content.7z.sha1 b/tests/auto/installer/treename/data/repository/componentA.sub1/1.0.0content.7z.sha1 new file mode 100644 index 000000000..3378d2da5 --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentA.sub1/1.0.0content.7z.sha1 @@ -0,0 +1 @@ +d46bf0f128c64749fb03050045afc816774185e2
\ No newline at end of file diff --git a/tests/auto/installer/treename/data/repository/componentA.sub1/1.0.0meta.7z b/tests/auto/installer/treename/data/repository/componentA.sub1/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..81ff563fc --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentA.sub1/1.0.0meta.7z diff --git a/tests/auto/installer/treename/data/repository/componentA.sub2/1.0.0content.7z b/tests/auto/installer/treename/data/repository/componentA.sub2/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..d7f4c781c --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentA.sub2/1.0.0content.7z diff --git a/tests/auto/installer/treename/data/repository/componentA.sub2/1.0.0content.7z.sha1 b/tests/auto/installer/treename/data/repository/componentA.sub2/1.0.0content.7z.sha1 new file mode 100644 index 000000000..0eb4045af --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentA.sub2/1.0.0content.7z.sha1 @@ -0,0 +1 @@ +6561aae70d055e1c4d72b30b12aef7a85cf2139e
\ No newline at end of file diff --git a/tests/auto/installer/treename/data/repository/componentA.sub2/1.0.0meta.7z b/tests/auto/installer/treename/data/repository/componentA.sub2/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..38d7c557d --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentA.sub2/1.0.0meta.7z diff --git a/tests/auto/installer/treename/data/repository/componentA/1.0.0content.7z b/tests/auto/installer/treename/data/repository/componentA/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..e50fc1e92 --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentA/1.0.0content.7z diff --git a/tests/auto/installer/treename/data/repository/componentA/1.0.0content.7z.sha1 b/tests/auto/installer/treename/data/repository/componentA/1.0.0content.7z.sha1 new file mode 100644 index 000000000..082bcbf64 --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentA/1.0.0content.7z.sha1 @@ -0,0 +1 @@ +d8486606a02b9c492e4c17d1e42cfea835a1da51
\ No newline at end of file diff --git a/tests/auto/installer/treename/data/repository/componentA/1.0.0meta.7z b/tests/auto/installer/treename/data/repository/componentA/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..c062c3cee --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentA/1.0.0meta.7z diff --git a/tests/auto/installer/treename/data/repository/componentB.sub1.sub1/1.0.0content.7z b/tests/auto/installer/treename/data/repository/componentB.sub1.sub1/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..2c254e3aa --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentB.sub1.sub1/1.0.0content.7z diff --git a/tests/auto/installer/treename/data/repository/componentB.sub1.sub1/1.0.0content.7z.sha1 b/tests/auto/installer/treename/data/repository/componentB.sub1.sub1/1.0.0content.7z.sha1 new file mode 100644 index 000000000..019ab5051 --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentB.sub1.sub1/1.0.0content.7z.sha1 @@ -0,0 +1 @@ +3fd04b8e55846f9622ffb8f9ae5f4e6c8b57f90e
\ No newline at end of file diff --git a/tests/auto/installer/treename/data/repository/componentB.sub1.sub1/1.0.0meta.7z b/tests/auto/installer/treename/data/repository/componentB.sub1.sub1/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..31630e810 --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentB.sub1.sub1/1.0.0meta.7z diff --git a/tests/auto/installer/treename/data/repository/componentB.sub1.sub2/1.0.0content.7z b/tests/auto/installer/treename/data/repository/componentB.sub1.sub2/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..261ea6ab9 --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentB.sub1.sub2/1.0.0content.7z diff --git a/tests/auto/installer/treename/data/repository/componentB.sub1.sub2/1.0.0content.7z.sha1 b/tests/auto/installer/treename/data/repository/componentB.sub1.sub2/1.0.0content.7z.sha1 new file mode 100644 index 000000000..c3753ca62 --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentB.sub1.sub2/1.0.0content.7z.sha1 @@ -0,0 +1 @@ +2e89c27c3590e12cd900cb55fa2c91428babfd45
\ No newline at end of file diff --git a/tests/auto/installer/treename/data/repository/componentB.sub1.sub2/1.0.0meta.7z b/tests/auto/installer/treename/data/repository/componentB.sub1.sub2/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..c449e57f6 --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentB.sub1.sub2/1.0.0meta.7z diff --git a/tests/auto/installer/treename/data/repository/componentB.sub1/1.0.0content.7z b/tests/auto/installer/treename/data/repository/componentB.sub1/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..d938d0fb2 --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentB.sub1/1.0.0content.7z diff --git a/tests/auto/installer/treename/data/repository/componentB.sub1/1.0.0content.7z.sha1 b/tests/auto/installer/treename/data/repository/componentB.sub1/1.0.0content.7z.sha1 new file mode 100644 index 000000000..3db5bca08 --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentB.sub1/1.0.0content.7z.sha1 @@ -0,0 +1 @@ +2407a2adb3d82211921b509e6dd792d67862de0e
\ No newline at end of file diff --git a/tests/auto/installer/treename/data/repository/componentB.sub1/1.0.0meta.7z b/tests/auto/installer/treename/data/repository/componentB.sub1/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..6996a4d01 --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentB.sub1/1.0.0meta.7z diff --git a/tests/auto/installer/treename/data/repository/componentB.sub2/1.0.0content.7z b/tests/auto/installer/treename/data/repository/componentB.sub2/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..7319cf08f --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentB.sub2/1.0.0content.7z diff --git a/tests/auto/installer/treename/data/repository/componentB.sub2/1.0.0content.7z.sha1 b/tests/auto/installer/treename/data/repository/componentB.sub2/1.0.0content.7z.sha1 new file mode 100644 index 000000000..855e2edab --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentB.sub2/1.0.0content.7z.sha1 @@ -0,0 +1 @@ +a8b85ffe4f91b4dc68a6402b314402949ef17a7a
\ No newline at end of file diff --git a/tests/auto/installer/treename/data/repository/componentB.sub2/1.0.0meta.7z b/tests/auto/installer/treename/data/repository/componentB.sub2/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..b91e41207 --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentB.sub2/1.0.0meta.7z diff --git a/tests/auto/installer/treename/data/repository/componentB/1.0.0content.7z b/tests/auto/installer/treename/data/repository/componentB/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..b3a0e683c --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentB/1.0.0content.7z diff --git a/tests/auto/installer/treename/data/repository/componentB/1.0.0content.7z.sha1 b/tests/auto/installer/treename/data/repository/componentB/1.0.0content.7z.sha1 new file mode 100644 index 000000000..377526fb6 --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentB/1.0.0content.7z.sha1 @@ -0,0 +1 @@ +274b3dbe9cceeca1b577eb2a8302d7690ad93eb3
\ No newline at end of file diff --git a/tests/auto/installer/treename/data/repository/componentB/1.0.0meta.7z b/tests/auto/installer/treename/data/repository/componentB/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..e9ab3969d --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentB/1.0.0meta.7z diff --git a/tests/auto/installer/treename/data/repository/componentC/1.0.0content.7z b/tests/auto/installer/treename/data/repository/componentC/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..7eca1e977 --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentC/1.0.0content.7z diff --git a/tests/auto/installer/treename/data/repository/componentC/1.0.0content.7z.sha1 b/tests/auto/installer/treename/data/repository/componentC/1.0.0content.7z.sha1 new file mode 100644 index 000000000..d3b44feee --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentC/1.0.0content.7z.sha1 @@ -0,0 +1 @@ +d3015ef5340508ad426c43daa2517c7b62581bab
\ No newline at end of file diff --git a/tests/auto/installer/treename/data/repository/componentC/1.0.0meta.7z b/tests/auto/installer/treename/data/repository/componentC/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..47ea321ec --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentC/1.0.0meta.7z diff --git a/tests/auto/installer/treename/data/repository/componentD/1.0.0content.7z b/tests/auto/installer/treename/data/repository/componentD/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..2299f9812 --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentD/1.0.0content.7z diff --git a/tests/auto/installer/treename/data/repository/componentD/1.0.0content.7z.sha1 b/tests/auto/installer/treename/data/repository/componentD/1.0.0content.7z.sha1 new file mode 100644 index 000000000..51dcdd0ed --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentD/1.0.0content.7z.sha1 @@ -0,0 +1 @@ +5ce5b91fb7ce209d83ba616ac01bf30e2942f70c
\ No newline at end of file diff --git a/tests/auto/installer/treename/data/repository/componentD/1.0.0meta.7z b/tests/auto/installer/treename/data/repository/componentD/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..3443e843b --- /dev/null +++ b/tests/auto/installer/treename/data/repository/componentD/1.0.0meta.7z diff --git a/tests/auto/installer/treename/data/repository_children/Updates.xml b/tests/auto/installer/treename/data/repository_children/Updates.xml new file mode 100644 index 000000000..a17f481d6 --- /dev/null +++ b/tests/auto/installer/treename/data/repository_children/Updates.xml @@ -0,0 +1,229 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>componentA</Name> + <DisplayName>Component A</DisplayName> + <Description>This component does not depend on any other component.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>100</SortingPriority> + <TreeName moveChildren="true">componentANew</TreeName> + <UpdateFile UncompressedSize="99" CompressedSize="263" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>8148a84c9a52eb989525f4807482f42c49c743a4</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentA.subcomponent1</Name> + <DisplayName>Subcomponent 1</DisplayName> + <Description>This component does not have leaf components.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>100</SortingPriority> + <UpdateFile UncompressedSize="99" CompressedSize="267" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>c0c5d273b9c413db07fbd1ffee58759f0059d668</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentB</Name> + <DisplayName>Component B (automatic dependency to componentA.subcomponent1)</DisplayName> + <Description>This component has an automatic dependency, If the dependency is marked for installation, this component is also installed.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>90</SortingPriority> + <AutoDependOn>componentA.subcomponent1</AutoDependOn> + <UpdateFile UncompressedSize="99" CompressedSize="263" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>c517b08c40ef5c5984f6bf34a626060dcbab6ba5</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentE</Name> + <DisplayName>Component E</DisplayName> + <Description>This is a component.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>60</SortingPriority> + <UpdateFile UncompressedSize="99" CompressedSize="263" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>2833ea6d508925e64f00fb6b699532992b923ab2</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentF</Name> + <DisplayName>Component F</DisplayName> + <Description>This component contains 2 subcomponents.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>40</SortingPriority> + <UpdateFile UncompressedSize="99" CompressedSize="263" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>21ca242b83ce32dfe066348cbb453080b5967e30</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentF.subcomponent1</Name> + <DisplayName>Subcomponent 1</DisplayName> + <Description>This component contains 2 leaf components.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>100</SortingPriority> + <TreeName moveChildren="true">FSub1ToRoot</TreeName> + <UpdateFile UncompressedSize="99" CompressedSize="267" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>e2745196bceaae476cac330f0af0ce6e564d2d3d</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentF.subcomponent1.subsubcomponent1</Name> + <DisplayName>Subsubcomponent 1</DisplayName> + <Description>This component does not depend on any other component.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>100</SortingPriority> + <UpdateFile UncompressedSize="99" CompressedSize="271" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>8af98107adadb1fda37c1c086c53ed289cc77661</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentF.subcomponent1.subsubcomponent2</Name> + <DisplayName>Subsubcomponent 2</DisplayName> + <Description>This component does not depend on any other component.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>50</SortingPriority> + <UpdateFile UncompressedSize="99" CompressedSize="271" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>69458b616989a44e52b480dd9133721bc52b1558</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentF.subcomponent2</Name> + <DisplayName>Subcomponent 2</DisplayName> + <Description>This component contains 2 leaf components.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>50</SortingPriority> + <TreeName moveChildren="true">componentE.sub1</TreeName> + <UpdateFile UncompressedSize="99" CompressedSize="267" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>9d985ee35442e6e621f8ec24dc41be9f6cab9dad</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentF.subcomponent2.subsubcomponent1</Name> + <DisplayName>Subsubcomponent 1</DisplayName> + <Description>This component does not depend on any other component.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>100</SortingPriority> + <UpdateFile UncompressedSize="99" CompressedSize="271" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>43223427efd8c2a428ead343a79709cd1bfc5618</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentF.subcomponent2.subsubcomponent2</Name> + <DisplayName>Subsubcomponent 2</DisplayName> + <Description>This component does not depend on any other component.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>50</SortingPriority> + <UpdateFile UncompressedSize="99" CompressedSize="271" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>d76690fb2f41aab262d7d8621c46fa464f35a550</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentH</Name> + <DisplayName>Component H</DisplayName> + <Description>An example component without dependencies.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>30</SortingPriority> + <TreeName moveChildren="true">componentI</TreeName> + <UpdateFile UncompressedSize="99" CompressedSize="263" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>04426aec311900e8d74ae42cc6fe49282d314841</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentH.subcomponent1</Name> + <DisplayName>Subcomponent 1</DisplayName> + <Description>This component does not contain leaf components.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>100</SortingPriority> + <UpdateFile UncompressedSize="99" CompressedSize="267" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>065a901fd86d4e7fd86200da47079c97070178c7</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentI.subcomponent2</Name> + <DisplayName>Subcomponent 1</DisplayName> + <Description>Subcomponent without original parent.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>30</SortingPriority> + <UpdateFile UncompressedSize="99" CompressedSize="267" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>3d2d928ed10455fe884cab96498a3fc826505406</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentJ</Name> + <DisplayName>Component J</DisplayName> + <Description>An example component without dependencies.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>30</SortingPriority> + <TreeName moveChildren="true">componentJNew</TreeName> + <UpdateFile UncompressedSize="99" CompressedSize="263" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>1a46e58cd1824b2c0a4a93d6b27050eb0f6feb29</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentJ.subcomponent1</Name> + <DisplayName>Subcomponent 1</DisplayName> + <Description>Subcomponent with parent.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>30</SortingPriority> + <UpdateFile UncompressedSize="99" CompressedSize="267" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>dd1cfaa8f6cd14f81635e8917f348006ca7ffdce</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentK</Name> + <DisplayName>Component K (depends on componentJ.subcomponent1)</DisplayName> + <Description>This component depends on Component J subcomponent.</Description> + <Dependencies>componentJ.subcomponent1</Dependencies> + <Version>1.0.0</Version> + <ReleaseDate>2014-08-25</ReleaseDate> + <SortingPriority>80</SortingPriority> + <UpdateFile UncompressedSize="99" CompressedSize="263" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>98253c1ab872c9baa64d2fe3525f86a65e73d1f2</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>componentL</Name> + <DisplayName>Component L</DisplayName> + <Description>Component with tree name, is replaced by other component.</Description> + <Version>1.0.0</Version> + <ReleaseDate>2022-01-01</ReleaseDate> + <TreeName moveChildren="true">LToNewRoot</TreeName> + </PackageUpdate> + <PackageUpdate> + <Name>componentL.sub1</Name> + <DisplayName>Component L subcomponent 1</DisplayName> + <Description>Child of component L</Description> + <Version>1.0.0</Version> + <ReleaseDate>2022-01-01</ReleaseDate> + </PackageUpdate> + <PackageUpdate> + <Name>componentL.sub2</Name> + <DisplayName>Component L subcomponent 2</DisplayName> + <Description>Child of component L</Description> + <Version>1.0.0</Version> + <ReleaseDate>2022-01-01</ReleaseDate> + </PackageUpdate> + <PackageUpdate> + <Name>componentM</Name> + <DisplayName>Component M</DisplayName> + <Description>Component that replaces other component</Description> + <Version>1.0.0</Version> + <ReleaseDate>2022-01-01</ReleaseDate> + <Replaces>componentL</Replaces> + </PackageUpdate> +</Updates> diff --git a/tests/auto/installer/treename/data/repository_children/componentA.subcomponent1/1.0.0content.7z b/tests/auto/installer/treename/data/repository_children/componentA.subcomponent1/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..095fd7e30 --- /dev/null +++ b/tests/auto/installer/treename/data/repository_children/componentA.subcomponent1/1.0.0content.7z diff --git a/tests/auto/installer/treename/data/repository_children/componentA.subcomponent1/1.0.0meta.7z b/tests/auto/installer/treename/data/repository_children/componentA.subcomponent1/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..5dcce5d73 --- /dev/null +++ b/tests/auto/installer/treename/data/repository_children/componentA.subcomponent1/1.0.0meta.7z diff --git a/tests/auto/installer/treename/data/repository_children/componentA/1.0.0content.7z b/tests/auto/installer/treename/data/repository_children/componentA/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..21d62e629 --- /dev/null +++ b/tests/auto/installer/treename/data/repository_children/componentA/1.0.0content.7z diff --git a/tests/auto/installer/treename/data/repository_children/componentA/1.0.0meta.7z b/tests/auto/installer/treename/data/repository_children/componentA/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..094ae8806 --- /dev/null +++ b/tests/auto/installer/treename/data/repository_children/componentA/1.0.0meta.7z diff --git a/tests/auto/installer/treename/data/repository_children/componentB/1.0.0content.7z b/tests/auto/installer/treename/data/repository_children/componentB/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..2cb5dfee9 --- /dev/null +++ b/tests/auto/installer/treename/data/repository_children/componentB/1.0.0content.7z diff --git a/tests/auto/installer/treename/data/repository_children/componentB/1.0.0meta.7z b/tests/auto/installer/treename/data/repository_children/componentB/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..d3ed0961e --- /dev/null +++ b/tests/auto/installer/treename/data/repository_children/componentB/1.0.0meta.7z diff --git a/tests/auto/installer/treename/data/repository_children/componentE/1.0.0content.7z b/tests/auto/installer/treename/data/repository_children/componentE/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..cfdef213e --- /dev/null +++ b/tests/auto/installer/treename/data/repository_children/componentE/1.0.0content.7z diff --git a/tests/auto/installer/treename/data/repository_children/componentE/1.0.0meta.7z b/tests/auto/installer/treename/data/repository_children/componentE/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..466926547 --- /dev/null +++ b/tests/auto/installer/treename/data/repository_children/componentE/1.0.0meta.7z diff --git a/tests/auto/installer/treename/data/repository_children/componentF.subcomponent1.subsubcomponent1/1.0.0content.7z b/tests/auto/installer/treename/data/repository_children/componentF.subcomponent1.subsubcomponent1/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..3e9297acc --- /dev/null +++ b/tests/auto/installer/treename/data/repository_children/componentF.subcomponent1.subsubcomponent1/1.0.0content.7z diff --git a/tests/auto/installer/treename/data/repository_children/componentF.subcomponent1.subsubcomponent1/1.0.0meta.7z b/tests/auto/installer/treename/data/repository_children/componentF.subcomponent1.subsubcomponent1/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..7adec9a82 --- /dev/null +++ b/tests/auto/installer/treename/data/repository_children/componentF.subcomponent1.subsubcomponent1/1.0.0meta.7z diff --git a/tests/auto/installer/treename/data/repository_children/componentF.subcomponent1.subsubcomponent2/1.0.0content.7z b/tests/auto/installer/treename/data/repository_children/componentF.subcomponent1.subsubcomponent2/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..b715e5587 --- /dev/null +++ b/tests/auto/installer/treename/data/repository_children/componentF.subcomponent1.subsubcomponent2/1.0.0content.7z diff --git a/tests/auto/installer/treename/data/repository_children/componentF.subcomponent1.subsubcomponent2/1.0.0meta.7z b/tests/auto/installer/treename/data/repository_children/componentF.subcomponent1.subsubcomponent2/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..69406b1b2 --- /dev/null +++ b/tests/auto/installer/treename/data/repository_children/componentF.subcomponent1.subsubcomponent2/1.0.0meta.7z diff --git a/tests/auto/installer/treename/data/repository_children/componentF.subcomponent1/1.0.0content.7z b/tests/auto/installer/treename/data/repository_children/componentF.subcomponent1/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..f2d2141d7 --- /dev/null +++ b/tests/auto/installer/treename/data/repository_children/componentF.subcomponent1/1.0.0content.7z diff --git a/tests/auto/installer/treename/data/repository_children/componentF.subcomponent1/1.0.0meta.7z b/tests/auto/installer/treename/data/repository_children/componentF.subcomponent1/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..1f5c58d2d --- /dev/null +++ b/tests/auto/installer/treename/data/repository_children/componentF.subcomponent1/1.0.0meta.7z diff --git a/tests/auto/installer/treename/data/repository_children/componentF.subcomponent2.subsubcomponent1/1.0.0content.7z b/tests/auto/installer/treename/data/repository_children/componentF.subcomponent2.subsubcomponent1/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..5307b3de4 --- /dev/null +++ b/tests/auto/installer/treename/data/repository_children/componentF.subcomponent2.subsubcomponent1/1.0.0content.7z diff --git a/tests/auto/installer/treename/data/repository_children/componentF.subcomponent2.subsubcomponent1/1.0.0meta.7z b/tests/auto/installer/treename/data/repository_children/componentF.subcomponent2.subsubcomponent1/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..1b44385ab --- /dev/null +++ b/tests/auto/installer/treename/data/repository_children/componentF.subcomponent2.subsubcomponent1/1.0.0meta.7z diff --git a/tests/auto/installer/treename/data/repository_children/componentF.subcomponent2.subsubcomponent2/1.0.0content.7z b/tests/auto/installer/treename/data/repository_children/componentF.subcomponent2.subsubcomponent2/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..7e83e996e --- /dev/null +++ b/tests/auto/installer/treename/data/repository_children/componentF.subcomponent2.subsubcomponent2/1.0.0content.7z diff --git a/tests/auto/installer/treename/data/repository_children/componentF.subcomponent2.subsubcomponent2/1.0.0meta.7z b/tests/auto/installer/treename/data/repository_children/componentF.subcomponent2.subsubcomponent2/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..c89ac2b7b --- /dev/null +++ b/tests/auto/installer/treename/data/repository_children/componentF.subcomponent2.subsubcomponent2/1.0.0meta.7z diff --git a/tests/auto/installer/treename/data/repository_children/componentF.subcomponent2/1.0.0content.7z b/tests/auto/installer/treename/data/repository_children/componentF.subcomponent2/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..9c97e4a99 --- /dev/null +++ b/tests/auto/installer/treename/data/repository_children/componentF.subcomponent2/1.0.0content.7z diff --git a/tests/auto/installer/treename/data/repository_children/componentF.subcomponent2/1.0.0meta.7z b/tests/auto/installer/treename/data/repository_children/componentF.subcomponent2/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..258b3905f --- /dev/null +++ b/tests/auto/installer/treename/data/repository_children/componentF.subcomponent2/1.0.0meta.7z diff --git a/tests/auto/installer/treename/data/repository_children/componentF/1.0.0content.7z b/tests/auto/installer/treename/data/repository_children/componentF/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..12c4c1248 --- /dev/null +++ b/tests/auto/installer/treename/data/repository_children/componentF/1.0.0content.7z diff --git a/tests/auto/installer/treename/data/repository_children/componentF/1.0.0meta.7z b/tests/auto/installer/treename/data/repository_children/componentF/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..88ec39233 --- /dev/null +++ b/tests/auto/installer/treename/data/repository_children/componentF/1.0.0meta.7z diff --git a/tests/auto/installer/treename/data/repository_children/componentH.subcomponent1/1.0.0content.7z b/tests/auto/installer/treename/data/repository_children/componentH.subcomponent1/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..4b2747235 --- /dev/null +++ b/tests/auto/installer/treename/data/repository_children/componentH.subcomponent1/1.0.0content.7z diff --git a/tests/auto/installer/treename/data/repository_children/componentH.subcomponent1/1.0.0meta.7z b/tests/auto/installer/treename/data/repository_children/componentH.subcomponent1/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..ab120d4c3 --- /dev/null +++ b/tests/auto/installer/treename/data/repository_children/componentH.subcomponent1/1.0.0meta.7z diff --git a/tests/auto/installer/treename/data/repository_children/componentH/1.0.0content.7z b/tests/auto/installer/treename/data/repository_children/componentH/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..767f789ff --- /dev/null +++ b/tests/auto/installer/treename/data/repository_children/componentH/1.0.0content.7z diff --git a/tests/auto/installer/treename/data/repository_children/componentH/1.0.0meta.7z b/tests/auto/installer/treename/data/repository_children/componentH/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..e5c9b47c9 --- /dev/null +++ b/tests/auto/installer/treename/data/repository_children/componentH/1.0.0meta.7z diff --git a/tests/auto/installer/treename/data/repository_children/componentI.subcomponent1/1.0.0content.7z b/tests/auto/installer/treename/data/repository_children/componentI.subcomponent1/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..2000479c9 --- /dev/null +++ b/tests/auto/installer/treename/data/repository_children/componentI.subcomponent1/1.0.0content.7z diff --git a/tests/auto/installer/treename/data/repository_children/componentI.subcomponent1/1.0.0meta.7z b/tests/auto/installer/treename/data/repository_children/componentI.subcomponent1/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..8ecfeaca8 --- /dev/null +++ b/tests/auto/installer/treename/data/repository_children/componentI.subcomponent1/1.0.0meta.7z diff --git a/tests/auto/installer/treename/data/repository_children/componentI.subcomponent2/1.0.0content.7z b/tests/auto/installer/treename/data/repository_children/componentI.subcomponent2/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..09a8e921a --- /dev/null +++ b/tests/auto/installer/treename/data/repository_children/componentI.subcomponent2/1.0.0content.7z diff --git a/tests/auto/installer/treename/data/repository_children/componentI.subcomponent2/1.0.0meta.7z b/tests/auto/installer/treename/data/repository_children/componentI.subcomponent2/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..acaccd042 --- /dev/null +++ b/tests/auto/installer/treename/data/repository_children/componentI.subcomponent2/1.0.0meta.7z diff --git a/tests/auto/installer/treename/data/repository_children/componentJ.subcomponent1/1.0.0content.7z b/tests/auto/installer/treename/data/repository_children/componentJ.subcomponent1/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..25247bad4 --- /dev/null +++ b/tests/auto/installer/treename/data/repository_children/componentJ.subcomponent1/1.0.0content.7z diff --git a/tests/auto/installer/treename/data/repository_children/componentJ.subcomponent1/1.0.0meta.7z b/tests/auto/installer/treename/data/repository_children/componentJ.subcomponent1/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..c45a63b41 --- /dev/null +++ b/tests/auto/installer/treename/data/repository_children/componentJ.subcomponent1/1.0.0meta.7z diff --git a/tests/auto/installer/treename/data/repository_children/componentJ/1.0.0content.7z b/tests/auto/installer/treename/data/repository_children/componentJ/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..aa3354b8c --- /dev/null +++ b/tests/auto/installer/treename/data/repository_children/componentJ/1.0.0content.7z diff --git a/tests/auto/installer/treename/data/repository_children/componentJ/1.0.0meta.7z b/tests/auto/installer/treename/data/repository_children/componentJ/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..14b41bdfe --- /dev/null +++ b/tests/auto/installer/treename/data/repository_children/componentJ/1.0.0meta.7z diff --git a/tests/auto/installer/treename/data/repository_children/componentK/1.0.0content.7z b/tests/auto/installer/treename/data/repository_children/componentK/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..e28bb9ea7 --- /dev/null +++ b/tests/auto/installer/treename/data/repository_children/componentK/1.0.0content.7z diff --git a/tests/auto/installer/treename/data/repository_children/componentK/1.0.0meta.7z b/tests/auto/installer/treename/data/repository_children/componentK/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..9112f88c3 --- /dev/null +++ b/tests/auto/installer/treename/data/repository_children/componentK/1.0.0meta.7z diff --git a/tests/auto/installer/treename/settings.qrc b/tests/auto/installer/treename/settings.qrc new file mode 100644 index 000000000..9b31cbade --- /dev/null +++ b/tests/auto/installer/treename/settings.qrc @@ -0,0 +1,65 @@ +<RCC> + <qresource prefix="/"> + <file>data/components.xml</file> + + <file>data/repository/Updates.xml</file> + <file>data/repository/componentA/1.0.0meta.7z</file> + <file>data/repository/componentA/1.0.0content.7z</file> + <file>data/repository/componentA.sub1/1.0.0meta.7z</file> + <file>data/repository/componentA.sub1/1.0.0content.7z</file> + <file>data/repository/componentA.sub2/1.0.0meta.7z</file> + <file>data/repository/componentA.sub2/1.0.0content.7z</file> + <file>data/repository/componentB/1.0.0meta.7z</file> + <file>data/repository/componentB/1.0.0content.7z</file> + <file>data/repository/componentB.sub1/1.0.0meta.7z</file> + <file>data/repository/componentB.sub1/1.0.0content.7z</file> + <file>data/repository/componentB.sub1.sub1/1.0.0meta.7z</file> + <file>data/repository/componentB.sub1.sub1/1.0.0content.7z</file> + <file>data/repository/componentB.sub1.sub2/1.0.0meta.7z</file> + <file>data/repository/componentB.sub1.sub2/1.0.0content.7z</file> + <file>data/repository/componentB.sub2/1.0.0meta.7z</file> + <file>data/repository/componentB.sub2/1.0.0content.7z</file> + <file>data/repository/componentC/1.0.0meta.7z</file> + <file>data/repository/componentC/1.0.0content.7z</file> + <file>data/repository/componentD/1.0.0meta.7z</file> + <file>data/repository/componentD/1.0.0content.7z</file> + + <file>data/invalid_repository/Updates.xml</file> + + <file>data/repository_children/componentA/1.0.0content.7z</file> + <file>data/repository_children/componentA/1.0.0meta.7z</file> + <file>data/repository_children/componentA.subcomponent1/1.0.0content.7z</file> + <file>data/repository_children/componentA.subcomponent1/1.0.0meta.7z</file> + <file>data/repository_children/componentB/1.0.0content.7z</file> + <file>data/repository_children/componentB/1.0.0meta.7z</file> + <file>data/repository_children/componentE/1.0.0content.7z</file> + <file>data/repository_children/componentE/1.0.0meta.7z</file> + <file>data/repository_children/componentF/1.0.0content.7z</file> + <file>data/repository_children/componentF/1.0.0meta.7z</file> + <file>data/repository_children/componentF.subcomponent1/1.0.0content.7z</file> + <file>data/repository_children/componentF.subcomponent1/1.0.0meta.7z</file> + <file>data/repository_children/componentF.subcomponent1.subsubcomponent1/1.0.0content.7z</file> + <file>data/repository_children/componentF.subcomponent1.subsubcomponent1/1.0.0meta.7z</file> + <file>data/repository_children/componentF.subcomponent1.subsubcomponent2/1.0.0content.7z</file> + <file>data/repository_children/componentF.subcomponent1.subsubcomponent2/1.0.0meta.7z</file> + <file>data/repository_children/componentF.subcomponent2/1.0.0content.7z</file> + <file>data/repository_children/componentF.subcomponent2/1.0.0meta.7z</file> + <file>data/repository_children/componentF.subcomponent2.subsubcomponent1/1.0.0content.7z</file> + <file>data/repository_children/componentF.subcomponent2.subsubcomponent1/1.0.0meta.7z</file> + <file>data/repository_children/componentF.subcomponent2.subsubcomponent2/1.0.0content.7z</file> + <file>data/repository_children/componentF.subcomponent2.subsubcomponent2/1.0.0meta.7z</file> + <file>data/repository_children/componentH/1.0.0content.7z</file> + <file>data/repository_children/componentH/1.0.0meta.7z</file> + <file>data/repository_children/componentH.subcomponent1/1.0.0content.7z</file> + <file>data/repository_children/componentH.subcomponent1/1.0.0meta.7z</file> + <file>data/repository_children/componentI.subcomponent2/1.0.0content.7z</file> + <file>data/repository_children/componentI.subcomponent2/1.0.0meta.7z</file> + <file>data/repository_children/componentJ/1.0.0content.7z</file> + <file>data/repository_children/componentJ/1.0.0meta.7z</file> + <file>data/repository_children/componentJ.subcomponent1/1.0.0content.7z</file> + <file>data/repository_children/componentJ.subcomponent1/1.0.0meta.7z</file> + <file>data/repository_children/componentK/1.0.0content.7z</file> + <file>data/repository_children/componentK/1.0.0meta.7z</file> + <file>data/repository_children/Updates.xml</file> + </qresource> +</RCC> diff --git a/tests/auto/installer/treename/treename.pro b/tests/auto/installer/treename/treename.pro new file mode 100644 index 000000000..97315faad --- /dev/null +++ b/tests/auto/installer/treename/treename.pro @@ -0,0 +1,10 @@ +include(../../qttest.pri) + +QT -= gui +QT += testlib + +SOURCES += tst_treename.cpp + +RESOURCES += \ + settings.qrc \ + ../shared/config.qrc diff --git a/tests/auto/installer/treename/tst_treename.cpp b/tests/auto/installer/treename/tst_treename.cpp new file mode 100644 index 000000000..2c8be6ddd --- /dev/null +++ b/tests/auto/installer/treename/tst_treename.cpp @@ -0,0 +1,457 @@ +/************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ +#include "../shared/packagemanager.h" +#include "../shared/verifyinstaller.h" + +#include <packagemanagercore.h> +#include <component.h> +#include <componentmodel.h> + +#include <QTest> +#include <QRegularExpression> + +class tst_TreeName : public QObject +{ + Q_OBJECT + +private slots: + void moveToRoot(); + void moveToSubItem(); + void dependencyToMovedItem(); + void autodependOnMovedItem(); + + void moveToExistingAllowUnstableComponents(); + void moveToExistingItemNoUnstableComponents(); + void moveWithChildrenChildConflictsAllowUnstable(); + void moveWithChildrenChildConflictsNoUnstable(); + + void moveToRootWithChildren(); + void moveToSubItemWithChildren(); + void moveToAvailableParentItemWithChilren(); + void dependencyToMovedSubItem(); + void autoDependOnMovedSubItem(); + + void replaceComponentWithTreeName(); + void replaceComponentWithTreeNameMoveChildren(); + + void remotePackageConflictsLocal(); + + void init(); + void cleanup(); + +private: + QString m_installDir; + +}; + +void tst_TreeName::moveToRoot() +{ + // componentB.sub1.sub1 moved from sub item to root (BSub1Sub1ToRoot) + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (m_installDir, ":///data/repository")); + QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() << "componentB.sub1.sub1")); + QList<Component*> installedComponents = core->orderedComponentsToInstall(); + + QCOMPARE(installedComponents.count(), 1); + QCOMPARE(installedComponents.at(0)->name(), "componentB.sub1.sub1"); + QCOMPARE(installedComponents.at(0)->treeName(), "BSub1Sub1ToRoot"); + QVERIFY(core->componentByName("componentB.sub1.sub1") != 0); + QVERIFY(core->componentByName("BSub1Sub1ToRoot") == 0); + VerifyInstaller::verifyInstallerResources(m_installDir, "componentB.sub1.sub1", "1.0.0content.txt"); + VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" + << "componentBSub1Sub1.txt"); +} + +void tst_TreeName::moveToSubItem() +{ + // componentB.sub1.sub2 moved under componentC (componentC.sub1) + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (m_installDir, ":///data/repository")); + + QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() << "componentC")); + VerifyInstaller::verifyInstallerResources(m_installDir, "componentB.sub1.sub2", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "componentC", "1.0.0content.txt"); + VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" + << "componentBSub1Sub2.txt" << "componentC.txt"); +} + +void tst_TreeName::dependencyToMovedItem() +{ + // componentA depends on componentB.sub2 which is moved to root + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (m_installDir, ":///data/repository")); + QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() << "componentA")); + + VerifyInstaller::verifyInstallerResources(m_installDir, "componentA", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "componentA.sub1", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "componentB.sub2", "1.0.0content.txt"); + VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" + << "componentA.txt" << "componentASub1.txt" << "componentBSub2.txt"); +} + +void tst_TreeName::autodependOnMovedItem() +{ + // componentD autodepends on componentA.sub2 which is moved to root + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (m_installDir, ":///data/repository")); + QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() << "componentA.sub2")); + VerifyInstaller::verifyInstallerResources(m_installDir, "componentA.sub2", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "componentD", "1.0.0content.txt"); + VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" + << "componentASub2.txt" << "componentD.txt"); +} + +void tst_TreeName::moveToExistingAllowUnstableComponents() +{ + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (m_installDir, ":///data/invalid_repository")); + core->settings().setAllowUnstableComponents(true); + + QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() << "componentA")); + QVERIFY(core->componentByName("componentB")->isUnstable()); +} + +void tst_TreeName::moveToExistingItemNoUnstableComponents() +{ + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (m_installDir, ":///data/invalid_repository")); + core->settings().setAllowUnstableComponents(false); + + QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() << "componentA")); + QVERIFY(!core->componentByName("componentB")); +} + +void tst_TreeName::replaceComponentWithTreeName() +{ + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (m_installDir, ":///data/repository")); + + QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() << "componentF")); + QVERIFY(core->componentByName("componentF")->value(scTreeName).isEmpty()); + QVERIFY(!core->componentByName("componentE")); +} + +void tst_TreeName::replaceComponentWithTreeNameMoveChildren() +{ + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (m_installDir, ":///data/repository_children")); + + QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() << "componentM")); + QVERIFY(core->componentByName("componentM")->value(scTreeName).isEmpty()); + QVERIFY(!core->componentByName("componentL")); + + Component *component1 = core->componentByName("componentL.sub1"); + QCOMPARE(component1->treeName(), component1->name()); + + Component *component2 = core->componentByName("componentL.sub2"); + QCOMPARE(component2->treeName(), component2->name()); +} + +void tst_TreeName::moveWithChildrenChildConflictsAllowUnstable() +{ + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (m_installDir, ":///data/invalid_repository")); + core->settings().setAllowUnstableComponents(true); + + QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() << "componentD")); + Component *const component = core->componentByName("componentD.sub1"); + QVERIFY(component && component->isUnstable() && !component->isInstalled()); +} + +void tst_TreeName::moveWithChildrenChildConflictsNoUnstable() +{ + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (m_installDir, ":///data/invalid_repository")); + core->settings().setAllowUnstableComponents(false); + + QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() << "componentD")); + QVERIFY(!core->componentByName("componentD.sub1")); +} + +void tst_TreeName::moveToRootWithChildren() +{ + // componentF.subcomponent1 moved from sub item to root (FSub1ToRoot) + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (m_installDir, ":///data/repository_children")); + QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently( + QStringList() << "componentF.subcomponent1")); + const QList<Component*> installedComponents = core->orderedComponentsToInstall(); + + QCOMPARE(installedComponents.count(), 3); + + Component const *parent = installedComponents.at(0); + QCOMPARE(parent->name(), "componentF.subcomponent1"); + QCOMPARE(parent->treeName(), "FSub1ToRoot"); + QVERIFY(parent->value(scAutoTreeName).isEmpty()); + + Component const *child1 = installedComponents.at(1); + QCOMPARE(child1->name(), "componentF.subcomponent1.subsubcomponent1"); + QCOMPARE(child1->treeName(), "FSub1ToRoot.subsubcomponent1"); + QCOMPARE(child1->treeName(), child1->value(scAutoTreeName)); + + Component const *child2 = installedComponents.at(2); + QCOMPARE(child2->name(), "componentF.subcomponent1.subsubcomponent2"); + QCOMPARE(child2->treeName(), "FSub1ToRoot.subsubcomponent2"); + QCOMPARE(child2->treeName(), child2->value(scAutoTreeName)); + + QVERIFY(core->componentByName("componentF.subcomponent1")); + QVERIFY(!core->componentByName("FSub1ToRoot")); + QVERIFY(core->componentByName("componentF.subcomponent1.subsubcomponent1")); + QVERIFY(!core->componentByName("FSub1ToRoot.subsubcomponent1")); + QVERIFY(core->componentByName("componentF.subcomponent1.subsubcomponent2")); + QVERIFY(!core->componentByName("FSub1ToRoot.subsubcomponent2")); + + VerifyInstaller::verifyInstallerResources(m_installDir, + "componentF.subcomponent1", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, + "componentF.subcomponent1.subsubcomponent1", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, + "componentF.subcomponent1.subsubcomponent2", "1.0.0content.txt"); + VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" + << "installcontentF_1.txt" << "installcontentF_1_1.txt" << "installcontentF_1_2.txt"); +} + +void tst_TreeName::moveToSubItemWithChildren() +{ + // componentF.subcomponent2 moved under componentE (componentE.sub1) + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (m_installDir, ":///data/repository_children")); + QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently( + QStringList() << "componentF.subcomponent2")); + const QList<Component*> installedComponents = core->orderedComponentsToInstall(); + + QCOMPARE(installedComponents.count(), 4); + + Component const *parent = installedComponents.at(1); + QCOMPARE(parent->name(), "componentF.subcomponent2"); + QCOMPARE(parent->treeName(), "componentE.sub1"); + QVERIFY(parent->value(scAutoTreeName).isEmpty()); + + Component const *child1 = installedComponents.at(2); + QCOMPARE(child1->name(), "componentF.subcomponent2.subsubcomponent1"); + QCOMPARE(child1->treeName(), "componentE.sub1.subsubcomponent1"); + QCOMPARE(child1->treeName(), child1->value(scAutoTreeName)); + + Component const *child2 = installedComponents.at(3); + QCOMPARE(child2->name(), "componentF.subcomponent2.subsubcomponent2"); + QCOMPARE(child2->treeName(), "componentE.sub1.subsubcomponent2"); + QCOMPARE(child2->treeName(), child2->value(scAutoTreeName)); + + QVERIFY(core->componentByName("componentF.subcomponent2")); + QVERIFY(!core->componentByName("componentE.sub1")); + QVERIFY(core->componentByName("componentF.subcomponent2.subsubcomponent1")); + QVERIFY(!core->componentByName("componentE.sub1.subsubcomponent1")); + QVERIFY(core->componentByName("componentF.subcomponent2.subsubcomponent2")); + QVERIFY(!core->componentByName("componentE.sub1.subsubcomponent2")); + + VerifyInstaller::verifyInstallerResources(m_installDir, "componentE", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, + "componentF.subcomponent2", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, + "componentF.subcomponent2.subsubcomponent1", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, + "componentF.subcomponent2.subsubcomponent2", "1.0.0content.txt"); + VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" + << "installcontentE.txt" << "installcontentF_2.txt" << "installcontentF_2_1.txt" + << "installcontentF_2_2.txt"); +} + +void tst_TreeName::moveToAvailableParentItemWithChilren() +{ + // componentH moved to componentI + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (m_installDir, ":///data/repository_children")); + QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently( + QStringList() << "componentH")); + const QList<Component*> installedComponents = core->orderedComponentsToInstall(); + + QCOMPARE(installedComponents.count(), 3); + + Component const *parent = installedComponents.at(0); + QCOMPARE(parent->name(), "componentH"); + QCOMPARE(parent->treeName(), "componentI"); + QVERIFY(parent->value(scAutoTreeName).isEmpty()); + + Component const *child1 = installedComponents.at(1); + QCOMPARE(child1->name(), "componentH.subcomponent1"); + QCOMPARE(child1->treeName(), "componentI.subcomponent1"); + QCOMPARE(child1->treeName(), child1->value(scAutoTreeName)); + + Component const *child2 = installedComponents.at(2); + QCOMPARE(child2->name(), "componentI.subcomponent2"); + QCOMPARE(child2->treeName(), child2->name()); + QVERIFY(child2->value(scAutoTreeName).isEmpty()); + + QVERIFY(core->componentByName("componentH")); + QVERIFY(!core->componentByName("componentI")); + QVERIFY(core->componentByName("componentH.subcomponent1")); + QVERIFY(!core->componentByName("componentI.subcomponent1")); + QVERIFY(core->componentByName("componentI.subcomponent2")); + + VerifyInstaller::verifyInstallerResources(m_installDir, "componentH", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, + "componentH.subcomponent1", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, + "componentI.subcomponent2", "1.0.0content.txt"); + VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" + << "installcontentH.txt" << "installcontentH_1.txt" << "installcontentI_2.txt"); +} + +void tst_TreeName::dependencyToMovedSubItem() +{ + // componentK has dependency to componentJ.subcomponent1, which has a parent with treename + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (m_installDir, ":///data/repository_children")); + QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently( + QStringList() << "componentK")); + const QList<Component*> installedComponents = core->orderedComponentsToInstall(); + + QCOMPARE(installedComponents.count(), 2); + + Component const *component1 = installedComponents.at(0); + QCOMPARE(component1->name(), "componentJ.subcomponent1"); + QCOMPARE(component1->treeName(), "componentJNew.subcomponent1"); + QCOMPARE(component1->treeName(), component1->value(scAutoTreeName)); + + Component const *component2 = installedComponents.at(1); + QCOMPARE(component2->name(), "componentK"); + QCOMPARE(component2->treeName(), component2->name()); + QVERIFY(component2->value(scAutoTreeName).isEmpty()); + + VerifyInstaller::verifyInstallerResources(m_installDir, + "componentJ.subcomponent1", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "componentK", "1.0.0content.txt"); + VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" + << "installcontentJ_1.txt" << "installcontentK.txt"); +} + +void tst_TreeName::autoDependOnMovedSubItem() +{ + // componentB auto-depends on componentA.subcomponent1, which has a parent with treename + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (m_installDir, ":///data/repository_children")); + QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently( + QStringList() << "componentA.subcomponent1")); + const QList<Component*> installedComponents = core->orderedComponentsToInstall(); + + QCOMPARE(installedComponents.count(), 3); + + Component const *component1 = installedComponents.at(0); + QCOMPARE(component1->name(), "componentA"); + QCOMPARE(component1->treeName(), "componentANew"); + QVERIFY(component1->value(scAutoTreeName).isEmpty()); + + Component const *component2 = installedComponents.at(1); + QCOMPARE(component2->name(), "componentA.subcomponent1"); + QCOMPARE(component2->treeName(), "componentANew.subcomponent1"); + QCOMPARE(component2->treeName(), component2->value(scAutoTreeName)); + + Component const *component3 = installedComponents.at(2); + QCOMPARE(component3->name(), "componentB"); + QCOMPARE(component3->treeName(), component3->name()); + + VerifyInstaller::verifyInstallerResources(m_installDir, "componentA", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, + "componentA.subcomponent1", "1.0.0content.txt"); + VerifyInstaller::verifyInstallerResources(m_installDir, "componentB", "1.0.0content.txt"); + VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" + << "installcontentA.txt" << "installcontentA_1.txt" << "installcontentB.txt"); +} + +void tst_TreeName::remotePackageConflictsLocal() +{ + const QString packageHubFile = qApp->applicationDirPath() + QDir::separator() + "components.xml"; + QFile::remove(packageHubFile); + QVERIFY(QFile::copy(":///data/components.xml", packageHubFile)); + // For some reason Windows sets the read-only flag when we copy the resource.. + QVERIFY(setDefaultFilePermissions(packageHubFile, DefaultFilePermissions::NonExecutable)); + + QHash<QString, QString> params; + params.insert(scTargetDir, qApp->applicationDirPath()); + PackageManagerCore core(BinaryContent::MagicPackageManagerMarker, QList<OperationBlob>(), + QString(), QString(), Protocol::DefaultAuthorizationKey, Protocol::Mode::Production, params); + + core.settings().setAllowUnstableComponents(true); + core.settings().setDefaultRepositories(QSet<Repository>() + << Repository::fromUserInput(":///data/repository")); + + QVERIFY(core.fetchRemotePackagesTree()); + { + // Remote treename conflicts with local name + Component *const local = core.componentByName("ASub2ToRoot"); + QVERIFY(local && local->isInstalled()); + + Component *const remote = core.componentByName("componentA.sub2"); + QVERIFY(remote && remote->isUnstable()); + QCOMPARE(remote->treeName(), remote->name()); + } + { + // Remote treename conflicts with local treename + Component *const local = core.componentByName("B"); + QVERIFY(local && local->isInstalled() && local->treeName() == "BSub2ToRoot"); + + Component *const remote = core.componentByName("componentB.sub2"); + QVERIFY(remote && remote->isUnstable()); + QCOMPARE(remote->treeName(), remote->name()); + } + { + // Remote name conflicts with local treename + Component *const local = core.componentByName("C"); + QVERIFY(local && local->isInstalled() && local->treeName() == "componentA"); + + Component *const remote = core.componentByName("componentA"); + QVERIFY(!remote); + } + { + // Component has a treename in local but not in remote, add with local treename + Component *const component = core.componentByName("componentD"); + QVERIFY(component && component->isInstalled() && component->treeName() == "componentDNew"); + } + { + // Component has different treename in local and remote, add with local treename + Component *const component = core.componentByName("componentB.sub1.sub2"); + QVERIFY(component && component->isInstalled() && component->treeName() == "componentC.sub2"); + } + QVERIFY(QFile::remove(packageHubFile)); +} + +void tst_TreeName::init() +{ + m_installDir = QInstaller::generateTemporaryFileName(); + QVERIFY(QDir().mkpath(m_installDir)); +} + +void tst_TreeName::cleanup() +{ + QDir dir(m_installDir); + QVERIFY(dir.removeRecursively()); +} + +QTEST_MAIN(tst_TreeName) + +#include "tst_treename.moc" diff --git a/tests/auto/installer/unicodeexecutable/main.c b/tests/auto/installer/unicodeexecutable/main.c index d82e0cb60..bce0321ab 100644 --- a/tests/auto/installer/unicodeexecutable/main.c +++ b/tests/auto/installer/unicodeexecutable/main.c @@ -1,32 +1,26 @@ /************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Installer Framework. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/tests/auto/installer/unicodeexecutable/stringdata.h b/tests/auto/installer/unicodeexecutable/stringdata.h index 901fac31a..f938374fa 100644 --- a/tests/auto/installer/unicodeexecutable/stringdata.h +++ b/tests/auto/installer/unicodeexecutable/stringdata.h @@ -1,32 +1,26 @@ /************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Installer Framework. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/tests/auto/tools/repotest/packages/A/data/A.txt b/tests/auto/tools/repotest/packages/A/data/A.txt new file mode 100644 index 000000000..98114dd6e --- /dev/null +++ b/tests/auto/tools/repotest/packages/A/data/A.txt @@ -0,0 +1,2 @@ +Example content for package A. + diff --git a/tests/auto/tools/repotest/packages/A/meta/package.xml b/tests/auto/tools/repotest/packages/A/meta/package.xml new file mode 100644 index 000000000..8383b10c7 --- /dev/null +++ b/tests/auto/tools/repotest/packages/A/meta/package.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Package> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.0</Version> + <ReleaseDate>2020-01-01</ReleaseDate> + <Default>true</Default> + <Script>script1.0.0.qs</Script> +</Package> diff --git a/tests/auto/tools/repotest/packages/A/meta/script1.0.0.qs b/tests/auto/tools/repotest/packages/A/meta/script1.0.0.qs new file mode 100644 index 000000000..addf3329a --- /dev/null +++ b/tests/auto/tools/repotest/packages/A/meta/script1.0.0.qs @@ -0,0 +1,3 @@ +function Component() +{ +} diff --git a/tests/auto/tools/repotest/packages/B/data/B.txt b/tests/auto/tools/repotest/packages/B/data/B.txt new file mode 100644 index 000000000..1ee864074 --- /dev/null +++ b/tests/auto/tools/repotest/packages/B/data/B.txt @@ -0,0 +1,2 @@ +Example content for package B. + diff --git a/tests/auto/tools/repotest/packages/B/meta/package.xml b/tests/auto/tools/repotest/packages/B/meta/package.xml new file mode 100644 index 000000000..99b723d50 --- /dev/null +++ b/tests/auto/tools/repotest/packages/B/meta/package.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Package> + <DisplayName>B</DisplayName> + <Description>Example component B</Description> + <Version>1.0.0</Version> + <ReleaseDate>2020-01-01</ReleaseDate> + <Default>true</Default> +</Package> diff --git a/tests/auto/tools/repotest/packages_new/C/data/C.txt b/tests/auto/tools/repotest/packages_new/C/data/C.txt new file mode 100644 index 000000000..b45c73606 --- /dev/null +++ b/tests/auto/tools/repotest/packages_new/C/data/C.txt @@ -0,0 +1,2 @@ +Example content for package C. + diff --git a/tests/auto/tools/repotest/packages_new/C/meta/package.xml b/tests/auto/tools/repotest/packages_new/C/meta/package.xml new file mode 100644 index 000000000..676f088be --- /dev/null +++ b/tests/auto/tools/repotest/packages_new/C/meta/package.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Package> + <DisplayName>C</DisplayName> + <Description>Example component C</Description> + <Version>1.0.0</Version> + <ReleaseDate>2020-01-01</ReleaseDate> + <Default>true</Default> +</Package> diff --git a/tests/auto/tools/repotest/packages_update/A/data/A_update.txt b/tests/auto/tools/repotest/packages_update/A/data/A_update.txt new file mode 100644 index 000000000..98114dd6e --- /dev/null +++ b/tests/auto/tools/repotest/packages_update/A/data/A_update.txt @@ -0,0 +1,2 @@ +Example content for package A. + diff --git a/tests/auto/tools/repotest/packages_update/A/meta/package.xml b/tests/auto/tools/repotest/packages_update/A/meta/package.xml new file mode 100644 index 000000000..1763dc4d8 --- /dev/null +++ b/tests/auto/tools/repotest/packages_update/A/meta/package.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Package> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>2.0.0</Version> + <ReleaseDate>2020-01-01</ReleaseDate> + <Default>true</Default> + <Script>script2.0.0.qs</Script> +</Package> diff --git a/tests/auto/tools/repotest/packages_update/A/meta/script2.0.0.qs b/tests/auto/tools/repotest/packages_update/A/meta/script2.0.0.qs new file mode 100644 index 000000000..addf3329a --- /dev/null +++ b/tests/auto/tools/repotest/packages_update/A/meta/script2.0.0.qs @@ -0,0 +1,3 @@ +function Component() +{ +} diff --git a/tests/auto/tools/repotest/packages_update/B/data/B_update.txt b/tests/auto/tools/repotest/packages_update/B/data/B_update.txt new file mode 100644 index 000000000..1ee864074 --- /dev/null +++ b/tests/auto/tools/repotest/packages_update/B/data/B_update.txt @@ -0,0 +1,2 @@ +Example content for package B. + diff --git a/tests/auto/tools/repotest/packages_update/B/meta/package.xml b/tests/auto/tools/repotest/packages_update/B/meta/package.xml new file mode 100644 index 000000000..99b723d50 --- /dev/null +++ b/tests/auto/tools/repotest/packages_update/B/meta/package.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Package> + <DisplayName>B</DisplayName> + <Description>Example component B</Description> + <Version>1.0.0</Version> + <ReleaseDate>2020-01-01</ReleaseDate> + <Default>true</Default> +</Package> diff --git a/tests/auto/tools/repotest/repository_component/A/2.0.0content.7z b/tests/auto/tools/repotest/repository_component/A/2.0.0content.7z Binary files differnew file mode 100644 index 000000000..46e2c9124 --- /dev/null +++ b/tests/auto/tools/repotest/repository_component/A/2.0.0content.7z diff --git a/tests/auto/tools/repotest/repository_component/A/2.0.0content.7z.sha1 b/tests/auto/tools/repotest/repository_component/A/2.0.0content.7z.sha1 new file mode 100644 index 000000000..53010cea2 --- /dev/null +++ b/tests/auto/tools/repotest/repository_component/A/2.0.0content.7z.sha1 @@ -0,0 +1 @@ +059e5ed8cd3a1fbca08cccfa4075265192603e3f
\ No newline at end of file diff --git a/tests/auto/tools/repotest/repository_component/A/2.0.0meta.7z b/tests/auto/tools/repotest/repository_component/A/2.0.0meta.7z Binary files differnew file mode 100644 index 000000000..af0863696 --- /dev/null +++ b/tests/auto/tools/repotest/repository_component/A/2.0.0meta.7z diff --git a/tests/auto/tools/repotest/repository_component/B/1.0.0content.7z b/tests/auto/tools/repotest/repository_component/B/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..46e2c9124 --- /dev/null +++ b/tests/auto/tools/repotest/repository_component/B/1.0.0content.7z diff --git a/tests/auto/tools/repotest/repository_component/B/1.0.0content.7z.sha1 b/tests/auto/tools/repotest/repository_component/B/1.0.0content.7z.sha1 new file mode 100644 index 000000000..53010cea2 --- /dev/null +++ b/tests/auto/tools/repotest/repository_component/B/1.0.0content.7z.sha1 @@ -0,0 +1 @@ +059e5ed8cd3a1fbca08cccfa4075265192603e3f
\ No newline at end of file diff --git a/tests/auto/tools/repotest/repository_component/B/1.0.0meta.7z b/tests/auto/tools/repotest/repository_component/B/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..e5be1148e --- /dev/null +++ b/tests/auto/tools/repotest/repository_component/B/1.0.0meta.7z diff --git a/tests/auto/tools/repotest/repository_component/Updates.xml b/tests/auto/tools/repotest/repository_component/Updates.xml new file mode 100644 index 000000000..dfae8c8bd --- /dev/null +++ b/tests/auto/tools/repotest/repository_component/Updates.xml @@ -0,0 +1,28 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>true</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>2.0.0</Version> + <ReleaseDate>2020-01-01</ReleaseDate> + <Default>true</Default> + <Script>script2.0.0.qs</Script> + <UpdateFile UncompressedSize="40" CompressedSize="72" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>da6dae55a8cc3fb9f012e33fa7b9c187a823aa9a</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>B</Name> + <DisplayName>B</DisplayName> + <Description>Example component B</Description> + <Version>1.0.0</Version> + <ReleaseDate>2020-01-01</ReleaseDate> + <Default>true</Default> + <UpdateFile UncompressedSize="40" CompressedSize="72" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>d88b373458b4bbec38132692061bf1e7aa68e7f7</SHA1> + </PackageUpdate> +</Updates> diff --git a/tests/auto/tools/repotest/repository_componentAndUnite/2020-11-10-0816_meta.7z b/tests/auto/tools/repotest/repository_componentAndUnite/2020-11-10-0816_meta.7z Binary files differnew file mode 100644 index 000000000..6a17ac028 --- /dev/null +++ b/tests/auto/tools/repotest/repository_componentAndUnite/2020-11-10-0816_meta.7z diff --git a/tests/auto/tools/repotest/repository_componentAndUnite/A/2.0.0content.7z b/tests/auto/tools/repotest/repository_componentAndUnite/A/2.0.0content.7z Binary files differnew file mode 100644 index 000000000..ef8741d32 --- /dev/null +++ b/tests/auto/tools/repotest/repository_componentAndUnite/A/2.0.0content.7z diff --git a/tests/auto/tools/repotest/repository_componentAndUnite/A/2.0.0content.7z.sha1 b/tests/auto/tools/repotest/repository_componentAndUnite/A/2.0.0content.7z.sha1 new file mode 100644 index 000000000..d5e23fd53 --- /dev/null +++ b/tests/auto/tools/repotest/repository_componentAndUnite/A/2.0.0content.7z.sha1 @@ -0,0 +1 @@ +c7cca768ebfe60c4295a79762d4e19e63f2c21d2
\ No newline at end of file diff --git a/tests/auto/tools/repotest/repository_componentAndUnite/A/2.0.0meta.7z b/tests/auto/tools/repotest/repository_componentAndUnite/A/2.0.0meta.7z Binary files differnew file mode 100644 index 000000000..c3cf7f7fa --- /dev/null +++ b/tests/auto/tools/repotest/repository_componentAndUnite/A/2.0.0meta.7z diff --git a/tests/auto/tools/repotest/repository_componentAndUnite/C/1.0.0content.7z b/tests/auto/tools/repotest/repository_componentAndUnite/C/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..de70ee790 --- /dev/null +++ b/tests/auto/tools/repotest/repository_componentAndUnite/C/1.0.0content.7z diff --git a/tests/auto/tools/repotest/repository_componentAndUnite/C/1.0.0content.7z.sha1 b/tests/auto/tools/repotest/repository_componentAndUnite/C/1.0.0content.7z.sha1 new file mode 100644 index 000000000..c290ccf6c --- /dev/null +++ b/tests/auto/tools/repotest/repository_componentAndUnite/C/1.0.0content.7z.sha1 @@ -0,0 +1 @@ +0e995c11dc35bd2b4ac04d408eb7091f8322ea49
\ No newline at end of file diff --git a/tests/auto/tools/repotest/repository_componentAndUnite/C/1.0.0meta.7z b/tests/auto/tools/repotest/repository_componentAndUnite/C/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..8b389f955 --- /dev/null +++ b/tests/auto/tools/repotest/repository_componentAndUnite/C/1.0.0meta.7z diff --git a/tests/auto/tools/repotest/repository_componentAndUnite/Updates.xml b/tests/auto/tools/repotest/repository_componentAndUnite/Updates.xml new file mode 100644 index 000000000..802f0a53e --- /dev/null +++ b/tests/auto/tools/repotest/repository_componentAndUnite/Updates.xml @@ -0,0 +1,30 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>2.0.0</Version> + <ReleaseDate>2020-01-01</ReleaseDate> + <Default>true</Default> + <Script>script2.0.0.qs</Script> + <UpdateFile OS="Any" CompressedSize="240" UncompressedSize="74"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>11f74e8fbc7d6c155dd6503c460c2c1955340cc1</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>C</Name> + <DisplayName>C</DisplayName> + <Description>Example component C</Description> + <Version>1.0.0</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <UpdateFile OS="Any" CompressedSize="239" UncompressedSize="89"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>4558f31428ef88eb23521b4f119465967945e2f7</SHA1> + </PackageUpdate> + <SHA1>d674e6574895c02d3a02fb97a46b159d35f17c68</SHA1> + <MetadataName>2020-11-10-0816_meta.7z</MetadataName> +</Updates> diff --git a/tests/auto/tools/repotest/repository_unite/2020-11-10-0931_meta.7z b/tests/auto/tools/repotest/repository_unite/2020-11-10-0931_meta.7z Binary files differnew file mode 100644 index 000000000..4008dc656 --- /dev/null +++ b/tests/auto/tools/repotest/repository_unite/2020-11-10-0931_meta.7z diff --git a/tests/auto/tools/repotest/repository_unite/A/2.0.0content.7z b/tests/auto/tools/repotest/repository_unite/A/2.0.0content.7z Binary files differnew file mode 100644 index 000000000..ef8741d32 --- /dev/null +++ b/tests/auto/tools/repotest/repository_unite/A/2.0.0content.7z diff --git a/tests/auto/tools/repotest/repository_unite/A/2.0.0content.7z.sha1 b/tests/auto/tools/repotest/repository_unite/A/2.0.0content.7z.sha1 new file mode 100644 index 000000000..d5e23fd53 --- /dev/null +++ b/tests/auto/tools/repotest/repository_unite/A/2.0.0content.7z.sha1 @@ -0,0 +1 @@ +c7cca768ebfe60c4295a79762d4e19e63f2c21d2
\ No newline at end of file diff --git a/tests/auto/tools/repotest/repository_unite/C/1.0.0content.7z b/tests/auto/tools/repotest/repository_unite/C/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..de70ee790 --- /dev/null +++ b/tests/auto/tools/repotest/repository_unite/C/1.0.0content.7z diff --git a/tests/auto/tools/repotest/repository_unite/C/1.0.0content.7z.sha1 b/tests/auto/tools/repotest/repository_unite/C/1.0.0content.7z.sha1 new file mode 100644 index 000000000..c290ccf6c --- /dev/null +++ b/tests/auto/tools/repotest/repository_unite/C/1.0.0content.7z.sha1 @@ -0,0 +1 @@ +0e995c11dc35bd2b4ac04d408eb7091f8322ea49
\ No newline at end of file diff --git a/tests/auto/tools/repotest/repository_unite/Updates.xml b/tests/auto/tools/repotest/repository_unite/Updates.xml new file mode 100644 index 000000000..0b0a8987b --- /dev/null +++ b/tests/auto/tools/repotest/repository_unite/Updates.xml @@ -0,0 +1,28 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>2.0.0</Version> + <ReleaseDate>2020-01-01</ReleaseDate> + <Default>true</Default> + <Script>script2.0.0.qs</Script> + <UpdateFile CompressedSize="240" UncompressedSize="74" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + </PackageUpdate> + <PackageUpdate> + <Name>C</Name> + <DisplayName>C</DisplayName> + <Description>Example component C</Description> + <Version>1.0.0</Version> + <ReleaseDate>2015-01-01</ReleaseDate> + <Default>true</Default> + <UpdateFile CompressedSize="239" UncompressedSize="89" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + </PackageUpdate> + <SHA1>3b46ef65a751d9498205412fc22de43ce29e5d8a</SHA1> + <MetadataName>2020-11-10-0931_meta.7z</MetadataName> +</Updates> diff --git a/tests/auto/tools/repotest/repotest.pro b/tests/auto/tools/repotest/repotest.pro new file mode 100644 index 000000000..c0ff8caa6 --- /dev/null +++ b/tests/auto/tools/repotest/repotest.pro @@ -0,0 +1,6 @@ +include(../../qttest.pri) + +QT -= gui + +SOURCES += tst_repotest.cpp + diff --git a/tests/auto/tools/repotest/test_package_versions/repository_1/A/2.0.0content.7z b/tests/auto/tools/repotest/test_package_versions/repository_1/A/2.0.0content.7z Binary files differnew file mode 100644 index 000000000..46e2c9124 --- /dev/null +++ b/tests/auto/tools/repotest/test_package_versions/repository_1/A/2.0.0content.7z diff --git a/tests/auto/tools/repotest/test_package_versions/repository_1/A/2.0.0content.7z.sha1 b/tests/auto/tools/repotest/test_package_versions/repository_1/A/2.0.0content.7z.sha1 new file mode 100644 index 000000000..53010cea2 --- /dev/null +++ b/tests/auto/tools/repotest/test_package_versions/repository_1/A/2.0.0content.7z.sha1 @@ -0,0 +1 @@ +059e5ed8cd3a1fbca08cccfa4075265192603e3f
\ No newline at end of file diff --git a/tests/auto/tools/repotest/test_package_versions/repository_1/A/2.0.0meta.7z b/tests/auto/tools/repotest/test_package_versions/repository_1/A/2.0.0meta.7z Binary files differnew file mode 100644 index 000000000..af0863696 --- /dev/null +++ b/tests/auto/tools/repotest/test_package_versions/repository_1/A/2.0.0meta.7z diff --git a/tests/auto/tools/repotest/test_package_versions/repository_1/B/1.0.0content.7z b/tests/auto/tools/repotest/test_package_versions/repository_1/B/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..46e2c9124 --- /dev/null +++ b/tests/auto/tools/repotest/test_package_versions/repository_1/B/1.0.0content.7z diff --git a/tests/auto/tools/repotest/test_package_versions/repository_1/B/1.0.0content.7z.sha1 b/tests/auto/tools/repotest/test_package_versions/repository_1/B/1.0.0content.7z.sha1 new file mode 100644 index 000000000..53010cea2 --- /dev/null +++ b/tests/auto/tools/repotest/test_package_versions/repository_1/B/1.0.0content.7z.sha1 @@ -0,0 +1 @@ +059e5ed8cd3a1fbca08cccfa4075265192603e3f
\ No newline at end of file diff --git a/tests/auto/tools/repotest/test_package_versions/repository_1/B/1.0.0meta.7z b/tests/auto/tools/repotest/test_package_versions/repository_1/B/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..e5be1148e --- /dev/null +++ b/tests/auto/tools/repotest/test_package_versions/repository_1/B/1.0.0meta.7z diff --git a/tests/auto/tools/repotest/test_package_versions/repository_1/Updates.xml b/tests/auto/tools/repotest/test_package_versions/repository_1/Updates.xml new file mode 100644 index 000000000..edb6515bd --- /dev/null +++ b/tests/auto/tools/repotest/test_package_versions/repository_1/Updates.xml @@ -0,0 +1,28 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>true</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Test component A</Description> + <Version>2.0.0</Version> + <ReleaseDate>2020-01-01</ReleaseDate> + <Default>true</Default> + <Script>script2.0.0.qs</Script> + <UpdateFile UncompressedSize="40" CompressedSize="72" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>da6dae55a8cc3fb9f012e33fa7b9c187a823aa9a</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>B</Name> + <DisplayName>B</DisplayName> + <Description>Test component B</Description> + <Version>1.0.0</Version> + <ReleaseDate>2020-01-01</ReleaseDate> + <Default>true</Default> + <UpdateFile UncompressedSize="40" CompressedSize="72" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>d88b373458b4bbec38132692061bf1e7aa68e7f7</SHA1> + </PackageUpdate> +</Updates> diff --git a/tests/auto/tools/repotest/test_package_versions/repository_2/A/1.0.0content.7z b/tests/auto/tools/repotest/test_package_versions/repository_2/A/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..46e2c9124 --- /dev/null +++ b/tests/auto/tools/repotest/test_package_versions/repository_2/A/1.0.0content.7z diff --git a/tests/auto/tools/repotest/test_package_versions/repository_2/A/1.0.0content.7z.sha1 b/tests/auto/tools/repotest/test_package_versions/repository_2/A/1.0.0content.7z.sha1 new file mode 100644 index 000000000..53010cea2 --- /dev/null +++ b/tests/auto/tools/repotest/test_package_versions/repository_2/A/1.0.0content.7z.sha1 @@ -0,0 +1 @@ +059e5ed8cd3a1fbca08cccfa4075265192603e3f
\ No newline at end of file diff --git a/tests/auto/tools/repotest/test_package_versions/repository_2/A/1.0.0meta.7z b/tests/auto/tools/repotest/test_package_versions/repository_2/A/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..c4da482bf --- /dev/null +++ b/tests/auto/tools/repotest/test_package_versions/repository_2/A/1.0.0meta.7z diff --git a/tests/auto/tools/repotest/test_package_versions/repository_2/B/1.0.0content.7z b/tests/auto/tools/repotest/test_package_versions/repository_2/B/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..46e2c9124 --- /dev/null +++ b/tests/auto/tools/repotest/test_package_versions/repository_2/B/1.0.0content.7z diff --git a/tests/auto/tools/repotest/test_package_versions/repository_2/B/1.0.0content.7z.sha1 b/tests/auto/tools/repotest/test_package_versions/repository_2/B/1.0.0content.7z.sha1 new file mode 100644 index 000000000..53010cea2 --- /dev/null +++ b/tests/auto/tools/repotest/test_package_versions/repository_2/B/1.0.0content.7z.sha1 @@ -0,0 +1 @@ +059e5ed8cd3a1fbca08cccfa4075265192603e3f
\ No newline at end of file diff --git a/tests/auto/tools/repotest/test_package_versions/repository_2/B/1.0.0meta.7z b/tests/auto/tools/repotest/test_package_versions/repository_2/B/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..e5be1148e --- /dev/null +++ b/tests/auto/tools/repotest/test_package_versions/repository_2/B/1.0.0meta.7z diff --git a/tests/auto/tools/repotest/test_package_versions/repository_2/Updates.xml b/tests/auto/tools/repotest/test_package_versions/repository_2/Updates.xml new file mode 100644 index 000000000..ac12fba4b --- /dev/null +++ b/tests/auto/tools/repotest/test_package_versions/repository_2/Updates.xml @@ -0,0 +1,28 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>true</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.0</Version> + <ReleaseDate>2020-01-01</ReleaseDate> + <Default>true</Default> + <Script>script1.0.0.qs</Script> + <UpdateFile UncompressedSize="40" CompressedSize="72" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>da6dae55a8cc3fb9f012e33fa7b9c187a823aa9a</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>B</Name> + <DisplayName>B</DisplayName> + <Description>Example component B</Description> + <Version>1.0.0</Version> + <ReleaseDate>2020-01-01</ReleaseDate> + <Default>true</Default> + <UpdateFile UncompressedSize="40" CompressedSize="72" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>d88b373458b4bbec38132692061bf1e7aa68e7f7</SHA1> + </PackageUpdate> +</Updates> diff --git a/tests/auto/tools/repotest/test_package_versions/repository_3/A/1.0.0content.7z b/tests/auto/tools/repotest/test_package_versions/repository_3/A/1.0.0content.7z Binary files differnew file mode 100644 index 000000000..46e2c9124 --- /dev/null +++ b/tests/auto/tools/repotest/test_package_versions/repository_3/A/1.0.0content.7z diff --git a/tests/auto/tools/repotest/test_package_versions/repository_3/A/1.0.0content.7z.sha1 b/tests/auto/tools/repotest/test_package_versions/repository_3/A/1.0.0content.7z.sha1 new file mode 100644 index 000000000..53010cea2 --- /dev/null +++ b/tests/auto/tools/repotest/test_package_versions/repository_3/A/1.0.0content.7z.sha1 @@ -0,0 +1 @@ +059e5ed8cd3a1fbca08cccfa4075265192603e3f
\ No newline at end of file diff --git a/tests/auto/tools/repotest/test_package_versions/repository_3/A/1.0.0meta.7z b/tests/auto/tools/repotest/test_package_versions/repository_3/A/1.0.0meta.7z Binary files differnew file mode 100644 index 000000000..3706e8dd8 --- /dev/null +++ b/tests/auto/tools/repotest/test_package_versions/repository_3/A/1.0.0meta.7z diff --git a/tests/auto/tools/repotest/test_package_versions/repository_3/B/3.0.0content.7z b/tests/auto/tools/repotest/test_package_versions/repository_3/B/3.0.0content.7z Binary files differnew file mode 100644 index 000000000..46e2c9124 --- /dev/null +++ b/tests/auto/tools/repotest/test_package_versions/repository_3/B/3.0.0content.7z diff --git a/tests/auto/tools/repotest/test_package_versions/repository_3/B/3.0.0content.7z.sha1 b/tests/auto/tools/repotest/test_package_versions/repository_3/B/3.0.0content.7z.sha1 new file mode 100644 index 000000000..53010cea2 --- /dev/null +++ b/tests/auto/tools/repotest/test_package_versions/repository_3/B/3.0.0content.7z.sha1 @@ -0,0 +1 @@ +059e5ed8cd3a1fbca08cccfa4075265192603e3f
\ No newline at end of file diff --git a/tests/auto/tools/repotest/test_package_versions/repository_3/B/3.0.0meta.7z b/tests/auto/tools/repotest/test_package_versions/repository_3/B/3.0.0meta.7z Binary files differnew file mode 100644 index 000000000..e5be1148e --- /dev/null +++ b/tests/auto/tools/repotest/test_package_versions/repository_3/B/3.0.0meta.7z diff --git a/tests/auto/tools/repotest/test_package_versions/repository_3/Updates.xml b/tests/auto/tools/repotest/test_package_versions/repository_3/Updates.xml new file mode 100644 index 000000000..40d86538c --- /dev/null +++ b/tests/auto/tools/repotest/test_package_versions/repository_3/Updates.xml @@ -0,0 +1,28 @@ +<Updates> + <ApplicationName>{AnyApplication}</ApplicationName> + <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>true</Checksum> + <PackageUpdate> + <Name>A</Name> + <DisplayName>A</DisplayName> + <Description>Example component A</Description> + <Version>1.0.0</Version> + <ReleaseDate>2020-01-01</ReleaseDate> + <Default>true</Default> + <Script>script1.0.0.qs</Script> + <UpdateFile UncompressedSize="40" CompressedSize="72" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>da6dae55a8cc3fb9f012e33fa7b9c187a823aa9a</SHA1> + </PackageUpdate> + <PackageUpdate> + <Name>B</Name> + <DisplayName>B</DisplayName> + <Description>Example component B</Description> + <Version>3.0.0</Version> + <ReleaseDate>2020-01-01</ReleaseDate> + <Default>true</Default> + <UpdateFile UncompressedSize="40" CompressedSize="72" OS="Any"/> + <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>d88b373458b4bbec38132692061bf1e7aa68e7f7</SHA1> + </PackageUpdate> +</Updates> diff --git a/tests/auto/tools/repotest/tst_repotest.cpp b/tests/auto/tools/repotest/tst_repotest.cpp new file mode 100644 index 000000000..f1c0ae9dd --- /dev/null +++ b/tests/auto/tools/repotest/tst_repotest.cpp @@ -0,0 +1,582 @@ +/************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ +#include "../../installer/shared/verifyinstaller.h" + +#include <repositorygen.h> +#include <repositorygen.cpp> +#include <init.h> +#include <archivefactory.h> + +#ifdef IFW_LIB7Z +#include <lib7z_facade.h> +#endif + +#include <QFile> +#include <QTest> +#include <QRegularExpression> + +class tst_repotest : public QObject +{ + Q_OBJECT +private: + void generateRepo(bool createSplitMetadata, bool createUnifiedMetadata, bool updateNewComponents, + QStringList packagesUpdatedWithSha = QStringList()) + { + QStringList filteredPackages; + + m_packages = QInstallerTools::collectPackages(m_repoInfo, + &filteredPackages, QInstallerTools::Exclude, updateNewComponents, packagesUpdatedWithSha); + + if (updateNewComponents) { //Verify that component B exists as that is not updated + if (createSplitMetadata) { + VerifyInstaller::verifyFileExistence(m_repoInfo.repositoryDir + "/B", QStringList() << "1.0.0content.7z" + << "1.0.0content.7z.sha1" << "1.0.0meta.7z"); + } else { + VerifyInstaller::verifyFileExistence(m_repoInfo.repositoryDir + "/B", QStringList() << "1.0.0content.7z" + << "1.0.0content.7z.sha1"); + } + } + QTemporaryDir tmp; + tmp.setAutoRemove(false); + const QString tmpMetaDir = tmp.path(); + QInstallerTools::createRepository(m_repoInfo, &m_packages, tmpMetaDir, createSplitMetadata, + createUnifiedMetadata, QLatin1String("7z")); + QInstaller::removeDirectory(tmpMetaDir, true); + } + + void clearData() + { + m_repoInfo.packages.clear(); + m_repoInfo.repositoryPackages.clear(); + m_packages.clear(); + } + + void initRepoUpdate() + { + clearData(); + m_repoInfo.packages << "packages_update"; + } + + void initRepoUpdateFromRepositories(const QStringList &repositories) + { + clearData(); + m_repoInfo.repositoryPackages << repositories; + } + + void verifyUniteMetadata(const QString &scriptVersion) + { + QString fileContent = VerifyInstaller::fileContent(m_repoInfo.repositoryDir + QDir::separator() + + "Updates.xml"); + QRegularExpression re("<MetadataName>(.*)<.MetadataName>"); + QStringList matches = re.match(fileContent).capturedTexts(); + QString existingUniteMeta7z = QInstallerTools::existingUniteMeta7z(m_repoInfo.repositoryDir); + QCOMPARE(2, matches.count()); + QCOMPARE(existingUniteMeta7z, matches.at(1)); + QScopedPointer<AbstractArchive> file(ArchiveFactory::instance() + .create(m_repoInfo.repositoryDir + QDir::separator() + matches.at(1))); + QVERIFY(file->open(QIODevice::ReadOnly)); + + //We have script<version>.qs for package A in the unite metadata + QVector<ArchiveEntry>::const_iterator fileIt; + const QVector<ArchiveEntry> files = file->list(); + for (fileIt = files.begin(); fileIt != files.end(); ++fileIt) { + if (fileIt->isDirectory) + continue; + QString fileName = "A/script%1.qs"; + QCOMPARE(qPrintable(fileName.arg(scriptVersion)), fileIt->path); + } + + VerifyInstaller::verifyFileExistence(m_repoInfo.repositoryDir, QStringList() << "Updates.xml" + << matches.at(1)); + VerifyInstaller::verifyFileContent(m_repoInfo.repositoryDir + QDir::separator() + "Updates.xml", + "SHA1"); + VerifyInstaller::verifyFileContent(m_repoInfo.repositoryDir + QDir::separator() + "Updates.xml", + "MetadataName"); + } + + void verifyComponentRepository(const QString &componentAVersion, const QString &componentBVersion, bool hasComponentMeta) + { + const QString content = "%1content.7z"; + const QString contentSha1 = "%1content.7z.sha1"; + const QString meta = "%1meta.7z"; + QStringList componentA; + QStringList componentB; + componentA << qPrintable(content.arg(componentAVersion)) << qPrintable(contentSha1.arg(componentAVersion)); + componentB << qPrintable(content.arg(componentBVersion)) << qPrintable(contentSha1.arg(componentBVersion)); + if (hasComponentMeta) { + componentA << qPrintable(meta.arg(componentAVersion)); + componentB << qPrintable(meta.arg(componentBVersion)); + } + VerifyInstaller::verifyFileExistence(m_repoInfo.repositoryDir + "/A", componentA); + VerifyInstaller::verifyFileExistence(m_repoInfo.repositoryDir + "/B", componentB); + } + + void verifyComponentMetaUpdatesXml() + { + VerifyInstaller::verifyFileExistence(m_repoInfo.repositoryDir, QStringList() << "Updates.xml"); + VerifyInstaller::verifyFileHasNoContent(m_repoInfo.repositoryDir + QDir::separator() + "Updates.xml", + "MetadataName"); + } + + void ignoreMessagesForComponentHash(const QStringList &components) + { + QString packageDir = m_repoInfo.packages.first(); + foreach (const QString component, components) { + QString message = "Copying component data for \"%1\""; + QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(component))); + QTest::ignoreMessage(QtDebugMsg, QRegularExpression("Compressing files found in data directory: *")); + QTest::ignoreMessage(QtDebugMsg, QRegularExpression("Hash is stored in *")); + QTest::ignoreMessage(QtDebugMsg, QRegularExpression("Creating hash of archive *")); + QTest::ignoreMessage(QtDebugMsg, QRegularExpression("Generated sha1 hash: *")); + } + } + + void ignoreMessagesForCopyRepository(const QString &component, const QString &version, const QString &repository) + { + QStringList contentFiles; + contentFiles << "content.7z" << "content.7z.sha1"; + QString message = "Copying component data for \"%1\""; + QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(component))); + foreach (const QString &fileName, contentFiles) { + message = "Copying file from \"%5/%1/%2%4\" to \"%3/%1/%2%4\""; + QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(component).arg(version) + .arg(m_repoInfo.repositoryDir).arg(fileName).arg(repository))); + } + } + + void ignoreMessageForCollectingRepository(const QStringList &repositories) + { + const QString message = "Process repository \"%2\""; + QTest::ignoreMessage(QtDebugMsg, "Collecting information about available repository packages..."); + for (auto &repo : repositories) + QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(repo))); + QTest::ignoreMessage(QtDebugMsg, "Collecting information about available packages..."); + QTest::ignoreMessage(QtDebugMsg, "No available packages found at the specified location."); + } + + void ignoreMessagesForCopyMetadata(const QString &component, bool hasMeta, bool update) + { + QString message = "Copy meta data for package \"%2\" using \"%1/%2/meta/package.xml\""; + QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(m_repoInfo.packages.first(), component))); + QTest::ignoreMessage(QtDebugMsg, QRegularExpression("calculate size of directory *")); + if (hasMeta) { + if (update) + message = "Copying associated \"script\" file \"%1/%2/meta/script2.0.0.qs\""; + else + message = "Copying associated \"script\" file \"%1/%2/meta/script1.0.0.qs\""; + QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(m_repoInfo.packages.first(), component))); + QTest::ignoreMessage(QtDebugMsg, "done."); + } + } + + void ignoreMessagesForComponentSha(const QStringList &components, bool clearOldChecksum) + { + foreach (const QString component, components) { + const QString message = "Searching sha1sum node for \"%1\""; + QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(component))); + if (clearOldChecksum) + QTest::ignoreMessage(QtDebugMsg, QRegularExpression("- clearing the old sha1sum *")); + QTest::ignoreMessage(QtDebugMsg, QRegularExpression("- writing the sha1sum *")); + } + } + + void ignoreMessagesForUniteMeta(bool update) + { + QTest::ignoreMessage(QtDebugMsg, "Writing sha1sum node."); + if (update) + QTest::ignoreMessage(QtDebugMsg, QRegularExpression("- clearing the old sha1sum *")); + QTest::ignoreMessage(QtDebugMsg, QRegularExpression("- writing the sha1sum")); + QTest::ignoreMessage(QtDebugMsg, QRegularExpression("Updating the metadata node with name *")); + } + + void ignoreMessageForCollectingPackages(const QString &versionA = QString(), + const QString &versionB = QString(), const QString &versionC = QString()) + { + QTest::ignoreMessage(QtDebugMsg, "Collecting information about available repository packages..."); + QTest::ignoreMessage(QtDebugMsg, "Collecting information about available packages..."); + if (!versionA.isEmpty()) { + QTest::ignoreMessage(QtDebugMsg, "Found subdirectory \"A\""); + const QString message = "- it provides the package \"A\" - \"%1\""; + QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(versionA))); + } + if (!versionB.isEmpty()) { + QTest::ignoreMessage(QtDebugMsg, "Found subdirectory \"B\""); + const QString message = "- it provides the package \"B\" - \"%1\""; + QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(versionB))); + } + if (!versionC.isEmpty()) { + QTest::ignoreMessage(QtDebugMsg, "Found subdirectory \"C\""); + const QString message = "- it provides the package \"C\" - \"%1\""; + QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(versionC))); + } + } + + void ignoreMessageForCollectingPackagesFromRepository(const QString &versionA, const QString &versionB) + { + QString message = "- it provides the package \"B\" - \"%1\""; + QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(versionB))); + message = "- it provides the package \"A\" - \"%1\""; + QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(versionA))); + QTest::ignoreMessage(QtDebugMsg, "Collecting information about available packages..."); + QTest::ignoreMessage(QtDebugMsg, "No available packages found at the specified location."); + } + + void ignoreMessagesForUpdateComponents() + { + ignoreMessageForCollectingPackages("2.0.0", "1.0.0"); + ignoreMessagesForComponentSha(QStringList() << "A" << "B", false); + ignoreMessagesForComponentHash(QStringList() << "A" << "B"); + ignoreMessagesForCopyMetadata("A", true, true); + ignoreMessagesForCopyMetadata("B", false, true); + } + + void ignoreMessageForUpdateComponent() + { + QString message = "Update component \"A\" in \"%1\" ."; + QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(m_repoInfo.repositoryDir))); + message = "Update component \"C\" in \"%1\" ."; + QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(m_repoInfo.repositoryDir))); + } + + void verifyComponentShaUpdate(int shaUpdateComponents) + { + QString updatesXmlFile(m_repoInfo.repositoryDir + QDir::separator() + "Updates.xml"); + QFile file(updatesXmlFile); + QDomDocument dom; + + QVERIFY(file.open(QIODevice::ReadOnly)); + QVERIFY(dom.setContent(&file)); + file.close(); + QCOMPARE(dom.elementsByTagName("ContentSha1").count(), shaUpdateComponents); + } + +private slots: + void init() + { + ignoreMessageForCollectingPackages("1.0.0", "1.0.0"); + + m_repoInfo.repositoryDir = QInstallerTools::makePathAbsolute(QInstaller::generateTemporaryFileName()); + m_tempDirDeleter.add(m_repoInfo.repositoryDir); + + m_repoInfo.packages << "packages"; + + ignoreMessagesForComponentHash(QStringList() << "A" << "B"); + ignoreMessagesForCopyMetadata("A", true, false); //Only A has metadata + ignoreMessagesForCopyMetadata("B", false, false); + } + + void initTestCase() + { +#ifdef IFW_LIB7Z + Lib7z::initSevenZ(); +#endif + } + + void testWithComponentMeta() + { + ignoreMessagesForComponentSha(QStringList () << "A" << "B", false); + generateRepo(true, false, false); + + verifyComponentRepository("1.0.0", "1.0.0", true); + verifyComponentMetaUpdatesXml(); + } + + void testWithComponentAndUniteMeta() + { + ignoreMessagesForComponentSha(QStringList() << "A" << "B", false); + ignoreMessagesForUniteMeta(false); + generateRepo(true, true, false); + + verifyComponentRepository("1.0.0", "1.0.0", true); + verifyUniteMetadata("1.0.0"); + } + + void testWithUniteMeta() + { + ignoreMessagesForUniteMeta(false); + generateRepo(false, true, false); + + verifyComponentRepository("1.0.0", "1.0.0", false); + verifyUniteMetadata("1.0.0"); + } + + void testWithComponentShaUpdate() + { + ignoreMessagesForComponentSha(QStringList () << "A" << "B", false); + generateRepo(true, false, false, QStringList () << "A"); + + verifyComponentRepository("1.0.0", "1.0.0", true); + verifyComponentMetaUpdatesXml(); + verifyComponentShaUpdate(1); + } + + void testWithTwoComponentsShaUpdate() + { + ignoreMessagesForComponentSha(QStringList () << "A" << "B", false); + generateRepo(true, false, false, QStringList () << "A" << "B"); + + verifyComponentRepository("1.0.0", "1.0.0", true); + verifyComponentMetaUpdatesXml(); + verifyComponentShaUpdate(2); + } + + void testUpdateNewComponents() + { + // Create 'base' repository which will be updated + ignoreMessagesForComponentSha(QStringList() << "A" << "B", false); + generateRepo(true, false, false); + verifyComponentRepository("1.0.0", "1.0.0", true); + + // Update the 'base' repository + initRepoUpdate(); + ignoreMessageForCollectingPackages("2.0.0", "1.0.0"); + ignoreMessagesForComponentSha(QStringList() << "A", false); //Only A has update + ignoreMessagesForComponentHash(QStringList() << "A"); + ignoreMessagesForCopyMetadata("A", true, true); + const QString &message = "Update component \"A\" in \"%1\" ."; + QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(m_repoInfo.repositoryDir))); + generateRepo(true, false, true); + verifyComponentRepository("2.0.0", "1.0.0", true); + verifyComponentMetaUpdatesXml(); + } + + void testUpdateNewComponentsWithUniteMetadata() + { + ignoreMessagesForComponentSha(QStringList() << "A" << "B", false); + ignoreMessagesForUniteMeta(false); + generateRepo(true, true, false); + verifyComponentRepository("1.0.0", "1.0.0", true); + + initRepoUpdate(); + ignoreMessageForCollectingPackages("2.0.0", "1.0.0"); + ignoreMessagesForComponentSha(QStringList() << "A", false); //Only A has update + ignoreMessagesForComponentHash(QStringList() << "A"); + ignoreMessagesForCopyMetadata("A", true, true); + ignoreMessagesForUniteMeta(true); + const QString &message = "Update component \"A\" in \"%1\" ."; + QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(m_repoInfo.repositoryDir))); + generateRepo(true, true, true); + verifyComponentRepository("2.0.0", "1.0.0", true); + verifyUniteMetadata("2.0.0"); + } + + void testUpdateNewComponentsWithOnlyUniteMetadata() + { + ignoreMessagesForUniteMeta(false); + generateRepo(false, true, false); + verifyComponentRepository("1.0.0", "1.0.0", false); + + initRepoUpdate(); + ignoreMessageForCollectingPackages("2.0.0", "1.0.0"); + ignoreMessagesForComponentHash(QStringList() << "A"); + ignoreMessagesForCopyMetadata("A", true, true); + ignoreMessagesForUniteMeta(true); + const QString &message = "Update component \"A\" in \"%1\" ."; + QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(m_repoInfo.repositoryDir))); + generateRepo(false, true, true); + verifyComponentRepository("2.0.0", "1.0.0", false); + verifyUniteMetadata("2.0.0"); + } + + void testUpdateComponents() + { + ignoreMessagesForComponentSha(QStringList() << "A" << "B", false); + generateRepo(true, false, false); + verifyComponentRepository("1.0.0", "1.0.0", true); + + initRepoUpdate(); + ignoreMessagesForUpdateComponents(); + generateRepo(true, false, false); + verifyComponentRepository("2.0.0", "1.0.0", true); + verifyComponentMetaUpdatesXml(); + } + + void testUpdateComponentsFromPartialPackageDir() + { + ignoreMessagesForComponentSha(QStringList() << "A" << "B", false); + ignoreMessagesForUniteMeta(false); + generateRepo(true, true, false); + verifyComponentRepository("1.0.0", "1.0.0", true); + + clearData(); + m_repoInfo.packages << "packages_new"; + { // ignore messages + ignoreMessagesForUniteMeta(false); + ignoreMessageForCollectingPackages(QString(), QString(), "1.0.0"); + ignoreMessagesForComponentSha(QStringList() << "C", true); + ignoreMessagesForCopyMetadata("C", false, false); + ignoreMessagesForComponentHash(QStringList() << "C"); + } + generateRepo(true, true, false); + verifyComponentRepository("1.0.0", "1.0.0", true); + VerifyInstaller::verifyFileExistence(m_repoInfo.repositoryDir + "/C", + QStringList() << "1.0.0content.7z" << "1.0.0content.7z.sha1" << "1.0.0meta.7z"); + verifyUniteMetadata("1.0.0"); + } + + void testUpdateComponentsWithUniteMetadata() + { + ignoreMessagesForComponentSha(QStringList() << "A" << "B", false); + ignoreMessagesForUniteMeta(false); + generateRepo(true, true, false); + verifyComponentRepository("1.0.0", "1.0.0", true); + + initRepoUpdate(); + ignoreMessagesForUpdateComponents(); + ignoreMessagesForUniteMeta(true); + generateRepo(true, true, false); + verifyComponentRepository("2.0.0", "1.0.0", true); + verifyUniteMetadata("2.0.0"); + } + + void testUpdateComponentsWithOnlyUniteMetadata() + { + ignoreMessagesForUniteMeta(false); + generateRepo(false, true, false); + verifyComponentRepository("1.0.0", "1.0.0", false); + + initRepoUpdate(); + ignoreMessageForCollectingPackages("2.0.0", "1.0.0"); + ignoreMessagesForComponentHash(QStringList() << "A" << "B"); + ignoreMessagesForCopyMetadata("A", true, true); + ignoreMessagesForCopyMetadata("B", false, true); + ignoreMessagesForUniteMeta(true); + generateRepo(false, true, false); + verifyComponentRepository("2.0.0", "1.0.0", false); + verifyUniteMetadata("2.0.0"); + } + + void testUpdateComponentsFromRepository() + { + ignoreMessagesForComponentSha(QStringList() << "A" << "B", false); + generateRepo(true, false, false); + verifyComponentRepository("1.0.0", "1.0.0", true); + + initRepoUpdateFromRepositories(QStringList() << "repository_component"); + ignoreMessageForCollectingRepository(QStringList() << "repository_component"); + QTest::ignoreMessage(QtDebugMsg, "- it provides the package \"A\" - \"2.0.0\""); + QTest::ignoreMessage(QtDebugMsg, "- it provides the package \"B\" - \"1.0.0\""); + + ignoreMessagesForCopyRepository("B", "1.0.0", "repository_component"); + ignoreMessagesForCopyRepository("A", "2.0.0", "repository_component"); + ignoreMessagesForComponentSha(QStringList() << "A" << "B", true); + generateRepo(true, false, false); + verifyComponentRepository("2.0.0", "1.0.0", true); + verifyComponentMetaUpdatesXml(); + } + + void testUpdateComponentsFromMultipleRepositories() + { + ignoreMessagesForComponentSha(QStringList() << "A" << "B", false); + generateRepo(true, false, false); + verifyComponentRepository("1.0.0", "1.0.0", true); + + initRepoUpdateFromRepositories(QStringList() << "test_package_versions/repository_1" + << "test_package_versions/repository_2" << "test_package_versions/repository_3"); + + ignoreMessageForCollectingRepository(QStringList() + << "repository_1" << "repository_2" << "repository_3"); + + QTest::ignoreMessage(QtDebugMsg, "- it provides the package \"A\" - \"2.0.0\""); + QTest::ignoreMessage(QtDebugMsg, "- it provides the package \"B\" - \"1.0.0\""); + + QTest::ignoreMessage(QtDebugMsg, "- it provides an old version of the package \"A\" - \"1.0.0\" - ignored"); + QTest::ignoreMessage(QtDebugMsg, "- it provides an old version of the package \"B\" - \"1.0.0\" - ignored"); + + QTest::ignoreMessage(QtDebugMsg, "- it provides an old version of the package \"A\" - \"1.0.0\" - ignored"); + QTest::ignoreMessage(QtDebugMsg, "- it provides a new version of the package \"B\" - \"3.0.0\" - replaced"); + + ignoreMessagesForCopyRepository("B", "3.0.0", "test_package_versions/repository_3"); + ignoreMessagesForCopyRepository("A", "2.0.0", "test_package_versions/repository_1"); + ignoreMessagesForComponentSha(QStringList() << "A" << "B", true); + generateRepo(true, false, false); + verifyComponentRepository("2.0.0", "3.0.0", true); + verifyComponentMetaUpdatesXml(); + } + + void testUpdateComponentsFromRepositoryWithUniteMetadata() + { + ignoreMessagesForComponentSha(QStringList() << "A" << "B", false); + ignoreMessagesForUniteMeta(false); + generateRepo(true, true, false); + verifyComponentRepository("1.0.0", "1.0.0", true); + + initRepoUpdateFromRepositories(QStringList() << "repository_componentAndUnite"); + ignoreMessageForCollectingRepository(QStringList() << "repository_componentAndUnite"); + QTest::ignoreMessage(QtDebugMsg, "- it provides the package \"A\" - \"2.0.0\""); + QTest::ignoreMessage(QtDebugMsg, "- it provides the package \"C\" - \"1.0.0\""); + ignoreMessageForUpdateComponent(); + ignoreMessagesForCopyRepository("A", "2.0.0", "repository_componentAndUnite"); + ignoreMessagesForCopyRepository("C", "1.0.0", "repository_componentAndUnite"); + ignoreMessagesForUniteMeta(true); + ignoreMessagesForComponentSha(QStringList() << "A" << "C", true); + + generateRepo(true, true, true); + verifyComponentRepository("2.0.0", "1.0.0", true); + VerifyInstaller::verifyFileExistence(m_repoInfo.repositoryDir + "/C", QStringList() << "1.0.0content.7z" << "1.0.0content.7z.sha1" << "1.0.0meta.7z"); + verifyUniteMetadata("2.0.0"); + } + + void testUpdateComponentsFromRepositoryWithOnlyUniteMetadata() + { + ignoreMessagesForUniteMeta(false); + generateRepo(false, true, false); + verifyComponentRepository("1.0.0", "1.0.0", false); + + initRepoUpdateFromRepositories(QStringList() << "repository_unite"); + ignoreMessageForCollectingRepository(QStringList() << "repository_unite"); + QTest::ignoreMessage(QtDebugMsg, "- it provides the package \"A\" - \"2.0.0\""); + QTest::ignoreMessage(QtDebugMsg, "- it provides the package \"C\" - \"1.0.0\""); + ignoreMessageForUpdateComponent(); + ignoreMessagesForCopyRepository("A", "2.0.0", "repository_unite"); + ignoreMessagesForCopyRepository("C", "1.0.0", "repository_unite"); + ignoreMessagesForUniteMeta(true); + + generateRepo(false, true, true); + verifyComponentRepository("2.0.0", "1.0.0", false); + VerifyInstaller::verifyFileExistence(m_repoInfo.repositoryDir + "/C", QStringList() << "1.0.0content.7z" << "1.0.0content.7z.sha1"); + verifyUniteMetadata("2.0.0"); + } + + void cleanup() + { + m_tempDirDeleter.releaseAndDeleteAll(); + m_repoInfo.packages.clear(); + m_packages.clear(); + m_repoInfo.repositoryPackages.clear(); + } + +private: + QInstallerTools::RepositoryInfo m_repoInfo; + QInstallerTools::PackageInfoVector m_packages; + TempPathDeleter m_tempDirDeleter; +}; + +QTEST_MAIN(tst_repotest) + +#include "tst_repotest.moc" diff --git a/tests/auto/tools/tools.pro b/tests/auto/tools/tools.pro new file mode 100644 index 000000000..7e881ecee --- /dev/null +++ b/tests/auto/tools/tools.pro @@ -0,0 +1,4 @@ +TEMPLATE = subdirs + +SUBDIRS += \ + repotest |