diff options
Diffstat (limited to 'tests/auto/installer')
344 files changed, 6510 insertions, 1183 deletions
diff --git a/tests/auto/installer/appendfileoperation/appendfileoperation.pro b/tests/auto/installer/appendfileoperation/appendfileoperation.pro index 64cea7039..aca9ffd36 100644 --- a/tests/auto/installer/appendfileoperation/appendfileoperation.pro +++ b/tests/auto/installer/appendfileoperation/appendfileoperation.pro @@ -7,4 +7,4 @@ SOURCES += tst_appendfileoperation.cpp RESOURCES += \ settings.qrc \ - ..\shared\config.qrc + ../shared/config.qrc diff --git a/tests/auto/installer/appendfileoperation/data/repository/Updates.xml b/tests/auto/installer/appendfileoperation/data/repository/Updates.xml index a1c8f6aa2..f12d387a1 100644 --- a/tests/auto/installer/appendfileoperation/data/repository/Updates.xml +++ b/tests/auto/installer/appendfileoperation/data/repository/Updates.xml @@ -1,6 +1,7 @@ <Updates> <ApplicationName>{AnyApplication}</ApplicationName> <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> <PackageUpdate> <Name>A</Name> <DisplayName>A</DisplayName> @@ -9,6 +10,7 @@ <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/tst_appendfileoperation.cpp b/tests/auto/installer/appendfileoperation/tst_appendfileoperation.cpp index 9fbfb08e7..743e4c625 100644 --- a/tests/auto/installer/appendfileoperation/tst_appendfileoperation.cpp +++ b/tests/auto/installer/appendfileoperation/tst_appendfileoperation.cpp @@ -81,8 +81,7 @@ private slots: QVERIFY(!op.performOperation()); QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::InvalidArguments); - QCOMPARE(op.errorString(), QString("Invalid arguments in AppendFile: " - "0 arguments given, exactly 2 arguments expected.")); + 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"); @@ -98,10 +97,14 @@ private slots: 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"; + << "Line1\nLine2\nLine3\nAppendedText" << false; QTest::newRow("no newline") << "Lorem ipsum " << "dolore sit amet" - << "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() @@ -109,28 +112,38 @@ private slots: 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 << flush; + stream << source << Qt::flush; file.close(); - AppendFileOperation op; - op.setArguments(QStringList() << m_testFilePath << append); + 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()); + op->backup(); + QVERIFY(QFileInfo(op->value("backupOfFile").toString()).exists()); - QVERIFY2(op.performOperation(), op.errorString().toLatin1()); + 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()); + QVERIFY2(op->undoOperation(), op->errorString().toLatin1()); QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text)); - QCOMPARE(stream.readAll(), source); + 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()); 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 23442d5fa..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); } @@ -262,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); @@ -272,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()); @@ -308,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(); @@ -384,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); @@ -501,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); @@ -513,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/cliinterface/data/repository/A/1.0.2-1content.7z b/tests/auto/installer/cliinterface/data/repository/A/1.0.2-1content.7z Binary files differdeleted file mode 100644 index 5a9383e7e..000000000 --- a/tests/auto/installer/cliinterface/data/repository/A/1.0.2-1content.7z +++ /dev/null diff --git a/tests/auto/installer/cliinterface/data/repository/A/1.0.2-1content.7z.sha1 b/tests/auto/installer/cliinterface/data/repository/A/1.0.2-1content.7z.sha1 deleted file mode 100644 index fd0bc548c..000000000 --- a/tests/auto/installer/cliinterface/data/repository/A/1.0.2-1content.7z.sha1 +++ /dev/null @@ -1 +0,0 @@ -643cb71b2337d5a49d57a5bc3c636ee9b84c0802
\ No newline at end of file diff --git a/tests/auto/installer/cliinterface/data/repository/A/1.0.2-1meta.7z b/tests/auto/installer/cliinterface/data/repository/A/1.0.2-1meta.7z Binary files differdeleted file mode 100644 index 6ef0b7959..000000000 --- a/tests/auto/installer/cliinterface/data/repository/A/1.0.2-1meta.7z +++ /dev/null diff --git a/tests/auto/installer/cliinterface/data/repository/AB/1.0.2-1meta.7z b/tests/auto/installer/cliinterface/data/repository/AB/1.0.2-1meta.7z Binary files differdeleted file mode 100644 index 6b5e5ac91..000000000 --- a/tests/auto/installer/cliinterface/data/repository/AB/1.0.2-1meta.7z +++ /dev/null diff --git a/tests/auto/installer/cliinterface/data/repository/B/1.0.0-1content.7z b/tests/auto/installer/cliinterface/data/repository/B/1.0.0-1content.7z Binary files differdeleted file mode 100644 index dfe41ad15..000000000 --- a/tests/auto/installer/cliinterface/data/repository/B/1.0.0-1content.7z +++ /dev/null diff --git a/tests/auto/installer/cliinterface/data/repository/B/1.0.0-1content.7z.sha1 b/tests/auto/installer/cliinterface/data/repository/B/1.0.0-1content.7z.sha1 deleted file mode 100644 index 50a632b49..000000000 --- a/tests/auto/installer/cliinterface/data/repository/B/1.0.0-1content.7z.sha1 +++ /dev/null @@ -1 +0,0 @@ -c7b9ab370efe036171dda7b71cd95021747cb101
\ No newline at end of file diff --git a/tests/auto/installer/cliinterface/data/repository/B/1.0.0-1meta.7z b/tests/auto/installer/cliinterface/data/repository/B/1.0.0-1meta.7z Binary files differdeleted file mode 100644 index 12d54f94c..000000000 --- a/tests/auto/installer/cliinterface/data/repository/B/1.0.0-1meta.7z +++ /dev/null diff --git a/tests/auto/installer/cliinterface/data/repository/C/1.0.0-1content.7z b/tests/auto/installer/cliinterface/data/repository/C/1.0.0-1content.7z Binary files differdeleted file mode 100644 index 7d03dca9c..000000000 --- a/tests/auto/installer/cliinterface/data/repository/C/1.0.0-1content.7z +++ /dev/null diff --git a/tests/auto/installer/cliinterface/data/repository/C/1.0.0-1content.7z.sha1 b/tests/auto/installer/cliinterface/data/repository/C/1.0.0-1content.7z.sha1 deleted file mode 100644 index 91ead97f0..000000000 --- a/tests/auto/installer/cliinterface/data/repository/C/1.0.0-1content.7z.sha1 +++ /dev/null @@ -1 +0,0 @@ -c8b7076fabaaf6b9d27f27350c577118c24f426b
\ No newline at end of file diff --git a/tests/auto/installer/cliinterface/data/repository/C/1.0.0-1meta.7z b/tests/auto/installer/cliinterface/data/repository/C/1.0.0-1meta.7z Binary files differdeleted file mode 100644 index 46bae0179..000000000 --- a/tests/auto/installer/cliinterface/data/repository/C/1.0.0-1meta.7z +++ /dev/null diff --git a/tests/auto/installer/cliinterface/data/uninstallableComponentsRepository/A/2.0.0content.7z b/tests/auto/installer/cliinterface/data/uninstallableComponentsRepository/A/2.0.0content.7z Binary files differdeleted file mode 100644 index d7fbf4d8e..000000000 --- a/tests/auto/installer/cliinterface/data/uninstallableComponentsRepository/A/2.0.0content.7z +++ /dev/null diff --git a/tests/auto/installer/cliinterface/data/uninstallableComponentsRepository/A/2.0.0content.7z.sha1 b/tests/auto/installer/cliinterface/data/uninstallableComponentsRepository/A/2.0.0content.7z.sha1 deleted file mode 100644 index c5825de47..000000000 --- a/tests/auto/installer/cliinterface/data/uninstallableComponentsRepository/A/2.0.0content.7z.sha1 +++ /dev/null @@ -1 +0,0 @@ -f33d2028e1c61061f7f29e5189f7d66800361dc2
\ No newline at end of file diff --git a/tests/auto/installer/cliinterface/data/uninstallableComponentsRepository/A/2.0.0meta.7z b/tests/auto/installer/cliinterface/data/uninstallableComponentsRepository/A/2.0.0meta.7z Binary files differdeleted file mode 100644 index d783c7c1c..000000000 --- a/tests/auto/installer/cliinterface/data/uninstallableComponentsRepository/A/2.0.0meta.7z +++ /dev/null diff --git a/tests/auto/installer/cliinterface/data/uninstallableComponentsRepository/AB/1.0.2-1meta.7z b/tests/auto/installer/cliinterface/data/uninstallableComponentsRepository/AB/1.0.2-1meta.7z Binary files differdeleted file mode 100644 index 20f2aca2d..000000000 --- a/tests/auto/installer/cliinterface/data/uninstallableComponentsRepository/AB/1.0.2-1meta.7z +++ /dev/null diff --git a/tests/auto/installer/cliinterface/data/uninstallableComponentsRepository/B/2.0.0content.7z b/tests/auto/installer/cliinterface/data/uninstallableComponentsRepository/B/2.0.0content.7z Binary files differdeleted file mode 100644 index bd0bc9352..000000000 --- a/tests/auto/installer/cliinterface/data/uninstallableComponentsRepository/B/2.0.0content.7z +++ /dev/null diff --git a/tests/auto/installer/cliinterface/data/uninstallableComponentsRepository/B/2.0.0content.7z.sha1 b/tests/auto/installer/cliinterface/data/uninstallableComponentsRepository/B/2.0.0content.7z.sha1 deleted file mode 100644 index e66535388..000000000 --- a/tests/auto/installer/cliinterface/data/uninstallableComponentsRepository/B/2.0.0content.7z.sha1 +++ /dev/null @@ -1 +0,0 @@ -bb256f1eda0f452c7ab33d1f364a4fad062f0a73
\ No newline at end of file diff --git a/tests/auto/installer/cliinterface/data/uninstallableComponentsRepository/B/2.0.0meta.7z b/tests/auto/installer/cliinterface/data/uninstallableComponentsRepository/B/2.0.0meta.7z Binary files differdeleted file mode 100644 index f92853734..000000000 --- a/tests/auto/installer/cliinterface/data/uninstallableComponentsRepository/B/2.0.0meta.7z +++ /dev/null diff --git a/tests/auto/installer/cliinterface/tst_cliinterface.cpp b/tests/auto/installer/cliinterface/tst_cliinterface.cpp deleted file mode 100644 index 550f45da2..000000000 --- a/tests/auto/installer/cliinterface/tst_cliinterface.cpp +++ /dev/null @@ -1,510 +0,0 @@ -/************************************************************************** -** -** 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 <component.h> -#include <packagemanagercore.h> - -#include <QLoggingCategory> -#include <QTest> - -using namespace QInstaller; - -class tst_CLIInterface : public QObject -{ - Q_OBJECT - -private slots: - void testListAvailablePackages() - { - QString loggingRules = (QLatin1String("ifw.* = false\n" - "ifw.package.* = true\n")); - - QTest::ignoreMessage(QtDebugMsg, "Operations sanity check succeeded."); - - PackageManagerCore *core = PackageManager::getPackageManager - (m_installDir, ":///data/repository"); - - QLoggingCategory::setFilterRules(loggingRules); - - QTest::ignoreMessage(QtDebugMsg, "<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"); - core->listAvailablePackages(QLatin1String(".")); - - QTest::ignoreMessage(QtDebugMsg, "<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"); - core->listAvailablePackages(QLatin1String("A")); - - - QTest::ignoreMessage(QtDebugMsg, "<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"); - core->listAvailablePackages(QLatin1String("A.*")); - - - QTest::ignoreMessage(QtDebugMsg, "<availablepackages>\n" - " <package name=\"B\" displayname=\"B\" version=\"1.0.0-1\"/>\n" - "</availablepackages>\n"); - core->listAvailablePackages(QLatin1String("^B")); - - QTest::ignoreMessage(QtDebugMsg, "<availablepackages>\n" - " <package name=\"B\" displayname=\"B\" version=\"1.0.0-1\"/>\n" - "</availablepackages>\n"); - core->listAvailablePackages(QLatin1String("^B.*")); - - QTest::ignoreMessage(QtDebugMsg, "<availablepackages>\n" - " <package name=\"C\" displayname=\"C\" version=\"1.0.0-1\"/>\n" - "</availablepackages>\n"); - core->listAvailablePackages(QLatin1String("^C")); - } - - void testInstallPackageFails() - { - QString loggingRules = (QLatin1String("ifw.* = false\n" - "ifw.installer.installlog = true\n")); - - PackageManagerCore *core = PackageManager::getPackageManager - (m_installDir, ":///data/uninstallableComponentsRepository"); - - QLoggingCategory::setFilterRules(loggingRules); - - QTest::ignoreMessage(QtDebugMsg, "Preparing meta information download..."); - QTest::ignoreMessage(QtDebugMsg, "Cannot install component A. Component is installed only as automatic dependency to autoDep.\n"); - QCOMPARE(PackageManagerCore::Canceled, core->installSelectedComponentsSilently(QStringList() - << QLatin1String("A"))); - - QTest::ignoreMessage(QtDebugMsg, "Preparing meta information download..."); - QTest::ignoreMessage(QtDebugMsg, "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"))); - - QTest::ignoreMessage(QtDebugMsg, "Preparing meta information download..."); - QTest::ignoreMessage(QtDebugMsg, "Cannot install B. Component is virtual.\n"); - QCOMPARE(PackageManagerCore::Canceled, core->installSelectedComponentsSilently(QStringList() - << QLatin1String("B"))); - - QTest::ignoreMessage(QtDebugMsg, "Preparing meta information download..."); - QTest::ignoreMessage(QtDebugMsg, "Cannot install MissingComponent. Component not found.\n"); - 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(); - QString appFilePath = QCoreApplication::applicationFilePath(); - core.setAllowedRunningProcesses(QStringList() << appFilePath); - QLoggingCategory::setFilterRules(loggingRules); - - m_installDir = QInstaller::generateTemporaryFileName(); - QVERIFY(QDir().mkpath(m_installDir)); - 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" - "ifw.package.* = true\n")); - PackageManagerCore core; - core.setPackageManager(); - QLoggingCategory::setFilterRules(loggingRules); - - const QString testDirectory = QInstaller::generateTemporaryFileName(); - QVERIFY(QDir().mkpath(testDirectory)); - QVERIFY(QFile::copy(":/data/components.xml", testDirectory + "/components.xml")); - - core.setValue(scTargetDir, testDirectory); - - QTest::ignoreMessage(QtDebugMsg, "<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"); - core.listInstalledPackages(); - - QTest::ignoreMessage(QtDebugMsg, "<localpackages>\n" - " <package name=\"A\" displayname=\"A Title\" version=\"1.0.2-1\"/>\n" - "</localpackages>\n"); - core.listInstalledPackages(QLatin1String("A")); - - QDir dir(testDirectory); - QVERIFY(dir.removeRecursively()); - } - - void testNoDefaultInstallations() - { - 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 testInstallForcedPackageSilently() - { - PackageManagerCore *core = PackageManager::getPackageManagerWithInit - (m_installDir, ":///data/installPackagesRepository"); - QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() - << QLatin1String("componentE"))); - QCOMPARE(PackageManagerCore::Success, core->status()); - VerifyInstaller::verifyInstallerResources(m_installDir, "componentA", "1.0.0content.txt"); - VerifyInstaller::verifyInstallerResources(m_installDir, "componentE", "1.0.0content.txt"); //ForcedInstall - VerifyInstaller::verifyInstallerResources(m_installDir, "componentG", "1.0.0content.txt"); //Depends on componentA - VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" << "installcontent.txt" - << "installcontentA.txt" << "installcontentE.txt" << "installcontentG.txt"); - } - - void testInstallPackageSilently() - { - PackageManagerCore *core = PackageManager::getPackageManagerWithInit - (m_installDir, ":///data/installPackagesRepository"); - QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() - << QLatin1String("componentA"))); - QCOMPARE(PackageManagerCore::Success, core->status()); - VerifyInstaller::verifyInstallerResources(m_installDir, "componentA", "1.0.0content.txt"); - VerifyInstaller::verifyInstallerResources(m_installDir, "componentE", "1.0.0content.txt"); //ForcedInstall - VerifyInstaller::verifyInstallerResources(m_installDir, "componentG", "1.0.0content.txt"); //Depends on componentA - VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" << "installcontent.txt" - << "installcontentA.txt" << "installcontentE.txt" << "installcontentG.txt"); - } - - void testUninstallPackageSilently() - { - 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->setPackageManager(); - QCOMPARE(PackageManagerCore::Success, core->uninstallComponentsSilently(QStringList() - << QLatin1String("componentA"))); - QCOMPARE(PackageManagerCore::Success, core->status()); - VerifyInstaller::verifyInstallerResources(m_installDir, "componentE", "1.0.0content.txt"); //ForcedInstall - VerifyInstaller::verifyInstallerResourcesDeletion(m_installDir, "componentA"); - VerifyInstaller::verifyInstallerResourcesDeletion(m_installDir, "componentG"); //Depends on componentA - VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" << "installcontentE.txt"); - } - - void testRemoveAllSilently() - { - 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 testInstallWithDependencySilently() - { - PackageManagerCore *core = PackageManager::getPackageManagerWithInit - (m_installDir, ":///data/installPackagesRepository"); - QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() - << QLatin1String("componentC"))); - QCOMPARE(PackageManagerCore::Success, core->status()); - VerifyInstaller::verifyInstallerResources(m_installDir, "componentA", "1.0.0content.txt"); //Dependency for componentC - VerifyInstaller::verifyInstallerResources(m_installDir, "componentB", "1.0.0content.txt"); //Dependency for componentC - VerifyInstaller::verifyInstallerResources(m_installDir, "componentE", "1.0.0content.txt"); //ForcedInstall - VerifyInstaller::verifyInstallerResources(m_installDir, "componentG", "1.0.0content.txt"); //Depends on componentA - VerifyInstaller::verifyInstallerResources(m_installDir, "componentI", "1.0.0content.txt"); //Virtual, depends on componentC - VerifyInstaller::verifyInstallerResources(m_installDir, "componentD", "1.0.0content.txt"); //Autodepend on componentA and componentB - VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" << "installcontentC.txt" - << "installcontent.txt" << "installcontentA.txt" << "installcontentB.txt" - << "installcontentD.txt"<< "installcontentE.txt" << "installcontentG.txt" << "installcontentI.txt"); - } - - void testUninstallWithDependencySilently() - { - PackageManagerCore *core = PackageManager::getPackageManagerWithInit - (m_installDir, ":///data/installPackagesRepository"); - QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() - << QLatin1String("componentC"))); - VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" << "installcontentC.txt" - << "installcontent.txt" << "installcontentA.txt" << "installcontentB.txt" - << "installcontentD.txt"<< "installcontentE.txt" << "installcontentG.txt" << "installcontentI.txt"); - - core->commitSessionOperations(); - core->setPackageManager(); - QCOMPARE(PackageManagerCore::Success, core->uninstallComponentsSilently(QStringList() - << QLatin1String("componentC"))); - QCOMPARE(PackageManagerCore::Success, core->status()); - VerifyInstaller::verifyInstallerResources(m_installDir, "componentA", "1.0.0content.txt"); //Dependency for componentC - VerifyInstaller::verifyInstallerResources(m_installDir, "componentB", "1.0.0content.txt"); //Dependency for componentC - VerifyInstaller::verifyInstallerResources(m_installDir, "componentE", "1.0.0content.txt"); //ForcedInstall - VerifyInstaller::verifyInstallerResources(m_installDir, "componentG", "1.0.0content.txt"); //Depends on componentA - VerifyInstaller::verifyInstallerResources(m_installDir, "componentD", "1.0.0content.txt"); //Autodepend on componentA and componentB - VerifyInstaller::verifyInstallerResourcesDeletion(m_installDir, "componentC"); - VerifyInstaller::verifyInstallerResourcesDeletion(m_installDir, "componentI"); //Virtual, depends on componentC - VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" - << "installcontent.txt" << "installcontentA.txt" << "installcontentB.txt" - << "installcontentD.txt"<< "installcontentE.txt" << "installcontentG.txt"); - } - - void testInstallSubcomponentSilently() - { - PackageManagerCore *core = PackageManager::getPackageManagerWithInit - (m_installDir, ":///data/installPackagesRepository"); - QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() - << QLatin1String("componentF.subcomponent2.subsubcomponent2"))); - QCOMPARE(PackageManagerCore::Success, core->status()); - VerifyInstaller::verifyInstallerResources(m_installDir, "componentF.subcomponent2.subsubcomponent2", "1.0.0content.txt"); - VerifyInstaller::verifyInstallerResources(m_installDir, "componentF.subcomponent2", "1.0.0content.txt"); - VerifyInstaller::verifyInstallerResources(m_installDir, "componentF", "1.0.0content.txt"); - 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 install - VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" << "installcontentF.txt" - << "installcontentF_2.txt" << "installcontentF_2_2.txt" - << "installcontent.txt" << "installcontentA.txt" - << "installcontentE.txt" << "installcontentG.txt"); - } - - void testUninstallSubcomponentSilently() - { - PackageManagerCore *core = PackageManager::getPackageManagerWithInit - (m_installDir, ":///data/installPackagesRepository"); - QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() - << QLatin1String("componentF.subcomponent2.subsubcomponent2"))); - QCOMPARE(PackageManagerCore::Success, core->status()); - VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" << "installcontentF.txt" - << "installcontentF_2.txt" << "installcontentF_2_2.txt" - << "installcontent.txt" << "installcontentA.txt" - << "installcontentE.txt" << "installcontentG.txt"); - core->commitSessionOperations(); - core->setPackageManager(); - QCOMPARE(PackageManagerCore::Success, core->uninstallComponentsSilently(QStringList() - << QLatin1String("componentF.subcomponent2"))); - 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 install - VerifyInstaller::verifyInstallerResourcesDeletion(m_installDir, "componentF.subcomponent2.subsubcomponent2"); - VerifyInstaller::verifyInstallerResourcesDeletion(m_installDir, "componentF.subcomponent2"); - VerifyInstaller::verifyInstallerResourcesDeletion(m_installDir, "componentF"); - VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" - << "installcontent.txt" << "installcontentA.txt" - << "installcontentE.txt" << "installcontentG.txt"); - } - - void testInstallDefaultPackagesSilently() - { - 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 testUnInstallDefaultPackagesSilently() - { - PackageManagerCore *core = PackageManager::getPackageManagerWithInit - (m_installDir, ":///data/installPackagesRepository"); - QCOMPARE(PackageManagerCore::Success, core->installDefaultComponentsSilently()); - QCOMPARE(PackageManagerCore::Success, core->status()); - VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" << "installcontent.txt" - << "installcontentA.txt" << "installcontentE.txt" << "installcontentG.txt"); - - core->commitSessionOperations(); - core->setPackageManager(); - QCOMPARE(PackageManagerCore::Success, core->uninstallComponentsSilently(QStringList() - << "componentG")); - 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::verifyInstallerResourcesDeletion(m_installDir, "componentG"); - VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" << "installcontent.txt" - << "installcontentA.txt" << "installcontentE.txt"); - } - - void testUninstallForcedPackagesSilenly() - { - PackageManagerCore *core = PackageManager::getPackageManagerWithInit - (m_installDir, ":///data/installPackagesRepository"); - QCOMPARE(PackageManagerCore::Success, core->installDefaultComponentsSilently()); - QCOMPARE(PackageManagerCore::Success, core->status()); - core->commitSessionOperations(); - core->setPackageManager(); - QCOMPARE(PackageManagerCore::Success, core->uninstallComponentsSilently(QStringList() - << "componentE")); - QCOMPARE(PackageManagerCore::Success, core->status()); - //Nothing is uninstalled as componentE is forced install and cannot be uninstalled - 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 testUninstallAutodependencyPackagesSilenly() - { - PackageManagerCore *core = PackageManager::getPackageManagerWithInit - (m_installDir, ":///data/installPackagesRepository"); - QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() - << "componentA" << "componentB")); - QCOMPARE(PackageManagerCore::Success, core->status()); - core->commitSessionOperations(); - core->setPackageManager(); - QCOMPARE(PackageManagerCore::Success, core->uninstallComponentsSilently(QStringList() - << "componentD")); - QCOMPARE(PackageManagerCore::Success, core->status()); - //Nothing is uninstalled as componentD is installed as autodependency to componentA and componentB - VerifyInstaller::verifyInstallerResources(m_installDir, "componentA", "1.0.0content.txt"); - VerifyInstaller::verifyInstallerResources(m_installDir, "componentB", "1.0.0content.txt"); - VerifyInstaller::verifyInstallerResources(m_installDir, "componentD", "1.0.0content.txt"); - 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" - << "installcontentB.txt" << "installcontentD.txt"); - } - - void testUninstallVirtualSetVisibleSilently() - { - 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() - { - 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()); - core->deleteLater(); - } - - 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_CLIInterface) - -#include "tst_cliinterface.moc" 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/cliinterface/data/components.xml b/tests/auto/installer/commandlineinstall/data/components.xml index d5102787f..d5102787f 100644 --- a/tests/auto/installer/cliinterface/data/components.xml +++ b/tests/auto/installer/commandlineinstall/data/components.xml diff --git a/tests/auto/installer/cliinterface/data/componentsFromInstallPackagesRepository.xml b/tests/auto/installer/commandlineinstall/data/componentsFromInstallPackagesRepository.xml index 18d6f11c3..18d6f11c3 100644 --- a/tests/auto/installer/cliinterface/data/componentsFromInstallPackagesRepository.xml +++ b/tests/auto/installer/commandlineinstall/data/componentsFromInstallPackagesRepository.xml diff --git a/tests/auto/installer/cliinterface/data/config.xml b/tests/auto/installer/commandlineinstall/data/config.xml index 041ce5062..041ce5062 100644 --- a/tests/auto/installer/cliinterface/data/config.xml +++ b/tests/auto/installer/commandlineinstall/data/config.xml 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/cliinterface/data/filequeryrepository/Updates.xml b/tests/auto/installer/commandlineinstall/data/filequeryrepository/Updates.xml index 72b7938d9..7957cde4e 100644 --- a/tests/auto/installer/cliinterface/data/filequeryrepository/Updates.xml +++ b/tests/auto/installer/commandlineinstall/data/filequeryrepository/Updates.xml @@ -1,6 +1,7 @@ <Updates> <ApplicationName>{AnyApplication}</ApplicationName> <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> <PackageUpdate> <Name>A</Name> <DisplayName>A</DisplayName> @@ -9,5 +10,6 @@ <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/cliinterface/data/installPackagesRepository/componentA/1.0.0content.7z b/tests/auto/installer/commandlineinstall/data/installPackagesDependencyChanged/componentA/2.0.0content.7z Binary files differindex 4ddbe565b..4ddbe565b 100644 --- a/tests/auto/installer/cliinterface/data/installPackagesRepository/componentA/1.0.0content.7z +++ b/tests/auto/installer/commandlineinstall/data/installPackagesDependencyChanged/componentA/2.0.0content.7z diff --git a/tests/auto/installer/cliinterface/data/installPackagesRepository/componentB/1.0.0content.7z b/tests/auto/installer/commandlineinstall/data/installPackagesDependencyChanged/componentB/1.0.0content.7z Binary files differindex f84ffcdc5..f84ffcdc5 100644 --- a/tests/auto/installer/cliinterface/data/installPackagesRepository/componentB/1.0.0content.7z +++ b/tests/auto/installer/commandlineinstall/data/installPackagesDependencyChanged/componentB/1.0.0content.7z diff --git a/tests/auto/installer/cliinterface/data/installPackagesRepository/componentC/1.0.0content.7z b/tests/auto/installer/commandlineinstall/data/installPackagesDependencyChanged/componentC/1.0.0content.7z Binary files differindex 9ad11e06f..9ad11e06f 100644 --- a/tests/auto/installer/cliinterface/data/installPackagesRepository/componentC/1.0.0content.7z +++ b/tests/auto/installer/commandlineinstall/data/installPackagesDependencyChanged/componentC/1.0.0content.7z diff --git a/tests/auto/installer/cliinterface/data/installPackagesRepository/componentD/1.0.0content.7z b/tests/auto/installer/commandlineinstall/data/installPackagesDependencyChanged/componentD/1.0.0content.7z Binary files differindex 0c8c52e31..0c8c52e31 100644 --- a/tests/auto/installer/cliinterface/data/installPackagesRepository/componentD/1.0.0content.7z +++ b/tests/auto/installer/commandlineinstall/data/installPackagesDependencyChanged/componentD/1.0.0content.7z diff --git a/tests/auto/installer/cliinterface/data/installPackagesRepository/componentF/1.0.0content.7z b/tests/auto/installer/commandlineinstall/data/installPackagesDependencyChanged/componentF/1.0.0content.7z Binary files differindex 4a04b1394..4a04b1394 100644 --- a/tests/auto/installer/cliinterface/data/installPackagesRepository/componentF/1.0.0content.7z +++ b/tests/auto/installer/commandlineinstall/data/installPackagesDependencyChanged/componentF/1.0.0content.7z diff --git a/tests/auto/installer/cliinterface/data/installPackagesRepository/componentH/1.0.0content.7z b/tests/auto/installer/commandlineinstall/data/installPackagesDependencyChanged/componentH/1.0.0content.7z Binary files differindex e1449ad29..e1449ad29 100644 --- a/tests/auto/installer/cliinterface/data/installPackagesRepository/componentH/1.0.0content.7z +++ b/tests/auto/installer/commandlineinstall/data/installPackagesDependencyChanged/componentH/1.0.0content.7z diff --git a/tests/auto/installer/cliinterface/data/installPackagesRepository/Updates.xml b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/Updates.xml index adabceab4..3b5e22cc0 100644 --- a/tests/auto/installer/cliinterface/data/installPackagesRepository/Updates.xml +++ b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/Updates.xml @@ -151,6 +151,7 @@ </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> @@ -160,6 +161,7 @@ </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> @@ -168,4 +170,14 @@ <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/cliinterface/data/installPackagesRepository/componentE/1.0.0content.7z b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentE/1.0.0content.7z Binary files differindex f5abacf81..f5abacf81 100644 --- a/tests/auto/installer/cliinterface/data/installPackagesRepository/componentE/1.0.0content.7z +++ b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentE/1.0.0content.7z diff --git a/tests/auto/installer/cliinterface/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 differindex 3aced680f..3aced680f 100644 --- a/tests/auto/installer/cliinterface/data/installPackagesRepository/componentF.subcomponent1.subsubcomponent1/1.0.0content.7z +++ b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentF.subcomponent1.subsubcomponent1/1.0.0content.7z diff --git a/tests/auto/installer/cliinterface/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 differindex e5385a163..e5385a163 100644 --- a/tests/auto/installer/cliinterface/data/installPackagesRepository/componentF.subcomponent1.subsubcomponent2/1.0.0content.7z +++ b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentF.subcomponent1.subsubcomponent2/1.0.0content.7z diff --git a/tests/auto/installer/cliinterface/data/installPackagesRepository/componentF.subcomponent1/1.0.0content.7z b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentF.subcomponent1/1.0.0content.7z Binary files differindex 5bc549863..5bc549863 100644 --- a/tests/auto/installer/cliinterface/data/installPackagesRepository/componentF.subcomponent1/1.0.0content.7z +++ b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentF.subcomponent1/1.0.0content.7z diff --git a/tests/auto/installer/cliinterface/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 differindex da9e9f340..da9e9f340 100644 --- a/tests/auto/installer/cliinterface/data/installPackagesRepository/componentF.subcomponent2.subsubcomponent1/1.0.0content.7z +++ b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentF.subcomponent2.subsubcomponent1/1.0.0content.7z diff --git a/tests/auto/installer/cliinterface/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 differindex d0b013706..d0b013706 100644 --- a/tests/auto/installer/cliinterface/data/installPackagesRepository/componentF.subcomponent2.subsubcomponent2/1.0.0content.7z +++ b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentF.subcomponent2.subsubcomponent2/1.0.0content.7z diff --git a/tests/auto/installer/cliinterface/data/installPackagesRepository/componentF.subcomponent2/1.0.0content.7z b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentF.subcomponent2/1.0.0content.7z Binary files differindex 74ab44033..74ab44033 100644 --- a/tests/auto/installer/cliinterface/data/installPackagesRepository/componentF.subcomponent2/1.0.0content.7z +++ 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/cliinterface/data/installPackagesRepository/componentG/1.0.0content.7z b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentG/1.0.0content.7z Binary files differindex 81fc02052..81fc02052 100644 --- a/tests/auto/installer/cliinterface/data/installPackagesRepository/componentG/1.0.0content.7z +++ b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentG/1.0.0content.7z diff --git a/tests/auto/installer/cliinterface/data/installPackagesRepository/componentG/1.0.0meta.7z b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentG/1.0.0meta.7z Binary files differindex 90bfe33a2..90bfe33a2 100644 --- a/tests/auto/installer/cliinterface/data/installPackagesRepository/componentG/1.0.0meta.7z +++ 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/cliinterface/data/installPackagesRepository/componentI/1.0.0content.7z b/tests/auto/installer/commandlineinstall/data/installPackagesRepository/componentI/1.0.0content.7z Binary files differindex 651a29f94..651a29f94 100644 --- a/tests/auto/installer/cliinterface/data/installPackagesRepository/componentI/1.0.0content.7z +++ 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/cliinterface/data/repository/Updates.xml b/tests/auto/installer/commandlineinstall/data/repository/Updates.xml index c7b11dc03..52707d09d 100644 --- a/tests/auto/installer/cliinterface/data/repository/Updates.xml +++ b/tests/auto/installer/commandlineinstall/data/repository/Updates.xml @@ -19,7 +19,7 @@ <Description>Example component B</Description> <Version>1.0.0-1</Version> <ReleaseDate>2015-01-01</ReleaseDate> - <Default>true</Default> + <Default>false</Default> <UpdateFile CompressedSize="222" OS="Any" UncompressedSize="72"/> <DownloadableArchives>content.7z</DownloadableArchives> <SHA1>9170d55a6af81c1a6a63d708a4ab6ed359775cd9</SHA1> @@ -35,6 +35,27 @@ <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> diff --git a/tests/auto/installer/cliinterface/data/uninstallableComponentsRepository/Updates.xml b/tests/auto/installer/commandlineinstall/data/uninstallableComponentsRepository/Updates.xml index e0aedffdd..f0c724db8 100644 --- a/tests/auto/installer/cliinterface/data/uninstallableComponentsRepository/Updates.xml +++ b/tests/auto/installer/commandlineinstall/data/uninstallableComponentsRepository/Updates.xml @@ -37,4 +37,14 @@ <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/cliinterface/settings.qrc b/tests/auto/installer/commandlineinstall/settings.qrc index 6b46aaffd..992dbfd58 100644 --- a/tests/auto/installer/cliinterface/settings.qrc +++ b/tests/auto/installer/commandlineinstall/settings.qrc @@ -14,6 +14,8 @@ <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> @@ -21,6 +23,13 @@ <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> 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 index 9ab982716..543ec8b23 100644 --- a/tests/auto/installer/commandlineupdate/commandlineupdate.pro +++ b/tests/auto/installer/commandlineupdate/commandlineupdate.pro @@ -6,4 +6,4 @@ SOURCES += tst_commandlineupdate.cpp RESOURCES += \ settings.qrc \ - ..\shared\config.qrc + ../shared/config.qrc diff --git a/tests/auto/installer/commandlineupdate/data/installPackagesRepository/Updates.xml b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/Updates.xml index 9e01f1800..de6e66525 100644 --- a/tests/auto/installer/commandlineupdate/data/installPackagesRepository/Updates.xml +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepository/Updates.xml @@ -160,4 +160,20 @@ <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/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 index f56888022..5fbfaa5e9 100644 --- a/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/Updates.xml +++ b/tests/auto/installer/commandlineupdate/data/installPackagesRepositoryUpdate/Updates.xml @@ -6,7 +6,7 @@ <Name>componentA</Name> <DisplayName>Component A</DisplayName> <Description>This component does not depend on any other component.</Description> - <Version>2.0.0</Version> + <Version>1.0.0</Version> <ReleaseDate>2015-08-25</ReleaseDate> <SortingPriority>100</SortingPriority> <UpdateFile CompressedSize="297" UncompressedSize="99" OS="Any"/> @@ -155,7 +155,7 @@ <Name>componentH</Name> <DisplayName>Component H. ForcedUpdate</DisplayName> <Description>Component H. ForcedUpdate</Description> - <Version>2.0.0</Version> + <Version>1.0.0</Version> <ReleaseDate>2014-08-25</ReleaseDate> <ForcedUpdate>true</ForcedUpdate> <DownloadableArchives>content.7z</DownloadableArchives> 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/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/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/settings.qrc b/tests/auto/installer/commandlineupdate/settings.qrc index bed0619d8..c8f328d6b 100644 --- a/tests/auto/installer/commandlineupdate/settings.qrc +++ b/tests/auto/installer/commandlineupdate/settings.qrc @@ -17,8 +17,10 @@ <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/2.0.0content.7z</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> @@ -26,15 +28,35 @@ <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/2.0.0content.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 index 07dad9d31..0faeecf74 100644 --- a/tests/auto/installer/commandlineupdate/tst_commandlineupdate.cpp +++ b/tests/auto/installer/commandlineupdate/tst_commandlineupdate.cpp @@ -1,6 +1,6 @@ /************************************************************************** ** -** Copyright (C) 2020 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. @@ -37,12 +37,15 @@ 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) + void setRepository(const QString &repository, PackageManagerCore *core) { core->reset(); core->cancelMetaInfoJob(); //Call cancel to reset metadata so that update repositories are fetched @@ -54,168 +57,359 @@ private: } private slots: - void initTestCase() - { - m_installDir = QInstaller::generateTemporaryFileName(); - core = PackageManager::getPackageManagerWithInit(m_installDir); - } - void testInstallWhenEssentialUpdate() + void testUpdate_data() { - setRepository(":///data/installPackagesRepository"); - QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() - << "componentA")); - QCOMPARE(PackageManagerCore::Success, core->status()); - VerifyInstaller::verifyInstallerResources(m_installDir, "componentA", "1.0.0content.txt"); - VerifyInstaller::verifyInstallerResources(m_installDir, "componentE", "1.0.0content.txt"); - VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" << "installcontent.txt" - << "installcontentA.txt" << "installcontentE.txt" << "installcontentG.txt"); - core->commitSessionOperations(); - core->setPackageManager(); - setRepository(":///data/installPackagesRepositoryUpdate"); - QCOMPARE(PackageManagerCore::ForceUpdate, core->installSelectedComponentsSilently(QStringList() - << "componentB")); - VerifyInstaller::verifyInstallerResources(m_installDir, "componentA", "1.0.0content.txt"); - VerifyInstaller::verifyInstallerResources(m_installDir, "componentE", "1.0.0content.txt"); - VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" << "installcontent.txt" - << "installcontentA.txt" << "installcontentE.txt" << "installcontentG.txt"); - } + 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"); - void testUpdateEssentialPackageSilently() - { - QCOMPARE(PackageManagerCore::EssentialUpdated, core->updateComponentsSilently(QStringList())); - VerifyInstaller::verifyInstallerResources(m_installDir, "componentA", "2.0.0content.txt"); - VerifyInstaller::verifyInstallerResources(m_installDir, "componentE", "1.0.0content.txt"); - VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" - << "installcontentA_update.txt" << "installcontentE.txt" << "installcontentG.txt"); - VerifyInstaller::verifyInstallerResourceFileDeletion(m_installDir, "componentA", "1.0.0content.txt"); - //As we are using the same core in tests, clean the essentalupdate value - core->setFoundEssentialUpdate(false); - } + /*********** Update essential packages **********/ + ComponentResourceHash componentResources; + componentResources.append(ComponentResource("componentA", "1.0.0content.txt")); + componentResources.append(ComponentResource("componentE", "1.0.0content.txt")); - void testUpdateEssentialWithAutodependOnSilently() - { - setRepository(":///data/repositoryWithDependencyToEssential"); - QCOMPARE(PackageManagerCore::EssentialUpdated, core->updateComponentsSilently(QStringList())); + ComponentResourceHash componentResourcesAfterUpdate; + componentResourcesAfterUpdate.append(ComponentResource("componentA", "2.0.0content.txt")); + componentResourcesAfterUpdate.append(ComponentResource("componentE", "1.0.0content.txt")); - VerifyInstaller::verifyInstallerResources(m_installDir, "componentA", "3.0.0content.txt"); - VerifyInstaller::verifyInstallerResources(m_installDir, "componentAutoDependOnA", "1.0content.txt"); - VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" - << "installcontentA_update.txt" << "installcontentE.txt" << "installcontentG.txt" - << "installContentAutoDependOnA.txt"); + ComponentResourceHash deletedComponentResources; + deletedComponentResources.append(ComponentResource("componentA", "1.0.0content.txt")); - //As we are using the same core in tests, clean the essentalupdate value - core->setFoundEssentialUpdate(false); - } + 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; - void testUpdateForceUpdatePackagesSilently() - { - setRepository(":///data/installPackagesRepository"); - QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() - << "componentH")); - VerifyInstaller::verifyInstallerResources(m_installDir, "componentH", "1.0.0content.txt"); - VerifyInstaller::verifyInstallerResources(m_installDir, "componentE", "1.0.0content.txt"); - VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" - << "installcontentA_update.txt" << "installcontentE.txt" << "installcontentG.txt" - << "installContentAutoDependOnA.txt" << "installcontentH.txt"); - core->commitSessionOperations(); + /*********** 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")); - setRepository(":///data/installPackagesRepositoryUpdate"); - QCOMPARE(PackageManagerCore::EssentialUpdated, core->updateComponentsSilently(QStringList())); - VerifyInstaller::verifyInstallerResourceFileDeletion(m_installDir, "componentH", "1.0.0content.txt"); - VerifyInstaller::verifyInstallerResources(m_installDir, "componentH", "2.0.0content.txt"); - //Verify that no other installed components got update - VerifyInstaller::verifyInstallerResources(m_installDir, "componentE", "1.0.0content.txt"); - VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" - << "installcontentA_update.txt" << "installcontentE.txt" << "installcontentG.txt" - << "installContentAutoDependOnA.txt" << "installcontentH_update.txt"); - core->setFoundEssentialUpdate(false); + 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 testUpdatePackageSilently() + void testUpdate() { - setRepository(":///data/installPackagesRepository"); - QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() - << "componentB")); - QCOMPARE(PackageManagerCore::Success, core->status()); - - VerifyInstaller::verifyInstallerResources(m_installDir, "componentA", "3.0.0content.txt"); - VerifyInstaller::verifyInstallerResources(m_installDir, "componentB", "1.0.0content.txt"); - VerifyInstaller::verifyInstallerResources(m_installDir, "componentD", "1.0.0content.txt"); - VerifyInstaller::verifyInstallerResources(m_installDir, "componentAutoDependOnA", "1.0content.txt"); - VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" - << "installcontentA_update.txt" << "installcontentE.txt" << "installcontentG.txt" - << "installcontentB.txt" << "installcontentD.txt" - << "installContentAutoDependOnA.txt" << "installcontentH_update.txt"); + 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)); - setRepository(":///data/installPackagesRepositoryUpdate"); - QCOMPARE(PackageManagerCore::Success, core->updateComponentsSilently(QStringList() - << "componentB")); - // componentD is autodependent and cannot be deselected - // componentE is a forced component and thus will be updated - VerifyInstaller::verifyInstallerResources(m_installDir, "componentA", "3.0.0content.txt"); - VerifyInstaller::verifyInstallerResources(m_installDir, "componentB", "2.0.0content.txt"); - VerifyInstaller::verifyInstallerResources(m_installDir, "componentD", "2.0.0content.txt"); - VerifyInstaller::verifyInstallerResources(m_installDir, "componentE", "2.0.0content.txt"); - VerifyInstaller::verifyInstallerResources(m_installDir, "componentAutoDependOnA", "1.0content.txt"); - - VerifyInstaller::verifyInstallerResourceFileDeletion(m_installDir, "componentD", "1.0.0content.txt"); - VerifyInstaller::verifyInstallerResourceFileDeletion(m_installDir, "componentE", "1.0.0content.txt"); - VerifyInstaller::verifyFileExistence(m_installDir, QStringList() << "components.xml" << "installcontentA_update.txt" - << "installcontentE_update.txt" << "installcontentG.txt" - << "installcontentB_update.txt" << "installcontentD_update.txt" - << "installContentAutoDependOnA.txt" << "installcontentH_update.txt"); + 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() { - setRepository(":///data/installPackagesRepositoryUpdate"); + 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 testUpdateTwoPackageSilently() - { - setRepository(":///data/installPackagesRepositoryUpdate"); - QCOMPARE(PackageManagerCore::Success, core->updateComponentsSilently(QStringList() - << "componentB" << "componentG")); - VerifyInstaller::verifyInstallerResources(m_installDir, "componentB", "2.0.0content.txt"); - VerifyInstaller::verifyInstallerResources(m_installDir, "componentG", "2.0.0content.txt"); - VerifyInstaller::verifyInstallerResourceFileDeletion(m_installDir, "componentB", "1.0.0content.txt"); - VerifyInstaller::verifyInstallerResourceFileDeletion(m_installDir, "componentG", "1.0.0content.txt"); - } - - void testUpdateAllPackagesSilently() + void init() { - setRepository(":///data/installPackagesRepository"); - QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() - << "componentA" << "componentB" << "componentG" << "componentF")); - VerifyInstaller::verifyInstallerResources(m_installDir, "componentF", "1.0.0content.txt"); - 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.subcomponent2", "1.0.0content.txt"); - core->commitSessionOperations(); - - setRepository(":///data/installPackagesRepositoryUpdate"); - QCOMPARE(PackageManagerCore::Success, core->updateComponentsSilently(QStringList())); - VerifyInstaller::verifyInstallerResources(m_installDir, "componentF", "2.0.0content.txt"); - VerifyInstaller::verifyInstallerResources(m_installDir, "componentF.subcomponent2", "2.0.0content.txt"); - VerifyInstaller::verifyInstallerResourceFileDeletion(m_installDir, "componentF", "1.0.0content.txt"); - VerifyInstaller::verifyInstallerResourceFileDeletion(m_installDir, "componentF.subcomponent2", "1.0.0content.txt"); + m_installDir = QInstaller::generateTemporaryFileName(); + QVERIFY(QDir().mkpath(m_installDir)); } - void cleanupTestCase() + void cleanup() { QDir dir(m_installDir); QVERIFY(dir.removeRecursively()); - delete core; } private: QString m_installDir; - PackageManagerCore *core; }; 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..bc16013b7 --- /dev/null +++ b/tests/auto/installer/componentalias/data/aliases-optional.xml @@ -0,0 +1,36 @@ +<?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> +</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..e128590dc --- /dev/null +++ b/tests/auto/installer/componentalias/data/repository/Updates.xml @@ -0,0 +1,43 @@ +<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> +</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..278ae918b --- /dev/null +++ b/tests/auto/installer/componentalias/metadata/installer-config/aliases.xml @@ -0,0 +1,52 @@ +<?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> +</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..f6742af1f --- /dev/null +++ b/tests/auto/installer/componentalias/tst_componentalias.cpp @@ -0,0 +1,269 @@ +/************************************************************************** +** +** 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)); + } + + 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-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"), 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-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"), 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-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"), 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 not install)") + << AliasSource(AliasSource::SourceFileFormat::Xml, ":///data/aliases-optional.xml", -1) + << (QStringList() << "set-optional-broken") + << PackageManagerCore::Canceled + << 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); + + 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(status, core->installSelectedComponentsSilently(selectedAliases)); + } + +private: + QString m_installDir; +}; + +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 3a6139446..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> diff --git a/tests/auto/installer/componentmodel/tst_componentmodel.cpp b/tests/auto/installer/componentmodel/tst_componentmodel.cpp index 0672a03ec..276292233 100644 --- a/tests/auto/installer/componentmodel/tst_componentmodel.cpp +++ b/tests/auto/installer/componentmodel/tst_componentmodel.cpp @@ -1,6 +1,6 @@ /************************************************************************** ** -** Copyright (C) 2021 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. @@ -59,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 @@ -92,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; @@ -116,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; @@ -141,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); @@ -162,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); @@ -184,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); @@ -204,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); @@ -226,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. @@ -262,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. @@ -300,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. @@ -335,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. @@ -367,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(); @@ -379,11 +393,14 @@ 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); } } @@ -397,7 +414,7 @@ private slots: // setup the model with 1 column ComponentModel model(1, &m_core); - model.setRootComponents(rootComponents); + model.reset(rootComponents); testDefaultInheritedModelBehavior(&model, 1); model.setCheckedState(ComponentModel::DefaultChecked); @@ -513,6 +530,7 @@ private: { UpdatesInfo updatesInfo; updatesInfo.setFileName(":///data/updates.xml"); + updatesInfo.parseFile(); const QList<UpdateInfo> updateInfos = updatesInfo.updatesInfo(); QHash<QString, Component*> components; @@ -521,7 +539,7 @@ private: // we need at least these to be able to test the model component->setValue("Name", info.data.value("Name").toString()); - component->setValue("TreeName", info.data.value("TreeName").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; @@ -529,6 +547,7 @@ private: 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()) diff --git a/tests/auto/installer/cliinterface/cliinterface.pro b/tests/auto/installer/componentreplace/componentreplace.pro index ccad1a00f..9df6f81ca 100644 --- a/tests/auto/installer/cliinterface/cliinterface.pro +++ b/tests/auto/installer/componentreplace/componentreplace.pro @@ -2,8 +2,8 @@ include(../../qttest.pri) QT += qml -SOURCES += tst_cliinterface.cpp +SOURCES += tst_componentreplace.cpp RESOURCES += \ settings.qrc \ - ..\shared\config.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 45d6dab1d..30a85bdcf 100644 --- a/tests/auto/installer/consumeoutputoperationtest/consumeoutputoperationtest.pro +++ b/tests/auto/installer/consumeoutputoperationtest/consumeoutputoperationtest.pro @@ -9,4 +9,4 @@ DEFINES += "QMAKE_BINARY=$$fromNativeSeparators($$QMAKE_BINARY)" RESOURCES += \ settings.qrc \ - ..\shared\config.qrc + ../shared/config.qrc diff --git a/tests/auto/installer/consumeoutputoperationtest/data/repository/Updates.xml b/tests/auto/installer/consumeoutputoperationtest/data/repository/Updates.xml index 6b1856d51..1c3caf7be 100644 --- a/tests/auto/installer/consumeoutputoperationtest/data/repository/Updates.xml +++ b/tests/auto/installer/consumeoutputoperationtest/data/repository/Updates.xml @@ -10,5 +10,6 @@ <ReleaseDate>2015-01-01</ReleaseDate> <Default>true</Default> <Script>script.qs</Script> + <SHA1>4da14562d6515590d145678d21990faa817832bb</SHA1> </PackageUpdate> </Updates> diff --git a/tests/auto/installer/consumeoutputoperationtest/tst_consumeoutputoperationtest.cpp b/tests/auto/installer/consumeoutputoperationtest/tst_consumeoutputoperationtest.cpp index 32f8c2d5c..c0c8d7390 100644 --- a/tests/auto/installer/consumeoutputoperationtest/tst_consumeoutputoperationtest.cpp +++ b/tests/auto/installer/consumeoutputoperationtest/tst_consumeoutputoperationtest.cpp @@ -125,7 +125,7 @@ private: if (process.state() != QProcess::NotRunning) loop.exec(); - return process.readAllStandardOutput(); + return process.readAllStandardOutput().trimmed(); } 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/metadatajob/data/config.xml b/tests/auto/installer/contentsha1check/data/config.xml index 041ce5062..041ce5062 100644 --- a/tests/auto/installer/metadatajob/data/config.xml +++ b/tests/auto/installer/contentsha1check/data/config.xml 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 index 69fb4ce0f..c3d7d17b9 100644 --- a/tests/auto/installer/copydirectoryoperation/copydirectoryoperation.pro +++ b/tests/auto/installer/copydirectoryoperation/copydirectoryoperation.pro @@ -7,4 +7,4 @@ SOURCES += tst_copydirectoryoperation.cpp RESOURCES += \ settings.qrc \ - ..\shared\config.qrc + ../shared/config.qrc diff --git a/tests/auto/installer/copydirectoryoperation/data/repository/Updates.xml b/tests/auto/installer/copydirectoryoperation/data/repository/Updates.xml index a1c8f6aa2..fb8c9cf1c 100644 --- a/tests/auto/installer/copydirectoryoperation/data/repository/Updates.xml +++ b/tests/auto/installer/copydirectoryoperation/data/repository/Updates.xml @@ -1,6 +1,7 @@ <Updates> <ApplicationName>{AnyApplication}</ApplicationName> <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> <PackageUpdate> <Name>A</Name> <DisplayName>A</DisplayName> @@ -9,6 +10,7 @@ <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/Updates.xml b/tests/auto/installer/copydirectoryoperation/data/xmloperationrepository/Updates.xml index 90b26a387..b495f3307 100644 --- a/tests/auto/installer/copydirectoryoperation/data/xmloperationrepository/Updates.xml +++ b/tests/auto/installer/copydirectoryoperation/data/xmloperationrepository/Updates.xml @@ -1,6 +1,7 @@ <Updates> <ApplicationName>{AnyApplication}</ApplicationName> <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> <PackageUpdate> <Name>A</Name> <DisplayName>A</DisplayName> @@ -8,6 +9,7 @@ <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"> diff --git a/tests/auto/installer/copyoperationtest/copyoperationtest.pro b/tests/auto/installer/copyoperationtest/copyoperationtest.pro index a4d9d1204..a832fe295 100644 --- a/tests/auto/installer/copyoperationtest/copyoperationtest.pro +++ b/tests/auto/installer/copyoperationtest/copyoperationtest.pro @@ -7,4 +7,4 @@ SOURCES = tst_copyoperationtest.cpp RESOURCES += \ settings.qrc \ - ..\shared\config.qrc + ../shared/config.qrc diff --git a/tests/auto/installer/copyoperationtest/tst_copyoperationtest.cpp b/tests/auto/installer/copyoperationtest/tst_copyoperationtest.cpp index d41853eee..692fd86d9 100644 --- a/tests/auto/installer/copyoperationtest/tst_copyoperationtest.cpp +++ b/tests/auto/installer/copyoperationtest/tst_copyoperationtest.cpp @@ -87,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() diff --git a/tests/auto/installer/createdesktopentryoperation/createdesktopentryoperation.pro b/tests/auto/installer/createdesktopentryoperation/createdesktopentryoperation.pro index 3c3338140..1f0b98429 100644 --- a/tests/auto/installer/createdesktopentryoperation/createdesktopentryoperation.pro +++ b/tests/auto/installer/createdesktopentryoperation/createdesktopentryoperation.pro @@ -7,4 +7,4 @@ SOURCES = tst_createdesktopentryoperation.cpp RESOURCES += \ settings.qrc \ - ..\shared\config.qrc + ../shared/config.qrc diff --git a/tests/auto/installer/createdesktopentryoperation/data/repository/Updates.xml b/tests/auto/installer/createdesktopentryoperation/data/repository/Updates.xml index 77b5a9956..ad6c49c81 100644 --- a/tests/auto/installer/createdesktopentryoperation/data/repository/Updates.xml +++ b/tests/auto/installer/createdesktopentryoperation/data/repository/Updates.xml @@ -1,6 +1,7 @@ <Updates> <ApplicationName>{AnyApplication}</ApplicationName> <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> <PackageUpdate> <Name>A</Name> <DisplayName>A</DisplayName> @@ -9,5 +10,6 @@ <ReleaseDate>2015-01-01</ReleaseDate> <Default>true</Default> <Script>script.qs</Script> + <SHA1>0746c8292e3799aac4a534a0a1a58d42ef24ed43</SHA1> </PackageUpdate> </Updates> diff --git a/tests/auto/installer/createdesktopentryoperation/tst_createdesktopentryoperation.cpp b/tests/auto/installer/createdesktopentryoperation/tst_createdesktopentryoperation.cpp index 32e23ea14..c73e7cc03 100644 --- a/tests/auto/installer/createdesktopentryoperation/tst_createdesktopentryoperation.cpp +++ b/tests/auto/installer/createdesktopentryoperation/tst_createdesktopentryoperation.cpp @@ -70,7 +70,7 @@ private: QVERIFY(QFileInfo(entryFileName).exists()); if (QFileInfo(createDesktopEntryOp->arguments().first()).isRelative()) { QStringList directories = QString::fromLocal8Bit(qgetenv("XDG_DATA_HOME")) - .split(QLatin1Char(':'), QString::SkipEmptyParts); + .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 diff --git a/tests/auto/installer/createoffline/createoffline.pro b/tests/auto/installer/createoffline/createoffline.pro index 5f14bf0bd..bdb050f4d 100644 --- a/tests/auto/installer/createoffline/createoffline.pro +++ b/tests/auto/installer/createoffline/createoffline.pro @@ -6,4 +6,4 @@ QT += testlib SOURCES = tst_createoffline.cpp RESOURCES += settings.qrc \ - ..\shared\config.qrc + ../shared/config.qrc 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/settings.qrc b/tests/auto/installer/createoffline/settings.qrc index 2c546d7f2..4b7666b4a 100644 --- a/tests/auto/installer/createoffline/settings.qrc +++ b/tests/auto/installer/createoffline/settings.qrc @@ -23,5 +23,10 @@ <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 index 474b1d5de..607f9b7cc 100644 --- a/tests/auto/installer/createoffline/tst_createoffline.cpp +++ b/tests/auto/installer/createoffline/tst_createoffline.cpp @@ -85,12 +85,15 @@ private slots: 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::Failure; + << PackageManagerCore::Canceled; } void testCreateOfflineInstaller() @@ -99,7 +102,8 @@ private slots: QFETCH(QString, component); QFETCH(PackageManagerCore::Status, expectedStatus); - PackageManagerCore *core = PackageManager::getPackageManagerWithInit(m_targetDir, repository); + QScopedPointer<PackageManagerCore> core( + PackageManager::getPackageManagerWithInit(m_targetDir, repository)); core->setCommandLineInstance(true); core->setOfflineBaseBinary(m_installerBase); core->setOfflineBinaryName("ifw_test_offline"); @@ -132,13 +136,13 @@ private slots: << true << PackageManagerCore::Canceled; QTest::newRow("Disallow unstable | Missing dependency with selected component") << ":///data/repository-missingdependency" << "example.with.unstable.dependency" - << false << PackageManagerCore::Failure; + << 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::Failure; + << false << PackageManagerCore::Canceled; } void testCreateOfflineWithUnstableComponent() @@ -148,7 +152,8 @@ private slots: QFETCH(bool, allowUnstable); QFETCH(PackageManagerCore::Status, expectedStatus); - PackageManagerCore *core = PackageManager::getPackageManagerWithInit(m_targetDir, repository); + QScopedPointer<PackageManagerCore> core( + PackageManager::getPackageManagerWithInit(m_targetDir, repository)); core->setCommandLineInstance(true); core->setOfflineBaseBinary(m_installerBase); core->setOfflineBinaryName("ifw_test_offline"); diff --git a/tests/auto/installer/createshortcutoperation/data/repository/Updates.xml b/tests/auto/installer/createshortcutoperation/data/repository/Updates.xml index 0826afae8..d1909d355 100644 --- a/tests/auto/installer/createshortcutoperation/data/repository/Updates.xml +++ b/tests/auto/installer/createshortcutoperation/data/repository/Updates.xml @@ -5,7 +5,7 @@ <PackageUpdate> <Name>A</Name> <DisplayName>A</DisplayName> - <Description>Example component A</Description> + <Description>Example component for CreateShortcutOperation</Description> <Version>1.0.2-1</Version> <ReleaseDate>2015-01-01</ReleaseDate> <Default>true</Default> diff --git a/tests/auto/installer/createshortcutoperation/tst_createshortcutoperation.cpp b/tests/auto/installer/createshortcutoperation/tst_createshortcutoperation.cpp index a57098d2a..a08567d64 100644 --- a/tests/auto/installer/createshortcutoperation/tst_createshortcutoperation.cpp +++ b/tests/auto/installer/createshortcutoperation/tst_createshortcutoperation.cpp @@ -52,10 +52,10 @@ private: void installFromCLI(const QString &repository) { QInstaller::init(); - PackageManagerCore *core = new PackageManagerCore(BinaryContent::MagicInstallerMarker, QList<OperationBlob> (), - QString(), Protocol::DefaultAuthorizationKey, Protocol::Mode::Production, - QHash<QString, QString>(), true); - core->setAllowedRunningProcesses(QStringList() << QCoreApplication::applicationFilePath()); + 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; @@ -69,7 +69,7 @@ private: core->installDefaultComponentsSilently(); QSettingsWrapper user(QLatin1String("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\" - "CurrentVersion\\Explorer\\User Shell Folders"), QSettingsWrapper::NativeFormat); + "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"; diff --git a/tests/auto/installer/deleteoperation/data/repository/Updates.xml b/tests/auto/installer/deleteoperation/data/repository/Updates.xml index 77b5a9956..5a8b28f38 100644 --- a/tests/auto/installer/deleteoperation/data/repository/Updates.xml +++ b/tests/auto/installer/deleteoperation/data/repository/Updates.xml @@ -1,6 +1,7 @@ <Updates> <ApplicationName>{AnyApplication}</ApplicationName> <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> <PackageUpdate> <Name>A</Name> <DisplayName>A</DisplayName> @@ -9,5 +10,6 @@ <ReleaseDate>2015-01-01</ReleaseDate> <Default>true</Default> <Script>script.qs</Script> + <SHA1>e8b8ce98862d463c855609ed8e139eda17092cc6</SHA1> </PackageUpdate> </Updates> diff --git a/tests/auto/installer/deleteoperation/deleteoperation.pro b/tests/auto/installer/deleteoperation/deleteoperation.pro index 8dca91226..f22867965 100644 --- a/tests/auto/installer/deleteoperation/deleteoperation.pro +++ b/tests/auto/installer/deleteoperation/deleteoperation.pro @@ -7,4 +7,4 @@ SOURCES += tst_deleteoperation.cpp RESOURCES += \ settings.qrc \ - ..\shared\config.qrc + ../shared/config.qrc diff --git a/tests/auto/installer/deleteoperation/tst_deleteoperation.cpp b/tests/auto/installer/deleteoperation/tst_deleteoperation.cpp index 807d03498..43ea52407 100644 --- a/tests/auto/installer/deleteoperation/tst_deleteoperation.cpp +++ b/tests/auto/installer/deleteoperation/tst_deleteoperation.cpp @@ -75,8 +75,7 @@ private slots: QVERIFY(!op.performOperation()); QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::InvalidArguments); - QCOMPARE(op.errorString(), QString("Invalid arguments in Delete: " - "0 arguments given, exactly 1 arguments expected.")); + 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"); @@ -92,13 +91,16 @@ private slots: void testDeleteRestore_data() { QTest::addColumn<QString>("path"); - QTest::newRow("relative") << "test"; - QTest::newRow("absolute") << qApp->applicationDirPath() + QDir::toNativeSeparators("/test"); + 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); @@ -107,23 +109,32 @@ private slots: out << testString; testFile.close(); - QVERIFY(QFileInfo(path).exists()); + QVERIFY(QFileInfo::exists(path)); QByteArray testFileHash = QInstaller::calculateHash(path, QCryptographicHash::Sha1); - DeleteOperation op; - op.setArguments(QStringList() << path); - - op.backup(); - QVERIFY(QFileInfo(op.value("backupOfExistingFile").toString()).exists()); - - QVERIFY2(op.performOperation(), op.errorString().toLatin1()); - QVERIFY(!QFileInfo(path).exists()); - - QVERIFY2(op.undoOperation(), op.errorString().toLatin1()); - QByteArray restoredFileHash = QInstaller::calculateHash(path, QCryptographicHash::Sha1); - QVERIFY(testFileHash == restoredFileHash); - - QVERIFY(QFile(path).remove()); + 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() diff --git a/tests/auto/installer/elevatedexecuteoperation/tst_elevatedexecuteoperation.cpp b/tests/auto/installer/elevatedexecuteoperation/tst_elevatedexecuteoperation.cpp index aa2849559..ef185a5cf 100644 --- a/tests/auto/installer/elevatedexecuteoperation/tst_elevatedexecuteoperation.cpp +++ b/tests/auto/installer/elevatedexecuteoperation/tst_elevatedexecuteoperation.cpp @@ -1,6 +1,6 @@ /************************************************************************** ** -** Copyright (C) 2021 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. @@ -46,12 +46,12 @@ private slots: 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")); + operation.setArguments(QStringList() << QLatin1String("UNDOEXECUTE") << QLatin1String("FAKE_QMAKE") << QLatin1String("-v")); - QTest::ignoreMessage(QtDebugMsg, "\"FAKE_QMAKE\" started, arguments: \"\""); - QString message = "Failed to run undo operation \"Execute\" for component . Trying again with arguments %1"; + 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: \"\""; + message = "\"%1\" started, arguments: \"-v\""; QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(QUOTE(QMAKE_BINARY)))); QCOMPARE(operation.undoOperation(), true); diff --git a/tests/auto/installer/environmentvariableoperation/data/repository/Updates.xml b/tests/auto/installer/environmentvariableoperation/data/repository/Updates.xml index 6b1856d51..5bcd58c69 100644 --- a/tests/auto/installer/environmentvariableoperation/data/repository/Updates.xml +++ b/tests/auto/installer/environmentvariableoperation/data/repository/Updates.xml @@ -10,5 +10,6 @@ <ReleaseDate>2015-01-01</ReleaseDate> <Default>true</Default> <Script>script.qs</Script> + <SHA1>4b7b52af2d838389a7404c553da74705fc106493</SHA1> </PackageUpdate> </Updates> diff --git a/tests/auto/installer/environmentvariableoperation/environmentvariableoperation.pro b/tests/auto/installer/environmentvariableoperation/environmentvariableoperation.pro index 2d09bc9da..77f566d59 100644 --- a/tests/auto/installer/environmentvariableoperation/environmentvariableoperation.pro +++ b/tests/auto/installer/environmentvariableoperation/environmentvariableoperation.pro @@ -7,5 +7,5 @@ SOURCES = tst_environmentvariableoperation.cpp RESOURCES += \ settings.qrc \ - ..\shared\config.qrc + ../shared/config.qrc diff --git a/tests/auto/installer/environmentvariableoperation/tst_environmentvariableoperation.cpp b/tests/auto/installer/environmentvariableoperation/tst_environmentvariableoperation.cpp index d0ded4c58..4afbc709c 100644 --- a/tests/auto/installer/environmentvariableoperation/tst_environmentvariableoperation.cpp +++ b/tests/auto/installer/environmentvariableoperation/tst_environmentvariableoperation.cpp @@ -47,8 +47,8 @@ private: { QString installDir = QInstaller::generateTemporaryFileName(); QVERIFY(QDir().mkpath(installDir)); - PackageManagerCore *core = PackageManager::getPackageManagerWithInit - (installDir, repository); + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (installDir, repository)); core->installDefaultComponentsSilently(); QVERIFY(m_settings->value("IFW_UNIT_TEST_LOCAL").toString().isEmpty()); diff --git a/tests/auto/installer/extractarchiveoperationtest/data.qrc b/tests/auto/installer/extractarchiveoperationtest/data.qrc index d6eb2cf92..87f648568 100644 --- a/tests/auto/installer/extractarchiveoperationtest/data.qrc +++ b/tests/auto/installer/extractarchiveoperationtest/data.qrc @@ -2,9 +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.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/Updates.xml b/tests/auto/installer/extractarchiveoperationtest/data/xmloperationrepository/Updates.xml index 3a8bdd018..73a093725 100644 --- a/tests/auto/installer/extractarchiveoperationtest/data/xmloperationrepository/Updates.xml +++ b/tests/auto/installer/extractarchiveoperationtest/data/xmloperationrepository/Updates.xml @@ -8,7 +8,7 @@ <Version>1.0.0</Version> <ReleaseDate>2015-01-01</ReleaseDate> <Default>true</Default> - <DownloadableArchives>content.7z,anothercontent.7z,default.7z</DownloadableArchives> + <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> @@ -19,6 +19,22 @@ <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> diff --git a/tests/auto/installer/extractarchiveoperationtest/extractarchiveoperationtest.pro b/tests/auto/installer/extractarchiveoperationtest/extractarchiveoperationtest.pro index 2343f546e..e0da85b0a 100644 --- a/tests/auto/installer/extractarchiveoperationtest/extractarchiveoperationtest.pro +++ b/tests/auto/installer/extractarchiveoperationtest/extractarchiveoperationtest.pro @@ -4,5 +4,5 @@ QT -= gui QT += testlib RESOURCES += data.qrc \ - ..\shared\config.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 baaf58da2..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. @@ -28,6 +28,7 @@ #include "../shared/packagemanager.h" +#include "concurrentoperationrunner.h" #include "init.h" #include "extractarchiveoperation.h" @@ -84,8 +85,57 @@ 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() @@ -94,13 +144,25 @@ private slots: QVERIFY(QDir().mkpath(m_testDirectory)); QVERIFY(QDir(m_testDirectory).exists()); - PackageManagerCore *core = PackageManager::getPackageManagerWithInit - (m_testDirectory, ":///data/xmloperationrepository"); + 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()); @@ -115,6 +177,39 @@ private slots: 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; }; diff --git a/tests/auto/installer/factory/tst_factory.cpp b/tests/auto/installer/factory/tst_factory.cpp index f44a6febe..4b6932c09 100644 --- a/tests/auto/installer/factory/tst_factory.cpp +++ b/tests/auto/installer/factory/tst_factory.cpp @@ -1,11 +1,11 @@ /************************************************************************** ** -** Copyright (C) 2020 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 @@ -14,24 +14,13 @@ ** 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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** 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-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. +** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** @@ -82,7 +71,7 @@ public: : Food(amount) , m_expireDate(expireDate) { qDebug().nospace().noquote() << "Constructor."; } - QDate expireDate() const { + QDate expireDate() const override { return m_expireDate; } private: @@ -92,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) { @@ -117,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/globalsettingsoperation/globalsettingsoperation.pro b/tests/auto/installer/globalsettingsoperation/globalsettingsoperation.pro index ddae3b1d7..c9e959cac 100644 --- a/tests/auto/installer/globalsettingsoperation/globalsettingsoperation.pro +++ b/tests/auto/installer/globalsettingsoperation/globalsettingsoperation.pro @@ -6,5 +6,5 @@ QT += testlib SOURCES = tst_globalsettingsoperation.cpp RESOURCES += \ - ..\shared\config.qrc + ../shared/config.qrc diff --git a/tests/auto/installer/installer.pro b/tests/auto/installer/installer.pro index 114c43d7a..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,12 +10,12 @@ SUBDIRS += \ fakestopprocessforupdateoperation \ messageboxhandler \ extractarchiveoperationtest \ - lib7zfacade \ fileutils \ unicodeexecutable \ scriptengine \ consumeoutputoperationtest \ mkdiroperationtest \ + rmdiroperationtest \ copyoperationtest \ solver \ binaryformat \ @@ -25,10 +26,11 @@ SUBDIRS += \ factory \ replaceoperation \ brokeninstaller \ - cliinterface \ + commandlineinstall \ linereplaceoperation \ metadatajob \ appendfileoperation \ + prependfileoperation \ simplemovefileoperation \ deleteoperation \ copydirectoryoperation \ @@ -39,7 +41,20 @@ SUBDIRS += \ globalsettingsoperation \ elevatedexecuteoperation \ treename \ - createoffline + createoffline \ + contentshaupdate \ + componentreplace \ + metadatacache \ + contentsha1check \ + componentalias + +CONFIG(libarchive) { + SUBDIRS += libarchivearchive +} + +CONFIG(lzmasdk) { + SUBDIRS += lib7zarchive +} win32 { SUBDIRS += registerfiletypeoperation \ diff --git a/tests/auto/installer/installiconsoperation/data/repository/Updates.xml b/tests/auto/installer/installiconsoperation/data/repository/Updates.xml index a1c8f6aa2..201e23c2d 100644 --- a/tests/auto/installer/installiconsoperation/data/repository/Updates.xml +++ b/tests/auto/installer/installiconsoperation/data/repository/Updates.xml @@ -1,6 +1,7 @@ <Updates> <ApplicationName>{AnyApplication}</ApplicationName> <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> <PackageUpdate> <Name>A</Name> <DisplayName>A</DisplayName> @@ -10,5 +11,6 @@ <Default>true</Default> <Script>script.qs</Script> <DownloadableArchives>content.7z</DownloadableArchives> + <SHA1>13c9e7e67c26e7fbf49cc30887d87140b65e11b5</SHA1> </PackageUpdate> </Updates> diff --git a/tests/auto/installer/installiconsoperation/installiconsoperation.pro b/tests/auto/installer/installiconsoperation/installiconsoperation.pro index 6e6a45f39..be4cd0b3d 100644 --- a/tests/auto/installer/installiconsoperation/installiconsoperation.pro +++ b/tests/auto/installer/installiconsoperation/installiconsoperation.pro @@ -7,4 +7,4 @@ SOURCES = tst_installiconsoperation.cpp RESOURCES += \ settings.qrc \ - ..\shared\config.qrc + ../shared/config.qrc diff --git a/tests/auto/installer/installiconsoperation/tst_installiconsoperation.cpp b/tests/auto/installer/installiconsoperation/tst_installiconsoperation.cpp index fdbbb29bc..3dc981652 100644 --- a/tests/auto/installer/installiconsoperation/tst_installiconsoperation.cpp +++ b/tests/auto/installer/installiconsoperation/tst_installiconsoperation.cpp @@ -47,8 +47,8 @@ private: { QString installDir = QInstaller::generateTemporaryFileName(); QVERIFY(QDir().mkpath(installDir)); - PackageManagerCore *core = PackageManager::getPackageManagerWithInit - (installDir, repository); + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (installDir, repository)); core->installDefaultComponentsSilently(); InstallIconsOperation *installIconsOp = nullptr; @@ -202,7 +202,7 @@ private slots: QString targetIconsDirectory = op.value("directory").toString(); QVERIFY(QFileInfo(targetIconsDirectory).exists()); QStringList directories = QString::fromLocal8Bit(qgetenv("XDG_DATA_HOME")) - .split(QLatin1Char(':'), QString::SkipEmptyParts); + .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 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/Updates.xml b/tests/auto/installer/licenseagreement/data/repository/Updates.xml index 2afd2a741..c57918162 100644 --- a/tests/auto/installer/licenseagreement/data/repository/Updates.xml +++ b/tests/auto/installer/licenseagreement/data/repository/Updates.xml @@ -9,6 +9,7 @@ <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> diff --git a/tests/auto/installer/licenseagreement/licenseagreement.pro b/tests/auto/installer/licenseagreement/licenseagreement.pro index 1d8c3c451..e0d7e98d3 100644 --- a/tests/auto/installer/licenseagreement/licenseagreement.pro +++ b/tests/auto/installer/licenseagreement/licenseagreement.pro @@ -7,4 +7,4 @@ SOURCES += tst_licenseagreement.cpp RESOURCES += \ settings.qrc \ - ..\shared\config.qrc + ../shared/config.qrc diff --git a/tests/auto/installer/linereplaceoperation/linereplaceoperation.pro b/tests/auto/installer/linereplaceoperation/linereplaceoperation.pro index 3aead8afb..87d0c97f4 100644 --- a/tests/auto/installer/linereplaceoperation/linereplaceoperation.pro +++ b/tests/auto/installer/linereplaceoperation/linereplaceoperation.pro @@ -7,4 +7,4 @@ SOURCES += tst_linereplaceoperation.cpp RESOURCES += \ settings.qrc \ - ..\shared\config.qrc + ../shared/config.qrc diff --git a/tests/auto/installer/linereplaceoperation/tst_linereplaceoperation.cpp b/tests/auto/installer/linereplaceoperation/tst_linereplaceoperation.cpp index 762ef0211..5c98d7f8b 100644 --- a/tests/auto/installer/linereplaceoperation/tst_linereplaceoperation.cpp +++ b/tests/auto/installer/linereplaceoperation/tst_linereplaceoperation.cpp @@ -45,8 +45,8 @@ private: { QString installDir = QInstaller::generateTemporaryFileName(); QVERIFY(QDir().mkpath(installDir)); - PackageManagerCore *core = PackageManager::getPackageManagerWithInit - (installDir, repository); + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (installDir, repository)); core->installDefaultComponentsSilently(); QFile file(installDir + QDir::separator() + "A.txt"); @@ -119,7 +119,7 @@ private slots: QVERIFY(file.open(QIODevice::WriteOnly | QIODevice::Text)); QTextStream stream(&file); - stream << source << endl; + stream << source << Qt::endl; file.close(); LineReplaceOperation op(nullptr); 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 differindex 3653317c6..f51ed49fa 100644 --- 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 diff --git a/tests/auto/installer/messageboxhandler/data/invalidoperation/Updates.xml b/tests/auto/installer/messageboxhandler/data/invalidoperation/Updates.xml index 77b5a9956..f92211497 100644 --- a/tests/auto/installer/messageboxhandler/data/invalidoperation/Updates.xml +++ b/tests/auto/installer/messageboxhandler/data/invalidoperation/Updates.xml @@ -1,6 +1,7 @@ <Updates> <ApplicationName>{AnyApplication}</ApplicationName> <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> <PackageUpdate> <Name>A</Name> <DisplayName>A</DisplayName> @@ -9,5 +10,6 @@ <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/Updates.xml b/tests/auto/installer/messageboxhandler/data/messagebox/Updates.xml index 77b5a9956..0781dcfc5 100644 --- a/tests/auto/installer/messageboxhandler/data/messagebox/Updates.xml +++ b/tests/auto/installer/messageboxhandler/data/messagebox/Updates.xml @@ -1,6 +1,7 @@ <Updates> <ApplicationName>{AnyApplication}</ApplicationName> <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> <PackageUpdate> <Name>A</Name> <DisplayName>A</DisplayName> @@ -9,5 +10,6 @@ <ReleaseDate>2015-01-01</ReleaseDate> <Default>true</Default> <Script>script.qs</Script> + <SHA1>ad3157ed059e3369c094e154319de1d255865de5</SHA1> </PackageUpdate> </Updates> diff --git a/tests/auto/installer/messageboxhandler/messageboxhandler.pro b/tests/auto/installer/messageboxhandler/messageboxhandler.pro index fd87ba92e..3f42aae7b 100644 --- a/tests/auto/installer/messageboxhandler/messageboxhandler.pro +++ b/tests/auto/installer/messageboxhandler/messageboxhandler.pro @@ -4,4 +4,4 @@ SOURCES += tst_messageboxhandler.cpp RESOURCES += \ settings.qrc \ - ..\shared\config.qrc + ../shared/config.qrc diff --git a/tests/auto/installer/messageboxhandler/tst_messageboxhandler.cpp b/tests/auto/installer/messageboxhandler/tst_messageboxhandler.cpp index 464e1eef7..5db79cc55 100644 --- a/tests/auto/installer/messageboxhandler/tst_messageboxhandler.cpp +++ b/tests/auto/installer/messageboxhandler/tst_messageboxhandler.cpp @@ -93,9 +93,8 @@ private slots: QInstaller::init(); //This will eat debug output core = new PackageManagerCore(BinaryContent::MagicInstallerMarker, QList<OperationBlob> (), - QString(), Protocol::DefaultAuthorizationKey, Protocol::Mode::Production, + QString(), QString(), Protocol::DefaultAuthorizationKey, Protocol::Mode::Production, QHash<QString, QString>(), true); - core->setAllowedRunningProcesses(QStringList() << QCoreApplication::applicationFilePath()); core->disableWriteMaintenanceTool(); core->setAutoConfirmCommand(); m_installDir = QInstaller::generateTemporaryFileName(); @@ -196,7 +195,7 @@ private slots: setRepository(":///data/missingarchive"); core->autoAcceptMessageBoxes(); core->installSelectedComponentsSilently(QStringList () << "C"); - QCOMPARE(PackageManagerCore::Canceled, core->status()); + QCOMPARE(PackageManagerCore::Failure, core->status()); // Fails after retrying } void messageBoxFromScriptDefaultAnswer() 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/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/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/settings.qrc b/tests/auto/installer/metadatajob/settings.qrc index c881f294b..5df3befd9 100644 --- a/tests/auto/installer/metadatajob/settings.qrc +++ b/tests/auto/installer/metadatajob/settings.qrc @@ -1,8 +1,9 @@ <RCC> <qresource prefix="/"> - <file>data/config.xml</file> <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 index ef7b42940..cb974e7ad 100644 --- a/tests/auto/installer/metadatajob/tst_metadatajob.cpp +++ b/tests/auto/installer/metadatajob/tst_metadatajob.cpp @@ -1,6 +1,6 @@ /************************************************************************** ** -** Copyright (C) 2020 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. @@ -47,7 +47,6 @@ class tst_MetaDataJob : public QObject private slots: void testRepository() { - Settings settings = Settings::fromFileAndPrefix(":///data/config.xml", ":///data"); PackageManagerCore core; core.setInstaller(); QSet<Repository> repoList; @@ -63,7 +62,6 @@ private slots: void testRepositoryUpdateActionAdd() { - Settings settings = Settings::fromFileAndPrefix(":///data/config.xml", ":///data"); PackageManagerCore core; core.setInstaller(); QSet<Repository> repoList; @@ -82,7 +80,6 @@ private slots: void testRepositoryUpdateActionRemove() { - Settings settings = Settings::fromFileAndPrefix(":///data/config.xml", ":///data"); PackageManagerCore core; core.setInstaller(); QSet<Repository> repoList; @@ -100,6 +97,49 @@ private slots: 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); + } }; 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/Updates.xml b/tests/auto/installer/moveoperation/data/repository/Updates.xml index 6b1856d51..5cdad4e45 100644 --- a/tests/auto/installer/moveoperation/data/repository/Updates.xml +++ b/tests/auto/installer/moveoperation/data/repository/Updates.xml @@ -10,5 +10,6 @@ <ReleaseDate>2015-01-01</ReleaseDate> <Default>true</Default> <Script>script.qs</Script> + <SHA1>badc75810d399a35bae6f6b2cd8acfc1d5b1ccd2</SHA1> </PackageUpdate> </Updates> diff --git a/tests/auto/installer/moveoperation/moveoperation.pro b/tests/auto/installer/moveoperation/moveoperation.pro index a5f17c889..a1195299a 100644 --- a/tests/auto/installer/moveoperation/moveoperation.pro +++ b/tests/auto/installer/moveoperation/moveoperation.pro @@ -7,4 +7,4 @@ SOURCES = tst_moveoperation.cpp RESOURCES += \ settings.qrc \ - ..\shared\config.qrc + ../shared/config.qrc diff --git a/tests/auto/installer/moveoperation/tst_moveoperation.cpp b/tests/auto/installer/moveoperation/tst_moveoperation.cpp index 6bc72242a..bb391efee 100644 --- a/tests/auto/installer/moveoperation/tst_moveoperation.cpp +++ b/tests/auto/installer/moveoperation/tst_moveoperation.cpp @@ -42,8 +42,8 @@ class tst_moveoperation : public QObject private: void installFromCLI(const QString &repository) { - PackageManagerCore *core = PackageManager::getPackageManagerWithInit - (m_testDirectory, repository); + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (m_testDirectory, repository)); core->installDefaultComponentsSilently(); QFile movedFile(m_testDirectory + QDir::separator() + "DestinationFolder/testFile.txt"); @@ -86,8 +86,8 @@ private slots: QVERIFY(!op.performOperation()); QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::InvalidArguments); - QCOMPARE(op.errorString(), QString("Invalid arguments in Move: " - "0 arguments given, exactly 2 arguments expected.")); + 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() diff --git a/tests/auto/installer/packagemanagercore/tst_packagemanagercore.cpp b/tests/auto/installer/packagemanagercore/tst_packagemanagercore.cpp index ae2c3b211..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. @@ -46,7 +46,7 @@ using namespace QInstaller; class DummyComponent : public Component { public: - DummyComponent(PackageManagerCore *core) + explicit DummyComponent(PackageManagerCore *core) : Component(core) { setCheckState(Qt::Checked); @@ -260,7 +260,6 @@ private slots: root->setInstalled(); child1->setInstalled(); child2->setUninstalled(); - core.componentsToInstallNeedsRecalculation(); core.calculateComponentsToInstall(); QCOMPARE(core.requiredDiskSpace(), 250ULL); } @@ -288,58 +287,12 @@ private slots: QVERIFY(QDir().rmdir(testDirectory)); } - void testAllowRunningProcess() - { - #ifdef Q_OS_MACOS - QSKIP("In macOS the app path and maintenancetool differ, not possible to test running processes."); - #endif - PackageManagerCore core; - core.setPackageManager(); - const QString testDirectory = QInstaller::generateTemporaryFileName(); - QVERIFY(QDir().mkpath(testDirectory)); - core.setValue(scTargetDir, testDirectory); - - QString appFilePath = QCoreApplication::applicationFilePath(); - core.setAllowedRunningProcesses(QStringList() << appFilePath); - const QString warningMessage = QString("Failure to read packages from "); - const QRegularExpression re(warningMessage); - QTest::ignoreMessage(QtWarningMsg, re); - QTest::ignoreMessage(QtDebugMsg, "No updates available."); - - QCOMPARE(PackageManagerCore::Failure, core.updateComponentsSilently(QStringList())); - QVERIFY(QDir().rmdir(testDirectory)); - } - - void testDisallowRunningProcess() - { - #ifdef Q_OS_MACOS - QSKIP("In macOS the app path and maintenancetool differ, not possible to test running processes."); - #endif - PackageManagerCore core; - core.setPackageManager(); - const QString testDirectory = QInstaller::generateTemporaryFileName(); - QVERIFY(QDir().mkpath(testDirectory)); - core.setValue(scTargetDir, testDirectory); - - const QString warningMessageUp = QString("Unable to update components. Please stop these processes: "); - const QRegularExpression reUp(warningMessageUp); - QTest::ignoreMessage(QtWarningMsg, reUp); - QVERIFY_EXCEPTION_THROWN(core.updateComponentsSilently(QStringList()), Error); - - const QString warningMessageRm = QString("Unable to remove components. Please stop these processes: "); - const QRegularExpression reRm(warningMessageRm); - QTest::ignoreMessage(QtWarningMsg, reRm); - QVERIFY_EXCEPTION_THROWN(core.removeInstallationSilently(), Error); - - QVERIFY(QDir().rmdir(testDirectory)); - } - void testCoreDataValues() { QHash<QString, QString> userValues; PackageManagerCore *core = new PackageManagerCore(BinaryContent::MagicInstallerMarker, QList<OperationBlob> (), - QString(), Protocol::DefaultAuthorizationKey, Protocol::Mode::Production, + QString(), QString(), Protocol::DefaultAuthorizationKey, Protocol::Mode::Production, userValues, true); QCOMPARE(core->value("AllUsers"), QLatin1String("")); QCOMPARE(core->value("ProductName"), QLatin1String("Unit Test Application")); @@ -361,7 +314,7 @@ private slots: userValues.insert("RootDir", "Overwritten RootDir"); PackageManagerCore *core = new PackageManagerCore(BinaryContent::MagicInstallerMarker, QList<OperationBlob> (), - QString(), Protocol::DefaultAuthorizationKey, Protocol::Mode::Production, + QString(), QString(), Protocol::DefaultAuthorizationKey, Protocol::Mode::Production, userValues, true); QCOMPARE(core->value("AllUsers"), QLatin1String("true")); QCOMPARE(core->value("ProductName"), QLatin1String("Overwritten ProductName")); @@ -370,6 +323,28 @@ private slots: QCOMPARE(core->value("RootDir"), QLatin1String("Overwritten RootDir")); core->deleteLater(); } + + 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"; + } + + void testToFromNativeSeparators() + { + QFETCH(QString, path); + + 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 + } }; 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/Updates.xml b/tests/auto/installer/registerfiletypeoperation/data/repository/Updates.xml index 0826afae8..6435ae0f7 100644 --- a/tests/auto/installer/registerfiletypeoperation/data/repository/Updates.xml +++ b/tests/auto/installer/registerfiletypeoperation/data/repository/Updates.xml @@ -5,7 +5,7 @@ <PackageUpdate> <Name>A</Name> <DisplayName>A</DisplayName> - <Description>Example component A</Description> + <Description>Example component for RegisterFileTypeOperation</Description> <Version>1.0.2-1</Version> <ReleaseDate>2015-01-01</ReleaseDate> <Default>true</Default> diff --git a/tests/auto/installer/registerfiletypeoperation/tst_registerfiletypeoperation.cpp b/tests/auto/installer/registerfiletypeoperation/tst_registerfiletypeoperation.cpp index 5a4377d7b..2b2bfc53c 100644 --- a/tests/auto/installer/registerfiletypeoperation/tst_registerfiletypeoperation.cpp +++ b/tests/auto/installer/registerfiletypeoperation/tst_registerfiletypeoperation.cpp @@ -1,7 +1,7 @@ /************************************************************************** ** -** Copyright (C) 2020 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. ** @@ -80,7 +80,6 @@ private slots: QInstaller::init(); QString randomString = ""; const QString possible = "abcdefghijklmnopqrstuvwxyz0123456789"; - qsrand(QTime::currentTime().msec()); for (int i = 0; i < 5; i++) { int index = QRandomGenerator::global()->generate() % possible.length(); QChar nextChar = possible.at(index); diff --git a/tests/auto/installer/replaceoperation/data/repository/Updates.xml b/tests/auto/installer/replaceoperation/data/repository/Updates.xml index a0ade298c..7585b57a4 100644 --- a/tests/auto/installer/replaceoperation/data/repository/Updates.xml +++ b/tests/auto/installer/replaceoperation/data/repository/Updates.xml @@ -1,6 +1,7 @@ <Updates> <ApplicationName>{AnyApplication}</ApplicationName> <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> <PackageUpdate> <Name>A</Name> <DisplayName>A</DisplayName> @@ -9,6 +10,7 @@ <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> diff --git a/tests/auto/installer/replaceoperation/replaceoperation.pro b/tests/auto/installer/replaceoperation/replaceoperation.pro index bc558c32e..2334fd661 100644 --- a/tests/auto/installer/replaceoperation/replaceoperation.pro +++ b/tests/auto/installer/replaceoperation/replaceoperation.pro @@ -7,4 +7,4 @@ SOURCES += tst_replaceoperation.cpp RESOURCES += \ settings.qrc \ - ..\shared\config.qrc + ../shared/config.qrc diff --git a/tests/auto/installer/replaceoperation/tst_replaceoperation.cpp b/tests/auto/installer/replaceoperation/tst_replaceoperation.cpp index 33bd2b6c1..488a14dd1 100644 --- a/tests/auto/installer/replaceoperation/tst_replaceoperation.cpp +++ b/tests/auto/installer/replaceoperation/tst_replaceoperation.cpp @@ -103,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); @@ -139,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); 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 952317105..e4a85a730 100644 --- a/tests/auto/installer/scriptengine/data/addOperation.qs +++ b/tests/auto/installer/scriptengine/data/addOperation.qs @@ -1,7 +1,7 @@ /************************************************************************** ** -** Copyright (C) 2020 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. ** 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 304dd21f4..bccb6f7ca 100644 --- a/tests/auto/installer/settings/data/full_config.xml +++ b/tests/auto/installer/settings/data/full_config.xml @@ -37,6 +37,7 @@ 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> diff --git a/tests/auto/installer/settings/tst_settings.cpp b/tests/auto/installer/settings/tst_settings.cpp index f8aa00528..15dcc98a1 100644 --- a/tests/auto/installer/settings/tst_settings.cpp +++ b/tests/auto/installer/settings/tst_settings.cpp @@ -36,6 +36,8 @@ using namespace QInstaller; +typedef QMap<QString, QVariant> ProductImageMap; + class tst_Settings : public QObject { Q_OBJECT @@ -93,7 +95,7 @@ void tst_Settings::loadTutorialConfig() QCOMPARE(settings.wizardMinimumWidth(), 0); QCOMPARE(settings.wizardMinimumHeight(), 0); QCOMPARE(settings.wizardShowPageList(), true); - QCOMPARE(settings.productImages(), QStringList()); + QCOMPARE(settings.productImages(), ProductImageMap()); QCOMPARE(settings.titleColor(), QString()); QCOMPARE(settings.runProgram(), QString()); QCOMPARE(settings.runProgramArguments(), QStringList()); @@ -107,6 +109,7 @@ 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); 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/cliinterface/data/filequeryrepository/A/1.0.2-1meta.7z b/tests/auto/installer/settingsoperation/data/repository/C/1.0.0meta.7z Binary files differindex a006c5c96..a990fdbf1 100644 --- a/tests/auto/installer/cliinterface/data/filequeryrepository/A/1.0.2-1meta.7z +++ 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 index 77b5a9956..3e88f849d 100644 --- a/tests/auto/installer/settingsoperation/data/repository/Updates.xml +++ b/tests/auto/installer/settingsoperation/data/repository/Updates.xml @@ -1,13 +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>true</Default> + <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 index d030220ab..8da639ad6 100644 --- a/tests/auto/installer/settingsoperation/settings.qrc +++ b/tests/auto/installer/settingsoperation/settings.qrc @@ -2,5 +2,7 @@ <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 b5faa933e..b4233f53f 100644 --- a/tests/auto/installer/settingsoperation/settingsoperation.pro +++ b/tests/auto/installer/settingsoperation/settingsoperation.pro @@ -6,4 +6,4 @@ QT += testlib SOURCES += tst_settingsoperation.cpp RESOURCES += settings.qrc\ - ..\shared\config.qrc + ../shared/config.qrc diff --git a/tests/auto/installer/settingsoperation/tst_settingsoperation.cpp b/tests/auto/installer/settingsoperation/tst_settingsoperation.cpp index b7ea4fbc5..2da0870c7 100644 --- a/tests/auto/installer/settingsoperation/tst_settingsoperation.cpp +++ b/tests/auto/installer/settingsoperation/tst_settingsoperation.cpp @@ -90,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 @@ -177,6 +177,7 @@ private slots: QFile testFile(testFilePath); QVERIFY2(testFile.open(QIODevice::WriteOnly | QIODevice::Text), contentFile.errorString().toLatin1()); + m_cleanupFilePaths << testFilePath; QTextStream out(&testFile); @@ -244,6 +245,7 @@ private slots: QFile testFile(testFilePath); QVERIFY2(testFile.open(QIODevice::WriteOnly | QIODevice::Text), contentFile.errorString() .toLatin1()); + m_cleanupFilePaths << testFilePath; QTextStream out(&testFile); @@ -293,7 +295,7 @@ private slots: QCOMPARE(testSettings.value("testcategory/categoryarrayvalue1").toStringList(), QStringList() << "value1" << "value2" << "value3"); - core->installDefaultComponentsSilently(); + core->installSelectedComponentsSilently(QStringList() << "A"); QCOMPARE(testSettings.value("testcategory/categoryarrayvalue1").toStringList(), QStringList() << "value1" << "value2" << "value3" << "valueFromScript"); @@ -309,6 +311,68 @@ private slots: 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/packagemanager.h b/tests/auto/installer/shared/packagemanager.h index 4cc5426ad..9948be00a 100644 --- a/tests/auto/installer/shared/packagemanager.h +++ b/tests/auto/installer/shared/packagemanager.h @@ -1,6 +1,6 @@ /************************************************************************** ** -** Copyright (C) 2020 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. @@ -30,24 +30,37 @@ #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->setAllowedRunningProcesses(QStringList() << appFilePath); core->disableWriteMaintenanceTool(); core->setAutoConfirmCommand(); QSet<Repository> repoList; @@ -62,6 +75,7 @@ struct PackageManager static PackageManagerCore *getPackageManagerWithInit(const QString &targetDir, const QString &repository = QString()) { QInstaller::init(); + qInstallMessageHandler(silentTestMessageHandler); return getPackageManager(targetDir, repository); } }; diff --git a/tests/auto/installer/shared/verifyinstaller.h b/tests/auto/installer/shared/verifyinstaller.h index 7cd2af05b..e19d3fa0a 100644 --- a/tests/auto/installer/shared/verifyinstaller.h +++ b/tests/auto/installer/shared/verifyinstaller.h @@ -1,6 +1,6 @@ /************************************************************************** ** -** Copyright (C) 2020 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. @@ -29,6 +29,8 @@ #ifndef VERIFYINSTALLER_H #define VERIFYINSTALLER_H +#include <packagemanagercore.h> + #include <QString> #include <QStringList> #include <QCryptographicHash> @@ -36,21 +38,25 @@ #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); - QVERIFY(dir.exists()); + QVERIFY2(dir.exists(), qPrintable(QLatin1String("Directory: \"%1\" does not exist").arg(dir.absolutePath()))); QFileInfo fileInfo; fileInfo.setFile(dir, fileName); - QVERIFY(fileInfo.exists()); + 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); - QVERIFY(!dir.exists()); + 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) @@ -58,7 +64,8 @@ struct VerifyInstaller QDir dir(installDir + QDir::separator() + "installerResources" + QDir::separator() + componentName); QFileInfo fileInfo; fileInfo.setFile(dir, fileName); - QVERIFY(!fileInfo.exists()); + QVERIFY2(!fileInfo.exists(), qPrintable(QLatin1String("File: \"%1\" still exists for \"%2\".") + .arg(fileName).arg(componentName))); } static void verifyFileExistence(const QString &installDir, const QStringList &fileList) @@ -112,5 +119,21 @@ struct VerifyInstaller } } } + + 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/Updates.xml b/tests/auto/installer/simplemovefileoperation/data/repository/Updates.xml index 77b5a9956..6df6a436b 100644 --- a/tests/auto/installer/simplemovefileoperation/data/repository/Updates.xml +++ b/tests/auto/installer/simplemovefileoperation/data/repository/Updates.xml @@ -1,6 +1,7 @@ <Updates> <ApplicationName>{AnyApplication}</ApplicationName> <ApplicationVersion>1.0.0</ApplicationVersion> + <Checksum>false</Checksum> <PackageUpdate> <Name>A</Name> <DisplayName>A</DisplayName> @@ -9,5 +10,6 @@ <ReleaseDate>2015-01-01</ReleaseDate> <Default>true</Default> <Script>script.qs</Script> + <SHA1>8f2df84c9eada2570c02a7df573288e5cb6644e2</SHA1> </PackageUpdate> </Updates> diff --git a/tests/auto/installer/simplemovefileoperation/simplemovefileoperation.pro b/tests/auto/installer/simplemovefileoperation/simplemovefileoperation.pro index a96003065..1cb84824f 100644 --- a/tests/auto/installer/simplemovefileoperation/simplemovefileoperation.pro +++ b/tests/auto/installer/simplemovefileoperation/simplemovefileoperation.pro @@ -7,4 +7,4 @@ SOURCES = tst_simplemovefileoperation.cpp RESOURCES += \ settings.qrc \ - ..\shared\config.qrc + ../shared/config.qrc 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 index a9542eb0d..b329bb223 100644 --- a/tests/auto/installer/treename/data/invalid_repository/Updates.xml +++ b/tests/auto/installer/treename/data/invalid_repository/Updates.xml @@ -9,10 +9,6 @@ <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> @@ -21,9 +17,6 @@ <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>componentB</Name> @@ -32,9 +25,31 @@ <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> <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 index 1ab3caa23..295f076dd 100644 --- a/tests/auto/installer/treename/data/repository/Updates.xml +++ b/tests/auto/installer/treename/data/repository/Updates.xml @@ -116,4 +116,20 @@ <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_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 index 3837d4440..9b31cbade 100644 --- a/tests/auto/installer/treename/settings.qrc +++ b/tests/auto/installer/treename/settings.qrc @@ -1,5 +1,7 @@ <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> @@ -21,6 +23,43 @@ <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 index f983b39cf..97315faad 100644 --- a/tests/auto/installer/treename/treename.pro +++ b/tests/auto/installer/treename/treename.pro @@ -7,4 +7,4 @@ SOURCES += tst_treename.cpp RESOURCES += \ settings.qrc \ - ..\shared\config.qrc + ../shared/config.qrc diff --git a/tests/auto/installer/treename/tst_treename.cpp b/tests/auto/installer/treename/tst_treename.cpp index 0dc7bfa33..2c8be6ddd 100644 --- a/tests/auto/installer/treename/tst_treename.cpp +++ b/tests/auto/installer/treename/tst_treename.cpp @@ -1,6 +1,6 @@ /************************************************************************** ** -** Copyright (C) 2021 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. @@ -44,7 +44,22 @@ private slots: void moveToSubItem(); void dependencyToMovedItem(); void autodependOnMovedItem(); - void moveToExistingItem(); + + 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(); @@ -57,8 +72,8 @@ private: void tst_TreeName::moveToRoot() { // componentB.sub1.sub1 moved from sub item to root (BSub1Sub1ToRoot) - PackageManagerCore *core = PackageManager::getPackageManagerWithInit - (m_installDir, ":///data/repository"); + QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit + (m_installDir, ":///data/repository")); QCOMPARE(PackageManagerCore::Success, core->installSelectedComponentsSilently(QStringList() << "componentB.sub1.sub1")); QList<Component*> installedComponents = core->orderedComponentsToInstall(); @@ -75,8 +90,8 @@ void tst_TreeName::moveToRoot() void tst_TreeName::moveToSubItem() { // componentB.sub1.sub2 moved under componentC (componentC.sub1) - PackageManagerCore *core = PackageManager::getPackageManagerWithInit - (m_installDir, ":///data/repository"); + 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"); @@ -88,8 +103,8 @@ void tst_TreeName::moveToSubItem() void tst_TreeName::dependencyToMovedItem() { // componentA depends on componentB.sub2 which is moved to root - PackageManagerCore *core = PackageManager::getPackageManagerWithInit - (m_installDir, ":///data/repository"); + 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"); @@ -102,8 +117,8 @@ void tst_TreeName::dependencyToMovedItem() void tst_TreeName::autodependOnMovedItem() { // componentD autodepends on componentA.sub2 which is moved to root - PackageManagerCore *core = PackageManager::getPackageManagerWithInit - (m_installDir, ":///data/repository"); + 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"); @@ -111,12 +126,318 @@ void tst_TreeName::autodependOnMovedItem() << "componentASub2.txt" << "componentD.txt"); } -void tst_TreeName::moveToExistingItem() +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() { - PackageManagerCore *core = PackageManager::getPackageManagerWithInit - (m_installDir, ":///data/invalid_repository"); - QCOMPARE(PackageManagerCore::Failure, core->installSelectedComponentsSilently(QStringList() << "componentA")); - QCOMPARE(core->error(), "Cannot register component! Component with identifier componentA.sub1 already exists."); + // 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() diff --git a/tests/auto/installer/unicodeexecutable/main.c b/tests/auto/installer/unicodeexecutable/main.c index 412d0c77a..bce0321ab 100644 --- a/tests/auto/installer/unicodeexecutable/main.c +++ b/tests/auto/installer/unicodeexecutable/main.c @@ -1,11 +1,11 @@ /************************************************************************** ** -** Copyright (C) 2020 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 @@ -14,24 +14,13 @@ ** 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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** 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-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. +** 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 299584b2b..f938374fa 100644 --- a/tests/auto/installer/unicodeexecutable/stringdata.h +++ b/tests/auto/installer/unicodeexecutable/stringdata.h @@ -1,11 +1,11 @@ /************************************************************************** ** -** 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 @@ -14,24 +14,13 @@ ** 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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** 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-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. +** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** |