mirror of
https://github.com/zebrajr/ansible.git
synced 2025-12-06 00:19:48 +01:00
Fix up coverage with async on Windows (#84917)
Fixes the coverage collection for Windows and async tasks. This ensures the async task still has access to the PSHost so that it can access the runspace debugger tasks on the host.
This commit is contained in:
parent
390e112822
commit
b7d76a93b2
|
|
@ -4,6 +4,7 @@
|
|||
using namespace Microsoft.Win32.SafeHandles
|
||||
using namespace System.Collections
|
||||
using namespace System.IO
|
||||
using namespace System.Management.Automation
|
||||
using namespace System.Text
|
||||
using namespace System.Threading
|
||||
|
||||
|
|
@ -43,6 +44,15 @@ param([ScriptBlock]$ScriptBlock, $Param)
|
|||
Param = $execInfo.Parameters
|
||||
})
|
||||
|
||||
# It is important we run with the invocation settings so that it has access
|
||||
# to the same PSHost. The pipeline input also needs to be marked as complete
|
||||
# so the exec_wrapper isn't waiting for input indefinitely.
|
||||
$pipelineInput = [PSDataCollection[object]]::new()
|
||||
$pipelineInput.Complete()
|
||||
$invocationSettings = [PSInvocationSettings]@{
|
||||
Host = $host
|
||||
}
|
||||
|
||||
# Signals async_wrapper that we are ready to start the job and to stop waiting
|
||||
$waitHandle = [SafeWaitHandle]::new([IntPtr]$WaitHandleId, $true)
|
||||
$waitEvent = [ManualResetEvent]::new($false)
|
||||
|
|
@ -52,7 +62,7 @@ $null = $waitEvent.Set()
|
|||
$jobOutput = $null
|
||||
$jobError = $null
|
||||
try {
|
||||
$jobAsyncResult = $ps.BeginInvoke()
|
||||
$jobAsyncResult = $ps.BeginInvoke($pipelineInput, $invocationSettings, $null, $null)
|
||||
$jobAsyncResult.AsyncWaitHandle.WaitOne($Timeout * 1000) > $null
|
||||
$result.finished = 1
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
Function Test-CollectionPwshCoverage {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Test coverage for collection pwsh util.
|
||||
#>
|
||||
'foo'
|
||||
}
|
||||
|
||||
Export-ModuleMember -Function Test-CollectionPwshCoverage
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
#!powershell
|
||||
|
||||
#AnsibleRequires -CSharpUtil Ansible.Basic
|
||||
#AnsibleRequires -PowerShell ..module_utils.CollectionPwshCoverage
|
||||
|
||||
$module = [Ansible.Basic.AnsibleModule]::Create($args, @{})
|
||||
$module.Result.util = Test-CollectionPwshCoverage
|
||||
$module.ExitJson()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
#!powershell
|
||||
|
||||
#AnsibleRequires -CSharpUtil Ansible.Basic
|
||||
|
||||
$module = [Ansible.Basic.AnsibleModule]::Create($args, @{})
|
||||
$module.ExitJson()
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
#!powershell
|
||||
|
||||
#AnsibleRequires -CSharpUtil Ansible.Basic
|
||||
#AnsibleRequires -PowerShell Ansible.ModuleUtils.AdjacentPwshCoverage
|
||||
|
||||
$module = [Ansible.Basic.AnsibleModule]::Create($args, @{})
|
||||
$module.Result.util = Test-AdjacentPwshCoverage
|
||||
$module.ExitJson()
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
Function Test-AdjacentPwshCoverage {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Test coverage for module_util adjacent pwsh util.
|
||||
#>
|
||||
'foo'
|
||||
}
|
||||
|
||||
Export-ModuleMember -Function Test-AdjacentPwshCoverage
|
||||
|
|
@ -2,4 +2,21 @@
|
|||
win_collection:
|
||||
|
||||
- name: run module in library adjacent to test coverage for test plugins
|
||||
test_win_collection:
|
||||
test_win_collection_normal:
|
||||
register: library_result
|
||||
|
||||
- name: assert run module with library adjacent module
|
||||
assert:
|
||||
that:
|
||||
- library_result.util == 'foo'
|
||||
|
||||
- name: test coverage under async
|
||||
test_win_collection_async:
|
||||
async: 30
|
||||
poll: 2
|
||||
|
||||
- name: test coverage under become
|
||||
test_win_collection_become:
|
||||
become: yes
|
||||
become_method: runas
|
||||
become_user: SYSTEM
|
||||
|
|
|
|||
|
|
@ -3,24 +3,42 @@ from __future__ import annotations
|
|||
import json
|
||||
import os
|
||||
import os.path
|
||||
import pathlib
|
||||
|
||||
|
||||
def main() -> None:
|
||||
collection_root = os.getcwd()
|
||||
collection_root = pathlib.Path(os.getcwd())
|
||||
print(f"Running windows-integration coverage test in '{collection_root}'")
|
||||
|
||||
result_path = os.path.join(collection_root, "tests", "output", "coverage", "coverage-powershell")
|
||||
module_path = os.path.join(collection_root, "plugins", "modules", "win_collection.ps1")
|
||||
test_path = os.path.join(collection_root, "tests", "integration", "targets", "win_collection", "library", "test_win_collection.ps1")
|
||||
result_path = collection_root / "tests" / "output" / "coverage" / "coverage-powershell"
|
||||
adjacent_modules_path = collection_root / "tests" / "integration" / "targets" / "win_collection" / "library"
|
||||
adjacent_utils_path = collection_root / "tests" / "integration" / "targets" / "win_collection" / "module_utils"
|
||||
collection_modules_path = collection_root / "plugins" / "modules"
|
||||
collection_utils_path = collection_root / "plugins" / "module_utils"
|
||||
|
||||
expected_hits = {
|
||||
str(adjacent_modules_path / 'test_win_collection_async.ps1'): {'5': 1, '6': 1},
|
||||
str(adjacent_modules_path / 'test_win_collection_become.ps1'): {'5': 1, '6': 1},
|
||||
str(adjacent_modules_path / 'test_win_collection_normal.ps1'): {'6': 1, '7': 1, '8': 1},
|
||||
str(adjacent_utils_path / 'Ansible.ModuleUtils.AdjacentPwshCoverage.psm1'): {'6': 1, '9': 1},
|
||||
str(collection_modules_path / 'win_collection.ps1'): {'6': 1, '7': 1, '8': 1},
|
||||
str(collection_utils_path / 'CollectionPwshCoverage.psm1'): {'6': 1, '9': 1},
|
||||
}
|
||||
found_hits = set()
|
||||
|
||||
with open(result_path, mode="rb") as fd:
|
||||
data = json.load(fd)
|
||||
|
||||
for path, result in data.items():
|
||||
print(f"Testing result for path '{path}' -> {result!r}")
|
||||
assert path in [module_path, test_path], f"Found unexpected coverage result path '{path}'"
|
||||
assert result == {'5': 1, '6': 1}, "Coverage result did not pick up a hit on lines 5 and 6"
|
||||
assert path in expected_hits, f"Found unexpected coverage result path '{path}'"
|
||||
|
||||
assert len(data) == 2, f"Expected coverage results for 2 files but got {len(data)}"
|
||||
expected = expected_hits[path]
|
||||
assert result == expected, f"Coverage result for {path} was {result!r} but was expecting {expected!r}"
|
||||
found_hits.add(path)
|
||||
|
||||
missing_hits = set(expected_hits.keys()).difference(found_hits)
|
||||
assert not missing_hits, f"Expected coverage results for {', '.join(missing_hits)} but they were not present"
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user