diff --git a/azurelinuxagent/common/rdma.py b/azurelinuxagent/common/rdma.py index 299b1a8a51..aabd05541e 100644 --- a/azurelinuxagent/common/rdma.py +++ b/azurelinuxagent/common/rdma.py @@ -419,28 +419,33 @@ def update_iboip_interfaces(self, mac_ip_array): @staticmethod def update_iboip_interface(ipv4_addr, timeout_sec, check_interval_sec): - logger.info("Wait for ib0 become available") + logger.info("Wait for ib become available") total_retries = timeout_sec / check_interval_sec n = 0 - found_ib0 = None - while not found_ib0 and n < total_retries: + found_ib = None + while not found_ib and n < total_retries: ret, output = shellutil.run_get_output("ifconfig -a") if ret != 0: raise Exception("Failed to list network interfaces") - found_ib0 = re.search("ib0", output, re.IGNORECASE) - if found_ib0: + found_ib = re.search(r"(ib\S+):", output, re.IGNORECASE) + if found_ib: break time.sleep(check_interval_sec) n += 1 - if not found_ib0: - raise Exception("ib0 is not available") + if not found_ib: + raise Exception("ib is not available") + + ibname = found_ib.groups()[0] + if shellutil.run("ifconfig {0} up".format(ibname)) != 0: + raise Exception("Could not run ifconfig {0} up".format(ibname)) netmask = 16 logger.info("RDMA: configuring IPv4 addr and netmask on ipoib interface") addr = '{0}/{1}'.format(ipv4_addr, netmask) - if shellutil.run("ifconfig ib0 {0}".format(addr)) != 0: - raise Exception("Could set addr to {0} on ib0".format(addr)) + if shellutil.run("ifconfig {0} {1}".format(ibname, addr)) != 0: + raise Exception("Could not set addr to {0} on {1}".format(addr, ibname)) + logger.info("RDMA: ipoib address and netmask configured on interface") @staticmethod diff --git a/tests_e2e/orchestrator/docker/Dockerfile b/tests_e2e/orchestrator/docker/Dockerfile index a748ff0b83..f248f8007c 100644 --- a/tests_e2e/orchestrator/docker/Dockerfile +++ b/tests_e2e/orchestrator/docker/Dockerfile @@ -42,10 +42,25 @@ RUN \ # \ groupadd waagent && \ useradd --shell /bin/bash --create-home -g waagent waagent && \ + \ + # \ + # Install the Azure CLI \ + # \ + apt-get install ca-certificates curl apt-transport-https lsb-release gnupg && \ + mkdir -p /etc/apt/keyrings && \ + curl -sLS https://packages.microsoft.com/keys/microsoft.asc \ + | gpg --dearmor \ + | tee /etc/apt/keyrings/microsoft.gpg > /dev/null && \ + chmod go+r /etc/apt/keyrings/microsoft.gpg && \ + AZ_REPO=$(lsb_release -cs) && \ + echo "deb [arch=`dpkg --print-architecture` signed-by=/etc/apt/keyrings/microsoft.gpg] https://packages.microsoft.com/repos/azure-cli/ $AZ_REPO main" \ + | tee /etc/apt/sources.list.d/azure-cli.list && \ + apt-get update && \ + apt-get install azure-cli && \ : # -# Do the Poetry and LISA setup as waagent +# Install LISA as user waagent # USER waagent diff --git a/tests_e2e/orchestrator/lib/agent_junit.py b/tests_e2e/orchestrator/lib/agent_junit.py index a8ff8eb6c5..78b7e35845 100644 --- a/tests_e2e/orchestrator/lib/agent_junit.py +++ b/tests_e2e/orchestrator/lib/agent_junit.py @@ -29,6 +29,7 @@ from lisa.messages import ( # pylint: disable=E0401 MessageBase, TestResultMessage, + TestStatus ) @@ -48,19 +49,24 @@ def type_schema(cls) -> Type[schema.TypedSchema]: return AgentJUnitSchema def _received_message(self, message: MessageBase) -> None: - # The Agent sends its own TestResultMessage and marks them as "AgentTestResultMessage"; for the - # test results sent by LISA itself, we change the suite name to "_Runbook_" in order to separate them - # from actual test results. + # The Agent sends its own TestResultMessages setting their type as "AgentTestResultMessage". + # Any other message types are sent by LISA. if isinstance(message, TestResultMessage) and message.type != "AgentTestResultMessage": if "Unexpected error in AgentTestSuite" in message.message: # Ignore these errors, they are already reported as AgentTestResultMessages return + # Change the suite name to "_Runbook_" for LISA messages in order to separate them + # from actual test results. message.suite_full_name = "_Runbook_" message.suite_name = message.suite_full_name image = message.information.get('image') if image is not None: - # NOTE: message.information['environment'] is similar to "[generated_2]" and can be correlated + # NOTE: The value of message.information['environment'] is similar to "[generated_2]" and can be correlated # with the main LISA log to find the specific VM for the message. message.full_name = f"{image} [{message.information['environment']}]" message.name = message.full_name + # LISA silently skips tests on situations that should be errors (e.g. trying to create a test VM using an image that is not available). + # Mark these messages as failed so that the JUnit report shows them as errors. + if message.status == TestStatus.SKIPPED: + message.status = TestStatus.FAILED super()._received_message(message) diff --git a/tests_e2e/orchestrator/lib/agent_test_loader.py b/tests_e2e/orchestrator/lib/agent_test_loader.py index 193ee9f4da..fcfd35ae3c 100644 --- a/tests_e2e/orchestrator/lib/agent_test_loader.py +++ b/tests_e2e/orchestrator/lib/agent_test_loader.py @@ -15,6 +15,7 @@ # limitations under the License. # import importlib.util +import re # E0401: Unable to import 'yaml' (import-error) import yaml # pylint: disable=E0401 @@ -118,6 +119,9 @@ def images(self) -> Dict[str, List[VmImageInfo]]: """ return self.__images + # Matches a reference to a random subset of images within a set with an optional count: random(, []), e.g. random(endorsed, 3), random(endorsed) + RANDOM_IMAGES_RE = re.compile(r"random\((?P[^,]+)(\s*,\s*(?P\d+))?\)") + def _validate(self): """ Performs some basic validations on the data loaded from the YAML description files @@ -125,6 +129,9 @@ def _validate(self): for suite in self.test_suites: # Validate that the images the suite must run on are in images.yml for image in suite.images: + match = AgentTestLoader.RANDOM_IMAGES_RE.match(image) + if match is not None: + image = match.group('image_set') if image not in self.images: raise Exception(f"Invalid image reference in test suite {suite.name}: Can't find {image} in images.yml") diff --git a/tests_e2e/orchestrator/lib/agent_test_suite.py b/tests_e2e/orchestrator/lib/agent_test_suite.py index 373ad826a4..d09361a963 100644 --- a/tests_e2e/orchestrator/lib/agent_test_suite.py +++ b/tests_e2e/orchestrator/lib/agent_test_suite.py @@ -135,7 +135,7 @@ def _initialize(self, node: Node, variables: Dict[str, Any], lisa_working_path: self.__context = self._Context( vm=VmIdentifier( - cloud=self._get_required_parameter(variables, "c_cloud"), + cloud=self._get_required_parameter(variables, "cloud"), location=self._get_required_parameter(variables, "c_location"), subscription=node.features._platform.subscription_id, resource_group=node_context.resource_group_name, @@ -454,8 +454,6 @@ def _execute_test_suite(self, suite: TestSuiteInfo) -> bool: suite_full_name = f"{suite_name}-{self.context.environment_name}" suite_start_time: datetime.datetime = datetime.datetime.now() - success: bool = True # True if all the tests succeed - with _set_thread_name(suite_full_name): # The thread name is added to the LISA log log_path: Path = self.context.log_path/f"{suite_full_name}.log" with set_current_thread_log(log_path): @@ -550,7 +548,7 @@ def _execute_test_suite(self, suite: TestSuiteInfo) -> bool: if not suite_success: self._mark_log_as_failed() - return success + return suite_success def _check_agent_log(self) -> bool: """ diff --git a/tests_e2e/orchestrator/lib/agent_test_suite_combinator.py b/tests_e2e/orchestrator/lib/agent_test_suite_combinator.py index efb0e6f212..82915dcfb0 100644 --- a/tests_e2e/orchestrator/lib/agent_test_suite_combinator.py +++ b/tests_e2e/orchestrator/lib/agent_test_suite_combinator.py @@ -1,6 +1,7 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT license. import logging +import random import re import urllib.parse @@ -17,7 +18,7 @@ from lisa.combinator import Combinator # pylint: disable=E0401 from lisa.util import field_metadata # pylint: disable=E0401 -from tests_e2e.orchestrator.lib.agent_test_loader import AgentTestLoader, VmImageInfo +from tests_e2e.orchestrator.lib.agent_test_loader import AgentTestLoader, VmImageInfo, TestSuiteInfo @dataclass_json() @@ -118,138 +119,90 @@ def _next(self) -> Optional[Dict[str, Any]]: def create_environment_for_existing_vm(self) -> List[Dict[str, Any]]: loader = AgentTestLoader(self.runbook.test_suites, self.runbook.cloud) - environment: List[Dict[str, Any]] = [ - { - "c_env_name": self.runbook.vm_name, - "c_vm_name": self.runbook.vm_name, - "c_location": self.runbook.location, - "c_test_suites": loader.test_suites, - } - ] + environment: Dict[str, Any] = { + "c_env_name": self.runbook.vm_name, + "c_vm_name": self.runbook.vm_name, + "c_location": self.runbook.location, + "c_test_suites": loader.test_suites, + } log: logging.Logger = logging.getLogger("lisa") - log.info("******** Environment for existing VMs *****") - log.info( - "{ c_env_name: '%s', c_vm_name: '%s', c_location: '%s', c_test_suites: '%s' }", - environment[0]['c_env_name'], environment[0]['c_vm_name'], environment[0]['c_location'], [s.name for s in environment[0]['c_test_suites']]) - log.info("***************************") + log.info("******** Waagent: Settings for existing VM *****") + log.info("") + log.info("Settings for %s:\n%s\n", environment['c_env_name'], self._get_env_settings(environment)) + log.info("") - return environment + return [environment] def create_environment_list(self) -> List[Dict[str, Any]]: + """ + Examines the test_suites specified in the runbook and returns a list of the environments (i.e. test VMs) that need to be + created in order to execute these suites. + + Note that if the runbook provides an 'image', 'location', or 'vm_size', those values override any values provided in the + configuration of the test suites. + """ + environments: List[Dict[str, Any]] = [] + shared_environments: Dict[str, Dict[str, Any]] = {} # environments shared by multiple test suites + loader = AgentTestLoader(self.runbook.test_suites, self.runbook.cloud) - # - # If the runbook provides any of 'image', 'location', or 'vm_size', those values - # override any configuration values on the test suite. - # - # Check 'images' first and add them to 'runbook_images', if any - # - if self.runbook.image == "": - runbook_images = [] - else: - runbook_images = loader.images.get(self.runbook.image) - if runbook_images is None: - if not self._is_urn(self.runbook.image) and not self._is_vhd(self.runbook.image): - raise Exception(f"The 'image' parameter must be an image or image set name, a urn, or a vhd: {self.runbook.image}") - i = VmImageInfo() - i.urn = self.runbook.image # Note that this could be a URN or the URI for a VHD - i.locations = [] - i.vm_sizes = [] - runbook_images = [i] - - # - # Now walk through all the test_suites and create a list of the environments (test VMs) that need to be created. - # - environment_list: List[Dict[str, Any]] = [] - shared_environments: Dict[str, Dict[str, Any]] = {} + runbook_images = self._get_runbook_images(loader) for suite_info in loader.test_suites: if len(runbook_images) > 0: - images_info = runbook_images + images_info: List[VmImageInfo] = runbook_images else: - # The test suite may be referencing multiple image sets, and sets can intersect, so we need to ensure - # we eliminate any duplicates. - unique_images: Dict[str, str] = {} - for image in suite_info.images: - for i in loader.images[image]: - unique_images[i] = i - images_info = unique_images.values() + images_info: List[VmImageInfo] = self._get_test_suite_images(suite_info, loader) for image in images_info: - # The URN can actually point to a VHD if the runbook provided a VHD in the 'images' parameter + # 'image.urn' can actually be the URL to a VHD if the runbook provided it in the 'image' parameter if self._is_vhd(image.urn): - marketplace_image = "" - vhd = image.urn - name = "vhd" + c_marketplace_image = "" + c_vhd = image.urn + image_name = "vhd" else: - marketplace_image = image.urn - vhd = "" - match = AgentTestSuitesCombinator._URN.match(image.urn) - if match is None: - raise Exception(f"Invalid URN: {image.urn}") - name = f"{match.group('offer')}-{match.group('sku')}" - - location: str = None - # If the runbook specified a location, use it. - if self.runbook.location != "": - location = self.runbook.location - # Then try the suite location, if any. - elif suite_info.location != '': - location = suite_info.location - # If the image has a location restriction, use any location where it is available. - # However, if it is not available on any location, skip the image. - elif image.locations: - image_locations = image.locations.get(self.runbook.cloud) - if image_locations is not None: - if len(image_locations) == 0: - continue - location = image_locations[0] - # If no location has been selected, use the default. - if location is None: - location = AgentTestSuitesCombinator._DEFAULT_LOCATIONS[self.runbook.cloud] - - # If the runbook specified a VM size, use it. Else if the image specifies a list of VM sizes, use any of them. Otherwise, - # set the size to empty and let LISA choose it. - if self.runbook.vm_size != '': - vm_size = self.runbook.vm_size - elif len(image.vm_sizes) > 0: - vm_size = image.vm_sizes[0] - else: - vm_size = "" + c_marketplace_image = image.urn + c_vhd = "" + image_name = self._get_image_name(image.urn) + + c_location: str = self._get_location(suite_info, image) + if c_location is None: + continue + + c_vm_size = self._get_vm_size(image) # Note: Disabling "W0640: Cell variable 'foo' defined in loop (cell-var-from-loop)". This is a false positive, the closure is OK # to use, since create_environment() is called within the same iteration of the loop. # pylint: disable=W0640 - def create_environment(env_name: str) -> Dict[str, Any]: - tags = {} + def create_environment(c_env_name: str) -> Dict[str, Any]: + c_vm_tags = {} if suite_info.template != '': - tags["templates"] = suite_info.template + c_vm_tags["templates"] = suite_info.template return { - "c_marketplace_image": marketplace_image, - "c_cloud": self.runbook.cloud, - "c_location": location, - "c_vm_size": vm_size, - "c_vhd": vhd, + "c_marketplace_image": c_marketplace_image, + "c_location": c_location, + "c_vm_size": c_vm_size, + "c_vhd": c_vhd, "c_test_suites": [suite_info], - "c_env_name": env_name, + "c_env_name": c_env_name, "c_marketplace_image_information_location": self._MARKETPLACE_IMAGE_INFORMATION_LOCATIONS[self.runbook.cloud], "c_shared_resource_group_location": self._SHARED_RESOURCE_GROUP_LOCATIONS[self.runbook.cloud], - "c_vm_tags": tags + "c_vm_tags": c_vm_tags } # pylint: enable=W0640 if suite_info.owns_vm: # create an environment for exclusive use by this suite - environment_list.append(create_environment(f"{name}-{suite_info.name}")) + environments.append(create_environment(f"{image_name}-{suite_info.name}")) else: # add this suite to the shared environments - key: str = f"{name}-{location}" - environment = shared_environments.get(key) - if environment is not None: - environment["c_test_suites"].append(suite_info) + key: str = f"{image_name}-{c_location}" + env = shared_environments.get(key) + if env is not None: + env["c_test_suites"].append(suite_info) if suite_info.template != '': - vm_tags = environment["c_vm_tags"] + vm_tags = env["c_vm_tags"] if "templates" in vm_tags: vm_tags["templates"] += ", " + suite_info.template else: @@ -257,21 +210,124 @@ def create_environment(env_name: str) -> Dict[str, Any]: else: shared_environments[key] = create_environment(key) - environment_list.extend(shared_environments.values()) + environments.extend(shared_environments.values()) - if len(environment_list) == 0: + if len(environments) == 0: raise Exception("No VM images were found to execute the test suites.") log: logging.Logger = logging.getLogger("lisa") log.info("") log.info("******** Waagent: Test Environments *****") log.info("") - for environment in environment_list: - test_suites = [s.name for s in environment['c_test_suites']] - log.info("Settings for %s:\n%s\n", environment['c_env_name'], '\n'.join([f"\t{name}: {value if name != 'c_test_suites' else test_suites}" for name, value in environment.items()])) + log.info("Will execute tests on %d environments:\n\n\t%s\n", len(environments), '\n\t'.join([env['c_env_name'] for env in environments])) + for env in environments: + log.info("Settings for %s:\n%s\n", env['c_env_name'], self._get_env_settings(env)) log.info("") - return environment_list + return environments + + def _get_runbook_images(self, loader: AgentTestLoader) -> List[VmImageInfo]: + """ + Returns the images specified in the runbook, or an empty list if none are specified. + """ + if self.runbook.image == "": + return [] + + images = loader.images.get(self.runbook.image) + if images is not None: + return images + + # If it is not image or image set, it must be a URN or VHD + if not self._is_urn(self.runbook.image) and not self._is_vhd(self.runbook.image): + raise Exception(f"The 'image' parameter must be an image, an image set name, a urn, or a vhd: {self.runbook.image}") + + i = VmImageInfo() + i.urn = self.runbook.image # Note that this could be a URN or the URI for a VHD + i.locations = [] + i.vm_sizes = [] + + return [i] + + @staticmethod + def _get_test_suite_images(suite: TestSuiteInfo, loader: AgentTestLoader) -> List[VmImageInfo]: + """ + Returns the images used by a test suite. + + A test suite may be reference multiple image sets and sets can intersect; this method eliminates any duplicates. + """ + unique: Dict[str, VmImageInfo] = {} + for image in suite.images: + match = AgentTestLoader.RANDOM_IMAGES_RE.match(image) + if match is None: + image_list = loader.images[image] + else: + count = match.group('count') + if count is None: + count = 1 + matching_images = loader.images[match.group('image_set')].copy() + random.shuffle(matching_images) + image_list = matching_images[0:count] + for i in image_list: + unique[i.urn] = i + return [v for k, v in unique.items()] + + def _get_location(self, suite_info: TestSuiteInfo, image: VmImageInfo) -> str: + """ + Returns the location on which the test VM for the given test suite and image should be created. + + If the image is not available on any location, returns None, to indicate that the test suite should be skipped. + """ + # If the runbook specified a location, use it. + if self.runbook.location != "": + return self.runbook.location + + # Then try the suite location, if any. + if suite_info.location != '': + return suite_info.location + + # If the image has a location restriction, use any location where it is available. + # However, if it is not available on any location, skip the image (return None) + if image.locations: + image_locations = image.locations.get(self.runbook.cloud) + if image_locations is not None: + if len(image_locations) == 0: + return None + return image_locations[0] + + # Else use the default. + return AgentTestSuitesCombinator._DEFAULT_LOCATIONS[self.runbook.cloud] + + def _get_vm_size(self, image: VmImageInfo) -> str: + """ + Returns the VM size that should be used to create the test VM for the given image. + + If the size is set to an empty string, LISA will choose an appropriate size + """ + # If the runbook specified a VM size, use it. + if self.runbook.vm_size != '': + return self.runbook.vm_size + + # If the image specifies a list of VM sizes, use any of them. + if len(image.vm_sizes) > 0: + return image.vm_sizes[0] + + # Otherwise, set the size to empty and LISA will select an appropriate size. + return "" + + @staticmethod + def _get_image_name(urn: str) -> str: + """ + Creates an image name ("offer-sku") given its URN + """ + match = AgentTestSuitesCombinator._URN.match(urn) + if match is None: + raise Exception(f"Invalid URN: {urn}") + return f"{match.group('offer')}-{match.group('sku')}" + + @staticmethod + def _get_env_settings(environment: Dict[str, Any]): + suite_names = [s.name for s in environment['c_test_suites']] + return '\n'.join([f"\t{name}: {value if name != 'c_test_suites' else suite_names}" for name, value in environment.items()]) _URN = re.compile(r"(?P[^\s:]+)[\s:](?P[^\s:]+)[\s:](?P[^\s:]+)[\s:](?P[^\s:]+)") diff --git a/tests_e2e/orchestrator/runbook.yml b/tests_e2e/orchestrator/runbook.yml index 15c39fff6f..d24e68f290 100644 --- a/tests_e2e/orchestrator/runbook.yml +++ b/tests_e2e/orchestrator/runbook.yml @@ -49,9 +49,10 @@ variable: # # The test suites to execute - name: test_suites - value: "agent_bvt" + value: "agent_bvt, no_outbound_connections" - name: cloud value: "AzureCloud" + is_case_visible: true - name: image value: "" - name: location @@ -82,9 +83,6 @@ variable: value: "" - name: c_vm_size value: "" - - name: c_cloud - value: "" - is_case_visible: true - name: c_location value: "" is_case_visible: true @@ -118,12 +116,9 @@ platform: keep_environment: $(keep_environment) azure: deploy: True -# -# TODO: Enable these parameters once LISA supports all Azure clouds -# -# cloud: $(cloud) -# marketplace_image_information_location: $(c_marketplace_image_information_location) -# shared_resource_group_location: $(c_shared_resource_group_location) + cloud: $(cloud) + marketplace_image_information_location: $(c_marketplace_image_information_location) + shared_resource_group_location: $(c_shared_resource_group_location) subscription_id: $(subscription_id) wait_delete: false vm_tags: $(c_vm_tags) diff --git a/tests_e2e/orchestrator/sample_runbooks/existing_vm.yml b/tests_e2e/orchestrator/sample_runbooks/existing_vm.yml index f1e480311e..8ef5baba28 100644 --- a/tests_e2e/orchestrator/sample_runbooks/existing_vm.yml +++ b/tests_e2e/orchestrator/sample_runbooks/existing_vm.yml @@ -33,6 +33,7 @@ variable: # - name: cloud value: "AzureCloud" + is_case_visible: true - name: subscription_id value: "" - name: resource_group_name @@ -88,9 +89,6 @@ variable: value: "" - name: c_shared_resource_group_location value: "" - - name: c_cloud - value: "" - is_case_visible: true - name: c_location value: "" is_case_visible: true @@ -118,12 +116,9 @@ platform: admin_username: $(user) admin_private_key_file: $(identity_file) azure: -# -# TODO: Enable these parameters once LISA supports all Azure clouds -# -# cloud: $(cloud) -# marketplace_image_information_location: $(c_marketplace_image_information_location) -# shared_resource_group_location: $(c_shared_resource_group_location) + cloud: $(cloud) + marketplace_image_information_location: $(c_marketplace_image_information_location) + shared_resource_group_location: $(c_shared_resource_group_location) resource_group_name: $(resource_group_name) deploy: false subscription_id: $(subscription_id) diff --git a/tests_e2e/orchestrator/scripts/install-agent b/tests_e2e/orchestrator/scripts/install-agent index 14663d0b8d..513487b211 100755 --- a/tests_e2e/orchestrator/scripts/install-agent +++ b/tests_e2e/orchestrator/scripts/install-agent @@ -70,16 +70,21 @@ if service-status walinuxagent > /dev/null 2>&1;then else service_name="waagent" fi -echo "Service name: $service_name" # # Output the initial version of the agent # python=$(get-agent-python) waagent=$(get-agent-bin-path) -echo "Agent's path: $waagent" + +echo "============================================================" +echo "Service Name: $service_name" +echo "Agent Path: $waagent" +echo "Agent Version:" $python "$waagent" --version -printf "\n" +echo "Service Status:" +service-status $service_name +echo "============================================================" # # Install the package diff --git a/tests_e2e/pipeline/pipeline-cleanup.yml b/tests_e2e/pipeline/pipeline-cleanup.yml index b82ad53eea..961778cf68 100644 --- a/tests_e2e/pipeline/pipeline-cleanup.yml +++ b/tests_e2e/pipeline/pipeline-cleanup.yml @@ -19,11 +19,8 @@ parameters: type: object default: - azuremanagement -# -# TODO: Enable these services connections once we create test pipelines for all Azure clouds -# -# - azuremanagement.china -# - azuremanagement.government + - azuremanagement.china + - azuremanagement.government pool: vmImage: ubuntu-latest diff --git a/tests_e2e/test_suites/images.yml b/tests_e2e/test_suites/images.yml index 6fef5314dd..a19105710b 100644 --- a/tests_e2e/test_suites/images.yml +++ b/tests_e2e/test_suites/images.yml @@ -80,6 +80,7 @@ images: urn: "Debian debian-11 11-backports-arm64 latest" locations: AzureUSGovernment: [] + AzureChinaCloud: [] flatcar: urn: "kinvolk flatcar-container-linux-free stable latest" locations: @@ -89,6 +90,7 @@ images: urn: "kinvolk flatcar-container-linux-corevm stable latest" locations: AzureChinaCloud: [] + AzureUSGovernment: [] vm_sizes: - "Standard_D2pls_v5" mariner_1: @@ -100,6 +102,8 @@ images: urn: "microsoftcblmariner cbl-mariner cbl-mariner-2-arm64 latest" locations: AzureCloud: ["eastus"] + AzureChinaCloud: [] + AzureUSGovernment: [] vm_sizes: - "Standard_D2pls_v5" rocky_9: @@ -125,8 +129,13 @@ images: urn: "RedHat rhel-arm64 9_0-arm64 latest" locations: AzureChinaCloud: [] + AzureUSGovernment: [] ubuntu_1604: "Canonical UbuntuServer 16.04-LTS latest" ubuntu_1804: "Canonical UbuntuServer 18.04-LTS latest" ubuntu_2004: "Canonical 0001-com-ubuntu-server-focal 20_04-lts latest" ubuntu_2204: "Canonical 0001-com-ubuntu-server-jammy 22_04-lts latest" - ubuntu_2204_arm64: "Canonical 0001-com-ubuntu-server-jammy 22_04-lts-arm64 latest" + ubuntu_2204_arm64: + urn: "Canonical 0001-com-ubuntu-server-jammy 22_04-lts-arm64 latest" + locations: + AzureChinaCloud: [] + AzureUSGovernment: [] diff --git a/tests_e2e/test_suites/no_outbound_connections.yml b/tests_e2e/test_suites/no_outbound_connections.yml index 23e3ef1ec2..6cf6c490f7 100644 --- a/tests_e2e/test_suites/no_outbound_connections.yml +++ b/tests_e2e/test_suites/no_outbound_connections.yml @@ -15,7 +15,6 @@ tests: - "bvts/run_command.py" - "bvts/vm_access.py" - "no_outbound_connections/check_fallback_to_hgap.py" -images: - - "ubuntu_2004" +images: "random(endorsed)" template: "no_outbound_connections/nsg_template.py" owns_vm: true diff --git a/tests_e2e/tests/lib/vm_extension.py b/tests_e2e/tests/lib/vm_extension.py index abefcc723f..bf7a41a44d 100644 --- a/tests_e2e/tests/lib/vm_extension.py +++ b/tests_e2e/tests/lib/vm_extension.py @@ -107,9 +107,7 @@ def enable( extension_parameters ).result(timeout=_TIMEOUT)) - if result.provisioning_state not in ('Succeeded', 'Updating'): - raise Exception(f"Enable {self._identifier} failed. Provisioning state: {result.provisioning_state}") - log.info("Enable completed (provisioning state: %s).", result.provisioning_state) + log.info("Enable completed. Provisioning state: %s", result.provisioning_state) def get_instance_view(self) -> VirtualMachineExtensionInstanceView: # TODO: Check type for scale sets """