From 40437ba8091c1a9cad1cdd98fb8bfe7aa2baa51c Mon Sep 17 00:00:00 2001 From: iSazonov Date: Thu, 17 Nov 2016 00:37:26 +0600 Subject: [PATCH 01/11] Correct samples in testing-guidelines (#2691) Replace 'Start-PSPester -Directory' with 'Start-PSPester -Path' --- docs/testing-guidelines/testing-guidelines.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/testing-guidelines/testing-guidelines.md b/docs/testing-guidelines/testing-guidelines.md index d2d4d18ede..85e78234e3 100755 --- a/docs/testing-guidelines/testing-guidelines.md +++ b/docs/testing-guidelines/testing-guidelines.md @@ -90,11 +90,11 @@ Start-PSPester ``` If you wish to run specific tests, that is possible as well: ``` -Start-PSPester -Directory test/powershell/engine/Api +Start-PSPester -Path test/powershell/engine/Api ``` Or a specific Pester test file: ``` -Start-PSPester -Directory test/powershell/engine/Api -Test XmlAdapter.Tests.Api +Start-PSPester -Path test/powershell/engine/Api/XmlAdapter.Tests.ps1 ``` ### What happens after your PR? From 7e581be7c4ccd40f4e84415b9c60c9d18f4416d6 Mon Sep 17 00:00:00 2001 From: Dongbo Wang Date: Wed, 16 Nov 2016 11:13:09 -0800 Subject: [PATCH 02/11] Add HelpUri for Get-Uptime (#2688) * Add HelpUri for Get-Uptime * Update online help test data to include Get-Uptime --- .../commands/utility/GetUptime.cs | 2 +- src/vs-csproj/Microsoft.PowerShell.Commands.Utility.csproj | 5 ++++- test/powershell/engine/Help/assets/HelpURI/V3Cmdlets.csv | 3 ++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetUptime.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetUptime.cs index ab873bf42e..86d1310809 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetUptime.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetUptime.cs @@ -12,7 +12,7 @@ namespace Microsoft.PowerShell.Commands /// /// This class implements Get-Uptime /// - [Cmdlet(VerbsCommon.Get, "Uptime", DefaultParameterSetName = TimespanParameterSet, HelpUri = "")] + [Cmdlet(VerbsCommon.Get, "Uptime", DefaultParameterSetName = TimespanParameterSet, HelpUri = "https://go.microsoft.com/fwlink/?linkid=834862")] [OutputType(typeof(TimeSpan), ParameterSetName = new string[] { TimespanParameterSet })] [OutputType(typeof(DateTime), ParameterSetName = new string[] { SinceParameterSet })] public class GetUptimeCommand : PSCmdlet diff --git a/src/vs-csproj/Microsoft.PowerShell.Commands.Utility.csproj b/src/vs-csproj/Microsoft.PowerShell.Commands.Utility.csproj index f0a75c8a5a..7513116c53 100644 --- a/src/vs-csproj/Microsoft.PowerShell.Commands.Utility.csproj +++ b/src/vs-csproj/Microsoft.PowerShell.Commands.Utility.csproj @@ -193,6 +193,9 @@ commands\utility\GetUnique.cs + + commands\utility\GetUptime.cs + commands\utility\group-object.cs @@ -694,4 +697,4 @@ - \ No newline at end of file + diff --git a/test/powershell/engine/Help/assets/HelpURI/V3Cmdlets.csv b/test/powershell/engine/Help/assets/HelpURI/V3Cmdlets.csv index cbc2c68e08..71f9f3e773 100644 --- a/test/powershell/engine/Help/assets/HelpURI/V3Cmdlets.csv +++ b/test/powershell/engine/Help/assets/HelpURI/V3Cmdlets.csv @@ -89,4 +89,5 @@ New-FileCatalog,https://go.microsoft.com/fwlink/?LinkId=786749 Test-FileCatalog,https://go.microsoft.com/fwlink/?LinkId=786750 Get-ComputerInfo,https://go.microsoft.com/fwlink/?LinkId=799466 Get-TimeZone,https://go.microsoft.com/fwlink/?LinkId=799468 -Set-TimeZone,https://go.microsoft.com/fwlink/?LinkId=799469 \ No newline at end of file +Set-TimeZone,https://go.microsoft.com/fwlink/?LinkId=799469 +Get-Uptime,https://go.microsoft.com/fwlink/?linkid=834862 From 15ed125c4a7305b3354ec40dd6591727b42d6aef Mon Sep 17 00:00:00 2001 From: Alessandro Pilotti Date: Thu, 17 Nov 2016 02:26:46 +0200 Subject: [PATCH 03/11] Fixes deprecated syscall issue on macOS 10.12 (#2633) (#2675) syscall() has been deprecated and is not available on macOS 10.12. --- src/libpsl-native/src/getcurrentthreadid.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libpsl-native/src/getcurrentthreadid.cpp b/src/libpsl-native/src/getcurrentthreadid.cpp index e836685ccd..84d5b6f4ae 100644 --- a/src/libpsl-native/src/getcurrentthreadid.cpp +++ b/src/libpsl-native/src/getcurrentthreadid.cpp @@ -3,6 +3,7 @@ #include #include #include +#include pid_t GetCurrentThreadId() { @@ -10,7 +11,9 @@ pid_t GetCurrentThreadId() #if defined(__linux__) tid = syscall(SYS_gettid); #elif defined(__APPLE__) && defined(__MACH__) - tid = syscall(SYS_thread_selfid); + uint64_t tid64; + pthread_threadid_np(NULL, &tid64); + tid = (pid_t)tid64; #endif return tid; } From ce26bca8db4880dbc0bc7fd19c7d46e374e3cdfc Mon Sep 17 00:00:00 2001 From: Sergei Vorobev Date: Wed, 16 Nov 2016 21:23:57 -0800 Subject: [PATCH 04/11] Re-enable Add-Type coreclr tests (#2705) --- .../Modules/Microsoft.PowerShell.Utility/Add-Type.Tests.ps1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/Add-Type.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/Add-Type.Tests.ps1 index ee0f2c951c..5b4b7d7d6e 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/Add-Type.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/Add-Type.Tests.ps1 @@ -1,11 +1,11 @@ $guid = [Guid]::NewGuid().ToString().Replace("-","") Describe "Add-Type" -Tags "CI" { - It "Should not throw given a simple class definition" -pending:($IsCoreCLR) { + It "Should not throw given a simple class definition" { { Add-Type -TypeDefinition "public static class foo { }" } | Should Not Throw } - It "Can use System.Management.Automation.CmdletAttribute" -pending:($IsCoreCLR) { + It "Can use System.Management.Automation.CmdletAttribute" { $code = @" [System.Management.Automation.Cmdlet("Get", "Thing", ConfirmImpact = System.Management.Automation.ConfirmImpact.High, SupportsPaging = true)] public class AttributeTest$guid {} @@ -13,7 +13,7 @@ public class AttributeTest$guid {} Add-Type -TypeDefinition $code -PassThru | Should Not Be $null } - It "Can load TPA assembly System.Runtime.Serialization.Primitives.dll" -pending:($IsCoreCLR) { + It "Can load TPA assembly System.Runtime.Serialization.Primitives.dll" { Add-Type -AssemblyName 'System.Runtime.Serialization.Primitives' -PassThru | Should Not Be $null } } From 3363b248a08ce3412bbf6fa1577f079be9d386f5 Mon Sep 17 00:00:00 2001 From: Sergei Vorobev Date: Thu, 17 Nov 2016 11:20:04 -0800 Subject: [PATCH 05/11] Fix code errors found by PVS-Studio (#2695) * Fix errors found by PSV-studio analyzer http://www.viva64.com/en/b/0447/ * Remove old redundent comment errorAsts is passed by ref --- .../common/DisplayDatabase/displayDescriptionData_List.cs | 2 +- .../common/DisplayDatabase/displayDescriptionData_Wide.cs | 2 +- .../FormatAndOutput/common/FormatViewGenerator_Complex.cs | 3 +-- .../engine/CommandMetadata.cs | 7 ++----- src/System.Management.Automation/engine/ErrorPackage.cs | 2 +- .../engine/Modules/ImportModuleCommand.cs | 2 +- .../engine/SessionStateProviderAPIs.cs | 2 +- .../engine/hostifaces/RunspacePoolInternal.cs | 8 ++++---- src/System.Management.Automation/engine/parser/Parser.cs | 3 +-- .../engine/remoting/client/Job.cs | 6 +++--- .../engine/remoting/server/serverremotesession.cs | 2 +- .../namespaces/FileSystemProvider.cs | 2 +- .../utils/PowerShellETWTracer.cs | 2 +- 13 files changed, 19 insertions(+), 24 deletions(-) diff --git a/src/System.Management.Automation/commands/utility/FormatAndOutput/common/DisplayDatabase/displayDescriptionData_List.cs b/src/System.Management.Automation/commands/utility/FormatAndOutput/common/DisplayDatabase/displayDescriptionData_List.cs index 436ba7b894..e62c649aa8 100644 --- a/src/System.Management.Automation/commands/utility/FormatAndOutput/common/DisplayDatabase/displayDescriptionData_List.cs +++ b/src/System.Management.Automation/commands/utility/FormatAndOutput/common/DisplayDatabase/displayDescriptionData_List.cs @@ -349,7 +349,7 @@ namespace System.Management.Automation internal bool SafeForExport() { return DisplayEntry.SafeForExport() && - ItemSelectionCondition == null || ItemSelectionCondition.SafeForExport(); + (ItemSelectionCondition == null || ItemSelectionCondition.SafeForExport()); } internal bool CompatibleWithOldPowerShell() diff --git a/src/System.Management.Automation/commands/utility/FormatAndOutput/common/DisplayDatabase/displayDescriptionData_Wide.cs b/src/System.Management.Automation/commands/utility/FormatAndOutput/common/DisplayDatabase/displayDescriptionData_Wide.cs index 660271fbcb..4e25bb280a 100644 --- a/src/System.Management.Automation/commands/utility/FormatAndOutput/common/DisplayDatabase/displayDescriptionData_Wide.cs +++ b/src/System.Management.Automation/commands/utility/FormatAndOutput/common/DisplayDatabase/displayDescriptionData_Wide.cs @@ -244,7 +244,7 @@ namespace System.Management.Automation internal bool SafeForExport() { - return DisplayEntry.SafeForExport() && EntrySelectedBy == null || EntrySelectedBy.SafeForExport(); + return DisplayEntry.SafeForExport() && (EntrySelectedBy == null || EntrySelectedBy.SafeForExport()); } internal bool CompatibleWithOldPowerShell() diff --git a/src/System.Management.Automation/commands/utility/FormatAndOutput/common/FormatViewGenerator_Complex.cs b/src/System.Management.Automation/commands/utility/FormatAndOutput/common/FormatViewGenerator_Complex.cs index 81ce6cea20..c01c363db1 100644 --- a/src/System.Management.Automation/commands/utility/FormatAndOutput/common/FormatViewGenerator_Complex.cs +++ b/src/System.Management.Automation/commands/utility/FormatAndOutput/common/FormatViewGenerator_Complex.cs @@ -433,8 +433,7 @@ namespace Microsoft.PowerShell.Commands.Internal.Format TraversalInfo level = new TraversalInfo(0, maxDepth); List mshParameterList = null; - if (inputParameters != null) - mshParameterList = inputParameters.mshParameterList; + mshParameterList = inputParameters.mshParameterList; // create a top level entry as root of the tree ComplexViewEntry cve = new ComplexViewEntry(); diff --git a/src/System.Management.Automation/engine/CommandMetadata.cs b/src/System.Management.Automation/engine/CommandMetadata.cs index b3502b598d..fc57bf4755 100644 --- a/src/System.Management.Automation/engine/CommandMetadata.cs +++ b/src/System.Management.Automation/engine/CommandMetadata.cs @@ -189,12 +189,9 @@ namespace System.Management.Automation _parameters = new Dictionary(other.Parameters.Count, StringComparer.OrdinalIgnoreCase); // deep copy - if (other.Parameters != null) + foreach (KeyValuePair entry in other.Parameters) { - foreach (KeyValuePair entry in other.Parameters) - { - _parameters.Add(entry.Key, new ParameterMetadata(entry.Value)); - } + _parameters.Add(entry.Key, new ParameterMetadata(entry.Value)); } // deep copy of the collection, collection items (Attributes) copied by reference diff --git a/src/System.Management.Automation/engine/ErrorPackage.cs b/src/System.Management.Automation/engine/ErrorPackage.cs index f78eb8ee66..b8edf4f060 100644 --- a/src/System.Management.Automation/engine/ErrorPackage.cs +++ b/src/System.Management.Automation/engine/ErrorPackage.cs @@ -1129,7 +1129,7 @@ namespace System.Management.Automation { PopulateProperties(exception, targetObject, fullyQualifiedErrorId, errorCategory, errorCategory_Activity, errorCategory_Reason, errorCategory_TargetName, errorCategory_TargetType, - errorDetails_Message, errorDetails_Message, errorDetails_RecommendedAction, null); + errorCategory_Message, errorDetails_Message, errorDetails_RecommendedAction, null); } private void PopulateProperties(Exception exception, diff --git a/src/System.Management.Automation/engine/Modules/ImportModuleCommand.cs b/src/System.Management.Automation/engine/Modules/ImportModuleCommand.cs index acabd4f007..0382232a37 100644 --- a/src/System.Management.Automation/engine/Modules/ImportModuleCommand.cs +++ b/src/System.Management.Automation/engine/Modules/ImportModuleCommand.cs @@ -1660,7 +1660,7 @@ namespace Microsoft.PowerShell.Commands /// protected override void ProcessRecord() { - if (BaseMaximumVersion != null && BaseMaximumVersion != null && BaseMaximumVersion < BaseMinimumVersion) + if (BaseMaximumVersion != null && BaseMinimumVersion != null && BaseMaximumVersion < BaseMinimumVersion) { string message = StringUtil.Format(Modules.MinimumVersionAndMaximumVersionInvalidRange, BaseMinimumVersion, BaseMaximumVersion); throw new PSArgumentOutOfRangeException(message); diff --git a/src/System.Management.Automation/engine/SessionStateProviderAPIs.cs b/src/System.Management.Automation/engine/SessionStateProviderAPIs.cs index 3ef80291a7..2196458f4b 100644 --- a/src/System.Management.Automation/engine/SessionStateProviderAPIs.cs +++ b/src/System.Management.Automation/engine/SessionStateProviderAPIs.cs @@ -1001,7 +1001,7 @@ namespace System.Management.Automation { ProviderNotFoundException e = new ProviderNotFoundException( - providerName.ToString(), + "null", SessionStateCategory.CmdletProvider, "ProviderNotFound", SessionStateStrings.ProviderNotFound); diff --git a/src/System.Management.Automation/engine/hostifaces/RunspacePoolInternal.cs b/src/System.Management.Automation/engine/hostifaces/RunspacePoolInternal.cs index c332583fe8..fd65d9f59c 100644 --- a/src/System.Management.Automation/engine/hostifaces/RunspacePoolInternal.cs +++ b/src/System.Management.Automation/engine/hostifaces/RunspacePoolInternal.cs @@ -574,14 +574,14 @@ namespace System.Management.Automation.Runspaces.Internal int unUsedCapacity = (maxPoolSz - totalRunspaces) < 0 ? 0 : (maxPoolSz - totalRunspaces); return (pool.Count + unUsedCapacity); } - else if (stateInfo.State != RunspacePoolState.BeforeOpen && stateInfo.State != RunspacePoolState.Opening) - { - throw new InvalidOperationException(HostInterfaceExceptionsStrings.RunspacePoolNotOpened); - } else if (stateInfo.State == RunspacePoolState.Disconnected) { throw new InvalidOperationException(RunspacePoolStrings.CannotWhileDisconnected); } + else if (stateInfo.State != RunspacePoolState.BeforeOpen && stateInfo.State != RunspacePoolState.Opening) + { + throw new InvalidOperationException(HostInterfaceExceptionsStrings.RunspacePoolNotOpened); + } else { return maxPoolSz; diff --git a/src/System.Management.Automation/engine/parser/Parser.cs b/src/System.Management.Automation/engine/parser/Parser.cs index 7ebedd8cc7..65a45bcf68 100644 --- a/src/System.Management.Automation/engine/parser/Parser.cs +++ b/src/System.Management.Automation/engine/parser/Parser.cs @@ -4970,9 +4970,8 @@ namespace System.Management.Automation.Language } else { - errorAsts.Concat(exceptionTypes); + errorAsts.AddRange(exceptionTypes); } - // REVIEW: seems like some code is missing here, errorAsts isn't used } return null; } diff --git a/src/System.Management.Automation/engine/remoting/client/Job.cs b/src/System.Management.Automation/engine/remoting/client/Job.cs index ff3162e9d6..913d8587c7 100644 --- a/src/System.Management.Automation/engine/remoting/client/Job.cs +++ b/src/System.Management.Automation/engine/remoting/client/Job.cs @@ -1873,7 +1873,7 @@ namespace System.Management.Automation foreach (Job j in ChildJobs) { PSRemotingChildJob child = j as PSRemotingChildJob; - if (j == null) continue; + if (child == null) continue; if (String.Equals(child.Runspace.ConnectionInfo.ComputerName, computerName, StringComparison.OrdinalIgnoreCase)) { @@ -1897,7 +1897,7 @@ namespace System.Management.Automation foreach (Job j in ChildJobs) { PSRemotingChildJob child = j as PSRemotingChildJob; - if (j == null) continue; + if (child == null) continue; if (child.Runspace.InstanceId.Equals(runspace.InstanceId)) { returnJobList.Add(child); @@ -1920,7 +1920,7 @@ namespace System.Management.Automation foreach (Job j in ChildJobs) { PSRemotingChildJob child = j as PSRemotingChildJob; - if (j == null) continue; + if (child == null) continue; if (child.Helper.Equals(helper)) { returnJobList.Add(child); diff --git a/src/System.Management.Automation/engine/remoting/server/serverremotesession.cs b/src/System.Management.Automation/engine/remoting/server/serverremotesession.cs index 25fc3d3233..9157455b35 100644 --- a/src/System.Management.Automation/engine/remoting/server/serverremotesession.cs +++ b/src/System.Management.Automation/engine/remoting/server/serverremotesession.cs @@ -630,7 +630,7 @@ namespace System.Management.Automation.Remoting int clientRequestedMinRunspaces = -1; int clientRequestedMaxRunspaces = -1; bool clientRequestedRunspaceCount = false; - if (connectRunspacePoolObject.Data.Properties[RemoteDataNameStrings.MinRunspaces] != null && connectRunspacePoolObject.Data.Properties[RemoteDataNameStrings.MinRunspaces] != null) + if (connectRunspacePoolObject.Data.Properties[RemoteDataNameStrings.MinRunspaces] != null && connectRunspacePoolObject.Data.Properties[RemoteDataNameStrings.MaxRunspaces] != null) { try { diff --git a/src/System.Management.Automation/namespaces/FileSystemProvider.cs b/src/System.Management.Automation/namespaces/FileSystemProvider.cs index 8e94801295..607ef6e47c 100644 --- a/src/System.Management.Automation/namespaces/FileSystemProvider.cs +++ b/src/System.Management.Automation/namespaces/FileSystemProvider.cs @@ -4125,7 +4125,7 @@ namespace Microsoft.PowerShell.Commands { // Check if the remote source file has any alternate data streams ArrayList remoteFileStreams = GetRemoteSourceAlternateStreams(ps, sourceFileFullName); - if ((remoteFileStreams.Count > 0) && (remoteFileStreams != null)) + if ((remoteFileStreams != null) && (remoteFileStreams.Count > 0)) { foreach (string streamName in remoteFileStreams) { diff --git a/src/System.Management.Automation/utils/PowerShellETWTracer.cs b/src/System.Management.Automation/utils/PowerShellETWTracer.cs index b853d751d4..ad27026a80 100644 --- a/src/System.Management.Automation/utils/PowerShellETWTracer.cs +++ b/src/System.Management.Automation/utils/PowerShellETWTracer.cs @@ -1085,7 +1085,7 @@ namespace System.Management.Automation.Tracing { return DebugChannel.TraceDebug(PowerShellTraceEvent.Job, PowerShellTraceOperationCode.Method, PowerShellTraceTask.None, - job.Id.ToString(CultureInfo.InvariantCulture), job.InstanceId.ToString(), "NULL job"); + "", "", "NULL job"); } } From 3f99de5784c27123c171a977b40d3cd9d0fd0587 Mon Sep 17 00:00:00 2001 From: "James Truher [MSFT]" Date: Thu, 17 Nov 2016 11:46:07 -0800 Subject: [PATCH 06/11] Added tests to close code coverage in CIM area (#2528) * Added tests to close code coverage in CIM area Added CimAdapter.Tests for adaptation layer (code cribbed from BVT tests) Added SessionOption.Tests.ps1 (Code cribbed from BVT tests) Modified CimClass tests by adding more tests Added CimSession.Tests for basic tests of New-CimSession cmdlet Added CimInstance.Tests for basic tests of Get-CimInstance * Add CI tags to tests * unify test execution to use try/catch for marking tests as skipped moved test which retrieves cimclass via method to feature as it is not a common operation, this test can take some time as well --- .../Modules/CimCmdlets/CimInstance.Tests.ps1 | 41 +++++++++ .../Modules/CimCmdlets/CimSession.Tests.ps1 | 44 +++++++++ .../Modules/CimCmdlets/Get-CimClass.Tests.ps1 | 48 ++++++++-- .../engine/ETS/CimAdapter.Tests.ps1 | 90 +++++++++++++++++++ .../engine/Remoting/SessionOption.Tests.ps1 | 54 +++++++++++ 5 files changed, 272 insertions(+), 5 deletions(-) create mode 100644 test/powershell/Modules/CimCmdlets/CimInstance.Tests.ps1 create mode 100644 test/powershell/Modules/CimCmdlets/CimSession.Tests.ps1 create mode 100644 test/powershell/engine/ETS/CimAdapter.Tests.ps1 create mode 100644 test/powershell/engine/Remoting/SessionOption.Tests.ps1 diff --git a/test/powershell/Modules/CimCmdlets/CimInstance.Tests.ps1 b/test/powershell/Modules/CimCmdlets/CimInstance.Tests.ps1 new file mode 100644 index 0000000000..db5a5a32c2 --- /dev/null +++ b/test/powershell/Modules/CimCmdlets/CimInstance.Tests.ps1 @@ -0,0 +1,41 @@ +Try { + if ( ! $IsWindows ) { + $PSDefaultParameterValues['it:pending'] = $true + } + Describe "CimInstance cmdlet tests" -Tag @("CI") { + BeforeAll { + if ( ! $IsWindows ) { return } + $instance = get-ciminstance cim_computersystem + } + It "CimClass property should not be null" { + # we can't use equals here as on windows cimclassname + # is win32_computersystem, but that's not likely to be the + # case on non-Windows systems + $instance.cimClass.CimClassName | should match _computersystem + } + It "Property access should be case insensitive" { + foreach($property in $instance.psobject.properties.name) { + $pUpper = $property.ToUpper() + $pLower = $property.ToLower() + [string]$pLowerValue = $pinstance.$pLower -join "," + [string]$pUpperValue = $pinstance.$pUpper -join "," + $pLowerValue | should be $pUpperValue + } + } + It "GetCimSessionInstanceId method invocation should return data" { + $instance.GetCimSessionInstanceId() | Should BeOfType "Guid" + } + It "should produce an error for a non-existing classname" { + try { + get-ciminstance -classname thisnameshouldnotexist -ea stop + throw "expected error did not occur" + } + catch { + $_.FullyQualifiedErrorId | should be "HRESULT 0x80041010,Microsoft.Management.Infrastructure.CimCmdlets.GetCimInstanceCommand" + } + } + } +} +finally { + $PSDefaultParameterValues.Remove('it:pending') +} diff --git a/test/powershell/Modules/CimCmdlets/CimSession.Tests.ps1 b/test/powershell/Modules/CimCmdlets/CimSession.Tests.ps1 new file mode 100644 index 0000000000..c60063f17a --- /dev/null +++ b/test/powershell/Modules/CimCmdlets/CimSession.Tests.ps1 @@ -0,0 +1,44 @@ +try { + if ( ! $IsWindows ) { + $PSDefaultParameterValues['it:pending'] = $true + } + Describe "New-CimSession" -Tag @("CI") { + BeforeAll { + $sessions = @() + } + AfterEach { + try { + $sessions | remove-cimsession + } + finally { + $sessions = @() + } + } + It "A cim session can be created" { + $sessionName = [guid]::NewGuid() + $session = New-CimSession -ComputerName . -name $sessionName + $sessions += $session + $session.Name | Should be $sessionName + $session.InstanceId | should BeOfType "System.Guid" + } + It "A Cim session can be retrieved" { + $sessionName = [guid]::NewGuid() + $session = New-CimSession -ComputerName . -name $sessionName + $sessions += $session + (get-cimsession -Name $sessionName).InstanceId | should be $session.InstanceId + (get-cimsession -Id $session.Id).InstanceId | should be $session.InstanceId + (get-cimsession -InstanceId $session.InstanceId).InstanceId | should be $session.InstanceId + } + It "A cim session can be removed" { + $sessionName = [guid]::NewGuid() + $session = New-CimSession -ComputerName . -name $sessionName + $sessions += $session + $session.Name | Should be $sessionName + $session | Remove-CimSession + Get-CimSession $session.Id -ErrorAction SilentlyContinue | should BeNullOrEmpty + } + } +} +finally { + $PSDefaultParameterValues.remove('it:pending') +} diff --git a/test/powershell/Modules/CimCmdlets/Get-CimClass.Tests.ps1 b/test/powershell/Modules/CimCmdlets/Get-CimClass.Tests.ps1 index f6a48089ce..0751cf9d86 100644 --- a/test/powershell/Modules/CimCmdlets/Get-CimClass.Tests.ps1 +++ b/test/powershell/Modules/CimCmdlets/Get-CimClass.Tests.ps1 @@ -1,6 +1,44 @@ -Describe 'Get-CimClass' -tags "CI" { - # Get-CimClass works only on windows - It 'can get CIM_Error CIM class' -Skip:(-not $IsWindows) { - Get-CimClass -ClassName CIM_Error | Should Not Be $null +try { + # Get-CimClass works only on windows right now + if ( ! $IsWindows ) { + $PSDefaultParameterValues['it:pending'] = $true } -} + + Describe 'Get-CimClass' -tags "CI" { + It 'can get CIM_Error CIM class' { + Get-CimClass -ClassName CIM_Error | Should Not BeNullOrEmpty + } + It 'can get class when namespace is specified' { + Get-CimClass -ClassName CIM_OperatingSystem -Namespace root/cimv2 | Should Not BeNullOrEmpty + } + + It 'produces an error when a non-existent class is used' { + try { + Get-CimClass -ClassName thisclasstypedoesnotexist -ea stop + throw "Expected error did not occur" + } + catch { + $_.FullyQualifiedErrorId | should be "HRESULT 0x80041002,Microsoft.Management.Infrastructure.CimCmdlets.GetCimClassCommand" + } + } + It 'produces an error when an improper namespace is used' { + try { + Get-CimClass -ClassName CIM_OperatingSystem -Namespace badnamespace -ea stop + throw "Expected error did not occur" + } + catch { + $_.FullyQualifiedErrorId | should be "HRESULT 0x8004100e,Microsoft.Management.Infrastructure.CimCmdlets.GetCimClassCommand" + } + } + } + + # feature tests + Describe 'Get-CimClass' -tags @("Feature") { + It 'can retrieve a class when a method is provided' { + Get-CimClass -MethodName Reboot | Should Not BeNullOrEmpty + } + } +} +finally { + $PSDefaultParameterValues.Remove('it:pending') +} diff --git a/test/powershell/engine/ETS/CimAdapter.Tests.ps1 b/test/powershell/engine/ETS/CimAdapter.Tests.ps1 new file mode 100644 index 0000000000..c267ca51a4 --- /dev/null +++ b/test/powershell/engine/ETS/CimAdapter.Tests.ps1 @@ -0,0 +1,90 @@ +function getIndex +{ + param([string[]]$strings,[string]$pattern) + for ($i = 0; $i -lt $strings.Count; $i++) { + if ($strings[$i] -like $pattern) { + return $i + } + } + return -1 +} + +try { + if ( ! $IsWindows ) { + $PSDefaultParameterValues["it:pending"] = $true + } + Describe "CIM Objects are adapted properly" -Tag @("CI") { + BeforeAll { + if ( ! $IsWindows ) { + return + } + $p = get-ciminstance win32_process |Select-object -first 1 + + $indexOf_namespaceQualified_Win32Process = getIndex $p.PSTypeNames "*root?cimv2?Win32_Process" + $indexOf_namespaceQualified_CimProcess = getIndex $p.PSTypeNames "*root?cimv2?CIM_Process" + $indexOf_namespaceQualified_CimLogicalElement = getIndex $p.PSTypeNames "*root?cimv2?CIM_LogicalElement" + $indexOf_namespaceQualified_CimManagedSystemElement = getIndex $p.PSTypeNames "*root?cimv2?CIM_ManagedSystemElement" + + $indexOf_className_Win32Process = getIndex $p.PSTypeNames "*#Win32_Process" + $indexOf_className_CimProcess = getIndex $p.PSTypeNames "*#CIM_Process" + $indexOf_className_CimLogicalElement = getIndex $p.PSTypeNames "*#CIM_LogicalElement" + $indexOf_className_CimManagedSystemElement = getIndex $p.PSTypeNames "*#CIM_ManagedSystemElement" + } + AfterAll { + $PSDefaultParameterValues.Remove("it:pending") + } + + It "Namespace-qualified Win32_Process is present" -skip:(!$IsWindows) { + $indexOf_namespaceQualified_Win32Process |Should not Be (-1) + } + It "Namespace-qualified CIM_Process is present" { + $indexOf_namespaceQualified_CimProcess |Should not Be (-1) + } + It "Namespace-qualified CIM_LogicalElement is present" { + $indexOf_namespaceQualified_CimLogicalElement |Should not Be (-1) + } + It "Namespace-qualified CIM_ManagedSystemElement is present" { + $indexOf_namespaceQualified_CimManagedSystemElement |Should not Be (-1) + } + + It "Classname of Win32_Process is present" -skip:(!$IsWindows) { + $indexOf_className_Win32Process |Should not Be (-1) + } + It "Classname of CIM_Process is present" { + $indexOf_className_CimProcess |Should not Be (-1) + } + It "Classname of CIM_LogicalElement is present" { + $indexOf_className_CimLogicalElement |Should not Be (-1) + } + It "Classname of CIM_ManagedSystemElement is present" { + $indexOf_className_CimManagedSystemElement |Should not Be (-1) + } + + It "Win32_Process comes after CIM_Process (namespace qualified)" -skip:(!$IsWindows) { + $indexOf_namespaceQualified_Win32Process |should belessthan $indexOf_namespaceQualified_CimProcess + } + It "CIM_Process comes after CIM_LogicalElement (namespace qualified)" { + $indexOf_namespaceQualified_CimProcess |should belessthan $indexOf_namespaceQualified_CimLogicalElement + } + It "CIM_LogicalElement comes after CIM_ManagedSystemElement (namespace qualified)" { + $indexOf_namespaceQualified_CimLogicalElement |should belessthan $indexOf_namespaceQualified_CimManagedSystemElement + } + + It "Win32_Process comes after CIM_Process (classname only)" -skip:(!$IsWindows) { + $indexOf_className_Win32Process |should belessthan $indexOf_className_CimProcess + } + It "CIM_Process comes after CIM_LogicalElement (classname only)" { + $indexOf_className_CimProcess |should belessthan $indexOf_className_CimLogicalElement + } + It "CIM_LogicalElement comes after CIM_ManagedSystemElement (classname only)" { + $indexOf_className_CimLogicalElement |should belessthan $indexOf_className_CimManagedSystemElement + } + + It "Namespace qualified PSTypenames comes after class-only PSTypeNames" -skip:(!$IsWindows) { + $indexOf_namespaceQualified_CimManagedSystemElement |should belessthan $indexOf_className_Win32Process + } + } +} +finally { + $PSDefaultParameterValues.Remove("it:pending") +} diff --git a/test/powershell/engine/Remoting/SessionOption.Tests.ps1 b/test/powershell/engine/Remoting/SessionOption.Tests.ps1 new file mode 100644 index 0000000000..f0431b5649 --- /dev/null +++ b/test/powershell/engine/Remoting/SessionOption.Tests.ps1 @@ -0,0 +1,54 @@ +try { + if ( ! $IsWindows ) { + $PSDefaultParameterValues['it:skip'] = $true + } + Describe " WSMan SessionOption object" -Tag @("CI") { + It "The SessionOption type exists" { + "Microsoft.WSMan.Management.SessionOption" -as "Type" | Should Not BeNullOrEmpty + } + It "The SessionOption type can be created" { + $result = [Microsoft.WSMan.Management.SessionOption]::new() + $result | should BeOfType "Microsoft.WSMan.Management.SessionOption" + } + It "The SessionOption type has the proper properties when created with the default constructor" { + $result = [Microsoft.WSMan.Management.SessionOption]::new() + $result.SkipCACheck | should be $False + $result.SkipCNCheck | should be $False + $result.SkipRevocationCheck | should be $False + $result.UseEncryption | should be $True + $result.UseUtf16 | should be $False + $result.ProxyAuthentication | should be 0 + $result.SPNPort | should be 0 + $result.OperationTimeout | should be 0 + $result.ProxyCredential | should BeNullOrEmpty + $result.ProxyAccessType | should be ProxyIEConfig + } + It "The values of SessionOption may be set" { + $result = [Microsoft.WSMan.Management.SessionOption]::new() + $result.SkipCACheck = $true + $result.SkipCNCheck = $true + $result.SkipRevocationCheck = $true + $result.UseUtf16 = $True + $result.UseEncryption = $false + $result.ProxyAuthentication = "Negotiate" + $result.SPNPort = 10 + $result.OperationTimeout = 10 + $result.ProxyAccessType = "ProxyAutoDetect" + $result.ProxyCredential = [System.Net.NetworkCredential]::new("user","pass") + + $result.SkipCACheck | should be $true + $result.SkipCNCheck | should be $true + $result.SkipRevocationCheck | should be $true + $result.UseEncryption | should be $False + $result.UseUtf16 | should be $True + $result.ProxyAuthentication | should be "Negotiate" + $result.SPNPort | should be 10 + $result.OperationTimeout | should be 10 + $result.ProxyCredential | should Not BeNullOrEmpty + $result.ProxyAccessType | should be "ProxyAutoDetect" + } + } +} +finally { + $PSDefaultParameterValues.remove("it:skip") +} From ca0be9ad6103c1ef0b48b52ae0a85666f7bf2332 Mon Sep 17 00:00:00 2001 From: "James Truher [MSFT]" Date: Thu, 17 Nov 2016 11:59:55 -0800 Subject: [PATCH 07/11] Jameswtruher/dailytravis (#2696) * Add daily build code for travis A cron job needs to be created to start the build, and the variable TRAVIS_DAILY_BUILD must be set to true * Change environment variable to the one suggested by the travis-ci documentation TRAVIS_EVENT_TYPE == "cron" --- tools/travis.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/travis.sh b/tools/travis.sh index 24765d17e5..f3ffb724b2 100755 --- a/tools/travis.sh +++ b/tools/travis.sh @@ -1,7 +1,10 @@ set -x ulimit -n 4096 +# do this for our daily build test run +if [[ "$TRAVIS_EVENT_TYPE" == "cron" ]]; then + powershell -c "Import-Module ./build.psm1; Start-PSBootstrap; Start-PSBuild -CrossGen; Start-PSPester -Tag @('CI','Feature','Scenario') -ExcludeTag RequireAdminOnWindows; Start-PSxUnit" # Only build packages for branches, not pull requests -if [[ "$TRAVIS_PULL_REQUEST" == "false" ]]; then +elif [[ "$TRAVIS_PULL_REQUEST" == "false" ]]; then powershell -c "Import-Module ./build.psm1; Start-PSBootstrap -Package; Start-PSBuild -CrossGen; Start-PSPackage; Start-PSPester -ThrowOnFailure; Test-PSPesterResults; Start-PSxUnit" else powershell -c "Import-Module ./build.psm1; Start-PSBootstrap; Start-PSBuild -CrossGen; Start-PSPester -ThrowOnFailure; Start-PSxUnit" From 469924d855aba51a539b8a1ac8a2f6c9442283e4 Mon Sep 17 00:00:00 2001 From: iSazonov Date: Fri, 18 Nov 2016 06:29:04 +0600 Subject: [PATCH 08/11] Add support W3C Extended Log File Format in Import-Csv (#2482) * Add support W3C Extended Log File Format 1. Add support W3C Extended Log File Format 2. Refactoring Import-Csv tests 3. Add #Type tests * Fx test after review * Fix tests after review * Remove unneeded test --- .../commands/utility/CSVCommands.cs | 45 ++++--- .../Import-Csv.Tests.ps1 | 126 ++++++++++-------- .../assets/TestImportCsv_NoHeader.csv | 4 + .../assets/TestImportCsv_W3C_ELF.csv | 9 ++ ...stCsv.csv => TestImportCsv_WithHeader.csv} | 11 +- 5 files changed, 118 insertions(+), 77 deletions(-) create mode 100644 test/powershell/Modules/Microsoft.PowerShell.Utility/assets/TestImportCsv_NoHeader.csv create mode 100644 test/powershell/Modules/Microsoft.PowerShell.Utility/assets/TestImportCsv_W3C_ELF.csv rename test/powershell/Modules/Microsoft.PowerShell.Utility/assets/{TestCsv.csv => TestImportCsv_WithHeader.csv} (78%) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CSVCommands.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CSVCommands.cs index 377607e976..78a7825ef6 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CSVCommands.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/CSVCommands.cs @@ -1190,11 +1190,31 @@ namespace Microsoft.PowerShell.Commands TypeName = ReadTypeInformation(); } - if ((Header == null) && (!this.EOF)) + while ((Header == null) && (!this.EOF)) { - Collection values = ParseNextRecord(true); - if (values.Count != 0) + Collection values = ParseNextRecord(); + + // Trim all trailing blankspaces and delimiters ( single/multiple ). + // If there is only one element in the row and if its a blankspace we dont trim it. + // A trailing delimiter is represented as a blankspace while being added to result collection + // which is getting trimmed along with blankspaces supplied through the CSV in the below loop. + while (values.Count > 1 && values[values.Count - 1].Equals(string.Empty)) { + values.RemoveAt(values.Count - 1); + } + + // File starts with '#' and contains '#Fields:' is W3C Extended Log File Format + if (values.Count != 0 && values[0].StartsWith("#Fields: ")) + { + values[0] = values[0].Substring(9); + Header = values; + } else if (values.Count != 0 && values[0].StartsWith("#")) + { + // Skip all lines starting with '#' + } else + { + // This is not W3C Extended Log File Format + // By default first line is Header Header = values; } } @@ -1213,7 +1233,7 @@ namespace Microsoft.PowerShell.Commands ReadHeader(); while (true) { - Collection values = ParseNextRecord(false); + Collection values = ParseNextRecord(); if (values.Count == 0) break; @@ -1300,14 +1320,11 @@ namespace Microsoft.PowerShell.Commands /// Reads the next record from the file and returns parsed collection /// of string. /// - /// - /// Indicates if the parsed row is a header row or a values row. - /// /// /// Parsed collection of strings. /// private Collection - ParseNextRecord(bool isHeaderRow) + ParseNextRecord() { //Collection of strings to return Collection result = new Collection(); @@ -1471,18 +1488,6 @@ namespace Microsoft.PowerShell.Commands result.Add(current.ToString()); } - //Trim all trailing blankspaces and delimiters ( single/multiple ). - // If there is only one element in the row and if its a blankspace we dont trim it. - // A trailing delimiter is represented as a blankspace while being added to result collection - // which is getting trimmed along with blankspaces supplied through the CSV in the below loop. - if (isHeaderRow) - { - while (result.Count > 1 && result[result.Count - 1].Equals(string.Empty)) - { - result.RemoveAt(result.Count - 1); - } - } - return result; } diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/Import-Csv.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/Import-Csv.Tests.ps1 index ff8290d97d..11f6f099f3 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/Import-Csv.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/Import-Csv.Tests.ps1 @@ -1,55 +1,3 @@ -Describe "Import-Csv" -Tags "CI" { - $testCsv = Join-Path -Path (Join-Path $PSScriptRoot -ChildPath assets) -ChildPath TestCsv.csv - - It "Should be able to call without error" { - { Import-Csv $testCsv } | Should Not Throw - } - - It "Should be able to assign to a variable" { - $actual = Import-Csv $testCsv - - $actual | Should Not BeNullOrEmpty - $actual.GetType().BaseType | Should Be array - } - - It "Should have the data from the csv file" { - $actualContent = $(Get-Content $testCsv)[0] - $testContent = $($(Import-Csv $testCsv) | Get-Member) | ? { $_.MemberType -eq "NoteProperty" } | % { $_.Name } | Select-Object -First 1 - - $actualContent.IndexOf($testContent) | Should BeGreaterThan -1 - } - - It "Should be able to prepend a custom header" { - $header = "test1","test2","test3" - - $originalContent = $($(Import-Csv $testCsv) | Get-Member) | ? { $_.MemberType -eq "NoteProperty" } | % { $_.Name } | Select-Object -First 1 - - $testContent = $($(Import-Csv $testCsv -Header $header) | Get-Member) | ? { $_.MemberType -eq "NoteProperty" } | % { $_.Name } | Select-Object -First 3 - - # the original csv file doesn't contain the headers - $originalContent.IndexOf($header[0]) | Should Be -1 - - # but it does with the -Header switch! - $testContent[0] | Should Be $header[0] - $testContent[1] | Should Be $header[1] - $testContent[2] | Should Be $header[2] - } - - It "Should be able to use the alias without error" { - { Import-Csv $testCsv } | Should Not Throw - } - - It "Should have the same output between the alias and the full cmdlet name" { - $alias = $($(ipcsv $testCsv) | Get-Member) | ? { $_.MemberType -eq "NoteProperty" } | % { $_.Name } | Select-Object -First 1 - $cmdlet = $($(Import-Csv $testCsv) | Get-Member) | ? { $_.MemberType -eq "NoteProperty" } | % { $_.Name } | Select-Object -First 1 - - $alias[0] | Should Be $cmdlet[0] - $alias[1] | Should Be $cmdlet[1] - $alias[2] | Should Be $cmdlet[2] - - } -} - Describe "Import-Csv DRT Unit Tests" -Tags "CI" { BeforeAll { $fileToGenerate = Join-Path $TestDrive -ChildPath "importCSVTest.csv" @@ -71,3 +19,77 @@ Describe "Import-Csv DRT Unit Tests" -Tags "CI" { $returnObject.Second | Should Be 2 } } + +Describe "Import-Csv File Format Tests" -Tags "CI" { + BeforeAll { + # The file is w/o header + $TestImportCsv_NoHeader = Join-Path -Path (Join-Path $PSScriptRoot -ChildPath assets) -ChildPath TestImportCsv_NoHeader.csv + # The file is with header + $TestImportCsv_WithHeader = Join-Path -Path (Join-Path $PSScriptRoot -ChildPath assets) -ChildPath TestImportCsv_WithHeader.csv + # The file is W3C Extended Log File Format + $TestImportCsv_W3C_ELF = Join-Path -Path (Join-Path $PSScriptRoot -ChildPath assets) -ChildPath TestImportCsv_W3C_ELF.csv + + $testCSVfiles = $TestImportCsv_NoHeader, $TestImportCsv_WithHeader, $TestImportCsv_W3C_ELF + $orginalHeader = "Column1","Column2","Column 3" + $customHeader = "test1","test2","test3" + } + # Test set is the same for all file formats + foreach ($testCsv in $testCSVfiles) { + $FileName = (dir $testCsv).Name + Context "Next test file: $FileName" { + BeforeAll { + $CustomHeaderParams = @{Header = $customHeader; Delimiter = ","} + if ($FileName -eq "TestImportCsv_NoHeader.csv") { + # The file does not have header + # (w/o Delimiter here we get throw (bug?)) + $HeaderParams = @{Header = $orginalHeader; Delimiter = ","} + } else { + # The files have header + $HeaderParams = @{Delimiter = ","} + } + + } + + It "Should be able to import all fields" { + $actual = Import-Csv -Path $testCsv @HeaderParams + $actualfields = $actual[0].psobject.Properties.Name + $actualfields | Should Be $orginalHeader + } + + It "Should be able to import all fields with custom header" { + $actual = Import-Csv -Path $testCsv @CustomHeaderParams + $actualfields = $actual[0].psobject.Properties.Name + $actualfields | Should Be $customHeader + } + + It "Should be able to import correct values" { + $actual = Import-Csv -Path $testCsv @HeaderParams + $actual.count | Should Be 4 + $actual[0].'Column1' | Should Be "data1" + $actual[0].'Column2' | Should Be "1" + $actual[0].'Column 3' | Should Be "A" + } + + } + } +} + +Describe "Import-Csv #Type Tests" -Tags "CI" { + BeforeAll { + $testfile = Join-Path $TestDrive -ChildPath "testfile.csv" + Remove-Item -Path $testfile -Force -ErrorAction SilentlyContinue + $processlist = (Get-Process)[0..1] + $processlist | Export-Csv -Path $testfile -Force + # Import-Csv add "CSV:" before actual type + # (Why #HandleCount ? See Issue #1812) + $expectedProcessType = "CSV:System.Diagnostics.Process#HandleCount" + } + + It "Test import-csv import Object" { + $importObjectList = Import-Csv -Path $testfile + $processlist.Count | Should Be $importObjectList.Count + + $importType = $importObjectList[0].psobject.TypeNames[0] + $importType | Should Be $expectedProcessType + } +} diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/assets/TestImportCsv_NoHeader.csv b/test/powershell/Modules/Microsoft.PowerShell.Utility/assets/TestImportCsv_NoHeader.csv new file mode 100644 index 0000000000..192b997de1 --- /dev/null +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/assets/TestImportCsv_NoHeader.csv @@ -0,0 +1,4 @@ +data1,1,A +data2,2,B +data3,3,C +data4,4,D diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/assets/TestImportCsv_W3C_ELF.csv b/test/powershell/Modules/Microsoft.PowerShell.Utility/assets/TestImportCsv_W3C_ELF.csv new file mode 100644 index 0000000000..e1f13f3406 --- /dev/null +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/assets/TestImportCsv_W3C_ELF.csv @@ -0,0 +1,9 @@ +#Software: Microsoft Exchange Server +#Version: 15.0.0.0 +#Log-type: Transport Connectivity Log +#Date: 2016-09-16T23:30:07.338Z +#Fields: Column1,Column2,Column 3 +data1,1,A +data2,2,B +data3,3,C +data4,4,D diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/assets/TestCsv.csv b/test/powershell/Modules/Microsoft.PowerShell.Utility/assets/TestImportCsv_WithHeader.csv similarity index 78% rename from test/powershell/Modules/Microsoft.PowerShell.Utility/assets/TestCsv.csv rename to test/powershell/Modules/Microsoft.PowerShell.Utility/assets/TestImportCsv_WithHeader.csv index 73a63d8992..1517b02299 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/assets/TestCsv.csv +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/assets/TestImportCsv_WithHeader.csv @@ -1,5 +1,6 @@ -Column1,Column2,Column 3 -data1,1,A -data2,2,B -data3,3,C -data4,4,D +# Test comment +Column1,Column2,Column 3 +data1,1,A +data2,2,B +data3,3,C +data4,4,D From 4edde10fdad63e05a20b80174171cc9039b0eb07 Mon Sep 17 00:00:00 2001 From: iSazonov Date: Sat, 19 Nov 2016 04:00:26 +0600 Subject: [PATCH 09/11] Now Enum values definition have space-insensitive syntax (#2690) Fix to support whitespace after the `=` and before the value expression. --- .../engine/parser/Parser.cs | 34 ++++++++++++------- .../Classes/scripting.enums.tests.ps1 | 4 +-- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/System.Management.Automation/engine/parser/Parser.cs b/src/System.Management.Automation/engine/parser/Parser.cs index 65a45bcf68..1310b24952 100644 --- a/src/System.Management.Automation/engine/parser/Parser.cs +++ b/src/System.Management.Automation/engine/parser/Parser.cs @@ -4311,23 +4311,33 @@ namespace System.Management.Automation.Language IScriptExtent endExtent = enumeratorName.Extent; ExpressionAst initialValueAst = null; - var assignToken = PeekToken(); var missingInitializer = false; - if (assignToken.Kind == TokenKind.Equals) + var oldTokenizerMode = _tokenizer.Mode; + Token assignToken = null; + try { - SkipToken(); - initialValueAst = ExpressionRule(); - if (initialValueAst == null) + SetTokenizerMode(TokenizerMode.Expression); + assignToken = PeekToken(); + if (assignToken.Kind == TokenKind.Equals) { - ReportError(After(assignToken), () => ParserStrings.ExpectedValueExpression, assignToken.Kind.Text()); - endExtent = assignToken.Extent; - missingInitializer = true; - } - else - { - endExtent = initialValueAst.Extent; + SkipToken(); + initialValueAst = ExpressionRule(); + if (initialValueAst == null) + { + ReportError(After(assignToken), () => ParserStrings.ExpectedValueExpression, assignToken.Kind.Text()); + endExtent = assignToken.Extent; + missingInitializer = true; + } + else + { + endExtent = initialValueAst.Extent; + } } } + finally + { + SetTokenizerMode(oldTokenizerMode); + } Token terminatorToken = PeekToken(); if (terminatorToken.Kind != TokenKind.NewLine && terminatorToken.Kind != TokenKind.Semi && terminatorToken.Kind != TokenKind.RCurly) diff --git a/test/powershell/Language/Classes/scripting.enums.tests.ps1 b/test/powershell/Language/Classes/scripting.enums.tests.ps1 index fbca0604c0..f13b31be47 100644 --- a/test/powershell/Language/Classes/scripting.enums.tests.ps1 +++ b/test/powershell/Language/Classes/scripting.enums.tests.ps1 @@ -3,7 +3,6 @@ # Describe 'enums' -Tags "CI" { - Context 'basic enums' { enum E1 { @@ -62,9 +61,10 @@ Describe 'enums' -Tags "CI" { e0 = [E6]::e0 + 2 } + # Don't add space after 'e0 ='! Fix #2543 enum E6 { - e0 = 38 + e0 =38 } It 'E4 has correct value' { [E4]::e0 | Should Be ([E4]42) } From e37df9da62149910725b2139c676787bbc7fca0c Mon Sep 17 00:00:00 2001 From: Oisin Grehan Date: Fri, 18 Nov 2016 16:36:26 -0600 Subject: [PATCH 10/11] Guard against ReflectionTypeLoadException in InitializeTypeCache (#2549) --- .../engine/CommandCompletion/CompletionCompleters.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs b/src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs index 1c9256e4c2..6a6769fc51 100644 --- a/src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs +++ b/src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs @@ -5860,7 +5860,17 @@ namespace System.Management.Automation #region Process_LoadedAssemblies var assembliesExcludingPSGenerated = ClrFacade.GetAssemblies(); - var allPublicTypes = assembliesExcludingPSGenerated.SelectMany(assembly => assembly.GetTypes().Where(TypeResolver.IsPublic)); + var allPublicTypes = assembliesExcludingPSGenerated.SelectMany(assembly => + { + try + { + return assembly.GetTypes().Where(TypeResolver.IsPublic); + } + catch (ReflectionTypeLoadException) + { + } + return Type.EmptyTypes; + }); foreach (var type in allPublicTypes) { From 9e9dbeaa5a734d35d11384f54023dd9881acc40e Mon Sep 17 00:00:00 2001 From: Steve Lee Date: Fri, 18 Nov 2016 15:03:59 -0800 Subject: [PATCH 11/11] updates to opencover module to make it more user friendly and works on coreclr (#2702) * added type to returned objects replaced expand-ziparchive with call to Archive module added defaults to location of opencover.xml, opencover installation, powershell.exe, and location of tests updated error messages with corrective action replaced System.Net.WebClient call (not available on coreclr) with invoke-webrequest scoped change of executionpolicy to process when starting pester to avoid error if system policy is less restrictive updated version of module * addressing code review feedback - check for git before using - check for opencover.console in path - fixed path to code coverage build of PS * added Expand-ZipArchive back to support psv4 scenario --- test/tools/OpenCover/OpenCover.psd1 | 2 +- test/tools/OpenCover/OpenCover.psm1 | 64 ++++++++++++++++++----------- 2 files changed, 40 insertions(+), 26 deletions(-) diff --git a/test/tools/OpenCover/OpenCover.psd1 b/test/tools/OpenCover/OpenCover.psd1 index 93b3e68284..435070e865 100644 --- a/test/tools/OpenCover/OpenCover.psd1 +++ b/test/tools/OpenCover/OpenCover.psd1 @@ -1,6 +1,6 @@ @{ RootModule = 'OpenCover.psm1' -ModuleVersion = '1.0.0.0' +ModuleVersion = '1.1.0.0' GUID = '4eedcffd-26e8-4172-8aad-9b882c13d370' Author = 'Microsoft Corporation' CompanyName = 'Microsoft Corporation' diff --git a/test/tools/OpenCover/OpenCover.psm1 b/test/tools/OpenCover/OpenCover.psm1 index 99cadf921a..6bf0261cc6 100644 --- a/test/tools/OpenCover/OpenCover.psm1 +++ b/test/tools/OpenCover/OpenCover.psm1 @@ -1,5 +1,10 @@ #region privateFunctions +$script:psRepoPath = [string]::Empty +if ((Get-Command -Name 'git' -ErrorAction Ignore) -ne $Null) { + $script:psRepoPath = git rev-parse --show-toplevel +} + function Get-AssemblyCoverageData([xml.xmlelement] $element) { $coverageSummary = (Get-CoverageSummary -element $element.Summary) @@ -11,7 +16,8 @@ function Get-AssemblyCoverageData([xml.xmlelement] $element) } $AssemblyCoverageData | Add-Member -MemberType ScriptMethod -Name ToString -Value { "{0} ({1})" -f $this.AssemblyName,$this.CoverageSummary.BranchCoverage } -Force - + $AssemblyCoverageData.PSTypeNames.Insert(0,"OpenCover.AssemblyCoverageData") + return $AssemblyCoverageData } @@ -48,6 +54,7 @@ function Get-CodeCoverageChange($r1, $r2) SequenceDelta = [double] ($r2.Summary.SequenceCoverage - $r1.Summary.SequenceCoverage) Deltas = $Deltas } + $CoverageChange.PSTypeNames.Insert(0,"OpenCover.CoverageChange") return $CoverageChange } @@ -72,6 +79,7 @@ function Get-AssemblyCoverageChange($r1, $r2) Sequence = $r2.Sequence SequenceDelta = $r2.Sequence - $r1.Sequence } + $AssemblyCoverageChange.PSTypeNames.Insert(0,"OpenCover.AssemblyCoverageChange") return $AssemblyCoverageChange } @@ -91,6 +99,7 @@ function Get-CoverageData($xmlPath) CoverageSummary = (Get-CoverageSummary -element $CoverageXml.CoverageSession.Summary) Assembly = $assemblies } + $CoverageData.PSTypeNames.Insert(0,"OpenCover.CoverageData") $null = $CoverageXml @@ -118,10 +127,12 @@ function Get-CoverageSummary([xml.xmlelement] $element) } $CoverageSummary | Add-Member -MemberType ScriptMethod -Name ToString -Value { "Branch:{0,3} Sequence:{1,3}" -f $this.BranchCoverage,$this.SequenceCoverage } -Force - + $CoverageSummary.PSTypeNames.Insert(0,"OpenCover.CoverageSummary") + return $CoverageSummary } +# needed for PowerShell v4 as Archive module isn't available by default function Expand-ZipArchive([string] $Path, [string] $DestinationPath) { try @@ -209,7 +220,7 @@ function Expand-ZipArchive([string] $Path, [string] $DestinationPath) #> function Get-CodeCoverage { - param ( [string]$CoverageXmlFile ) + param ( [string]$CoverageXmlFile = "$pwd/OpenCover.xml" ) $xmlPath = (get-item $CoverageXmlFile).Fullname (Get-CoverageData -xmlPath $xmlPath) } @@ -306,22 +317,22 @@ function Install-OpenCover { param ( [parameter()][string]$Version = "4.6.519", - [parameter(Mandatory=$true)][string]$TargetDirectory, + [parameter()][string]$TargetDirectory = "~/", [parameter()][switch]$Force ) - $webclient = New-Object System.Net.WebClient $filename = "opencover.${version}.zip" + $tempPath = "$env:TEMP/$Filename" $packageUrl = "https://github.com/OpenCover/opencover/releases/download/${version}/${filename}" - if ( test-path $env:TEMP/$Filename ) + if ( test-path $tempPath ) { if ( $force ) { - remove-item -force "$env:TEMP/$Filename" + remove-item -force $tempPath } else { - throw "package already exists at $env:TEMP/$Filename, not downloading" + throw "Package already exists at $tempPath, not continuing. Use -force to re-install" } } if ( test-path "$TargetDirectory/OpenCover" ) @@ -332,18 +343,24 @@ function Install-OpenCover } else { - throw "$TargetDirectory/OpenCover exists" + throw "$TargetDirectory/OpenCover exists, not continuing. Use -force to re-install" } } - $webclient.DownloadFile($packageUrl, "$env:TEMP/$filename") - if ( ! (test-path $env:TEMP/$Filename) ) + Invoke-WebRequest -Uri $packageUrl -OutFile "$tempPath" + if ( ! (test-path $tempPath) ) { throw "Download failed: $packageUrl" } import-module Microsoft.PowerShell.Archive - Expand-ZipArchive -Path "$env:TEMP/$filename" -DestinationPath "$TargetDirectory/OpenCover" + + if ((Get-Command Expand-Archive -ErrorAction Ignore) -ne $null) { + Expand-Archive -Path $tempPath -DestinationPath "$TargetDirectory/OpenCover" + } else { + Expand-ZipArchive -Path $tempPath -DestinationPath "$TargetDirectory/OpenCover" + } + Remove-Item -force $tempPath } <# @@ -359,26 +376,23 @@ function Invoke-OpenCover [CmdletBinding(SupportsShouldProcess=$true)] param ( [parameter()]$OutputLog = "$pwd/OpenCover.xml", - [parameter(Mandatory=$true)]$TestDirectory, - [parameter()]$OpenCoverPath, - [parameter(Mandatory=$true)]$PowerShellExeDirectory, + [parameter()]$TestDirectory = "$($script:psRepoPath)/test/powershell", + [parameter()]$OpenCoverPath = "~/OpenCover", + [parameter()]$PowerShellExeDirectory = "$($script:psRepoPath)/src/powershell-win-core/bin/CodeCoverage/netcoreapp1.0/win10-x64", [switch]$CIOnly ) # check to be sure that OpenCover is present - if(-not $PSBoundParameters.ContainsKey('OpenCoverPath')) - { - $openCoverBin = (Get-Command -Name 'opencover.console' -ErrorAction Ignore).Source - } - else - { - $OpenCoverBin = "$OpenCoverPath\opencover.console.exe" - } + $OpenCoverBin = "$OpenCoverPath\opencover.console.exe" if ( ! (test-path $OpenCoverBin)) { - throw "$OpenCoverBin does not exist" + # see if it's somewhere else in the path + $openCoverBin = (Get-Command -Name 'opencover.console' -ErrorAction Ignore).Source + if ($openCoverBin -eq $null) { + throw "$OpenCoverBin does not exist" + } } # check to be sure that powershell.exe is present @@ -389,7 +403,7 @@ function Invoke-OpenCover } # create the arguments for OpenCover - $targetArgs = "-c", "Set-ExecutionPolicy Bypass -Force;", "Invoke-Pester","${TestDirectory}" + $targetArgs = "-c", "Set-ExecutionPolicy Bypass -Force -Scope Process;", "Invoke-Pester","${TestDirectory}" if ( $CIOnly ) {