From 9800832d4fbfef2624baa0d3c1a0aa737bc0dfb2 Mon Sep 17 00:00:00 2001 From: harlowja Date: Thu, 10 Jan 2013 23:09:02 -0800 Subject: Add a context manager function in test helpers. This function can be used to ensure that mocker objects are restored and verified during usage if exceptions are thrown while the mock object is being used. Ensure it is used in the config drive test when multiple mock objects are being created and restored. LP: #1098430 --- tests/unittests/helpers.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'tests/unittests/helpers.py') diff --git a/tests/unittests/helpers.py b/tests/unittests/helpers.py index 92540b0c..4258a29d 100644 --- a/tests/unittests/helpers.py +++ b/tests/unittests/helpers.py @@ -2,6 +2,9 @@ import os import sys import unittest +from contextlib import contextmanager + +from mocker import Mocker from mocker import MockerTestCase from cloudinit import helpers as ch @@ -31,6 +34,17 @@ else: pass +@contextmanager +def mocker(verify_calls=True): + m = Mocker() + try: + yield m + finally: + m.restore() + if verify_calls: + m.verify() + + # Makes the old path start # with new base instead of whatever # it previously had -- cgit v1.2.3 From a0f882fdd306ef7b3b90c53d5622eb5a6878cb81 Mon Sep 17 00:00:00 2001 From: Scott Moser Date: Thu, 7 Feb 2013 12:08:30 -0500 Subject: more test cases for nocloud including one for config seed --- tests/unittests/helpers.py | 7 ++ tests/unittests/test_datasource/test_maas.py | 8 +- tests/unittests/test_datasource/test_nocloud.py | 113 ++++++++++++++++++++++-- 3 files changed, 115 insertions(+), 13 deletions(-) (limited to 'tests/unittests/helpers.py') diff --git a/tests/unittests/helpers.py b/tests/unittests/helpers.py index 4258a29d..91a50e18 100644 --- a/tests/unittests/helpers.py +++ b/tests/unittests/helpers.py @@ -182,3 +182,10 @@ class FilesystemMockingTestCase(ResourceUsingTestCase): trap_func = retarget_many_wrapper(new_root, 1, func) setattr(mod, f, trap_func) self.patched_funcs.append((mod, f, func)) + +def populate_dir(path, files): + os.makedirs(path) + for (name, content) in files.iteritems(): + with open(os.path.join(path, name), "w") as fp: + fp.write(content) + fp.close() diff --git a/tests/unittests/test_datasource/test_maas.py b/tests/unittests/test_datasource/test_maas.py index 85e6add0..b56fea82 100644 --- a/tests/unittests/test_datasource/test_maas.py +++ b/tests/unittests/test_datasource/test_maas.py @@ -3,6 +3,7 @@ import os from cloudinit.sources import DataSourceMAAS from cloudinit import url_helper +from tests.unittests.helpers import populate_dir from mocker import MockerTestCase @@ -137,11 +138,4 @@ class TestMAASDataSource(MockerTestCase): pass -def populate_dir(seed_dir, files): - os.mkdir(seed_dir) - for (name, content) in files.iteritems(): - with open(os.path.join(seed_dir, name), "w") as fp: - fp.write(content) - fp.close() - # vi: ts=4 expandtab diff --git a/tests/unittests/test_datasource/test_nocloud.py b/tests/unittests/test_datasource/test_nocloud.py index 850d3214..28e0a472 100644 --- a/tests/unittests/test_datasource/test_nocloud.py +++ b/tests/unittests/test_datasource/test_nocloud.py @@ -1,16 +1,106 @@ +from cloudinit import helpers +from tests.unittests.helpers import populate_dir from cloudinit.sources import DataSourceNoCloud +from cloudinit import util from mocker import MockerTestCase +import os +import yaml class TestNoCloudDataSource(MockerTestCase): def setUp(self): + self.tmp = self.makeDir() + self.paths = helpers.Paths({'cloud_dir': self.tmp}) + + self.cmdline = "root=TESTCMDLINE" + + self.unapply = [] + self.apply_patches([(util, 'get_cmdline', self._getcmdline)]) super(TestNoCloudDataSource, self).setUp() - def test_parse_cmdline_data_valid(self): - parse = DataSourceNoCloud.parse_cmdline_data + def tearDown(self): + apply_patches([i for i in reversed(self.unapply)]) + super(TestNoCloudDataSource, self).setUp() + + def apply_patches(self, patches): + ret = apply_patches(patches) + self.unapply += ret + + def _getcmdline(self): + return self.cmdline + + def test_nocloud_seed_dir(self): + md = {'instance-id': 'IID', 'dsmode': 'local'} + ud = "USER_DATA_HERE" + populate_dir(os.path.join(self.paths.seed_dir, "nocloud"), + {'user-data': ud, '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) + ret = dsrc.get_data() + self.assertEqual(dsrc.userdata_raw, ud) + self.assertEqual(dsrc.metadata, md) + self.assertTrue(ret) + + def test_fs_label(self): + #find_devs_with should not be called ff fs_label is None + ds = DataSourceNoCloud.DataSourceNoCloud + + class PsuedoException(Exception): + pass + + def my_find_devs_with(*args, **kwargs): + _f = (args, kwargs) + raise PsuedoException + + self.apply_patches([(util, 'find_devs_with', my_find_devs_with)]) + # by default, NoCloud should search for filesystems by label + sys_cfg = {'datasource': {'NoCloud': {}}} + dsrc = ds(sys_cfg=sys_cfg, distro=None, paths=self.paths) + self.assertRaises(PsuedoException, dsrc.get_data) + + # but disabling searching should just end up with None found + sys_cfg = {'datasource': {'NoCloud': {'fs_label': None}}} + dsrc = ds(sys_cfg=sys_cfg, distro=None, paths=self.paths) + ret = dsrc.get_data() + self.assertFalse(ret) + + def test_no_datasource_expected(self): + #no source should be found if no cmdline, config, and fs_label=None + sys_cfg = {'datasource': {'NoCloud': {'fs_label': None}}} + + ds = DataSourceNoCloud.DataSourceNoCloud + dsrc = ds(sys_cfg=sys_cfg, distro=None, paths=self.paths) + self.assertFalse(dsrc.get_data()) + + def test_seed_in_config(self): + ds = DataSourceNoCloud.DataSourceNoCloud + + data = { + 'fs_label': None, + 'meta-data': {'instance-id': 'IID'}, + 'user-data': "USER_DATA_RAW", + } + + sys_cfg = {'datasource': {'NoCloud': data}} + dsrc = ds(sys_cfg=sys_cfg, distro=None, paths=self.paths) + ret = dsrc.get_data() + self.assertEqual(dsrc.userdata_raw, "USER_DATA_RAW") + self.assertEqual(dsrc.metadata.get('instance-id'), 'IID') + self.assertTrue(ret) + + +class TestParseCommandLineData(MockerTestCase): + + def test_parse_cmdline_data_valid(self): ds_id = "ds=nocloud" pairs = ( ("root=/dev/sda1 %(ds_id)s", {}), @@ -29,13 +119,12 @@ class TestNoCloudDataSource(MockerTestCase): for (fmt, expected) in pairs: fill = {} cmdline = fmt % {'ds_id': ds_id} - ret = parse(ds_id=ds_id, fill=fill, cmdline=cmdline) + ret = DataSourceNoCloud.parse_cmdline_data(ds_id=ds_id, fill=fill, + cmdline=cmdline) self.assertEqual(expected, fill) self.assertTrue(ret) def test_parse_cmdline_data_none(self): - parse = DataSourceNoCloud.parse_cmdline_data - ds_id = "ds=foo" cmdlines = ( "root=/dev/sda1 ro", @@ -48,9 +137,21 @@ class TestNoCloudDataSource(MockerTestCase): for cmdline in cmdlines: fill = {} - ret = parse(ds_id=ds_id, fill=fill, cmdline=cmdline) + ret = DataSourceNoCloud.parse_cmdline_data(ds_id=ds_id, fill=fill, + cmdline=cmdline) self.assertEqual(fill, {}) self.assertFalse(ret) +def apply_patches(patches): + ret = [] + for (ref, name, replace) in patches: + if replace is None: + continue + orig = getattr(ref, name) + setattr(ref, name, replace) + ret.append((ref, name, orig)) + return ret + + # vi: ts=4 expandtab -- cgit v1.2.3