summaryrefslogtreecommitdiff
path: root/tests/unittests
diff options
context:
space:
mode:
Diffstat (limited to 'tests/unittests')
-rw-r--r--tests/unittests/__init__.py2
-rw-r--r--tests/unittests/helpers.py37
-rw-r--r--tests/unittests/test__init__.py2
-rw-r--r--tests/unittests/test_atomic_helper.py4
-rw-r--r--tests/unittests/test_builtin_handlers.py4
-rw-r--r--tests/unittests/test_cli.py5
-rw-r--r--tests/unittests/test_cs_util.py4
-rw-r--r--tests/unittests/test_data.py55
-rw-r--r--tests/unittests/test_datasource/test_aliyun.py4
-rw-r--r--tests/unittests/test_datasource/test_altcloud.py24
-rw-r--r--tests/unittests/test_datasource/test_azure.py44
-rw-r--r--tests/unittests/test_datasource/test_azure_helper.py4
-rw-r--r--tests/unittests/test_datasource/test_cloudsigma.py22
-rw-r--r--tests/unittests/test_datasource/test_cloudstack.py4
-rw-r--r--tests/unittests/test_datasource/test_common.py75
-rw-r--r--tests/unittests/test_datasource/test_configdrive.py2
-rw-r--r--tests/unittests/test_datasource/test_digitalocean.py19
-rw-r--r--tests/unittests/test_datasource/test_gce.py19
-rw-r--r--tests/unittests/test_datasource/test_maas.py2
-rw-r--r--tests/unittests/test_datasource/test_nocloud.py2
-rw-r--r--tests/unittests/test_datasource/test_opennebula.py2
-rw-r--r--tests/unittests/test_datasource/test_openstack.py20
-rw-r--r--tests/unittests/test_datasource/test_ovf.py20
-rw-r--r--tests/unittests/test_datasource/test_smartos.py33
-rw-r--r--tests/unittests/test_distros/test_create_users.py151
-rw-r--r--tests/unittests/test_distros/test_generic.py2
-rw-r--r--tests/unittests/test_distros/test_hostname.py4
-rw-r--r--tests/unittests/test_distros/test_hosts.py4
-rw-r--r--tests/unittests/test_distros/test_netconfig.py4
-rw-r--r--tests/unittests/test_distros/test_resolv.py4
-rw-r--r--tests/unittests/test_distros/test_sysconfig.py4
-rwxr-xr-xtests/unittests/test_distros/test_user_data_normalize.py4
-rw-r--r--tests/unittests/test_ec2_util.py4
-rw-r--r--tests/unittests/test_filters/test_launch_index.py4
-rw-r--r--tests/unittests/test_handler/test_handler_apt_conf_v1.py2
-rw-r--r--tests/unittests/test_handler/test_handler_apt_configure_sources_list_v1.py2
-rw-r--r--tests/unittests/test_handler/test_handler_apt_configure_sources_list_v3.py2
-rw-r--r--tests/unittests/test_handler/test_handler_apt_source_v1.py2
-rw-r--r--tests/unittests/test_handler/test_handler_apt_source_v3.py2
-rw-r--r--tests/unittests/test_handler/test_handler_ca_certs.py4
-rw-r--r--tests/unittests/test_handler/test_handler_chef.py4
-rw-r--r--tests/unittests/test_handler/test_handler_debug.py18
-rw-r--r--tests/unittests/test_handler/test_handler_disk_setup.py76
-rw-r--r--tests/unittests/test_handler/test_handler_growpart.py2
-rw-r--r--tests/unittests/test_handler/test_handler_locale.py20
-rw-r--r--tests/unittests/test_handler/test_handler_lxd.py4
-rw-r--r--tests/unittests/test_handler/test_handler_mcollective.py4
-rw-r--r--tests/unittests/test_handler/test_handler_mounts.py4
-rw-r--r--tests/unittests/test_handler/test_handler_ntp.py4
-rw-r--r--tests/unittests/test_handler/test_handler_power_state.py4
-rw-r--r--tests/unittests/test_handler/test_handler_rsyslog.py4
-rw-r--r--tests/unittests/test_handler/test_handler_seed_random.py16
-rw-r--r--tests/unittests/test_handler/test_handler_set_hostname.py4
-rw-r--r--tests/unittests/test_handler/test_handler_snappy.py4
-rw-r--r--tests/unittests/test_handler/test_handler_spacewalk.py4
-rw-r--r--tests/unittests/test_handler/test_handler_timezone.py20
-rw-r--r--tests/unittests/test_handler/test_handler_write_files.py2
-rw-r--r--tests/unittests/test_handler/test_handler_yum_add_repo.py4
-rw-r--r--tests/unittests/test_helpers.py4
-rw-r--r--tests/unittests/test_merging.py4
-rwxr-xr-x[-rw-r--r--]tests/unittests/test_net.py154
-rw-r--r--tests/unittests/test_pathprefix2dict.py2
-rw-r--r--tests/unittests/test_registry.py4
-rw-r--r--tests/unittests/test_reporting.py5
-rw-r--r--tests/unittests/test_rh_subscription.py20
-rw-r--r--tests/unittests/test_runs/test_merge_run.py4
-rw-r--r--tests/unittests/test_runs/test_simple_run.py4
-rw-r--r--tests/unittests/test_sshutil.py2
-rw-r--r--tests/unittests/test_templating.py20
-rw-r--r--tests/unittests/test_util.py71
-rw-r--r--tests/unittests/test_vmware_config_file.py22
71 files changed, 880 insertions, 242 deletions
diff --git a/tests/unittests/__init__.py b/tests/unittests/__init__.py
index 1b34b5af..d89ed443 100644
--- a/tests/unittests/__init__.py
+++ b/tests/unittests/__init__.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
try:
# For test cases, avoid the following UserWarning to stderr:
# You don't have the C version of NameMapper installed ...
diff --git a/tests/unittests/helpers.py b/tests/unittests/helpers.py
index a2355a79..cf3b46d2 100644
--- a/tests/unittests/helpers.py
+++ b/tests/unittests/helpers.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
from __future__ import print_function
import functools
@@ -300,6 +302,39 @@ def dir2dict(startdir, prefix=None):
return flist
+def wrap_and_call(prefix, mocks, func, *args, **kwargs):
+ """
+ call func(args, **kwargs) with mocks applied, then unapplies mocks
+ nicer to read than repeating dectorators on each function
+
+ prefix: prefix for mock names (e.g. 'cloudinit.stages.util') or None
+ mocks: dictionary of names (under 'prefix') to mock and either
+ a return value or a dictionary to pass to the mock.patch call
+ func: function to call with mocks applied
+ *args,**kwargs: arguments for 'func'
+
+ return_value: return from 'func'
+ """
+ delim = '.'
+ if prefix is None:
+ prefix = ''
+ prefix = prefix.rstrip(delim)
+ unwraps = []
+ for fname, kw in mocks.items():
+ if prefix:
+ fname = delim.join((prefix, fname))
+ if not isinstance(kw, dict):
+ kw = {'return_value': kw}
+ p = mock.patch(fname, **kw)
+ p.start()
+ unwraps.append(p)
+ try:
+ return func(*args, **kwargs)
+ finally:
+ for p in unwraps:
+ p.stop()
+
+
try:
skipIf = unittest.skipIf
except AttributeError:
@@ -313,3 +348,5 @@ except AttributeError:
print(reason, file=sys.stderr)
return wrapper
return decorator
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test__init__.py b/tests/unittests/test__init__.py
index 0154784a..7b6f8c4e 100644
--- a/tests/unittests/test__init__.py
+++ b/tests/unittests/test__init__.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
import os
import shutil
import tempfile
diff --git a/tests/unittests/test_atomic_helper.py b/tests/unittests/test_atomic_helper.py
index feb81551..e170c7c3 100644
--- a/tests/unittests/test_atomic_helper.py
+++ b/tests/unittests/test_atomic_helper.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
import json
import os
import stat
@@ -52,3 +54,5 @@ class TestAtomicHelper(helpers.TempDirTestCase):
def check_perms(self, path, perms):
file_stat = os.stat(path)
self.assertEqual(perms, stat.S_IMODE(file_stat.st_mode))
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_builtin_handlers.py b/tests/unittests/test_builtin_handlers.py
index dea908d7..dd9d0357 100644
--- a/tests/unittests/test_builtin_handlers.py
+++ b/tests/unittests/test_builtin_handlers.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
"""Tests of the built-in user data handlers."""
import os
@@ -71,3 +73,5 @@ class TestBuiltins(test_helpers.FilesystemMockingTestCase):
mockobj.assert_called_once_with(
['initctl', 'reload-configuration'], capture=False)
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_cli.py b/tests/unittests/test_cli.py
index 5fa252f7..06f366b2 100644
--- a/tests/unittests/test_cli.py
+++ b/tests/unittests/test_cli.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
import six
from . import helpers as test_helpers
@@ -32,3 +34,6 @@ class TestCLI(test_helpers.FilesystemMockingTestCase):
self.assertIn('cloud-init: error: too few arguments',
self.stderr.getvalue())
self.assertEqual(2, exit_code)
+
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_cs_util.py b/tests/unittests/test_cs_util.py
index 56c9ce9e..b8f5031c 100644
--- a/tests/unittests/test_cs_util.py
+++ b/tests/unittests/test_cs_util.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
from __future__ import print_function
from . import helpers as test_helpers
@@ -61,3 +63,5 @@ class CepkoResultTests(test_helpers.TestCase):
self.assertEqual('much server', result[0])
self.assertTrue('very performance' in result)
self.assertEqual(2, len(result))
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_data.py b/tests/unittests/test_data.py
index 55d9b93f..4092d9ca 100644
--- a/tests/unittests/test_data.py
+++ b/tests/unittests/test_data.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
"""Tests for handling of userdata within cloud init."""
import gzip
@@ -559,3 +561,56 @@ class TestConvertString(helpers.TestCase):
text = "hi mom"
msg = ud.convert_string(text)
self.assertEqual(text, msg.get_payload(decode=False))
+
+
+class TestFetchBaseConfig(helpers.TestCase):
+
+ def test_only_builtin_gets_builtin2(self):
+ ret = helpers.wrap_and_call(
+ 'cloudinit.stages.util',
+ {'read_conf_with_confd': None,
+ 'read_conf_from_cmdline': None},
+ stages.fetch_base_config)
+ self.assertEqual(util.get_builtin_cfg(), ret)
+
+ def test_conf_d_overrides_defaults(self):
+ builtin = util.get_builtin_cfg()
+ test_key = sorted(builtin)[0]
+ test_value = 'test'
+ ret = helpers.wrap_and_call(
+ 'cloudinit.stages.util',
+ {'read_conf_with_confd': {'return_value': {test_key: test_value}},
+ 'read_conf_from_cmdline': None},
+ stages.fetch_base_config)
+ self.assertEqual(ret.get(test_key), test_value)
+ builtin[test_key] = test_value
+ self.assertEqual(ret, builtin)
+
+ def test_cmdline_overrides_defaults(self):
+ builtin = util.get_builtin_cfg()
+ test_key = sorted(builtin)[0]
+ test_value = 'test'
+ cmdline = {test_key: test_value}
+ ret = helpers.wrap_and_call(
+ 'cloudinit.stages.util',
+ {'read_conf_from_cmdline': {'return_value': cmdline},
+ 'read_conf_with_confd': None},
+ stages.fetch_base_config)
+ self.assertEqual(ret.get(test_key), test_value)
+ builtin[test_key] = test_value
+ self.assertEqual(ret, builtin)
+
+ def test_cmdline_overrides_conf_d_and_defaults(self):
+ builtin = {'key1': 'value0', 'key3': 'other2'}
+ conf_d = {'key1': 'value1', 'key2': 'other1'}
+ cmdline = {'key3': 'other3', 'key2': 'other2'}
+ ret = helpers.wrap_and_call(
+ 'cloudinit.stages.util',
+ {'read_conf_with_confd': {'return_value': conf_d},
+ 'get_builtin_cfg': {'return_value': builtin},
+ 'read_conf_from_cmdline': {'return_value': cmdline}},
+ stages.fetch_base_config)
+ self.assertEqual(ret, {'key1': 'value1', 'key2': 'other2',
+ 'key3': 'other3'})
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_datasource/test_aliyun.py b/tests/unittests/test_datasource/test_aliyun.py
index 6f1de072..c16d1a6e 100644
--- a/tests/unittests/test_datasource/test_aliyun.py
+++ b/tests/unittests/test_datasource/test_aliyun.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
import functools
import httpretty
import os
@@ -146,3 +148,5 @@ class TestAliYunDatasource(test_helpers.HttprettyTestCase):
'ssh-key-1']}}
self.assertEqual(ay.parse_public_keys(public_keys),
public_keys['key-pair-0']['openssh-key'])
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_datasource/test_altcloud.py b/tests/unittests/test_datasource/test_altcloud.py
index 12966563..b0ad86ab 100644
--- a/tests/unittests/test_datasource/test_altcloud.py
+++ b/tests/unittests/test_datasource/test_altcloud.py
@@ -1,22 +1,11 @@
-# vi: ts=4 expandtab
-#
-# Copyright (C) 2009-2010 Canonical Ltd.
-# Copyright (C) 2012 Hewlett-Packard Development Company, L.P.
-# Copyright (C) 2012 Yahoo! Inc.
-#
-# Author: Joe VLcek <JVLcek@RedHat.com>
+# Copyright (C) 2009-2010 Canonical Ltd.
+# Copyright (C) 2012 Hewlett-Packard Development Company, L.P.
+# Copyright (C) 2012 Yahoo! Inc.
#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
+# Author: Joe VLcek <JVLcek@RedHat.com>
#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# This file is part of cloud-init. See LICENSE file for license information.
+
'''
This test file exercises the code in sources DataSourceAltCloud.py
'''
@@ -448,5 +437,4 @@ def force_arch(arch=None):
elif arch is None:
setattr(os, 'uname', OS_UNAME_ORIG)
-
# vi: ts=4 expandtab
diff --git a/tests/unittests/test_datasource/test_azure.py b/tests/unittests/test_datasource/test_azure.py
index 07127008..8d22bb59 100644
--- a/tests/unittests/test_datasource/test_azure.py
+++ b/tests/unittests/test_datasource/test_azure.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
from cloudinit import helpers
from cloudinit.util import b64e, decode_binary, load_file
from cloudinit.sources import DataSourceAzure
@@ -93,7 +95,7 @@ class TestAzureDataSource(TestCase):
for module, name, new in patches:
self.patches.enter_context(mock.patch.object(module, name, new))
- def _get_ds(self, data):
+ def _get_ds(self, data, agent_command=None):
def dsdevs():
return data.get('dsdevs', [])
@@ -137,6 +139,8 @@ class TestAzureDataSource(TestCase):
dsrc = mod.DataSourceAzureNet(
data.get('sys_cfg', {}), distro=None, paths=self.paths)
+ if agent_command is not None:
+ dsrc.ds_cfg['agent_command'] = agent_command
return dsrc
@@ -299,7 +303,7 @@ class TestAzureDataSource(TestCase):
data = {'ovfcontent': construct_valid_ovf_env(data=odata,
pubkeys=pubkeys)}
- dsrc = self._get_ds(data)
+ dsrc = self._get_ds(data, agent_command=['not', '__builtin__'])
ret = dsrc.get_data()
self.assertTrue(ret)
for mypk in mypklist:
@@ -314,7 +318,7 @@ class TestAzureDataSource(TestCase):
data = {'ovfcontent': construct_valid_ovf_env(data=odata,
pubkeys=pubkeys)}
- dsrc = self._get_ds(data)
+ dsrc = self._get_ds(data, agent_command=['not', '__builtin__'])
ret = dsrc.get_data()
self.assertTrue(ret)
@@ -330,7 +334,7 @@ class TestAzureDataSource(TestCase):
data = {'ovfcontent': construct_valid_ovf_env(data=odata,
pubkeys=pubkeys)}
- dsrc = self._get_ds(data)
+ dsrc = self._get_ds(data, agent_command=['not', '__builtin__'])
ret = dsrc.get_data()
self.assertTrue(ret)
@@ -487,12 +491,15 @@ class TestAzureBounce(TestCase):
def tearDown(self):
self.patches.close()
- def _get_ds(self, ovfcontent=None):
+ def _get_ds(self, ovfcontent=None, agent_command=None):
if ovfcontent is not None:
populate_dir(os.path.join(self.paths.seed_dir, "azure"),
{'ovf-env.xml': ovfcontent})
- return DataSourceAzure.DataSourceAzureNet(
+ dsrc = DataSourceAzure.DataSourceAzureNet(
{}, distro=None, paths=self.paths)
+ if agent_command is not None:
+ dsrc.ds_cfg['agent_command'] = agent_command
+ return dsrc
def get_ovf_env_with_dscfg(self, hostname, cfg):
odata = {
@@ -537,14 +544,17 @@ class TestAzureBounce(TestCase):
host_name = 'unchanged-host-name'
self.get_hostname.return_value = host_name
cfg = {'hostname_bounce': {'policy': 'force'}}
- self._get_ds(self.get_ovf_env_with_dscfg(host_name, cfg)).get_data()
+ self._get_ds(self.get_ovf_env_with_dscfg(host_name, cfg),
+ agent_command=['not', '__builtin__']).get_data()
self.assertEqual(1, perform_hostname_bounce.call_count)
def test_different_hostnames_sets_hostname(self):
expected_hostname = 'azure-expected-host-name'
self.get_hostname.return_value = 'default-host-name'
self._get_ds(
- self.get_ovf_env_with_dscfg(expected_hostname, {})).get_data()
+ self.get_ovf_env_with_dscfg(expected_hostname, {}),
+ agent_command=['not', '__builtin__'],
+ ).get_data()
self.assertEqual(expected_hostname,
self.set_hostname.call_args_list[0][0][0])
@@ -554,14 +564,18 @@ class TestAzureBounce(TestCase):
expected_hostname = 'azure-expected-host-name'
self.get_hostname.return_value = 'default-host-name'
self._get_ds(
- self.get_ovf_env_with_dscfg(expected_hostname, {})).get_data()
+ self.get_ovf_env_with_dscfg(expected_hostname, {}),
+ agent_command=['not', '__builtin__'],
+ ).get_data()
self.assertEqual(1, perform_hostname_bounce.call_count)
def test_different_hostnames_sets_hostname_back(self):
initial_host_name = 'default-host-name'
self.get_hostname.return_value = initial_host_name
self._get_ds(
- self.get_ovf_env_with_dscfg('some-host-name', {})).get_data()
+ self.get_ovf_env_with_dscfg('some-host-name', {}),
+ agent_command=['not', '__builtin__'],
+ ).get_data()
self.assertEqual(initial_host_name,
self.set_hostname.call_args_list[-1][0][0])
@@ -572,7 +586,9 @@ class TestAzureBounce(TestCase):
initial_host_name = 'default-host-name'
self.get_hostname.return_value = initial_host_name
self._get_ds(
- self.get_ovf_env_with_dscfg('some-host-name', {})).get_data()
+ self.get_ovf_env_with_dscfg('some-host-name', {}),
+ agent_command=['not', '__builtin__'],
+ ).get_data()
self.assertEqual(initial_host_name,
self.set_hostname.call_args_list[-1][0][0])
@@ -583,7 +599,7 @@ class TestAzureBounce(TestCase):
self.get_hostname.return_value = old_hostname
cfg = {'hostname_bounce': {'interface': interface, 'policy': 'force'}}
data = self.get_ovf_env_with_dscfg(hostname, cfg)
- self._get_ds(data).get_data()
+ self._get_ds(data, agent_command=['not', '__builtin__']).get_data()
self.assertEqual(1, self.subp.call_count)
bounce_env = self.subp.call_args[1]['env']
self.assertEqual(interface, bounce_env['interface'])
@@ -595,7 +611,7 @@ class TestAzureBounce(TestCase):
DataSourceAzure.BUILTIN_DS_CONFIG['hostname_bounce']['command'] = cmd
cfg = {'hostname_bounce': {'policy': 'force'}}
data = self.get_ovf_env_with_dscfg('some-hostname', cfg)
- self._get_ds(data).get_data()
+ self._get_ds(data, agent_command=['not', '__builtin__']).get_data()
self.assertEqual(1, self.subp.call_count)
bounce_args = self.subp.call_args[1]['args']
self.assertEqual(cmd, bounce_args)
@@ -630,3 +646,5 @@ class TestReadAzureOvf(TestCase):
(_md, _ud, cfg) = DataSourceAzure.read_azure_ovf(content)
for mypk in mypklist:
self.assertIn(mypk, cfg['_pubkeys'])
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_datasource/test_azure_helper.py b/tests/unittests/test_datasource/test_azure_helper.py
index 64523e16..aafdebd7 100644
--- a/tests/unittests/test_datasource/test_azure_helper.py
+++ b/tests/unittests/test_datasource/test_azure_helper.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
import os
from cloudinit.sources.helpers import azure as azure_helper
@@ -419,3 +421,5 @@ class TestGetMetadataFromFabric(TestCase):
self.assertRaises(SentinelException,
azure_helper.get_metadata_from_fabric)
self.assertEqual(1, shim.return_value.clean_up.call_count)
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_datasource/test_cloudsigma.py b/tests/unittests/test_datasource/test_cloudsigma.py
index 2a42ce0c..5997102c 100644
--- a/tests/unittests/test_datasource/test_cloudsigma.py
+++ b/tests/unittests/test_datasource/test_cloudsigma.py
@@ -1,8 +1,9 @@
-# coding: utf-8
+# This file is part of cloud-init. See LICENSE file for license information.
import copy
from cloudinit.cs_utils import Cepko
+from cloudinit import sources
from cloudinit.sources import DataSourceCloudSigma
from .. import helpers as test_helpers
@@ -49,7 +50,8 @@ class DataSourceCloudSigmaTest(test_helpers.TestCase):
self.assertEqual("test_server", self.datasource.get_hostname())
self.datasource.metadata['name'] = ''
self.assertEqual("65b2fb23", self.datasource.get_hostname())
- self.datasource.metadata['name'] = u'тест'
+ utf8_hostname = b'\xd1\x82\xd0\xb5\xd1\x81\xd1\x82'.decode('utf-8')
+ self.datasource.metadata['name'] = utf8_hostname
self.assertEqual("65b2fb23", self.datasource.get_hostname())
def test_get_public_ssh_keys(self):
@@ -97,3 +99,19 @@ class DataSourceCloudSigmaTest(test_helpers.TestCase):
self.datasource.get_data()
self.assertIsNone(self.datasource.vendordata_raw)
+
+
+class DsLoads(test_helpers.TestCase):
+ def test_get_datasource_list_returns_in_local(self):
+ deps = (sources.DEP_FILESYSTEM,)
+ ds_list = DataSourceCloudSigma.get_datasource_list(deps)
+ self.assertEqual(ds_list,
+ [DataSourceCloudSigma.DataSourceCloudSigma])
+
+ def test_list_sources_finds_ds(self):
+ found = sources.list_sources(
+ ['CloudSigma'], (sources.DEP_FILESYSTEM,), ['cloudinit.sources'])
+ self.assertEqual([DataSourceCloudSigma.DataSourceCloudSigma],
+ found)
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_datasource/test_cloudstack.py b/tests/unittests/test_datasource/test_cloudstack.py
index b1aab17b..e93d28de 100644
--- a/tests/unittests/test_datasource/test_cloudstack.py
+++ b/tests/unittests/test_datasource/test_cloudstack.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
from cloudinit import helpers
from cloudinit.sources.DataSourceCloudStack import DataSourceCloudStack
@@ -76,3 +78,5 @@ class TestCloudStackPasswordFetching(TestCase):
def test_password_not_saved_if_bad_request(self):
self._check_password_not_saved_for('bad_request')
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_datasource/test_common.py b/tests/unittests/test_datasource/test_common.py
new file mode 100644
index 00000000..c08717f3
--- /dev/null
+++ b/tests/unittests/test_datasource/test_common.py
@@ -0,0 +1,75 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
+from cloudinit import settings
+from cloudinit import sources
+from cloudinit import type_utils
+from cloudinit.sources import (
+ DataSourceAliYun as AliYun,
+ DataSourceAltCloud as AltCloud,
+ DataSourceAzure as Azure,
+ DataSourceBigstep as Bigstep,
+ DataSourceCloudSigma as CloudSigma,
+ DataSourceCloudStack as CloudStack,
+ DataSourceConfigDrive as ConfigDrive,
+ DataSourceDigitalOcean as DigitalOcean,
+ DataSourceEc2 as Ec2,
+ DataSourceGCE as GCE,
+ DataSourceMAAS as MAAS,
+ DataSourceNoCloud as NoCloud,
+ DataSourceOpenNebula as OpenNebula,
+ DataSourceOpenStack as OpenStack,
+ DataSourceOVF as OVF,
+ DataSourceSmartOS as SmartOS,
+)
+from cloudinit.sources import DataSourceNone as DSNone
+
+from .. import helpers as test_helpers
+
+DEFAULT_LOCAL = [
+ CloudSigma.DataSourceCloudSigma,
+ ConfigDrive.DataSourceConfigDrive,
+ DigitalOcean.DataSourceDigitalOcean,
+ NoCloud.DataSourceNoCloud,
+ OpenNebula.DataSourceOpenNebula,
+ OVF.DataSourceOVF,
+ SmartOS.DataSourceSmartOS,
+]
+
+DEFAULT_NETWORK = [
+ AltCloud.DataSourceAltCloud,
+ Azure.DataSourceAzureNet,
+ Bigstep.DataSourceBigstep,
+ CloudStack.DataSourceCloudStack,
+ DSNone.DataSourceNone,
+ Ec2.DataSourceEc2,
+ GCE.DataSourceGCE,
+ MAAS.DataSourceMAAS,
+ NoCloud.DataSourceNoCloudNet,
+ OpenStack.DataSourceOpenStack,
+ OVF.DataSourceOVFNet,
+]
+
+
+class ExpectedDataSources(test_helpers.TestCase):
+ builtin_list = settings.CFG_BUILTIN['datasource_list']
+ deps_local = [sources.DEP_FILESYSTEM]
+ deps_network = [sources.DEP_FILESYSTEM, sources.DEP_NETWORK]
+ pkg_list = [type_utils.obj_name(sources)]
+
+ def test_expected_default_local_sources_found(self):
+ found = sources.list_sources(
+ self.builtin_list, self.deps_local, self.pkg_list)
+ self.assertEqual(set(DEFAULT_LOCAL), set(found))
+
+ def test_expected_default_network_sources_found(self):
+ found = sources.list_sources(
+ self.builtin_list, self.deps_network, self.pkg_list)
+ self.assertEqual(set(DEFAULT_NETWORK), set(found))
+
+ def test_expected_nondefault_network_sources_found(self):
+ found = sources.list_sources(
+ ['AliYun'], self.deps_network, self.pkg_list)
+ self.assertEqual(set([AliYun.DataSourceAliYun]), set(found))
+
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_datasource/test_configdrive.py b/tests/unittests/test_datasource/test_configdrive.py
index 6e00abf4..55153357 100644
--- a/tests/unittests/test_datasource/test_configdrive.py
+++ b/tests/unittests/test_datasource/test_configdrive.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
from copy import copy, deepcopy
import json
import os
diff --git a/tests/unittests/test_datasource/test_digitalocean.py b/tests/unittests/test_datasource/test_digitalocean.py
index 7bde0820..9be6bc19 100644
--- a/tests/unittests/test_datasource/test_digitalocean.py
+++ b/tests/unittests/test_datasource/test_digitalocean.py
@@ -1,19 +1,8 @@
+# Copyright (C) 2014 Neal Shrader
#
-# Copyright (C) 2014 Neal Shrader
+# Author: Neal Shrader <neal@digitalocean.com>
#
-# Author: Neal Shrader <neal@digitalocean.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# This file is part of cloud-init. See LICENSE file for license information.
import json
@@ -330,3 +319,5 @@ class TestNetworkConvert(TestCase):
self.assertEqual(
sorted(['45.55.249.133', '10.17.0.5']),
sorted([i['address'] for i in eth0['subnets']]))
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_datasource/test_gce.py b/tests/unittests/test_datasource/test_gce.py
index 6e62a4d2..4f667678 100644
--- a/tests/unittests/test_datasource/test_gce.py
+++ b/tests/unittests/test_datasource/test_gce.py
@@ -1,19 +1,8 @@
+# Copyright (C) 2014 Vaidas Jablonskis
#
-# Copyright (C) 2014 Vaidas Jablonskis
+# Author: Vaidas Jablonskis <jablonskis@gmail.com>
#
-# Author: Vaidas Jablonskis <jablonskis@gmail.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# This file is part of cloud-init. See LICENSE file for license information.
import re
@@ -164,3 +153,5 @@ class TestDataSourceGCE(test_helpers.HttprettyTestCase):
_set_mock_metadata()
self.ds.get_data()
self.assertEqual('bar', self.ds.availability_zone)
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_datasource/test_maas.py b/tests/unittests/test_datasource/test_maas.py
index 0126c883..693882d2 100644
--- a/tests/unittests/test_datasource/test_maas.py
+++ b/tests/unittests/test_datasource/test_maas.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
from copy import copy
import os
import shutil
diff --git a/tests/unittests/test_datasource/test_nocloud.py b/tests/unittests/test_datasource/test_nocloud.py
index f6a46ce9..ff294395 100644
--- a/tests/unittests/test_datasource/test_nocloud.py
+++ b/tests/unittests/test_datasource/test_nocloud.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
from cloudinit import helpers
from cloudinit.sources import DataSourceNoCloud
from cloudinit import util
diff --git a/tests/unittests/test_datasource/test_opennebula.py b/tests/unittests/test_datasource/test_opennebula.py
index ce5b5550..a266e952 100644
--- a/tests/unittests/test_datasource/test_opennebula.py
+++ b/tests/unittests/test_datasource/test_opennebula.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
from cloudinit import helpers
from cloudinit.sources import DataSourceOpenNebula as ds
from cloudinit import util
diff --git a/tests/unittests/test_datasource/test_openstack.py b/tests/unittests/test_datasource/test_openstack.py
index 125c6d6e..e5b6fcc6 100644
--- a/tests/unittests/test_datasource/test_openstack.py
+++ b/tests/unittests/test_datasource/test_openstack.py
@@ -1,20 +1,8 @@
-# vi: ts=4 expandtab
-#
-# Copyright (C) 2014 Yahoo! Inc.
-#
-# Author: Joshua Harlow <harlowja@yahoo-inc.com>
+# Copyright (C) 2014 Yahoo! Inc.
#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
+# Author: Joshua Harlow <harlowja@yahoo-inc.com>
#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# This file is part of cloud-init. See LICENSE file for license information.
import copy
import json
@@ -344,3 +332,5 @@ class TestVendorDataLoading(test_helpers.TestCase):
def test_vd_load_dict_ci_list(self):
data = {'foo': 'bar', 'cloud-init': ['VD_1', 'VD_2']}
self.assertEqual(self.cvj(data), data['cloud-init'])
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_datasource/test_ovf.py b/tests/unittests/test_datasource/test_ovf.py
index 5f8e7e44..3e09510c 100644
--- a/tests/unittests/test_datasource/test_ovf.py
+++ b/tests/unittests/test_datasource/test_ovf.py
@@ -1,20 +1,8 @@
-# vi: ts=4 expandtab
-#
-# Copyright (C) 2016 Canonical Ltd.
-#
-# Author: Scott Moser <scott.moser@canonical.com>
+# Copyright (C) 2016 Canonical Ltd.
#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
+# Author: Scott Moser <scott.moser@canonical.com>
#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# This file is part of cloud-init. See LICENSE file for license information.
import base64
@@ -81,3 +69,5 @@ class TestReadOvfEnv(test_helpers.TestCase):
self.assertEqual({"instance-id": "inst-001"}, md)
self.assertEqual({'password': "passw0rd"}, cfg)
self.assertEqual(None, ud)
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_datasource/test_smartos.py b/tests/unittests/test_datasource/test_smartos.py
index 0532f986..e3c99bbb 100644
--- a/tests/unittests/test_datasource/test_smartos.py
+++ b/tests/unittests/test_datasource/test_smartos.py
@@ -1,26 +1,15 @@
-# vi: ts=4 expandtab
-#
-# Copyright (C) 2013 Canonical Ltd.
-#
-# Author: Ben Howard <ben.howard@canonical.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# Copyright (C) 2013 Canonical Ltd.
#
+# Author: Ben Howard <ben.howard@canonical.com>
#
-# This is a testcase for the SmartOS datasource. It replicates a serial
-# console and acts like the SmartOS console does in order to validate
-# return responses.
-#
+# This file is part of cloud-init. See LICENSE file for license information.
+
+'''This is a testcase for the SmartOS datasource.
+
+It replicates a serial console and acts like the SmartOS console does in
+order to validate return responses.
+
+'''
from __future__ import print_function
@@ -881,3 +870,5 @@ class TestNetworkConversion(TestCase):
'type': 'static'}]}]}
found = convert_net(SDC_NICS_SINGLE_GATEWAY)
self.assertEqual(expected, found)
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_distros/test_create_users.py b/tests/unittests/test_distros/test_create_users.py
new file mode 100644
index 00000000..9ded4f6c
--- /dev/null
+++ b/tests/unittests/test_distros/test_create_users.py
@@ -0,0 +1,151 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
+from cloudinit import distros
+from ..helpers import (TestCase, mock)
+
+
+class MyBaseDistro(distros.Distro):
+ # MyBaseDistro is here to test base Distro class implementations
+
+ def __init__(self, name="basedistro", cfg={}, paths={}):
+ super(MyBaseDistro, self).__init__(name, cfg, paths)
+
+ def install_packages(self, pkglist):
+ raise NotImplementedError()
+
+ def _write_network(self, settings):
+ raise NotImplementedError()
+
+ def package_command(self, cmd, args=None, pkgs=None):
+ raise NotImplementedError()
+
+ def update_package_sources(self):
+ raise NotImplementedError()
+
+ def apply_locale(self, locale, out_fn=None):
+ raise NotImplementedError()
+
+ def set_timezone(self, tz):
+ raise NotImplementedError()
+
+ def _read_hostname(self, filename, default=None):
+ raise NotImplementedError()
+
+ def _write_hostname(self, hostname, filename):
+ raise NotImplementedError()
+
+ def _read_system_hostname(self):
+ raise NotImplementedError()
+
+
+class TestCreateUser(TestCase):
+ def setUp(self):
+ super(TestCase, self).setUp()
+ self.dist = MyBaseDistro()
+
+ def _useradd2call(self, args):
+ # return a mock call for the useradd command in args
+ # with expected 'logstring'.
+ args = ['useradd'] + args
+ logcmd = [a for a in args]
+ for i in range(len(args)):
+ if args[i] in ('--password',):
+ logcmd[i + 1] = 'REDACTED'
+ return mock.call(args, logstring=logcmd)
+
+ @mock.patch("cloudinit.distros.util.subp")
+ def test_basic(self, m_subp):
+ user = 'foouser'
+ self.dist.create_user(user)
+ self.assertEqual(
+ m_subp.call_args_list,
+ [self._useradd2call([user, '-m']),
+ mock.call(['passwd', '-l', user])])
+
+ @mock.patch("cloudinit.distros.util.subp")
+ def test_no_home(self, m_subp):
+ user = 'foouser'
+ self.dist.create_user(user, no_create_home=True)
+ self.assertEqual(
+ m_subp.call_args_list,
+ [self._useradd2call([user, '-M']),
+ mock.call(['passwd', '-l', user])])
+
+ @mock.patch("cloudinit.distros.util.subp")
+ def test_system_user(self, m_subp):
+ # system user should have no home and get --system
+ user = 'foouser'
+ self.dist.create_user(user, system=True)
+ self.assertEqual(
+ m_subp.call_args_list,
+ [self._useradd2call([user, '--system', '-M']),
+ mock.call(['passwd', '-l', user])])
+
+ @mock.patch("cloudinit.distros.util.subp")
+ def test_explicit_no_home_false(self, m_subp):
+ user = 'foouser'
+ self.dist.create_user(user, no_create_home=False)
+ self.assertEqual(
+ m_subp.call_args_list,
+ [self._useradd2call([user, '-m']),
+ mock.call(['passwd', '-l', user])])
+
+ @mock.patch("cloudinit.distros.util.subp")
+ def test_unlocked(self, m_subp):
+ user = 'foouser'
+ self.dist.create_user(user, lock_passwd=False)
+ self.assertEqual(
+ m_subp.call_args_list,
+ [self._useradd2call([user, '-m'])])
+
+ @mock.patch("cloudinit.distros.util.subp")
+ def test_set_password(self, m_subp):
+ user = 'foouser'
+ password = 'passfoo'
+ self.dist.create_user(user, passwd=password)
+ self.assertEqual(
+ m_subp.call_args_list,
+ [self._useradd2call([user, '--password', password, '-m']),
+ mock.call(['passwd', '-l', user])])
+
+ @mock.patch("cloudinit.distros.util.is_group")
+ @mock.patch("cloudinit.distros.util.subp")
+ def test_group_added(self, m_subp, m_is_group):
+ m_is_group.return_value = False
+ user = 'foouser'
+ self.dist.create_user(user, groups=['group1'])
+ expected = [
+ mock.call(['groupadd', 'group1']),
+ self._useradd2call([user, '--groups', 'group1', '-m']),
+ mock.call(['passwd', '-l', user])]
+ self.assertEqual(m_subp.call_args_list, expected)
+
+ @mock.patch("cloudinit.distros.util.is_group")
+ @mock.patch("cloudinit.distros.util.subp")
+ def test_only_new_group_added(self, m_subp, m_is_group):
+ ex_groups = ['existing_group']
+ groups = ['group1', ex_groups[0]]
+ m_is_group.side_effect = lambda m: m in ex_groups
+ user = 'foouser'
+ self.dist.create_user(user, groups=groups)
+ expected = [
+ mock.call(['groupadd', 'group1']),
+ self._useradd2call([user, '--groups', ','.join(groups), '-m']),
+ mock.call(['passwd', '-l', user])]
+ self.assertEqual(m_subp.call_args_list, expected)
+
+ @mock.patch("cloudinit.distros.util.is_group")
+ @mock.patch("cloudinit.distros.util.subp")
+ def test_create_groups_with_whitespace_string(self, m_subp, m_is_group):
+ # groups supported as a comma delimeted string even with white space
+ m_is_group.return_value = False
+ user = 'foouser'
+ self.dist.create_user(user, groups='group1, group2')
+ expected = [
+ mock.call(['groupadd', 'group1']),
+ mock.call(['groupadd', 'group2']),
+ self._useradd2call([user, '--groups', 'group1,group2', '-m']),
+ mock.call(['passwd', '-l', user])]
+ self.assertEqual(m_subp.call_args_list, expected)
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_distros/test_generic.py b/tests/unittests/test_distros/test_generic.py
index 24ad115f..c9be277e 100644
--- a/tests/unittests/test_distros/test_generic.py
+++ b/tests/unittests/test_distros/test_generic.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
from cloudinit import distros
from cloudinit import util
diff --git a/tests/unittests/test_distros/test_hostname.py b/tests/unittests/test_distros/test_hostname.py
index 5f28a868..f6d4dbe5 100644
--- a/tests/unittests/test_distros/test_hostname.py
+++ b/tests/unittests/test_distros/test_hostname.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
import unittest
from cloudinit.distros.parsers import hostname
@@ -36,3 +38,5 @@ class TestHostnameHelper(unittest.TestCase):
bbbbd
'''
self.assertEqual(str(hn).strip(), expected_out.strip())
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_distros/test_hosts.py b/tests/unittests/test_distros/test_hosts.py
index ab867c6f..8aaa6e48 100644
--- a/tests/unittests/test_distros/test_hosts.py
+++ b/tests/unittests/test_distros/test_hosts.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
import unittest
from cloudinit.distros.parsers import hosts
@@ -39,3 +41,5 @@ class TestHostsHelper(unittest.TestCase):
eh.del_entries('127.0.0.0')
self.assertEqual(eh.get_entry('127.0.0.0'), [])
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_distros/test_netconfig.py b/tests/unittests/test_distros/test_netconfig.py
index 36eae2dc..bde3bb50 100644
--- a/tests/unittests/test_distros/test_netconfig.py
+++ b/tests/unittests/test_distros/test_netconfig.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
import os
from six import StringIO
@@ -379,3 +381,5 @@ ifconfig_vtnet0="DHCP"
'''
self.assertCfgEquals(expected_buf, str(write_buf))
self.assertEqual(write_buf.mode, 0o644)
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_distros/test_resolv.py b/tests/unittests/test_distros/test_resolv.py
index 9402b5ea..6b535a95 100644
--- a/tests/unittests/test_distros/test_resolv.py
+++ b/tests/unittests/test_distros/test_resolv.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
from cloudinit.distros.parsers import resolv_conf
from cloudinit.distros import rhel_util
@@ -65,3 +67,5 @@ class TestResolvHelper(TestCase):
self.assertEqual(len(rp.search_domains), 6)
self.assertRaises(ValueError, rp.add_search_domain, 'bbb5.y.com')
self.assertEqual(len(rp.search_domains), 6)
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_distros/test_sysconfig.py b/tests/unittests/test_distros/test_sysconfig.py
index 8cb55522..235ecebb 100644
--- a/tests/unittests/test_distros/test_sysconfig.py
+++ b/tests/unittests/test_distros/test_sysconfig.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
import re
from cloudinit.distros.parsers.sys_conf import SysConf
@@ -80,3 +82,5 @@ USEMD5=no'''
contents = str(conf)
self.assertIn("Z=d", contents)
self.assertIn("BLAH=b", contents)
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_distros/test_user_data_normalize.py b/tests/unittests/test_distros/test_user_data_normalize.py
index 33bf922d..88746e0a 100755
--- a/tests/unittests/test_distros/test_user_data_normalize.py
+++ b/tests/unittests/test_distros/test_user_data_normalize.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
from cloudinit import distros
from cloudinit.distros import ug_util
from cloudinit import helpers
@@ -361,3 +363,5 @@ class TestUGNormalize(TestCase):
mock_subp.assert_any_call(groupcmd)
mock_subp.assert_any_call(addcmd, logstring=addcmd)
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_ec2_util.py b/tests/unittests/test_ec2_util.py
index d6cf17fa..4a33d747 100644
--- a/tests/unittests/test_ec2_util.py
+++ b/tests/unittests/test_ec2_util.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
from . import helpers
from cloudinit import ec2_utils as eu
@@ -137,3 +139,5 @@ class TestEc2Util(helpers.HttprettyTestCase):
self.assertEqual(2, len(bdm))
self.assertEqual(bdm['ami'], 'sdb')
self.assertEqual(bdm['ephemeral0'], 'sdc')
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_filters/test_launch_index.py b/tests/unittests/test_filters/test_launch_index.py
index 395713e6..13137f6d 100644
--- a/tests/unittests/test_filters/test_launch_index.py
+++ b/tests/unittests/test_filters/test_launch_index.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
import copy
from .. import helpers
@@ -130,3 +132,5 @@ class TestLaunchFilter(helpers.ResourceUsingTestCase):
'1': 2,
}
self.assertCounts(message, expected_counts)
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_handler/test_handler_apt_conf_v1.py b/tests/unittests/test_handler/test_handler_apt_conf_v1.py
index 64acc3e0..554277ff 100644
--- a/tests/unittests/test_handler/test_handler_apt_conf_v1.py
+++ b/tests/unittests/test_handler/test_handler_apt_conf_v1.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
from cloudinit.config import cc_apt_configure
from cloudinit import util
diff --git a/tests/unittests/test_handler/test_handler_apt_configure_sources_list_v1.py b/tests/unittests/test_handler/test_handler_apt_configure_sources_list_v1.py
index f4411869..f53ddbb2 100644
--- a/tests/unittests/test_handler/test_handler_apt_configure_sources_list_v1.py
+++ b/tests/unittests/test_handler/test_handler_apt_configure_sources_list_v1.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
""" test_handler_apt_configure_sources_list
Test templating of sources list
"""
diff --git a/tests/unittests/test_handler/test_handler_apt_configure_sources_list_v3.py b/tests/unittests/test_handler/test_handler_apt_configure_sources_list_v3.py
index e53b0450..24e45233 100644
--- a/tests/unittests/test_handler/test_handler_apt_configure_sources_list_v3.py
+++ b/tests/unittests/test_handler/test_handler_apt_configure_sources_list_v3.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
""" test_apt_custom_sources_list
Test templating of custom sources list
"""
diff --git a/tests/unittests/test_handler/test_handler_apt_source_v1.py b/tests/unittests/test_handler/test_handler_apt_source_v1.py
index ddff4341..12502d05 100644
--- a/tests/unittests/test_handler/test_handler_apt_source_v1.py
+++ b/tests/unittests/test_handler/test_handler_apt_source_v1.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
""" test_handler_apt_source_v1
Testing various config variations of the apt_source config
This calls all things with v1 format to stress the conversion code on top of
diff --git a/tests/unittests/test_handler/test_handler_apt_source_v3.py b/tests/unittests/test_handler/test_handler_apt_source_v3.py
index b92a50d7..292d3f59 100644
--- a/tests/unittests/test_handler/test_handler_apt_source_v3.py
+++ b/tests/unittests/test_handler/test_handler_apt_source_v3.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
"""test_handler_apt_source_v3
Testing various config variations of the apt_source custom config
This tries to call all in the new v3 format and cares about new features
diff --git a/tests/unittests/test_handler/test_handler_ca_certs.py b/tests/unittests/test_handler/test_handler_ca_certs.py
index 5e771731..7cee2c3f 100644
--- a/tests/unittests/test_handler/test_handler_ca_certs.py
+++ b/tests/unittests/test_handler/test_handler_ca_certs.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
from cloudinit import cloud
from cloudinit.config import cc_ca_certs
from cloudinit import helpers
@@ -269,3 +271,5 @@ class TestRemoveDefaultCaCerts(TestCase):
mock_subp.assert_called_once_with(
('debconf-set-selections', '-'),
"ca-certificates ca-certificates/trust_new_crts select no")
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_handler/test_handler_chef.py b/tests/unittests/test_handler/test_handler_chef.py
index 7a1bc317..6a152ea2 100644
--- a/tests/unittests/test_handler/test_handler_chef.py
+++ b/tests/unittests/test_handler/test_handler_chef.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
import json
import logging
import os
@@ -190,3 +192,5 @@ class TestChef(t_help.FilesystemMockingTestCase):
self.assertIn(v_path, content)
util.load_file(v_path)
self.assertEqual(expected_cert, util.load_file(v_path))
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_handler/test_handler_debug.py b/tests/unittests/test_handler/test_handler_debug.py
index 80708d7b..929f786e 100644
--- a/tests/unittests/test_handler/test_handler_debug.py
+++ b/tests/unittests/test_handler/test_handler_debug.py
@@ -1,18 +1,6 @@
-# vi: ts=4 expandtab
-#
-# Copyright (C) 2014 Yahoo! Inc.
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
+# Copyright (C) 2014 Yahoo! Inc.
#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# This file is part of cloud-init. See LICENSE file for license information.
from cloudinit.config import cc_debug
@@ -79,3 +67,5 @@ class TestDebug(t_help.FilesystemMockingTestCase):
cc_debug.handle('cc_debug', cfg, cc, LOG, [])
self.assertRaises(IOError,
util.load_file, '/var/log/cloud-init-debug.log')
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_handler/test_handler_disk_setup.py b/tests/unittests/test_handler/test_handler_disk_setup.py
index ddef8d48..227f0497 100644
--- a/tests/unittests/test_handler/test_handler_disk_setup.py
+++ b/tests/unittests/test_handler/test_handler_disk_setup.py
@@ -1,3 +1,7 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
+import random
+
from cloudinit.config import cc_disk_setup
from ..helpers import ExitStack, mock, TestCase
@@ -28,3 +32,75 @@ class TestIsDiskUsed(TestCase):
self.enumerate_disk.return_value = (mock.MagicMock() for _ in range(1))
self.check_fs.return_value = (mock.MagicMock(), None, mock.MagicMock())
self.assertFalse(cc_disk_setup.is_disk_used(mock.MagicMock()))
+
+
+class TestGetMbrHddSize(TestCase):
+
+ def setUp(self):
+ super(TestGetMbrHddSize, self).setUp()
+ self.patches = ExitStack()
+ self.subp = self.patches.enter_context(
+ mock.patch.object(cc_disk_setup.util, 'subp'))
+
+ def tearDown(self):
+ super(TestGetMbrHddSize, self).tearDown()
+ self.patches.close()
+
+ def _configure_subp_mock(self, hdd_size_in_bytes, sector_size_in_bytes):
+ def _subp(cmd, *args, **kwargs):
+ self.assertEqual(3, len(cmd))
+ if '--getsize64' in cmd:
+ return hdd_size_in_bytes, None
+ elif '--getss' in cmd:
+ return sector_size_in_bytes, None
+ raise Exception('Unexpected blockdev command called')
+
+ self.subp.side_effect = _subp
+
+ def _test_for_sector_size(self, sector_size):
+ size_in_bytes = random.randint(10000, 10000000) * 512
+ size_in_sectors = size_in_bytes / sector_size
+ self._configure_subp_mock(size_in_bytes, sector_size)
+ self.assertEqual(size_in_sectors,
+ cc_disk_setup.get_mbr_hdd_size('/dev/sda1'))
+
+ def test_size_for_512_byte_sectors(self):
+ self._test_for_sector_size(512)
+
+ def test_size_for_1024_byte_sectors(self):
+ self._test_for_sector_size(1024)
+
+ def test_size_for_2048_byte_sectors(self):
+ self._test_for_sector_size(2048)
+
+ def test_size_for_4096_byte_sectors(self):
+ self._test_for_sector_size(4096)
+
+
+class TestGetPartitionMbrLayout(TestCase):
+
+ def test_single_partition_using_boolean(self):
+ self.assertEqual('0,',
+ cc_disk_setup.get_partition_mbr_layout(1000, True))
+
+ def test_single_partition_using_list(self):
+ disk_size = random.randint(1000000, 1000000000000)
+ self.assertEqual(
+ ',,83',
+ cc_disk_setup.get_partition_mbr_layout(disk_size, [100]))
+
+ def test_half_and_half(self):
+ disk_size = random.randint(1000000, 1000000000000)
+ expected_partition_size = int(float(disk_size) / 2)
+ self.assertEqual(
+ ',{0},83\n,,83'.format(expected_partition_size),
+ cc_disk_setup.get_partition_mbr_layout(disk_size, [50, 50]))
+
+ def test_thirds_with_different_partition_type(self):
+ disk_size = random.randint(1000000, 1000000000000)
+ expected_partition_size = int(float(disk_size) * 0.33)
+ self.assertEqual(
+ ',{0},83\n,,82'.format(expected_partition_size),
+ cc_disk_setup.get_partition_mbr_layout(disk_size, [33, [66, 82]]))
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_handler/test_handler_growpart.py b/tests/unittests/test_handler/test_handler_growpart.py
index e28067de..c5fc8c9b 100644
--- a/tests/unittests/test_handler/test_handler_growpart.py
+++ b/tests/unittests/test_handler/test_handler_growpart.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
from cloudinit import cloud
from cloudinit.config import cc_growpart
from cloudinit import util
diff --git a/tests/unittests/test_handler/test_handler_locale.py b/tests/unittests/test_handler/test_handler_locale.py
index c91908f4..e9a810c5 100644
--- a/tests/unittests/test_handler/test_handler_locale.py
+++ b/tests/unittests/test_handler/test_handler_locale.py
@@ -1,20 +1,8 @@
-# Copyright (C) 2013 Hewlett-Packard Development Company, L.P.
+# Copyright (C) 2013 Hewlett-Packard Development Company, L.P.
#
-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
+# Author: Juerg Haefliger <juerg.haefliger@hp.com>
#
-# Based on test_handler_set_hostname.py
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# This file is part of cloud-init. See LICENSE file for license information.
from cloudinit.config import cc_locale
@@ -65,3 +53,5 @@ class TestLocale(t_help.FilesystemMockingTestCase):
contents = util.load_file('/etc/sysconfig/language', decode=False)
n_cfg = ConfigObj(BytesIO(contents))
self.assertEqual({'RC_LANG': cfg['locale']}, dict(n_cfg))
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_handler/test_handler_lxd.py b/tests/unittests/test_handler/test_handler_lxd.py
index 14366a10..351226bf 100644
--- a/tests/unittests/test_handler/test_handler_lxd.py
+++ b/tests/unittests/test_handler/test_handler_lxd.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
from cloudinit.config import cc_lxd
from cloudinit.sources import DataSourceNoCloud
from cloudinit import (distros, helpers, cloud)
@@ -183,3 +185,5 @@ class TestLxd(t_help.TestCase):
self.assertEqual(
cc_lxd.bridge_to_cmd(data),
(None, None))
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_handler/test_handler_mcollective.py b/tests/unittests/test_handler/test_handler_mcollective.py
index c3a5a634..2a9f3823 100644
--- a/tests/unittests/test_handler/test_handler_mcollective.py
+++ b/tests/unittests/test_handler/test_handler_mcollective.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
from cloudinit import (cloud, distros, helpers, util)
from cloudinit.config import cc_mcollective
from cloudinit.sources import DataSourceNoCloud
@@ -148,3 +150,5 @@ class TestHandler(t_help.TestCase):
self.assertTrue(mock_util.subp.called)
self.assertEqual(mock_util.subp.call_args_list[0][0][0],
['service', 'mcollective', 'restart'])
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_handler/test_handler_mounts.py b/tests/unittests/test_handler/test_handler_mounts.py
index 355674b2..650ca0ec 100644
--- a/tests/unittests/test_handler/test_handler_mounts.py
+++ b/tests/unittests/test_handler/test_handler_mounts.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
import os.path
import shutil
import tempfile
@@ -131,3 +133,5 @@ class TestSanitizeDevname(test_helpers.FilesystemMockingTestCase):
self.assertIsNone(
cc_mounts.sanitize_devname(
'ephemeral0.1', lambda x: disk_path, mock.Mock()))
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_handler/test_handler_ntp.py b/tests/unittests/test_handler/test_handler_ntp.py
index 1c7bb06a..ec600077 100644
--- a/tests/unittests/test_handler/test_handler_ntp.py
+++ b/tests/unittests/test_handler/test_handler_ntp.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
from cloudinit.config import cc_ntp
from cloudinit.sources import DataSourceNone
from cloudinit import templater
@@ -272,3 +274,5 @@ class TestNtp(FilesystemMockingTestCase):
cc_ntp.handle('cc_ntp', {}, cc, LOG, [])
self.assertFalse(cc.distro.install_packages.called)
self.assertFalse(mock_util.subp.called)
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_handler/test_handler_power_state.py b/tests/unittests/test_handler/test_handler_power_state.py
index feff319d..3fd0069d 100644
--- a/tests/unittests/test_handler/test_handler_power_state.py
+++ b/tests/unittests/test_handler/test_handler_power_state.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
import sys
from cloudinit.config import cc_power_state_change as psc
@@ -125,3 +127,5 @@ def check_lps_ret(psc_return, mode=None):
if len(errs):
lines = ["Errors in result: %s" % str(psc_return)] + errs
raise Exception('\n'.join(lines))
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_handler/test_handler_rsyslog.py b/tests/unittests/test_handler/test_handler_rsyslog.py
index 38636063..cca06678 100644
--- a/tests/unittests/test_handler/test_handler_rsyslog.py
+++ b/tests/unittests/test_handler/test_handler_rsyslog.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
import os
import shutil
import tempfile
@@ -172,3 +174,5 @@ class TestRemotesToSyslog(t_help.TestCase):
lines = r.splitlines()
self.assertEqual(1, len(lines))
self.assertTrue(myline in r.splitlines())
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_handler/test_handler_seed_random.py b/tests/unittests/test_handler/test_handler_seed_random.py
index a0390da9..e5e607fb 100644
--- a/tests/unittests/test_handler/test_handler_seed_random.py
+++ b/tests/unittests/test_handler/test_handler_seed_random.py
@@ -1,20 +1,12 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
# Copyright (C) 2013 Hewlett-Packard Development Company, L.P.
#
# Author: Juerg Haefliger <juerg.haefliger@hp.com>
#
# Based on test_handler_set_hostname.py
#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# This file is part of cloud-init. See LICENSE file for license information.
from cloudinit.config import cc_seed_random
@@ -225,3 +217,5 @@ def apply_patches(patches):
setattr(ref, name, replace)
ret.append((ref, name, orig))
return ret
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_handler/test_handler_set_hostname.py b/tests/unittests/test_handler/test_handler_set_hostname.py
index 7effa124..4b18de75 100644
--- a/tests/unittests/test_handler/test_handler_set_hostname.py
+++ b/tests/unittests/test_handler/test_handler_set_hostname.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
from cloudinit.config import cc_set_hostname
from cloudinit import cloud
@@ -70,3 +72,5 @@ class TestHostname(t_help.FilesystemMockingTestCase):
cc_set_hostname.handle('cc_set_hostname', cfg, cc, LOG, [])
contents = util.load_file("/etc/HOSTNAME")
self.assertEqual('blah', contents.strip())
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_handler/test_handler_snappy.py b/tests/unittests/test_handler/test_handler_snappy.py
index e320dd82..edb73d6d 100644
--- a/tests/unittests/test_handler/test_handler_snappy.py
+++ b/tests/unittests/test_handler/test_handler_snappy.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
from cloudinit.config.cc_snappy import (
makeop, get_package_ops, render_snap_op)
from cloudinit.config.cc_snap_config import (
@@ -595,3 +597,5 @@ def apply_patches(patches):
setattr(ref, name, replace)
ret.append((ref, name, orig))
return ret
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_handler/test_handler_spacewalk.py b/tests/unittests/test_handler/test_handler_spacewalk.py
index 44f95e4c..28b5892a 100644
--- a/tests/unittests/test_handler/test_handler_spacewalk.py
+++ b/tests/unittests/test_handler/test_handler_spacewalk.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
from cloudinit.config import cc_spacewalk
from cloudinit import util
@@ -40,3 +42,5 @@ class TestSpacewalk(helpers.TestCase):
'--profilename', 'test',
'--sslCACert', cc_spacewalk.def_ca_cert_path,
], capture=False)
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_handler/test_handler_timezone.py b/tests/unittests/test_handler/test_handler_timezone.py
index b7e6b03d..c30fbdfe 100644
--- a/tests/unittests/test_handler/test_handler_timezone.py
+++ b/tests/unittests/test_handler/test_handler_timezone.py
@@ -1,20 +1,8 @@
-# Copyright (C) 2013 Hewlett-Packard Development Company, L.P.
+# Copyright (C) 2013 Hewlett-Packard Development Company, L.P.
#
-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
+# Author: Juerg Haefliger <juerg.haefliger@hp.com>
#
-# Based on test_handler_set_hostname.py
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# This file is part of cloud-init. See LICENSE file for license information.
from cloudinit.config import cc_timezone
@@ -74,3 +62,5 @@ class TestTimezone(t_help.FilesystemMockingTestCase):
contents = util.load_file('/etc/localtime')
self.assertEqual(dummy_contents, contents.strip())
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_handler/test_handler_write_files.py b/tests/unittests/test_handler/test_handler_write_files.py
index 466e45f8..fb252d1d 100644
--- a/tests/unittests/test_handler/test_handler_write_files.py
+++ b/tests/unittests/test_handler/test_handler_write_files.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
from cloudinit.config.cc_write_files import write_files
from cloudinit import log as logging
from cloudinit import util
diff --git a/tests/unittests/test_handler/test_handler_yum_add_repo.py b/tests/unittests/test_handler/test_handler_yum_add_repo.py
index 28b060f8..3feba86c 100644
--- a/tests/unittests/test_handler/test_handler_yum_add_repo.py
+++ b/tests/unittests/test_handler/test_handler_yum_add_repo.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
from cloudinit.config import cc_yum_add_repo
from cloudinit import util
@@ -66,3 +68,5 @@ class TestConfig(helpers.FilesystemMockingTestCase):
}
}
self.assertEqual(expected, dict(contents))
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_helpers.py b/tests/unittests/test_helpers.py
index 943a5723..955f8dfa 100644
--- a/tests/unittests/test_helpers.py
+++ b/tests/unittests/test_helpers.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
"""Tests of the built-in user data handlers."""
import os
@@ -31,3 +33,5 @@ class TestPaths(test_helpers.ResourceUsingTestCase):
mypaths = self.getCloudPaths(myds)
self.assertEqual(None, mypaths.get_ipath())
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_merging.py b/tests/unittests/test_merging.py
index a33ec184..0658b6b4 100644
--- a/tests/unittests/test_merging.py
+++ b/tests/unittests/test_merging.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
from . import helpers
from cloudinit.handlers import cloud_config
@@ -255,3 +257,5 @@ class TestSimpleRun(helpers.ResourceUsingTestCase):
c = _old_mergedict(a, b)
d = util.mergemanydict([a, b])
self.assertEqual(c, d)
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
index 78c080ca..1090282a 100644..100755
--- a/tests/unittests/test_net.py
+++ b/tests/unittests/test_net.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
from cloudinit import net
from cloudinit.net import cmdline
from cloudinit.net import eni
@@ -8,6 +10,8 @@ from cloudinit import util
from .helpers import dir2dict
from .helpers import mock
+from .helpers import populate_dir
+from .helpers import TempDirTestCase
from .helpers import TestCase
import base64
@@ -54,22 +58,9 @@ DHCP_EXPECTED_1 = {
}
DHCP6_CONTENT_1 = """
-DEVICE=eno1
-HOSTNAME=
-DNSDOMAIN=
-reason='PREINIT'
-interface='eno1'
-DEVICE=eno1
+DEVICE6=eno1
HOSTNAME=
DNSDOMAIN=
-reason='FAIL'
-interface='eno1'
-DEVICE=eno1
-HOSTNAME=
-DNSDOMAIN=
-reason='PREINIT6'
-interface='eno1'
-DEVICE=eno1
IPV6PROTO=dhcp6
IPV6ADDR=2001:67c:1562:8010:0:1::
IPV6NETMASK=64
@@ -77,11 +68,6 @@ IPV6DNS0=2001:67c:1562:8010::2:1
IPV6DOMAINSEARCH=
HOSTNAME=
DNSDOMAIN=
-reason='BOUND6'
-interface='eno1'
-new_ip6_address='2001:67c:1562:8010:0:1::'
-new_ip6_prefixlen='64'
-new_dhcp6_name_servers='2001:67c:1562:8010::2:1'
"""
DHCP6_EXPECTED_1 = {
@@ -461,7 +447,7 @@ pre-down route del -net 10.0.0.0 netmask 255.0.0.0 gw 11.0.0.1 metric 3 || true
}
-def _setup_test(tmp_dir, mock_get_devicelist, mock_sys_netdev_info,
+def _setup_test(tmp_dir, mock_get_devicelist, mock_read_sys_net,
mock_sys_dev_path):
mock_get_devicelist.return_value = ['eth1000']
dev_characteristics = {
@@ -474,10 +460,12 @@ def _setup_test(tmp_dir, mock_get_devicelist, mock_sys_netdev_info,
}
}
- def netdev_info(name, field):
- return dev_characteristics[name][field]
+ def fake_read(devname, path, translate=None,
+ on_enoent=None, on_keyerror=None,
+ on_einval=None):
+ return dev_characteristics[devname][path]
- mock_sys_netdev_info.side_effect = netdev_info
+ mock_read_sys_net.side_effect = fake_read
def sys_dev_path(devname, path=""):
return tmp_dir + devname + "/" + path
@@ -493,15 +481,15 @@ def _setup_test(tmp_dir, mock_get_devicelist, mock_sys_netdev_info,
class TestSysConfigRendering(TestCase):
@mock.patch("cloudinit.net.sys_dev_path")
- @mock.patch("cloudinit.net.sys_netdev_info")
+ @mock.patch("cloudinit.net.read_sys_net")
@mock.patch("cloudinit.net.get_devicelist")
def test_default_generation(self, mock_get_devicelist,
- mock_sys_netdev_info,
+ mock_read_sys_net,
mock_sys_dev_path):
tmp_dir = tempfile.mkdtemp()
self.addCleanup(shutil.rmtree, tmp_dir)
_setup_test(tmp_dir, mock_get_devicelist,
- mock_sys_netdev_info, mock_sys_dev_path)
+ mock_read_sys_net, mock_sys_dev_path)
network_cfg = net.generate_fallback_config()
ns = network_state.parse_net_config_data(network_cfg,
@@ -550,15 +538,15 @@ USERCTL=no
class TestEniNetRendering(TestCase):
@mock.patch("cloudinit.net.sys_dev_path")
- @mock.patch("cloudinit.net.sys_netdev_info")
+ @mock.patch("cloudinit.net.read_sys_net")
@mock.patch("cloudinit.net.get_devicelist")
def test_default_generation(self, mock_get_devicelist,
- mock_sys_netdev_info,
+ mock_read_sys_net,
mock_sys_dev_path):
tmp_dir = tempfile.mkdtemp()
self.addCleanup(shutil.rmtree, tmp_dir)
_setup_test(tmp_dir, mock_get_devicelist,
- mock_sys_netdev_info, mock_sys_dev_path)
+ mock_read_sys_net, mock_sys_dev_path)
network_cfg = net.generate_fallback_config()
ns = network_state.parse_net_config_data(network_cfg,
@@ -677,6 +665,66 @@ class TestCmdlineConfigParsing(TestCase):
self.assertEqual(found, self.simple_cfg)
+class TestCmdlineReadKernelConfig(TempDirTestCase):
+ macs = {
+ 'eth0': '14:02:ec:42:48:00',
+ 'eno1': '14:02:ec:42:48:01',
+ }
+
+ def test_ip_cmdline_read_kernel_cmdline_ip(self):
+ content = {'net-eth0.conf': DHCP_CONTENT_1}
+ populate_dir(self.tmp, content)
+ files = [os.path.join(self.tmp, k) for k in content.keys()]
+ found = cmdline.read_kernel_cmdline_config(
+ files=files, cmdline='foo ip=dhcp', mac_addrs=self.macs)
+ exp1 = copy.deepcopy(DHCP_EXPECTED_1)
+ exp1['mac_address'] = self.macs['eth0']
+ self.assertEqual(found['version'], 1)
+ self.assertEqual(found['config'], [exp1])
+
+ def test_ip_cmdline_read_kernel_cmdline_ip6(self):
+ content = {'net6-eno1.conf': DHCP6_CONTENT_1}
+ populate_dir(self.tmp, content)
+ files = [os.path.join(self.tmp, k) for k in content.keys()]
+ found = cmdline.read_kernel_cmdline_config(
+ files=files, cmdline='foo ip6=dhcp root=/dev/sda',
+ mac_addrs=self.macs)
+ self.assertEqual(
+ found,
+ {'version': 1, 'config': [
+ {'type': 'physical', 'name': 'eno1',
+ 'mac_address': self.macs['eno1'],
+ 'subnets': [
+ {'dns_nameservers': ['2001:67c:1562:8010::2:1'],
+ 'control': 'manual', 'type': 'dhcp6', 'netmask': '64'}]}]})
+
+ def test_ip_cmdline_read_kernel_cmdline_none(self):
+ # if there is no ip= or ip6= on cmdline, return value should be None
+ content = {'net6-eno1.conf': DHCP6_CONTENT_1}
+ populate_dir(self.tmp, content)
+ files = [os.path.join(self.tmp, k) for k in content.keys()]
+ found = cmdline.read_kernel_cmdline_config(
+ files=files, cmdline='foo root=/dev/sda', mac_addrs=self.macs)
+ self.assertEqual(found, None)
+
+ def test_ip_cmdline_both_ip_ip6(self):
+ content = {'net-eth0.conf': DHCP_CONTENT_1,
+ 'net6-eth0.conf': DHCP6_CONTENT_1.replace('eno1', 'eth0')}
+ populate_dir(self.tmp, content)
+ files = [os.path.join(self.tmp, k) for k in sorted(content.keys())]
+ found = cmdline.read_kernel_cmdline_config(
+ files=files, cmdline='foo ip=dhcp ip6=dhcp', mac_addrs=self.macs)
+
+ eth0 = copy.deepcopy(DHCP_EXPECTED_1)
+ eth0['mac_address'] = self.macs['eth0']
+ eth0['subnets'].append(
+ {'control': 'manual', 'type': 'dhcp6',
+ 'netmask': '64', 'dns_nameservers': ['2001:67c:1562:8010::2:1']})
+ expected = [eth0]
+ self.assertEqual(found['version'], 1)
+ self.assertEqual(found['config'], expected)
+
+
class TestEniRoundTrip(TestCase):
def setUp(self):
super(TestCase, self).setUp()
@@ -723,6 +771,52 @@ class TestEniRoundTrip(TestCase):
entry['expected_eni'].splitlines(),
files['/etc/network/interfaces'].splitlines())
+ def test_routes_rendered(self):
+ # as reported in bug 1649652
+ conf = [
+ {'name': 'eth0', 'type': 'physical',
+ 'subnets': [{
+ 'address': '172.23.31.42/26',
+ 'dns_nameservers': [], 'gateway': '172.23.31.2',
+ 'type': 'static'}]},
+ {'type': 'route', 'id': 4,
+ 'metric': 0, 'destination': '10.0.0.0/12',
+ 'gateway': '172.23.31.1'},
+ {'type': 'route', 'id': 5,
+ 'metric': 0, 'destination': '192.168.2.0/16',
+ 'gateway': '172.23.31.1'},
+ {'type': 'route', 'id': 6,
+ 'metric': 1, 'destination': '10.0.200.0/16',
+ 'gateway': '172.23.31.1'},
+ ]
+
+ files = self._render_and_read(
+ network_config={'config': conf, 'version': 1})
+ expected = [
+ 'auto lo',
+ 'iface lo inet loopback',
+ 'auto eth0',
+ 'iface eth0 inet static',
+ ' address 172.23.31.42/26',
+ ' gateway 172.23.31.2',
+ ('post-up route add -net 10.0.0.0 netmask 255.240.0.0 gw '
+ '172.23.31.1 metric 0 || true'),
+ ('pre-down route del -net 10.0.0.0 netmask 255.240.0.0 gw '
+ '172.23.31.1 metric 0 || true'),
+ ('post-up route add -net 192.168.2.0 netmask 255.255.0.0 gw '
+ '172.23.31.1 metric 0 || true'),
+ ('pre-down route del -net 192.168.2.0 netmask 255.255.0.0 gw '
+ '172.23.31.1 metric 0 || true'),
+ ('post-up route add -net 10.0.200.0 netmask 255.255.0.0 gw '
+ '172.23.31.1 metric 1 || true'),
+ ('pre-down route del -net 10.0.200.0 netmask 255.255.0.0 gw '
+ '172.23.31.1 metric 1 || true'),
+ ]
+ found = files['/etc/network/interfaces'].splitlines()
+
+ self.assertEqual(
+ expected, [line for line in found if line])
+
def _gzip_data(data):
with io.BytesIO() as iobuf:
@@ -730,3 +824,5 @@ def _gzip_data(data):
gzfp.write(data)
gzfp.close()
return iobuf.getvalue()
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_pathprefix2dict.py b/tests/unittests/test_pathprefix2dict.py
index 38fd75b6..a4ae284f 100644
--- a/tests/unittests/test_pathprefix2dict.py
+++ b/tests/unittests/test_pathprefix2dict.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
from cloudinit import util
from .helpers import TestCase, populate_dir
diff --git a/tests/unittests/test_registry.py b/tests/unittests/test_registry.py
index bcf01475..acf0bf4f 100644
--- a/tests/unittests/test_registry.py
+++ b/tests/unittests/test_registry.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
from cloudinit.registry import DictRegistry
from .helpers import (mock, TestCase)
@@ -26,3 +28,5 @@ class TestDictRegistry(TestCase):
registry.register_item(item_key, mock.Mock())
self.assertRaises(ValueError,
registry.register_item, item_key, mock.Mock())
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_reporting.py b/tests/unittests/test_reporting.py
index 20ca23df..f3b8f992 100644
--- a/tests/unittests/test_reporting.py
+++ b/tests/unittests/test_reporting.py
@@ -1,7 +1,6 @@
# Copyright 2015 Canonical Ltd.
-# This file is part of cloud-init. See LICENCE file for license information.
#
-# vi: ts=4 expandtab
+# This file is part of cloud-init. See LICENSE file for license information.
from cloudinit import reporting
from cloudinit.reporting import events
@@ -369,3 +368,5 @@ class TestReportingEventStack(TestCase):
class TestStatusAccess(TestCase):
def test_invalid_status_access_raises_value_error(self):
self.assertRaises(AttributeError, getattr, events.status, "BOGUS")
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_rh_subscription.py b/tests/unittests/test_rh_subscription.py
index 891dbe77..ca14cd46 100644
--- a/tests/unittests/test_rh_subscription.py
+++ b/tests/unittests/test_rh_subscription.py
@@ -1,14 +1,6 @@
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# This file is part of cloud-init. See LICENSE file for license information.
+
+"""Tests for registering RHEL subscription via rh_subscription."""
import logging
@@ -83,8 +75,8 @@ class GoodTests(TestCase):
'''
call_lists = []
call_lists.append(['attach', '--pool=pool1', '--pool=pool3'])
- call_lists.append(['repos', '--enable=repo2', '--enable=repo3',
- '--disable=repo5'])
+ call_lists.append(['repos', '--disable=repo5', '--enable=repo2',
+ '--enable=repo3'])
call_lists.append(['attach', '--auto', '--servicelevel=self-support'])
self.SM.log_success = mock.MagicMock()
reg = "The system has been registered with ID:" \
@@ -224,3 +216,5 @@ class TestBadInput(TestCase):
self.SM._sub_man_cli.assert_called_with(['identity'])
self.assertEqual(self.SM.log_warn.call_count, 4)
self.assertEqual(self.SM._sub_man_cli.call_count, 1)
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_runs/test_merge_run.py b/tests/unittests/test_runs/test_merge_run.py
index ce43798e..65895273 100644
--- a/tests/unittests/test_runs/test_merge_run.py
+++ b/tests/unittests/test_runs/test_merge_run.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
import os
import shutil
import tempfile
@@ -52,3 +54,5 @@ class TestMergeRun(helpers.FilesystemMockingTestCase):
self.assertIn('write-files', which_ran)
contents = util.load_file('/etc/blah.ini')
self.assertEqual(contents, 'blah')
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_runs/test_simple_run.py b/tests/unittests/test_runs/test_simple_run.py
index 07e7b1a8..31324204 100644
--- a/tests/unittests/test_runs/test_simple_run.py
+++ b/tests/unittests/test_runs/test_simple_run.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
import os
import shutil
import tempfile
@@ -79,3 +81,5 @@ class TestSimpleRun(helpers.FilesystemMockingTestCase):
self.assertIn('write-files', which_ran)
contents = util.load_file('/etc/blah.ini')
self.assertEqual(contents, 'blah')
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_sshutil.py b/tests/unittests/test_sshutil.py
index 9aeb1cde..55971b5e 100644
--- a/tests/unittests/test_sshutil.py
+++ b/tests/unittests/test_sshutil.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
from mock import patch
from . import helpers as test_helpers
diff --git a/tests/unittests/test_templating.py b/tests/unittests/test_templating.py
index 94b6e061..4e627826 100644
--- a/tests/unittests/test_templating.py
+++ b/tests/unittests/test_templating.py
@@ -1,20 +1,8 @@
-# vi: ts=4 expandtab
-#
-# Copyright (C) 2014 Yahoo! Inc.
-#
-# Author: Joshua Harlow <harlowja@yahoo-inc.com>
+# Copyright (C) 2014 Yahoo! Inc.
#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
+# Author: Joshua Harlow <harlowja@yahoo-inc.com>
#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# This file is part of cloud-init. See LICENSE file for license information.
from __future__ import print_function
@@ -117,3 +105,5 @@ $a,$b'''
{'mirror': mirror,
'codename': codename})
self.assertEqual(ex_data, out_data)
+
+# vi: ts=4 expandtab
diff --git a/tests/unittests/test_util.py b/tests/unittests/test_util.py
index f6a8ab75..ab74311e 100644
--- a/tests/unittests/test_util.py
+++ b/tests/unittests/test_util.py
@@ -1,3 +1,5 @@
+# This file is part of cloud-init. See LICENSE file for license information.
+
from __future__ import print_function
import logging
@@ -611,4 +613,73 @@ class TestEncode(helpers.TestCase):
text = util.decode_binary(blob)
self.assertEqual(text, blob)
+
+class TestProcessExecutionError(helpers.TestCase):
+
+ template = ('{description}\n'
+ 'Command: {cmd}\n'
+ 'Exit code: {exit_code}\n'
+ 'Reason: {reason}\n'
+ 'Stdout: {stdout}\n'
+ 'Stderr: {stderr}')
+ empty_attr = '-'
+ empty_description = 'Unexpected error while running command.'
+
+ def test_pexec_error_indent_text(self):
+ error = util.ProcessExecutionError()
+ msg = 'abc\ndef'
+ formatted = 'abc\n{0}def'.format(' ' * 4)
+ self.assertEqual(error._indent_text(msg, indent_level=4), formatted)
+ self.assertEqual(error._indent_text(msg.encode(), indent_level=4),
+ formatted.encode())
+ self.assertIsInstance(
+ error._indent_text(msg.encode()), type(msg.encode()))
+
+ def test_pexec_error_type(self):
+ self.assertIsInstance(util.ProcessExecutionError(), IOError)
+
+ def test_pexec_error_empty_msgs(self):
+ error = util.ProcessExecutionError()
+ self.assertTrue(all(attr == self.empty_attr for attr in
+ (error.stderr, error.stdout, error.reason)))
+ self.assertEqual(error.description, self.empty_description)
+ self.assertEqual(str(error), self.template.format(
+ description=self.empty_description, exit_code=self.empty_attr,
+ reason=self.empty_attr, stdout=self.empty_attr,
+ stderr=self.empty_attr, cmd=self.empty_attr))
+
+ def test_pexec_error_single_line_msgs(self):
+ stdout_msg = 'out out'
+ stderr_msg = 'error error'
+ cmd = 'test command'
+ exit_code = 3
+ error = util.ProcessExecutionError(
+ stdout=stdout_msg, stderr=stderr_msg, exit_code=3, cmd=cmd)
+ self.assertEqual(str(error), self.template.format(
+ description=self.empty_description, stdout=stdout_msg,
+ stderr=stderr_msg, exit_code=str(exit_code),
+ reason=self.empty_attr, cmd=cmd))
+
+ def test_pexec_error_multi_line_msgs(self):
+ # make sure bytes is converted handled properly when formatting
+ stdout_msg = 'multi\nline\noutput message'.encode()
+ stderr_msg = 'multi\nline\nerror message\n\n\n'
+ error = util.ProcessExecutionError(
+ stdout=stdout_msg, stderr=stderr_msg)
+ self.assertEqual(
+ str(error),
+ '\n'.join((
+ '{description}',
+ 'Command: {empty_attr}',
+ 'Exit code: {empty_attr}',
+ 'Reason: {empty_attr}',
+ 'Stdout: multi',
+ ' line',
+ ' output message',
+ 'Stderr: multi',
+ ' line',
+ ' error message',
+ )).format(description=self.empty_description,
+ empty_attr=self.empty_attr))
+
# vi: ts=4 expandtab
diff --git a/tests/unittests/test_vmware_config_file.py b/tests/unittests/test_vmware_config_file.py
index d5c7367b..18475f10 100644
--- a/tests/unittests/test_vmware_config_file.py
+++ b/tests/unittests/test_vmware_config_file.py
@@ -1,21 +1,9 @@
-# vi: ts=4 expandtab
-#
-# Copyright (C) 2015 Canonical Ltd.
-# Copyright (C) 2016 VMware INC.
-#
-# Author: Sankar Tanguturi <stanguturi@vmware.com>
+# Copyright (C) 2015 Canonical Ltd.
+# Copyright (C) 2016 VMware INC.
#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
+# Author: Sankar Tanguturi <stanguturi@vmware.com>
#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# This file is part of cloud-init. See LICENSE file for license information.
import logging
import sys
@@ -101,3 +89,5 @@ class TestVmwareConfigFile(unittest.TestCase):
self.assertEqual('NIC1', nics[0].name, "nic0")
self.assertEqual('00:50:56:a6:8c:08', nics[0].mac, "mac0")
self.assertEqual(BootProtoEnum.DHCP, nics[0].bootProto, "bootproto0")
+
+# vi: ts=4 expandtab