Skip to content

Commit

Permalink
Include region/partition criteria for test instance selection
Browse files Browse the repository at this point in the history
  • Loading branch information
apozsuse committed Dec 20, 2024
1 parent fe39292 commit 341c563
Show file tree
Hide file tree
Showing 4 changed files with 183 additions and 42 deletions.
42 changes: 42 additions & 0 deletions config/mash_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ cloud:
us-west-2: ami-0ec021424fb596d6c
test_instance_catalog:
- region: us-east-1
partition: aws
arch: x86_64
instance_names:
- c5.large
Expand All @@ -101,13 +102,15 @@ cloud:
cpu_options: []
- region: us-east-1
arch: x86_64
partition: aws
instance_names:
- i3.large
- t2.small
boot_types:
- bios
cpu_options: []
- region: us-east-2
partition: aws
arch: x86_64
instance_names:
- m6a.large
Expand All @@ -119,6 +122,7 @@ cloud:
cpu_options:
- AmdSevSnp_enabled
- region: us-east-1
partition: aws
arch: aarch64
instance_names:
- t4g.small
Expand All @@ -127,6 +131,44 @@ cloud:
- uefi
- uefi-preferred
cpu_options: []
- region: cn-north-1
partition: aws-cn
arch: x86_64
instance_names:
- t3.small
boot_types:
- bios
cpu_options: []
- region: cn-north-1
partition: aws-cn
arch: x86_64
instance_names:
- m5.large
- t3.small
boot_types:
- uefi-preferred
- uefi
cpu_options: []
- region: us-gov-east-1
partition: aws-us-gov
arch: x86_64
instance_names:
- i3.large
- t3.small
boot_types:
- bios
cpu_options: []
- region: us-gov-east-1
partition: aws-us-gov
arch: x86_64
instance_names:
- c5.large
- m5.large
- t3.small
boot_types:
- uefi-preferred
- uefi
cpu_options: []
test:
img_proof_timeout: 600
upload:
Expand Down
94 changes: 58 additions & 36 deletions mash/services/test/ec2_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@
)
from mash.services.test.ec2_test_utils import (
get_instance_feature_combinations,
select_instances_for_tests
select_instances_for_tests,
get_partition_test_regions
)
from mash.utils.mash_utils import create_ssh_key_pair
from mash.utils.ec2 import (
Expand Down Expand Up @@ -84,6 +85,13 @@ def run_job(self):
)
return

self.partitions = get_partition_test_regions(self.test_regions)
if not self.partitions:
msg = 'At least one partition is required for tests.'
if self.log_callback:
self.log_callback.error(msg)
raise MashTestException(msg)

self.cloud_architecture = self.job_config.get(
'cloud_architecture', 'x86_64'
)
Expand All @@ -94,58 +102,72 @@ def run_job(self):
self.cpu_options = self.job_config.get('cpu_options', {})
self.instance_catalog = self.config.get_test_ec2_instance_catalog()

# Get all account credentials in one request
accounts = []
for region, info in self.test_regions.items():
account = get_testing_account(info)
if account not in accounts:
accounts.append(account)
self.request_credentials(accounts)

# Feature combinations are common for all partitions
self.feature_combinations = get_instance_feature_combinations(
self.cloud_architecture,
self.boot_firmware,
self.cpu_options,
logger=self.log_callback
)
self.instance_types = select_instances_for_tests(
instance_catalog=self.instance_catalog,
feature_combinations=self.feature_combinations,
logger=self.log_callback
)

if not self.instance_types:
msg = (
'No instances in the instance catalog can cover the required '
f'feature combinations: {self.feature_combinations}'
# mash will try to test all the possible features supported in the
# available test regions for each partition
for partition, test_regions in self.partitions:

instance_types = select_instances_for_tests(
test_regions=test_regions,
instance_catalog=self.instance_catalog,
feature_combinations=self.feature_combinations,
logger=self.log_callback
)
raise MashTestException(msg)

# Get all account credentials in one request
accounts = []
for region, info in self.test_regions.items():
account = get_testing_account(info)
if account not in accounts:
accounts.append(account)
self.request_credentials(accounts)
if not instance_types:

for instance_type in self.instance_types:
if self.log_callback:
self.log_callback.info(
'Running img-proof tests against image with '
'type: {inst_type}.'.format(
inst_type=instance_type
)
if partition in ('aws-cn', 'aws-us-gov') and \
self.cloud_architecture == 'aarch64':
# Skip test aarch64 images in China and GovCloud.
# There are no aarch64 based instance types available.
continue

# There are no instance types configured in the test regions
# for the partition that can cover a single feat combination
msg = (
f'No instances in the instance catalog for {partition}'
f' partition can cover the any feature combination: '
f'{self.feature_combinations}'
)
if self.log_callback:
self.log_callback.error(msg)
raise MashTestException(msg)

for instance_type in self.instance_types:
if self.log_callback:
self.log_callback.info(
'Running img-proof tests for image in {part} with '
'instance type: {inst_type}.'.format(
part=partition,
inst_type=instance_type
)
)

region = instance_type.get('region')
account = get_testing_account(self.test_regions[region])
credentials = self.credentials[account]

if info['partition'] in ('aws-cn', 'aws-us-gov') and \
self.cloud_architecture == 'aarch64':
# Skip test aarch64 images in China and GovCloud.
# There are no aarch64 based instance types available.
continue

# with setup_ec2_networking(
# credentials['access_key_id'],
# region,
# credentials['secret_access_key'],
# self.ssh_private_key_file,
# subnet_id=info.get('subnet')
# credentials['access_key_id'],
# region,
# credentials['secret_access_key'],
# self.ssh_private_key_file,
# subnet_id=info.get('subnet')
# ) as network_details:
# status = self.run_tests(
# access_key_id=credentials['access_key_id'],
Expand Down
22 changes: 21 additions & 1 deletion mash/services/test/ec2_test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
# along with mash. If not, see <http://www.gnu.org/licenses/>
#

from collections import defaultdict
import itertools
import logging
import random
Expand Down Expand Up @@ -93,6 +94,7 @@ def remove_incompatible_feature_combinations(feature_combinations):


def select_instances_for_tests(
test_regions: list,
instance_catalog: list,
feature_combinations: list,
logger: logging.Logger = None
Expand All @@ -108,6 +110,7 @@ def select_instances_for_tests(
instances = []
for feature_combination in feature_combinations:
instance = select_instance_for_feature_combination(
test_regions=test_regions,
feature_combination=feature_combination,
instance_catalog=instance_catalog,
logger=logger
Expand All @@ -130,6 +133,7 @@ def select_instances_for_tests(


def select_instance_for_feature_combination(
test_regions: list,
feature_combination: tuple,
instance_catalog: list,
logger: logging.Logger = None
Expand All @@ -148,6 +152,10 @@ def select_instance_for_feature_combination(
cpu_option = feature_combination[2]

for instance_group in instance_catalog:
if instance_group['region'] not in test_regions:
# intance belongs to a region not available for tests for this job
continue

if arch != instance_group.get('arch'):
# arch not matching the group
continue
Expand All @@ -171,6 +179,18 @@ def select_instance_for_feature_combination(
'instance_name': random.choice(selected_group['instance_names']),
'boot_type': boot_type,
'cpu_option': cpu_option,
'region': selected_group['region']
'region': selected_group['region'],
'partition': selected_group['partition']
}
return instance


def get_partition_test_regions(test_regions: dict):
"""
Provides a dictionary with the tests region names available for testing
per partitions
"""
partitions = defaultdict(list)
for region_name, region in test_regions.items():
partitions[region.get('partition')].append(region_name)
return partitions
Loading

0 comments on commit 341c563

Please sign in to comment.