From 2a14305b96c790ddb8a1eda46fe1d47a7e06be1b Mon Sep 17 00:00:00 2001 From: Flor Elisa Chacon Ochoa Date: Mon, 13 Dec 2021 15:36:26 -0800 Subject: [PATCH 1/3] Match installed type with manifest declared installer types --- .../Workflows/ManifestComparator.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/AppInstallerCLICore/Workflows/ManifestComparator.cpp b/src/AppInstallerCLICore/Workflows/ManifestComparator.cpp index 162edb9e47..89b5c5b6e4 100644 --- a/src/AppInstallerCLICore/Workflows/ManifestComparator.cpp +++ b/src/AppInstallerCLICore/Workflows/ManifestComparator.cpp @@ -194,11 +194,21 @@ namespace AppInstaller::CLI::Workflow InapplicabilityFlags IsApplicable(const Manifest::ManifestInstaller& installer) override { + // The installer is applicable if it's type or any of its ARP entries' type matches the installed type if (Manifest::IsInstallerTypeCompatible(installer.InstallerType, m_installedType)) { return InapplicabilityFlags::None; } + auto itr = std::find_if( + installer.AppsAndFeaturesEntries.begin(), + installer.AppsAndFeaturesEntries.end(), + [=](AppsAndFeaturesEntry arpEntry) { return Manifest::IsInstallerTypeCompatible(arpEntry.InstallerType, m_installedType); }); + if (itr != installer.AppsAndFeaturesEntries.end()) + { + return InapplicabilityFlags::None; + } + return InapplicabilityFlags::InstalledType; } From 5bca199e2fac960b2120c9dd76b589dd4d96ace0 Mon Sep 17 00:00:00 2001 From: Flor Elisa Chacon Ochoa Date: Mon, 13 Dec 2021 16:11:37 -0800 Subject: [PATCH 2/3] Add test --- .../AppInstallerCLITests.vcxproj | 3 ++ .../AppInstallerCLITests.vcxproj.filters | 3 ++ .../UpdateFlowTest_Exe_ARPInstallerType.yaml | 22 ++++++++++++ src/AppInstallerCLITests/WorkFlow.cpp | 36 +++++++++++++++++++ 4 files changed, 64 insertions(+) create mode 100644 src/AppInstallerCLITests/TestData/UpdateFlowTest_Exe_ARPInstallerType.yaml diff --git a/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj b/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj index c8a48d7f07..2e83454d04 100644 --- a/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj +++ b/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj @@ -515,6 +515,9 @@ true + + true + true diff --git a/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj.filters b/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj.filters index 033bf540d6..0ca28abd99 100644 --- a/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj.filters +++ b/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj.filters @@ -435,6 +435,9 @@ TestData + + TestData + TestData diff --git a/src/AppInstallerCLITests/TestData/UpdateFlowTest_Exe_ARPInstallerType.yaml b/src/AppInstallerCLITests/TestData/UpdateFlowTest_Exe_ARPInstallerType.yaml new file mode 100644 index 0000000000..4fd4f71e5e --- /dev/null +++ b/src/AppInstallerCLITests/TestData/UpdateFlowTest_Exe_ARPInstallerType.yaml @@ -0,0 +1,22 @@ +# Similar content to UpdateFlowTest_Exe.yaml, but with an AppsAndFeaturesEntry specifying installer type +PackageIdentifier: AppInstallerCliTest.TestExeInstaller +PackageVersion: 2.0.0.0 +PackageLocale: en-US +PackageName: AppInstaller Test Installer +Publisher: Microsoft Corporation +Moniker: AICLITestExe +License: Test +AppsAndFeaturesEntries: + - InstallerType: msix +InstallerSwitches: + Custom: /custom /ver2.0.0.0 + SilentWithProgress: /silentwithprogress + Silent: /silence + Update: /update +Installers: + - Architecture: x86 + InstallerUrl: https://ThisIsNotUsed + InstallerType: exe + InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B +ManifestType: singleton +ManifestVersion: 1.1.0 diff --git a/src/AppInstallerCLITests/WorkFlow.cpp b/src/AppInstallerCLITests/WorkFlow.cpp index 5de3d30afa..8edc977151 100644 --- a/src/AppInstallerCLITests/WorkFlow.cpp +++ b/src/AppInstallerCLITests/WorkFlow.cpp @@ -210,6 +210,21 @@ namespace PackageMatchFilter(PackageMatchField::Id, MatchType::Exact, "AppInstallerCliTest.TestExeInstaller"))); } + if (input == "TestExeInstallerWithDifferentInstalledType") + { + auto manifest = YamlParser::CreateFromPath(TestDataFile("InstallFlowTest_Exe.yaml")); + auto manifest2 = YamlParser::CreateFromPath(TestDataFile("UpdateFlowTest_Exe_ARPInstallerType.yaml")); + result.Matches.emplace_back( + ResultMatch( + TestPackage::Make( + manifest, + TestPackage::MetadataMap{ { PackageVersionMetadata::InstalledType, "Msix" } }, + std::vector{ manifest2, manifest }, + shared_from_this() + ), + PackageMatchFilter(PackageMatchField::Id, MatchType::Exact, "AppInstallerCliTest.TestExeInstaller"))); + } + if (input == "TestExeInstallerWithNothingInstalled") { auto manifest = YamlParser::CreateFromPath(TestDataFile("InstallFlowTest_Exe.yaml")); @@ -1495,6 +1510,27 @@ TEST_CASE("UpdateFlow_UpdateExeInstallerTypeNotApplicableSpecificVersion", "[Upd REQUIRE(context.GetTerminationHR() == APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE); } +TEST_CASE("UpdateFlow_UpdateExeWithDifferentInstalledType", "[UpdateFlow][workflow]") +{ + // Tests installer applicability when installed type is different but listed in the manifest + TestCommon::TempFile updateResultPath("TestExeInstalled.txt"); + + std::ostringstream updateOutput; + TestContext context{ updateOutput, std::cin }; + auto previousThreadGlobals = context.SetForCurrentThread(); + OverrideForCompositeInstalledSource(context); + OverrideForShellExecute(context); + context.Args.AddArg(Execution::Args::Type::Query, "TestExeInstallerWithDifferentInstalledType"sv); + + UpgradeCommand update({}); + update.Execute(context); + INFO(updateOutput.str()); + + // Verify Installer is called. + REQUIRE(context.GetTerminationHR() == S_OK); + REQUIRE(std::filesystem::exists(updateResultPath.GetPath())); +} + TEST_CASE("UpdateFlow_UpdateExeSpecificVersionNotFound", "[UpdateFlow][workflow]") { TestCommon::TempFile updateResultPath("TestExeInstalled.txt"); From fa1290c346161ae876771367087e6d311d6ca4b7 Mon Sep 17 00:00:00 2001 From: Flor Elisa Chacon Ochoa Date: Mon, 13 Dec 2021 17:35:45 -0800 Subject: [PATCH 3/3] Extend inapplicable reason string --- .../Workflows/ManifestComparator.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/AppInstallerCLICore/Workflows/ManifestComparator.cpp b/src/AppInstallerCLICore/Workflows/ManifestComparator.cpp index 89b5c5b6e4..0a475b088d 100644 --- a/src/AppInstallerCLICore/Workflows/ManifestComparator.cpp +++ b/src/AppInstallerCLICore/Workflows/ManifestComparator.cpp @@ -214,8 +214,20 @@ namespace AppInstaller::CLI::Workflow std::string ExplainInapplicable(const Manifest::ManifestInstaller& installer) override { - std::string result = "Installed package type is not compatible with "; - result += Manifest::InstallerTypeToString(installer.InstallerType); + std::string result = "Installed package type '" + std::string{ Manifest::InstallerTypeToString(m_installedType) } + + "' is not compatible with installer type " + std::string{ Manifest::InstallerTypeToString(installer.InstallerType) }; + + std::string arpInstallerTypes; + for (const auto& entry : installer.AppsAndFeaturesEntries) + { + arpInstallerTypes += " " + std::string{ Manifest::InstallerTypeToString(entry.InstallerType) }; + } + + if (!arpInstallerTypes.empty()) + { + result += ", or with accepted type(s)" + arpInstallerTypes; + } + return result; }