From cfdae3013ff04fe7096e69c79c6201569e2955e3 Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Mon, 8 May 2017 11:38:26 -0700 Subject: [PATCH] Enable Get-TimeZone for *nix and Mac OS. Get-TimeZone can be enabled now as the required classes are available in .Net Standard 2.0 Address code review feedback --- .../commands/management/TimeZoneCommands.cs | 23 +- .../Microsoft.PowerShell.Management.psd1 | 3 +- .../TimeZone.Tests.ps1 | 268 +++++++++--------- .../Unimplemented-Cmdlet.Tests.ps1 | 1 - .../Default-Aliases.Tests.ps1 | 2 +- 5 files changed, 142 insertions(+), 155 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/TimeZoneCommands.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/TimeZoneCommands.cs index 339e2e2dba4..213ac8cf27c 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/TimeZoneCommands.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/TimeZoneCommands.cs @@ -1,5 +1,3 @@ -#if !UNIX - using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -66,15 +64,7 @@ protected override void ProcessRecord() { WriteObject(TimeZoneInfo.FindSystemTimeZoneById(tzid)); } -#if CORECLR - // TimeZoneNotFoundException is thrown by TimeZoneInfo, but not - // publicly visible (so can't be caught), so for now we're catching - // the parent exception time. This should be removed once the more - // specific exception is available. - catch (Exception e) -#else catch (TimeZoneNotFoundException e) -#endif { WriteError(new ErrorRecord(e, TimeZoneHelper.TimeZoneNotFoundError, ErrorCategory.InvalidArgument, "Id")); @@ -103,14 +93,8 @@ protected override void ProcessRecord() { string message = string.Format(CultureInfo.InvariantCulture, TimeZoneResources.TimeZoneNameNotFound, tzname); -#if CORECLR - // Because .NET Core does not currently expose the TimeZoneNotFoundException - // we need to throw the more generic parent exception class for the time being. - // This should be removed once the correct exception class is available. - Exception e = new Exception(message); -#else + Exception e = new TimeZoneNotFoundException(message); -#endif WriteError(new ErrorRecord(e, TimeZoneHelper.TimeZoneNotFoundError, ErrorCategory.InvalidArgument, "Name")); } @@ -125,6 +109,7 @@ protected override void ProcessRecord() } } +#if !UNIX /// /// A cmdlet to set the system's local time zone. @@ -804,7 +789,7 @@ public struct TOKEN_PRIVILEGES #endregion Win32 interop helper } - +#endif /// /// static Helper class for working with system time zones. /// @@ -862,5 +847,3 @@ internal static TimeZoneInfo[] LookupSystemTimeZoneInfoByName(string name) } } } - -#endif diff --git a/src/Modules/Unix/Microsoft.PowerShell.Management/Microsoft.PowerShell.Management.psd1 b/src/Modules/Unix/Microsoft.PowerShell.Management/Microsoft.PowerShell.Management.psd1 index db3a08fe3e1..de0f7f818ae 100644 --- a/src/Modules/Unix/Microsoft.PowerShell.Management/Microsoft.PowerShell.Management.psd1 +++ b/src/Modules/Unix/Microsoft.PowerShell.Management/Microsoft.PowerShell.Management.psd1 @@ -48,5 +48,6 @@ CmdletsToExport=@("Add-Content", "Rename-ItemProperty", "Resolve-Path", "Set-Content", - "Set-ItemProperty") + "Set-ItemProperty", + "Get-TimeZone") } diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/TimeZone.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/TimeZone.Tests.ps1 index 6c78ed080c4..3ac4b6f64f6 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/TimeZone.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/TimeZone.Tests.ps1 @@ -14,11 +14,6 @@ [snippet] Both StandardName and DaylightName are localized according to the current user default UI language. #> -try { - - $defaultParamValues = $PSdefaultParameterValues.Clone() - $PSDefaultParameterValues["it:skip"] = !$IsWindows - function Assert-ListsSame { param([object[]] $expected, [object[]] $observed ) @@ -31,15 +26,24 @@ function Assert-ListsSame } } -Describe "Get-Timezone test case no switches" -Tags "CI" { +Describe "Get-Timezone test cases" -Tags "CI" { + + BeforeAll { + $TimeZonesAvailable = [System.TimeZoneInfo]::GetSystemTimeZones() + + $defaultParamValues = $PSdefaultParameterValues.Clone() + $PSDefaultParameterValues["it:skip"] = ($TimeZonesAvailable.Count -eq 0) + } + + AfterAll { + $global:PSDefaultParameterValues = $defaultParamValues + } + It "Call without ListAvailable switch returns current TimeZoneInfo" { $observed = (Get-TimeZone).Id $expected = ([System.TimeZoneInfo]::Local).Id - $observed -eq $expected | Should Be $true + $observed | Should Be $expected } -} - -Describe "Get-Timezone test cases" -Tags "CI" { It "Call without ListAvailable switch returns an object of type TimeZoneInfo" { $result = Get-TimeZone @@ -48,58 +52,64 @@ Describe "Get-Timezone test cases" -Tags "CI" { It "Call WITH ListAvailable switch returns ArrayList of TimeZoneInfo objects where the list is greater than 0 item" { $list = Get-TimeZone -ListAvailable - $list.Count -gt 0 | Should Be $true + $list.Count | Should BeGreaterThan 0 ,$list | Should BeOfType "Object[]" $list[0] | Should BeOfType "TimeZoneInfo" } + ## The local time zone could be set to UTC or GMT*. In this case, the .NET API returns the region ID + ## and not 'UTC'. To avoid a string matching error, we compare the BaseUtcOffset instead. It "Call with ListAvailable switch returns a list containing TimeZoneInfo.Local" { - $observedIdList = Get-TimeZone -ListAvailable | Select-Object -ExpandProperty Id - $oneExpectedId = ([System.TimeZoneInfo]::Local).Id - $observedIdList -contains $oneExpectedId | Should Be $true + $observedIdList = Get-TimeZone -ListAvailable | Select-Object -ExpandProperty BaseUtcOffset + $oneExpectedOffset = ([System.TimeZoneInfo]::Local).BaseUtcOffset + $observedIdList -eq $oneExpectedOffset | Should Be $oneExpectedOffset } + ## The local time zone could be set to UTC or GMT*. In this case, the .NET API returns the region ID + ## and not UTC. To avoid a string matching error, we compare the BaseUtcOffset instead. It "Call with ListAvailable switch returns a list containing one returned by Get-TimeZone" { - $observedIdList = Get-TimeZone -ListAvailable | Select-Object -ExpandProperty Id - $oneExpectedId = (Get-TimeZone).Id - $observedIdList -contains $oneExpectedId | Should Be $true + $observedIdList = Get-TimeZone -ListAvailable | Select-Object -ExpandProperty BaseUtcOffset + $oneExpectedOffset = (Get-TimeZone).BaseUtcOffset + $observedIdList -eq $oneExpectedOffset | Should Be $oneExpectedOffset } It "Call Get-TimeZone using ID param and single item" { - (Get-TimeZone -Id "Cape Verde Standard Time").Id -eq "Cape Verde Standard Time" | Should Be $true + $selectedTZ = $TimeZonesAvailable[0] + (Get-TimeZone -Id $selectedTZ.Id).Id | Should Be $selectedTZ.Id } It "Call Get-TimeZone using ID param and multiple items" { - $idList = @("Cape Verde Standard Time","Morocco Standard Time","Azores Standard Time") - $result = (Get-TimeZone -Id $idList).Id - Assert-ListsSame $result $idList + $selectedTZ = $TimeZonesAvailable | Select-Object -First 3 -ExpandProperty Id + $result = (Get-TimeZone -Id $selectedTZ).Id + Assert-ListsSame $result $selectedTZ } It "Call Get-TimeZone using ID param and multiple items, where first and third are invalid ids - expect error" { - $null = Get-TimeZone -Id @("Cape Verde Standard","Morocco Standard Time","Azores Standard") ` + $selectedTZ = $TimeZonesAvailable[0].Id + $null = Get-TimeZone -Id @("Cape Verde Standard",$selectedTZ,"Azores Standard") ` -ErrorVariable errVar -ErrorAction SilentlyContinue - $errVar.Count -eq 2 | Should Be $true + $errVar.Count | Should Be 2 $errVar[0].FullyQualifiedErrorID | Should Be "TimeZoneNotFound,Microsoft.PowerShell.Commands.GetTimeZoneCommand" } It "Call Get-TimeZone using ID param and multiple items, one is wild card but error action ignore works as expected" { - $result = Get-TimeZone -Id @("Cape Verde Standard Time","Morocco Standard Time","*","Azores Standard Time") ` - -ErrorAction SilentlyContinue | ForEach-Object Id - $expectedIdList = @("Cape Verde Standard Time","Morocco Standard Time","Azores Standard Time") - Assert-ListsSame $expectedIdList $result + $selectedTZ = $TimeZonesAvailable | Select-Object -First 3 -ExpandProperty Id + $inputArray = $selectedTZ + "*" + $result = Get-TimeZone -Id $inputArray -ErrorAction SilentlyContinue | ForEach-Object Id + Assert-ListsSame $selectedTZ $result } It "Call Get-TimeZone using Name param and singe item" { $timezoneList = Get-TimeZone -ListAvailable $timezoneName = $timezoneList[0].StandardName $observed = Get-TimeZone -Name $timezoneName - $observed.StandardName -eq $timezoneName | Should Be $true + $observed.StandardName | Should Be $timezoneName } - It "Call Get-TimeZone using Name param with wild card" { + It "Call Get-TimeZone using Name param with wild card" { $result = (Get-TimeZone -Name "Pacific*").Id - $expectedIdList = @("Pacific Standard Time (Mexico)","Pacific Standard Time","Pacific SA Standard Time") + $expectedIdList = ($TimeZonesAvailable | Where-Object { $_.StandardName -match "^Pacific" }).Id Assert-ListsSame $expectedIdList $result } @@ -109,7 +119,7 @@ Describe "Get-Timezone test cases" -Tags "CI" { It "Call Get-TimeZone Name parameter from pipeline by value " { $result = ("Pacific*" | Get-TimeZone).Id - $expectedIdList = @("Pacific Standard Time (Mexico)","Pacific Standard Time","Pacific SA Standard Time") + $expectedIdList = ($TimeZonesAvailable | Where-Object { $_.StandardName -match "^Pacific" }).Id Assert-ListsSame $expectedIdList $result } @@ -117,134 +127,128 @@ Describe "Get-Timezone test cases" -Tags "CI" { $timezoneList = Get-TimeZone -ListAvailable $timezone = $timezoneList[0] $observed = $timezone | Get-TimeZone - $observed.StandardName -eq $timezone.StandardName | Should Be $true + $observed.StandardName | Should Be $timezone.StandardName } } -Describe "Set-Timezone test case: call by single Id" -Tags @('CI', 'RequireAdminOnWindows') { - BeforeAll { - if ($IsWindows) { - $originalTimeZoneId = (Get-TimeZone).Id +try { + $defaultParamValues = $PSdefaultParameterValues.Clone() + $PSDefaultParameterValues["it:skip"] = !$IsWindows + + Describe "Set-Timezone test case: call by single Id" -Tags @('CI', 'RequireAdminOnWindows') { + BeforeAll { + if ($IsWindows) { + $originalTimeZoneId = (Get-TimeZone).Id + } } - } - AfterAll { - if ($IsWindows) { - Set-TimeZone -ID $originalTimeZoneId + AfterAll { + if ($IsWindows) { + Set-TimeZone -ID $originalTimeZoneId + } } - } - It "Call Set-TimeZone by Id" { - $origTimeZoneID = (Get-TimeZone).Id - $timezoneList = Get-TimeZone -ListAvailable - $testTimezone = $null - foreach($timezone in $timezoneList) - { - if ($timezone.Id -ne $origTimeZoneID) - { - $testTimezone = $timezone - break + It "Call Set-TimeZone by Id" { + $origTimeZoneID = (Get-TimeZone).Id + $timezoneList = Get-TimeZone -ListAvailable + $testTimezone = $null + foreach ($timezone in $timezoneList) { + if ($timezone.Id -ne $origTimeZoneID) { + $testTimezone = $timezone + break + } } + Set-TimeZone -Id $testTimezone.Id + $observed = Get-TimeZone + $testTimezone.Id | Should Be $observed.Id } - Set-TimeZone -Id $testTimezone.Id - $observed = Get-TimeZone - $testTimezone.Id -eq $observed.Id | Should Be $true } -} -Describe "Set-Timezone test cases" -Tags @('Feature', 'RequireAdminOnWindows') { - BeforeAll { - if ($IsWindows) { - $originalTimeZoneId = (Get-TimeZone).Id + Describe "Set-Timezone test cases" -Tags @('Feature', 'RequireAdminOnWindows') { + BeforeAll { + if ($IsWindows) + { + $originalTimeZoneId = (Get-TimeZone).Id + } } - } - AfterAll { - if ($IsWindows) { - Set-TimeZone -ID $originalTimeZoneId + AfterAll { + if ($IsWindows) { + Set-TimeZone -ID $originalTimeZoneId + } } - } - It "Call Set-TimeZone with invalid Id" { - try - { - Set-TimeZone -Id "zzInvalidID" - throw "No Exception!" - } - catch - { - $_.FullyQualifiedErrorID | Should Be "TimeZoneNotFound,Microsoft.PowerShell.Commands.SetTimeZoneCommand" + It "Call Set-TimeZone with invalid Id" { + try { + Set-TimeZone -Id "zzInvalidID" + throw "No Exception!" + } + catch { + $_.FullyQualifiedErrorID | Should Be "TimeZoneNotFound,Microsoft.PowerShell.Commands.SetTimeZoneCommand" + } } - } - It "Call Set-TimeZone by Name" { - $origTimeZoneName = (Get-TimeZone).StandardName - $timezoneList = Get-TimeZone -ListAvailable - $testTimezone = $null - foreach($timezone in $timezoneList) - { - if ($timezone.StandardName -ne $origTimeZoneName) - { - $testTimezone = $timezone - break + It "Call Set-TimeZone by Name" { + $origTimeZoneName = (Get-TimeZone).StandardName + $timezoneList = Get-TimeZone -ListAvailable + $testTimezone = $null + foreach ($timezone in $timezoneList) { + if ($timezone.StandardName -ne $origTimeZoneName) { + $testTimezone = $timezone + break + } } + Set-TimeZone -Name $testTimezone.StandardName + $observed = Get-TimeZone + $testTimezone.StandardName | Should Be $observed.StandardName } - Set-TimeZone -Name $testTimezone.StandardName - $observed = Get-TimeZone - $testTimezone.StandardName -eq $observed.StandardName | Should Be $true - } - It "Call Set-TimeZone with invalid Name" { - try - { - Set-TimeZone -Name "zzINVALID_Name" - throw "No Exception!" - } - catch - { - $_.FullyQualifiedErrorID | Should Be "TimeZoneNotFound,Microsoft.PowerShell.Commands.SetTimeZoneCommand" + It "Call Set-TimeZone with invalid Name" { + try { + Set-TimeZone -Name "zzINVALID_Name" + throw "No Exception!" + } + catch { + $_.FullyQualifiedErrorID | Should Be "TimeZoneNotFound,Microsoft.PowerShell.Commands.SetTimeZoneCommand" + } } - } - It "Verify that alias 'stz' exists" { - (Get-Alias -Name "stz").Name | Should Be "stz" - } + It "Verify that alias 'stz' exists" { + (Get-Alias -Name "stz").Name | Should Be "stz" + } - It "Call Set-TimeZone from pipeline input object of type TimeZoneInfo" { - $origTimeZoneID = (Get-TimeZone).Id - $timezoneList = Get-TimeZone -ListAvailable - $testTimezone = $null - foreach($timezone in $timezoneList) - { - if ($timezone.Id -ne $origTimeZoneID) - { - $testTimezone = $timezone - break + It "Call Set-TimeZone from pipeline input object of type TimeZoneInfo" { + $origTimeZoneID = (Get-TimeZone).Id + $timezoneList = Get-TimeZone -ListAvailable + $testTimezone = $null + foreach ($timezone in $timezoneList) { + if ($timezone.Id -ne $origTimeZoneID) { + $testTimezone = $timezone + break + } } - } - $testTimezone | Set-TimeZone - $observed = Get-TimeZone - $observed.ID -eq $testTimezone.Id | Should Be $true - } + $testTimezone | Set-TimeZone + $observed = Get-TimeZone + $observed.ID | Should Be $testTimezone.Id + } - It "Call Set-TimeZone from pipeline input object of type TimeZoneInfo, verify supports whatif" { - $origTimeZoneID = (Get-TimeZone).Id - $timezoneList = Get-TimeZone -ListAvailable - $testTimezone = $null - foreach($timezone in $timezoneList) - { - if ($timezone.Id -ne $origTimeZoneID) - { - $testTimezone = $timezone - break + It "Call Set-TimeZone from pipeline input object of type TimeZoneInfo, verify supports whatif" { + $origTimeZoneID = (Get-TimeZone).Id + $timezoneList = Get-TimeZone -ListAvailable + $testTimezone = $null + foreach ($timezone in $timezoneList) { + if ($timezone.Id -ne $origTimeZoneID) { + $testTimezone = $timezone + break + } } - } - Set-TimeZone -Id $testTimezone.Id -WhatIf > $null - $observed = Get-TimeZone - $observed.Id -eq $origTimeZoneID | Should Be $true + Set-TimeZone -Id $testTimezone.Id -WhatIf > $null + $observed = Get-TimeZone + $observed.Id | Should Be $origTimeZoneID + } } } - -} finally { +finally { $global:PSDefaultParameterValues = $defaultParamValues } + diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Unimplemented-Cmdlet.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Unimplemented-Cmdlet.Tests.ps1 index be7bbea13c4..09a88ae71c6 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Unimplemented-Cmdlet.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Unimplemented-Cmdlet.Tests.ps1 @@ -18,7 +18,6 @@ Describe "Unimplemented Management Cmdlet Tests" -Tags "CI" { "Test-Connection", - "Get-TimeZone", "Set-TimeZone" ) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/Default-Aliases.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/Default-Aliases.Tests.ps1 index 5879c152ae5..fc1cfe8ed5b 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/Default-Aliases.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/Default-Aliases.Tests.ps1 @@ -93,7 +93,7 @@ Describe "Verify approved aliases list" -Tags "CI" { "gsn -> Get-PSSession" = $FullCLR -or $CoreWindows -or $CoreUnix "gsnp -> Get-PSSnapin" = $FullCLR "gsv -> Get-Service" = $FullCLR -or $CoreWindows -or $CoreUnix - "gtz -> Get-TimeZone" = $CoreWindows + "gtz -> Get-TimeZone" = $FullCLR -or $CoreWindows -or $CoreUnix "gu -> Get-Unique" = $FullCLR -or $CoreWindows -or $CoreUnix "gv -> Get-Variable" = $FullCLR -or $CoreWindows -or $CoreUnix "gwmi -> Get-WmiObject" = $FullCLR