Merge ~wesley-wiedenmeier/cloud-init:revert-63501f44 into cloud-init:master

Proposed by Wesley Wiedenmeier
Status: Merged
Merged at revision: 0b0f254a6935a1b1fff128fa177152dd519e1a3d
Proposed branch: ~wesley-wiedenmeier/cloud-init:revert-63501f44
Merge into: cloud-init:master
Diff against target: 124 lines (+84/-5)
3 files modified
cloudinit/stages.py (+5/-5)
tests/unittests/helpers.py (+28/-0)
tests/unittests/test_data.py (+51/-0)
Reviewer Review Type Date Requested Status
cloud-init Commiters Pending
Review via email: mp+313665@code.launchpad.net

Description of the change

Revert 63501f44 which regressed behavior of stages.fetch_base_config() and added unittests for stages.fetch_base_config()

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/cloudinit/stages.py b/cloudinit/stages.py
2index 86a1378..40e826a 100644
3--- a/cloudinit/stages.py
4+++ b/cloudinit/stages.py
5@@ -847,16 +847,16 @@ class Modules(object):
6 def fetch_base_config():
7 base_cfgs = []
8 default_cfg = util.get_builtin_cfg()
9-
10- # Anything in your conf.d location??
11- # or the 'default' cloud.cfg location???
12- base_cfgs.append(util.read_conf_with_confd(CLOUD_CONFIG))
13+ kern_contents = util.read_cc_from_cmdline()
14
15 # Kernel/cmdline parameters override system config
16- kern_contents = util.read_cc_from_cmdline()
17 if kern_contents:
18 base_cfgs.append(util.load_yaml(kern_contents, default={}))
19
20+ # Anything in your conf.d location??
21+ # or the 'default' cloud.cfg location???
22+ base_cfgs.append(util.read_conf_with_confd(CLOUD_CONFIG))
23+
24 # And finally the default gets to play
25 if default_cfg:
26 base_cfgs.append(default_cfg)
27diff --git a/tests/unittests/helpers.py b/tests/unittests/helpers.py
28index a2355a7..14a7ef3 100644
29--- a/tests/unittests/helpers.py
30+++ b/tests/unittests/helpers.py
31@@ -300,6 +300,34 @@ def dir2dict(startdir, prefix=None):
32 return flist
33
34
35+def wrap_and_call(prefix, mocks, func, *args, **kwargs):
36+ """
37+ call func(args, **kwargs) with mocks applied, then unapplies mocks
38+ nicer to read than repeating dectorators on each function
39+
40+ prefix: prefix for mock names (e.g. 'cloudinit.stages.util')
41+ mocks: dictionary of names (under 'prefix') to mock and either
42+ a return value or a dictionary to pass to the mock.patch call
43+ func: function to call with mocks applied
44+ *args,**kwargs: arguments for 'func'
45+
46+ return_value: return from 'func'
47+ """
48+ delim = '.'
49+ unwraps = []
50+ for fname, kw in mocks.items():
51+ if not isinstance(kw, dict):
52+ kw = {'return_value': kw}
53+ p = mock.patch(delim.join((prefix.rstrip(delim), fname)), **kw)
54+ p.start()
55+ unwraps.append(p)
56+ try:
57+ return func(*args, **kwargs)
58+ finally:
59+ for p in unwraps:
60+ p.stop()
61+
62+
63 try:
64 skipIf = unittest.skipIf
65 except AttributeError:
66diff --git a/tests/unittests/test_data.py b/tests/unittests/test_data.py
67index 55d9b93..dc64e8c 100644
68--- a/tests/unittests/test_data.py
69+++ b/tests/unittests/test_data.py
70@@ -559,3 +559,54 @@ class TestConvertString(helpers.TestCase):
71 text = "hi mom"
72 msg = ud.convert_string(text)
73 self.assertEqual(text, msg.get_payload(decode=False))
74+
75+
76+class TestFetchBaseConfig(helpers.TestCase):
77+
78+ def test_only_builtin_gets_builtin2(self):
79+ ret = helpers.wrap_and_call(
80+ 'cloudinit.stages.util',
81+ {'read_conf_with_confd': None,
82+ 'read_cc_from_cmdline': None},
83+ stages.fetch_base_config)
84+ self.assertEqual(util.get_builtin_cfg(), ret)
85+
86+ def test_conf_d_overrides_defaults(self):
87+ builtin = util.get_builtin_cfg()
88+ test_key = sorted(builtin)[0]
89+ test_value = 'test'
90+ ret = helpers.wrap_and_call(
91+ 'cloudinit.stages.util',
92+ {'read_conf_with_confd': {'return_value': {test_key: test_value}},
93+ 'read_cc_from_cmdline': None},
94+ stages.fetch_base_config)
95+ self.assertEqual(ret.get(test_key), test_value)
96+ builtin[test_key] = test_value
97+ self.assertEqual(ret, builtin)
98+
99+ def test_cmdline_overrides_defaults(self):
100+ builtin = util.get_builtin_cfg()
101+ test_key = sorted(builtin)[0]
102+ test_value = 'test'
103+ cmdline = '{}: "{}"'.format(test_key, test_value)
104+ ret = helpers.wrap_and_call(
105+ 'cloudinit.stages.util',
106+ {'read_cc_from_cmdline': {'return_value': cmdline},
107+ 'read_conf_with_confd': None},
108+ stages.fetch_base_config)
109+ self.assertEqual(ret.get(test_key), test_value)
110+ builtin[test_key] = test_value
111+ self.assertEqual(ret, builtin)
112+
113+ def test_cmdline_overrides_conf_d_and_defaults(self):
114+ builtin = {'key1': 'value0', 'key3': 'other2'}
115+ conf_d = {'key1': 'value1', 'key2': 'other1'}
116+ cmdline = 'key3: "other3"\nkey2: "other2"'
117+ ret = helpers.wrap_and_call(
118+ 'cloudinit.stages.util',
119+ {'read_conf_with_confd': {'return_value': conf_d},
120+ 'get_builtin_cfg': {'return_value': builtin},
121+ 'read_cc_from_cmdline': {'return_value': cmdline}},
122+ stages.fetch_base_config)
123+ self.assertEqual(ret, {'key1': 'value1', 'key2': 'other2',
124+ 'key3': 'other3'})

Subscribers

People subscribed via source and target branches