22
33import subprocess
44from pathlib import Path
5+ from string import Template
56
67from bcbench .config import get_config
78from bcbench .exceptions import BuildError , TestExecutionError
1112_config = get_config ()
1213
1314
14- def _build_ps_script_header (app_utils_path : Path ) -> str :
15- """Build common PowerShell script header with module imports."""
16- return f"""
15+ def _escape_ps_string (value : str ) -> str :
16+ """Escape single quotes for PowerShell strings.
17+
18+ In PowerShell single-quoted strings, single quotes are escaped by doubling them.
19+ """
20+ return value .replace ("'" , "''" )
21+
22+
23+ # PowerShell script templates using Python's built-in string.Template
24+ _BUILD_AND_PUBLISH_TEMPLATE = Template (
25+ """
26+ Import-Module BcContainerHelper -Force -DisableNameChecking
27+ Import-Module '$app_utils_path' -Force
28+ $$ErrorActionPreference = 'Stop'
29+
30+ $$projectPath = '$project_path'
31+ $$password = ConvertTo-SecureString '$password' -AsPlainText -Force
32+ $$credential = New-Object System.Management.Automation.PSCredential('$username', $$password)
33+
34+ Update-AppProjectVersion -ProjectPath $$projectPath -Version $version
35+ Invoke-AppBuildAndPublish -containerName '$container_name' -appProjectFolder $$projectPath -credential $$credential -skipVerification -useDevEndpoint
36+ """ .strip ()
37+ )
38+
39+ _TEST_EXECUTION_TEMPLATE = Template (
40+ """
41+ Import-Module BcContainerHelper -Force -DisableNameChecking
42+ Import-Module '$app_utils_path' -Force
43+ $$ErrorActionPreference = 'Stop'
44+
45+ $$password = ConvertTo-SecureString '$password' -AsPlainText -Force
46+ $$credential = New-Object System.Management.Automation.PSCredential('$username', $$password)
47+
48+ Write-Host "Running tests for codeunit $codeunit_id"
49+ Invoke-BCTest -containerName '$container_name' -credential $$credential -codeunitID $codeunit_id$function_param
50+ """ .strip ()
51+ )
52+
53+ _DATASET_TESTS_TEMPLATE = Template (
54+ """
1755Import-Module BcContainerHelper -Force -DisableNameChecking
18- Import-Module '{ app_utils_path } ' -Force
19- $ErrorActionPreference = 'Stop'
20- """
56+ Import-Module '$app_utils_path' -Force
57+ $$ErrorActionPreference = 'Stop'
58+
59+ $$password = ConvertTo-SecureString '$password' -AsPlainText -Force
60+ $$credential = New-Object System.Management.Automation.PSCredential('$username', $$password)
2161
62+ $$testEntries = '$test_entries_json' | ConvertFrom-Json
2263
23- def _build_ps_credential_setup (username : str , password : str ) -> str :
24- """Build PowerShell credential setup commands."""
25- return f"""
26- $password = ConvertTo-SecureString '{ password } ' -AsPlainText -Force
27- $credential = New-Object System.Management.Automation.PSCredential('{ username } ', $password)
28- """
64+ Invoke-DatasetTests -containerName '$container_name' -credential $$credential -testEntries $$testEntries -expectation '$expectation'
65+ """ .strip ()
66+ )
2967
3068
3169def build_ps_app_build_and_publish (container_name : str , username : str , password : str , project_path : Path , version : str ) -> str :
32- """Build complete PowerShell script for app build and publish."""
3370 app_utils_path = _config .paths .ps_script_path / "AppUtils.psm1"
3471
35- return (
36- _build_ps_script_header (app_utils_path )
37- + f"\n $projectPath = '{ project_path } '"
38- + _build_ps_credential_setup (username , password )
39- + f"\n Update-AppProjectVersion -ProjectPath $projectPath -Version { version } "
40- + f"\n Invoke-AppBuildAndPublish -containerName '{ container_name } ' -appProjectFolder $projectPath -credential $credential -skipVerification -useDevEndpoint\n "
72+ return _BUILD_AND_PUBLISH_TEMPLATE .substitute (
73+ app_utils_path = _escape_ps_string (str (app_utils_path )),
74+ container_name = _escape_ps_string (container_name ),
75+ username = _escape_ps_string (username ),
76+ password = _escape_ps_string (password ),
77+ project_path = _escape_ps_string (str (project_path )),
78+ version = version ,
4179 )
4280
4381
44- def build_ps_test_script (
45- container_name : str ,
46- username : str ,
47- password : str ,
48- codeunit_id : int ,
49- function_names : list [str ] | None = None ,
50- ) -> str :
51- """Build complete PowerShell script for running tests."""
82+ def build_ps_test_script (container_name : str , username : str , password : str , codeunit_id : int , function_names : list [str ] | None = None ) -> str :
5283 app_utils_path = _config .paths .ps_script_path / "AppUtils.psm1"
5384
85+ # Build function parameter if needed
5486 if function_names :
55- function_array = ", " . join ( [f"'{ fn } '" for fn in function_names ])
56- function_param = f"-functionNames @({ function_array } )"
87+ escaped_names = [f"'{ _escape_ps_string ( fn ) } '" for fn in function_names ]
88+ function_param = f" -functionNames @({ ', ' . join ( escaped_names ) } )"
5789 else :
5890 function_param = ""
5991
60- return (
61- _build_ps_script_header (app_utils_path )
62- + _build_ps_credential_setup (username , password )
63- + f'\n Write-Host "Running tests for codeunit { codeunit_id } "\n '
64- + f"Invoke-BCTest -containerName '{ container_name } ' -credential $credential -codeunitID { codeunit_id } { function_param } \n "
92+ return _TEST_EXECUTION_TEMPLATE .substitute (
93+ app_utils_path = _escape_ps_string (str (app_utils_path )),
94+ container_name = _escape_ps_string (container_name ),
95+ username = _escape_ps_string (username ),
96+ password = _escape_ps_string (password ),
97+ codeunit_id = codeunit_id ,
98+ function_param = function_param ,
6599 )
66100
67101
68- def build_ps_dataset_tests_script (
69- container_name : str ,
70- username : str ,
71- password : str ,
72- test_entries_json : str ,
73- expectation : str ,
74- ) -> str :
75- """Build complete PowerShell script for running dataset tests."""
102+ def build_ps_dataset_tests_script (container_name : str , username : str , password : str , test_entries_json : str , expectation : str ) -> str :
76103 app_utils_path = _config .paths .ps_script_path / "AppUtils.psm1"
77104
78- return (
79- _build_ps_script_header (app_utils_path )
80- + _build_ps_credential_setup (username , password )
81- + f"\n $testEntries = '{ test_entries_json } ' | ConvertFrom-Json\n "
82- + f"\n Invoke-DatasetTests -containerName '{ container_name } ' -credential $credential -testEntries $testEntries -expectation '{ expectation } '\n "
105+ return _DATASET_TESTS_TEMPLATE .substitute (
106+ app_utils_path = _escape_ps_string (str (app_utils_path )),
107+ container_name = _escape_ps_string (container_name ),
108+ username = _escape_ps_string (username ),
109+ password = _escape_ps_string (password ),
110+ test_entries_json = _escape_ps_string (test_entries_json ),
111+ expectation = _escape_ps_string (expectation ),
83112 )
84113
85114
86- def build_and_publish_projects (
87- repo_path : Path ,
88- project_paths : list [str ],
89- container_name : str ,
90- username : str ,
91- password : str ,
92- version : str ,
93- ) -> None :
115+ def build_and_publish_projects (repo_path : Path , project_paths : list [str ], container_name : str , username : str , password : str , version : str ) -> None :
94116 """Build and publish all projects."""
95117 logger .info (f"Building and publishing { len (project_paths )} projects" )
96118
@@ -124,12 +146,7 @@ def build_and_publish_projects(
124146 logger .info ("All projects built and published" )
125147
126148
127- def run_tests (
128- entry ,
129- container_name : str ,
130- username : str ,
131- password : str ,
132- ) -> None :
149+ def run_tests (entry , container_name : str , username : str , password : str ) -> None :
133150 """Run fail-to-pass and pass-to-pass tests."""
134151 logger .info ("Running tests" )
135152
@@ -144,13 +161,7 @@ def run_tests(
144161 logger .info ("All tests completed" )
145162
146163
147- def _run_test_suite (
148- test_entries : list ,
149- expectation : str ,
150- container_name : str ,
151- username : str ,
152- password : str ,
153- ) -> None :
164+ def _run_test_suite (test_entries : list , expectation : str , container_name : str , username : str , password : str ) -> None :
154165 """Run a suite of tests."""
155166 test_entries_json = str (test_entries ).replace ("'" , '"' )
156167
0 commit comments