From 283a12e8402fe7480882c1d49d574f3933561ca8 Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Mon, 5 Dec 2022 22:57:06 -0800 Subject: [PATCH 1/3] fix include unknown bug --- .../Commands/UpgradeCommand.cpp | 3 +- .../AppInstallerCLITests.vcxproj | 3 + .../AppInstallerCLITests.vcxproj.filters | 3 + .../InstallFlowTest_UnknownVersion.yaml | 29 ++++ src/AppInstallerCLITests/WorkFlow.cpp | 144 +++++++++++++++++- 5 files changed, 178 insertions(+), 4 deletions(-) create mode 100644 src/AppInstallerCLITests/TestData/InstallFlowTest_UnknownVersion.yaml diff --git a/src/AppInstallerCLICore/Commands/UpgradeCommand.cpp b/src/AppInstallerCLICore/Commands/UpgradeCommand.cpp index 7162c98b89..0a804bdf30 100644 --- a/src/AppInstallerCLICore/Commands/UpgradeCommand.cpp +++ b/src/AppInstallerCLICore/Commands/UpgradeCommand.cpp @@ -45,8 +45,7 @@ namespace AppInstaller::CLI // either for upgrading or for listing available upgrades. bool HasArgumentsForMultiplePackages(Execution::Args& execArgs) { - return execArgs.Contains(Args::Type::All) || - execArgs.Contains(Args::Type::IncludeUnknown); + return execArgs.Contains(Args::Type::All); } // Determines whether there are any arguments only used as options during an upgrade, diff --git a/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj b/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj index 490582234b..300c14991a 100644 --- a/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj +++ b/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj @@ -303,6 +303,9 @@ true + + true + true diff --git a/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj.filters b/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj.filters index c63d10d997..2eb85c90d6 100644 --- a/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj.filters +++ b/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj.filters @@ -552,6 +552,9 @@ TestData + + TestData + TestData diff --git a/src/AppInstallerCLITests/TestData/InstallFlowTest_UnknownVersion.yaml b/src/AppInstallerCLITests/TestData/InstallFlowTest_UnknownVersion.yaml new file mode 100644 index 0000000000..e3d023b6c6 --- /dev/null +++ b/src/AppInstallerCLITests/TestData/InstallFlowTest_UnknownVersion.yaml @@ -0,0 +1,29 @@ +Id: AppInstallerCliTest.TestExeUnknownVersion +Version: 1.0.0.0 +Name: AppInstaller Test Exe Unknown Version +Publisher: Microsoft Corporation +AppMoniker: AICLITestExe +License: Test +ProductCode: AppInstallerCliTest.TestExeUnknownVersion +Installers: + - Arch: x64 + Url: https://ThisIsNotUsed + InstallerType: exe + Sha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B + Scope: user + Switches: + Custom: /custom /scope=user + SilentWithProgress: /silentwithprogress + Silent: /silence + Update: /update + - Arch: x64 + Url: https://ThisIsNotUsed + InstallerType: exe + Sha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B + Scope: machine + Switches: + Custom: /custom /scope=machine + SilentWithProgress: /silentwithprogress + Silent: /silence + Update: /update +ManifestVersion: 0.1.0 diff --git a/src/AppInstallerCLITests/WorkFlow.cpp b/src/AppInstallerCLITests/WorkFlow.cpp index b8638ad5bc..6c1bf02fa2 100644 --- a/src/AppInstallerCLITests/WorkFlow.cpp +++ b/src/AppInstallerCLITests/WorkFlow.cpp @@ -258,6 +258,23 @@ namespace PackageMatchFilter(PackageMatchField::Id, MatchType::Exact, "AppInstallerCliTest.TestMSStoreInstaller"))); } + if (input.empty() || input == "TestExeInstallerWithUnknownVersion") + { + auto installed = YamlParser::CreateFromPath(TestDataFile("InstallFlowTest_UnknownVersion.yaml")); + auto available = installed; + // Override the installed version to be unknown. + installed.Version = "unknown"; + result.Matches.emplace_back( + ResultMatch( + TestPackage::Make( + installed, + TestPackage::MetadataMap{ { PackageVersionMetadata::InstalledType, "Exe" } }, + std::vector{ available }, + shared_from_this() + ), + PackageMatchFilter(PackageMatchField::Id, MatchType::Exact, "AppInstallerCliTest.TestExeUnknownVersion"))); + } + if (input == "TestExeInstallerWithLatestInstalled") { auto manifest = YamlParser::CreateFromPath(TestDataFile("InstallFlowTest_Exe.yaml")); @@ -2191,6 +2208,84 @@ TEST_CASE("UpdateFlow_UpdateExeWithUnsupportedArgs", "[UpdateFlow][workflow]") REQUIRE(updateOutput.str().find("-l,--location") != std::string::npos); } +TEST_CASE("UpdateFlow_UnknownVersion", "[UpdateFlow][workflow]") +{ + TestCommon::TempFile updateResultPath("TestExeInstalled.txt"); + TestCommon::TempDirectory tempDirectory("TempDirectory", false); + + std::ostringstream updateOutput; + TestContext context{ updateOutput, std::cin }; + auto previousThreadGlobals = context.SetForCurrentThread(); + OverrideForCompositeInstalledSource(context); + context.Args.AddArg(Execution::Args::Type::Query, "TestExeInstallerWithUnknownVersion"sv); + context.Args.AddArg(Execution::Args::Type::InstallLocation, tempDirectory); + + UpgradeCommand update({}); + context.SetExecutingCommand(&update); + update.Execute(context); + INFO(updateOutput.str()); + + // Verify help message is shown the user to use --include-unknown + REQUIRE(context.GetTerminationHR() == APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE); + REQUIRE(!std::filesystem::exists(updateResultPath.GetPath())); + REQUIRE(updateOutput.str().find(Resource::LocString(Resource::String::UpgradeUnknownVersionExplanation).get()) != std::string::npos); +} + +TEST_CASE("UpdateFlow_UnknownVersion_IncludeUnknownArg", "[UpdateFlow][workflow]") +{ + TestCommon::TempFile updateResultPath("TestExeInstalled.txt"); + TestCommon::TempDirectory tempDirectory("TempDirectory", false); + + std::ostringstream updateOutput; + TestContext context{ updateOutput, std::cin }; + auto previousThreadGlobals = context.SetForCurrentThread(); + OverrideForCompositeInstalledSource(context); + OverrideForShellExecute(context); + context.Args.AddArg(Execution::Args::Type::Query, "TestExeInstallerWithUnknownVersion"sv); + context.Args.AddArg(Execution::Args::Type::InstallLocation, tempDirectory); + context.Args.AddArg(Execution::Args::Type::IncludeUnknown); + + UpgradeCommand update({}); + context.SetExecutingCommand(&update); + update.Execute(context); + INFO(updateOutput.str()); + REQUIRE(std::filesystem::exists(updateResultPath.GetPath())); +} + +TEST_CASE("UpdateFlow_NoArgs_UnknownVersion", "[UpdateFlow][workflow]") +{ + std::ostringstream updateOutput; + TestContext context{ updateOutput, std::cin }; + auto previousThreadGlobals = context.SetForCurrentThread(); + OverrideForCompositeInstalledSource(context); + + UpgradeCommand update({}); + context.SetExecutingCommand(&update); + update.Execute(context); + INFO(updateOutput.str()); + + // Verify --include-unknown help text is displayed if update is executed with no args and an unknown version package is available for upgrade. + REQUIRE(updateOutput.str().find(Resource::LocString(Resource::String::UpgradeUnknownVersionCount).get()) != std::string::npos); +} + +TEST_CASE("UpdateFlow_IncludeUnknown", "[UpdateFlow][workflow]") +{ + std::ostringstream updateOutput; + TestContext context{ updateOutput, std::cin }; + auto previousThreadGlobals = context.SetForCurrentThread(); + OverrideForCompositeInstalledSource(context); + context.Args.AddArg(Execution::Args::Type::IncludeUnknown); + + UpgradeCommand update({}); + context.SetExecutingCommand(&update); + update.Execute(context); + INFO(updateOutput.str()); + + // Verify unknown version package is displayed available for upgrade. + REQUIRE(updateOutput.str().find(Resource::LocString(Resource::String::UpgradeUnknownVersionCount).get()) == std::string::npos); + REQUIRE(updateOutput.str().find("unknown") != std::string::npos); +} + TEST_CASE("UpdateFlow_UpdatePortableWithManifest", "[UpdateFlow][workflow]") { TestCommon::TempFile updateResultPath("TestPortableInstalled.txt"); @@ -2396,6 +2491,43 @@ TEST_CASE("UpdateFlow_UpdateAllApplicable", "[UpdateFlow][workflow]") update.Execute(context); INFO(updateOutput.str()); + // Verify that --include-unknown help message is displayed. + REQUIRE(updateOutput.str().find(Resource::LocString(Resource::String::UpgradeUnknownVersionCount).get()) != std::string::npos); + REQUIRE(updateOutput.str().find("AppInstallerCliTest.TestExeUnknownVersion") == std::string::npos); + + // Verify installers are called. + REQUIRE(std::filesystem::exists(updateExeResultPath.GetPath())); + REQUIRE(std::filesystem::exists(updateMsixResultPath.GetPath())); + REQUIRE(std::filesystem::exists(updateMSStoreResultPath.GetPath())); + REQUIRE(std::filesystem::exists(updatePortableResultPath.GetPath())); +} + +TEST_CASE("UpdateFlow_UpdateAll_IncludeUnknown", "[UpdateFlow][workflow]") +{ + TestCommon::TempFile updateExeResultPath("TestExeInstalled.txt"); + TestCommon::TempFile updateMsixResultPath("TestMsixInstalled.txt"); + TestCommon::TempFile updateMSStoreResultPath("TestMSStoreUpdated.txt"); + TestCommon::TempFile updatePortableResultPath("TestPortableInstalled.txt"); + + std::ostringstream updateOutput; + TestContext context{ updateOutput, std::cin }; + auto previousThreadGlobals = context.SetForCurrentThread(); + OverrideForCompositeInstalledSource(context); + OverrideForShellExecute(context); + OverrideForMSIX(context); + OverrideForMSStore(context, true); + OverrideForPortableInstall(context); + context.Args.AddArg(Execution::Args::Type::All); + context.Args.AddArg(Execution::Args::Type::IncludeUnknown); + + UpgradeCommand update({}); + update.Execute(context); + INFO(updateOutput.str()); + + // Verify that --include-unknown help message is NOT displayed and unknown version package is upgraded. + REQUIRE(updateOutput.str().find(Resource::LocString(Resource::String::UpgradeUnknownVersionCount).get()) == std::string::npos); + REQUIRE(updateOutput.str().find("AppInstallerCliTest.TestExeUnknownVersion") != std::string::npos); + // Verify installers are called. REQUIRE(std::filesystem::exists(updateExeResultPath.GetPath())); REQUIRE(std::filesystem::exists(updateMsixResultPath.GetPath())); @@ -2767,7 +2899,7 @@ TEST_CASE("ExportFlow_ExportAll", "[ExportFlow][workflow]") REQUIRE(exportedCollection.Sources[0].Details.Identifier == "*TestSource"); const auto& exportedPackages = exportedCollection.Sources[0].Packages; - REQUIRE(exportedPackages.size() == 5); + REQUIRE(exportedPackages.size() == 6); REQUIRE(exportedPackages.end() != std::find_if(exportedPackages.begin(), exportedPackages.end(), [](const auto& p) { return p.Id == "AppInstallerCliTest.TestExeInstaller" && p.VersionAndChannel.GetVersion().ToString().empty(); @@ -2788,6 +2920,10 @@ TEST_CASE("ExportFlow_ExportAll", "[ExportFlow][workflow]") { return p.Id == "AppInstallerCliTest.TestZipInstaller" && p.VersionAndChannel.GetVersion().ToString().empty(); })); + REQUIRE(exportedPackages.end() != std::find_if(exportedPackages.begin(), exportedPackages.end(), [](const auto& p) + { + return p.Id == "AppInstallerCliTest.TestExeUnknownVersion" && p.VersionAndChannel.GetVersion().ToString().empty(); + })); } TEST_CASE("ExportFlow_ExportAll_WithVersions", "[ExportFlow][workflow]") @@ -2811,7 +2947,7 @@ TEST_CASE("ExportFlow_ExportAll_WithVersions", "[ExportFlow][workflow]") REQUIRE(exportedCollection.Sources[0].Details.Identifier == "*TestSource"); const auto& exportedPackages = exportedCollection.Sources[0].Packages; - REQUIRE(exportedPackages.size() == 5); + REQUIRE(exportedPackages.size() == 6); REQUIRE(exportedPackages.end() != std::find_if(exportedPackages.begin(), exportedPackages.end(), [](const auto& p) { return p.Id == "AppInstallerCliTest.TestExeInstaller" && p.VersionAndChannel.GetVersion().ToString() == "1.0.0.0"; @@ -2832,6 +2968,10 @@ TEST_CASE("ExportFlow_ExportAll_WithVersions", "[ExportFlow][workflow]") { return p.Id == "AppInstallerCliTest.TestZipInstaller" && p.VersionAndChannel.GetVersion().ToString() == "1.0.0.0"; })); + REQUIRE(exportedPackages.end() != std::find_if(exportedPackages.begin(), exportedPackages.end(), [](const auto& p) + { + return p.Id == "AppInstallerCliTest.TestExeUnknownVersion" && p.VersionAndChannel.GetVersion().ToString() == "unknown"; + })); } TEST_CASE("ImportFlow_Successful", "[ImportFlow][workflow]") From 40af546ee21d061f48117c11d6721eece8123fb7 Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Mon, 5 Dec 2022 23:06:04 -0800 Subject: [PATCH 2/3] use 1.3 for test manifest --- .../InstallFlowTest_UnknownVersion.yaml | 38 +++++++------------ 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/src/AppInstallerCLITests/TestData/InstallFlowTest_UnknownVersion.yaml b/src/AppInstallerCLITests/TestData/InstallFlowTest_UnknownVersion.yaml index e3d023b6c6..89dc4523ca 100644 --- a/src/AppInstallerCLITests/TestData/InstallFlowTest_UnknownVersion.yaml +++ b/src/AppInstallerCLITests/TestData/InstallFlowTest_UnknownVersion.yaml @@ -1,29 +1,19 @@ -Id: AppInstallerCliTest.TestExeUnknownVersion -Version: 1.0.0.0 -Name: AppInstaller Test Exe Unknown Version +# Same content with InstallFlowTest_Exe.yaml but with higher version +PackageIdentifier: AppInstallerCliTest.TestExeUnknownVersion +PackageVersion: 1.0.0.0 +PackageLocale: en-US +PackageName: AppInstaller Test Exe Unknown Version Publisher: Microsoft Corporation AppMoniker: AICLITestExe License: Test -ProductCode: AppInstallerCliTest.TestExeUnknownVersion +Switches: + SilentWithProgress: /silentwithprogress + Silent: /silence + Update: /update Installers: - - Arch: x64 - Url: https://ThisIsNotUsed + - Architecture: x64 + InstallerUrl: https://ThisIsNotUsed InstallerType: exe - Sha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B - Scope: user - Switches: - Custom: /custom /scope=user - SilentWithProgress: /silentwithprogress - Silent: /silence - Update: /update - - Arch: x64 - Url: https://ThisIsNotUsed - InstallerType: exe - Sha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B - Scope: machine - Switches: - Custom: /custom /scope=machine - SilentWithProgress: /silentwithprogress - Silent: /silence - Update: /update -ManifestVersion: 0.1.0 + InstallerSha256: 65DB2F2AC2686C7F2FD69D4A4C6683B888DC55BFA20A0E32CA9F838B51689A3B +ManifestType: singleton +ManifestVersion: 1.3.0 \ No newline at end of file From ba1e9f5eefe39dfa0dd65238392857608ad16721 Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Mon, 5 Dec 2022 23:21:39 -0800 Subject: [PATCH 3/3] fix comment --- .../TestData/InstallFlowTest_UnknownVersion.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AppInstallerCLITests/TestData/InstallFlowTest_UnknownVersion.yaml b/src/AppInstallerCLITests/TestData/InstallFlowTest_UnknownVersion.yaml index 89dc4523ca..ffc46c0991 100644 --- a/src/AppInstallerCLITests/TestData/InstallFlowTest_UnknownVersion.yaml +++ b/src/AppInstallerCLITests/TestData/InstallFlowTest_UnknownVersion.yaml @@ -1,4 +1,4 @@ -# Same content with InstallFlowTest_Exe.yaml but with higher version +# Test manifest for upgrading a package with an unknown version. PackageIdentifier: AppInstallerCliTest.TestExeUnknownVersion PackageVersion: 1.0.0.0 PackageLocale: en-US