MegaBites-AI/Windows-powershell
0372
1# Copyright (c) Microsoft Corporation.2# Licensed under the MIT License.3Describe "XmlCommand DRT basic functionality Tests" -Tags "CI" {4 5 BeforeAll {6 if(-not ('IsHiddenTestType' -as "type"))7 {8 Add-Type -TypeDefinition @"9 public class IsHiddenTestType10 {11 public IsHiddenTestType()12 {13 Property1 = 1;14 Property2 = "some string";15 }16 17 public IsHiddenTestType(int val, string data)18 {19 Property1 = val;20 Property2 = data;21 }22 23 public int Property1;24 public string Property2;25 }26"@27 }28 29 class Four30 {31 [int] $num = 4;32 }33 34 class Three35 {36 [Four] $four = [Four]::New();37 [int] $num = 3;38 }39 40 class Two41 {42 [Three] $three = [Three]::New();43 [int] $value = 2;44 }45 46 class One47 {48 [Two] $two = [Two]::New();49 [int] $value = 1;50 }51 }52 53 BeforeEach {54 $testfile = Join-Path -Path $TestDrive -ChildPath "clixml-directive.xml"55 }56 57 AfterEach {58 Remove-Item $testfile -Force -ErrorAction SilentlyContinue59 }60 61 It "Import with CliXml directive should work" {62 Get-Command export* -Type Cmdlet | Select-Object -First 3 | Export-Clixml -Path $testfile63 $results = Import-Clixml $testfile64 $results.Count | Should -BeExactly 365 $results[0].PSTypeNames[0] | Should -Be "Deserialized.System.Management.Automation.CmdletInfo"66 }67 68 It "Import with Rehydration should work" {69 $property1 = 25670 $property2 = "abcdef"71 $isHiddenTestType = [IsHiddenTestType]::New($property1,$property2)72 $isHiddenTestType | Export-Clixml $testfile73 $results = Import-Clixml $testfile74 $results.Property1 | Should -Be $property175 $results.Property2 | Should -Be $property276 }77 78 It "Import Hashtable from exported non-ordered dictionary object should create non-ordered dictionary object" {79 $dict = @{}80 $dict['Larry'] = 'Poik!'81 $dict['Curly'] = 'Nyuk!'82 $dict['Moe'] = 'Wise guy!'83 $dict['larry'] = 'poik!'84 $dict['curly'] = 'nyuk!'85 $dict['moe'] = 'wise guy!'86 $dict.Count | Should -Be 387 $dict | Export-Clixml $testfile88 $results = Import-Clixml $testfile89 $results.GetType().Name | Should -BeExactly "Hashtable"90 $results.Count | Should -Be 391 }92 93 It "Import OrderedDictionary from exported ordered dictionary object should create ordered dictionary object" {94 $dict = [ordered]@{}95 $dict['Larry'] = 'Poik!'96 $dict['Curly'] = 'Nyuk!'97 $dict['Moe'] = 'Wise guy!'98 $dict['larry'] = 'poik!'99 $dict['curly'] = 'nyuk!'100 $dict['moe'] = 'wise guy!'101 $dict.Count | Should -Be 3102 $dict | Export-Clixml $testfile103 $results = Import-Clixml $testfile104 $results.GetType().Name | Should -BeExactly "OrderedDictionary"105 $results.Count | Should -Be 3106 $results[0] | Should -BeExactly $dict[0]107 $results[1] | Should -BeExactly $dict[1]108 $results[2] | Should -BeExactly $dict[2]109 }110 111 It "Import Hashtable from exported non-ordered case-sentitive dictionary object" {112 $dict = New-Object hashtable113 $dict['Larry'] = 'Poik!'114 $dict['Curly'] = 'Nyuk!'115 $dict['Moe'] = 'Wise guy!'116 $dict['larry'] = 'poik!'117 $dict['curly'] = 'nyuk!'118 $dict['moe'] = 'wise guy!'119 $dict.Count | Should -Be 6120 $dict | Export-Clixml $testfile121 $results = Import-Clixml $testfile122 $results.GetType().Name | Should -BeExactly "Hashtable"123 $results.Count | Should -Be 6124 }125 126 It "Import OrderedDictionary from XML with case-sensitive duplicate keys" {127 $dupKeysXml =128 '<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">129 <Obj RefId="0">130 <TN RefId="0">131 <T>System.Collections.Specialized.OrderedDictionary</T>132 <T>System.Object</T>133 </TN>134 <DCT>135 <En>136 <S N="Key">Larry</S>137 <S N="Value">Poik!</S>138 </En>139 <En>140 <S N="Key">Moe</S>141 <S N="Value">Wise guy!</S>142 </En>143 <En>144 <S N="Key">Curly</S>145 <S N="Value">Nyuk!</S>146 </En>147 <En>148 <S N="Key">larry</S>149 <S N="Value">poik!</S>150 </En>151 <En>152 <S N="Key">moe</S>153 <S N="Value">wise guy!</S>154 </En>155 <En>156 <S N="Key">curly</S>157 <S N="Value">nyuk!</S>158 </En>159 </DCT>160 </Obj>161 </Objs>162 '163 $dupKeysXml | Out-File -FilePath $testfile164 $results = Import-Clixml $testfile165 $results.GetType().Name | Should -BeExactly "OrderedDictionary"166 $results.Count | Should -Be 6167 }168 169 It "Import Hashtable from XML with duplicate keys" {170 $dupKeysXml =171 '<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">172 <Obj RefId="0">173 <TN RefId="0">174 <T>System.Collections.Hashtable</T>175 <T>System.Object</T>176 </TN>177 <DCT>178 <En>179 <S N="Key">Larry</S>180 <S N="Value">Poik!</S>181 </En>182 <En>183 <S N="Key">Moe</S>184 <S N="Value">Wise guy!</S>185 </En>186 <En>187 <S N="Key">Curly</S>188 <S N="Value">Nyuk!</S>189 </En>190 <En>191 <S N="Key">Larry</S>192 <S N="Value">Poik!</S>193 </En>194 <En>195 <S N="Key">Moe</S>196 <S N="Value">Wise guy!</S>197 </En>198 <En>199 <S N="Key">Curly</S>200 <S N="Value">Nyuk!</S>201 </En>202 </DCT>203 </Obj>204 </Objs>205 '206 $dupKeysXml | Out-File -FilePath $testfile207 $results = Import-Clixml $testfile208 $results.GetType().Name | Should -BeExactly "Hashtable"209 $results.Count | Should -Be 6210 }211 212 It "Import OrderedDictionary from XML with duplicate keys" {213 $dupKeysXml =214 '<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">215 <Obj RefId="0">216 <TN RefId="0">217 <T>System.Collections.Specialized.OrderedDictionary</T>218 <T>System.Object</T>219 </TN>220 <DCT>221 <En>222 <S N="Key">Larry</S>223 <S N="Value">Poik!</S>224 </En>225 <En>226 <S N="Key">Moe</S>227 <S N="Value">Wise guy!</S>228 </En>229 <En>230 <S N="Key">Curly</S>231 <S N="Value">Nyuk!</S>232 </En>233 <En>234 <S N="Key">Larry</S>235 <S N="Value">Poik!</S>236 </En>237 <En>238 <S N="Key">Moe</S>239 <S N="Value">Wise guy!</S>240 </En>241 <En>242 <S N="Key">Curly</S>243 <S N="Value">Nyuk!</S>244 </En>245 </DCT>246 </Obj>247 </Objs>248 '249 $dupKeysXml | Out-File -FilePath $testfile250 $results = Import-Clixml $testfile251 $results.GetType().Name | Should -BeExactly "OrderedDictionary"252 $results.Count | Should -Be 6253 }254 255 It "Export-Clixml StopProcessing should succeed" {256 $ps = [PowerShell]::Create()257 $null = $ps.AddScript("1..10")258 $null = $ps.AddCommand("foreach-object")259 $null = $ps.AddParameter("Process", { $_; Start-Sleep -Seconds 1 })260 $null = $ps.AddCommand("Export-CliXml")261 $null = $ps.AddParameter("Path", $testfile)262 $null = $ps.BeginInvoke()263 Start-Sleep -Seconds 1264 $null = $ps.Stop()265 $ps.InvocationStateInfo.State | Should -Be "Stopped"266 $ps.Dispose()267 }268 269 It "Import-Clixml StopProcessing should succeed" {270 # create a file to use for import. It should have some complexity271 Get-Process -Id $PID | Export-Clixml -Path $testfile272 # create a large number of files to import273 $script = '$f = ,"' + $testfile + '" * 1000'274 $ps = [PowerShell]::Create()275 $ps.AddScript($script)276 $ps.Invoke()277 $ps.Commands.Clear()278 $ps.AddScript('$null = Import-CliXml -Path $f')279 $ps.BeginInvoke()280 $ps.Stop()281 $ps.InvocationStateInfo.State | Should -Be "Stopped"282 }283 284 It "Export-Clixml using -Depth should work" {285 $one = [One]::New()286 $one | Export-Clixml -Depth 2 -Path $testfile287 $deserialized_one = Import-Clixml -Path $testfile288 $deserialized_one.Value | Should -Be 1289 $deserialized_one.two.Value | Should -Be 2290 $deserialized_one.two.Three | Should -Not -BeNullOrEmpty291 $deserialized_one.two.three.num | Should -BeNullOrEmpty292 }293 294 It "Import-Clixml should work with XML serialization from pwsh.exe" {295 # need to create separate process so that current powershell doesn't interpret clixml output296 Start-Process -FilePath $PSHOME\pwsh -RedirectStandardOutput $testfile -Args "-noprofile -nologo -outputformat xml -command get-command import-clixml" -Wait297 $out = Import-Clixml -Path $testfile298 $out.Name | Should -Be "Import-CliXml"299 $out.CommandType.ToString() | Should -Be "Cmdlet"300 $out.Source | Should -Be "Microsoft.PowerShell.Utility"301 }302 303 It "Import-Clixml -IncludeTotalCount always returns unknown total count" {304 # this cmdlets supports paging, but not this switch305 [PSCustomObject]@{foo=1;bar=@{hello="world"}} | Export-Clixml -Path $testfile306 $out = Import-Clixml -Path $testfile -IncludeTotalCount307 $out[0].ToString() | Should -BeExactly "Unknown total count"308 }309 310 It "Import-Clixml -First and -Skip work together for simple types" {311 "one","two","three","four" | Export-Clixml -Path $testfile312 $out = Import-Clixml -Path $testfile -First 2 -Skip 1313 $out.Count | Should -Be 2314 $out[0] | Should -BeExactly "two"315 $out[1] | Should -BeExactly "three"316 }317 318 It "Import-Clixml -First and -Skip work together for collections" {319 @{a=1;b=2;c=3;d=4} | Export-Clixml -Path $testfile320 # order not guaranteed, even with [ordered] so we have to be smart here and compare against the full result321 $out1 = Import-Clixml -Path $testfile # this results in a hashtable322 $out2 = Import-Clixml -Path $testfile -First 2 -Skip 1 # this results in a dictionary entry323 $out2.Count | Should -Be 2324 ($out2.Name) -join ":" | Should -Be (@($out1.Keys)[1, 2] -join ":")325 ($out2.Value) -join ":" | Should -Be (@($out1.Values)[1, 2] -join ":")326 }327 328 # these tests just cover aspects that aren't normally exercised being used as a cmdlet329 It "Can read back switch and parameter values using api" {330 Add-Type -AssemblyName "${pshome}/Microsoft.PowerShell.Commands.Utility.dll"331 332 $cmd = [Microsoft.PowerShell.Commands.ExportClixmlCommand]::new()333 $cmd.LiteralPath = "foo"334 $cmd.LiteralPath | Should -BeExactly "foo"335 $cmd.NoClobber = $true336 $cmd.NoClobber | Should -BeTrue337 338 $cmd = [Microsoft.PowerShell.Commands.ImportClixmlCommand]::new()339 $cmd.LiteralPath = "bar"340 $cmd.LiteralPath | Should -BeExactly "bar"341 342 $cmd = [Microsoft.PowerShell.Commands.SelectXmlCommand]::new()343 $cmd.LiteralPath = "foo"344 $cmd.LiteralPath | Should -BeExactly "foo"345 $xml = [xml]"<a/>"346 $cmd.Xml = $xml347 $cmd.Xml | Should -Be $xml348 }349 350 Context "ConvertTo-CliXml & ConvertFrom-CliXml" {351 352 It "Getting cmdlet info should work" {353 $content = $content = Get-Command ConvertTo-CliXml,ConvertFrom-CliXml | ConvertTo-Clixml354 $results = ConvertFrom-CliXml $content355 $results.Count | Should -Be 2356 $results[0].PSTypeNames[0] | Should -BeExactly "Deserialized.System.Management.Automation.CmdletInfo"357 $results[1].PSTypeNames[0] | Should -BeExactly "Deserialized.System.Management.Automation.CmdletInfo"358 }359 360 It "Rehydration should work" {361 $property1 = 256362 $property2 = "abcdef"363 $isHiddenTestType = [IsHiddenTestType]::New($property1,$property2)364 $content = $isHiddenTestType | ConvertTo-CliXml365 $results = ConvertFrom-CliXml $content366 $results.Property1 | Should -Be $property1367 $results.Property2 | Should -BeExactly $property2368 }369 370 It "ConvertTo-CliXml StopProcessing should succeed" {371 $ps = [PowerShell]::Create()372 $null = $ps.AddScript("1..10")373 $null = $ps.AddCommand("foreach-object")374 $null = $ps.AddParameter("Process", { $_; Start-Sleep -Seconds 1 })375 $null = $ps.AddCommand("ConvertTo-CliXml")376 377 Wait-UntilTrue { $ps.BeginInvoke() } -IntervalInMilliseconds 1000378 $null = $ps.Stop()379 $ps.InvocationStateInfo.State | Should -BeExactly "Stopped"380 $ps.Dispose()381 }382 383 It "ConvertFrom-CliXml StopProcessing should succeed" {384 $content = 1,2,3 | ConvertTo-CliXml385 $ps = [PowerShell]::Create()386 $ps.AddCommand("Get-Process")387 $ps.AddCommand("ConvertFrom-CliXml")388 $ps.AddParameter("InputObject", $content)389 $ps.BeginInvoke()390 $ps.Stop()391 $ps.InvocationStateInfo.State | Should -BeExactly "Stopped"392 }393 394 It "Should serialize integers correctly using ValueFromPipeline" {395 $testObject = 1,2,3396 $content = $testObject | ConvertTo-CliXml397 $testObject | Export-CliXml -Path $testfile398 (Get-Content -Path $testfile -Raw) | Should -Be $content399 $out = ConvertFrom-CliXml -InputObject $content400 $out -is [array] | Should -BeTrue401 $out.Count | Should -Be 3402 $out[0] | Should -BeOfType [int]403 $out[0] | Should -Be 1404 $out[1] | Should -BeOfType [int]405 $out[1] | Should -Be 2406 $out[2] | Should -BeOfType [int]407 $out[2] | Should -Be 3408 }409 410 It "Using default depth of 2 should work" {411 $testObject = [One]::New()412 $content = $testObject | ConvertTo-CliXml413 $testObject | Export-Clixml -Path $testfile414 (Get-Content -Path $testfile -Raw) | Should -Be $content415 $deserialized_one = ConvertFrom-CliXml -InputObject $content416 $deserialized_one.value | Should -Be 1417 $deserialized_one.two | Should -Not -BeNullOrEmpty418 $deserialized_one.two.value | Should -Be 2419 $deserialized_one.two.three | Should -Not -BeNullOrEmpty420 $deserialized_one.two.three.num | Should -BeNullOrEmpty421 }422 423 It "Using -Depth 3 should work" {424 $testObject = [One]::New()425 $content = $testObject | ConvertTo-CliXml -Depth 3426 $testObject | Export-CliXml -Path $testfile -Depth 3427 (Get-Content -Path $testfile -Raw) | Should -Be $content428 $deserialized_one = ConvertFrom-CliXml -InputObject $content429 $deserialized_one.value | Should -Be 1430 $deserialized_one.two | Should -Not -BeNullOrEmpty431 $deserialized_one.two.value | Should -Be 2432 $deserialized_one.two.three | Should -Not -BeNullOrEmpty433 $deserialized_one.two.three.num | Should -Be 3434 $deserialized_one.two.three.four | Should -Not -BeNullOrEmpty435 $deserialized_one.two.three.four.num | Should -BeNullOrEmpty436 }437 438 It "Using -Depth 4 should work" {439 $testObject = [One]::New()440 $content = $testObject | ConvertTo-CliXml -Depth 4441 $testObject | Export-CliXml -Path $testfile -Depth 4442 (Get-Content -Path $testfile -Raw) | Should -Be $content443 $deserialized_one = ConvertFrom-CliXml -InputObject $content444 $deserialized_one.value | Should -Be 1445 $deserialized_one.two | Should -Not -BeNullOrEmpty446 $deserialized_one.two.value | Should -Be 2447 $deserialized_one.two.three | Should -Not -BeNullOrEmpty448 $deserialized_one.two.three.num | Should -Be 3449 $deserialized_one.two.three.four | Should -Not -BeNullOrEmpty450 $deserialized_one.two.three.four.num | Should -Be 4451 }452 453 It "Using -Depth 2 cannot get value beyond depth" {454 $testObject = [One]::New()455 $content = $testObject | ConvertTo-CliXml -Depth 2456 $testObject | Export-CliXml -Path $testfile -Depth 2457 (Get-Content -Path $testfile -Raw) | Should -Be $content458 $deserialized_one = ConvertFrom-CliXml -InputObject $content459 $deserialized_one.value | Should -Be 1460 $deserialized_one.two | Should -Not -BeNullOrEmpty461 $deserialized_one.two.value | Should -Be 2462 $deserialized_one.two.three | Should -Not -BeNullOrEmpty463 $deserialized_one.two.three.num | Should -BeNullOrEmpty464 }465 466 It "Should serialize array correctly using ValueFromPipeline" {467 $testObject = @(1,2,3,4)468 $content = $testObject | ConvertTo-CliXml469 $testObject | Export-CliXml -Path $testfile470 (Get-Content -Path $testfile -Raw) | Should -Be $content471 $out = ConvertFrom-CliXml -InputObject $content472 $out -is [array] | Should -BeTrue473 $out.Count | Should -Be 4474 $out[0] | Should -BeOfType [int]475 $out[0] | Should -Be 1476 $out[1] | Should -BeOfType [int]477 $out[1] | Should -Be 2478 $out[2] | Should -BeOfType [int]479 $out[2] | Should -Be 3480 $out[3] | Should -BeOfType [int]481 $out[3] | Should -Be 4482 }483 484 It "Should serialize array correctly using -InputObject" {485 $testObject = @(1,2,3,4)486 $content = ConvertTo-CliXml -InputObject $testObject487 Export-CliXml -Path $testfile -InputObject $testObject488 (Get-Content -Path $testfile -Raw) | Should -Be $content489 $out = ConvertFrom-CliXml -InputObject $content490 $out -is [System.Collections.ArrayList] | Should -BeTrue491 $out.Count | Should -Be 4492 $out[0] | Should -BeOfType [int]493 $out[0] | Should -Be 1494 $out[1] | Should -BeOfType [int]495 $out[1] | Should -Be 2496 $out[2] | Should -BeOfType [int]497 $out[2] | Should -Be 3498 $out[3] | Should -BeOfType [int]499 $out[3] | Should -Be 4500 }501 502 It "Should serialize hashtable correctly" {503 $testObject = [ordered]@{ a = 1; b = 2; c = 3; d = 4 }504 $content = $testObject | ConvertTo-CliXml505 $testObject | Export-CliXml -Path $testfile506 (Get-Content -Path $testfile -Raw) | Should -Be $content507 $out = ConvertFrom-CliXml -InputObject $content508 $out -is [ordered] | Should -BeTrue509 $out.Count | Should -Be 4510 $out.Keys | Should -BeIn @('a', 'b', 'c', 'd')511 $out.Values | Should -BeIn @(1, 2, 3, 4)512 }513 514 It "Should serialize PSCustomObject correctly" {515 $testObject = [PSCustomObject]@{ a = 1; b = 2; c = 3; d = 4 }516 $content = $testObject | ConvertTo-CliXml517 $testObject | Export-CliXml -Path $testfile518 (Get-Content -Path $testfile -Raw) | Should -Be $content519 $out = ConvertFrom-CliXml -InputObject $content520 $out -is [pscustomobject] | Should -BeTrue521 $out.a | Should -BeOfType [int]522 $out.a | Should -Be 1523 $out.b | Should -BeOfType [int]524 $out.b | Should -Be 2525 $out.c | Should -BeOfType [int]526 $out.c | Should -Be 3527 $out.d | Should -BeOfType [int]528 $out.d | Should -Be 4529 }530 531 It "Should serialize nested PSCustomObject correctly" {532 $testObject = [PSCustomObject]@{ a = 1; b = 2; c = 3; d = [PSCustomObject]@{ e = 4 } }533 $content = $testObject | ConvertTo-CliXml534 $testObject | Export-CliXml -Path $testfile535 (Get-Content -Path $testfile -Raw) | Should -Be $content536 $out = ConvertFrom-CliXml -InputObject $content537 $out -is [pscustomobject] | Should -BeTrue538 $out.a | Should -BeOfType [int]539 $out.a | Should -Be 1540 $out.b | Should -BeOfType [int]541 $out.b | Should -Be 2542 $out.c | Should -BeOfType [int]543 $out.c | Should -Be 3544 $out.d -is [pscustomobject] | Should -BeTrue545 $out.d.e | Should -BeOfType [int]546 $out.d.e | Should -Be 4547 }548 549 It "Should serialize array of PSCustomObjects correctly" {550 $testObject = @(551 [PSCustomObject]@{ Property = 1 }552 [PSCustomObject]@{ Property = 2 }553 [PSCustomObject]@{ Property = 3 }554 )555 $content = $testObject | ConvertTo-CliXml556 $testObject | Export-CliXml -Path $testfile557 (Get-Content -Path $testfile -Raw) | Should -Be $content558 $out = ConvertFrom-CliXml -InputObject $content559 $out -is [array] | Should -BeTrue560 $out.Count | Should -Be 3561 $out[0].Property | Should -BeOfType [int]562 $out[0].Property | Should -Be 1563 $out[1].Property | Should -BeOfType [int]564 $out[1].Property | Should -Be 2565 $out[2].Property | Should -BeOfType [int]566 $out[2].Property | Should -Be 3567 }568 569 It "Should serialize array of single PSCustomObject when using ValueFromPipeline" {570 $testObject = @(571 [PSCustomObject]@{ Property = 1 }572 )573 $content = $testObject | ConvertTo-CliXml574 $testObject | Export-CliXml -Path $testfile575 (Get-Content -Path $testfile -Raw) | Should -Be $content576 $out = ConvertFrom-CliXml -InputObject $content577 $out -is [pscustomobject] | Should -BeTrue578 $out.Property | Should -BeOfType [int]579 $out.Property | Should -Be 1580 }581 582 It "Should serialize array of single PSCustomObject when using -InputObject" {583 $testObject = @(584 [PSCustomObject]@{ Property = 1 }585 )586 $content = ConvertTo-CliXml -InputObject $testObject587 Export-CliXml -InputObject $testObject -Path $testfile588 (Get-Content -Path $testfile -Raw) | Should -Be $content589 $out = ConvertFrom-CliXml -InputObject $content590 $out -is [System.Collections.ArrayList] | Should -BeTrue591 $out.Count | Should -Be 1592 $out[0].Property | Should -BeOfType [int]593 $out[0].Property | Should -Be 1594 }595 }596}597 