Add Enable-ExperimentalFeature and Disable-ExperimentalFeature cmdlets (#8318)

[breaking change]
Major changes are as follows:
- Add `Enable-ExperimentalFeature` and `Disable-ExperimentalFeature` cmdlets.
- Remove `-ListAvailable` from `Get-ExperimentalFeature`.
- Add `ArgumentCompleter` for `Get-ExperimentalFeature` cmdlet.
- Refactor some existing Experimental Feature tests.
- Make `ConfigScope` public and renamed `SystemWide` to `AllUsers`. Also update experimental feature code to prefer the current user config over the all user config.
This commit is contained in:
Steve Lee
2018-12-05 12:20:58 -08:00
committed by Dongbo Wang
parent 74de391193
commit 52aef57ab6
14 changed files with 552 additions and 276 deletions
+6 -6
View File
@@ -348,7 +348,7 @@ namespace PSTests.Sequential
public void PowerShellConfig_GetPowerShellPolicies_BothConfigFilesNotEmpty()
{
fixture.SetupConfigFile1();
var sysPolicies = PowerShellConfig.Instance.GetPowerShellPolicies(ConfigScope.SystemWide);
var sysPolicies = PowerShellConfig.Instance.GetPowerShellPolicies(ConfigScope.AllUsers);
var userPolicies = PowerShellConfig.Instance.GetPowerShellPolicies(ConfigScope.CurrentUser);
Assert.NotNull(sysPolicies);
@@ -362,7 +362,7 @@ namespace PSTests.Sequential
public void PowerShellConfig_GetPowerShellPolicies_EmptyUserConfig()
{
fixture.SetupConfigFile2();
var sysPolicies = PowerShellConfig.Instance.GetPowerShellPolicies(ConfigScope.SystemWide);
var sysPolicies = PowerShellConfig.Instance.GetPowerShellPolicies(ConfigScope.AllUsers);
var userPolicies = PowerShellConfig.Instance.GetPowerShellPolicies(ConfigScope.CurrentUser);
Assert.NotNull(sysPolicies);
@@ -375,7 +375,7 @@ namespace PSTests.Sequential
public void PowerShellConfig_GetPowerShellPolicies_EmptySystemConfig()
{
fixture.SetupConfigFile3();
var sysPolicies = PowerShellConfig.Instance.GetPowerShellPolicies(ConfigScope.SystemWide);
var sysPolicies = PowerShellConfig.Instance.GetPowerShellPolicies(ConfigScope.AllUsers);
var userPolicies = PowerShellConfig.Instance.GetPowerShellPolicies(ConfigScope.CurrentUser);
Assert.Null(sysPolicies);
@@ -388,7 +388,7 @@ namespace PSTests.Sequential
public void PowerShellConfig_GetPowerShellPolicies_BothConfigFilesEmpty()
{
fixture.SetupConfigFile4();
var sysPolicies = PowerShellConfig.Instance.GetPowerShellPolicies(ConfigScope.SystemWide);
var sysPolicies = PowerShellConfig.Instance.GetPowerShellPolicies(ConfigScope.AllUsers);
var userPolicies = PowerShellConfig.Instance.GetPowerShellPolicies(ConfigScope.CurrentUser);
Assert.Null(sysPolicies);
@@ -399,7 +399,7 @@ namespace PSTests.Sequential
public void PowerShellConfig_GetPowerShellPolicies_BothConfigFilesNotExist()
{
fixture.CleanupConfigFiles();
var sysPolicies = PowerShellConfig.Instance.GetPowerShellPolicies(ConfigScope.SystemWide);
var sysPolicies = PowerShellConfig.Instance.GetPowerShellPolicies(ConfigScope.AllUsers);
var userPolicies = PowerShellConfig.Instance.GetPowerShellPolicies(ConfigScope.CurrentUser);
Assert.Null(sysPolicies);
@@ -899,4 +899,4 @@ namespace PSTests.Sequential
fixture.CompareConsoleSessionConfiguration(consoleSessionConfiguration, null);
}
}
}
}
@@ -209,6 +209,7 @@ Describe "Verify approved aliases list" -Tags "CI" {
"Cmdlet", "Debug-Process", , $($FullCLR -or $CoreWindows -or $CoreUnix)
"Cmdlet", "Debug-Runspace", , $($FullCLR -or $CoreWindows -or $CoreUnix)
"Cmdlet", "Disable-ComputerRestore", , $($FullCLR )
"Cmdlet", "Disable-ExperimentalFeature", , $( $CoreWindows -or $CoreUnix)
"Cmdlet", "Disable-PSBreakpoint", , $($FullCLR -or $CoreWindows -or $CoreUnix)
"Cmdlet", "Disable-PSRemoting", , $($FullCLR -or $CoreWindows )
"Cmdlet", "Disable-PSSessionConfiguration", , $($FullCLR -or $CoreWindows )
@@ -217,6 +218,7 @@ Describe "Verify approved aliases list" -Tags "CI" {
"Cmdlet", "Disconnect-PSSession", , $($FullCLR -or $CoreWindows )
"Cmdlet", "Disconnect-WSMan", , $($FullCLR -or $CoreWindows )
"Cmdlet", "Enable-ComputerRestore", , $($FullCLR )
"Cmdlet", "Enable-ExperimentalFeature", , $( $CoreWindows -or $CoreUnix)
"Cmdlet", "Enable-PSBreakpoint", , $($FullCLR -or $CoreWindows -or $CoreUnix)
"Cmdlet", "Enable-PSRemoting", , $($FullCLR -or $CoreWindows )
"Cmdlet", "Enable-PSSessionConfiguration", , $($FullCLR -or $CoreWindows )
@@ -0,0 +1,87 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
Describe "Enable-ExperimentalFeature and Disable-ExperimentalFeature tests" -tags "Feature","RequireAdminOnWindows" {
BeforeAll {
$systemConfigPath = "$PSHOME/powershell.config.json"
if ($IsWindows) {
$userConfigPath = "~/Documents/powershell/powershell.config.json"
}
else {
$userConfigPath = "~/.config/powershell/powershell.config.json"
}
$systemConfigExists = $false
if (Test-Path $systemConfigPath) {
$systemConfigExists = $true
Move-Item $systemConfigPath "$systemConfigPath.backup" -Force -ErrorAction SilentlyContinue
}
$userConfigExists = $false
if (Test-Path $userConfigPath) {
$userConfigExists = $true
Move-Item $userConfigPath "$userConfigPath.backup" -Force -ErrorAction SilentlyContinue
}
$testModulePath = Join-Path -Path $PSScriptRoot -ChildPath "assets"
$originalModulePath = $env:PSModulePath
$env:PSModulePath = $testModulePath
}
AfterAll {
if ($systemConfigExists) {
Move-Item "$systemConfigPath.backup" $systemConfigPath -Force -ErrorAction SilentlyContinue
}
if ($userConfigExists) {
Move-Item "$userConfigPath.backup" $userConfigPath -Force -ErrorAction SilentlyContinue
}
$env:PSModulePath = $originalModulePath
}
AfterEach {
Remove-Item $systemConfigPath -Force -ErrorAction SilentlyContinue
Remove-Item $userConfigPath -Force -ErrorAction SilentlyContinue
}
It "Enable-ExperimentalFeature will enable Experimental Feature for scope: <scope>" -TestCases @(
@{ scope = "AllUsers" },
@{ scope = "CurrentUser" }
) {
param ($scope)
$feature = pwsh -noprofile -output xml -command Get-ExperimentalFeature ExpTest.FeatureOne
$feature.Enabled | Should -BeFalse -Because "All Experimental Features disabled when no config file"
$feature = pwsh -noprofile -output xml -command Enable-ExperimentalFeature ExpTest.FeatureOne -Scope $scope -WarningAction SilentlyContinue
$feature | Should -BeNullOrEmpty -Because "No object is output to pipeline on success"
$feature = pwsh -noprofile -output xml -command Get-ExperimentalFeature ExpTest.FeatureOne
$feature.Enabled | Should -BeTrue -Because "The experimental feature is now enabled"
}
It "Disable-ExperimentalFeature will disable Experimental Feature for scope: <scope>" -TestCases @(
@{ scope = "AllUsers" ; configPath = $systemConfigPath },
@{ scope = "CurrentUser"; configPath = $userConfigPath }
) {
param ($scope, $configPath)
'{"ExperimentalFeatures":["ExpTest.FeatureOne"]}' > $configPath
$feature = pwsh -noprofile -output xml -command Get-ExperimentalFeature ExpTest.FeatureOne
$feature.Enabled | Should -BeTrue -Because "Test config should enable ExpTest.FeatureOne"
$feature = pwsh -noprofile -output xml -command Disable-ExperimentalFeature ExpTest.FeatureOne -Scope $scope -WarningAction SilentlyContinue
$feature | Should -BeNullOrEmpty -Because "No object is output to pipeline on success"
$feature = pwsh -noprofile -output xml -command Get-ExperimentalFeature ExpTest.FeatureOne
$feature.Enabled | Should -BeFalse -Because "The experimental feature is now disabled"
}
It "<cmdlet> will output warning message" -TestCases @(
@{ cmdlet = "Enable-ExperimentalFeature" },
@{ cmdlet = "Disable-Experimentalfeature" }
) {
param ($cmdlet)
& $cmdlet ExpTest.FeatureOne -WarningVariable warning -WarningAction SilentlyContinue
$warning | Should -Not -BeNullOrEmpty -Because "A warning message is always given indicating restart is required"
}
}
@@ -1,117 +1,126 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
Describe "Get-ExperimentalFeature basic tests - Feature-Disabled" -tags "CI" {
Describe "Get-ExperimentalFeature Tests" -tags "Feature","RequireAdminOnWindows" {
BeforeAll {
$skipTest = $EnabledExperimentalFeatures.Contains('ExpTest.FeatureOne')
if ($skipTest) {
Write-Verbose "Test Suite Skipped. The test suite requires the experimental feature 'ExpTest.FeatureOne' to be disabled." -Verbose
$originalDefaultParameterValues = $PSDefaultParameterValues.Clone()
$PSDefaultParameterValues["it:skip"] = $true
} else {
Remove-Module -Name ExpTest -Force -ErrorAction SilentlyContinue
$testModulePath = Join-Path -Path $PSScriptRoot -ChildPath "assets"
$testModuleManifestPath = Join-Path -Path $testModulePath "ExpTest" "ExpTest.psd1"
$originalModulePath = $env:PSModulePath
$env:PSModulePath = $testModulePath
$systemConfigPath = "$PSHOME/powershell.config.json"
if ($IsWindows) {
$userConfigPath = "~/Documents/powershell/powershell.config.json"
}
else {
$userConfigPath = "~/.config/powershell/powershell.config.json"
}
$systemConfigExists = $false
if (Test-Path $systemConfigPath) {
$systemConfigExists = $true
Move-Item $systemConfigPath "$systemConfigPath.backup" -Force -ErrorAction SilentlyContinue
}
$userConfigExists = $false
if (Test-Path $userConfigPath) {
$userConfigExists = $true
Move-Item $userConfigPath "$userConfigPath.backup" -Force -ErrorAction SilentlyContinue
}
$testModulePath = Join-Path -Path $PSScriptRoot -ChildPath "assets"
$testModuleManifestPath = Join-Path -Path $testModulePath "ExpTest" "ExpTest.psd1"
$originalModulePath = $env:PSModulePath
$env:PSModulePath = $testModulePath
}
AfterAll {
if ($skipTest) {
$global:PSDefaultParameterValues = $originalDefaultParameterValues
} else {
$env:PSModulePath = $originalModulePath
if ($systemConfigExists) {
Move-Item "$systemConfigPath.backup" $systemConfigPath -Force -ErrorAction SilentlyContinue
}
if ($userConfigExists) {
Move-Item "$userConfigPath.backup" $userConfigPath -Force -ErrorAction SilentlyContinue
}
$env:PSModulePath = $originalModulePath
}
AfterEach {
Remove-Item $systemConfigPath -Force -ErrorAction SilentlyContinue
Remove-Item $userConfigPath -Force -ErrorAction SilentlyContinue
}
Context "Feature disabled tests" {
It "'Get-ExperimentalFeature' should return all available features from module path" {
$features = pwsh -noprofile -output xml -command Get-ExperimentalFeature "ExpTest*"
$features | Should -Not -BeNullOrEmpty
$features[0].Name | Should -BeExactly "ExpTest.FeatureOne"
$features[0].Enabled | Should -BeFalse
$features[0].Source | Should -BeExactly $testModuleManifestPath
$features[1].Name | Should -BeExactly "ExpTest.FeatureTwo"
$features[1].Enabled | Should -BeFalse
$features[1].Source | Should -BeExactly $testModuleManifestPath
}
It "'Get-ExperimentalFeature' pipeline input" {
$features = pwsh -noprofile -output xml -command { "ExpTest.FeatureOne", "ExpTest.FeatureTwo" | Get-ExperimentalFeature }
$features | Should -Not -BeNullOrEmpty
$features[0].Name | Should -BeExactly "ExpTest.FeatureOne"
$features[0].Enabled | Should -BeFalse
$features[0].Source | Should -BeExactly $testModuleManifestPath
$features[1].Name | Should -BeExactly "ExpTest.FeatureTwo"
$features[1].Enabled | Should -BeFalse
$features[1].Source | Should -BeExactly $testModuleManifestPath
}
}
It "'Get-ExperimentalFeature' should only return enabled features" {
$EnabledExperimentalFeatures.Count | Should -Be 0
Get-ExperimentalFeature | Should -BeNullOrEmpty
Context "Feature enabled tests" {
BeforeEach {
'{"ExperimentalFeatures":["ExpTest.FeatureOne"]}' > $userConfigPath
}
It "'Get-ExperimentalFeature' should return enabled features 'ExpTest.FeatureOne'" {
pwsh -noprofile -command '$EnabledExperimentalFeatures.Count' | Should -Be 1
$feature = pwsh -noprofile -output xml -command Get-ExperimentalFeature "ExpTest.FeatureOne"
$feature | Should -Not -BeNullOrEmpty
$feature.Enabled | Should -BeTrue
$feature.Source | Should -BeExactly $testModuleManifestPath
}
It "'Get-ExperimentalFeature' should return all available features from module path" {
$features = pwsh -noprofile -output xml -command Get-ExperimentalFeature "ExpTest*"
$features | Should -Not -BeNullOrEmpty
$features[0].Name | Should -BeExactly "ExpTest.FeatureOne"
$features[0].Enabled | Should -BeTrue
$features[0].Source | Should -BeExactly $testModuleManifestPath
$features[1].Name | Should -BeExactly "ExpTest.FeatureTwo"
$features[1].Enabled | Should -BeFalse
$features[1].Source | Should -BeExactly $testModuleManifestPath
}
It "'Get-ExperimentalFeature' pipeline input" {
$features = pwsh -noprofile -output xml -command { "ExpTest.FeatureOne", "ExpTest.FeatureTwo" | Get-ExperimentalFeature }
$features | Should -Not -BeNullOrEmpty
$features[0].Name | Should -BeExactly "ExpTest.FeatureOne"
$features[0].Enabled | Should -BeTrue
$features[0].Source | Should -BeExactly $testModuleManifestPath
$features[1].Name | Should -BeExactly "ExpTest.FeatureTwo"
$features[1].Enabled | Should -BeFalse
$features[1].Source | Should -BeExactly $testModuleManifestPath
}
}
It "'Get-ExperimentalFeature -ListAvailable' should return all available features from module path" {
$features = Get-ExperimentalFeature "ExpTest*" -ListAvailable
$features | Should -Not -BeNullOrEmpty
$features[0].Name | Should -BeExactly "ExpTest.FeatureOne"
$features[0].Enabled | Should -Be $false
$features[0].Source | Should -BeExactly $testModuleManifestPath
Context "User config takes precedence over system config" {
It "Feature is enabled in user config only" {
'{"ExperimentalFeatures":["ExpTest.FeatureOne"]}' > $userConfigPath
'{"ExperimentalFeatures":["ExpTest.FeatureTwo"]}' > $systemConfigPath
$features[1].Name | Should -BeExactly "ExpTest.FeatureTwo"
$features[1].Enabled | Should -Be $false
$features[1].Source | Should -BeExactly $testModuleManifestPath
}
It "'Get-ExperimentalFeature -ListAvailable' pipeline input" {
$features = "ExpTest.FeatureOne", "ExpTest.FeatureTwo" | Get-ExperimentalFeature -ListAvailable
$features | Should -Not -BeNullOrEmpty
$features[0].Name | Should -BeExactly "ExpTest.FeatureOne"
$features[0].Enabled | Should -Be $false
$features[0].Source | Should -BeExactly $testModuleManifestPath
$features[1].Name | Should -BeExactly "ExpTest.FeatureTwo"
$features[1].Enabled | Should -Be $false
$features[1].Source | Should -BeExactly $testModuleManifestPath
}
}
Describe "Get-ExperimentalFeature basic tests - Feature-Enabled" -tags "CI" {
BeforeAll {
$skipTest = -not $EnabledExperimentalFeatures.Contains('ExpTest.FeatureOne')
if ($skipTest) {
Write-Verbose "Test Suite Skipped. The test suite requires the experimental feature 'ExpTest.FeatureOne' to be enabled." -Verbose
$originalDefaultParameterValues = $PSDefaultParameterValues.Clone()
$PSDefaultParameterValues["it:skip"] = $true
} else {
Remove-Module -Name ExpTest -Force -ErrorAction SilentlyContinue
$testModulePath = Join-Path -Path $PSScriptRoot -ChildPath "assets"
$testModuleManifestPath = Join-Path -Path $testModulePath "ExpTest" "ExpTest.psd1"
$originalModulePath = $env:PSModulePath
$env:PSModulePath = $testModulePath
$feature = pwsh -noprofile -output xml -command Get-ExperimentalFeature ExpTest.FeatureOne
$feature.Enabled | Should -BeTrue -Because "FeatureOne is enabled in user config"
$feature = pwsh -noprofile -output xml -command Get-ExperimentalFeature ExpTest.FeatureTwo
$feature.Enabled | Should -BeFalse -Because "System config is not read when user config exists"
}
}
AfterAll {
if ($skipTest) {
$global:PSDefaultParameterValues = $originalDefaultParameterValues
} else {
$env:PSModulePath = $originalModulePath
}
}
It "'Get-ExperimentalFeature' should return enabled features 'ExpTest.FeatureOne'" {
$EnabledExperimentalFeatures.Count | Should -Be 1
$feature = Get-ExperimentalFeature "ExpTest.FeatureOne"
$feature | Should -Not -BeNullOrEmpty
$feature.Enabled | Should -Be $true
$feature.Source | Should -BeExactly $testModuleManifestPath
}
It "'Get-ExperimentalFeature -ListAvailable' should return all available features from module path" {
$features = Get-ExperimentalFeature "ExpTest*" -ListAvailable
$features | Should -Not -BeNullOrEmpty
$features[0].Name | Should -BeExactly "ExpTest.FeatureOne"
$features[0].Enabled | Should -Be $true
$features[0].Source | Should -BeExactly $testModuleManifestPath
$features[1].Name | Should -BeExactly "ExpTest.FeatureTwo"
$features[1].Enabled | Should -Be $false
$features[1].Source | Should -BeExactly $testModuleManifestPath
}
It "'Get-ExperimentalFeature -ListAvailable' pipeline input" {
$features = "ExpTest.FeatureOne", "ExpTest.FeatureTwo" | Get-ExperimentalFeature -ListAvailable
$features | Should -Not -BeNullOrEmpty
$features[0].Name | Should -BeExactly "ExpTest.FeatureOne"
$features[0].Enabled | Should -Be $true
$features[0].Source | Should -BeExactly $testModuleManifestPath
$features[1].Name | Should -BeExactly "ExpTest.FeatureTwo"
$features[1].Enabled | Should -Be $false
$features[1].Source | Should -BeExactly $testModuleManifestPath
}
}
@@ -11,7 +11,9 @@ $script:cmdletsToSkip = @(
"Get-PSSessionCapability",
"Disable-PSRemoting", # Content not available: Issue # https://github.com/PowerShell/PowerShell-Docs/issues/1790
"Enable-PSRemoting",
"Get-ExperimentalFeature"
"Get-ExperimentalFeature",
"Enable-ExperimentalFeature",
"Disable-ExperimentalFeature"
)
function UpdateHelpFromLocalContentPath {
+1 -1
View File
@@ -1,5 +1,5 @@
{
"ExperimentalFeatures": {
"ExpTest.FeatureOne": [ "test/powershell/engine/ExperimentalFeature" ]
"ExpTest.FeatureOne": [ "test/powershell/engine/ExperimentalFeature/ExperimentalFeature.Basic.Tests.ps1" ]
}
}