diff options
author | Katja Marttila <katja.marttila@qt.io> | 2019-12-27 10:24:45 +0200 |
---|---|---|
committer | Katja Marttila <katja.marttila@qt.io> | 2020-03-24 14:36:03 +0200 |
commit | e97b7ef213b21669bad38ed42cbcccd663f39e1b (patch) | |
tree | b80c738ed545db539ddaa898fe396ac5542be9fb /src | |
parent | 14a2502c7781a7e8036912767eea990a92dd560c (diff) |
Refactor and add unit tests for metadatajob
Split long functions into smaller understandable functions, added
unit tests for metadatajob.
Change-Id: Ib423eab3c9ae7771fb032b99f767f96e52266ea7
Reviewed-by: Iikka Eklund <iikka.eklund@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/libs/installer/metadatajob.cpp | 234 | ||||
-rw-r--r-- | src/libs/installer/metadatajob.h | 9 | ||||
-rw-r--r-- | src/libs/installer/packagemanagercore.cpp | 9 | ||||
-rw-r--r-- | src/libs/installer/packagemanagercore.h | 1 |
4 files changed, 148 insertions, 105 deletions
diff --git a/src/libs/installer/metadatajob.cpp b/src/libs/installer/metadatajob.cpp index 5fe660315..7651ee51c 100644 --- a/src/libs/installer/metadatajob.cpp +++ b/src/libs/installer/metadatajob.cpp @@ -600,25 +600,12 @@ MetadataJob::Status MetadataJob::parseUpdatesXml(const QList<FileTaskResult> &re if (!el.isNull() && el.tagName() == QLatin1String("PackageUpdate")) { const QDomNodeList c2 = el.childNodes(); QString packageName, packageVersion, packageHash; - for (int j = 0; j < c2.count(); ++j) { - if (c2.at(j).toElement().tagName() == scName) - packageName = c2.at(j).toElement().text(); - else if (c2.at(j).toElement().tagName() == scVersion) - packageVersion = (online ? c2.at(j).toElement().text() : QString()); - else if ((c2.at(j).toElement().tagName() == QLatin1String("SHA1")) && testCheckSum) - packageHash = c2.at(j).toElement().text(); - else { - foreach (QString meta, metaElements) { - if (c2.at(j).toElement().tagName() == meta) { - metaFound = true; - break; - } - } - } - } - const QString repoUrl = metadata.repository.url().toString(); - //If script element is not found, no need to fetch metadata + metaFound = parsePackageUpdate(c2, packageName, packageVersion, packageHash, + online, testCheckSum); + + //If meta element (script, licenses, etc.) is not found, no need to fetch metadata if (metaFound) { + const QString repoUrl = metadata.repository.url().toString(); addFileTaskItem(QString::fromLatin1("%1/%2/%3meta.7z").arg(repoUrl, packageName, packageVersion), metadata.directory + QString::fromLatin1("/%1-%2-meta.7z").arg(packageName, packageVersion), metadata, packageHash, packageName); @@ -663,93 +650,13 @@ MetadataJob::Status MetadataJob::parseUpdatesXml(const QList<FileTaskResult> &re // search for additional repositories that we might need to check const QDomNode repositoryUpdate = root.firstChildElement(QLatin1String("RepositoryUpdate")); - if (repositoryUpdate.isNull()) - continue; - - QHash<QString, QPair<Repository, Repository> > repositoryUpdates; - children = repositoryUpdate.toElement().childNodes(); - for (int i = 0; i < children.count(); ++i) { - const QDomElement el = children.at(i).toElement(); - if (!el.isNull() && el.tagName() == QLatin1String("Repository")) { - const QString action = el.attribute(QLatin1String("action")); - if (action == QLatin1String("add")) { - // add a new repository to the defaults list - Repository repository(resolveUrl(result, el.attribute(QLatin1String("url"))), true); - repository.setUsername(el.attribute(QLatin1String("username"))); - repository.setPassword(el.attribute(QLatin1String("password"))); - repository.setDisplayName(el.attribute(QLatin1String("displayname"))); - if (ProductKeyCheck::instance()->isValidRepository(repository)) { - repositoryUpdates.insertMulti(action, qMakePair(repository, Repository())); - qCDebug(QInstaller::lcGeneral) << "Repository to add:" - << repository.displayname(); - } - } else if (action == QLatin1String("remove")) { - // remove possible default repositories using the given server url - Repository repository(resolveUrl(result, el.attribute(QLatin1String("url"))), true); - repository.setDisplayName(el.attribute(QLatin1String("displayname"))); - repositoryUpdates.insertMulti(action, qMakePair(repository, Repository())); - - qCDebug(QInstaller::lcGeneral) << "Repository to remove:" - << repository.displayname(); - } else if (action == QLatin1String("replace")) { - // replace possible default repositories using the given server url - Repository oldRepository(resolveUrl(result, el.attribute(QLatin1String("oldUrl"))), true); - Repository newRepository(resolveUrl(result, el.attribute(QLatin1String("newUrl"))), true); - newRepository.setUsername(el.attribute(QLatin1String("username"))); - newRepository.setPassword(el.attribute(QLatin1String("password"))); - newRepository.setDisplayName(el.attribute(QLatin1String("displayname"))); - - if (ProductKeyCheck::instance()->isValidRepository(newRepository)) { - // store the new repository and the one old it replaces - repositoryUpdates.insertMulti(action, qMakePair(newRepository, oldRepository)); - qCDebug(QInstaller::lcGeneral) << "Replace repository" - << oldRepository.displayname() << "with" << newRepository.displayname(); - } - } else { - qCWarning(QInstaller::lcInstallerInstallLog) << "Invalid additional repositories action set " - "in Updates.xml fetched from" << metadata.repository.displayname() - << "line:" << el.lineNumber(); - } - } - } - - if (!repositoryUpdates.isEmpty()) { - Settings &s = m_core->settings(); - const QSet<Repository> temporaries = s.temporaryRepositories(); - // in case the temp repository introduced something new, we only want that temporary - if (temporaries.contains(metadata.repository)) { - QSet<Repository> tmpRepositories; - typedef QPair<Repository, Repository> RepositoryPair; - - QList<RepositoryPair> values = repositoryUpdates.values(QLatin1String("add")); - foreach (const RepositoryPair &value, values) - tmpRepositories.insert(value.first); - - values = repositoryUpdates.values(QLatin1String("replace")); - foreach (const RepositoryPair &value, values) - tmpRepositories.insert(value.first); - - tmpRepositories = tmpRepositories.subtract(temporaries); - if (tmpRepositories.count() > 0) { - s.addTemporaryRepositories(tmpRepositories, true); - QFile::remove(result.target()); - m_metaFromDefaultRepositories.clear(); - return XmlDownloadRetry; - } - } else if (s.updateDefaultRepositories(repositoryUpdates) == Settings::UpdatesApplied) { - if (m_core->isMaintainer()) { - bool gainedAdminRights = false; - if (!m_core->directoryWritable(m_core->value(scTargetDir))) { - m_core->gainAdminRights(); - gainedAdminRights = true; - } - m_core->writeMaintenanceConfigFiles(); - if (gainedAdminRights) - m_core->dropAdminRights(); - } - m_metaFromDefaultRepositories.clear(); - QFile::remove(result.target()); - return XmlDownloadRetry; + if (!repositoryUpdate.isNull()) { + QHash<QString, QPair<Repository, Repository> > repositoryUpdates = + searchAdditionalRepositories(repositoryUpdate, result, metadata); + if (!repositoryUpdates.isEmpty()) { + MetadataJob::Status status = setAdditionalRepositories(repositoryUpdates, result, metadata); + if (status == XmlDownloadRetry) + return status; } } } @@ -806,4 +713,121 @@ void MetadataJob::addFileTaskItem(const QString &source, const QString &target, m_packages.append(item); } +bool MetadataJob::parsePackageUpdate(const QDomNodeList &c2, QString &packageName, + QString &packageVersion, QString &packageHash, + bool online, bool testCheckSum) +{ + bool metaFound = false; + for (int j = 0; j < c2.count(); ++j) { + const QDomElement element = c2.at(j).toElement(); + if (element.tagName() == scName) + packageName = element.text(); + else if (element.tagName() == scVersion) + packageVersion = (online ? element.text() : QString()); + else if ((element.tagName() == QLatin1String("SHA1")) && testCheckSum) + packageHash = element.text(); + else { + foreach (QString meta, metaElements) { + if (element.tagName() == meta) { + metaFound = true; + break; + } + } + } + } + return metaFound; +} + +QHash<QString, QPair<Repository, Repository> > MetadataJob::searchAdditionalRepositories + (const QDomNode &repositoryUpdate, const FileTaskResult &result, const Metadata &metadata) +{ + QHash<QString, QPair<Repository, Repository> > repositoryUpdates; + const QDomNodeList children = repositoryUpdate.toElement().childNodes(); + for (int i = 0; i < children.count(); ++i) { + const QDomElement el = children.at(i).toElement(); + if (!el.isNull() && el.tagName() == QLatin1String("Repository")) { + const QString action = el.attribute(QLatin1String("action")); + if (action == QLatin1String("add")) { + // add a new repository to the defaults list + Repository repository(resolveUrl(result, el.attribute(QLatin1String("url"))), true); + repository.setUsername(el.attribute(QLatin1String("username"))); + repository.setPassword(el.attribute(QLatin1String("password"))); + repository.setDisplayName(el.attribute(QLatin1String("displayname"))); + if (ProductKeyCheck::instance()->isValidRepository(repository)) { + repositoryUpdates.insertMulti(action, qMakePair(repository, Repository())); + qDebug() << "Repository to add:" << repository.displayname(); + } + } else if (action == QLatin1String("remove")) { + // remove possible default repositories using the given server url + Repository repository(resolveUrl(result, el.attribute(QLatin1String("url"))), true); + repository.setDisplayName(el.attribute(QLatin1String("displayname"))); + repositoryUpdates.insertMulti(action, qMakePair(repository, Repository())); + + qDebug() << "Repository to remove:" << repository.displayname(); + } else if (action == QLatin1String("replace")) { + // replace possible default repositories using the given server url + Repository oldRepository(resolveUrl(result, el.attribute(QLatin1String("oldUrl"))), true); + Repository newRepository(resolveUrl(result, el.attribute(QLatin1String("newUrl"))), true); + newRepository.setUsername(el.attribute(QLatin1String("username"))); + newRepository.setPassword(el.attribute(QLatin1String("password"))); + newRepository.setDisplayName(el.attribute(QLatin1String("displayname"))); + + if (ProductKeyCheck::instance()->isValidRepository(newRepository)) { + // store the new repository and the one old it replaces + repositoryUpdates.insertMulti(action, qMakePair(newRepository, oldRepository)); + qDebug() << "Replace repository" << oldRepository.displayname() << "with" + << newRepository.displayname(); + } + } else { + qDebug() << "Invalid additional repositories action set in Updates.xml fetched " + "from" << metadata.repository.displayname() << "line:" << el.lineNumber(); + } + } + } + return repositoryUpdates; +} + +MetadataJob::Status MetadataJob::setAdditionalRepositories(QHash<QString, QPair<Repository, Repository> > repositoryUpdates, + const FileTaskResult &result, const Metadata& metadata) +{ + MetadataJob::Status status = XmlDownloadSuccess; + Settings &s = m_core->settings(); + const QSet<Repository> temporaries = s.temporaryRepositories(); + // in case the temp repository introduced something new, we only want that temporary + if (temporaries.contains(metadata.repository)) { + QSet<Repository> tmpRepositories; + typedef QPair<Repository, Repository> RepositoryPair; + + QList<RepositoryPair> values = repositoryUpdates.values(QLatin1String("add")); + foreach (const RepositoryPair &value, values) + tmpRepositories.insert(value.first); + + values = repositoryUpdates.values(QLatin1String("replace")); + foreach (const RepositoryPair &value, values) + tmpRepositories.insert(value.first); + + tmpRepositories = tmpRepositories.subtract(temporaries); + if (tmpRepositories.count() > 0) { + s.addTemporaryRepositories(tmpRepositories, true); + QFile::remove(result.target()); + m_metaFromDefaultRepositories.clear(); + status = XmlDownloadRetry; + } + } else if (s.updateDefaultRepositories(repositoryUpdates) == Settings::UpdatesApplied) { + if (m_core->isMaintainer()) { + bool gainedAdminRights = false; + if (!m_core->directoryWritable(m_core->value(scTargetDir))) { + m_core->gainAdminRights(); + gainedAdminRights = true; + } + m_core->writeMaintenanceConfigFiles(); + if (gainedAdminRights) + m_core->dropAdminRights(); + } + m_metaFromDefaultRepositories.clear(); + QFile::remove(result.target()); + status = XmlDownloadRetry; + } + return status; +} } // namespace QInstaller diff --git a/src/libs/installer/metadatajob.h b/src/libs/installer/metadatajob.h index e3a7f6a44..f8f935529 100644 --- a/src/libs/installer/metadatajob.h +++ b/src/libs/installer/metadatajob.h @@ -36,6 +36,9 @@ #include <QFutureWatcher> +class QDomNodeList; +class QDomNode; + namespace QInstaller { class PackageManagerCore; @@ -101,6 +104,12 @@ private: QSet<Repository> getRepositories(); void addFileTaskItem(const QString &source, const QString &target, const Metadata &metadata, const QString &sha1, const QString &packageName); + bool parsePackageUpdate(const QDomNodeList &c2, QString &packageName, QString &packageVersion, + QString &packageHash, bool online, bool testCheckSum); + QHash<QString, QPair<Repository, Repository> > searchAdditionalRepositories(const QDomNode &repositoryUpdate, + const FileTaskResult &result, const Metadata &metadata); + MetadataJob::Status setAdditionalRepositories(QHash<QString, QPair<Repository, Repository> > repositoryUpdates, + const FileTaskResult &result, const Metadata& metadata); private: PackageManagerCore *m_core; diff --git a/src/libs/installer/packagemanagercore.cpp b/src/libs/installer/packagemanagercore.cpp index 085de5049..8d3754f8a 100644 --- a/src/libs/installer/packagemanagercore.cpp +++ b/src/libs/installer/packagemanagercore.cpp @@ -2922,6 +2922,15 @@ QString PackageManagerCore::installerBinaryPath() const } /*! + \sa {installer::setInstaller}{installer.setInstaller} + \sa isInstaller(), setUpdater(), setPackageManager() +*/ +void PackageManagerCore::setInstaller() +{ + d->m_magicBinaryMarker = BinaryContent::MagicInstallerMarker; +} + +/*! Returns \c true if running as installer. \sa {installer::isInstaller}{installer.isInstaller} diff --git a/src/libs/installer/packagemanagercore.h b/src/libs/installer/packagemanagercore.h index 75bdfb863..6c32fcb29 100644 --- a/src/libs/installer/packagemanagercore.h +++ b/src/libs/installer/packagemanagercore.h @@ -223,6 +223,7 @@ public: bool uninstallComponentsSilently(const QStringList& components); // convenience + Q_INVOKABLE void setInstaller(); Q_INVOKABLE bool isInstaller() const; Q_INVOKABLE bool isOfflineOnly() const; |