From 120eb55417a2f7065cd705edf470324c7be6b8cb Mon Sep 17 00:00:00 2001 From: Jay Gupta Date: Mon, 6 Jul 2026 14:35:11 +0530 Subject: [PATCH 1/2] test(vm_extensions): add CustomScript boot validation test case Add a minimal, self-contained Custom Script extension boot validation test to CustomScriptTests. It installs the extension with a single inline commandToExecute (no fileUris, so no storage account or public blob is required), asserts provisioning succeeds, then removes the extension. Publisher, type and version are read from runbook variables (extension_publisher, extension_type, extension_version), defaulting to the Custom Script extension. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../runtime_extensions/custom_script.py | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/lisa/microsoft/testsuites/vm_extensions/runtime_extensions/custom_script.py b/lisa/microsoft/testsuites/vm_extensions/runtime_extensions/custom_script.py index 232bb2a06f..aa750d7aed 100644 --- a/lisa/microsoft/testsuites/vm_extensions/runtime_extensions/custom_script.py +++ b/lisa/microsoft/testsuites/vm_extensions/runtime_extensions/custom_script.py @@ -103,6 +103,52 @@ def before_case(self, log: Logger, **kwargs: Any) -> None: node: Node = kwargs.pop("node") check_waagent_version_supported(node=node) + @TestCaseMetadata( + description=""" + Basic boot validation for the Custom Script VM extension. + + Installs the extension with a single inline commandToExecute and no file + uris, so it needs no storage account or public blob access. Verifies that + provisioning succeeds, then removes the extension. + + The extension publisher, type and version are read from runbook variables + (extension_publisher, extension_type, extension_version), defaulting to the + Custom Script extension. The deployed extension is named + '__boot_validation_test'. + """, + priority=1, + ) + def microsoft_azure_extensions_customscript_boot_validation_test( + self, log: Logger, node: Node, variables: Dict[str, Any] + ) -> None: + publisher: str = variables.get( + "extension_publisher", "Microsoft.Azure.Extensions" + ).strip() + extension_type: str = variables.get("extension_type", "CustomScript").strip() + version: str = variables.get("extension_version", "2.1").strip() + + extension_name = f"{publisher}_{extension_type}_boot_validation_test" + settings = {"commandToExecute": "echo 'CSE test success'"} + + extension = node.features[AzureExtension] + extension.delete(name=extension_name, ignore_not_found=True) + + log.info(f"Installing extension '{extension_name}'...") + result = extension.create_or_update( + name=extension_name, + publisher=publisher, + type_=extension_type, + type_handler_version=version, + auto_upgrade_minor_version=True, + settings=settings, + ) + + assert_that(result["provisioning_state"]).described_as( + "Expected the extension to succeed" + ).is_equal_to("Succeeded") + + extension.delete(name=extension_name, ignore_not_found=True) + @TestCaseMetadata( description=""" Runs the Custom Script VM extension with a public Azure storage file uri. From 25ca6b17f3a801abe3b92d56c8e5cb28afa31f67 Mon Sep 17 00:00:00 2001 From: Jay Gupta Date: Mon, 6 Jul 2026 15:12:36 +0530 Subject: [PATCH 2/2] test(vm_extensions): guarantee CustomScript extension cleanup Wrap the install and provisioning-state assertion in try/finally so the extension is always deleted, even if create_or_update raises or the assertion fails, avoiding a leftover extension that could affect subsequent tests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../runtime_extensions/custom_script.py | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/lisa/microsoft/testsuites/vm_extensions/runtime_extensions/custom_script.py b/lisa/microsoft/testsuites/vm_extensions/runtime_extensions/custom_script.py index aa750d7aed..9fa1c65fad 100644 --- a/lisa/microsoft/testsuites/vm_extensions/runtime_extensions/custom_script.py +++ b/lisa/microsoft/testsuites/vm_extensions/runtime_extensions/custom_script.py @@ -133,21 +133,22 @@ def microsoft_azure_extensions_customscript_boot_validation_test( extension = node.features[AzureExtension] extension.delete(name=extension_name, ignore_not_found=True) - log.info(f"Installing extension '{extension_name}'...") - result = extension.create_or_update( - name=extension_name, - publisher=publisher, - type_=extension_type, - type_handler_version=version, - auto_upgrade_minor_version=True, - settings=settings, - ) - - assert_that(result["provisioning_state"]).described_as( - "Expected the extension to succeed" - ).is_equal_to("Succeeded") - - extension.delete(name=extension_name, ignore_not_found=True) + try: + log.info(f"Installing extension '{extension_name}'...") + result = extension.create_or_update( + name=extension_name, + publisher=publisher, + type_=extension_type, + type_handler_version=version, + auto_upgrade_minor_version=True, + settings=settings, + ) + + assert_that(result["provisioning_state"]).described_as( + "Expected the extension to succeed" + ).is_equal_to("Succeeded") + finally: + extension.delete(name=extension_name, ignore_not_found=True) @TestCaseMetadata( description="""