This repository was archived by the owner on Feb 19, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 342
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'per-machine-install-v6' into stable
* per-machine-install-v6: tests: add environment manipulation mocking facility helpers: add environment variable management abstractions rename Test-AdminRights to Test-ProcessAdminRights setup tests: fix formatting setup tests: do not vary by UAC status when running with administrative rights, set environment variables at Machine scope setup tests: with admin rights, variables should be set at Machine level regardless of UAC setup tests: add simulated standard user scenarios enable mocking Test-AdminRights for setup tests Test-AdminRights: request WindowsIdentity with minimal access necessary add Test-AdminRights helper setup tests: mock UAC status setup tests: conditionally test default installation add tests for Chocolatey setup (Initialize-Chocolatey) tests: add environment variable handling facilities
- Loading branch information
Showing
19 changed files
with
1,109 additions
and
81 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
function Get-EnvironmentVariable([string] $Name, [System.EnvironmentVariableTarget] $Scope) { | ||
[Environment]::GetEnvironmentVariable($Name, $Scope) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
function Get-EnvironmentVariableNames([System.EnvironmentVariableTarget] $Scope) { | ||
switch ($Scope) { | ||
'User' { Get-Item 'HKCU:\Environment' | Select-Object -ExpandProperty Property } | ||
'Machine' { Get-Item 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment' | Select-Object -ExpandProperty Property } | ||
'Process' { Get-ChildItem Env:\ | Select-Object -ExpandProperty Key } | ||
default { throw "Unsupported environment scope: $Scope" } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
function Set-EnvironmentVariable([string] $Name, [string] $Value, [System.EnvironmentVariableTarget] $Scope) { | ||
[Environment]::SetEnvironmentVariable($Name, $Value, $Scope) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
function Test-ProcessAdminRights { | ||
<# | ||
.SYNOPSIS | ||
Tests whether the current process is running with administrative rights. | ||
.DESCRIPTION | ||
This function checks whether the current process has administrative rights | ||
by checking if the current user identity is a member of the Administrators group. | ||
It returns $true if the current process is running with administrative rights, | ||
$false otherwise. | ||
On Windows Vista and later, with UAC enabled, the returned value represents the | ||
actual rights available to the process, i.e. if it returns $true, the process is | ||
running elevated. | ||
.OUTPUTS | ||
System.Boolean | ||
#> | ||
|
||
$currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent([Security.Principal.TokenAccessLevels]'Query,Duplicate')) | ||
$isAdmin = $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) | ||
Write-Debug "Test-ProcessAdminRights: returning $isAdmin" | ||
return $isAdmin | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
$here = Split-Path -Parent $MyInvocation.MyCommand.Definition | ||
|
||
Get-ChildItem "$here\mocks" -Filter *.ps1 -Recurse | ForEach-Object { Write-Debug "Importing $($_.FullName)"; . $_.FullName } | ||
|
||
function Get-EnvironmentSnapshot() | ||
{ | ||
Write-Debug 'Obtaining snapshot of the environment' | ||
$machineEnv = @{} | ||
$key = Get-Item 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment' | ||
$key.GetValueNames() | ForEach-Object { $machineEnv[$_] = $key.GetValue($_) } | ||
|
||
$userEnv = @{} | ||
$key = Get-Item 'HKCU:\Environment' | ||
$key.GetValueNames() | ForEach-Object { $userEnv[$_] = $key.GetValue($_) } | ||
|
||
$processEnv = @{} | ||
Get-ChildItem Env:\ | ForEach-Object { $processEnv[$_.Key] = $_.Value } | ||
|
||
return New-Object PSCustomObject -Property @{ machine = $machineEnv; user = $userEnv; process = $processEnv } | ||
} | ||
|
||
function Restore-Environment($state) | ||
{ | ||
Write-Debug 'Restoring the environment' | ||
$state.machine.GetEnumerator() | ForEach-Object { | ||
$current = [Environment]::GetEnvironmentVariable($_.Key, 'Machine') | ||
if ($current -ne $_.Value) { | ||
Write-Warning "Restoring value of environment variable $($_.Key) at Machine scope. The need to do that means that some code did not use the environment manipulation functions *-EnvironmentVariable*." | ||
[Environment]::SetEnvironmentVariable($_.Key, $_.Value, 'Machine') | ||
} | ||
} | ||
|
||
$key = Get-Item 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment' | ||
$key.GetValueNames() | Where-Object { -not $state.machine.ContainsKey($_) } | ForEach-Object { | ||
Write-Warning "Deleting environment variable $_ at Machine scope. The need to do that means that some code did not use the environment manipulation functions *-EnvironmentVariable*." | ||
[Environment]::SetEnvironmentVariable($_, $null, 'Machine') | ||
} | ||
|
||
$state.user.GetEnumerator() | ForEach-Object { | ||
$current = [Environment]::GetEnvironmentVariable($_.Key, 'User') | ||
if ($current -ne $_.Value) { | ||
Write-Warning "Restoring value of environment variable $($_.Key) at User scope. The need to do that means that some code did not use the environment manipulation functions *-EnvironmentVariable*." | ||
[Environment]::SetEnvironmentVariable($_.Key, $_.Value, 'User') | ||
} | ||
} | ||
|
||
$key = Get-Item 'HKCU:\Environment' | ||
$key.GetValueNames() | Where-Object { -not $state.user.ContainsKey($_) } | ForEach-Object { | ||
Write-Warning "Deleting environment variable $_ at User scope. The need to do that means that some code did not use the environment manipulation functions *-EnvironmentVariable*." | ||
[Environment]::SetEnvironmentVariable($_, $null, 'User') | ||
} | ||
|
||
$state.process.GetEnumerator() | ForEach-Object { | ||
$current = [Environment]::GetEnvironmentVariable($_.Key, 'Process') | ||
if ($current -ne $_.Value) { | ||
Write-Debug "Restoring value of environment variable $($_.Key) at Process scope" | ||
[Environment]::SetEnvironmentVariable($_.Key, $_.Value, 'Process') | ||
} | ||
} | ||
|
||
Get-ChildItem Env:\ | Select-Object -ExpandProperty Name | Where-Object { -not $state.process.ContainsKey($_) } | ForEach-Object { | ||
Write-Debug "Deleting environment variable $_ at Process scope" | ||
[Environment]::SetEnvironmentVariable($_, $null, 'Process') | ||
} | ||
} | ||
|
||
function Setup-EnvironmentMockup | ||
{ | ||
$global:ChocolateyTestEnvironmentVariables = Get-EnvironmentSnapshot | ||
} | ||
|
||
function Cleanup-EnvironmentMockup | ||
{ | ||
$global:ChocolateyTestEnvironmentVariables = $null | ||
} | ||
|
||
function Execute-WithEnvironmentProtection($scriptBlock) | ||
{ | ||
$savedEnvironment = Get-EnvironmentSnapshot | ||
try | ||
{ | ||
Setup-EnvironmentMockup | ||
try | ||
{ | ||
& $scriptBlock | ||
} | ||
finally | ||
{ | ||
Cleanup-EnvironmentMockup | ||
} | ||
} | ||
finally | ||
{ | ||
Restore-Environment $savedEnvironment | ||
} | ||
} | ||
|
||
function Add-EnvironmentVariable($name, $value, $targetScope) | ||
{ | ||
Write-Debug "Setting $name to $value at $targetScope scope" | ||
Set-EnvironmentVariable -Name $name -Value $Value -Scope $targetScope | ||
if ($targetScope -eq 'Process') { | ||
Write-Debug "Current $name value is '$value' (from Process scope)" | ||
return | ||
} | ||
# find lowest scope with $name set and use that value as current | ||
foreach ($currentScope in @('User', 'Machine')) { | ||
$valueAtCurrentScope = Get-EnvironmentVariable -Name $name -Scope $currentScope | ||
if ($valueAtCurrentScope -ne $null) { | ||
Write-Debug "Current $name value is '$valueAtCurrentScope' (from $currentScope scope)" | ||
Set-EnvironmentVariable -Name $name -Value $valueAtCurrentScope -Scope Process | ||
break | ||
} | ||
} | ||
} | ||
|
||
function Remove-EnvironmentVariable($name) | ||
{ | ||
Write-Debug "Ensuring environment variable $name is not set at any scope" | ||
'Machine','User','Process' | ForEach-Object { | ||
if (-not ([String]::IsNullOrEmpty((Get-EnvironmentVariable -Name $name -Scope $_)))) { | ||
Write-Debug "Deleting environment variable $name at $_ scope" | ||
Set-EnvironmentVariable -Name $name -Value $null -Scope $_ | ||
} | ||
} | ||
} | ||
|
||
function Add-DirectoryToPath($directory, $scope) | ||
{ | ||
$curPath = Get-EnvironmentVariable -Name 'PATH' -Scope $scope | ||
$newPath = ($curPath -split ';' | Where-Object { $_.TrimEnd('\') -ne $directory.TrimEnd('\') }) -join ';' | ||
if ($newPath -ne $curPath) { | ||
Write-Debug "Directory $directory is already on PATH at $scope scope" | ||
} else { | ||
Write-Debug "Adding directory $directory to PATH at $scope scope" | ||
if ([String]::IsNullOrEmpty($newPath)) { | ||
Set-EnvironmentVariable -Name 'PATH' -Value $directory -Scope $scope | ||
} else { | ||
Set-EnvironmentVariable -Name 'PATH' -Value "$($newPath.TrimEnd(';'));$directory" -Scope $scope | ||
} | ||
} | ||
if ($scope -ne 'Process') { | ||
$curPath = Get-EnvironmentVariable -Name 'PATH' -Scope Process | ||
$newPath = ($curPath -split ';' | Where-Object { $_.TrimEnd('\') -ne $directory.TrimEnd('\') }) -join ';' | ||
if ($newPath -eq $curPath) { | ||
Write-Debug "Adding directory $directory to PATH at Process scope" | ||
if ([String]::IsNullOrEmpty($newPath)) { | ||
Set-EnvironmentVariable -Name 'PATH' -Value $directory -Scope Process | ||
} else { | ||
Set-EnvironmentVariable -Name 'PATH' -Value "$($newPath.TrimEnd(';'));$directory" -Scope Process | ||
} | ||
} | ||
} | ||
} | ||
|
||
function Remove-DirectoryFromPath($directory) | ||
{ | ||
Write-Debug "Ensuring directory $directory is not on PATH at any scope" | ||
'Machine','User','Process' | ForEach-Object { | ||
$scope = $_ | ||
$curPath = Get-EnvironmentVariable -Name 'PATH' -Scope $scope | ||
$newPath = ($curPath -split ';' | Where-Object { $_.TrimEnd('\') -ne $directory.TrimEnd('\') }) -join ';' | ||
if ($newPath -ne $curPath) { | ||
Write-Debug "Removing directory $directory from PATH at $scope scope" | ||
Set-EnvironmentVariable -Name 'PATH' -Value $newPath -Scope $scope | ||
} | ||
} | ||
} | ||
|
||
function Assert-OnPath($directory, $pathScope) | ||
{ | ||
$path = Get-EnvironmentVariable -Name 'PATH' -Scope $pathScope | ||
$dirInPath = $path -split ';' | Where-Object { $_ -eq $directory } | ||
"$dirInPath" | Should not BeNullOrEmpty | ||
} | ||
|
||
function Assert-NotOnPath($directory, $pathScope) | ||
{ | ||
$path = Get-EnvironmentVariable -Name 'PATH' -Scope $pathScope | ||
$dirInPath = $path -split ';' | Where-Object { $_ -eq $directory } | ||
"$dirInPath" | Should BeNullOrEmpty | ||
} |
Oops, something went wrong.