diff options
-rw-r--r-- | src/manager-lib/installationtask.cpp | 7 | ||||
-rw-r--r-- | src/manager-lib/packagemanager.cpp | 9 | ||||
-rw-r--r-- | src/manager-lib/packagemanager.h | 2 | ||||
-rw-r--r-- | tests/applicationinstaller/tst_applicationinstaller.cpp | 23 |
4 files changed, 41 insertions, 0 deletions
diff --git a/src/manager-lib/installationtask.cpp b/src/manager-lib/installationtask.cpp index 06e10ac9..7cdd2555 100644 --- a/src/manager-lib/installationtask.cpp +++ b/src/manager-lib/installationtask.cpp @@ -321,6 +321,13 @@ void InstallationTask::checkExtractedFile(const QString &file) Q_DECL_NOEXCEPT_E } if (m_foundIcon && m_foundInfo) { + bool doubleInstallation = false; + QMetaObject::invokeMethod(PackageManager::instance(), [this, &doubleInstallation]() { + doubleInstallation = PackageManager::instance()->isPackageInstallationActive(m_packageId); + }, Qt::BlockingQueuedConnection); + if (doubleInstallation) + throw Exception(Error::Package, "Cannot install the same package %1 multiple times in parallel").arg(m_packageId); + qCDebug(LogInstaller) << "emit taskRequestingInstallationAcknowledge" << id() << "for package" << m_package->id(); // this is a temporary just for the signal emission below diff --git a/src/manager-lib/packagemanager.cpp b/src/manager-lib/packagemanager.cpp index 301bf80b..8a70b465 100644 --- a/src/manager-lib/packagemanager.cpp +++ b/src/manager-lib/packagemanager.cpp @@ -839,6 +839,15 @@ QVariantMap PackageManager::documentLocation() const return locationMap(d->documentPath); } +bool PackageManager::isPackageInstallationActive(const QString &packageId) const +{ + for (const auto *t : qAsConst(d->installationTaskList)) { + if (t->packageId() == packageId) + return true; + } + return false; +} + void PackageManager::cleanupBrokenInstallations() Q_DECL_NOEXCEPT_EXPR(false) { if (d->cleanupBrokenInstallationsDone) diff --git a/src/manager-lib/packagemanager.h b/src/manager-lib/packagemanager.h index ef9863b0..4be96f5d 100644 --- a/src/manager-lib/packagemanager.h +++ b/src/manager-lib/packagemanager.h @@ -152,6 +152,8 @@ public: QVariantMap installationLocation() const; QVariantMap documentLocation() const; + bool isPackageInstallationActive(const QString &packageId) const; + // Q_SCRIPTABLEs are available via both QML and D-Bus Q_SCRIPTABLE QStringList packageIds() const; Q_SCRIPTABLE QVariantMap get(const QString &packageId) const; diff --git a/tests/applicationinstaller/tst_applicationinstaller.cpp b/tests/applicationinstaller/tst_applicationinstaller.cpp index 309d15b2..d5f7829e 100644 --- a/tests/applicationinstaller/tst_applicationinstaller.cpp +++ b/tests/applicationinstaller/tst_applicationinstaller.cpp @@ -120,6 +120,7 @@ private slots: void cancelPackageInstallation(); void parallelPackageInstallation(); + void doublePackageInstallation(); void validateDnsName_data(); void validateDnsName(); @@ -685,6 +686,28 @@ void tst_PackageManager::parallelPackageInstallation() clearSignalSpies(); } +void tst_PackageManager::doublePackageInstallation() +{ + QString task1Id = m_pm->startPackageInstallation(QUrl::fromLocalFile(qL1S(AM_TESTDATA_DIR "packages/test-dev-signed.appkg"))); + QVERIFY(!task1Id.isEmpty()); + QVERIFY(m_blockingUntilInstallationAcknowledgeSpy->wait(spyTimeout)); + QCOMPARE(m_blockingUntilInstallationAcknowledgeSpy->first()[0].toString(), task1Id); + + QString task2Id = m_pm->startPackageInstallation(QUrl::fromLocalFile(qL1S(AM_TESTDATA_DIR "packages/test-dev-signed.appkg"))); + QVERIFY(!task2Id.isEmpty()); + m_pm->acknowledgePackageInstallation(task2Id); + QVERIFY(m_failedSpy->wait(spyTimeout)); + QCOMPARE(m_failedSpy->first()[0].toString(), task2Id); + QCOMPARE(m_failedSpy->first()[2].toString(), qL1S("Cannot install the same package com.pelagicore.test multiple times in parallel")); + + clearSignalSpies(); + m_pm->cancelTask(task1Id); + QVERIFY(m_failedSpy->wait(spyTimeout)); + QCOMPARE(m_failedSpy->first()[0].toString(), task1Id); + + clearSignalSpies(); +} + void tst_PackageManager::validateDnsName_data() { QTest::addColumn<QString>("dnsName"); |