summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorKatja Marttila <katja.marttila@qt.io>2018-02-28 09:54:22 +0200
committerKatja Marttila <katja.marttila@qt.io>2018-04-05 06:54:21 +0000
commitd2ae9c16c3427c272d41e9a471f705ad8947a97a (patch)
tree4ed6b3cafd28b11f02ef4f4faa6164bcfbd85b63 /tests
parent6664ca85f09d6ae195ac30f83a60d53c2355da0f (diff)
Add attribute to mark parts of install tree unstable
This commit adds new AllowUnstableComponents configuration. Setting AllowUnstablecomponents to true in config.xml will * allow installing other components when there are errors in scripts * allow installing other components when there are missing dependencies * will mark the 'broken' components uninstallable in treeview Task-number: QTIFW-930 Change-Id: I8d28cf9c4b0401e0bb76795e87d581f39b64f128 Reviewed-by: Iikka Eklund <iikka.eklund@qt.io>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/installer/brokeninstaller/brokeninstaller.pro8
-rw-r--r--tests/auto/installer/brokeninstaller/components.qrc6
-rw-r--r--tests/auto/installer/brokeninstaller/data/broken_script.qs31
-rw-r--r--tests/auto/installer/brokeninstaller/data/updates.xml163
-rw-r--r--tests/auto/installer/brokeninstaller/tst_brokeninstaller.cpp228
5 files changed, 436 insertions, 0 deletions
diff --git a/tests/auto/installer/brokeninstaller/brokeninstaller.pro b/tests/auto/installer/brokeninstaller/brokeninstaller.pro
new file mode 100644
index 000000000..e48733ac6
--- /dev/null
+++ b/tests/auto/installer/brokeninstaller/brokeninstaller.pro
@@ -0,0 +1,8 @@
+include(../../qttest.pri)
+
+QT -= gui
+QT += network xml qml
+
+SOURCES += tst_brokeninstaller.cpp
+
+RESOURCES += components.qrc
diff --git a/tests/auto/installer/brokeninstaller/components.qrc b/tests/auto/installer/brokeninstaller/components.qrc
new file mode 100644
index 000000000..1431393a6
--- /dev/null
+++ b/tests/auto/installer/brokeninstaller/components.qrc
@@ -0,0 +1,6 @@
+<RCC>
+ <qresource prefix="/">
+ <file>data/updates.xml</file>
+ <file>data/broken_script.qs</file>
+ </qresource>
+</RCC>
diff --git a/tests/auto/installer/brokeninstaller/data/broken_script.qs b/tests/auto/installer/brokeninstaller/data/broken_script.qs
new file mode 100644
index 000000000..a1574f46d
--- /dev/null
+++ b/tests/auto/installer/brokeninstaller/data/broken_script.qs
@@ -0,0 +1,31 @@
+/**************************************************************************
+**
+** Copyright (C) 2018 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$
+**
+**************************************************************************/
+function Component()
+{
+ installer.invalidScriptCall()
+}
diff --git a/tests/auto/installer/brokeninstaller/data/updates.xml b/tests/auto/installer/brokeninstaller/data/updates.xml
new file mode 100644
index 000000000..a20275120
--- /dev/null
+++ b/tests/auto/installer/brokeninstaller/data/updates.xml
@@ -0,0 +1,163 @@
+<Updates>
+ <ApplicationName>Your application</ApplicationName>
+ <ApplicationVersion>1.2.3</ApplicationVersion>
+ <Checksum>true</Checksum>
+ <PackageUpdate>
+ <Name>componentinvalidscript</Name>
+ <DisplayName>Invalid script component</DisplayName>
+ <Description>Install this example.</Description>
+ <Version>0.1.0-1</Version>
+ <ReleaseDate>2010-09-21</ReleaseDate>
+ <Default>true</Default>
+ <SortingPriority>1</SortingPriority>
+ <UpdateFile UncompressedSize="61"
+ CompressedSize="61"/>
+ <Licenses>
+ <License name="Beer Public License Agreement"
+ file="license.txt"/>
+ </Licenses>
+ </PackageUpdate>
+ <PackageUpdate>
+ <Name>componentb</Name>
+ <DisplayName>The second root component</DisplayName>
+ <Description>Install this example.</Description>
+ <Version>0.1.0-1</Version>
+ <ReleaseDate>2010-09-21</ReleaseDate>
+ <Default>true</Default>
+ <Script>installscript.qs</Script>
+ <SortingPriority>1</SortingPriority>
+ <UpdateFile UncompressedSize="61"
+ CompressedSize="61"/>
+ <Licenses>
+ <License name="Beer Public License Agreement"
+ file="license.txt"/>
+ </Licenses>
+ </PackageUpdate>
+ <PackageUpdate>
+ <Name>componentc</Name>
+ <DisplayName>The third root component</DisplayName>
+ <Description>Install this example.</Description>
+ <Version>0.1.0-1</Version>
+ <ReleaseDate>2010-09-21</ReleaseDate>
+ <Default>true</Default>
+ <Script>installscript.qs</Script>
+ <SortingPriority>1</SortingPriority>
+ <UpdateFile UncompressedSize="61"
+ CompressedSize="61"/>
+ <Licenses>
+ <License name="Beer Public License Agreement"
+ file="license.txt"/>
+ </Licenses>
+ </PackageUpdate>
+ <PackageUpdate>
+ <Name>componentc.subnode</Name>
+ <DisplayName>A subcomponent for the third root, dependency to component with invalid script</DisplayName>
+ <Description>Install this example.</Description>
+ <Version>0.1.0-1</Version>
+ <ReleaseDate>2010-09-21</ReleaseDate>
+ <Default>true</Default>
+ <Script>installscript.qs</Script>
+ <SortingPriority>1</SortingPriority>
+ <Dependencies>componentinvalidscript</Dependencies>
+ <UpdateFile UncompressedSize="61"
+ CompressedSize="61"/>
+ <Licenses>
+ <License name="Beer Public License Agreement"
+ file="license.txt"/>
+ </Licenses>
+ </PackageUpdate>
+ <PackageUpdate>
+ <Name>componentc.subnode.sub</Name>
+ <DisplayName>A subcomponent for the third roots subcomponent</DisplayName>
+ <Description>Install this example.</Description>
+ <Version>0.1.0-1</Version>
+ <ReleaseDate>2010-09-21</ReleaseDate>
+ <Script>installscript.qs</Script>
+ <Default>true</Default>
+ <UpdateFile UncompressedSize="61"
+ CompressedSize="61"/>
+ <Licenses>
+ <License name="Beer Public License Agreement"
+ file="license.txt"/>
+ </Licenses>
+ </PackageUpdate>
+ <PackageUpdate>
+ <Name>componentmissingdependency</Name>
+ <DisplayName>A component that has missing sha</DisplayName>
+ <Description>Install this example.</Description>
+ <Version>0.1.0-1</Version>
+ <ReleaseDate>2010-09-21</ReleaseDate>
+ <Default>true</Default>
+ <Script>installscript.qs</Script>
+ <UpdateFile UncompressedSize="61"
+ CompressedSize="61"/>
+ <Licenses>
+ <License name="Beer Public License Agreement"
+ file="license.txt"/>
+ </Licenses>
+ </PackageUpdate>
+ <PackageUpdate>
+ <Name>componentd</Name>
+ <DisplayName>Component that depends on component which is missing dependency</DisplayName>
+ <Description>Install this example.</Description>
+ <Version>0.1.0-1</Version>
+ <ReleaseDate>2010-09-21</ReleaseDate>
+ <Script>installscript.qs</Script>
+ <UpdateFile UncompressedSize="61"
+ CompressedSize="61"/>
+ <Licenses>
+ <License name="Beer Public License Agreement"
+ file="license.txt"/>
+ </Licenses>
+ </PackageUpdate>
+ <PackageUpdate>
+ <Name>componentmissingcontent</Name>
+ <DisplayName>A component which is missing 7z</DisplayName>
+ <Description>Install this example.</Description>
+ <Version>0.1.0-1</Version>
+ <ReleaseDate>2010-09-21</ReleaseDate>
+ <Default>true</Default>
+ <Script>installscript.qs</Script>
+ <SortingPriority>0</SortingPriority>
+ <DownloadableArchives>content.7z</DownloadableArchives>
+ <UpdateFile UncompressedSize="61"
+ CompressedSize="61"/>
+ <Licenses>
+ <License name="Beer Public License Agreement"
+ file="license.txt"/>
+ </Licenses>
+ </PackageUpdate>
+ <PackageUpdate>
+ <Name>componentmissingcontent.sub</Name>
+ <DisplayName>A subcomponent of component which is missing 7z</DisplayName>
+ <Description>Install this example.</Description>
+ <Version>0.1.0-1</Version>
+ <ReleaseDate>2010-09-21</ReleaseDate>
+ <Checkable>true</Checkable>
+ <Default>true</Default>
+ <Script>installscript.qs</Script>
+ <UpdateFile UncompressedSize="61"
+ CompressedSize="61"/>
+ <Licenses>
+ <License name="Beer Public License Agreement"
+ file="license.txt"/>
+ </Licenses>
+ </PackageUpdate>
+ <PackageUpdate>
+ <Name>componentE</Name>
+ <DisplayName>A component which is dependent on subcomponent of missing 7z component</DisplayName>
+ <Description>Install this example.</Description>
+ <Version>0.1.0-1</Version>
+ <ReleaseDate>2010-09-21</ReleaseDate>
+ <Script>installscript.qs</Script>
+ <Checkable>true</Checkable>
+ <Default>true</Default>
+ <Dependencies>componentmissingcontent.sub</Dependencies>
+ <UpdateFile UncompressedSize="61"
+ CompressedSize="61"/>
+ <Licenses>
+ <License name="Beer Public License Agreement"
+ file="license.txt"/>
+ </Licenses>
+ </PackageUpdate>
+</Updates>
diff --git a/tests/auto/installer/brokeninstaller/tst_brokeninstaller.cpp b/tests/auto/installer/brokeninstaller/tst_brokeninstaller.cpp
new file mode 100644
index 000000000..95f4ac77d
--- /dev/null
+++ b/tests/auto/installer/brokeninstaller/tst_brokeninstaller.cpp
@@ -0,0 +1,228 @@
+/**************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Installer Framework.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+**************************************************************************/
+
+#include "component.h"
+#include "componentmodel.h"
+#include "updatesinfo_p.h"
+#include "packagemanagercore.h"
+#include "settings.h"
+
+#include <QTest>
+#include <QtCore/QLocale>
+#include <QRegularExpression>
+
+using namespace KDUpdater;
+using namespace QInstaller;
+
+#define EXPECTED_COUNTS_COMPONENTS_VISIBLE 10
+#define EXPECTED_COUNT_ROOT_COMPONENTS 7
+#define EXPECTED_COUNT_INVALID_SCRIPT 7
+#define EXPECTED_COUNT_MISSING_DEPENDENCY 8
+
+static const char componentInvalidScript[] = "componentinvalidscript";
+static const char componentB[] = "componentb";
+
+static const char componentC[] = "componentc";
+static const char componentCSubnodeDependsOnInvalidScriptComponent[] = "componentc.subnode";
+static const char componentCSubnodeDependsOnInvalidScriptComponentSub[] = "componentc.subnode.sub";
+
+static const char componentMissingDependency[] = "componentmissingdependency";
+static const char componentDependsOnMissingDependency[] = "componentd";
+
+static const char componentMissingContent[] = "componentmissingcontent";
+static const char componentMissingContentSub[] = "componentmissingcontent.sub";
+static const char componentDependsOnMissingContentSub[] = "componentE";
+
+static const QMap<QString, QString> rootComponentDisplayNames = {
+ {"", QLatin1String("The root component")},
+ {"ru_ru", QString::fromUtf8("Корневая компонента")},
+ {"de_de", QString::fromUtf8("Wurzel Komponente")}
+};
+
+using namespace QInstaller;
+
+class tst_BrokenInstaller : public QObject
+{
+ Q_OBJECT
+
+public:
+ enum Option {
+ NoFlags = 0x00,
+ VirtualsVisible = 0x01,
+ NoForcedInstallation = 0x02
+ };
+ Q_DECLARE_FLAGS(Options, Option);
+
+private slots:
+ void initTestCase()
+ {
+
+ m_checkedComponentsWithBrokenScript << componentB << componentMissingDependency << componentDependsOnMissingDependency << componentMissingContent
+ << componentMissingContentSub << componentDependsOnMissingContentSub;
+ m_uncheckedComponentsWithBrokenScript << componentInvalidScript << componentCSubnodeDependsOnInvalidScriptComponent
+ << componentCSubnodeDependsOnInvalidScriptComponentSub << componentC;
+
+ m_checkedComponentsWithMissingDependency << componentB << componentMissingContent << componentMissingContentSub << componentDependsOnMissingContentSub
+ << componentInvalidScript << componentCSubnodeDependsOnInvalidScriptComponent
+ << componentCSubnodeDependsOnInvalidScriptComponentSub << componentC;
+ m_uncheckedComponentsWithMissingDependency << componentMissingDependency << componentDependsOnMissingDependency;
+
+ }
+
+ void testNameToIndexAndIndexToName()
+ {
+ PackageManagerCore core;
+ QList<Component*> rootComponents = loadComponents(core);
+
+ ComponentModel *model = new ComponentModel(1, &core);
+ model->setRootComponents(rootComponents);
+ // all names should be resolvable
+ QStringList all;
+ all << m_checkedComponentsWithBrokenScript << m_uncheckedComponentsWithBrokenScript << m_partiallyCheckedComponentsWithBrokenScript;
+ foreach (const QString &name, all) {
+ QVERIFY(model->indexFromComponentName(name).isValid());
+ QVERIFY(model->componentFromIndex(model->indexFromComponentName(name)) != 0);
+ QCOMPARE(model->componentFromIndex(model->indexFromComponentName(name))->name(), name);
+ }
+ }
+
+ void testInvalidScript()
+ {
+ PackageManagerCore core;
+ QList<Component*> components = loadComponents(core);
+
+ core.settings().setAllowUnstableComponents(true);
+ ComponentModel *model = new ComponentModel(1, &core);
+ Component *invalidScriptComponent = core.componentByName("componentinvalidscript");
+
+ // Using regexp to ignore the warning message as the message contains
+ // object address which we don't know
+ const QString debugMessage = QString("Exception while loading the component script");
+ const QRegularExpression re(debugMessage);
+ QTest::ignoreMessage(QtWarningMsg, re);
+ invalidScriptComponent->loadComponentScript(":///data/broken_script.qs");
+
+ model->setRootComponents(components);
+ testModelState(model, m_checkedComponentsWithBrokenScript, m_partiallyCheckedComponentsWithBrokenScript, m_uncheckedComponentsWithBrokenScript);
+ }
+
+ void testMissingDependency()
+ {
+ PackageManagerCore core;
+ QList<Component*> components = loadComponents(core);
+
+ core.settings().setAllowUnstableComponents(true);
+ ComponentModel *model = new ComponentModel(1, &core);
+
+ Component *invalidComponent = core.componentByName("componentmissingdependency");
+ invalidComponent->addDependency("missingcomponent");
+
+ Component *componentDependingOnMissingDependency = core.componentByName("componentd");
+ componentDependingOnMissingDependency->addDependency("componentmissingdependency");
+
+ core.componentsToInstallNeedsRecalculation();
+ model->setRootComponents(components);
+
+ testModelState(model, m_checkedComponentsWithMissingDependency, m_partiallyCheckedComponentsWithBrokenScript, m_uncheckedComponentsWithMissingDependency);
+ }
+
+private:
+
+ QList<Component*> loadComponents(PackageManagerCore &core)
+ {
+ UpdatesInfo updatesInfo;
+ updatesInfo.setFileName(":///data/updates.xml");
+ const QList<UpdateInfo> updateInfos = updatesInfo.updatesInfo();
+
+ QList <Component*> components;
+ UpdateInfo info;
+ for (int i = 0; i < updateInfos.count(); i++) {
+ info = updateInfos.at(i);
+ Component *component = new Component(&core);
+
+ // we need at least these to be able to test the model
+ component->setValue("Name", info.data.value("Name").toString());
+ 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("Dependencies", info.data.value("Dependencies").toString());
+ component->setCheckState(Qt::Checked);
+ QString forced = info.data.value("ForcedInstallation", scFalse).toString().toLower();
+ if (core.noForceInstallation())
+ forced = scFalse;
+ component->setValue("ForcedInstallation", forced);
+ if (forced == scTrue) {
+ component->setEnabled(false);
+ component->setCheckable(false);
+ }
+ //If name does not contain dot it is root component
+ qDebug()<<"component name "<<component->name();
+ if (!component->name().contains('.')) {
+ core.appendRootComponent(component);
+ } else { //Contains dot, is previous components child component
+ components.at(i-1)->appendComponent(component);
+ }
+ components.append(component);
+ }
+ return components;
+ }
+
+ void testModelState(ComponentModel *model, const QStringList &checked, const QStringList &partially,
+ const QStringList &unchecked) const
+ {
+ QCOMPARE(model->checked().count(), checked.count());
+ QCOMPARE(model->partially().count(), partially.count());
+ QCOMPARE(model->unchecked().count(), unchecked.count());
+
+ // these components should have checked state
+ foreach (Component *const component, model->checked())
+ QVERIFY(checked.contains(component->name()));
+
+ // these components should not have partially checked state
+ foreach (Component *const component, model->partially())
+ QVERIFY(partially.contains(component->name()));
+
+ // these components should not have checked state
+ foreach (Component *const component, model->unchecked())
+ QVERIFY(unchecked.contains(component->name()));
+ }
+
+private:
+ QStringList m_checkedComponentsWithBrokenScript;
+ QStringList m_uncheckedComponentsWithBrokenScript;
+ QStringList m_partiallyCheckedComponentsWithBrokenScript;
+
+ QStringList m_checkedComponentsWithMissingDependency;
+ QStringList m_uncheckedComponentsWithMissingDependency;
+ QStringList m_partiallyCheckedComponentsWithMissingDependency;
+};
+Q_DECLARE_OPERATORS_FOR_FLAGS(tst_BrokenInstaller::Options)
+
+QTEST_MAIN(tst_BrokenInstaller)
+
+#include "tst_brokeninstaller.moc"