← Back to team overview

cloud-init-dev team mailing list archive

Re: [Merge] ~smoser/cloud-init:cleanup/ec2-initial-tests into cloud-init:master

 

Inline comment below

Diff comments:

> diff --git a/tests/unittests/test_datasource/test_ec2.py b/tests/unittests/test_datasource/test_ec2.py
> new file mode 100644
> index 0000000..a5485ff
> --- /dev/null
> +++ b/tests/unittests/test_datasource/test_ec2.py
> @@ -0,0 +1,201 @@
> +# This file is part of cloud-init. See LICENSE file for license information.
> +
> +import httpretty
> +import mock
> +
> +from .. import helpers as test_helpers
> +from cloudinit import helpers
> +from cloudinit.sources import DataSourceEc2 as ec2
> +
> +
> +# collected from api version 2009-04-04/ with
> +# python3 -c 'import json
> +# from cloudinit.ec2_utils import get_instance_metadata as gm
> +# print(json.dumps(gm("2009-04-04"), indent=1, sort_keys=True))'
> +DEFAULT_METADATA = {
> +    "ami-id": "ami-80861296",
> +    "ami-launch-index": "0",
> +    "ami-manifest-path": "(unknown)",
> +    "block-device-mapping": {"ami": "/dev/sda1", "root": "/dev/sda1"},
> +    "hostname": "ip-10-0-0-149",
> +    "instance-action": "none",
> +    "instance-id": "i-0052913950685138c",
> +    "instance-type": "t2.micro",
> +    "local-hostname": "ip-10-0-0-149",
> +    "local-ipv4": "10.0.0.149",
> +    "placement": {"availability-zone": "us-east-1b"},
> +    "profile": "default-hvm",
> +    "public-hostname": "",
> +    "public-ipv4": "107.23.188.247",
> +    "public-keys": {"brickies": ["ssh-rsa AAAAB3Nz....w== brickies"]},
> +    "reservation-id": "r-00a2c173fb5782a08",
> +    "security-groups": "wide-open"
> +}
> +
> +
> +def register_ssh_keys(rfunc, base_url, keys_data):
> +    """handle ssh key inconsistencies.
> +
> +    public-keys in the ec2 metadata is inconsistently formated compared
> +    to other entries.
> +    Given keys_data of {name1: pubkey1, name2: pubkey2}
> +
> +    This registers the following urls:
> +       base_url                 0={name1}\n1={name2} # (for each name)
> +       base_url/                0={name1}\n1={name2} # (for each name)
> +       base_url/0               openssh-key
> +       base_url/0/              openssh-key
> +       base_url/0/openssh-key   {pubkey1}
> +       base_url/0/openssh-key/  {pubkey1}
> +       ...
> +    """
> +
> +    base_url = base_url.rstrip("/")
> +    odd_index = '\n'.join(
> +        ["{0}={1}".format(n, name)
> +         for n, name in enumerate(sorted(keys_data))])
> +
> +    rfunc(base_url, odd_index)
> +    rfunc(base_url + "/", odd_index)
> +
> +    for n, name in enumerate(sorted(keys_data)):
> +        val = keys_data[name]
> +        if isinstance(val, list):
> +            val = '\n'.join(val)
> +        burl = base_url + "/%s" % n
> +        rfunc(burl, "openssh-key")
> +        rfunc(burl + "/", "openssh-key")
> +        rfunc(burl + "/%s/openssh-key" % name, val)
> +        rfunc(burl + "/%s/openssh-key/" % name, val)
> +
> +
> +def register_mock_metaserver(base_url, data):
> +    """Register with httpretty a ec2 metadata like service serving 'data'.
> +
> +    If given a dictionary, it will populate urls under base_url for
> +    that dictionary.  For example, input of
> +       {"instance-id": "i-abc", "mac": "00:16:3e:00:00:00"}
> +    populates
> +       base_url  with 'instance-id\nmac'
> +       base_url/ with 'instance-id\nmac'
> +       base_url/instance-id with i-abc
> +       base_url/mac with 00:16:3e:00:00:00
> +    """
> +    def register_helper(register, base_url, body):
> +        if isinstance(body, str):
> +            register(base_url, body)
> +        elif isinstance(body, list):
> +            register(base_url.rstrip('/'), '\n'.join(body) + '\n')

there's a whole lot of .rstrip('/') and then appending.  Is there a more general way to do that?  Maybe I don't quite understand what's happening here so maybe a comment w.r.t all of the trailing slash stripping/appending.

> +            register(base_url.rstrip('/') + '/', '\n'.join(body) + '\n')
> +        elif isinstance(body, dict):
> +            vals = []
> +            for k, v in body.items():
> +                if k == 'public-keys':
> +                    register_ssh_keys(
> +                        register, base_url.rstrip('/') + '/public-keys/', v)
> +                    continue
> +                if isinstance(v, (str, list)):
> +                    suffix = k.rstrip('/')
> +                else:
> +                    suffix = k.rstrip('/') + '/'
> +                vals.append(suffix)
> +                url = base_url.rstrip('/') + '/' + suffix
> +                register_helper(register, url, v)
> +            register(base_url.rstrip('/'), '\n'.join(vals) + '\n')
> +            register(base_url.rstrip('/') + '/', '\n'.join(vals) + '\n')
> +        elif body is None:
> +            register(base_url.rstrip('/'), 'not found', status_code=404)
> +
> +    def myreg(*argc, **kwargs):
> +        # print("register_url(%s, %s)" % (argc, kwargs))
> +        return httpretty.register_uri(httpretty.GET, *argc, **kwargs)
> +
> +    register_helper(myreg, base_url, data)
> +
> +
> +class TestEc2(test_helpers.HttprettyTestCase):
> +    valid_platform_data = {
> +        'uuid': 'ec212f79-87d1-2f1d-588f-d86dc0fd5412',
> +        'uuid_source': 'dmi',
> +        'serial': 'ec212f79-87d1-2f1d-588f-d86dc0fd5412',
> +    }
> +
> +    def setUp(self):
> +        super(TestEc2, self).setUp()
> +        self.metadata_addr = ec2.DataSourceEc2.metadata_urls[0]
> +        self.api_ver = '2009-04-04'
> +
> +    @property
> +    def metadata_url(self):
> +        return '/'.join([self.metadata_addr, self.api_ver, 'meta-data', ''])
> +
> +    @property
> +    def userdata_url(self):
> +        return '/'.join([self.metadata_addr, self.api_ver, 'user-data'])
> +
> +    def _patch_add_cleanup(self, mpath, *args, **kwargs):
> +        p = mock.patch(mpath, *args, **kwargs)
> +        p.start()
> +        self.addCleanup(p.stop)
> +
> +    def _setup_ds(self, sys_cfg=None, platform_data=None, md=None, ud=None):
> +        distro = {}
> +        paths = helpers.Paths({})
> +        if sys_cfg is None:
> +            sys_cfg = {}
> +        ds = ec2.DataSourceEc2(sys_cfg=sys_cfg, distro=distro, paths=paths)
> +        if platform_data is not None:
> +            self._patch_add_cleanup(
> +                "cloudinit.sources.DataSourceEc2._collect_platform_data",
> +                return_value=platform_data)
> +
> +        if md:
> +            register_mock_metaserver(self.metadata_url, md)
> +            register_mock_metaserver(self.userdata_url, ud)
> +
> +        return ds
> +
> +    @httpretty.activate
> +    def test_valid_platform_with_strict_true(self):
> +        """Valid platform data should return true with strict_id true."""
> +        ds = self._setup_ds(
> +            platform_data=self.valid_platform_data,
> +            sys_cfg={'datasource': {'Ec2': {'strict_id': True}}},
> +            md=DEFAULT_METADATA)
> +        ret = ds.get_data()
> +        self.assertEqual(True, ret)
> +
> +    @httpretty.activate
> +    def test_valid_platform_with_strict_false(self):
> +        """Valid platform data should return true with strict_id false."""
> +        ds = self._setup_ds(
> +            platform_data=self.valid_platform_data,
> +            sys_cfg={'datasource': {'Ec2': {'strict_id': False}}},
> +            md=DEFAULT_METADATA)
> +        ret = ds.get_data()
> +        self.assertEqual(True, ret)
> +
> +    @httpretty.activate
> +    def test_unknown_platform_with_strict_true(self):
> +        """Unknown platform data with strict_id true should return False."""
> +        uuid = 'ab439480-72bf-11d3-91fc-b8aded755F9a'
> +        ds = self._setup_ds(
> +            platform_data={'uuid': uuid, 'uuid_source': 'dmi', 'serial': ''},
> +            sys_cfg={'datasource': {'Ec2': {'strict_id': True}}},
> +            md=DEFAULT_METADATA)
> +        ret = ds.get_data()
> +        self.assertEqual(False, ret)
> +
> +    @httpretty.activate
> +    def test_unknown_platform_with_strict_false(self):
> +        """Unknown platform data with strict_id false should return True."""
> +        uuid = 'ab439480-72bf-11d3-91fc-b8aded755F9a'
> +        ds = self._setup_ds(
> +            platform_data={'uuid': uuid, 'uuid_source': 'dmi', 'serial': ''},
> +            sys_cfg={'datasource': {'Ec2': {'strict_id': False}}},
> +            md=DEFAULT_METADATA)
> +        ret = ds.get_data()
> +        self.assertEqual(True, ret)
> +
> +
> +# vi: ts=4 expandtab


-- 
https://code.launchpad.net/~smoser/cloud-init/+git/cloud-init/+merge/327534
Your team cloud-init commiters is requested to review the proposed merge of ~smoser/cloud-init:cleanup/ec2-initial-tests into cloud-init:master.


References