summaryrefslogtreecommitdiff
path: root/tests/unittests
diff options
context:
space:
mode:
Diffstat (limited to 'tests/unittests')
-rw-r--r--tests/unittests/test_datasource/test_aliyun.py4
-rw-r--r--tests/unittests/test_datasource/test_altcloud.py118
-rw-r--r--tests/unittests/test_datasource/test_azure.py110
-rw-r--r--tests/unittests/test_datasource/test_cloudsigma.py6
-rw-r--r--tests/unittests/test_datasource/test_configdrive.py3
-rw-r--r--tests/unittests/test_datasource/test_ec2.py20
-rw-r--r--tests/unittests/test_datasource/test_ibmcloud.py40
-rw-r--r--tests/unittests/test_datasource/test_nocloud.py45
-rw-r--r--tests/unittests/test_datasource/test_opennebula.py4
-rw-r--r--tests/unittests/test_datasource/test_ovf.py52
-rw-r--r--tests/unittests/test_datasource/test_smartos.py7
11 files changed, 289 insertions, 120 deletions
diff --git a/tests/unittests/test_datasource/test_aliyun.py b/tests/unittests/test_datasource/test_aliyun.py
index 1e77842f..e9213ca1 100644
--- a/tests/unittests/test_datasource/test_aliyun.py
+++ b/tests/unittests/test_datasource/test_aliyun.py
@@ -140,6 +140,10 @@ class TestAliYunDatasource(test_helpers.HttprettyTestCase):
self._test_get_sshkey()
self._test_get_iid()
self._test_host_name()
+ self.assertEqual('aliyun', self.ds.cloud_name)
+ self.assertEqual('ec2', self.ds.platform)
+ self.assertEqual(
+ 'metadata (http://100.100.100.200)', self.ds.subplatform)
@mock.patch("cloudinit.sources.DataSourceAliYun._is_aliyun")
def test_returns_false_when_not_on_aliyun(self, m_is_aliyun):
diff --git a/tests/unittests/test_datasource/test_altcloud.py b/tests/unittests/test_datasource/test_altcloud.py
index ff35904e..3119bfac 100644
--- a/tests/unittests/test_datasource/test_altcloud.py
+++ b/tests/unittests/test_datasource/test_altcloud.py
@@ -10,7 +10,6 @@
This test file exercises the code in sources DataSourceAltCloud.py
'''
-import mock
import os
import shutil
import tempfile
@@ -18,32 +17,13 @@ import tempfile
from cloudinit import helpers
from cloudinit import util
-from cloudinit.tests.helpers import CiTestCase
+from cloudinit.tests.helpers import CiTestCase, mock
import cloudinit.sources.DataSourceAltCloud as dsac
OS_UNAME_ORIG = getattr(os, 'uname')
-def _write_cloud_info_file(value):
- '''
- Populate the CLOUD_INFO_FILE which would be populated
- with a cloud backend identifier ImageFactory when building
- an image with ImageFactory.
- '''
- cifile = open(dsac.CLOUD_INFO_FILE, 'w')
- cifile.write(value)
- cifile.close()
- os.chmod(dsac.CLOUD_INFO_FILE, 0o664)
-
-
-def _remove_cloud_info_file():
- '''
- Remove the test CLOUD_INFO_FILE
- '''
- os.remove(dsac.CLOUD_INFO_FILE)
-
-
def _write_user_data_files(mount_dir, value):
'''
Populate the deltacloud_user_data_file the user_data_file
@@ -98,13 +78,15 @@ def _dmi_data(expected):
class TestGetCloudType(CiTestCase):
- '''
- Test to exercise method: DataSourceAltCloud.get_cloud_type()
- '''
+ '''Test to exercise method: DataSourceAltCloud.get_cloud_type()'''
+
+ with_logs = True
def setUp(self):
'''Set up.'''
- self.paths = helpers.Paths({'cloud_dir': '/tmp'})
+ super(TestGetCloudType, self).setUp()
+ self.tmp = self.tmp_dir()
+ self.paths = helpers.Paths({'cloud_dir': self.tmp})
self.dmi_data = util.read_dmi_data
# We have a different code path for arm to deal with LP1243287
# We have to switch arch to x86_64 to avoid test failure
@@ -115,6 +97,26 @@ class TestGetCloudType(CiTestCase):
util.read_dmi_data = self.dmi_data
force_arch()
+ def test_cloud_info_file_ioerror(self):
+ """Return UNKNOWN when /etc/sysconfig/cloud-info exists but errors."""
+ self.assertEqual('/etc/sysconfig/cloud-info', dsac.CLOUD_INFO_FILE)
+ dsrc = dsac.DataSourceAltCloud({}, None, self.paths)
+ # Attempting to read the directory generates IOError
+ with mock.patch.object(dsac, 'CLOUD_INFO_FILE', self.tmp):
+ self.assertEqual('UNKNOWN', dsrc.get_cloud_type())
+ self.assertIn(
+ "[Errno 21] Is a directory: '%s'" % self.tmp,
+ self.logs.getvalue())
+
+ def test_cloud_info_file(self):
+ """Return uppercase stripped content from /etc/sysconfig/cloud-info."""
+ dsrc = dsac.DataSourceAltCloud({}, None, self.paths)
+ cloud_info = self.tmp_path('cloud-info', dir=self.tmp)
+ util.write_file(cloud_info, ' OverRiDdeN CloudType ')
+ # Attempting to read the directory generates IOError
+ with mock.patch.object(dsac, 'CLOUD_INFO_FILE', cloud_info):
+ self.assertEqual('OVERRIDDEN CLOUDTYPE', dsrc.get_cloud_type())
+
def test_rhev(self):
'''
Test method get_cloud_type() for RHEVm systems.
@@ -153,60 +155,57 @@ class TestGetDataCloudInfoFile(CiTestCase):
self.tmp = self.tmp_dir()
self.paths = helpers.Paths(
{'cloud_dir': self.tmp, 'run_dir': self.tmp})
- self.cloud_info_file = tempfile.mkstemp()[1]
- self.dmi_data = util.read_dmi_data
- dsac.CLOUD_INFO_FILE = self.cloud_info_file
-
- def tearDown(self):
- # Reset
-
- # Attempt to remove the temp file ignoring errors
- try:
- os.remove(self.cloud_info_file)
- except OSError:
- pass
-
- util.read_dmi_data = self.dmi_data
- dsac.CLOUD_INFO_FILE = '/etc/sysconfig/cloud-info'
+ self.cloud_info_file = self.tmp_path('cloud-info', dir=self.tmp)
def test_rhev(self):
'''Success Test module get_data() forcing RHEV.'''
- _write_cloud_info_file('RHEV')
+ util.write_file(self.cloud_info_file, 'RHEV')
dsrc = dsac.DataSourceAltCloud({}, None, self.paths)
dsrc.user_data_rhevm = lambda: True
- self.assertEqual(True, dsrc.get_data())
+ with mock.patch.object(dsac, 'CLOUD_INFO_FILE', self.cloud_info_file):
+ self.assertEqual(True, dsrc.get_data())
+ self.assertEqual('altcloud', dsrc.cloud_name)
+ self.assertEqual('altcloud', dsrc.platform_type)
+ self.assertEqual('rhev (/dev/fd0)', dsrc.subplatform)
def test_vsphere(self):
'''Success Test module get_data() forcing VSPHERE.'''
- _write_cloud_info_file('VSPHERE')
+ util.write_file(self.cloud_info_file, 'VSPHERE')
dsrc = dsac.DataSourceAltCloud({}, None, self.paths)
dsrc.user_data_vsphere = lambda: True
- self.assertEqual(True, dsrc.get_data())
+ with mock.patch.object(dsac, 'CLOUD_INFO_FILE', self.cloud_info_file):
+ self.assertEqual(True, dsrc.get_data())
+ self.assertEqual('altcloud', dsrc.cloud_name)
+ self.assertEqual('altcloud', dsrc.platform_type)
+ self.assertEqual('vsphere (unknown)', dsrc.subplatform)
def test_fail_rhev(self):
'''Failure Test module get_data() forcing RHEV.'''
- _write_cloud_info_file('RHEV')
+ util.write_file(self.cloud_info_file, 'RHEV')
dsrc = dsac.DataSourceAltCloud({}, None, self.paths)
dsrc.user_data_rhevm = lambda: False
- self.assertEqual(False, dsrc.get_data())
+ with mock.patch.object(dsac, 'CLOUD_INFO_FILE', self.cloud_info_file):
+ self.assertEqual(False, dsrc.get_data())
def test_fail_vsphere(self):
'''Failure Test module get_data() forcing VSPHERE.'''
- _write_cloud_info_file('VSPHERE')
+ util.write_file(self.cloud_info_file, 'VSPHERE')
dsrc = dsac.DataSourceAltCloud({}, None, self.paths)
dsrc.user_data_vsphere = lambda: False
- self.assertEqual(False, dsrc.get_data())
+ with mock.patch.object(dsac, 'CLOUD_INFO_FILE', self.cloud_info_file):
+ self.assertEqual(False, dsrc.get_data())
def test_unrecognized(self):
'''Failure Test module get_data() forcing unrecognized.'''
- _write_cloud_info_file('unrecognized')
+ util.write_file(self.cloud_info_file, 'unrecognized')
dsrc = dsac.DataSourceAltCloud({}, None, self.paths)
- self.assertEqual(False, dsrc.get_data())
+ with mock.patch.object(dsac, 'CLOUD_INFO_FILE', self.cloud_info_file):
+ self.assertEqual(False, dsrc.get_data())
class TestGetDataNoCloudInfoFile(CiTestCase):
@@ -322,7 +321,8 @@ class TestUserDataVsphere(CiTestCase):
'''
def setUp(self):
'''Set up.'''
- self.paths = helpers.Paths({'cloud_dir': '/tmp'})
+ self.tmp = self.tmp_dir()
+ self.paths = helpers.Paths({'cloud_dir': self.tmp})
self.mount_dir = tempfile.mkdtemp()
_write_user_data_files(self.mount_dir, 'test user data')
@@ -363,6 +363,22 @@ class TestUserDataVsphere(CiTestCase):
self.assertEqual(1, m_find_devs_with.call_count)
self.assertEqual(1, m_mount_cb.call_count)
+ @mock.patch("cloudinit.sources.DataSourceAltCloud.util.find_devs_with")
+ @mock.patch("cloudinit.sources.DataSourceAltCloud.util.mount_cb")
+ def test_user_data_vsphere_success(self, m_mount_cb, m_find_devs_with):
+ """Test user_data_vsphere() where successful."""
+ m_find_devs_with.return_value = ["/dev/mock/cdrom"]
+ m_mount_cb.return_value = 'raw userdata from cdrom'
+ dsrc = dsac.DataSourceAltCloud({}, None, self.paths)
+ cloud_info = self.tmp_path('cloud-info', dir=self.tmp)
+ util.write_file(cloud_info, 'VSPHERE')
+ self.assertEqual(True, dsrc.user_data_vsphere())
+ m_find_devs_with.assert_called_once_with('LABEL=CDROM')
+ m_mount_cb.assert_called_once_with(
+ '/dev/mock/cdrom', dsac.read_user_data_callback)
+ with mock.patch.object(dsrc, 'get_cloud_type', return_value='VSPHERE'):
+ self.assertEqual('vsphere (/dev/mock/cdrom)', dsrc.subplatform)
+
class TestReadUserDataCallback(CiTestCase):
'''
diff --git a/tests/unittests/test_datasource/test_azure.py b/tests/unittests/test_datasource/test_azure.py
index 4e428b71..0f4b7bf7 100644
--- a/tests/unittests/test_datasource/test_azure.py
+++ b/tests/unittests/test_datasource/test_azure.py
@@ -110,6 +110,8 @@ NETWORK_METADATA = {
}
}
+MOCKPATH = 'cloudinit.sources.DataSourceAzure.'
+
class TestGetMetadataFromIMDS(HttprettyTestCase):
@@ -119,9 +121,9 @@ class TestGetMetadataFromIMDS(HttprettyTestCase):
super(TestGetMetadataFromIMDS, self).setUp()
self.network_md_url = dsaz.IMDS_URL + "instance?api-version=2017-12-01"
- @mock.patch('cloudinit.sources.DataSourceAzure.readurl')
- @mock.patch('cloudinit.sources.DataSourceAzure.EphemeralDHCPv4')
- @mock.patch('cloudinit.sources.DataSourceAzure.net.is_up')
+ @mock.patch(MOCKPATH + 'readurl')
+ @mock.patch(MOCKPATH + 'EphemeralDHCPv4')
+ @mock.patch(MOCKPATH + 'net.is_up')
def test_get_metadata_does_not_dhcp_if_network_is_up(
self, m_net_is_up, m_dhcp, m_readurl):
"""Do not perform DHCP setup when nic is already up."""
@@ -138,9 +140,9 @@ class TestGetMetadataFromIMDS(HttprettyTestCase):
"Crawl of Azure Instance Metadata Service (IMDS) took", # log_time
self.logs.getvalue())
- @mock.patch('cloudinit.sources.DataSourceAzure.readurl')
- @mock.patch('cloudinit.sources.DataSourceAzure.EphemeralDHCPv4')
- @mock.patch('cloudinit.sources.DataSourceAzure.net.is_up')
+ @mock.patch(MOCKPATH + 'readurl')
+ @mock.patch(MOCKPATH + 'EphemeralDHCPv4')
+ @mock.patch(MOCKPATH + 'net.is_up')
def test_get_metadata_performs_dhcp_when_network_is_down(
self, m_net_is_up, m_dhcp, m_readurl):
"""Perform DHCP setup when nic is not up."""
@@ -163,7 +165,7 @@ class TestGetMetadataFromIMDS(HttprettyTestCase):
headers={'Metadata': 'true'}, retries=2, timeout=1)
@mock.patch('cloudinit.url_helper.time.sleep')
- @mock.patch('cloudinit.sources.DataSourceAzure.net.is_up')
+ @mock.patch(MOCKPATH + 'net.is_up')
def test_get_metadata_from_imds_empty_when_no_imds_present(
self, m_net_is_up, m_sleep):
"""Return empty dict when IMDS network metadata is absent."""
@@ -380,7 +382,7 @@ fdescfs /dev/fd fdescfs rw 0 0
res = get_path_dev_freebsd('/etc', mnt_list)
self.assertIsNotNone(res)
- @mock.patch('cloudinit.sources.DataSourceAzure._is_platform_viable')
+ @mock.patch(MOCKPATH + '_is_platform_viable')
def test_call_is_platform_viable_seed(self, m_is_platform_viable):
"""Check seed_dir using _is_platform_viable and return False."""
# Return a non-matching asset tag value
@@ -401,6 +403,24 @@ fdescfs /dev/fd fdescfs rw 0 0
self.assertEqual(dsrc.metadata['local-hostname'], odata['HostName'])
self.assertTrue(os.path.isfile(
os.path.join(self.waagent_d, 'ovf-env.xml')))
+ self.assertEqual('azure', dsrc.cloud_name)
+ self.assertEqual('azure', dsrc.platform_type)
+ self.assertEqual(
+ 'seed-dir (%s/seed/azure)' % self.tmp, dsrc.subplatform)
+
+ def test_basic_dev_file(self):
+ """When a device path is used, present that in subplatform."""
+ data = {'sys_cfg': {}, 'dsdevs': ['/dev/cd0']}
+ dsrc = self._get_ds(data)
+ with mock.patch(MOCKPATH + 'util.mount_cb') as m_mount_cb:
+ m_mount_cb.return_value = (
+ {'local-hostname': 'me'}, 'ud', {'cfg': ''}, {})
+ self.assertTrue(dsrc.get_data())
+ self.assertEqual(dsrc.userdata_raw, 'ud')
+ self.assertEqual(dsrc.metadata['local-hostname'], 'me')
+ self.assertEqual('azure', dsrc.cloud_name)
+ self.assertEqual('azure', dsrc.platform_type)
+ self.assertEqual('config-disk (/dev/cd0)', dsrc.subplatform)
def test_get_data_non_ubuntu_will_not_remove_network_scripts(self):
"""get_data on non-Ubuntu will not remove ubuntu net scripts."""
@@ -769,8 +789,8 @@ fdescfs /dev/fd fdescfs rw 0 0
ds.get_data()
self.assertEqual(self.instance_id, ds.metadata['instance-id'])
- @mock.patch("cloudinit.sources.DataSourceAzure.util.is_FreeBSD")
- @mock.patch("cloudinit.sources.DataSourceAzure._check_freebsd_cdrom")
+ @mock.patch(MOCKPATH + 'util.is_FreeBSD')
+ @mock.patch(MOCKPATH + '_check_freebsd_cdrom')
def test_list_possible_azure_ds_devs(self, m_check_fbsd_cdrom,
m_is_FreeBSD):
"""On FreeBSD, possible devs should show /dev/cd0."""
@@ -885,17 +905,17 @@ fdescfs /dev/fd fdescfs rw 0 0
expected_config['config'].append(blacklist_config)
self.assertEqual(netconfig, expected_config)
- @mock.patch("cloudinit.sources.DataSourceAzure.util.subp")
+ @mock.patch(MOCKPATH + 'util.subp')
def test_get_hostname_with_no_args(self, subp):
dsaz.get_hostname()
subp.assert_called_once_with(("hostname",), capture=True)
- @mock.patch("cloudinit.sources.DataSourceAzure.util.subp")
+ @mock.patch(MOCKPATH + 'util.subp')
def test_get_hostname_with_string_arg(self, subp):
dsaz.get_hostname(hostname_command="hostname")
subp.assert_called_once_with(("hostname",), capture=True)
- @mock.patch("cloudinit.sources.DataSourceAzure.util.subp")
+ @mock.patch(MOCKPATH + 'util.subp')
def test_get_hostname_with_iterable_arg(self, subp):
dsaz.get_hostname(hostname_command=("hostname",))
subp.assert_called_once_with(("hostname",), capture=True)
@@ -949,7 +969,7 @@ class TestAzureBounce(CiTestCase):
self.set_hostname = self.patches.enter_context(
mock.patch.object(dsaz, 'set_hostname'))
self.subp = self.patches.enter_context(
- mock.patch('cloudinit.sources.DataSourceAzure.util.subp'))
+ mock.patch(MOCKPATH + 'util.subp'))
self.find_fallback_nic = self.patches.enter_context(
mock.patch('cloudinit.net.find_fallback_nic', return_value='eth9'))
@@ -989,7 +1009,7 @@ class TestAzureBounce(CiTestCase):
ds.get_data()
self.assertEqual(0, self.set_hostname.call_count)
- @mock.patch('cloudinit.sources.DataSourceAzure.perform_hostname_bounce')
+ @mock.patch(MOCKPATH + 'perform_hostname_bounce')
def test_disabled_bounce_does_not_perform_bounce(
self, perform_hostname_bounce):
cfg = {'hostname_bounce': {'policy': 'off'}}
@@ -1005,7 +1025,7 @@ class TestAzureBounce(CiTestCase):
ds.get_data()
self.assertEqual(0, self.set_hostname.call_count)
- @mock.patch('cloudinit.sources.DataSourceAzure.perform_hostname_bounce')
+ @mock.patch(MOCKPATH + 'perform_hostname_bounce')
def test_unchanged_hostname_does_not_perform_bounce(
self, perform_hostname_bounce):
host_name = 'unchanged-host-name'
@@ -1015,7 +1035,7 @@ class TestAzureBounce(CiTestCase):
ds.get_data()
self.assertEqual(0, perform_hostname_bounce.call_count)
- @mock.patch('cloudinit.sources.DataSourceAzure.perform_hostname_bounce')
+ @mock.patch(MOCKPATH + 'perform_hostname_bounce')
def test_force_performs_bounce_regardless(self, perform_hostname_bounce):
host_name = 'unchanged-host-name'
self.get_hostname.return_value = host_name
@@ -1032,7 +1052,7 @@ class TestAzureBounce(CiTestCase):
cfg = {'hostname_bounce': {'policy': 'force'}}
dsrc = self._get_ds(self.get_ovf_env_with_dscfg(host_name, cfg),
agent_command=['not', '__builtin__'])
- patch_path = 'cloudinit.sources.DataSourceAzure.util.which'
+ patch_path = MOCKPATH + 'util.which'
with mock.patch(patch_path) as m_which:
m_which.return_value = None
ret = self._get_and_setup(dsrc)
@@ -1053,7 +1073,7 @@ class TestAzureBounce(CiTestCase):
self.assertEqual(expected_hostname,
self.set_hostname.call_args_list[0][0][0])
- @mock.patch('cloudinit.sources.DataSourceAzure.perform_hostname_bounce')
+ @mock.patch(MOCKPATH + 'perform_hostname_bounce')
def test_different_hostnames_performs_bounce(
self, perform_hostname_bounce):
expected_hostname = 'azure-expected-host-name'
@@ -1076,7 +1096,7 @@ class TestAzureBounce(CiTestCase):
self.assertEqual(initial_host_name,
self.set_hostname.call_args_list[-1][0][0])
- @mock.patch('cloudinit.sources.DataSourceAzure.perform_hostname_bounce')
+ @mock.patch(MOCKPATH + 'perform_hostname_bounce')
def test_failure_in_bounce_still_resets_host_name(
self, perform_hostname_bounce):
perform_hostname_bounce.side_effect = Exception
@@ -1117,7 +1137,7 @@ class TestAzureBounce(CiTestCase):
self.assertEqual(
dsaz.BOUNCE_COMMAND_IFUP, bounce_args)
- @mock.patch('cloudinit.sources.DataSourceAzure.perform_hostname_bounce')
+ @mock.patch(MOCKPATH + 'perform_hostname_bounce')
def test_set_hostname_option_can_disable_bounce(
self, perform_hostname_bounce):
cfg = {'set_hostname': False, 'hostname_bounce': {'policy': 'force'}}
@@ -1218,12 +1238,12 @@ class TestCanDevBeReformatted(CiTestCase):
def has_ntfs_fs(device):
return bypath.get(device, {}).get('fs') == 'ntfs'
- p = 'cloudinit.sources.DataSourceAzure'
- self._domock(p + "._partitions_on_device", 'm_partitions_on_device')
- self._domock(p + "._has_ntfs_filesystem", 'm_has_ntfs_filesystem')
- self._domock(p + ".util.mount_cb", 'm_mount_cb')
- self._domock(p + ".os.path.realpath", 'm_realpath')
- self._domock(p + ".os.path.exists", 'm_exists')
+ p = MOCKPATH
+ self._domock(p + "_partitions_on_device", 'm_partitions_on_device')
+ self._domock(p + "_has_ntfs_filesystem", 'm_has_ntfs_filesystem')
+ self._domock(p + "util.mount_cb", 'm_mount_cb')
+ self._domock(p + "os.path.realpath", 'm_realpath')
+ self._domock(p + "os.path.exists", 'm_exists')
self.m_exists.side_effect = lambda p: p in bypath
self.m_realpath.side_effect = realpath
@@ -1488,7 +1508,7 @@ class TestPreprovisioningShouldReprovision(CiTestCase):
self.paths = helpers.Paths({'cloud_dir': tmp})
dsaz.BUILTIN_DS_CONFIG['data_dir'] = self.waagent_d
- @mock.patch('cloudinit.sources.DataSourceAzure.util.write_file')
+ @mock.patch(MOCKPATH + 'util.write_file')
def test__should_reprovision_with_true_cfg(self, isfile, write_f):
"""The _should_reprovision method should return true with config
flag present."""
@@ -1512,7 +1532,7 @@ class TestPreprovisioningShouldReprovision(CiTestCase):
dsa = dsaz.DataSourceAzure({}, distro=None, paths=self.paths)
self.assertFalse(dsa._should_reprovision((None, None, {}, None)))
- @mock.patch('cloudinit.sources.DataSourceAzure.DataSourceAzure._poll_imds')
+ @mock.patch(MOCKPATH + 'DataSourceAzure._poll_imds')
def test_reprovision_calls__poll_imds(self, _poll_imds, isfile):
"""_reprovision will poll IMDS."""
isfile.return_value = False
@@ -1528,8 +1548,7 @@ class TestPreprovisioningShouldReprovision(CiTestCase):
@mock.patch('cloudinit.net.dhcp.EphemeralIPv4Network')
@mock.patch('cloudinit.net.dhcp.maybe_perform_dhcp_discovery')
@mock.patch('requests.Session.request')
-@mock.patch(
- 'cloudinit.sources.DataSourceAzure.DataSourceAzure._report_ready')
+@mock.patch(MOCKPATH + 'DataSourceAzure._report_ready')
class TestPreprovisioningPollIMDS(CiTestCase):
def setUp(self):
@@ -1539,7 +1558,7 @@ class TestPreprovisioningPollIMDS(CiTestCase):
self.paths = helpers.Paths({'cloud_dir': self.tmp})
dsaz.BUILTIN_DS_CONFIG['data_dir'] = self.waagent_d
- @mock.patch('cloudinit.sources.DataSourceAzure.util.write_file')
+ @mock.patch(MOCKPATH + 'util.write_file')
def test_poll_imds_calls_report_ready(self, write_f, report_ready_func,
fake_resp, m_dhcp, m_net):
"""The poll_imds will call report_ready after creating marker file."""
@@ -1550,8 +1569,7 @@ class TestPreprovisioningPollIMDS(CiTestCase):
'unknown-245': '624c3620'}
m_dhcp.return_value = [lease]
dsa = dsaz.DataSourceAzure({}, distro=None, paths=self.paths)
- mock_path = (
- 'cloudinit.sources.DataSourceAzure.REPORTED_READY_MARKER_FILE')
+ mock_path = (MOCKPATH + 'REPORTED_READY_MARKER_FILE')
with mock.patch(mock_path, report_marker):
dsa._poll_imds()
self.assertEqual(report_ready_func.call_count, 1)
@@ -1561,23 +1579,21 @@ class TestPreprovisioningPollIMDS(CiTestCase):
fake_resp, m_dhcp, m_net):
"""The poll_imds should not call reporting ready
when flag is false"""
- report_marker = self.tmp_path('report_marker', self.tmp)
- write_file(report_marker, content='dont run report_ready :)')
+ report_file = self.tmp_path('report_marker', self.tmp)
+ write_file(report_file, content='dont run report_ready :)')
m_dhcp.return_value = [{
'interface': 'eth9', 'fixed-address': '192.168.2.9',
'routers': '192.168.2.1', 'subnet-mask': '255.255.255.0',
'unknown-245': '624c3620'}]
dsa = dsaz.DataSourceAzure({}, distro=None, paths=self.paths)
- mock_path = (
- 'cloudinit.sources.DataSourceAzure.REPORTED_READY_MARKER_FILE')
- with mock.patch(mock_path, report_marker):
+ with mock.patch(MOCKPATH + 'REPORTED_READY_MARKER_FILE', report_file):
dsa._poll_imds()
self.assertEqual(report_ready_func.call_count, 0)
-@mock.patch('cloudinit.sources.DataSourceAzure.util.subp')
-@mock.patch('cloudinit.sources.DataSourceAzure.util.write_file')
-@mock.patch('cloudinit.sources.DataSourceAzure.util.is_FreeBSD')
+@mock.patch(MOCKPATH + 'util.subp')
+@mock.patch(MOCKPATH + 'util.write_file')
+@mock.patch(MOCKPATH + 'util.is_FreeBSD')
@mock.patch('cloudinit.net.dhcp.EphemeralIPv4Network')
@mock.patch('cloudinit.net.dhcp.maybe_perform_dhcp_discovery')
@mock.patch('requests.Session.request')
@@ -1688,7 +1704,7 @@ class TestRemoveUbuntuNetworkConfigScripts(CiTestCase):
self.tmp_path('notfilehere', dir=self.tmp)])
self.assertNotIn('/not/a', self.logs.getvalue()) # No delete logs
- @mock.patch('cloudinit.sources.DataSourceAzure.os.path.exists')
+ @mock.patch(MOCKPATH + 'os.path.exists')
def test_remove_network_scripts_default_removes_stock_scripts(self,
m_exists):
"""Azure's stock ubuntu image scripts and artifacts are removed."""
@@ -1704,14 +1720,14 @@ class TestWBIsPlatformViable(CiTestCase):
"""White box tests for _is_platform_viable."""
with_logs = True
- @mock.patch('cloudinit.sources.DataSourceAzure.util.read_dmi_data')
+ @mock.patch(MOCKPATH + 'util.read_dmi_data')
def test_true_on_non_azure_chassis(self, m_read_dmi_data):
"""Return True if DMI chassis-asset-tag is AZURE_CHASSIS_ASSET_TAG."""
m_read_dmi_data.return_value = dsaz.AZURE_CHASSIS_ASSET_TAG
self.assertTrue(dsaz._is_platform_viable('doesnotmatter'))
- @mock.patch('cloudinit.sources.DataSourceAzure.os.path.exists')
- @mock.patch('cloudinit.sources.DataSourceAzure.util.read_dmi_data')
+ @mock.patch(MOCKPATH + 'os.path.exists')
+ @mock.patch(MOCKPATH + 'util.read_dmi_data')
def test_true_on_azure_ovf_env_in_seed_dir(self, m_read_dmi_data, m_exist):
"""Return True if ovf-env.xml exists in known seed dirs."""
# Non-matching Azure chassis-asset-tag
@@ -1729,7 +1745,7 @@ class TestWBIsPlatformViable(CiTestCase):
and no devices have a label starting with prefix 'rd_rdfe_'.
"""
self.assertFalse(wrap_and_call(
- 'cloudinit.sources.DataSourceAzure',
+ MOCKPATH,
{'os.path.exists': False,
# Non-matching Azure chassis-asset-tag
'util.read_dmi_data': dsaz.AZURE_CHASSIS_ASSET_TAG + 'X',
diff --git a/tests/unittests/test_datasource/test_cloudsigma.py b/tests/unittests/test_datasource/test_cloudsigma.py
index 380ad1b5..3bf52e69 100644
--- a/tests/unittests/test_datasource/test_cloudsigma.py
+++ b/tests/unittests/test_datasource/test_cloudsigma.py
@@ -68,6 +68,12 @@ class DataSourceCloudSigmaTest(test_helpers.CiTestCase):
self.assertEqual(SERVER_CONTEXT['uuid'],
self.datasource.get_instance_id())
+ def test_platform(self):
+ """All platform-related attributes are set."""
+ self.assertEqual(self.datasource.cloud_name, 'cloudsigma')
+ self.assertEqual(self.datasource.platform_type, 'cloudsigma')
+ self.assertEqual(self.datasource.subplatform, 'cepko (/dev/ttyS1)')
+
def test_metadata(self):
self.assertEqual(self.datasource.metadata, SERVER_CONTEXT)
diff --git a/tests/unittests/test_datasource/test_configdrive.py b/tests/unittests/test_datasource/test_configdrive.py
index 231619c9..dcdabea5 100644
--- a/tests/unittests/test_datasource/test_configdrive.py
+++ b/tests/unittests/test_datasource/test_configdrive.py
@@ -478,6 +478,9 @@ class TestConfigDriveDataSource(CiTestCase):
myds = cfg_ds_from_dir(self.tmp, files=CFG_DRIVE_FILES_V2)
self.assertEqual(myds.get_public_ssh_keys(),
[OSTACK_META['public_keys']['mykey']])
+ self.assertEqual('configdrive', myds.cloud_name)
+ self.assertEqual('openstack', myds.platform)
+ self.assertEqual('seed-dir (%s/seed)' % self.tmp, myds.subplatform)
class TestNetJson(CiTestCase):
diff --git a/tests/unittests/test_datasource/test_ec2.py b/tests/unittests/test_datasource/test_ec2.py
index 497e7610..9f81255a 100644
--- a/tests/unittests/test_datasource/test_ec2.py
+++ b/tests/unittests/test_datasource/test_ec2.py
@@ -351,7 +351,9 @@ class TestEc2(test_helpers.HttprettyTestCase):
m_get_interface_mac.return_value = mac1
nc = ds.network_config # Will re-crawl network metadata
self.assertIsNotNone(nc)
- self.assertIn('Re-crawl of metadata service', self.logs.getvalue())
+ self.assertIn(
+ 'Refreshing stale metadata from prior to upgrade',
+ self.logs.getvalue())
expected = {'version': 1, 'config': [
{'mac_address': '06:17:04:d7:26:09',
'name': 'eth9',
@@ -386,7 +388,7 @@ class TestEc2(test_helpers.HttprettyTestCase):
register_mock_metaserver(
'{0}/{1}/dynamic/'.format(ds.metadata_address, all_versions[-1]),
DYNAMIC_METADATA)
- ds._cloud_platform = ec2.Platforms.AWS
+ ds._cloud_name = ec2.CloudNames.AWS
# Setup cached metadata on the Datasource
ds.metadata = DEFAULT_METADATA
self.assertEqual('my-identity-id', ds.get_instance_id())
@@ -401,6 +403,9 @@ class TestEc2(test_helpers.HttprettyTestCase):
ret = ds.get_data()
self.assertTrue(ret)
self.assertEqual(0, m_dhcp.call_count)
+ self.assertEqual('aws', ds.cloud_name)
+ self.assertEqual('ec2', ds.platform_type)
+ self.assertEqual('metadata (%s)' % ds.metadata_address, ds.subplatform)
def test_valid_platform_with_strict_false(self):
"""Valid platform data should return true with strict_id false."""
@@ -439,16 +444,17 @@ class TestEc2(test_helpers.HttprettyTestCase):
sys_cfg={'datasource': {'Ec2': {'strict_id': False}}},
md=DEFAULT_METADATA)
platform_attrs = [
- attr for attr in ec2.Platforms.__dict__.keys()
+ attr for attr in ec2.CloudNames.__dict__.keys()
if not attr.startswith('__')]
for attr_name in platform_attrs:
- platform_name = getattr(ec2.Platforms, attr_name)
- if platform_name != 'AWS':
- ds._cloud_platform = platform_name
+ platform_name = getattr(ec2.CloudNames, attr_name)
+ if platform_name != 'aws':
+ ds._cloud_name = platform_name
ret = ds.get_data()
+ self.assertEqual('ec2', ds.platform_type)
self.assertFalse(ret)
message = (
- "Local Ec2 mode only supported on ('AWS',),"
+ "Local Ec2 mode only supported on ('aws',),"
' not {0}'.format(platform_name))
self.assertIn(message, self.logs.getvalue())
diff --git a/tests/unittests/test_datasource/test_ibmcloud.py b/tests/unittests/test_datasource/test_ibmcloud.py
index e639ae47..0b54f585 100644
--- a/tests/unittests/test_datasource/test_ibmcloud.py
+++ b/tests/unittests/test_datasource/test_ibmcloud.py
@@ -1,14 +1,17 @@
# This file is part of cloud-init. See LICENSE file for license information.
+from cloudinit.helpers import Paths
from cloudinit.sources import DataSourceIBMCloud as ibm
from cloudinit.tests import helpers as test_helpers
+from cloudinit import util
import base64
import copy
import json
-import mock
from textwrap import dedent
+mock = test_helpers.mock
+
D_PATH = "cloudinit.sources.DataSourceIBMCloud."
@@ -309,4 +312,39 @@ class TestIsIBMProvisioning(test_helpers.FilesystemMockingTestCase):
self.assertIn("no reference file", self.logs.getvalue())
+class TestDataSourceIBMCloud(test_helpers.CiTestCase):
+
+ def setUp(self):
+ super(TestDataSourceIBMCloud, self).setUp()
+ self.tmp = self.tmp_dir()
+ self.cloud_dir = self.tmp_path('cloud', dir=self.tmp)
+ util.ensure_dir(self.cloud_dir)
+ paths = Paths({'run_dir': self.tmp, 'cloud_dir': self.cloud_dir})
+ self.ds = ibm.DataSourceIBMCloud(
+ sys_cfg={}, distro=None, paths=paths)
+
+ def test_get_data_false(self):
+ """When read_md returns None, get_data returns False."""
+ with mock.patch(D_PATH + 'read_md', return_value=None):
+ self.assertFalse(self.ds.get_data())
+
+ def test_get_data_processes_read_md(self):
+ """get_data processes and caches content returned by read_md."""
+ md = {
+ 'metadata': {}, 'networkdata': 'net', 'platform': 'plat',
+ 'source': 'src', 'system-uuid': 'uuid', 'userdata': 'ud',
+ 'vendordata': 'vd'}
+ with mock.patch(D_PATH + 'read_md', return_value=md):
+ self.assertTrue(self.ds.get_data())
+ self.assertEqual('src', self.ds.source)
+ self.assertEqual('plat', self.ds.platform)
+ self.assertEqual({}, self.ds.metadata)
+ self.assertEqual('ud', self.ds.userdata_raw)
+ self.assertEqual('net', self.ds.network_json)
+ self.assertEqual('vd', self.ds.vendordata_pure)
+ self.assertEqual('uuid', self.ds.system_uuid)
+ self.assertEqual('ibmcloud', self.ds.cloud_name)
+ self.assertEqual('ibmcloud', self.ds.platform_type)
+ self.assertEqual('plat (src)', self.ds.subplatform)
+
# vi: ts=4 expandtab
diff --git a/tests/unittests/test_datasource/test_nocloud.py b/tests/unittests/test_datasource/test_nocloud.py
index 21931eb7..b6468b6d 100644
--- a/tests/unittests/test_datasource/test_nocloud.py
+++ b/tests/unittests/test_datasource/test_nocloud.py
@@ -10,6 +10,7 @@ import textwrap
import yaml
+@mock.patch('cloudinit.sources.DataSourceNoCloud.util.is_lxd')
class TestNoCloudDataSource(CiTestCase):
def setUp(self):
@@ -28,10 +29,11 @@ class TestNoCloudDataSource(CiTestCase):
self.mocks.enter_context(
mock.patch.object(util, 'read_dmi_data', return_value=None))
- def test_nocloud_seed_dir(self):
+ def test_nocloud_seed_dir_on_lxd(self, m_is_lxd):
md = {'instance-id': 'IID', 'dsmode': 'local'}
ud = b"USER_DATA_HERE"
- populate_dir(os.path.join(self.paths.seed_dir, "nocloud"),
+ seed_dir = os.path.join(self.paths.seed_dir, "nocloud")
+ populate_dir(seed_dir,
{'user-data': ud, 'meta-data': yaml.safe_dump(md)})
sys_cfg = {
@@ -44,9 +46,32 @@ class TestNoCloudDataSource(CiTestCase):
ret = dsrc.get_data()
self.assertEqual(dsrc.userdata_raw, ud)
self.assertEqual(dsrc.metadata, md)
+ self.assertEqual(dsrc.platform_type, 'lxd')
+ self.assertEqual(
+ dsrc.subplatform, 'seed-dir (%s)' % seed_dir)
self.assertTrue(ret)
- def test_fs_label(self):
+ def test_nocloud_seed_dir_non_lxd_platform_is_nocloud(self, m_is_lxd):
+ """Non-lxd environments will list nocloud as the platform."""
+ m_is_lxd.return_value = False
+ md = {'instance-id': 'IID', 'dsmode': 'local'}
+ seed_dir = os.path.join(self.paths.seed_dir, "nocloud")
+ populate_dir(seed_dir,
+ {'user-data': '', 'meta-data': yaml.safe_dump(md)})
+
+ sys_cfg = {
+ 'datasource': {'NoCloud': {'fs_label': None}}
+ }
+
+ ds = DataSourceNoCloud.DataSourceNoCloud
+
+ dsrc = ds(sys_cfg=sys_cfg, distro=None, paths=self.paths)
+ self.assertTrue(dsrc.get_data())
+ self.assertEqual(dsrc.platform_type, 'nocloud')
+ self.assertEqual(
+ dsrc.subplatform, 'seed-dir (%s)' % seed_dir)
+
+ def test_fs_label(self, m_is_lxd):
# find_devs_with should not be called ff fs_label is None
ds = DataSourceNoCloud.DataSourceNoCloud
@@ -68,7 +93,7 @@ class TestNoCloudDataSource(CiTestCase):
ret = dsrc.get_data()
self.assertFalse(ret)
- def test_no_datasource_expected(self):
+ def test_no_datasource_expected(self, m_is_lxd):
# no source should be found if no cmdline, config, and fs_label=None
sys_cfg = {'datasource': {'NoCloud': {'fs_label': None}}}
@@ -76,7 +101,7 @@ class TestNoCloudDataSource(CiTestCase):
dsrc = ds(sys_cfg=sys_cfg, distro=None, paths=self.paths)
self.assertFalse(dsrc.get_data())
- def test_seed_in_config(self):
+ def test_seed_in_config(self, m_is_lxd):
ds = DataSourceNoCloud.DataSourceNoCloud
data = {
@@ -92,7 +117,7 @@ class TestNoCloudDataSource(CiTestCase):
self.assertEqual(dsrc.metadata.get('instance-id'), 'IID')
self.assertTrue(ret)
- def test_nocloud_seed_with_vendordata(self):
+ def test_nocloud_seed_with_vendordata(self, m_is_lxd):
md = {'instance-id': 'IID', 'dsmode': 'local'}
ud = b"USER_DATA_HERE"
vd = b"THIS IS MY VENDOR_DATA"
@@ -114,7 +139,7 @@ class TestNoCloudDataSource(CiTestCase):
self.assertEqual(dsrc.vendordata_raw, vd)
self.assertTrue(ret)
- def test_nocloud_no_vendordata(self):
+ def test_nocloud_no_vendordata(self, m_is_lxd):
populate_dir(os.path.join(self.paths.seed_dir, "nocloud"),
{'user-data': b"ud", 'meta-data': "instance-id: IID\n"})
@@ -128,7 +153,7 @@ class TestNoCloudDataSource(CiTestCase):
self.assertFalse(dsrc.vendordata)
self.assertTrue(ret)
- def test_metadata_network_interfaces(self):
+ def test_metadata_network_interfaces(self, m_is_lxd):
gateway = "103.225.10.1"
md = {
'instance-id': 'i-abcd',
@@ -157,7 +182,7 @@ class TestNoCloudDataSource(CiTestCase):
# very simple check just for the strings above
self.assertIn(gateway, str(dsrc.network_config))
- def test_metadata_network_config(self):
+ def test_metadata_network_config(self, m_is_lxd):
# network-config needs to get into network_config
netconf = {'version': 1,
'config': [{'type': 'physical', 'name': 'interface0',
@@ -177,7 +202,7 @@ class TestNoCloudDataSource(CiTestCase):
self.assertTrue(ret)
self.assertEqual(netconf, dsrc.network_config)
- def test_metadata_network_config_over_interfaces(self):
+ def test_metadata_network_config_over_interfaces(self, m_is_lxd):
# network-config should override meta-data/network-interfaces
gateway = "103.225.10.1"
md = {
diff --git a/tests/unittests/test_datasource/test_opennebula.py b/tests/unittests/test_datasource/test_opennebula.py
index 61591017..bb399f6d 100644
--- a/tests/unittests/test_datasource/test_opennebula.py
+++ b/tests/unittests/test_datasource/test_opennebula.py
@@ -123,6 +123,10 @@ class TestOpenNebulaDataSource(CiTestCase):
self.assertTrue(ret)
finally:
util.find_devs_with = orig_find_devs_with
+ self.assertEqual('opennebula', dsrc.cloud_name)
+ self.assertEqual('opennebula', dsrc.platform_type)
+ self.assertEqual(
+ 'seed-dir (%s/seed/opennebula)' % self.tmp, dsrc.subplatform)
def test_seed_dir_non_contextdisk(self):
self.assertRaises(ds.NonContextDiskDir, ds.read_context_disk_dir,
diff --git a/tests/unittests/test_datasource/test_ovf.py b/tests/unittests/test_datasource/test_ovf.py
index 9d52eb99..a226c032 100644
--- a/tests/unittests/test_datasource/test_ovf.py
+++ b/tests/unittests/test_datasource/test_ovf.py
@@ -11,7 +11,7 @@ from collections import OrderedDict
from textwrap import dedent
from cloudinit import util
-from cloudinit.tests.helpers import CiTestCase, wrap_and_call
+from cloudinit.tests.helpers import CiTestCase, mock, wrap_and_call
from cloudinit.helpers import Paths
from cloudinit.sources import DataSourceOVF as dsovf
from cloudinit.sources.helpers.vmware.imc.config_custom_script import (
@@ -120,7 +120,7 @@ class TestDatasourceOVF(CiTestCase):
def test_get_data_false_on_none_dmi_data(self):
"""When dmi for system-product-name is None, get_data returns False."""
- paths = Paths({'seed_dir': self.tdir})
+ paths = Paths({'cloud_dir': self.tdir})
ds = self.datasource(sys_cfg={}, distro={}, paths=paths)
retcode = wrap_and_call(
'cloudinit.sources.DataSourceOVF',
@@ -134,7 +134,7 @@ class TestDatasourceOVF(CiTestCase):
def test_get_data_no_vmware_customization_disabled(self):
"""When vmware customization is disabled via sys_cfg log a message."""
- paths = Paths({'seed_dir': self.tdir})
+ paths = Paths({'cloud_dir': self.tdir})
ds = self.datasource(
sys_cfg={'disable_vmware_customization': True}, distro={},
paths=paths)
@@ -153,7 +153,7 @@ class TestDatasourceOVF(CiTestCase):
"""When cloud-init workflow for vmware is enabled via sys_cfg log a
message.
"""
- paths = Paths({'seed_dir': self.tdir})
+ paths = Paths({'cloud_dir': self.tdir})
ds = self.datasource(
sys_cfg={'disable_vmware_customization': False}, distro={},
paths=paths)
@@ -178,6 +178,50 @@ class TestDatasourceOVF(CiTestCase):
self.assertIn('Script %s not found!!' % customscript,
str(context.exception))
+ def test_get_data_non_vmware_seed_platform_info(self):
+ """Platform info properly reports when on non-vmware platforms."""
+ paths = Paths({'cloud_dir': self.tdir, 'run_dir': self.tdir})
+ # Write ovf-env.xml seed file
+ seed_dir = self.tmp_path('seed', dir=self.tdir)
+ ovf_env = self.tmp_path('ovf-env.xml', dir=seed_dir)
+ util.write_file(ovf_env, OVF_ENV_CONTENT)
+ ds = self.datasource(sys_cfg={}, distro={}, paths=paths)
+
+ self.assertEqual('ovf', ds.cloud_name)
+ self.assertEqual('ovf', ds.platform_type)
+ MPATH = 'cloudinit.sources.DataSourceOVF.'
+ with mock.patch(MPATH + 'util.read_dmi_data', return_value='!VMware'):
+ with mock.patch(MPATH + 'transport_vmware_guestd') as m_guestd:
+ with mock.patch(MPATH + 'transport_iso9660') as m_iso9660:
+ m_iso9660.return_value = (None, 'ignored', 'ignored')
+ m_guestd.return_value = (None, 'ignored', 'ignored')
+ self.assertTrue(ds.get_data())
+ self.assertEqual(
+ 'ovf (%s/seed/ovf-env.xml)' % self.tdir,
+ ds.subplatform)
+
+ def test_get_data_vmware_seed_platform_info(self):
+ """Platform info properly reports when on VMware platform."""
+ paths = Paths({'cloud_dir': self.tdir, 'run_dir': self.tdir})
+ # Write ovf-env.xml seed file
+ seed_dir = self.tmp_path('seed', dir=self.tdir)
+ ovf_env = self.tmp_path('ovf-env.xml', dir=seed_dir)
+ util.write_file(ovf_env, OVF_ENV_CONTENT)
+ ds = self.datasource(sys_cfg={}, distro={}, paths=paths)
+
+ self.assertEqual('ovf', ds.cloud_name)
+ self.assertEqual('ovf', ds.platform_type)
+ MPATH = 'cloudinit.sources.DataSourceOVF.'
+ with mock.patch(MPATH + 'util.read_dmi_data', return_value='VMWare'):
+ with mock.patch(MPATH + 'transport_vmware_guestd') as m_guestd:
+ with mock.patch(MPATH + 'transport_iso9660') as m_iso9660:
+ m_iso9660.return_value = (None, 'ignored', 'ignored')
+ m_guestd.return_value = (None, 'ignored', 'ignored')
+ self.assertTrue(ds.get_data())
+ self.assertEqual(
+ 'vmware (%s/seed/ovf-env.xml)' % self.tdir,
+ ds.subplatform)
+
class TestTransportIso9660(CiTestCase):
diff --git a/tests/unittests/test_datasource/test_smartos.py b/tests/unittests/test_datasource/test_smartos.py
index 46d67b94..42ac6971 100644
--- a/tests/unittests/test_datasource/test_smartos.py
+++ b/tests/unittests/test_datasource/test_smartos.py
@@ -426,6 +426,13 @@ class TestSmartOSDataSource(FilesystemMockingTestCase):
self.assertEqual(MOCK_RETURNS['sdc:uuid'],
dsrc.metadata['instance-id'])
+ def test_platform_info(self):
+ """All platform-related attributes are properly set."""
+ dsrc = self._get_ds(mockdata=MOCK_RETURNS)
+ self.assertEqual('joyent', dsrc.cloud_name)
+ self.assertEqual('joyent', dsrc.platform_type)
+ self.assertEqual('serial (/dev/ttyS1)', dsrc.subplatform)
+
def test_root_keys(self):
dsrc = self._get_ds(mockdata=MOCK_RETURNS)
ret = dsrc.get_data()