winget-cli

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

WindowsFeature.cpp (8706B)


      1 // Copyright (c) Microsoft Corporation.
      2 // Licensed under the MIT License.
      3 #include "pch.h"
      4 #include "TestCommon.h"
      5 #include "WorkflowCommon.h"
      6 #include <AppInstallerRuntime.h>
      7 #include <Commands/InstallCommand.h>
      8 #include "TestHooks.h"
      9 
     10 using namespace AppInstaller::CLI;
     11 using namespace AppInstaller::Settings;
     12 using namespace AppInstaller::Utility;
     13 using namespace TestCommon;
     14 
     15 TEST_CASE("InstallFlow_WindowsFeatureDoesNotExist", "[windowsFeature]")
     16 {
     17     if (!AppInstaller::Runtime::IsRunningAsAdmin())
     18     {
     19         WARN("Test requires admin privilege. Skipped.");
     20         return;
     21     }
     22 
     23     TestCommon::TempFile installResultPath("TestExeInstalled.txt");
     24     TestCommon::TestUserSettings testSettings;
     25 
     26     std::ostringstream installOutput;
     27     TestContext context{ installOutput, std::cin };
     28     auto previousThreadGlobals = context.SetForCurrentThread();
     29     OverrideOpenDependencySource(context);
     30 
     31     context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile("InstallFlowTest_WindowsFeatures.yaml").GetPath().u8string());
     32 
     33     InstallCommand install({});
     34     install.Execute(context);
     35     INFO(installOutput.str());
     36 
     37     REQUIRE(context.GetTerminationHR() == APPINSTALLER_CLI_ERROR_INSTALL_DEPENDENCIES);
     38     REQUIRE(!std::filesystem::exists(installResultPath.GetPath()));
     39     REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::WindowsFeatureNotFound(LocIndView{ "testFeature1" })).get()) != std::string::npos);
     40 
     41     // "badFeature" should not be displayed as the flow should terminate after failing to find the first feature.
     42     REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::WindowsFeatureNotFound(LocIndView{ "testFeature2" })).get()) == std::string::npos);
     43     REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::FailedToEnableWindowsFeatureOverrideRequired).get()) != std::string::npos);
     44 }
     45 
     46 TEST_CASE("InstallFlow_FailedToEnableWindowsFeature", "[windowsFeature]")
     47 {
     48     if (!AppInstaller::Runtime::IsRunningAsAdmin())
     49     {
     50         WARN("Test requires admin privilege. Skipped.");
     51         return;
     52     }
     53 
     54     TestCommon::TempFile installResultPath("TestExeInstalled.txt");
     55     TestCommon::TestUserSettings testSettings;
     56 
     57     std::ostringstream installOutput;
     58     TestContext context{ installOutput, std::cin };
     59     auto previousThreadGlobals = context.SetForCurrentThread();
     60     OverrideOpenDependencySource(context);
     61 
     62     context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile("InstallFlowTest_WindowsFeatures.yaml").GetPath().u8string());
     63 
     64     auto setDoesFeatureExistOverride = TestHook::SetDoesWindowsFeatureExistResult_Override(ERROR_SUCCESS);
     65     auto setEnableFeatureOverride = TestHook::SetEnableWindowsFeatureResult_Override(0xc0040001); // DISMAPI_E_DISMAPI_NOT_INITIALIZED
     66 
     67     InstallCommand install({});
     68     install.Execute(context);
     69     INFO(installOutput.str());
     70 
     71     REQUIRE(context.GetTerminationHR() == APPINSTALLER_CLI_ERROR_INSTALL_DEPENDENCIES);
     72     REQUIRE(!std::filesystem::exists(installResultPath.GetPath()));
     73     REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::FailedToEnableWindowsFeatureOverrideRequired).get()) != std::string::npos);
     74 }
     75 
     76 TEST_CASE("InstallFlow_FailedToEnableWindowsFeature_Force", "[windowsFeature]")
     77 {
     78     if (!AppInstaller::Runtime::IsRunningAsAdmin())
     79     {
     80         WARN("Test requires admin privilege. Skipped.");
     81         return;
     82     }
     83 
     84     TestCommon::TempFile installResultPath("TestExeInstalled.txt");
     85     TestCommon::TestUserSettings testSettings;
     86 
     87     auto doesFeatureExistOverride = TestHook::SetDoesWindowsFeatureExistResult_Override(ERROR_SUCCESS);
     88     auto expectedErrorCode = 0xc0040001; // DISMAPI_E_DISMAPI_NOT_INITIALIZED
     89     auto setEnableFeatureOverride = TestHook::SetEnableWindowsFeatureResult_Override(expectedErrorCode);
     90 
     91     std::ostringstream installOutput;
     92     TestContext context{ installOutput, std::cin };
     93     auto previousThreadGlobals = context.SetForCurrentThread();
     94     OverrideForShellExecute(context);
     95     OverrideOpenDependencySource(context);
     96 
     97     context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile("InstallFlowTest_WindowsFeatures.yaml").GetPath().u8string());
     98     context.Args.AddArg(Execution::Args::Type::Force);
     99 
    100     InstallCommand install({});
    101     install.Execute(context);
    102     INFO(installOutput.str());
    103 
    104     // Verify Installer is called and parameters are passed in.
    105     REQUIRE(context.GetTerminationHR() == ERROR_SUCCESS);
    106     REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::FailedToEnableWindowsFeature(LocIndView{ "testFeature1" }, expectedErrorCode)).get()) != std::string::npos);
    107     REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::FailedToEnableWindowsFeature(LocIndView{ "testFeature2" }, expectedErrorCode)).get()) != std::string::npos);
    108     REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::FailedToEnableWindowsFeatureOverridden).get()) != std::string::npos);
    109     REQUIRE(std::filesystem::exists(installResultPath.GetPath()));
    110     std::ifstream installResultFile(installResultPath.GetPath());
    111     REQUIRE(installResultFile.is_open());
    112     std::string installResultStr;
    113     std::getline(installResultFile, installResultStr);
    114     REQUIRE(installResultStr.find("/custom") != std::string::npos);
    115     REQUIRE(installResultStr.find("/silentwithprogress") != std::string::npos);
    116 }
    117 
    118 TEST_CASE("InstallFlow_RebootRequired", "[windowsFeature]")
    119 {
    120     if (!AppInstaller::Runtime::IsRunningAsAdmin())
    121     {
    122         WARN("Test requires admin privilege. Skipped.");
    123         return;
    124     }
    125 
    126     TestCommon::TempFile installResultPath("TestExeInstalled.txt");
    127     TestCommon::TestUserSettings testSettings;
    128 
    129     // Override with reboot required HRESULT.
    130     auto doesFeatureExistOverride = TestHook::SetDoesWindowsFeatureExistResult_Override(ERROR_SUCCESS);
    131     auto setEnableFeatureOverride = TestHook::SetEnableWindowsFeatureResult_Override(ERROR_SUCCESS_REBOOT_REQUIRED);
    132 
    133     std::ostringstream installOutput;
    134     TestContext context{ installOutput, std::cin };
    135     auto previousThreadGlobals = context.SetForCurrentThread();
    136     OverrideOpenDependencySource(context);
    137 
    138     context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile("InstallFlowTest_WindowsFeatures.yaml").GetPath().u8string());
    139 
    140     InstallCommand install({});
    141     install.Execute(context);
    142     INFO(installOutput.str());
    143 
    144     REQUIRE(context.GetTerminationHR() == APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_FOR_INSTALL);
    145     REQUIRE(!std::filesystem::exists(installResultPath.GetPath()));
    146     REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::RebootRequiredToEnableWindowsFeatureOverrideRequired).get()) != std::string::npos);
    147 }
    148 
    149 TEST_CASE("InstallFlow_RebootRequired_Force", "[windowsFeature]")
    150 {
    151     if (!AppInstaller::Runtime::IsRunningAsAdmin())
    152     {
    153         WARN("Test requires admin privilege. Skipped.");
    154         return;
    155     }
    156 
    157     TestCommon::TempFile installResultPath("TestExeInstalled.txt");
    158     TestCommon::TestUserSettings testSettings;
    159 
    160     // Override with reboot required HRESULT.
    161     auto doesFeatureExistOverride = TestHook::SetDoesWindowsFeatureExistResult_Override(ERROR_SUCCESS);
    162     auto setEnableFeatureOverride = TestHook::SetEnableWindowsFeatureResult_Override(ERROR_SUCCESS_REBOOT_REQUIRED);
    163 
    164     std::ostringstream installOutput;
    165     TestContext context{ installOutput, std::cin };
    166     auto previousThreadGlobals = context.SetForCurrentThread();
    167     OverrideForShellExecute(context);
    168     OverrideOpenDependencySource(context);
    169 
    170     context.Args.AddArg(Execution::Args::Type::Manifest, TestDataFile("InstallFlowTest_WindowsFeatures.yaml").GetPath().u8string());
    171     context.Args.AddArg(Execution::Args::Type::Force);
    172 
    173     InstallCommand install({});
    174     install.Execute(context);
    175     INFO(installOutput.str());
    176 
    177     // Verify Installer is called and parameters are passed in.
    178     REQUIRE(context.GetTerminationHR() == ERROR_SUCCESS);
    179     REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::RebootRequiredToEnableWindowsFeatureOverridden).get()) != std::string::npos);
    180     REQUIRE(std::filesystem::exists(installResultPath.GetPath()));
    181     std::ifstream installResultFile(installResultPath.GetPath());
    182     REQUIRE(installResultFile.is_open());
    183     std::string installResultStr;
    184     std::getline(installResultFile, installResultStr);
    185     REQUIRE(installResultStr.find("/custom") != std::string::npos);
    186     REQUIRE(installResultStr.find("/silentwithprogress") != std::string::npos);
    187 }