summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorScott Moser <smoser@brickies.net>2016-08-12 17:05:04 -0400
committerScott Moser <smoser@brickies.net>2016-08-12 17:05:04 -0400
commitbf1728902bd3e81e00aa9786a5b1c67e4f30a659 (patch)
tree857c914003fda2ec5223425a31b646cbafd9907b /tests
parente28ba310872846e0bc60595aed353c17b760fdcb (diff)
parentbc2c3267549b9067c017a34e22bbee18890aec06 (diff)
downloadvyos-cloud-init-bf1728902bd3e81e00aa9786a5b1c67e4f30a659.tar.gz
vyos-cloud-init-bf1728902bd3e81e00aa9786a5b1c67e4f30a659.zip
Merge branch 'master' into ubuntu/devel
Diffstat (limited to 'tests')
-rw-r--r--tests/unittests/helpers.py4
-rw-r--r--tests/unittests/test_datasource/test_configdrive.py44
-rw-r--r--tests/unittests/test_datasource/test_digitalocean.py67
-rw-r--r--tests/unittests/test_datasource/test_maas.py127
-rw-r--r--tests/unittests/test_datasource/test_nocloud.py85
-rw-r--r--tests/unittests/test_datasource/test_openstack.py3
-rw-r--r--tests/unittests/test_datasource/test_smartos.py350
-rw-r--r--tests/unittests/test_handler/test_handler_mcollective.py1
-rw-r--r--tests/unittests/test_handler/test_handler_ntp.py274
-rw-r--r--tests/unittests/test_util.py26
10 files changed, 866 insertions, 115 deletions
diff --git a/tests/unittests/helpers.py b/tests/unittests/helpers.py
index 972245df..de2cf638 100644
--- a/tests/unittests/helpers.py
+++ b/tests/unittests/helpers.py
@@ -256,7 +256,9 @@ def populate_dir(path, files):
if not os.path.exists(path):
os.makedirs(path)
for (name, content) in files.items():
- with open(os.path.join(path, name), "wb") as fp:
+ p = os.path.join(path, name)
+ util.ensure_dir(os.path.dirname(p))
+ with open(p, "wb") as fp:
if isinstance(content, six.binary_type):
fp.write(content)
else:
diff --git a/tests/unittests/test_datasource/test_configdrive.py b/tests/unittests/test_datasource/test_configdrive.py
index 18551b92..d0269943 100644
--- a/tests/unittests/test_datasource/test_configdrive.py
+++ b/tests/unittests/test_datasource/test_configdrive.py
@@ -101,6 +101,41 @@ NETWORK_DATA_2 = {
"type": "vif", "id": "eth1", "vif_id": "vif-foo2"}]
}
+# This network data ha 'tap' type for a link.
+NETWORK_DATA_3 = {
+ "services": [{"type": "dns", "address": "172.16.36.11"},
+ {"type": "dns", "address": "172.16.36.12"}],
+ "networks": [
+ {"network_id": "7c41450c-ba44-401a-9ab1-1604bb2da51e",
+ "type": "ipv4", "netmask": "255.255.255.128",
+ "link": "tap77a0dc5b-72", "ip_address": "172.17.48.18",
+ "id": "network0",
+ "routes": [{"netmask": "0.0.0.0", "network": "0.0.0.0",
+ "gateway": "172.17.48.1"}]},
+ {"network_id": "7c41450c-ba44-401a-9ab1-1604bb2da51e",
+ "type": "ipv6", "netmask": "ffff:ffff:ffff:ffff::",
+ "link": "tap77a0dc5b-72",
+ "ip_address": "fdb8:52d0:9d14:0:f816:3eff:fe9f:70d",
+ "id": "network1",
+ "routes": [{"netmask": "::", "network": "::",
+ "gateway": "fdb8:52d0:9d14::1"}]},
+ {"network_id": "1f53cb0e-72d3-47c7-94b9-ff4397c5fe54",
+ "type": "ipv4", "netmask": "255.255.255.128",
+ "link": "tap7d6b7bec-93", "ip_address": "172.16.48.13",
+ "id": "network2",
+ "routes": [{"netmask": "0.0.0.0", "network": "0.0.0.0",
+ "gateway": "172.16.48.1"},
+ {"netmask": "255.255.0.0", "network": "172.16.0.0",
+ "gateway": "172.16.48.1"}]}],
+ "links": [
+ {"ethernet_mac_address": "fa:16:3e:dd:50:9a", "mtu": None,
+ "type": "tap", "id": "tap77a0dc5b-72",
+ "vif_id": "77a0dc5b-720e-41b7-bfa7-1b2ff62e0d48"},
+ {"ethernet_mac_address": "fa:16:3e:a8:14:69", "mtu": None,
+ "type": "tap", "id": "tap7d6b7bec-93",
+ "vif_id": "7d6b7bec-93e6-4c03-869a-ddc5014892d5"}
+ ]
+}
KNOWN_MACS = {
'fa:16:3e:69:b0:58': 'enp0s1',
@@ -555,6 +590,15 @@ class TestConvertNetworkData(TestCase):
eni_rendering = f.read()
self.assertIn("route add default gw 2.2.2.9", eni_rendering)
+ def test_conversion_with_tap(self):
+ ncfg = openstack.convert_net_json(NETWORK_DATA_3,
+ known_macs=KNOWN_MACS)
+ physicals = set()
+ for i in ncfg['config']:
+ if i.get('type') == "physical":
+ physicals.add(i['name'])
+ self.assertEqual(physicals, set(('foo1', 'foo2')))
+
def cfg_ds_from_dir(seed_d):
cfg_ds = ds.DataSourceConfigDrive(settings.CFG_BUILTIN, None,
diff --git a/tests/unittests/test_datasource/test_digitalocean.py b/tests/unittests/test_datasource/test_digitalocean.py
index 8936a1e3..f5d2ef35 100644
--- a/tests/unittests/test_datasource/test_digitalocean.py
+++ b/tests/unittests/test_datasource/test_digitalocean.py
@@ -15,68 +15,58 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-import re
-
-from six.moves.urllib_parse import urlparse
+import json
from cloudinit import helpers
from cloudinit import settings
from cloudinit.sources import DataSourceDigitalOcean
from .. import helpers as test_helpers
+from ..helpers import HttprettyTestCase
httpretty = test_helpers.import_httpretty()
-# Abbreviated for the test
-DO_INDEX = """id
- hostname
- user-data
- vendor-data
- public-keys
- region"""
-
-DO_MULTIPLE_KEYS = """ssh-rsa AAAAB3NzaC1yc2EAAAA... neal@digitalocean.com
- ssh-rsa AAAAB3NzaC1yc2EAAAA... neal2@digitalocean.com"""
-DO_SINGLE_KEY = "ssh-rsa AAAAB3NzaC1yc2EAAAA... neal@digitalocean.com"
+DO_MULTIPLE_KEYS = ["ssh-rsa AAAAB3NzaC1yc2EAAAA... test1@do.co",
+ "ssh-rsa AAAAB3NzaC1yc2EAAAA... test2@do.co"]
+DO_SINGLE_KEY = "ssh-rsa AAAAB3NzaC1yc2EAAAA... test@do.co"
DO_META = {
- '': DO_INDEX,
- 'user-data': '#!/bin/bash\necho "user-data"',
- 'vendor-data': '#!/bin/bash\necho "vendor-data"',
- 'public-keys': DO_SINGLE_KEY,
+ 'user_data': 'user_data_here',
+ 'vendor_data': 'vendor_data_here',
+ 'public_keys': DO_SINGLE_KEY,
'region': 'nyc3',
'id': '2000000',
'hostname': 'cloudinit-test',
}
-MD_URL_RE = re.compile(r'http://169.254.169.254/metadata/v1/.*')
+MD_URL = 'http://169.254.169.254/metadata/v1.json'
+
+
+def _mock_dmi():
+ return (True, DO_META.get('id'))
def _request_callback(method, uri, headers):
- url_path = urlparse(uri).path
- if url_path.startswith('/metadata/v1/'):
- path = url_path.split('/metadata/v1/')[1:][0]
- else:
- path = None
- if path in DO_META:
- return (200, headers, DO_META.get(path))
- else:
- return (404, headers, '')
+ return (200, headers, json.dumps(DO_META))
-class TestDataSourceDigitalOcean(test_helpers.HttprettyTestCase):
+class TestDataSourceDigitalOcean(HttprettyTestCase):
+ """
+ Test reading the meta-data
+ """
def setUp(self):
self.ds = DataSourceDigitalOcean.DataSourceDigitalOcean(
settings.CFG_BUILTIN, None,
helpers.Paths({}))
+ self.ds._get_sysinfo = _mock_dmi
super(TestDataSourceDigitalOcean, self).setUp()
@httpretty.activate
def test_connection(self):
httpretty.register_uri(
- httpretty.GET, MD_URL_RE,
- body=_request_callback)
+ httpretty.GET, MD_URL,
+ body=json.dumps(DO_META))
success = self.ds.get_data()
self.assertTrue(success)
@@ -84,14 +74,14 @@ class TestDataSourceDigitalOcean(test_helpers.HttprettyTestCase):
@httpretty.activate
def test_metadata(self):
httpretty.register_uri(
- httpretty.GET, MD_URL_RE,
+ httpretty.GET, MD_URL,
body=_request_callback)
self.ds.get_data()
- self.assertEqual(DO_META.get('user-data'),
+ self.assertEqual(DO_META.get('user_data'),
self.ds.get_userdata_raw())
- self.assertEqual(DO_META.get('vendor-data'),
+ self.assertEqual(DO_META.get('vendor_data'),
self.ds.get_vendordata_raw())
self.assertEqual(DO_META.get('region'),
@@ -103,11 +93,8 @@ class TestDataSourceDigitalOcean(test_helpers.HttprettyTestCase):
self.assertEqual(DO_META.get('hostname'),
self.ds.get_hostname())
- self.assertEqual('http://mirrors.digitalocean.com/',
- self.ds.get_package_mirror_info())
-
# Single key
- self.assertEqual([DO_META.get('public-keys')],
+ self.assertEqual([DO_META.get('public_keys')],
self.ds.get_public_ssh_keys())
self.assertIsInstance(self.ds.get_public_ssh_keys(), list)
@@ -116,12 +103,12 @@ class TestDataSourceDigitalOcean(test_helpers.HttprettyTestCase):
def test_multiple_ssh_keys(self):
DO_META['public_keys'] = DO_MULTIPLE_KEYS
httpretty.register_uri(
- httpretty.GET, MD_URL_RE,
+ httpretty.GET, MD_URL,
body=_request_callback)
self.ds.get_data()
# Multiple keys
- self.assertEqual(DO_META.get('public-keys').splitlines(),
+ self.assertEqual(DO_META.get('public_keys'),
self.ds.get_public_ssh_keys())
self.assertIsInstance(self.ds.get_public_ssh_keys(), list)
diff --git a/tests/unittests/test_datasource/test_maas.py b/tests/unittests/test_datasource/test_maas.py
index f66f1c6d..0126c883 100644
--- a/tests/unittests/test_datasource/test_maas.py
+++ b/tests/unittests/test_datasource/test_maas.py
@@ -2,6 +2,7 @@ from copy import copy
import os
import shutil
import tempfile
+import yaml
from cloudinit.sources import DataSourceMAAS
from cloudinit import url_helper
@@ -24,41 +25,44 @@ class TestMAASDataSource(TestCase):
def test_seed_dir_valid(self):
"""Verify a valid seeddir is read as such."""
- data = {'instance-id': 'i-valid01',
- 'local-hostname': 'valid01-hostname',
- 'user-data': b'valid01-userdata',
+ userdata = b'valid01-userdata'
+ data = {'meta-data/instance-id': 'i-valid01',
+ 'meta-data/local-hostname': 'valid01-hostname',
+ 'user-data': userdata,
'public-keys': 'ssh-rsa AAAAB3Nz...aC1yc2E= keyname'}
my_d = os.path.join(self.tmp, "valid")
populate_dir(my_d, data)
- (userdata, metadata) = DataSourceMAAS.read_maas_seed_dir(my_d)
+ ud, md, vd = DataSourceMAAS.read_maas_seed_dir(my_d)
- self.assertEqual(userdata, data['user-data'])
+ self.assertEqual(userdata, ud)
for key in ('instance-id', 'local-hostname'):
- self.assertEqual(data[key], metadata[key])
+ self.assertEqual(data["meta-data/" + key], md[key])
# verify that 'userdata' is not returned as part of the metadata
- self.assertFalse(('user-data' in metadata))
+ self.assertFalse(('user-data' in md))
+ self.assertEqual(vd, None)
def test_seed_dir_valid_extra(self):
"""Verify extra files do not affect seed_dir validity."""
- data = {'instance-id': 'i-valid-extra',
- 'local-hostname': 'valid-extra-hostname',
- 'user-data': b'valid-extra-userdata', 'foo': 'bar'}
+ userdata = b'valid-extra-userdata'
+ data = {'meta-data/instance-id': 'i-valid-extra',
+ 'meta-data/local-hostname': 'valid-extra-hostname',
+ 'user-data': userdata, 'foo': 'bar'}
my_d = os.path.join(self.tmp, "valid_extra")
populate_dir(my_d, data)
- (userdata, metadata) = DataSourceMAAS.read_maas_seed_dir(my_d)
+ ud, md, vd = DataSourceMAAS.read_maas_seed_dir(my_d)
- self.assertEqual(userdata, data['user-data'])
+ self.assertEqual(userdata, ud)
for key in ('instance-id', 'local-hostname'):
- self.assertEqual(data[key], metadata[key])
+ self.assertEqual(data['meta-data/' + key], md[key])
# additional files should not just appear as keys in metadata atm
- self.assertFalse(('foo' in metadata))
+ self.assertFalse(('foo' in md))
def test_seed_dir_invalid(self):
"""Verify that invalid seed_dir raises MAASSeedDirMalformed."""
@@ -97,67 +101,60 @@ class TestMAASDataSource(TestCase):
DataSourceMAAS.read_maas_seed_dir,
os.path.join(self.tmp, "nonexistantdirectory"))
+ def mock_read_maas_seed_url(self, data, seed, version="19991231"):
+ """mock up readurl to appear as a web server at seed has provided data.
+ return what read_maas_seed_url returns."""
+ def my_readurl(*args, **kwargs):
+ if len(args):
+ url = args[0]
+ else:
+ url = kwargs['url']
+ prefix = "%s/%s/" % (seed, version)
+ if not url.startswith(prefix):
+ raise ValueError("unexpected call %s" % url)
+
+ short = url[len(prefix):]
+ if short not in data:
+ raise url_helper.UrlError("not found", code=404, url=url)
+ return url_helper.StringResponse(data[short])
+
+ # Now do the actual call of the code under test.
+ with mock.patch("cloudinit.url_helper.readurl") as mock_readurl:
+ mock_readurl.side_effect = my_readurl
+ return DataSourceMAAS.read_maas_seed_url(seed, version=version)
+
def test_seed_url_valid(self):
"""Verify that valid seed_url is read as such."""
valid = {
'meta-data/instance-id': 'i-instanceid',
'meta-data/local-hostname': 'test-hostname',
'meta-data/public-keys': 'test-hostname',
+ 'meta-data/vendor-data': b'my-vendordata',
'user-data': b'foodata',
}
- valid_order = [
- 'meta-data/local-hostname',
- 'meta-data/instance-id',
- 'meta-data/public-keys',
- 'user-data',
- ]
my_seed = "http://example.com/xmeta"
my_ver = "1999-99-99"
- my_headers = {'header1': 'value1', 'header2': 'value2'}
-
- def my_headers_cb(url):
- return my_headers
-
- # Each time url_helper.readurl() is called, something different is
- # returned based on the canned data above. We need to build up a list
- # of side effect return values, which the mock will return. At the
- # same time, we'll build up a list of expected call arguments for
- # asserting after the code under test is run.
- calls = []
-
- def side_effect():
- for key in valid_order:
- resp = valid.get(key)
- url = "%s/%s/%s" % (my_seed, my_ver, key)
- calls.append(
- mock.call(url, headers=None, timeout=mock.ANY,
- data=mock.ANY, sec_between=mock.ANY,
- ssl_details=mock.ANY, retries=mock.ANY,
- headers_cb=my_headers_cb,
- exception_cb=mock.ANY))
- yield url_helper.StringResponse(resp)
-
- # Now do the actual call of the code under test.
- with mock.patch.object(url_helper, 'readurl',
- side_effect=side_effect()) as mockobj:
- userdata, metadata = DataSourceMAAS.read_maas_seed_url(
- my_seed, version=my_ver)
-
- self.assertEqual(b"foodata", userdata)
- self.assertEqual(metadata['instance-id'],
- valid['meta-data/instance-id'])
- self.assertEqual(metadata['local-hostname'],
- valid['meta-data/local-hostname'])
-
- mockobj.has_calls(calls)
-
- def test_seed_url_invalid(self):
- """Verify that invalid seed_url raises MAASSeedDirMalformed."""
- pass
-
- def test_seed_url_missing(self):
- """Verify seed_url with no found entries raises MAASSeedDirNone."""
- pass
+ ud, md, vd = self.mock_read_maas_seed_url(valid, my_seed, my_ver)
+
+ self.assertEqual(valid['meta-data/instance-id'], md['instance-id'])
+ self.assertEqual(
+ valid['meta-data/local-hostname'], md['local-hostname'])
+ self.assertEqual(valid['meta-data/public-keys'], md['public-keys'])
+ self.assertEqual(valid['user-data'], ud)
+ # vendor-data is yaml, which decodes a string
+ self.assertEqual(valid['meta-data/vendor-data'].decode(), vd)
+
+ def test_seed_url_vendor_data_dict(self):
+ expected_vd = {'key1': 'value1'}
+ valid = {
+ 'meta-data/instance-id': 'i-instanceid',
+ 'meta-data/local-hostname': 'test-hostname',
+ 'meta-data/vendor-data': yaml.safe_dump(expected_vd).encode(),
+ }
+ ud, md, vd = self.mock_read_maas_seed_url(
+ valid, "http://example.com/foo")
+ self.assertEqual(valid['meta-data/instance-id'], md['instance-id'])
+ self.assertEqual(expected_vd, vd)
# vi: ts=4 expandtab
diff --git a/tests/unittests/test_datasource/test_nocloud.py b/tests/unittests/test_datasource/test_nocloud.py
index b0fa1130..f6a46ce9 100644
--- a/tests/unittests/test_datasource/test_nocloud.py
+++ b/tests/unittests/test_datasource/test_nocloud.py
@@ -6,7 +6,7 @@ from ..helpers import TestCase, populate_dir, mock, ExitStack
import os
import shutil
import tempfile
-
+import textwrap
import yaml
@@ -129,6 +129,89 @@ class TestNoCloudDataSource(TestCase):
self.assertFalse(dsrc.vendordata)
self.assertTrue(ret)
+ def test_metadata_network_interfaces(self):
+ gateway = "103.225.10.1"
+ md = {
+ 'instance-id': 'i-abcd',
+ 'local-hostname': 'hostname1',
+ 'network-interfaces': textwrap.dedent("""\
+ auto eth0
+ iface eth0 inet static
+ hwaddr 00:16:3e:70:e1:04
+ address 103.225.10.12
+ netmask 255.255.255.0
+ gateway """ + gateway + """
+ dns-servers 8.8.8.8""")}
+
+ populate_dir(
+ os.path.join(self.paths.seed_dir, "nocloud"),
+ {'user-data': b"ud",
+ 'meta-data': yaml.dump(md) + "\n"})
+
+ sys_cfg = {'datasource': {'NoCloud': {'fs_label': None}}}
+
+ ds = DataSourceNoCloud.DataSourceNoCloud
+
+ dsrc = ds(sys_cfg=sys_cfg, distro=None, paths=self.paths)
+ ret = dsrc.get_data()
+ self.assertTrue(ret)
+ # very simple check just for the strings above
+ self.assertIn(gateway, str(dsrc.network_config))
+
+ def test_metadata_network_config(self):
+ # network-config needs to get into network_config
+ netconf = {'version': 1,
+ 'config': [{'type': 'physical', 'name': 'interface0',
+ 'subnets': [{'type': 'dhcp'}]}]}
+ populate_dir(
+ os.path.join(self.paths.seed_dir, "nocloud"),
+ {'user-data': b"ud",
+ 'meta-data': "instance-id: IID\n",
+ 'network-config': yaml.dump(netconf) + "\n"})
+
+ sys_cfg = {'datasource': {'NoCloud': {'fs_label': None}}}
+
+ ds = DataSourceNoCloud.DataSourceNoCloud
+
+ dsrc = ds(sys_cfg=sys_cfg, distro=None, paths=self.paths)
+ ret = dsrc.get_data()
+ self.assertTrue(ret)
+ self.assertEqual(netconf, dsrc.network_config)
+
+ def test_metadata_network_config_over_interfaces(self):
+ # network-config should override meta-data/network-interfaces
+ gateway = "103.225.10.1"
+ md = {
+ 'instance-id': 'i-abcd',
+ 'local-hostname': 'hostname1',
+ 'network-interfaces': textwrap.dedent("""\
+ auto eth0
+ iface eth0 inet static
+ hwaddr 00:16:3e:70:e1:04
+ address 103.225.10.12
+ netmask 255.255.255.0
+ gateway """ + gateway + """
+ dns-servers 8.8.8.8""")}
+
+ netconf = {'version': 1,
+ 'config': [{'type': 'physical', 'name': 'interface0',
+ 'subnets': [{'type': 'dhcp'}]}]}
+ populate_dir(
+ os.path.join(self.paths.seed_dir, "nocloud"),
+ {'user-data': b"ud",
+ 'meta-data': yaml.dump(md) + "\n",
+ 'network-config': yaml.dump(netconf) + "\n"})
+
+ sys_cfg = {'datasource': {'NoCloud': {'fs_label': None}}}
+
+ ds = DataSourceNoCloud.DataSourceNoCloud
+
+ dsrc = ds(sys_cfg=sys_cfg, distro=None, paths=self.paths)
+ ret = dsrc.get_data()
+ self.assertTrue(ret)
+ self.assertEqual(netconf, dsrc.network_config)
+ self.assertNotIn(gateway, str(dsrc.network_config))
+
class TestParseCommandLineData(TestCase):
diff --git a/tests/unittests/test_datasource/test_openstack.py b/tests/unittests/test_datasource/test_openstack.py
index 5c8592c5..97b99a18 100644
--- a/tests/unittests/test_datasource/test_openstack.py
+++ b/tests/unittests/test_datasource/test_openstack.py
@@ -27,6 +27,7 @@ from six import StringIO
from cloudinit import helpers
from cloudinit import settings
+from cloudinit.sources import convert_vendordata
from cloudinit.sources import DataSourceOpenStack as ds
from cloudinit.sources.helpers import openstack
from cloudinit import util
@@ -318,7 +319,7 @@ class TestOpenStackDataSource(test_helpers.HttprettyTestCase):
class TestVendorDataLoading(test_helpers.TestCase):
def cvj(self, data):
- return openstack.convert_vendordata_json(data)
+ return convert_vendordata(data)
def test_vd_load_none(self):
# non-existant vendor-data should return none
diff --git a/tests/unittests/test_datasource/test_smartos.py b/tests/unittests/test_datasource/test_smartos.py
index 9c6c8768..0532f986 100644
--- a/tests/unittests/test_datasource/test_smartos.py
+++ b/tests/unittests/test_datasource/test_smartos.py
@@ -36,6 +36,8 @@ import uuid
from cloudinit import serial
from cloudinit.sources import DataSourceSmartOS
+from cloudinit.sources.DataSourceSmartOS import (
+ convert_smartos_network_data as convert_net)
import six
@@ -86,6 +88,229 @@ SDC_NICS = json.loads("""
]
""")
+
+SDC_NICS_ALT = json.loads("""
+[
+ {
+ "interface": "net0",
+ "mac": "90:b8:d0:ae:64:51",
+ "vlan_id": 324,
+ "nic_tag": "external",
+ "gateway": "8.12.42.1",
+ "gateways": [
+ "8.12.42.1"
+ ],
+ "netmask": "255.255.255.0",
+ "ip": "8.12.42.51",
+ "ips": [
+ "8.12.42.51/24"
+ ],
+ "network_uuid": "992fc7ce-6aac-4b74-aed6-7b9d2c6c0bfe",
+ "model": "virtio",
+ "mtu": 1500,
+ "primary": true
+ },
+ {
+ "interface": "net1",
+ "mac": "90:b8:d0:bd:4f:9c",
+ "vlan_id": 600,
+ "nic_tag": "internal",
+ "netmask": "255.255.255.0",
+ "ip": "10.210.1.217",
+ "ips": [
+ "10.210.1.217/24"
+ ],
+ "network_uuid": "98657fdf-11f4-4ee2-88a4-ce7fe73e33a6",
+ "model": "virtio",
+ "mtu": 1500
+ }
+]
+""")
+
+SDC_NICS_DHCP = json.loads("""
+[
+ {
+ "interface": "net0",
+ "mac": "90:b8:d0:ae:64:51",
+ "vlan_id": 324,
+ "nic_tag": "external",
+ "gateway": "8.12.42.1",
+ "gateways": [
+ "8.12.42.1"
+ ],
+ "netmask": "255.255.255.0",
+ "ip": "8.12.42.51",
+ "ips": [
+ "8.12.42.51/24"
+ ],
+ "network_uuid": "992fc7ce-6aac-4b74-aed6-7b9d2c6c0bfe",
+ "model": "virtio",
+ "mtu": 1500,
+ "primary": true
+ },
+ {
+ "interface": "net1",
+ "mac": "90:b8:d0:bd:4f:9c",
+ "vlan_id": 600,
+ "nic_tag": "internal",
+ "netmask": "255.255.255.0",
+ "ip": "10.210.1.217",
+ "ips": [
+ "dhcp"
+ ],
+ "network_uuid": "98657fdf-11f4-4ee2-88a4-ce7fe73e33a6",
+ "model": "virtio",
+ "mtu": 1500
+ }
+]
+""")
+
+SDC_NICS_MIP = json.loads("""
+[
+ {
+ "interface": "net0",
+ "mac": "90:b8:d0:ae:64:51",
+ "vlan_id": 324,
+ "nic_tag": "external",
+ "gateway": "8.12.42.1",
+ "gateways": [
+ "8.12.42.1"
+ ],
+ "netmask": "255.255.255.0",
+ "ip": "8.12.42.51",
+ "ips": [
+ "8.12.42.51/24",
+ "8.12.42.52/24"
+ ],
+ "network_uuid": "992fc7ce-6aac-4b74-aed6-7b9d2c6c0bfe",
+ "model": "virtio",
+ "mtu": 1500,
+ "primary": true
+ },
+ {
+ "interface": "net1",
+ "mac": "90:b8:d0:bd:4f:9c",
+ "vlan_id": 600,
+ "nic_tag": "internal",
+ "netmask": "255.255.255.0",
+ "ip": "10.210.1.217",
+ "ips": [
+ "10.210.1.217/24",
+ "10.210.1.151/24"
+ ],
+ "network_uuid": "98657fdf-11f4-4ee2-88a4-ce7fe73e33a6",
+ "model": "virtio",
+ "mtu": 1500
+ }
+]
+""")
+
+SDC_NICS_MIP_IPV6 = json.loads("""
+[
+ {
+ "interface": "net0",
+ "mac": "90:b8:d0:ae:64:51",
+ "vlan_id": 324,
+ "nic_tag": "external",
+ "gateway": "8.12.42.1",
+ "gateways": [
+ "8.12.42.1"
+ ],
+ "netmask": "255.255.255.0",
+ "ip": "8.12.42.51",
+ "ips": [
+ "2001:4800:78ff:1b:be76:4eff:fe06:96b3/64",
+ "8.12.42.51/24"
+ ],
+ "network_uuid": "992fc7ce-6aac-4b74-aed6-7b9d2c6c0bfe",
+ "model": "virtio",
+ "mtu": 1500,
+ "primary": true
+ },
+ {
+ "interface": "net1",
+ "mac": "90:b8:d0:bd:4f:9c",
+ "vlan_id": 600,
+ "nic_tag": "internal",
+ "netmask": "255.255.255.0",
+ "ip": "10.210.1.217",
+ "ips": [
+ "10.210.1.217/24"
+ ],
+ "network_uuid": "98657fdf-11f4-4ee2-88a4-ce7fe73e33a6",
+ "model": "virtio",
+ "mtu": 1500
+ }
+]
+""")
+
+SDC_NICS_IPV4_IPV6 = json.loads("""
+[
+ {
+ "interface": "net0",
+ "mac": "90:b8:d0:ae:64:51",
+ "vlan_id": 324,
+ "nic_tag": "external",
+ "gateway": "8.12.42.1",
+ "gateways": ["8.12.42.1", "2001::1", "2001::2"],
+ "netmask": "255.255.255.0",
+ "ip": "8.12.42.51",
+ "ips": ["2001::10/64", "8.12.42.51/24", "2001::11/64",
+ "8.12.42.52/32"],
+ "network_uuid": "992fc7ce-6aac-4b74-aed6-7b9d2c6c0bfe",
+ "model": "virtio",
+ "mtu": 1500,
+ "primary": true
+ },
+ {
+ "interface": "net1",
+ "mac": "90:b8:d0:bd:4f:9c",
+ "vlan_id": 600,
+ "nic_tag": "internal",
+ "netmask": "255.255.255.0",
+ "ip": "10.210.1.217",
+ "ips": ["10.210.1.217/24"],
+ "gateways": ["10.210.1.210"],
+ "network_uuid": "98657fdf-11f4-4ee2-88a4-ce7fe73e33a6",
+ "model": "virtio",
+ "mtu": 1500
+ }
+]
+""")
+
+SDC_NICS_SINGLE_GATEWAY = json.loads("""
+[
+ {
+ "interface":"net0",
+ "mac":"90:b8:d0:d8:82:b4",
+ "vlan_id":324,
+ "nic_tag":"external",
+ "gateway":"8.12.42.1",
+ "gateways":["8.12.42.1"],
+ "netmask":"255.255.255.0",
+ "ip":"8.12.42.26",
+ "ips":["8.12.42.26/24"],
+ "network_uuid":"992fc7ce-6aac-4b74-aed6-7b9d2c6c0bfe",
+ "model":"virtio",
+ "mtu":1500,
+ "primary":true
+ },
+ {
+ "interface":"net1",
+ "mac":"90:b8:d0:0a:51:31",
+ "vlan_id":600,
+ "nic_tag":"internal",
+ "netmask":"255.255.255.0",
+ "ip":"10.210.1.27",
+ "ips":["10.210.1.27/24"],
+ "network_uuid":"98657fdf-11f4-4ee2-88a4-ce7fe73e33a6",
+ "model":"virtio",
+ "mtu":1500
+ }
+]
+""")
+
+
MOCK_RETURNS = {
'hostname': 'test-host',
'root_authorized_keys': 'ssh-rsa AAAAB3Nz...aC1yc2E= keyname',
@@ -524,20 +749,135 @@ class TestJoyentMetadataClient(FilesystemMockingTestCase):
class TestNetworkConversion(TestCase):
-
def test_convert_simple(self):
expected = {
'version': 1,
'config': [
{'name': 'net0', 'type': 'physical',
'subnets': [{'type': 'static', 'gateway': '8.12.42.1',
- 'netmask': '255.255.255.0',
'address': '8.12.42.102/24'}],
'mtu': 1500, 'mac_address': '90:b8:d0:f5:e4:f5'},
{'name': 'net1', 'type': 'physical',
- 'subnets': [{'type': 'static', 'gateway': '192.168.128.1',
- 'netmask': '255.255.252.0',
+ 'subnets': [{'type': 'static',
'address': '192.168.128.93/22'}],
'mtu': 8500, 'mac_address': '90:b8:d0:a5:ff:cd'}]}
- found = DataSourceSmartOS.convert_smartos_network_data(SDC_NICS)
+ found = convert_net(SDC_NICS)
+ self.assertEqual(expected, found)
+
+ def test_convert_simple_alt(self):
+ expected = {
+ 'version': 1,
+ 'config': [
+ {'name': 'net0', 'type': 'physical',
+ 'subnets': [{'type': 'static', 'gateway': '8.12.42.1',
+ 'address': '8.12.42.51/24'}],
+ 'mtu': 1500, 'mac_address': '90:b8:d0:ae:64:51'},
+ {'name': 'net1', 'type': 'physical',
+ 'subnets': [{'type': 'static',
+ 'address': '10.210.1.217/24'}],
+ 'mtu': 1500, 'mac_address': '90:b8:d0:bd:4f:9c'}]}
+ found = convert_net(SDC_NICS_ALT)
+ self.assertEqual(expected, found)
+
+ def test_convert_simple_dhcp(self):
+ expected = {
+ 'version': 1,
+ 'config': [
+ {'name': 'net0', 'type': 'physical',
+ 'subnets': [{'type': 'static', 'gateway': '8.12.42.1',
+ 'address': '8.12.42.51/24'}],
+ 'mtu': 1500, 'mac_address': '90:b8:d0:ae:64:51'},
+ {'name': 'net1', 'type': 'physical',
+ 'subnets': [{'type': 'dhcp4'}],
+ 'mtu': 1500, 'mac_address': '90:b8:d0:bd:4f:9c'}]}
+ found = convert_net(SDC_NICS_DHCP)
+ self.assertEqual(expected, found)
+
+ def test_convert_simple_multi_ip(self):
+ expected = {
+ 'version': 1,
+ 'config': [
+ {'name': 'net0', 'type': 'physical',
+ 'subnets': [{'type': 'static', 'gateway': '8.12.42.1',
+ 'address': '8.12.42.51/24'},
+ {'type': 'static',
+ 'address': '8.12.42.52/24'}],
+ 'mtu': 1500, 'mac_address': '90:b8:d0:ae:64:51'},
+ {'name': 'net1', 'type': 'physical',
+ 'subnets': [{'type': 'static',
+ 'address': '10.210.1.217/24'},
+ {'type': 'static',
+ 'address': '10.210.1.151/24'}],
+ 'mtu': 1500, 'mac_address': '90:b8:d0:bd:4f:9c'}]}
+ found = convert_net(SDC_NICS_MIP)
+ self.assertEqual(expected, found)
+
+ def test_convert_with_dns(self):
+ expected = {
+ 'version': 1,
+ 'config': [
+ {'name': 'net0', 'type': 'physical',
+ 'subnets': [{'type': 'static', 'gateway': '8.12.42.1',
+ 'address': '8.12.42.51/24'}],
+ 'mtu': 1500, 'mac_address': '90:b8:d0:ae:64:51'},
+ {'name': 'net1', 'type': 'physical',
+ 'subnets': [{'type': 'dhcp4'}],
+ 'mtu': 1500, 'mac_address': '90:b8:d0:bd:4f:9c'},
+ {'type': 'nameserver',
+ 'address': ['8.8.8.8', '8.8.8.1'], 'search': ["local"]}]}
+ found = convert_net(
+ network_data=SDC_NICS_DHCP, dns_servers=['8.8.8.8', '8.8.8.1'],
+ dns_domain="local")
+ self.assertEqual(expected, found)
+
+ def test_convert_simple_multi_ipv6(self):
+ expected = {
+ 'version': 1,
+ 'config': [
+ {'name': 'net0', 'type': 'physical',
+ 'subnets': [{'type': 'static', 'address':
+ '2001:4800:78ff:1b:be76:4eff:fe06:96b3/64'},
+ {'type': 'static', 'gateway': '8.12.42.1',
+ 'address': '8.12.42.51/24'}],
+ 'mtu': 1500, 'mac_address': '90:b8:d0:ae:64:51'},
+ {'name': 'net1', 'type': 'physical',
+ 'subnets': [{'type': 'static',
+ 'address': '10.210.1.217/24'}],
+ 'mtu': 1500, 'mac_address': '90:b8:d0:bd:4f:9c'}]}
+ found = convert_net(SDC_NICS_MIP_IPV6)
+ self.assertEqual(expected, found)
+
+ def test_convert_simple_both_ipv4_ipv6(self):
+ expected = {
+ 'version': 1,
+ 'config': [
+ {'mac_address': '90:b8:d0:ae:64:51', 'mtu': 1500,
+ 'name': 'net0', 'type': 'physical',
+ 'subnets': [{'address': '2001::10/64', 'gateway': '2001::1',
+ 'type': 'static'},
+ {'address': '8.12.42.51/24',
+ 'gateway': '8.12.42.1',
+ 'type': 'static'},
+ {'address': '2001::11/64', 'type': 'static'},
+ {'address': '8.12.42.52/32', 'type': 'static'}]},
+ {'mac_address': '90:b8:d0:bd:4f:9c', 'mtu': 1500,
+ 'name': 'net1', 'type': 'physical',
+ 'subnets': [{'address': '10.210.1.217/24',
+ 'type': 'static'}]}]}
+ found = convert_net(SDC_NICS_IPV4_IPV6)
+ self.assertEqual(expected, found)
+
+ def test_gateways_not_on_all_nics(self):
+ expected = {
+ 'version': 1,
+ 'config': [
+ {'mac_address': '90:b8:d0:d8:82:b4', 'mtu': 1500,
+ 'name': 'net0', 'type': 'physical',
+ 'subnets': [{'address': '8.12.42.26/24',
+ 'gateway': '8.12.42.1', 'type': 'static'}]},
+ {'mac_address': '90:b8:d0:0a:51:31', 'mtu': 1500,
+ 'name': 'net1', 'type': 'physical',
+ 'subnets': [{'address': '10.210.1.27/24',
+ 'type': 'static'}]}]}
+ found = convert_net(SDC_NICS_SINGLE_GATEWAY)
self.assertEqual(expected, found)
diff --git a/tests/unittests/test_handler/test_handler_mcollective.py b/tests/unittests/test_handler/test_handler_mcollective.py
index 8fa0147a..c3a5a634 100644
--- a/tests/unittests/test_handler/test_handler_mcollective.py
+++ b/tests/unittests/test_handler/test_handler_mcollective.py
@@ -138,6 +138,7 @@ class TestHandler(t_help.TestCase):
def test_mcollective_install(self, mock_util):
cc = self._get_cloud('ubuntu')
cc.distro = t_help.mock.MagicMock()
+ mock_util.load_file.return_value = b""
mycfg = {'mcollective': {'conf': {'loglevel': 'debug'}}}
cc_mcollective.handle('cc_mcollective', mycfg, cc, LOG, [])
self.assertTrue(cc.distro.install_packages.called)
diff --git a/tests/unittests/test_handler/test_handler_ntp.py b/tests/unittests/test_handler/test_handler_ntp.py
new file mode 100644
index 00000000..1c7bb06a
--- /dev/null
+++ b/tests/unittests/test_handler/test_handler_ntp.py
@@ -0,0 +1,274 @@
+from cloudinit.config import cc_ntp
+from cloudinit.sources import DataSourceNone
+from cloudinit import templater
+from cloudinit import (distros, helpers, cloud, util)
+from ..helpers import FilesystemMockingTestCase, mock
+
+import logging
+import os
+import shutil
+import tempfile
+
+LOG = logging.getLogger(__name__)
+
+NTP_TEMPLATE = """
+## template: jinja
+
+{% if pools %}# pools
+{% endif %}
+{% for pool in pools -%}
+pool {{pool}} iburst
+{% endfor %}
+{%- if servers %}# servers
+{% endif %}
+{% for server in servers -%}
+server {{server}} iburst
+{% endfor %}
+
+"""
+
+
+NTP_EXPECTED_UBUNTU = """
+# pools
+pool 0.mycompany.pool.ntp.org iburst
+# servers
+server 192.168.23.3 iburst
+
+"""
+
+
+class TestNtp(FilesystemMockingTestCase):
+
+ def setUp(self):
+ super(TestNtp, self).setUp()
+ self.subp = util.subp
+ self.new_root = tempfile.mkdtemp()
+ self.addCleanup(shutil.rmtree, self.new_root)
+
+ def _get_cloud(self, distro, metadata=None):
+ self.patchUtils(self.new_root)
+ paths = helpers.Paths({})
+ cls = distros.fetch(distro)
+ mydist = cls(distro, {}, paths)
+ myds = DataSourceNone.DataSourceNone({}, mydist, paths)
+ if metadata:
+ myds.metadata.update(metadata)
+ return cloud.Cloud(myds, paths, {}, mydist, None)
+
+ @mock.patch("cloudinit.config.cc_ntp.util")
+ def test_ntp_install(self, mock_util):
+ cc = self._get_cloud('ubuntu')
+ cc.distro = mock.MagicMock()
+ cc.distro.name = 'ubuntu'
+ mock_util.which.return_value = None
+ install_func = mock.MagicMock()
+
+ cc_ntp.install_ntp(install_func, packages=['ntpx'], check_exe='ntpdx')
+
+ self.assertTrue(install_func.called)
+ mock_util.which.assert_called_with('ntpdx')
+ install_pkg = install_func.call_args_list[0][0][0]
+ self.assertEqual(sorted(install_pkg), ['ntpx'])
+
+ @mock.patch("cloudinit.config.cc_ntp.util")
+ def test_ntp_install_not_needed(self, mock_util):
+ cc = self._get_cloud('ubuntu')
+ cc.distro = mock.MagicMock()
+ cc.distro.name = 'ubuntu'
+ mock_util.which.return_value = ["/usr/sbin/ntpd"]
+ cc_ntp.install_ntp(cc)
+ self.assertFalse(cc.distro.install_packages.called)
+
+ def test_ntp_rename_ntp_conf(self):
+ with mock.patch.object(os.path, 'exists',
+ return_value=True) as mockpath:
+ with mock.patch.object(util, 'rename') as mockrename:
+ cc_ntp.rename_ntp_conf()
+
+ mockpath.assert_called_with('/etc/ntp.conf')
+ mockrename.assert_called_with('/etc/ntp.conf', '/etc/ntp.conf.dist')
+
+ def test_ntp_rename_ntp_conf_skip_missing(self):
+ with mock.patch.object(os.path, 'exists',
+ return_value=False) as mockpath:
+ with mock.patch.object(util, 'rename') as mockrename:
+ cc_ntp.rename_ntp_conf()
+
+ mockpath.assert_called_with('/etc/ntp.conf')
+ mockrename.assert_not_called()
+
+ def ntp_conf_render(self, distro):
+ """ntp_conf_render
+ Test rendering of a ntp.conf from template for a given distro
+ """
+
+ cfg = {'ntp': {}}
+ mycloud = self._get_cloud(distro)
+ distro_names = cc_ntp.generate_server_names(distro)
+
+ with mock.patch.object(templater, 'render_to_file') as mocktmpl:
+ with mock.patch.object(os.path, 'isfile', return_value=True):
+ with mock.patch.object(util, 'rename'):
+ cc_ntp.write_ntp_config_template(cfg, mycloud)
+
+ mocktmpl.assert_called_once_with(
+ ('/etc/cloud/templates/ntp.conf.%s.tmpl' % distro),
+ '/etc/ntp.conf',
+ {'servers': [], 'pools': distro_names})
+
+ def test_ntp_conf_render_rhel(self):
+ """Test templater.render_to_file() for rhel"""
+ self.ntp_conf_render('rhel')
+
+ def test_ntp_conf_render_debian(self):
+ """Test templater.render_to_file() for debian"""
+ self.ntp_conf_render('debian')
+
+ def test_ntp_conf_render_fedora(self):
+ """Test templater.render_to_file() for fedora"""
+ self.ntp_conf_render('fedora')
+
+ def test_ntp_conf_render_sles(self):
+ """Test templater.render_to_file() for sles"""
+ self.ntp_conf_render('sles')
+
+ def test_ntp_conf_render_ubuntu(self):
+ """Test templater.render_to_file() for ubuntu"""
+ self.ntp_conf_render('ubuntu')
+
+ def test_ntp_conf_servers_no_pools(self):
+ distro = 'ubuntu'
+ pools = []
+ servers = ['192.168.2.1']
+ cfg = {
+ 'ntp': {
+ 'pools': pools,
+ 'servers': servers,
+ }
+ }
+ mycloud = self._get_cloud(distro)
+
+ with mock.patch.object(templater, 'render_to_file') as mocktmpl:
+ with mock.patch.object(os.path, 'isfile', return_value=True):
+ with mock.patch.object(util, 'rename'):
+ cc_ntp.write_ntp_config_template(cfg.get('ntp'), mycloud)
+
+ mocktmpl.assert_called_once_with(
+ ('/etc/cloud/templates/ntp.conf.%s.tmpl' % distro),
+ '/etc/ntp.conf',
+ {'servers': servers, 'pools': pools})
+
+ def test_ntp_conf_custom_pools_no_server(self):
+ distro = 'ubuntu'
+ pools = ['0.mycompany.pool.ntp.org']
+ servers = []
+ cfg = {
+ 'ntp': {
+ 'pools': pools,
+ 'servers': servers,
+ }
+ }
+ mycloud = self._get_cloud(distro)
+
+ with mock.patch.object(templater, 'render_to_file') as mocktmpl:
+ with mock.patch.object(os.path, 'isfile', return_value=True):
+ with mock.patch.object(util, 'rename'):
+ cc_ntp.write_ntp_config_template(cfg.get('ntp'), mycloud)
+
+ mocktmpl.assert_called_once_with(
+ ('/etc/cloud/templates/ntp.conf.%s.tmpl' % distro),
+ '/etc/ntp.conf',
+ {'servers': servers, 'pools': pools})
+
+ def test_ntp_conf_custom_pools_and_server(self):
+ distro = 'ubuntu'
+ pools = ['0.mycompany.pool.ntp.org']
+ servers = ['192.168.23.3']
+ cfg = {
+ 'ntp': {
+ 'pools': pools,
+ 'servers': servers,
+ }
+ }
+ mycloud = self._get_cloud(distro)
+
+ with mock.patch.object(templater, 'render_to_file') as mocktmpl:
+ with mock.patch.object(os.path, 'isfile', return_value=True):
+ with mock.patch.object(util, 'rename'):
+ cc_ntp.write_ntp_config_template(cfg.get('ntp'), mycloud)
+
+ mocktmpl.assert_called_once_with(
+ ('/etc/cloud/templates/ntp.conf.%s.tmpl' % distro),
+ '/etc/ntp.conf',
+ {'servers': servers, 'pools': pools})
+
+ def test_ntp_conf_contents_match(self):
+ """Test rendered contents of /etc/ntp.conf for ubuntu"""
+ pools = ['0.mycompany.pool.ntp.org']
+ servers = ['192.168.23.3']
+ cfg = {
+ 'ntp': {
+ 'pools': pools,
+ 'servers': servers,
+ }
+ }
+ mycloud = self._get_cloud('ubuntu')
+ side_effect = [NTP_TEMPLATE.lstrip()]
+
+ # work backwards from util.write_file and mock out call path
+ # write_ntp_config_template()
+ # cloud.get_template_filename()
+ # os.path.isfile()
+ # templater.render_to_file()
+ # templater.render_from_file()
+ # util.load_file()
+ # util.write_file()
+ #
+ with mock.patch.object(util, 'write_file') as mockwrite:
+ with mock.patch.object(util, 'load_file', side_effect=side_effect):
+ with mock.patch.object(os.path, 'isfile', return_value=True):
+ with mock.patch.object(util, 'rename'):
+ cc_ntp.write_ntp_config_template(cfg.get('ntp'),
+ mycloud)
+
+ mockwrite.assert_called_once_with(
+ '/etc/ntp.conf',
+ NTP_EXPECTED_UBUNTU,
+ mode=420)
+
+ def test_ntp_handler(self):
+ """Test ntp handler renders ubuntu ntp.conf template"""
+ pools = ['0.mycompany.pool.ntp.org']
+ servers = ['192.168.23.3']
+ cfg = {
+ 'ntp': {
+ 'pools': pools,
+ 'servers': servers,
+ }
+ }
+ mycloud = self._get_cloud('ubuntu')
+ side_effect = [NTP_TEMPLATE.lstrip()]
+
+ with mock.patch.object(util, 'which', return_value=None):
+ with mock.patch.object(os.path, 'exists'):
+ with mock.patch.object(util, 'write_file') as mockwrite:
+ with mock.patch.object(util, 'load_file',
+ side_effect=side_effect):
+ with mock.patch.object(os.path, 'isfile',
+ return_value=True):
+ with mock.patch.object(util, 'rename'):
+ cc_ntp.handle("notimportant", cfg,
+ mycloud, LOG, None)
+
+ mockwrite.assert_called_once_with(
+ '/etc/ntp.conf',
+ NTP_EXPECTED_UBUNTU,
+ mode=420)
+
+ @mock.patch("cloudinit.config.cc_ntp.util")
+ def test_no_ntpcfg_does_nothing(self, mock_util):
+ cc = self._get_cloud('ubuntu')
+ cc.distro = mock.MagicMock()
+ cc_ntp.handle('cc_ntp', {}, cc, LOG, [])
+ self.assertFalse(cc.distro.install_packages.called)
+ self.assertFalse(mock_util.subp.called)
diff --git a/tests/unittests/test_util.py b/tests/unittests/test_util.py
index 37a984ac..73369cd3 100644
--- a/tests/unittests/test_util.py
+++ b/tests/unittests/test_util.py
@@ -371,8 +371,30 @@ class TestReadDMIData(helpers.FilesystemMockingTestCase):
self._create_sysfs_parent_directory()
expected_dmi_value = 'dmidecode-used'
self._configure_dmidecode_return('use-dmidecode', expected_dmi_value)
- self.assertEqual(expected_dmi_value,
- util.read_dmi_data('use-dmidecode'))
+ with mock.patch("cloudinit.util.os.uname") as m_uname:
+ m_uname.return_value = ('x-sysname', 'x-nodename',
+ 'x-release', 'x-version', 'x86_64')
+ self.assertEqual(expected_dmi_value,
+ util.read_dmi_data('use-dmidecode'))
+
+ def test_dmidecode_not_used_on_arm(self):
+ self.patch_mapping({})
+ self._create_sysfs_parent_directory()
+ dmi_val = 'from-dmidecode'
+ dmi_name = 'use-dmidecode'
+ self._configure_dmidecode_return(dmi_name, dmi_val)
+
+ expected = {'armel': None, 'aarch64': None, 'x86_64': dmi_val}
+ found = {}
+ # we do not run the 'dmi-decode' binary on some arches
+ # verify that anything requested that is not in the sysfs dir
+ # will return None on those arches.
+ with mock.patch("cloudinit.util.os.uname") as m_uname:
+ for arch in expected:
+ m_uname.return_value = ('x-sysname', 'x-nodename',
+ 'x-release', 'x-version', arch)
+ found[arch] = util.read_dmi_data(dmi_name)
+ self.assertEqual(expected, found)
def test_none_returned_if_neither_source_has_data(self):
self.patch_mapping({})