Consolidated the two test exes into one (#3982)
Combined the previous echoargs and createchildprocess test exes into a single TestExe that can be extended for other tests.
This commit is contained in:
parent
65f96e0298
commit
ea0082ab8d
14
build.psm1
14
build.psm1
|
@ -696,25 +696,31 @@ function Publish-PSTestTools {
|
|||
|
||||
Find-Dotnet
|
||||
|
||||
$tools = @("$PSScriptRoot/test/tools/EchoArgs", "echoargs"), @("$PSScriptRoot/test/tools/CreateChildProcess", "createchildprocess")
|
||||
$tools = @(
|
||||
@{Path="${PSScriptRoot}/test/tools/TestExe";Output="testexe"}
|
||||
)
|
||||
if ($Options -eq $null)
|
||||
{
|
||||
$Options = New-PSOptions
|
||||
}
|
||||
|
||||
# Publish EchoArgs so it can be run by tests
|
||||
# Publish tools so it can be run by tests
|
||||
foreach ($tool in $tools)
|
||||
{
|
||||
Push-Location $tool[0]
|
||||
Push-Location $tool.Path
|
||||
try {
|
||||
dotnet publish --output bin --configuration $Options.Configuration --framework $Options.Framework --runtime $Options.Runtime
|
||||
$toolPath = Join-Path -Path $tool.Path -ChildPath "bin"
|
||||
|
||||
# add 'x' permission when building the standalone application
|
||||
# this is temporary workaround to a bug in dotnet.exe, tracking by dotnet/cli issue #6286
|
||||
if ($Options.Configuration -eq "Linux") {
|
||||
$executable = Join-Path -Path $tool[0] -ChildPath "bin/$($tool[1])"
|
||||
$executable = Join-Path -Path $toolPath -ChildPath "$($tool.Output)"
|
||||
chmod u+x $executable
|
||||
}
|
||||
if ( $env:PATH -notcontains $toolPath ) {
|
||||
$env:PATH = $toolPath+$TestModulePathSeparator+$($env:PATH)
|
||||
}
|
||||
} finally {
|
||||
Pop-Location
|
||||
}
|
||||
|
|
|
@ -1,41 +1,34 @@
|
|||
Describe "Native Command Arguments" -tags "CI" {
|
||||
# Find where test/powershell is so we can find the echoargs command relative to it
|
||||
$powershellTestDir = $PSScriptRoot
|
||||
while ($powershellTestDir -notmatch 'test[\\/]powershell$') {
|
||||
$powershellTestDir = Split-Path $powershellTestDir
|
||||
}
|
||||
$echoArgs = Join-Path (Split-Path $powershellTestDir) tools/EchoArgs/bin/echoargs
|
||||
|
||||
# When passing arguments to native commands, quoted segments that contain
|
||||
# spaces need to be quoted with '"' characters when they are passed to the
|
||||
# native command (or to bash or sh on Linux).
|
||||
#
|
||||
# This test checks that the proper quoting is occuring by passing arguments
|
||||
# to the echoargs native command and looking at how it got the arguments.
|
||||
It "Should handle quoted spaces correctly" {
|
||||
$a = 'a"b c"d'
|
||||
$lines = & $echoArgs $a 'a"b c"d' a"b c"d
|
||||
($lines | measure).Count | Should Be 3
|
||||
$lines[0] | Should Be 'Arg 0 is <ab cd>'
|
||||
$lines[1] | Should Be 'Arg 1 is <ab cd>'
|
||||
$lines[2] | Should Be 'Arg 2 is <ab cd>'
|
||||
}
|
||||
|
||||
# In order to pass '"' characters so they are actually part of command line
|
||||
# arguments for native commands, they need to be escaped with a '\' (this
|
||||
# is in addition to the '`' escaping needed inside '"' quoted strings in
|
||||
# PowerShell).
|
||||
#
|
||||
# This functionality was broken in PowerShell 5.0 and 5.1, so this test
|
||||
# will fail on those versions unless the fix is backported to them.
|
||||
#
|
||||
# This test checks that the proper quoting and escaping is occurring by
|
||||
# passing arguments with escaped quotes to the echoargs native command and
|
||||
# looking at how it got the arguments.
|
||||
It "Should handle spaces between escaped quotes" {
|
||||
$lines = & $echoArgs 'a\"b c\"d' "a\`"b c\`"d"
|
||||
($lines | measure).Count | Should Be 2
|
||||
$lines[0] | Should Be 'Arg 0 is <a"b c"d>'
|
||||
$lines[1] | Should Be 'Arg 1 is <a"b c"d>'
|
||||
}
|
||||
}
|
||||
Describe "Native Command Arguments" -tags "CI" {
|
||||
# When passing arguments to native commands, quoted segments that contain
|
||||
# spaces need to be quoted with '"' characters when they are passed to the
|
||||
# native command (or to bash or sh on Linux).
|
||||
#
|
||||
# This test checks that the proper quoting is occuring by passing arguments
|
||||
# to the testexe native command and looking at how it got the arguments.
|
||||
It "Should handle quoted spaces correctly" {
|
||||
$a = 'a"b c"d'
|
||||
$lines = testexe -echoargs $a 'a"b c"d' a"b c"d
|
||||
($lines | measure).Count | Should Be 3
|
||||
$lines[0] | Should Be 'Arg 0 is <ab cd>'
|
||||
$lines[1] | Should Be 'Arg 1 is <ab cd>'
|
||||
$lines[2] | Should Be 'Arg 2 is <ab cd>'
|
||||
}
|
||||
|
||||
# In order to pass '"' characters so they are actually part of command line
|
||||
# arguments for native commands, they need to be escaped with a '\' (this
|
||||
# is in addition to the '`' escaping needed inside '"' quoted strings in
|
||||
# PowerShell).
|
||||
#
|
||||
# This functionality was broken in PowerShell 5.0 and 5.1, so this test
|
||||
# will fail on those versions unless the fix is backported to them.
|
||||
#
|
||||
# This test checks that the proper quoting and escaping is occurring by
|
||||
# passing arguments with escaped quotes to the testexe native command and
|
||||
# looking at how it got the arguments.
|
||||
It "Should handle spaces between escaped quotes" {
|
||||
$lines = testexe -echoargs 'a\"b c\"d' "a\`"b c\`"d"
|
||||
($lines | measure).Count | Should Be 2
|
||||
$lines[0] | Should Be 'Arg 0 is <a"b c"d>'
|
||||
$lines[1] | Should Be 'Arg 1 is <a"b c"d>'
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,35 +27,25 @@ Describe 'native commands lifecycle' -tags 'Feature' {
|
|||
|
||||
Describe "Native Command Processor" -tags "Feature" {
|
||||
|
||||
BeforeAll {
|
||||
# Find where test/powershell is so we can find the createchildprocess command relative to it
|
||||
$powershellTestDir = $PSScriptRoot
|
||||
while ($powershellTestDir -notmatch 'test[\\/]powershell$') {
|
||||
$powershellTestDir = Split-Path $powershellTestDir
|
||||
}
|
||||
$createchildprocess = Join-Path (Split-Path $powershellTestDir) tools/CreateChildProcess/bin/createchildprocess
|
||||
}
|
||||
|
||||
# If powershell receives a StopProcessing, it should kill the native process and all child processes
|
||||
|
||||
# this test should pass and no longer Pending when #2561 is fixed
|
||||
It "Should kill native process tree" -Pending {
|
||||
|
||||
# make sure no test processes are running
|
||||
# on Linux, the Process class truncates the name so filter using Where-Object
|
||||
Get-Process | Where-Object {$_.Name -like 'createchildproc*'} | Stop-Process
|
||||
Get-Process testexe -ErrorAction SilentlyContinue | Stop-Process
|
||||
|
||||
[int] $numToCreate = 2
|
||||
|
||||
$ps = [PowerShell]::Create().AddCommand($createchildprocess)
|
||||
$ps.AddParameter($numToCreate)
|
||||
$ps = [PowerShell]::Create().AddCommand("testexe")
|
||||
$ps.AddArgument("-createchildprocess")
|
||||
$ps.AddArgument($numToCreate)
|
||||
$async = $ps.BeginInvoke()
|
||||
$ps.InvocationStateInfo.State | Should Be "Running"
|
||||
|
||||
[bool] $childrenCreated = $false
|
||||
while (-not $childrenCreated)
|
||||
{
|
||||
$childprocesses = Get-Process | Where-Object {$_.Name -like 'createchildproc*'}
|
||||
$childprocesses = Get-Process testexe -ErrorAction SilentlyContinue
|
||||
if ($childprocesses.count -eq $numToCreate+1)
|
||||
{
|
||||
$childrenCreated = $true
|
||||
|
@ -72,7 +62,7 @@ Describe "Native Command Processor" -tags "Feature" {
|
|||
break
|
||||
}
|
||||
}
|
||||
$childprocesses = Get-Process | Where-Object {$_.Name -like 'createchildproc*'}
|
||||
$childprocesses = Get-Process testexe
|
||||
$count = $childprocesses.count
|
||||
$childprocesses | Stop-Process
|
||||
$count | Should Be 0
|
||||
|
|
|
@ -1,70 +1,63 @@
|
|||
Describe "Native streams behavior with PowerShell" -Tags 'CI' {
|
||||
$powershell = Join-Path -Path $PsHome -ChildPath "powershell"
|
||||
|
||||
Context "Error stream" {
|
||||
# we are using powershell itself as an example of a native program.
|
||||
# we can create a behavior we want on the fly and test complex scenarios.
|
||||
|
||||
$error.Clear()
|
||||
|
||||
$command = [string]::Join('', @(
|
||||
'[Console]::Error.Write(\"foo`n`nbar`n`nbaz\"); ',
|
||||
'[Console]::Error.Write(\"middle\"); ',
|
||||
'[Console]::Error.Write(\"foo`n`nbar`n`nbaz\")'
|
||||
))
|
||||
|
||||
$out = & $powershell -noprofile -command $command 2>&1
|
||||
|
||||
# this check should be the first one, because $error is a global shared variable
|
||||
It 'should not add records to $error variable' {
|
||||
# we are keeping existing Windows PS v5.1 behavior for $error variable
|
||||
$error.Count | Should Be 9
|
||||
}
|
||||
|
||||
It 'uses ErrorRecord object to return stderr output' {
|
||||
($out | measure).Count | Should BeGreaterThan 1
|
||||
|
||||
$out[0] | Should BeOfType 'System.Management.Automation.ErrorRecord'
|
||||
$out[0].FullyQualifiedErrorId | Should Be 'NativeCommandError'
|
||||
|
||||
$out | Select-Object -Skip 1 | % {
|
||||
$_ | Should BeOfType 'System.Management.Automation.ErrorRecord'
|
||||
$_.FullyQualifiedErrorId | Should Be 'NativeCommandErrorMessage'
|
||||
}
|
||||
}
|
||||
|
||||
It 'uses correct exception messages for error stream' {
|
||||
($out | measure).Count | Should Be 9
|
||||
$out[0].Exception.Message | Should Be 'foo'
|
||||
$out[1].Exception.Message | Should Be ''
|
||||
$out[2].Exception.Message | Should Be 'bar'
|
||||
$out[3].Exception.Message | Should Be ''
|
||||
$out[4].Exception.Message | Should Be 'bazmiddlefoo'
|
||||
$out[5].Exception.Message | Should Be ''
|
||||
$out[6].Exception.Message | Should Be 'bar'
|
||||
$out[7].Exception.Message | Should Be ''
|
||||
$out[8].Exception.Message | Should Be 'baz'
|
||||
}
|
||||
|
||||
It 'preserves error stream as is with Out-String' {
|
||||
($out | Out-String).Replace("`r", '') | Should Be "foo`n`nbar`n`nbazmiddlefoo`n`nbar`n`nbaz`n"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Describe 'piping powershell objects to finished native executable' -Tags 'CI' {
|
||||
# Find where test/powershell is so we can find the echoargs command relative to it
|
||||
$powershellTestDir = $PSScriptRoot
|
||||
while ($powershellTestDir -notmatch 'test[\\/]powershell$') {
|
||||
$powershellTestDir = Split-Path $powershellTestDir
|
||||
}
|
||||
$echoArgs = Join-Path (Split-Path $powershellTestDir) tools/EchoArgs/bin/echoargs
|
||||
|
||||
It 'doesn''t throw any exceptions, when we are piping to the closed executable' {
|
||||
1..3 | % {
|
||||
Start-Sleep -Milliseconds 100
|
||||
# yeild some multi-line formatted object
|
||||
@{'a' = 'b'}
|
||||
} | & $echoArgs | Should Be $null
|
||||
}
|
||||
}
|
||||
Describe "Native streams behavior with PowerShell" -Tags 'CI' {
|
||||
$powershell = Join-Path -Path $PsHome -ChildPath "powershell"
|
||||
|
||||
Context "Error stream" {
|
||||
# we are using powershell itself as an example of a native program.
|
||||
# we can create a behavior we want on the fly and test complex scenarios.
|
||||
|
||||
$error.Clear()
|
||||
|
||||
$command = [string]::Join('', @(
|
||||
'[Console]::Error.Write(\"foo`n`nbar`n`nbaz\"); ',
|
||||
'[Console]::Error.Write(\"middle\"); ',
|
||||
'[Console]::Error.Write(\"foo`n`nbar`n`nbaz\")'
|
||||
))
|
||||
|
||||
$out = & $powershell -noprofile -command $command 2>&1
|
||||
|
||||
# this check should be the first one, because $error is a global shared variable
|
||||
It 'should not add records to $error variable' {
|
||||
# we are keeping existing Windows PS v5.1 behavior for $error variable
|
||||
$error.Count | Should Be 9
|
||||
}
|
||||
|
||||
It 'uses ErrorRecord object to return stderr output' {
|
||||
($out | measure).Count | Should BeGreaterThan 1
|
||||
|
||||
$out[0] | Should BeOfType 'System.Management.Automation.ErrorRecord'
|
||||
$out[0].FullyQualifiedErrorId | Should Be 'NativeCommandError'
|
||||
|
||||
$out | Select-Object -Skip 1 | % {
|
||||
$_ | Should BeOfType 'System.Management.Automation.ErrorRecord'
|
||||
$_.FullyQualifiedErrorId | Should Be 'NativeCommandErrorMessage'
|
||||
}
|
||||
}
|
||||
|
||||
It 'uses correct exception messages for error stream' {
|
||||
($out | measure).Count | Should Be 9
|
||||
$out[0].Exception.Message | Should Be 'foo'
|
||||
$out[1].Exception.Message | Should Be ''
|
||||
$out[2].Exception.Message | Should Be 'bar'
|
||||
$out[3].Exception.Message | Should Be ''
|
||||
$out[4].Exception.Message | Should Be 'bazmiddlefoo'
|
||||
$out[5].Exception.Message | Should Be ''
|
||||
$out[6].Exception.Message | Should Be 'bar'
|
||||
$out[7].Exception.Message | Should Be ''
|
||||
$out[8].Exception.Message | Should Be 'baz'
|
||||
}
|
||||
|
||||
It 'preserves error stream as is with Out-String' {
|
||||
($out | Out-String).Replace("`r", '') | Should Be "foo`n`nbar`n`nbazmiddlefoo`n`nbar`n`nbaz`n"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Describe 'piping powershell objects to finished native executable' -Tags 'CI' {
|
||||
It 'doesn''t throw any exceptions, when we are piping to the closed executable' {
|
||||
1..3 | % {
|
||||
Start-Sleep -Milliseconds 100
|
||||
# yeild some multi-line formatted object
|
||||
@{'a' = 'b'}
|
||||
} | testexe -echoargs | Should Be $null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
|
||||
namespace CreateChildProcess
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
if (args.Length > 0)
|
||||
{
|
||||
uint num = UInt32.Parse(args[0]);
|
||||
for (uint i = 0; i < num; i++)
|
||||
{
|
||||
Process child = new Process();
|
||||
child.StartInfo.FileName = Process.GetCurrentProcess().MainModule.FileName;
|
||||
child.Start();
|
||||
}
|
||||
}
|
||||
// sleep is needed so the process doesn't exit before the test case kill it
|
||||
Thread.Sleep(100000);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Description>Very simple little console app that creates child processes of itself</Description>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<AssemblyName>createchildprocess</AssemblyName>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RuntimeIdentifiers>ubuntu.16.04-x64;ubuntu.14.04-x64;debian.8-x64;centos.7-x64;fedora.24-x64;win7-x86;win7-x64;win81-x64;win10-x64;osx.10.11-x64;osx.10.12-x64;opensuse.13.2-x64;opensuse.42.1-x64</RuntimeIdentifiers>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
|
@ -1,25 +0,0 @@
|
|||
//---------------------------------------------------------------------
|
||||
// Author: Keith Hill
|
||||
// Source: https://github.com/Pscx/Pscx/blob/master/Src/EchoArgs/EchoArgs.cs
|
||||
//
|
||||
// Description: Very simple little console class that you can use to see
|
||||
// how PowerShell is passing parameters to legacy console
|
||||
// apps.
|
||||
//
|
||||
// Creation Date: March 06, 2006
|
||||
//---------------------------------------------------------------------
|
||||
using System;
|
||||
|
||||
namespace Pscx.Applications
|
||||
{
|
||||
class EchoArgs
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
for (int i = 0; i < args.Length; i++)
|
||||
{
|
||||
Console.WriteLine("Arg {0} is <{1}>", i, args[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
64
test/tools/TestExe/TestExe.cs
Normal file
64
test/tools/TestExe/TestExe.cs
Normal file
|
@ -0,0 +1,64 @@
|
|||
using System;
|
||||
using System.Threading;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace TestExe
|
||||
{
|
||||
class TestExe
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
if (args.Length > 0)
|
||||
{
|
||||
switch(args[0].ToLowerInvariant())
|
||||
{
|
||||
case "-echoargs":
|
||||
EchoArgs(args);
|
||||
break;
|
||||
case "-createchildprocess":
|
||||
CreateChildProcess(args);
|
||||
break;
|
||||
default:
|
||||
Console.WriteLine("Unknown test {0}", args[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Test not specified");
|
||||
}
|
||||
}
|
||||
|
||||
// <Summary>
|
||||
// Echos back to stdout the arguments passed in
|
||||
// </Summary>
|
||||
static void EchoArgs(string[] args)
|
||||
{
|
||||
for (int i = 1; i < args.Length; i++)
|
||||
{
|
||||
Console.WriteLine("Arg {0} is <{1}>", i-1, args[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// <Summary>
|
||||
// First argument is the number of child processes to create which are instances of itself
|
||||
// Processes automatically exit after 100 seconds
|
||||
// </Summary>
|
||||
static void CreateChildProcess(string[] args)
|
||||
{
|
||||
if (args.Length > 1)
|
||||
{
|
||||
uint num = UInt32.Parse(args[1]);
|
||||
for (uint i = 0; i < num; i++)
|
||||
{
|
||||
Process child = new Process();
|
||||
child.StartInfo.FileName = Process.GetCurrentProcess().MainModule.FileName;
|
||||
child.StartInfo.Arguments = "-createchildprocess";
|
||||
child.Start();
|
||||
}
|
||||
}
|
||||
// sleep is needed so the process doesn't exit before the test case kill it
|
||||
Thread.Sleep(100000);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Description>Very simple little console class that you can use to see how PowerShell is passing parameters to legacy console apps.</Description>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<AssemblyName>echoargs</AssemblyName>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RuntimeIdentifiers>ubuntu.16.04-x64;ubuntu.14.04-x64;debian.8-x64;centos.7-x64;fedora.24-x64;win7-x86;win7-x64;win81-x64;win10-x64;osx.10.11-x64;osx.10.12-x64;opensuse.13.2-x64;opensuse.42.1-x64</RuntimeIdentifiers>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Description>Very simple little console class that you can use to for testing PowerShell interaction with native commands</Description>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<AssemblyName>testexe</AssemblyName>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RuntimeIdentifiers>ubuntu.16.04-x64;ubuntu.14.04-x64;debian.8-x64;centos.7-x64;fedora.24-x64;win7-x86;win7-x64;win81-x64;win10-x64;osx.10.11-x64;osx.10.12-x64;opensuse.13.2-x64;opensuse.42.1-x64</RuntimeIdentifiers>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
Loading…
Reference in a new issue