summaryrefslogtreecommitdiff
path: root/tests/unittests/distros/test_init.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/unittests/distros/test_init.py')
-rw-r--r--tests/unittests/distros/test_init.py273
1 files changed, 180 insertions, 93 deletions
diff --git a/tests/unittests/distros/test_init.py b/tests/unittests/distros/test_init.py
index fd64a322..8f3c8978 100644
--- a/tests/unittests/distros/test_init.py
+++ b/tests/unittests/distros/test_init.py
@@ -9,16 +9,17 @@ from unittest import mock
import pytest
-from cloudinit.distros import _get_package_mirror_info, LDH_ASCII_CHARS
+from cloudinit.distros import LDH_ASCII_CHARS, _get_package_mirror_info
# In newer versions of Python, these characters will be omitted instead
# of substituted because of security concerns.
# See https://bugs.python.org/issue43882
-SECURITY_URL_CHARS = '\n\r\t'
+SECURITY_URL_CHARS = "\n\r\t"
# Define a set of characters we would expect to be replaced
INVALID_URL_CHARS = [
- chr(x) for x in range(127)
+ chr(x)
+ for x in range(127)
if chr(x) not in LDH_ASCII_CHARS + SECURITY_URL_CHARS
]
for separator in [":", ".", "/", "#", "?", "@", "[", "]"]:
@@ -37,21 +38,41 @@ class TestGetPackageMirrorInfo:
These tests are more focused on specific aspects of the unit under test.
"""
- @pytest.mark.parametrize('mirror_info,expected', [
- # Empty info gives empty return
- ({}, {}),
- # failsafe values used if present
- ({'failsafe': {'primary': 'http://value', 'security': 'http://other'}},
- {'primary': 'http://value', 'security': 'http://other'}),
- # search values used if present
- ({'search': {'primary': ['http://value'],
- 'security': ['http://other']}},
- {'primary': ['http://value'], 'security': ['http://other']}),
- # failsafe values used if search value not present
- ({'search': {'primary': ['http://value']},
- 'failsafe': {'security': 'http://other'}},
- {'primary': ['http://value'], 'security': 'http://other'})
- ])
+ @pytest.mark.parametrize(
+ "mirror_info,expected",
+ [
+ # Empty info gives empty return
+ ({}, {}),
+ # failsafe values used if present
+ (
+ {
+ "failsafe": {
+ "primary": "http://value",
+ "security": "http://other",
+ }
+ },
+ {"primary": "http://value", "security": "http://other"},
+ ),
+ # search values used if present
+ (
+ {
+ "search": {
+ "primary": ["http://value"],
+ "security": ["http://other"],
+ }
+ },
+ {"primary": ["http://value"], "security": ["http://other"]},
+ ),
+ # failsafe values used if search value not present
+ (
+ {
+ "search": {"primary": ["http://value"]},
+ "failsafe": {"security": "http://other"},
+ },
+ {"primary": ["http://value"], "security": "http://other"},
+ ),
+ ],
+ )
def test_get_package_mirror_info_failsafe(self, mirror_info, expected):
"""
Test the interaction between search and failsafe inputs
@@ -60,97 +81,163 @@ class TestGetPackageMirrorInfo:
options; test_failsafe_used_if_all_search_results_filtered_out covers
that.)
"""
- assert expected == _get_package_mirror_info(mirror_info,
- mirror_filter=lambda x: x)
+ assert expected == _get_package_mirror_info(
+ mirror_info, mirror_filter=lambda x: x
+ )
def test_failsafe_used_if_all_search_results_filtered_out(self):
"""Test the failsafe option used if all search options eliminated."""
mirror_info = {
- 'search': {'primary': ['http://value']},
- 'failsafe': {'primary': 'http://other'}
+ "search": {"primary": ["http://value"]},
+ "failsafe": {"primary": "http://other"},
}
- assert {'primary': 'http://other'} == _get_package_mirror_info(
- mirror_info, mirror_filter=lambda x: False)
+ assert {"primary": "http://other"} == _get_package_mirror_info(
+ mirror_info, mirror_filter=lambda x: False
+ )
- @pytest.mark.parametrize('allow_ec2_mirror, platform_type', [
- (True, 'ec2')
- ])
- @pytest.mark.parametrize('availability_zone,region,patterns,expected', (
- # Test ec2_region alone
- ('fk-fake-1f', None, ['http://EC2-%(ec2_region)s/ubuntu'],
- ['http://ec2-fk-fake-1/ubuntu']),
- # Test availability_zone alone
- ('fk-fake-1f', None, ['http://AZ-%(availability_zone)s/ubuntu'],
- ['http://az-fk-fake-1f/ubuntu']),
- # Test region alone
- (None, 'fk-fake-1', ['http://RG-%(region)s/ubuntu'],
- ['http://rg-fk-fake-1/ubuntu']),
- # Test that ec2_region is not available for non-matching AZs
- ('fake-fake-1f', None,
- ['http://EC2-%(ec2_region)s/ubuntu',
- 'http://AZ-%(availability_zone)s/ubuntu'],
- ['http://az-fake-fake-1f/ubuntu']),
- # Test that template order maintained
- (None, 'fake-region',
- ['http://RG-%(region)s-2/ubuntu', 'http://RG-%(region)s-1/ubuntu'],
- ['http://rg-fake-region-2/ubuntu', 'http://rg-fake-region-1/ubuntu']),
- # Test that non-ASCII hostnames are IDNA encoded;
- # "IDNA-ТεЅТ̣".encode('idna') == b"xn--idna--4kd53hh6aba3q"
- (None, 'ТεЅТ̣', ['http://www.IDNA-%(region)s.com/ubuntu'],
- ['http://www.xn--idna--4kd53hh6aba3q.com/ubuntu']),
- # Test that non-ASCII hostnames with a port are IDNA encoded;
- # "IDNA-ТεЅТ̣".encode('idna') == b"xn--idna--4kd53hh6aba3q"
- (None, 'ТεЅТ̣', ['http://www.IDNA-%(region)s.com:8080/ubuntu'],
- ['http://www.xn--idna--4kd53hh6aba3q.com:8080/ubuntu']),
- # Test that non-ASCII non-hostname parts of URLs are unchanged
- (None, 'ТεЅТ̣', ['http://www.example.com/%(region)s/ubuntu'],
- ['http://www.example.com/ТεЅТ̣/ubuntu']),
- # Test that IPv4 addresses are unchanged
- (None, 'fk-fake-1', ['http://192.168.1.1:8080/%(region)s/ubuntu'],
- ['http://192.168.1.1:8080/fk-fake-1/ubuntu']),
- # Test that IPv6 addresses are unchanged
- (None, 'fk-fake-1',
- ['http://[2001:67c:1360:8001::23]/%(region)s/ubuntu'],
- ['http://[2001:67c:1360:8001::23]/fk-fake-1/ubuntu']),
- # Test that unparseable URLs are filtered out of the mirror list
- (None, 'inv[lid',
- ['http://%(region)s.in.hostname/should/be/filtered',
- 'http://but.not.in.the.path/%(region)s'],
- ['http://but.not.in.the.path/inv[lid']),
- (None, '-some-region-',
- ['http://-lead-ing.%(region)s.trail-ing-.example.com/ubuntu'],
- ['http://lead-ing.some-region.trail-ing.example.com/ubuntu']),
- ) + tuple(
- # Dynamically generate a test case for each non-LDH
- # (Letters/Digits/Hyphen) ASCII character, testing that it is
- # substituted with a hyphen
- (None, 'fk{0}fake{0}1'.format(invalid_char),
- ['http://%(region)s/ubuntu'], ['http://fk-fake-1/ubuntu'])
- for invalid_char in INVALID_URL_CHARS
- ))
- def test_valid_substitution(self,
- allow_ec2_mirror,
- platform_type,
- availability_zone,
- region,
- patterns,
- expected):
+ @pytest.mark.parametrize(
+ "allow_ec2_mirror, platform_type", [(True, "ec2")]
+ )
+ @pytest.mark.parametrize(
+ "availability_zone,region,patterns,expected",
+ (
+ # Test ec2_region alone
+ (
+ "fk-fake-1f",
+ None,
+ ["http://EC2-%(ec2_region)s/ubuntu"],
+ ["http://ec2-fk-fake-1/ubuntu"],
+ ),
+ # Test availability_zone alone
+ (
+ "fk-fake-1f",
+ None,
+ ["http://AZ-%(availability_zone)s/ubuntu"],
+ ["http://az-fk-fake-1f/ubuntu"],
+ ),
+ # Test region alone
+ (
+ None,
+ "fk-fake-1",
+ ["http://RG-%(region)s/ubuntu"],
+ ["http://rg-fk-fake-1/ubuntu"],
+ ),
+ # Test that ec2_region is not available for non-matching AZs
+ (
+ "fake-fake-1f",
+ None,
+ [
+ "http://EC2-%(ec2_region)s/ubuntu",
+ "http://AZ-%(availability_zone)s/ubuntu",
+ ],
+ ["http://az-fake-fake-1f/ubuntu"],
+ ),
+ # Test that template order maintained
+ (
+ None,
+ "fake-region",
+ [
+ "http://RG-%(region)s-2/ubuntu",
+ "http://RG-%(region)s-1/ubuntu",
+ ],
+ [
+ "http://rg-fake-region-2/ubuntu",
+ "http://rg-fake-region-1/ubuntu",
+ ],
+ ),
+ # Test that non-ASCII hostnames are IDNA encoded;
+ # "IDNA-ТεЅТ̣".encode('idna') == b"xn--idna--4kd53hh6aba3q"
+ (
+ None,
+ "ТεЅТ̣",
+ ["http://www.IDNA-%(region)s.com/ubuntu"],
+ ["http://www.xn--idna--4kd53hh6aba3q.com/ubuntu"],
+ ),
+ # Test that non-ASCII hostnames with a port are IDNA encoded;
+ # "IDNA-ТεЅТ̣".encode('idna') == b"xn--idna--4kd53hh6aba3q"
+ (
+ None,
+ "ТεЅТ̣",
+ ["http://www.IDNA-%(region)s.com:8080/ubuntu"],
+ ["http://www.xn--idna--4kd53hh6aba3q.com:8080/ubuntu"],
+ ),
+ # Test that non-ASCII non-hostname parts of URLs are unchanged
+ (
+ None,
+ "ТεЅТ̣",
+ ["http://www.example.com/%(region)s/ubuntu"],
+ ["http://www.example.com/ТεЅТ̣/ubuntu"],
+ ),
+ # Test that IPv4 addresses are unchanged
+ (
+ None,
+ "fk-fake-1",
+ ["http://192.168.1.1:8080/%(region)s/ubuntu"],
+ ["http://192.168.1.1:8080/fk-fake-1/ubuntu"],
+ ),
+ # Test that IPv6 addresses are unchanged
+ (
+ None,
+ "fk-fake-1",
+ ["http://[2001:67c:1360:8001::23]/%(region)s/ubuntu"],
+ ["http://[2001:67c:1360:8001::23]/fk-fake-1/ubuntu"],
+ ),
+ # Test that unparseable URLs are filtered out of the mirror list
+ (
+ None,
+ "inv[lid",
+ [
+ "http://%(region)s.in.hostname/should/be/filtered",
+ "http://but.not.in.the.path/%(region)s",
+ ],
+ ["http://but.not.in.the.path/inv[lid"],
+ ),
+ (
+ None,
+ "-some-region-",
+ ["http://-lead-ing.%(region)s.trail-ing-.example.com/ubuntu"],
+ ["http://lead-ing.some-region.trail-ing.example.com/ubuntu"],
+ ),
+ )
+ + tuple(
+ # Dynamically generate a test case for each non-LDH
+ # (Letters/Digits/Hyphen) ASCII character, testing that it is
+ # substituted with a hyphen
+ (
+ None,
+ "fk{0}fake{0}1".format(invalid_char),
+ ["http://%(region)s/ubuntu"],
+ ["http://fk-fake-1/ubuntu"],
+ )
+ for invalid_char in INVALID_URL_CHARS
+ ),
+ )
+ def test_valid_substitution(
+ self,
+ allow_ec2_mirror,
+ platform_type,
+ availability_zone,
+ region,
+ patterns,
+ expected,
+ ):
"""Test substitution works as expected."""
- flag_path = "cloudinit.distros." \
- "ALLOW_EC2_MIRRORS_ON_NON_AWS_INSTANCE_TYPES"
+ flag_path = (
+ "cloudinit.distros.ALLOW_EC2_MIRRORS_ON_NON_AWS_INSTANCE_TYPES"
+ )
m_data_source = mock.Mock(
availability_zone=availability_zone,
region=region,
- platform_type=platform_type
+ platform_type=platform_type,
)
- mirror_info = {'search': {'primary': patterns}}
+ mirror_info = {"search": {"primary": patterns}}
with mock.patch(flag_path, allow_ec2_mirror):
ret = _get_package_mirror_info(
mirror_info,
data_source=m_data_source,
- mirror_filter=lambda x: x
+ mirror_filter=lambda x: x,
)
print(allow_ec2_mirror)
print(platform_type)
@@ -158,4 +245,4 @@ class TestGetPackageMirrorInfo:
print(region)
print(patterns)
print(expected)
- assert {'primary': expected} == ret
+ assert {"primary": expected} == ret