Skip to content

Commit 6760e5f

Browse files
committed
powershell script building using template
1 parent 4e4dfa4 commit 6760e5f

2 files changed

Lines changed: 281 additions & 68 deletions

File tree

src/bcbench/operations/bc_operations.py

Lines changed: 79 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import subprocess
44
from pathlib import Path
5+
from string import Template
56

67
from bcbench.config import get_config
78
from bcbench.exceptions import BuildError, TestExecutionError
@@ -11,86 +12,107 @@
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+
"""
1755
Import-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

3169
def 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"\nUpdate-AppProjectVersion -ProjectPath $projectPath -Version {version}"
40-
+ f"\nInvoke-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'\nWrite-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"\nInvoke-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

Comments
 (0)