Merge ~smoser/cloud-init:bug/run_test_net into cloud-init:master

Proposed by Scott Moser
Status: Merged
Merged at revision: 65e01b463cee0bdb8c8b415e78abfcc3262aad89
Proposed branch: ~smoser/cloud-init:bug/run_test_net
Merge into: cloud-init:master
Diff against target: 338 lines (+55/-61)
5 files modified
tests/unittests/helpers.py (+27/-20)
tests/unittests/test__init__.py (+6/-6)
tests/unittests/test_atomic_helper.py (+2/-2)
tests/unittests/test_distros/test_user_data_normalize.py (+0/-0)
tests/unittests/test_net.py (+20/-33)
Reviewer Review Type Date Requested Status
cloud-init Commiters Pending
Review via email: mp+315402@code.launchpad.net

Commit message

tests: remove executable bit on test_net, so it runs, and fix it.

The test_user_data_normalize and test_net files had gotten
the executable bit set, and thus are skipped by nose by default.
We could set run with the --exe flag, but they should not have
gotten this way.

Other changes here:
 * replace TempDirTestCase with CiTestCase, which has some nice
   tmp_dir() and tmp_path() functions. Going forward the intent
   is to have CiTestCase be the base test case for tests.
 * test_net: switch to CiTestCase and fix usage that was
   silently broken, because of exe bit.
 * populate_dir: return the list of files that it writes rather
   than having no return value.
 * CiTestCase:
    * support tmp_path("foo") that returns a full path to 'foo'
      under a tmpdir.
    * add tmp_dir() to get a temp dir and clean up.

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
diff --git a/tests/unittests/helpers.py b/tests/unittests/helpers.py
index a093346..90e2431 100644
--- a/tests/unittests/helpers.py
+++ b/tests/unittests/helpers.py
@@ -2,6 +2,7 @@
22
3from __future__ import print_function3from __future__ import print_function
44
5import functools
5import os6import os
6import shutil7import shutil
7import sys8import sys
@@ -82,6 +83,28 @@ class TestCase(unittest2.TestCase):
82 pass83 pass
8384
8485
86class CiTestCase(TestCase):
87 """This is the preferred test case base class unless user
88 needs other test case classes below."""
89 def tmp_dir(self, dir=None, cleanup=True):
90 # return a full path to a temporary directory that will be cleaned up.
91 if dir is None:
92 tmpd = tempfile.mkdtemp(
93 prefix="ci-%s." % self.__class__.__name__)
94 else:
95 tmpd = tempfile.mkdtemp(dir=dir)
96 self.addCleanup(functools.partial(shutil.rmtree, tmpd))
97 return tmpd
98
99 def tmp_path(self, path, dir=None):
100 # return an absolute path to 'path' under dir.
101 # if dir is None, one will be created with tmp_dir()
102 # the file is not created or modified.
103 if dir is None:
104 dir = self.tmp_dir()
105 return os.path.normpath(os.path.abspath(os.path.join(dir, path)))
106
107
85class ResourceUsingTestCase(TestCase):108class ResourceUsingTestCase(TestCase):
86 def setUp(self):109 def setUp(self):
87 super(ResourceUsingTestCase, self).setUp()110 super(ResourceUsingTestCase, self).setUp()
@@ -227,29 +250,10 @@ class HttprettyTestCase(TestCase):
227 super(HttprettyTestCase, self).tearDown()250 super(HttprettyTestCase, self).tearDown()
228251
229252
230class TempDirTestCase(TestCase):
231 # provide a tempdir per class, not per test.
232 @classmethod
233 def setUpClass(cls):
234 cls.tmpd = tempfile.mkdtemp(prefix="ci-%s." % cls.__name__)
235 return TestCase.setUpClass()
236
237 @classmethod
238 def tearDownClass(cls):
239 shutil.rmtree(cls.tmpd)
240 return TestCase.tearDownClass()
241
242 def tmp_path(self, path):
243 # if absolute path (starts with /), then make ./path
244 if path.startswith(os.path.sep):
245 path = "." + path
246
247 return os.path.normpath(os.path.join(self.tmpd, path))
248
249
250def populate_dir(path, files):253def populate_dir(path, files):
251 if not os.path.exists(path):254 if not os.path.exists(path):
252 os.makedirs(path)255 os.makedirs(path)
256 ret = []
253 for (name, content) in files.items():257 for (name, content) in files.items():
254 p = os.path.join(path, name)258 p = os.path.join(path, name)
255 util.ensure_dir(os.path.dirname(p))259 util.ensure_dir(os.path.dirname(p))
@@ -259,6 +263,9 @@ def populate_dir(path, files):
259 else:263 else:
260 fp.write(content.encode('utf-8'))264 fp.write(content.encode('utf-8'))
261 fp.close()265 fp.close()
266 ret.append(p)
267
268 return ret
262269
263270
264def dir2dict(startdir, prefix=None):271def dir2dict(startdir, prefix=None):
diff --git a/tests/unittests/test__init__.py b/tests/unittests/test__init__.py
index e6f4c31..781f6d5 100644
--- a/tests/unittests/test__init__.py
+++ b/tests/unittests/test__init__.py
@@ -12,7 +12,7 @@ from cloudinit import settings
12from cloudinit import url_helper12from cloudinit import url_helper
13from cloudinit import util13from cloudinit import util
1414
15from .helpers import TestCase, TempDirTestCase, ExitStack, mock15from .helpers import TestCase, CiTestCase, ExitStack, mock
1616
1717
18class FakeModule(handlers.Handler):18class FakeModule(handlers.Handler):
@@ -172,7 +172,7 @@ class TestHandlerHandlePart(TestCase):
172 self.data, self.ctype, self.filename, self.payload)172 self.data, self.ctype, self.filename, self.payload)
173173
174174
175class TestCmdlineUrl(TempDirTestCase):175class TestCmdlineUrl(CiTestCase):
176 def test_parse_cmdline_url_nokey_raises_keyerror(self):176 def test_parse_cmdline_url_nokey_raises_keyerror(self):
177 self.assertRaises(177 self.assertRaises(
178 KeyError, main.parse_cmdline_url, 'root=foo bar single')178 KeyError, main.parse_cmdline_url, 'root=foo bar single')
@@ -189,7 +189,7 @@ class TestCmdlineUrl(TempDirTestCase):
189 cmdline = "ro %s=%s bar=1" % (key, url)189 cmdline = "ro %s=%s bar=1" % (key, url)
190 m_read.return_value = url_helper.StringResponse(b"unexpected blob")190 m_read.return_value = url_helper.StringResponse(b"unexpected blob")
191191
192 fpath = self.tmp_path("test_valid")192 fpath = self.tmp_path("ccfile")
193 lvl, msg = main.attempt_cmdline_url(193 lvl, msg = main.attempt_cmdline_url(
194 fpath, network=True, cmdline=cmdline)194 fpath, network=True, cmdline=cmdline)
195 self.assertEqual(logging.WARN, lvl)195 self.assertEqual(logging.WARN, lvl)
@@ -203,7 +203,7 @@ class TestCmdlineUrl(TempDirTestCase):
203 cmdline = "ro %s=%s bar=1" % ('cloud-config-url', url)203 cmdline = "ro %s=%s bar=1" % ('cloud-config-url', url)
204204
205 m_read.return_value = url_helper.StringResponse(payload)205 m_read.return_value = url_helper.StringResponse(payload)
206 fpath = self.tmp_path("test_valid")206 fpath = self.tmp_path("ccfile")
207 lvl, msg = main.attempt_cmdline_url(207 lvl, msg = main.attempt_cmdline_url(
208 fpath, network=True, cmdline=cmdline)208 fpath, network=True, cmdline=cmdline)
209 self.assertEqual(util.load_file(fpath, decode=False), payload)209 self.assertEqual(util.load_file(fpath, decode=False), payload)
@@ -213,7 +213,7 @@ class TestCmdlineUrl(TempDirTestCase):
213 @mock.patch('cloudinit.cmd.main.util.read_file_or_url')213 @mock.patch('cloudinit.cmd.main.util.read_file_or_url')
214 def test_no_key_found(self, m_read):214 def test_no_key_found(self, m_read):
215 cmdline = "ro mykey=http://example.com/foo root=foo"215 cmdline = "ro mykey=http://example.com/foo root=foo"
216 fpath = self.tmp_path("test_no_key_found")216 fpath = self.tmp_path("ccpath")
217 lvl, msg = main.attempt_cmdline_url(217 lvl, msg = main.attempt_cmdline_url(
218 fpath, network=True, cmdline=cmdline)218 fpath, network=True, cmdline=cmdline)
219219
@@ -225,7 +225,7 @@ class TestCmdlineUrl(TempDirTestCase):
225 def test_exception_warns(self, m_read):225 def test_exception_warns(self, m_read):
226 url = "http://example.com/foo"226 url = "http://example.com/foo"
227 cmdline = "ro cloud-config-url=%s root=LABEL=bar" % url227 cmdline = "ro cloud-config-url=%s root=LABEL=bar" % url
228 fpath = self.tmp_path("test_no_key_found")228 fpath = self.tmp_path("ccfile")
229 m_read.side_effect = url_helper.UrlError(229 m_read.side_effect = url_helper.UrlError(
230 cause="Unexpected Error", url="http://example.com/foo")230 cause="Unexpected Error", url="http://example.com/foo")
231231
diff --git a/tests/unittests/test_atomic_helper.py b/tests/unittests/test_atomic_helper.py
index e170c7c..515919d 100644
--- a/tests/unittests/test_atomic_helper.py
+++ b/tests/unittests/test_atomic_helper.py
@@ -6,10 +6,10 @@ import stat
66
7from cloudinit import atomic_helper7from cloudinit import atomic_helper
88
9from . import helpers9from .helpers import CiTestCase
1010
1111
12class TestAtomicHelper(helpers.TempDirTestCase):12class TestAtomicHelper(CiTestCase):
13 def test_basic_usage(self):13 def test_basic_usage(self):
14 """write_file takes bytes if no omode."""14 """write_file takes bytes if no omode."""
15 path = self.tmp_path("test_basic_usage")15 path = self.tmp_path("test_basic_usage")
diff --git a/tests/unittests/test_distros/test_user_data_normalize.py b/tests/unittests/test_distros/test_user_data_normalize.py
16old mode 10075516old mode 100755
17new mode 10064417new mode 100644
index 88746e0..88746e0
--- a/tests/unittests/test_distros/test_user_data_normalize.py
+++ b/tests/unittests/test_distros/test_user_data_normalize.py
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
18old mode 10075518old mode 100755
19new mode 10064419new mode 100644
index 1090282..2c2bde9
--- a/tests/unittests/test_net.py
+++ b/tests/unittests/test_net.py
@@ -8,11 +8,10 @@ from cloudinit.net import sysconfig
8from cloudinit.sources.helpers import openstack8from cloudinit.sources.helpers import openstack
9from cloudinit import util9from cloudinit import util
1010
11from .helpers import CiTestCase
11from .helpers import dir2dict12from .helpers import dir2dict
12from .helpers import mock13from .helpers import mock
13from .helpers import populate_dir14from .helpers import populate_dir
14from .helpers import TempDirTestCase
15from .helpers import TestCase
1615
17import base6416import base64
18import copy17import copy
@@ -20,8 +19,6 @@ import gzip
20import io19import io
21import json20import json
22import os21import os
23import shutil
24import tempfile
25import textwrap22import textwrap
26import yaml23import yaml
2724
@@ -478,7 +475,7 @@ def _setup_test(tmp_dir, mock_get_devicelist, mock_read_sys_net,
478 mock_sys_dev_path.side_effect = sys_dev_path475 mock_sys_dev_path.side_effect = sys_dev_path
479476
480477
481class TestSysConfigRendering(TestCase):478class TestSysConfigRendering(CiTestCase):
482479
483 @mock.patch("cloudinit.net.sys_dev_path")480 @mock.patch("cloudinit.net.sys_dev_path")
484 @mock.patch("cloudinit.net.read_sys_net")481 @mock.patch("cloudinit.net.read_sys_net")
@@ -486,8 +483,7 @@ class TestSysConfigRendering(TestCase):
486 def test_default_generation(self, mock_get_devicelist,483 def test_default_generation(self, mock_get_devicelist,
487 mock_read_sys_net,484 mock_read_sys_net,
488 mock_sys_dev_path):485 mock_sys_dev_path):
489 tmp_dir = tempfile.mkdtemp()486 tmp_dir = self.tmp_dir()
490 self.addCleanup(shutil.rmtree, tmp_dir)
491 _setup_test(tmp_dir, mock_get_devicelist,487 _setup_test(tmp_dir, mock_get_devicelist,
492 mock_read_sys_net, mock_sys_dev_path)488 mock_read_sys_net, mock_sys_dev_path)
493489
@@ -518,9 +514,7 @@ USERCTL=no
518 self.assertEqual(expected_content, content)514 self.assertEqual(expected_content, content)
519515
520 def test_openstack_rendering_samples(self):516 def test_openstack_rendering_samples(self):
521 tmp_dir = tempfile.mkdtemp()517 render_dir = self.tmp_dir()
522 self.addCleanup(shutil.rmtree, tmp_dir)
523 render_dir = os.path.join(tmp_dir, "render")
524 for os_sample in OS_SAMPLES:518 for os_sample in OS_SAMPLES:
525 ex_input = os_sample['in_data']519 ex_input = os_sample['in_data']
526 ex_mac_addrs = os_sample['in_macs']520 ex_mac_addrs = os_sample['in_macs']
@@ -535,7 +529,7 @@ USERCTL=no
535 self.assertEqual(expected_content, fh.read())529 self.assertEqual(expected_content, fh.read())
536530
537531
538class TestEniNetRendering(TestCase):532class TestEniNetRendering(CiTestCase):
539533
540 @mock.patch("cloudinit.net.sys_dev_path")534 @mock.patch("cloudinit.net.sys_dev_path")
541 @mock.patch("cloudinit.net.read_sys_net")535 @mock.patch("cloudinit.net.read_sys_net")
@@ -543,8 +537,7 @@ class TestEniNetRendering(TestCase):
543 def test_default_generation(self, mock_get_devicelist,537 def test_default_generation(self, mock_get_devicelist,
544 mock_read_sys_net,538 mock_read_sys_net,
545 mock_sys_dev_path):539 mock_sys_dev_path):
546 tmp_dir = tempfile.mkdtemp()540 tmp_dir = self.tmp_dir()
547 self.addCleanup(shutil.rmtree, tmp_dir)
548 _setup_test(tmp_dir, mock_get_devicelist,541 _setup_test(tmp_dir, mock_get_devicelist,
549 mock_read_sys_net, mock_sys_dev_path)542 mock_read_sys_net, mock_sys_dev_path)
550543
@@ -576,7 +569,7 @@ iface eth1000 inet dhcp
576 self.assertEqual(expected.lstrip(), contents.lstrip())569 self.assertEqual(expected.lstrip(), contents.lstrip())
577570
578571
579class TestEniNetworkStateToEni(TestCase):572class TestEniNetworkStateToEni(CiTestCase):
580 mycfg = {573 mycfg = {
581 'config': [{"type": "physical", "name": "eth0",574 'config': [{"type": "physical", "name": "eth0",
582 "mac_address": "c0:d6:9f:2c:e8:80",575 "mac_address": "c0:d6:9f:2c:e8:80",
@@ -607,7 +600,7 @@ class TestEniNetworkStateToEni(TestCase):
607 self.assertNotIn("hwaddress", rendered)600 self.assertNotIn("hwaddress", rendered)
608601
609602
610class TestCmdlineConfigParsing(TestCase):603class TestCmdlineConfigParsing(CiTestCase):
611 simple_cfg = {604 simple_cfg = {
612 'config': [{"type": "physical", "name": "eth0",605 'config': [{"type": "physical", "name": "eth0",
613 "mac_address": "c0:d6:9f:2c:e8:80",606 "mac_address": "c0:d6:9f:2c:e8:80",
@@ -665,7 +658,7 @@ class TestCmdlineConfigParsing(TestCase):
665 self.assertEqual(found, self.simple_cfg)658 self.assertEqual(found, self.simple_cfg)
666659
667660
668class TestCmdlineReadKernelConfig(TempDirTestCase):661class TestCmdlineReadKernelConfig(CiTestCase):
669 macs = {662 macs = {
670 'eth0': '14:02:ec:42:48:00',663 'eth0': '14:02:ec:42:48:00',
671 'eno1': '14:02:ec:42:48:01',664 'eno1': '14:02:ec:42:48:01',
@@ -673,8 +666,7 @@ class TestCmdlineReadKernelConfig(TempDirTestCase):
673666
674 def test_ip_cmdline_read_kernel_cmdline_ip(self):667 def test_ip_cmdline_read_kernel_cmdline_ip(self):
675 content = {'net-eth0.conf': DHCP_CONTENT_1}668 content = {'net-eth0.conf': DHCP_CONTENT_1}
676 populate_dir(self.tmp, content)669 files = sorted(populate_dir(self.tmp_dir(), content))
677 files = [os.path.join(self.tmp, k) for k in content.keys()]
678 found = cmdline.read_kernel_cmdline_config(670 found = cmdline.read_kernel_cmdline_config(
679 files=files, cmdline='foo ip=dhcp', mac_addrs=self.macs)671 files=files, cmdline='foo ip=dhcp', mac_addrs=self.macs)
680 exp1 = copy.deepcopy(DHCP_EXPECTED_1)672 exp1 = copy.deepcopy(DHCP_EXPECTED_1)
@@ -684,8 +676,7 @@ class TestCmdlineReadKernelConfig(TempDirTestCase):
684676
685 def test_ip_cmdline_read_kernel_cmdline_ip6(self):677 def test_ip_cmdline_read_kernel_cmdline_ip6(self):
686 content = {'net6-eno1.conf': DHCP6_CONTENT_1}678 content = {'net6-eno1.conf': DHCP6_CONTENT_1}
687 populate_dir(self.tmp, content)679 files = sorted(populate_dir(self.tmp_dir(), content))
688 files = [os.path.join(self.tmp, k) for k in content.keys()]
689 found = cmdline.read_kernel_cmdline_config(680 found = cmdline.read_kernel_cmdline_config(
690 files=files, cmdline='foo ip6=dhcp root=/dev/sda',681 files=files, cmdline='foo ip6=dhcp root=/dev/sda',
691 mac_addrs=self.macs)682 mac_addrs=self.macs)
@@ -701,8 +692,7 @@ class TestCmdlineReadKernelConfig(TempDirTestCase):
701 def test_ip_cmdline_read_kernel_cmdline_none(self):692 def test_ip_cmdline_read_kernel_cmdline_none(self):
702 # if there is no ip= or ip6= on cmdline, return value should be None693 # if there is no ip= or ip6= on cmdline, return value should be None
703 content = {'net6-eno1.conf': DHCP6_CONTENT_1}694 content = {'net6-eno1.conf': DHCP6_CONTENT_1}
704 populate_dir(self.tmp, content)695 files = sorted(populate_dir(self.tmp_dir(), content))
705 files = [os.path.join(self.tmp, k) for k in content.keys()]
706 found = cmdline.read_kernel_cmdline_config(696 found = cmdline.read_kernel_cmdline_config(
707 files=files, cmdline='foo root=/dev/sda', mac_addrs=self.macs)697 files=files, cmdline='foo root=/dev/sda', mac_addrs=self.macs)
708 self.assertEqual(found, None)698 self.assertEqual(found, None)
@@ -710,8 +700,7 @@ class TestCmdlineReadKernelConfig(TempDirTestCase):
710 def test_ip_cmdline_both_ip_ip6(self):700 def test_ip_cmdline_both_ip_ip6(self):
711 content = {'net-eth0.conf': DHCP_CONTENT_1,701 content = {'net-eth0.conf': DHCP_CONTENT_1,
712 'net6-eth0.conf': DHCP6_CONTENT_1.replace('eno1', 'eth0')}702 'net6-eth0.conf': DHCP6_CONTENT_1.replace('eno1', 'eth0')}
713 populate_dir(self.tmp, content)703 files = sorted(populate_dir(self.tmp_dir(), content))
714 files = [os.path.join(self.tmp, k) for k in sorted(content.keys())]
715 found = cmdline.read_kernel_cmdline_config(704 found = cmdline.read_kernel_cmdline_config(
716 files=files, cmdline='foo ip=dhcp ip6=dhcp', mac_addrs=self.macs)705 files=files, cmdline='foo ip=dhcp ip6=dhcp', mac_addrs=self.macs)
717706
@@ -725,14 +714,12 @@ class TestCmdlineReadKernelConfig(TempDirTestCase):
725 self.assertEqual(found['config'], expected)714 self.assertEqual(found['config'], expected)
726715
727716
728class TestEniRoundTrip(TestCase):717class TestEniRoundTrip(CiTestCase):
729 def setUp(self):
730 super(TestCase, self).setUp()
731 self.tmp_dir = tempfile.mkdtemp()
732 self.addCleanup(shutil.rmtree, self.tmp_dir)
733
734 def _render_and_read(self, network_config=None, state=None, eni_path=None,718 def _render_and_read(self, network_config=None, state=None, eni_path=None,
735 links_prefix=None, netrules_path=None):719 links_prefix=None, netrules_path=None, dir=None):
720 if dir is None:
721 dir = self.tmp_dir()
722
736 if network_config:723 if network_config:
737 ns = network_state.parse_net_config_data(network_config)724 ns = network_state.parse_net_config_data(network_config)
738 elif state:725 elif state:
@@ -747,8 +734,8 @@ class TestEniRoundTrip(TestCase):
747 config={'eni_path': eni_path, 'links_path_prefix': links_prefix,734 config={'eni_path': eni_path, 'links_path_prefix': links_prefix,
748 'netrules_path': netrules_path})735 'netrules_path': netrules_path})
749736
750 renderer.render_network_state(self.tmp_dir, ns)737 renderer.render_network_state(dir, ns)
751 return dir2dict(self.tmp_dir)738 return dir2dict(dir)
752739
753 def testsimple_convert_and_render(self):740 def testsimple_convert_and_render(self):
754 network_config = eni.convert_eni_data(EXAMPLE_ENI)741 network_config = eni.convert_eni_data(EXAMPLE_ENI)

Subscribers

People subscribed via source and target branches