Merge lp:~chad.smith/curtin/common-ci-test-case into lp:~curtin-dev/curtin/trunk

Proposed by Chad Smith
Status: Merged
Merged at revision: 519
Proposed branch: lp:~chad.smith/curtin/common-ci-test-case
Merge into: lp:~curtin-dev/curtin/trunk
Diff against target: 1483 lines (+247/-347)
24 files modified
tests/unittests/helpers.py (+36/-0)
tests/unittests/test_apt_custom_sources_list.py (+3/-6)
tests/unittests/test_apt_source.py (+4/-7)
tests/unittests/test_basic.py (+4/-4)
tests/unittests/test_block.py (+20/-36)
tests/unittests/test_block_iscsi.py (+6/-18)
tests/unittests/test_block_lvm.py (+2/-2)
tests/unittests/test_block_mdadm.py (+10/-22)
tests/unittests/test_block_mkfs.py (+2/-2)
tests/unittests/test_clear_holders.py (+5/-5)
tests/unittests/test_commands_apply_net.py (+8/-20)
tests/unittests/test_commands_block_meta.py (+6/-19)
tests/unittests/test_commands_install.py (+4/-4)
tests/unittests/test_config.py (+6/-6)
tests/unittests/test_curthooks.py (+21/-46)
tests/unittests/test_feature.py (+2/-2)
tests/unittests/test_gpg.py (+4/-4)
tests/unittests/test_make_dname.py (+4/-4)
tests/unittests/test_net.py (+8/-14)
tests/unittests/test_partitioning.py (+4/-3)
tests/unittests/test_public.py (+4/-4)
tests/unittests/test_reporter.py (+29/-38)
tests/unittests/test_util.py (+48/-62)
tests/unittests/test_version.py (+7/-19)
To merge this branch: bzr merge lp:~chad.smith/curtin/common-ci-test-case
Reviewer Review Type Date Requested Status
Server Team CI bot continuous-integration Approve
curtin developers Pending
Review via email: mp+328477@code.launchpad.net

Commit message

tests: Add CiTestCase common parent for all curtin tests

This branch makes sure all unittests subclass from CiTestCase which provides all unit tests with an add_patch method for mocking as well as tmp_dir and tmp_path creation.

Drop any unittest-specific tempfile setup in favor of self.tmp_dir and self.tmp_path.

Also drop any duplicate add_patch method definitions and convert any mock start/stop logic to add_patch where possible.

Description of the change

tests: Add CiTestCase common parent for all curtin tests

This branch makes sure all unittests subclass from CiTestCase which provides all unit tests with an add_patch method for mocking as well as tmp_dir and tmp_path creation.

Drop any unittest-specific tempfile setup in favor of self.tmp_dir and self.tmp_path.

Also drop any duplicate add_patch method definitions and convert any mock start/stop logic to add_patch where possible.

To post a comment you must log in.
Revision history for this message
Server Team CI bot (server-team-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Ryan Harper (raharper) wrote :

Thanks for starting this.

I'd suggest also adding in the add_patch() which is repeated in many of the base classes in the unittests. It's fine if we punt that to a second MP after this lands as well.

Overall looks fine, couple of questions in line.

Revision history for this message
Scott Moser (smoser) wrote :

responded to ryan's comment in line. lets drop the functools.

518. By Chad Smith

drop functools partial as it is unneeded

Revision history for this message
Chad Smith (chad.smith) :
Revision history for this message
Server Team CI bot (server-team-bot) wrote :
review: Approve (continuous-integration)
519. By Chad Smith

move add_patch up into CiTestCase, drop all add_patch definitions in subclasses. Convert any locally defined mock start/stop definitions to use add_patch

520. By Chad Smith

add missing super...setUp calls to classes which have overridden the unittest.setUp method

Revision history for this message
Server Team CI bot (server-team-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Ryan Harper (raharper) wrote :

Looks good once you make tox happy

521. By Chad Smith

allow kwargs passed into CiTestCase.add_patch per review comments

Revision history for this message
Server Team CI bot (server-team-bot) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'tests/unittests/helpers.py'
--- tests/unittests/helpers.py 2016-11-30 22:57:10 +0000
+++ tests/unittests/helpers.py 2017-08-03 19:32:06 +0000
@@ -19,6 +19,10 @@
19import imp19import imp
20import importlib20import importlib
21import mock21import mock
22import os
23import shutil
24import tempfile
25from unittest import TestCase
2226
2327
24def builtin_module_name():28def builtin_module_name():
@@ -43,3 +47,35 @@
43 m_patch = '{}.open'.format(mod_name)47 m_patch = '{}.open'.format(mod_name)
44 with mock.patch(m_patch, m_open, create=True):48 with mock.patch(m_patch, m_open, create=True):
45 yield m_open49 yield m_open
50
51
52class CiTestCase(TestCase):
53 """Common testing class which all curtin unit tests subclass."""
54
55 def add_patch(self, target, attr, **kwargs):
56 """Patches specified target object and sets it as attr on test
57 instance also schedules cleanup"""
58 if 'autospec' not in kwargs:
59 kwargs['autospec'] = True
60 m = mock.patch(target, **kwargs)
61 p = m.start()
62 self.addCleanup(m.stop)
63 setattr(self, attr, p)
64
65 def tmp_dir(self, dir=None, cleanup=True):
66 """Return a full path to a temporary directory for the test run."""
67 if dir is None:
68 tmpd = tempfile.mkdtemp(
69 prefix="curtin-ci-%s." % self.__class__.__name__)
70 else:
71 tmpd = tempfile.mkdtemp(dir=dir)
72 self.addCleanup(shutil.rmtree, tmpd)
73 return tmpd
74
75 def tmp_path(self, path, _dir=None):
76 # return an absolute path to 'path' under dir.
77 # if dir is None, one will be created with tmp_dir()
78 # the file is not created or modified.
79 if _dir is None:
80 _dir = self.tmp_dir()
81 return os.path.normpath(os.path.abspath(os.path.join(_dir, path)))
4682
=== modified file 'tests/unittests/test_apt_custom_sources_list.py'
--- tests/unittests/test_apt_custom_sources_list.py 2016-07-29 10:27:20 +0000
+++ tests/unittests/test_apt_custom_sources_list.py 2017-08-03 19:32:06 +0000
@@ -3,10 +3,7 @@
3"""3"""
4import logging4import logging
5import os5import os
6import shutil
7import tempfile
86
9from unittest import TestCase
107
11import yaml8import yaml
12import mock9import mock
@@ -14,6 +11,7 @@
1411
15from curtin import util12from curtin import util
16from curtin.commands import apt_config13from curtin.commands import apt_config
14from .helpers import CiTestCase
1715
18LOG = logging.getLogger(__name__)16LOG = logging.getLogger(__name__)
1917
@@ -85,12 +83,11 @@
85""")83""")
8684
8785
88class TestAptSourceConfigSourceList(TestCase):86class TestAptSourceConfigSourceList(CiTestCase):
89 """TestAptSourceConfigSourceList - Class to test sources list rendering"""87 """TestAptSourceConfigSourceList - Class to test sources list rendering"""
90 def setUp(self):88 def setUp(self):
91 super(TestAptSourceConfigSourceList, self).setUp()89 super(TestAptSourceConfigSourceList, self).setUp()
92 self.new_root = tempfile.mkdtemp()90 self.new_root = self.tmp_dir()
93 self.addCleanup(shutil.rmtree, self.new_root)
94 # self.patchUtils(self.new_root)91 # self.patchUtils(self.new_root)
9592
96 @staticmethod93 @staticmethod
9794
=== modified file 'tests/unittests/test_apt_source.py'
--- tests/unittests/test_apt_source.py 2017-02-09 19:59:11 +0000
+++ tests/unittests/test_apt_source.py 2017-08-03 19:32:06 +0000
@@ -4,11 +4,8 @@
4import glob4import glob
5import os5import os
6import re6import re
7import shutil
8import socket7import socket
9import tempfile
108
11from unittest import TestCase
129
13import mock10import mock
14from mock import call11from mock import call
@@ -16,6 +13,7 @@
16from curtin import util13from curtin import util
17from curtin import gpg14from curtin import gpg
18from curtin.commands import apt_config15from curtin.commands import apt_config
16from .helpers import CiTestCase
1917
2018
21EXPECTEDKEY = u"""-----BEGIN PGP PUBLIC KEY BLOCK-----19EXPECTEDKEY = u"""-----BEGIN PGP PUBLIC KEY BLOCK-----
@@ -62,14 +60,13 @@
62ChrootableTargetStr = "curtin.commands.apt_config.util.ChrootableTarget"60ChrootableTargetStr = "curtin.commands.apt_config.util.ChrootableTarget"
6361
6462
65class TestAptSourceConfig(TestCase):63class TestAptSourceConfig(CiTestCase):
66 """ TestAptSourceConfig64 """ TestAptSourceConfig
67 Main Class to test apt configs65 Main Class to test apt configs
68 """66 """
69 def setUp(self):67 def setUp(self):
70 super(TestAptSourceConfig, self).setUp()68 super(TestAptSourceConfig, self).setUp()
71 self.tmp = tempfile.mkdtemp()69 self.tmp = self.tmp_dir()
72 self.addCleanup(shutil.rmtree, self.tmp)
73 self.aptlistfile = os.path.join(self.tmp, "single-deb.list")70 self.aptlistfile = os.path.join(self.tmp, "single-deb.list")
74 self.aptlistfile2 = os.path.join(self.tmp, "single-deb2.list")71 self.aptlistfile2 = os.path.join(self.tmp, "single-deb2.list")
75 self.aptlistfile3 = os.path.join(self.tmp, "single-deb3.list")72 self.aptlistfile3 = os.path.join(self.tmp, "single-deb3.list")
@@ -930,7 +927,7 @@
930 orig, apt_config.disable_suites(["proposed"], orig, rel))927 orig, apt_config.disable_suites(["proposed"], orig, rel))
931928
932929
933class TestDebconfSelections(TestCase):930class TestDebconfSelections(CiTestCase):
934931
935 @mock.patch("curtin.commands.apt_config.debconf_set_selections")932 @mock.patch("curtin.commands.apt_config.debconf_set_selections")
936 def test_no_set_sel_if_none_to_set(self, m_set_sel):933 def test_no_set_sel_if_none_to_set(self, m_set_sel):
937934
=== modified file 'tests/unittests/test_basic.py'
--- tests/unittests/test_basic.py 2013-07-29 19:59:51 +0000
+++ tests/unittests/test_basic.py 2017-08-03 19:32:06 +0000
@@ -1,7 +1,7 @@
1from unittest import TestCase1from .helpers import CiTestCase
22
33
4class TestImport(TestCase):4class TestImport(CiTestCase):
5 def test_import(self):5 def test_import(self):
6 import curtin6 import curtin
7 self.assertFalse(getattr(curtin, 'BOGUS_ENTRY', None))7 self.assertFalse(getattr(curtin, 'BOGUS_ENTRY', None))
88
=== modified file 'tests/unittests/test_block.py'
--- tests/unittests/test_block.py 2017-05-22 20:10:23 +0000
+++ tests/unittests/test_block.py 2017-08-03 19:32:06 +0000
@@ -1,19 +1,16 @@
1from unittest import TestCase
2import functools1import functools
3import os2import os
4import mock3import mock
5import tempfile
6import shutil
7import sys4import sys
85
9from collections import OrderedDict6from collections import OrderedDict
107
11from .helpers import simple_mocked_open8from .helpers import CiTestCase, simple_mocked_open
12from curtin import util9from curtin import util
13from curtin import block10from curtin import block
1411
1512
16class TestBlock(TestCase):13class TestBlock(CiTestCase):
1714
18 @mock.patch("curtin.block.util")15 @mock.patch("curtin.block.util")
19 def test_get_volume_uuid(self, mock_util):16 def test_get_volume_uuid(self, mock_util):
@@ -103,7 +100,7 @@
103 block.lookup_disk(serial)100 block.lookup_disk(serial)
104101
105102
106class TestSysBlockPath(TestCase):103class TestSysBlockPath(CiTestCase):
107 @mock.patch("curtin.block.get_blockdev_for_partition")104 @mock.patch("curtin.block.get_blockdev_for_partition")
108 @mock.patch("os.path.exists")105 @mock.patch("os.path.exists")
109 def test_existing_valid_devname(self, m_os_path_exists, m_get_blk):106 def test_existing_valid_devname(self, m_os_path_exists, m_get_blk):
@@ -177,19 +174,13 @@
177 block.sys_block_path('/dev/cciss/c0d0p1'))174 block.sys_block_path('/dev/cciss/c0d0p1'))
178175
179176
180class TestWipeFile(TestCase):177class TestWipeFile(CiTestCase):
181 def __init__(self, *args, **kwargs):178 def __init__(self, *args, **kwargs):
182 super(TestWipeFile, self).__init__(*args, **kwargs)179 super(TestWipeFile, self).__init__(*args, **kwargs)
183180
184 def tfile(self, *args):
185 # return a temp file in a dir that will be cleaned up
186 tmpdir = tempfile.mkdtemp()
187 self.addCleanup(shutil.rmtree, tmpdir)
188 return os.path.sep.join([tmpdir] + list(args))
189
190 def test_non_exist_raises_file_not_found(self):181 def test_non_exist_raises_file_not_found(self):
191 try:182 try:
192 p = self.tfile("enofile")183 p = self.tmp_path("enofile")
193 block.wipe_file(p)184 block.wipe_file(p)
194 raise Exception("%s did not raise exception" % p)185 raise Exception("%s did not raise exception" % p)
195 except Exception as e:186 except Exception as e:
@@ -198,7 +189,7 @@
198189
199 def test_non_exist_dir_raises_file_not_found(self):190 def test_non_exist_dir_raises_file_not_found(self):
200 try:191 try:
201 p = self.tfile("enodir", "file")192 p = self.tmp_path(os.path.sep.join(["enodir", "file"]))
202 block.wipe_file(p)193 block.wipe_file(p)
203 raise Exception("%s did not raise exception" % p)194 raise Exception("%s did not raise exception" % p)
204 except Exception as e:195 except Exception as e:
@@ -207,7 +198,7 @@
207198
208 def test_default_is_zero(self):199 def test_default_is_zero(self):
209 flen = 1024200 flen = 1024
210 myfile = self.tfile("def_zero")201 myfile = self.tmp_path("def_zero")
211 util.write_file(myfile, flen * b'\1', omode="wb")202 util.write_file(myfile, flen * b'\1', omode="wb")
212 block.wipe_file(myfile)203 block.wipe_file(myfile)
213 found = util.load_file(myfile, decode=False)204 found = util.load_file(myfile, decode=False)
@@ -219,7 +210,7 @@
219 def reader(size):210 def reader(size):
220 return size * b'\1'211 return size * b'\1'
221212
222 myfile = self.tfile("reader_used")213 myfile = self.tmp_path("reader_used")
223 # populate with nulls214 # populate with nulls
224 util.write_file(myfile, flen * b'\0', omode="wb")215 util.write_file(myfile, flen * b'\0', omode="wb")
225 block.wipe_file(myfile, reader=reader, buflen=flen)216 block.wipe_file(myfile, reader=reader, buflen=flen)
@@ -236,15 +227,15 @@
236 data['x'] = data['x'][size:]227 data['x'] = data['x'][size:]
237 return buf228 return buf
238229
239 myfile = self.tfile("reader_twice")230 myfile = self.tmp_path("reader_twice")
240 util.write_file(myfile, flen * b'\xff', omode="wb")231 util.write_file(myfile, flen * b'\xff', omode="wb")
241 block.wipe_file(myfile, reader=reader, buflen=20)232 block.wipe_file(myfile, reader=reader, buflen=20)
242 found = util.load_file(myfile, decode=False)233 found = util.load_file(myfile, decode=False)
243 self.assertEqual(found, expected)234 self.assertEqual(found, expected)
244235
245 def test_reader_fhandle(self):236 def test_reader_fhandle(self):
246 srcfile = self.tfile("fhandle_src")237 srcfile = self.tmp_path("fhandle_src")
247 trgfile = self.tfile("fhandle_trg")238 trgfile = self.tmp_path("fhandle_trg")
248 data = '\n'.join(["this is source file." for f in range(0, 10)] + [])239 data = '\n'.join(["this is source file." for f in range(0, 10)] + [])
249 util.write_file(srcfile, data)240 util.write_file(srcfile, data)
250 util.write_file(trgfile, 'a' * len(data))241 util.write_file(trgfile, 'a' * len(data))
@@ -254,7 +245,7 @@
254 self.assertEqual(data, found)245 self.assertEqual(data, found)
255246
256 def test_exclusive_open_raise_missing(self):247 def test_exclusive_open_raise_missing(self):
257 myfile = self.tfile("no-such-file")248 myfile = self.tmp_path("no-such-file")
258249
259 with self.assertRaises(ValueError):250 with self.assertRaises(ValueError):
260 with block.exclusive_open(myfile) as fp:251 with block.exclusive_open(myfile) as fp:
@@ -265,7 +256,7 @@
265 @mock.patch('os.open')256 @mock.patch('os.open')
266 def test_exclusive_open(self, mock_os_open, mock_os_fdopen, mock_os_close):257 def test_exclusive_open(self, mock_os_open, mock_os_fdopen, mock_os_close):
267 flen = 1024258 flen = 1024
268 myfile = self.tfile("my_exclusive_file")259 myfile = self.tmp_path("my_exclusive_file")
269 util.write_file(myfile, flen * b'\1', omode="wb")260 util.write_file(myfile, flen * b'\1', omode="wb")
270 mock_fd = 3261 mock_fd = 3
271 mock_os_open.return_value = mock_fd262 mock_os_open.return_value = mock_fd
@@ -288,7 +279,7 @@
288 mock_os_close,279 mock_os_close,
289 mock_util_fuser):280 mock_util_fuser):
290 flen = 1024281 flen = 1024
291 myfile = self.tfile("my_exclusive_file")282 myfile = self.tmp_path("my_exclusive_file")
292 util.write_file(myfile, flen * b'\1', omode="wb")283 util.write_file(myfile, flen * b'\1', omode="wb")
293 mock_os_open.side_effect = OSError("NO_O_EXCL")284 mock_os_open.side_effect = OSError("NO_O_EXCL")
294 mock_holders.return_value = ['md1']285 mock_holders.return_value = ['md1']
@@ -310,7 +301,7 @@
310 def test_exclusive_open_fdopen_failure(self, mock_os_open,301 def test_exclusive_open_fdopen_failure(self, mock_os_open,
311 mock_os_fdopen, mock_os_close):302 mock_os_fdopen, mock_os_close):
312 flen = 1024303 flen = 1024
313 myfile = self.tfile("my_exclusive_file")304 myfile = self.tmp_path("my_exclusive_file")
314 util.write_file(myfile, flen * b'\1', omode="wb")305 util.write_file(myfile, flen * b'\1', omode="wb")
315 mock_fd = 3306 mock_fd = 3
316 mock_os_open.return_value = mock_fd307 mock_os_open.return_value = mock_fd
@@ -328,7 +319,7 @@
328 self.assertEqual([], mock_os_close.call_args_list)319 self.assertEqual([], mock_os_close.call_args_list)
329320
330321
331class TestWipeVolume(TestCase):322class TestWipeVolume(CiTestCase):
332 dev = '/dev/null'323 dev = '/dev/null'
333324
334 @mock.patch('curtin.block.lvm')325 @mock.patch('curtin.block.lvm')
@@ -366,7 +357,7 @@
366 block.wipe_volume(self.dev, mode='invalidmode')357 block.wipe_volume(self.dev, mode='invalidmode')
367358
368359
369class TestBlockKnames(TestCase):360class TestBlockKnames(CiTestCase):
370 """Tests for some of the kname functions in block"""361 """Tests for some of the kname functions in block"""
371 def test_determine_partition_kname(self):362 def test_determine_partition_kname(self):
372 part_knames = [(('sda', 1), 'sda1'),363 part_knames = [(('sda', 1), 'sda1'),
@@ -430,7 +421,7 @@
430 block.kname_to_path(kname)421 block.kname_to_path(kname)
431422
432423
433class TestPartTableSignature(TestCase):424class TestPartTableSignature(CiTestCase):
434 blockdev = '/dev/null'425 blockdev = '/dev/null'
435 dos_content = b'\x00' * 0x1fe + b'\x55\xAA' + b'\x00' * 0xf00426 dos_content = b'\x00' * 0x1fe + b'\x55\xAA' + b'\x00' * 0xf00
436 gpt_content = b'\x00' * 0x200 + b'EFI PART' + b'\x00' * (0x200 - 8)427 gpt_content = b'\x00' * 0x200 + b'EFI PART' + b'\x00' * (0x200 - 8)
@@ -493,7 +484,7 @@
493 block.check_efi_signature(self.blockdev))484 block.check_efi_signature(self.blockdev))
494485
495486
496class TestNonAscii(TestCase):487class TestNonAscii(CiTestCase):
497 @mock.patch('curtin.block.util.subp')488 @mock.patch('curtin.block.util.subp')
498 def test_lsblk(self, mock_subp):489 def test_lsblk(self, mock_subp):
499 # lsblk can write non-ascii data, causing shlex to blow up490 # lsblk can write non-ascii data, causing shlex to blow up
@@ -519,14 +510,7 @@
519 block.blkid()510 block.blkid()
520511
521512
522class TestSlaveKnames(TestCase):513class TestSlaveKnames(CiTestCase):
523 def add_patch(self, target, attr, autospec=True):
524 """Patches specified target object and sets it as attr on test
525 instance also schedules cleanup"""
526 m = mock.patch(target, autospec=autospec)
527 p = m.start()
528 self.addCleanup(m.stop)
529 setattr(self, attr, p)
530514
531 def setUp(self):515 def setUp(self):
532 super(TestSlaveKnames, self).setUp()516 super(TestSlaveKnames, self).setUp()
533517
=== modified file 'tests/unittests/test_block_iscsi.py'
--- tests/unittests/test_block_iscsi.py 2017-05-12 20:20:02 +0000
+++ tests/unittests/test_block_iscsi.py 2017-08-03 19:32:06 +0000
@@ -1,23 +1,11 @@
1import mock1import mock
22
3from unittest import TestCase
4from curtin.block import iscsi3from curtin.block import iscsi
54from .helpers import CiTestCase
65
7class IscsiTestBase(TestCase):6
8 def setUp(self):7class TestBlockIscsiPortalParsing(CiTestCase):
9 super(IscsiTestBase, self).setUp()8
10
11 def add_patch(self, target, attr):
12 """Patches specified target object and sets it as attr on test
13 instance also schedules cleanup"""
14 m = mock.patch(target, autospec=True)
15 p = m.start()
16 self.addCleanup(m.stop)
17 setattr(self, attr, p)
18
19
20class TestBlockIscsiPortalParsing(IscsiTestBase):
21 def test_iscsi_portal_parsing_string(self):9 def test_iscsi_portal_parsing_string(self):
22 with self.assertRaisesRegexp(ValueError, 'not a string'):10 with self.assertRaisesRegexp(ValueError, 'not a string'):
23 iscsi.assert_valid_iscsi_portal(1234)11 iscsi.assert_valid_iscsi_portal(1234)
@@ -490,7 +478,7 @@
490 self.assertEquals(i.target, 'iqn.2017-04.com.example.test:target-name')478 self.assertEquals(i.target, 'iqn.2017-04.com.example.test:target-name')
491479
492480
493class TestBlockIscsiVolPath(IscsiTestBase):481class TestBlockIscsiVolPath(CiTestCase):
494 # non-iscsi backed disk returns false482 # non-iscsi backed disk returns false
495 # regular iscsi-backed disk returns true483 # regular iscsi-backed disk returns true
496 # layered setup without an iscsi member returns false484 # layered setup without an iscsi member returns false
497485
=== modified file 'tests/unittests/test_block_lvm.py'
--- tests/unittests/test_block_lvm.py 2016-08-15 14:52:56 +0000
+++ tests/unittests/test_block_lvm.py 2017-08-03 19:32:06 +0000
@@ -1,10 +1,10 @@
1from curtin.block import lvm1from curtin.block import lvm
22
3from unittest import TestCase3from .helpers import CiTestCase
4import mock4import mock
55
66
7class TestBlockLvm(TestCase):7class TestBlockLvm(CiTestCase):
8 vg_name = 'ubuntu-volgroup'8 vg_name = 'ubuntu-volgroup'
99
10 @mock.patch('curtin.block.lvm.util')10 @mock.patch('curtin.block.lvm.util')
1111
=== modified file 'tests/unittests/test_block_mdadm.py'
--- tests/unittests/test_block_mdadm.py 2017-05-08 20:38:48 +0000
+++ tests/unittests/test_block_mdadm.py 2017-08-03 19:32:06 +0000
@@ -1,27 +1,15 @@
1from unittest import TestCase
2from mock import call, patch1from mock import call, patch
3from curtin.block import dev_short2from curtin.block import dev_short
4from curtin.block import mdadm3from curtin.block import mdadm
5from curtin import util4from curtin import util
5from .helpers import CiTestCase
6import os6import os
7import subprocess7import subprocess
8import textwrap8import textwrap
99
1010
11class MdadmTestBase(TestCase):11class TestBlockMdadmAssemble(CiTestCase):
12 def setUp(self):12
13 super(MdadmTestBase, self).setUp()
14
15 def add_patch(self, target, attr):
16 """Patches specified target object and sets it as attr on test
17 instance also schedules cleanup"""
18 m = patch(target, autospec=True)
19 p = m.start()
20 self.addCleanup(m.stop)
21 setattr(self, attr, p)
22
23
24class TestBlockMdadmAssemble(MdadmTestBase):
25 def setUp(self):13 def setUp(self):
26 super(TestBlockMdadmAssemble, self).setUp()14 super(TestBlockMdadmAssemble, self).setUp()
27 self.add_patch('curtin.block.mdadm.util', 'mock_util')15 self.add_patch('curtin.block.mdadm.util', 'mock_util')
@@ -94,7 +82,7 @@
94 rcs=[0, 1, 2])82 rcs=[0, 1, 2])
9583
9684
97class TestBlockMdadmCreate(MdadmTestBase):85class TestBlockMdadmCreate(CiTestCase):
98 def setUp(self):86 def setUp(self):
99 super(TestBlockMdadmCreate, self).setUp()87 super(TestBlockMdadmCreate, self).setUp()
100 self.add_patch('curtin.block.mdadm.util', 'mock_util')88 self.add_patch('curtin.block.mdadm.util', 'mock_util')
@@ -243,7 +231,7 @@
243 self.mock_util.subp.assert_has_calls(expected_calls)231 self.mock_util.subp.assert_has_calls(expected_calls)
244232
245233
246class TestBlockMdadmExamine(MdadmTestBase):234class TestBlockMdadmExamine(CiTestCase):
247 def setUp(self):235 def setUp(self):
248 super(TestBlockMdadmExamine, self).setUp()236 super(TestBlockMdadmExamine, self).setUp()
249 self.add_patch('curtin.block.mdadm.util', 'mock_util')237 self.add_patch('curtin.block.mdadm.util', 'mock_util')
@@ -328,7 +316,7 @@
328 self.assertEqual(data, {})316 self.assertEqual(data, {})
329317
330318
331class TestBlockMdadmStop(MdadmTestBase):319class TestBlockMdadmStop(CiTestCase):
332 def setUp(self):320 def setUp(self):
333 super(TestBlockMdadmStop, self).setUp()321 super(TestBlockMdadmStop, self).setUp()
334 self.add_patch('curtin.block.mdadm.util.lsb_release', 'mock_util_lsb')322 self.add_patch('curtin.block.mdadm.util.lsb_release', 'mock_util_lsb')
@@ -495,7 +483,7 @@
495 self.mock_util_write_file.assert_has_calls(expected_writes)483 self.mock_util_write_file.assert_has_calls(expected_writes)
496484
497485
498class TestBlockMdadmRemove(MdadmTestBase):486class TestBlockMdadmRemove(CiTestCase):
499 def setUp(self):487 def setUp(self):
500 super(TestBlockMdadmRemove, self).setUp()488 super(TestBlockMdadmRemove, self).setUp()
501 self.add_patch('curtin.block.mdadm.util', 'mock_util')489 self.add_patch('curtin.block.mdadm.util', 'mock_util')
@@ -521,7 +509,7 @@
521 self.mock_util.subp.assert_has_calls(expected_calls)509 self.mock_util.subp.assert_has_calls(expected_calls)
522510
523511
524class TestBlockMdadmQueryDetail(MdadmTestBase):512class TestBlockMdadmQueryDetail(CiTestCase):
525 def setUp(self):513 def setUp(self):
526 super(TestBlockMdadmQueryDetail, self).setUp()514 super(TestBlockMdadmQueryDetail, self).setUp()
527 self.add_patch('curtin.block.mdadm.util', 'mock_util')515 self.add_patch('curtin.block.mdadm.util', 'mock_util')
@@ -599,7 +587,7 @@
599 '93a73e10:427f280b:b7076c02:204b8f7a')587 '93a73e10:427f280b:b7076c02:204b8f7a')
600588
601589
602class TestBlockMdadmDetailScan(MdadmTestBase):590class TestBlockMdadmDetailScan(CiTestCase):
603 def setUp(self):591 def setUp(self):
604 super(TestBlockMdadmDetailScan, self).setUp()592 super(TestBlockMdadmDetailScan, self).setUp()
605 self.add_patch('curtin.block.mdadm.util', 'mock_util')593 self.add_patch('curtin.block.mdadm.util', 'mock_util')
@@ -634,7 +622,7 @@
634 self.assertEqual(None, data)622 self.assertEqual(None, data)
635623
636624
637class TestBlockMdadmMdHelpers(MdadmTestBase):625class TestBlockMdadmMdHelpers(CiTestCase):
638 def setUp(self):626 def setUp(self):
639 super(TestBlockMdadmMdHelpers, self).setUp()627 super(TestBlockMdadmMdHelpers, self).setUp()
640 self.add_patch('curtin.block.mdadm.util', 'mock_util')628 self.add_patch('curtin.block.mdadm.util', 'mock_util')
641629
=== modified file 'tests/unittests/test_block_mkfs.py'
--- tests/unittests/test_block_mkfs.py 2016-06-30 21:40:28 +0000
+++ tests/unittests/test_block_mkfs.py 2017-08-03 19:32:06 +0000
@@ -1,10 +1,10 @@
1from curtin.block import mkfs1from curtin.block import mkfs
22
3from unittest import TestCase3from .helpers import CiTestCase
4import mock4import mock
55
66
7class TestBlockMkfs(TestCase):7class TestBlockMkfs(CiTestCase):
8 test_uuid = "fb26cc6c-ae73-11e5-9e38-2fb63f0c3155"8 test_uuid = "fb26cc6c-ae73-11e5-9e38-2fb63f0c3155"
99
10 def _get_config(self, fstype):10 def _get_config(self, fstype):
1111
=== modified file 'tests/unittests/test_clear_holders.py'
--- tests/unittests/test_clear_holders.py 2017-05-30 15:27:14 +0000
+++ tests/unittests/test_clear_holders.py 2017-08-03 19:32:06 +0000
@@ -1,12 +1,12 @@
1from unittest import TestCase
2import mock1import mock
3
4from curtin.block import clear_holders
5import os2import os
6import textwrap3import textwrap
74
85from curtin.block import clear_holders
9class TestClearHolders(TestCase):6from .helpers import CiTestCase
7
8
9class TestClearHolders(CiTestCase):
10 test_blockdev = '/dev/null'10 test_blockdev = '/dev/null'
11 test_syspath = '/sys/class/block/null'11 test_syspath = '/sys/class/block/null'
12 remove_retries = [0.2] * 150 # clear_holders defaults to 30 seconds12 remove_retries = [0.2] * 150 # clear_holders defaults to 30 seconds
1313
=== modified file 'tests/unittests/test_commands_apply_net.py'
--- tests/unittests/test_commands_apply_net.py 2017-07-19 14:32:15 +0000
+++ tests/unittests/test_commands_apply_net.py 2017-08-03 19:32:06 +0000
@@ -1,26 +1,14 @@
1from unittest import TestCase
2from mock import patch, call1from mock import patch, call
3import copy2import copy
4import os3import os
54
6from curtin.commands import apply_net5from curtin.commands import apply_net
7from curtin import util6from curtin import util
87from .helpers import CiTestCase
98
10class ApplyNetTestBase(TestCase):9
11 def setUp(self):10class TestApplyNet(CiTestCase):
12 super(ApplyNetTestBase, self).setUp()11
13
14 def add_patch(self, target, attr):
15 """Patches specified target object and sets it as attr on test
16 instance also schedules cleanup"""
17 m = patch(target, autospec=True)
18 p = m.start()
19 self.addCleanup(m.stop)
20 setattr(self, attr, p)
21
22
23class TestApplyNet(ApplyNetTestBase):
24 def setUp(self):12 def setUp(self):
25 super(TestApplyNet, self).setUp()13 super(TestApplyNet, self).setUp()
2614
@@ -150,7 +138,7 @@
150 self.m_ipv6_mtu.assert_called_with(self.target)138 self.m_ipv6_mtu.assert_called_with(self.target)
151139
152140
153class TestApplyNetPatchIfupdown(ApplyNetTestBase):141class TestApplyNetPatchIfupdown(CiTestCase):
154142
155 @patch('curtin.util.write_file')143 @patch('curtin.util.write_file')
156 def test_apply_ipv6_mtu_hook(self, mock_write):144 def test_apply_ipv6_mtu_hook(self, mock_write):
@@ -218,7 +206,7 @@
218 self.assertEqual(0, mock_write.call_count)206 self.assertEqual(0, mock_write.call_count)
219207
220208
221class TestApplyNetPatchIpv6Priv(ApplyNetTestBase):209class TestApplyNetPatchIpv6Priv(CiTestCase):
222210
223 @patch('curtin.util.del_file')211 @patch('curtin.util.del_file')
224 @patch('curtin.util.load_file')212 @patch('curtin.util.load_file')
@@ -274,7 +262,7 @@
274 self.assertEqual(0, mock_load.call_count)262 self.assertEqual(0, mock_load.call_count)
275263
276264
277class TestApplyNetRemoveLegacyEth0(ApplyNetTestBase):265class TestApplyNetRemoveLegacyEth0(CiTestCase):
278266
279 @patch('curtin.util.del_file')267 @patch('curtin.util.del_file')
280 @patch('curtin.util.load_file')268 @patch('curtin.util.load_file')
281269
=== modified file 'tests/unittests/test_commands_block_meta.py'
--- tests/unittests/test_commands_block_meta.py 2017-03-22 15:34:21 +0000
+++ tests/unittests/test_commands_block_meta.py 2017-08-03 19:32:06 +0000
@@ -1,24 +1,11 @@
1from unittest import TestCase
2from mock import patch, call1from mock import patch, call
3from argparse import Namespace2from argparse import Namespace
43
5from curtin.commands import block_meta4from curtin.commands import block_meta
65from .helpers import CiTestCase
76
8class BlockMetaTestBase(TestCase):7
9 def setUp(self):8class TestBlockMetaSimple(CiTestCase):
10 super(BlockMetaTestBase, self).setUp()
11
12 def add_patch(self, target, attr):
13 """Patches specified target object and sets it as attr on test
14 instance also schedules cleanup"""
15 m = patch(target, autospec=True)
16 p = m.start()
17 self.addCleanup(m.stop)
18 setattr(self, attr, p)
19
20
21class TestBlockMetaSimple(BlockMetaTestBase):
22 def setUp(self):9 def setUp(self):
23 super(TestBlockMetaSimple, self).setUp()10 super(TestBlockMetaSimple, self).setUp()
24 self.target = "my_target"11 self.target = "my_target"
@@ -120,10 +107,10 @@
120 [call(['mount', devname, self.target])])107 [call(['mount', devname, self.target])])
121108
122109
123class TestBlockMeta(BlockMetaTestBase):110class TestBlockMeta(CiTestCase):
111
124 def setUp(self):112 def setUp(self):
125 super(TestBlockMeta, self).setUp()113 super(TestBlockMeta, self).setUp()
126 # self.target = tempfile.mkdtemp()
127114
128 basepath = 'curtin.commands.block_meta.'115 basepath = 'curtin.commands.block_meta.'
129 self.add_patch(basepath + 'get_path_to_storage_volume', 'mock_getpath')116 self.add_patch(basepath + 'get_path_to_storage_volume', 'mock_getpath')
130117
=== modified file 'tests/unittests/test_commands_install.py'
--- tests/unittests/test_commands_install.py 2017-07-21 20:57:06 +0000
+++ tests/unittests/test_commands_install.py 2017-08-03 19:32:06 +0000
@@ -1,10 +1,10 @@
1from unittest import TestCase
2import copy1import copy
32
4from curtin.commands import install3from curtin.commands import install
54from .helpers import CiTestCase
65
7class TestMigrateProxy(TestCase):6
7class TestMigrateProxy(CiTestCase):
8 def test_legacy_moved_over(self):8 def test_legacy_moved_over(self):
9 """Legacy setting should get moved over."""9 """Legacy setting should get moved over."""
10 proxy = "http://my.proxy:3128"10 proxy = "http://my.proxy:3128"
1111
=== modified file 'tests/unittests/test_config.py'
--- tests/unittests/test_config.py 2015-09-02 17:17:45 +0000
+++ tests/unittests/test_config.py 2017-08-03 19:32:06 +0000
@@ -1,12 +1,12 @@
1from unittest import TestCase
2import copy1import copy
3import json2import json
4import textwrap3import textwrap
54
6from curtin import config5from curtin import config
76from .helpers import CiTestCase
87
9class TestMerge(TestCase):8
9class TestMerge(CiTestCase):
10 def test_merge_cfg_string(self):10 def test_merge_cfg_string(self):
11 d1 = {'str1': 'str_one'}11 d1 = {'str1': 'str_one'}
12 d2 = {'dict1': {'d1.e1': 'd1-e1'}}12 d2 = {'dict1': {'d1.e1': 'd1-e1'}}
@@ -16,7 +16,7 @@
16 self.assertEqual(d1, expected)16 self.assertEqual(d1, expected)
1717
1818
19class TestCmdArg2Cfg(TestCase):19class TestCmdArg2Cfg(CiTestCase):
20 def test_cmdarg_flat(self):20 def test_cmdarg_flat(self):
21 self.assertEqual(config.cmdarg2cfg("foo=bar"), {'foo': 'bar'})21 self.assertEqual(config.cmdarg2cfg("foo=bar"), {'foo': 'bar'})
2222
@@ -50,7 +50,7 @@
50 self.assertEqual(via_merge, via_merge_cmdarg)50 self.assertEqual(via_merge, via_merge_cmdarg)
5151
5252
53class TestConfigArchive(TestCase):53class TestConfigArchive(CiTestCase):
54 def test_archive_dict(self):54 def test_archive_dict(self):
55 myarchive = _replace_consts(textwrap.dedent("""55 myarchive = _replace_consts(textwrap.dedent("""
56 _ARCH_HEAD_56 _ARCH_HEAD_
5757
=== modified file 'tests/unittests/test_curthooks.py'
--- tests/unittests/test_curthooks.py 2017-07-28 19:01:38 +0000
+++ tests/unittests/test_curthooks.py 2017-08-03 19:32:06 +0000
@@ -1,29 +1,14 @@
1import os1import os
2from unittest import TestCase
3from mock import call, patch, MagicMock2from mock import call, patch, MagicMock
4import shutil
5import tempfile
63
7from curtin.commands import curthooks4from curtin.commands import curthooks
8from curtin import util5from curtin import util
9from curtin import config6from curtin import config
10from curtin.reporter import events7from curtin.reporter import events
118from .helpers import CiTestCase
129
13class CurthooksBase(TestCase):10
14 def setUp(self):11class TestGetFlashKernelPkgs(CiTestCase):
15 super(CurthooksBase, self).setUp()
16
17 def add_patch(self, target, attr, autospec=True):
18 """Patches specified target object and sets it as attr on test
19 instance also schedules cleanup"""
20 m = patch(target, autospec=autospec)
21 p = m.start()
22 self.addCleanup(m.stop)
23 setattr(self, attr, p)
24
25
26class TestGetFlashKernelPkgs(CurthooksBase):
27 def setUp(self):12 def setUp(self):
28 super(TestGetFlashKernelPkgs, self).setUp()13 super(TestGetFlashKernelPkgs, self).setUp()
29 self.add_patch('curtin.util.subp', 'mock_subp')14 self.add_patch('curtin.util.subp', 'mock_subp')
@@ -57,7 +42,7 @@
57 self.mock_is_uefi_bootable.assert_called_once_with()42 self.mock_is_uefi_bootable.assert_called_once_with()
5843
5944
60class TestCurthooksInstallKernel(CurthooksBase):45class TestCurthooksInstallKernel(CiTestCase):
61 def setUp(self):46 def setUp(self):
62 super(TestCurthooksInstallKernel, self).setUp()47 super(TestCurthooksInstallKernel, self).setUp()
63 self.add_patch('curtin.util.has_pkg_available', 'mock_haspkg')48 self.add_patch('curtin.util.has_pkg_available', 'mock_haspkg')
@@ -70,7 +55,7 @@
70 'fallback-package': 'mock-fallback',55 'fallback-package': 'mock-fallback',
71 'mapping': {}}}56 'mapping': {}}}
72 # Tests don't actually install anything so we just need a name57 # Tests don't actually install anything so we just need a name
73 self.target = tempfile.mktemp()58 self.target = self.tmp_dir()
7459
75 def test__installs_flash_kernel_packages_when_needed(self):60 def test__installs_flash_kernel_packages_when_needed(self):
76 kernel_package = self.kernel_cfg.get('kernel', {}).get('package', {})61 kernel_package = self.kernel_cfg.get('kernel', {}).get('package', {})
@@ -94,14 +79,11 @@
94 [kernel_package], target=self.target)79 [kernel_package], target=self.target)
9580
9681
97class TestUpdateInitramfs(CurthooksBase):82class TestUpdateInitramfs(CiTestCase):
98 def setUp(self):83 def setUp(self):
99 super(TestUpdateInitramfs, self).setUp()84 super(TestUpdateInitramfs, self).setUp()
100 self.add_patch('curtin.util.subp', 'mock_subp')85 self.add_patch('curtin.util.subp', 'mock_subp')
101 self.target = tempfile.mkdtemp()86 self.target = self.tmp_dir()
102
103 def tearDown(self):
104 shutil.rmtree(self.target)
10587
106 def _mnt_call(self, point):88 def _mnt_call(self, point):
107 target = os.path.join(self.target, point)89 target = os.path.join(self.target, point)
@@ -134,7 +116,7 @@
134 self.mock_subp.assert_has_calls(subp_calls)116 self.mock_subp.assert_has_calls(subp_calls)
135117
136118
137class TestInstallMissingPkgs(CurthooksBase):119class TestInstallMissingPkgs(CiTestCase):
138 def setUp(self):120 def setUp(self):
139 super(TestInstallMissingPkgs, self).setUp()121 super(TestInstallMissingPkgs, self).setUp()
140 self.add_patch('platform.machine', 'mock_machine')122 self.add_patch('platform.machine', 'mock_machine')
@@ -176,11 +158,11 @@
176 self.assertEqual([], self.mock_install_packages.call_args_list)158 self.assertEqual([], self.mock_install_packages.call_args_list)
177159
178160
179class TestSetupZipl(CurthooksBase):161class TestSetupZipl(CiTestCase):
180162
181 def setUp(self):163 def setUp(self):
182 super(TestSetupZipl, self).setUp()164 super(TestSetupZipl, self).setUp()
183 self.target = tempfile.mkdtemp()165 self.target = self.tmp_dir()
184166
185 @patch('curtin.block.get_devices_for_mp')167 @patch('curtin.block.get_devices_for_mp')
186 @patch('platform.machine')168 @patch('platform.machine')
@@ -203,11 +185,11 @@
203 content)185 content)
204186
205187
206class TestSetupGrub(CurthooksBase):188class TestSetupGrub(CiTestCase):
207189
208 def setUp(self):190 def setUp(self):
209 super(TestSetupGrub, self).setUp()191 super(TestSetupGrub, self).setUp()
210 self.target = tempfile.mkdtemp()192 self.target = self.tmp_dir()
211 self.add_patch('curtin.util.lsb_release', 'mock_lsb_release')193 self.add_patch('curtin.util.lsb_release', 'mock_lsb_release')
212 self.mock_lsb_release.return_value = {194 self.mock_lsb_release.return_value = {
213 'codename': 'xenial',195 'codename': 'xenial',
@@ -230,9 +212,6 @@
230 self.mock_in_chroot_subp.side_effect = iter(self.in_chroot_subp_output)212 self.mock_in_chroot_subp.side_effect = iter(self.in_chroot_subp_output)
231 self.mock_chroot.return_value = self.mock_in_chroot213 self.mock_chroot.return_value = self.mock_in_chroot
232214
233 def tearDown(self):
234 shutil.rmtree(self.target)
235
236 def test_uses_old_grub_install_devices_in_cfg(self):215 def test_uses_old_grub_install_devices_in_cfg(self):
237 cfg = {216 cfg = {
238 'grub_install_devices': ['/dev/vdb']217 'grub_install_devices': ['/dev/vdb']
@@ -461,17 +440,13 @@
461 self.mock_in_chroot_subp.call_args_list[0][0])440 self.mock_in_chroot_subp.call_args_list[0][0])
462441
463442
464class TestUbuntuCoreHooks(CurthooksBase):443class TestUbuntuCoreHooks(CiTestCase):
465 def setUp(self):444 def setUp(self):
466 super(TestUbuntuCoreHooks, self).setUp()445 super(TestUbuntuCoreHooks, self).setUp()
467 self.target = None446 self.target = None
468447
469 def tearDown(self):
470 if self.target:
471 shutil.rmtree(self.target)
472
473 def test_target_is_ubuntu_core(self):448 def test_target_is_ubuntu_core(self):
474 self.target = tempfile.mkdtemp()449 self.target = self.tmp_dir()
475 ubuntu_core_path = os.path.join(self.target, 'system-data',450 ubuntu_core_path = os.path.join(self.target, 'system-data',
476 'var/lib/snapd')451 'var/lib/snapd')
477 util.ensure_dir(ubuntu_core_path)452 util.ensure_dir(ubuntu_core_path)
@@ -484,7 +459,7 @@
484 self.assertFalse(is_core)459 self.assertFalse(is_core)
485460
486 def test_target_is_ubuntu_core_noncore_target(self):461 def test_target_is_ubuntu_core_noncore_target(self):
487 self.target = tempfile.mkdtemp()462 self.target = self.tmp_dir()
488 non_core_path = os.path.join(self.target, 'curtin')463 non_core_path = os.path.join(self.target, 'curtin')
489 util.ensure_dir(non_core_path)464 util.ensure_dir(non_core_path)
490 self.assertTrue(os.path.isdir(non_core_path))465 self.assertTrue(os.path.isdir(non_core_path))
@@ -496,7 +471,7 @@
496 @patch('curtin.commands.curthooks.handle_cloudconfig')471 @patch('curtin.commands.curthooks.handle_cloudconfig')
497 def test_curthooks_no_config(self, mock_handle_cc, mock_del_file,472 def test_curthooks_no_config(self, mock_handle_cc, mock_del_file,
498 mock_write_file):473 mock_write_file):
499 self.target = tempfile.mkdtemp()474 self.target = self.tmp_dir()
500 cfg = {}475 cfg = {}
501 curthooks.ubuntu_core_curthooks(cfg, target=self.target)476 curthooks.ubuntu_core_curthooks(cfg, target=self.target)
502 self.assertEqual(len(mock_handle_cc.call_args_list), 0)477 self.assertEqual(len(mock_handle_cc.call_args_list), 0)
@@ -505,7 +480,7 @@
505480
506 @patch('curtin.commands.curthooks.handle_cloudconfig')481 @patch('curtin.commands.curthooks.handle_cloudconfig')
507 def test_curthooks_cloud_config_remove_disabled(self, mock_handle_cc):482 def test_curthooks_cloud_config_remove_disabled(self, mock_handle_cc):
508 self.target = tempfile.mkdtemp()483 self.target = self.tmp_dir()
509 uc_cloud = os.path.join(self.target, 'system-data', 'etc/cloud')484 uc_cloud = os.path.join(self.target, 'system-data', 'etc/cloud')
510 cc_disabled = os.path.join(uc_cloud, 'cloud-init.disabled')485 cc_disabled = os.path.join(uc_cloud, 'cloud-init.disabled')
511 cc_path = os.path.join(uc_cloud, 'cloud.cfg.d')486 cc_path = os.path.join(uc_cloud, 'cloud.cfg.d')
@@ -531,7 +506,7 @@
531 @patch('curtin.commands.curthooks.handle_cloudconfig')506 @patch('curtin.commands.curthooks.handle_cloudconfig')
532 def test_curthooks_cloud_config(self, mock_handle_cc, mock_del_file,507 def test_curthooks_cloud_config(self, mock_handle_cc, mock_del_file,
533 mock_write_file):508 mock_write_file):
534 self.target = tempfile.mkdtemp()509 self.target = self.tmp_dir()
535 cfg = {510 cfg = {
536 'cloudconfig': {511 'cloudconfig': {
537 'file1': {512 'file1': {
@@ -553,7 +528,7 @@
553 @patch('curtin.commands.curthooks.handle_cloudconfig')528 @patch('curtin.commands.curthooks.handle_cloudconfig')
554 def test_curthooks_net_config(self, mock_handle_cc, mock_del_file,529 def test_curthooks_net_config(self, mock_handle_cc, mock_del_file,
555 mock_write_file):530 mock_write_file):
556 self.target = tempfile.mkdtemp()531 self.target = self.tmp_dir()
557 cfg = {532 cfg = {
558 'network': {533 'network': {
559 'version': '1',534 'version': '1',
@@ -603,7 +578,7 @@
603 curthooks.handle_cloudconfig([], base_dir="foobar")578 curthooks.handle_cloudconfig([], base_dir="foobar")
604579
605580
606class TestDetectRequiredPackages(TestCase):581class TestDetectRequiredPackages(CiTestCase):
607 test_config = {582 test_config = {
608 'storage': {583 'storage': {
609 1: {584 1: {
610585
=== modified file 'tests/unittests/test_feature.py'
--- tests/unittests/test_feature.py 2017-07-28 19:22:14 +0000
+++ tests/unittests/test_feature.py 2017-08-03 19:32:06 +0000
@@ -1,9 +1,9 @@
1from unittest import TestCase1from .helpers import CiTestCase
22
3import curtin3import curtin
44
55
6class TestExportsFeatures(TestCase):6class TestExportsFeatures(CiTestCase):
7 def test_has_storage_v1(self):7 def test_has_storage_v1(self):
8 self.assertIn('STORAGE_CONFIG_V1', curtin.FEATURES)8 self.assertIn('STORAGE_CONFIG_V1', curtin.FEATURES)
99
1010
=== modified file 'tests/unittests/test_gpg.py'
--- tests/unittests/test_gpg.py 2017-02-03 16:02:29 +0000
+++ tests/unittests/test_gpg.py 2017-08-03 19:32:06 +0000
@@ -1,12 +1,12 @@
1from unittest import TestCase
2from mock import call, patch1from mock import call, patch
3import textwrap2import textwrap
43
5from curtin import gpg4from curtin import gpg
6from curtin import util5from curtin import util
76from .helpers import CiTestCase
87
9class TestCurtinGpg(TestCase):8
9class TestCurtinGpg(CiTestCase):
1010
11 @patch('curtin.util.subp')11 @patch('curtin.util.subp')
12 def test_export_armour(self, mock_subp):12 def test_export_armour(self, mock_subp):
1313
=== modified file 'tests/unittests/test_make_dname.py'
--- tests/unittests/test_make_dname.py 2016-07-13 17:07:11 +0000
+++ tests/unittests/test_make_dname.py 2017-08-03 19:32:06 +0000
@@ -1,13 +1,13 @@
1from unittest import TestCase
2import mock1import mock
32
4import textwrap3import textwrap
5import uuid4import uuid
65
7from curtin.commands import block_meta6from curtin.commands import block_meta
87from .helpers import CiTestCase
98
10class TestMakeDname(TestCase):9
10class TestMakeDname(CiTestCase):
11 state = {'scratch': '/tmp/null'}11 state = {'scratch': '/tmp/null'}
12 rules_d = '/tmp/null/rules.d'12 rules_d = '/tmp/null/rules.d'
13 rule_file = '/tmp/null/rules.d/{}.rules'13 rule_file = '/tmp/null/rules.d/{}.rules'
1414
=== modified file 'tests/unittests/test_net.py'
--- tests/unittests/test_net.py 2017-07-19 21:54:01 +0000
+++ tests/unittests/test_net.py 2017-08-03 19:32:06 +0000
@@ -1,16 +1,14 @@
1from unittest import TestCase
2import mock1import mock
3import os2import os
4import shutil
5import tempfile
6import yaml3import yaml
74
8from curtin import config, net, util5from curtin import config, net, util
9import curtin.net.network_state as network_state6import curtin.net.network_state as network_state
7from .helpers import CiTestCase
10from textwrap import dedent8from textwrap import dedent
119
1210
13class TestNetParserData(TestCase):11class TestNetParserData(CiTestCase):
1412
15 def test_parse_deb_config_data_ignores_comments(self):13 def test_parse_deb_config_data_ignores_comments(self):
16 contents = dedent("""\14 contents = dedent("""\
@@ -235,13 +233,11 @@
235 }, ifaces)233 }, ifaces)
236234
237235
238class TestNetParser(TestCase):236class TestNetParser(CiTestCase):
239237
240 def setUp(self):238 def setUp(self):
241 self.target = tempfile.mkdtemp()239 super(TestNetParser, self).setUp()
242240 self.target = self.tmp_dir()
243 def tearDown(self):
244 shutil.rmtree(self.target)
245241
246 def make_config(self, path=None, name=None, contents=None,242 def make_config(self, path=None, name=None, contents=None,
247 parse=True):243 parse=True):
@@ -387,9 +383,10 @@
387 self.assertEqual({}, observed)383 self.assertEqual({}, observed)
388384
389385
390class TestNetConfig(TestCase):386class TestNetConfig(CiTestCase):
391 def setUp(self):387 def setUp(self):
392 self.target = tempfile.mkdtemp()388 super(TestNetConfig, self).setUp()
389 self.target = self.tmp_dir()
393 self.config_f = os.path.join(self.target, 'config')390 self.config_f = os.path.join(self.target, 'config')
394 self.config = '''391 self.config = '''
395# YAML example of a simple network config392# YAML example of a simple network config
@@ -436,9 +433,6 @@
436 ns.parse_config()433 ns.parse_config()
437 return ns434 return ns
438435
439 def tearDown(self):
440 shutil.rmtree(self.target)
441
442 def test_parse_net_config_data(self):436 def test_parse_net_config_data(self):
443 ns = self.get_net_state()437 ns = self.get_net_state()
444 net_state_from_cls = ns.network_state438 net_state_from_cls = ns.network_state
445439
=== modified file 'tests/unittests/test_partitioning.py'
--- tests/unittests/test_partitioning.py 2015-08-10 16:34:02 +0000
+++ tests/unittests/test_partitioning.py 2017-08-03 19:32:06 +0000
@@ -1,6 +1,7 @@
1import unittest1from unittest import skip
2import mock2import mock
3import curtin.commands.block_meta3import curtin.commands.block_meta
4from .helpers import CiTestCase
45
5from sys import version_info6from sys import version_info
6if version_info.major == 2:7if version_info.major == 2:
@@ -11,8 +12,8 @@
11parted = None # FIXME: remove these tests entirely. This is here for flake812parted = None # FIXME: remove these tests entirely. This is here for flake8
1213
1314
14@unittest.skip15@skip
15class TestBlock(unittest.TestCase):16class TestBlock(CiTestCase):
16 storage_config = {17 storage_config = {
17 "sda": {"id": "sda", "type": "disk", "ptable": "msdos",18 "sda": {"id": "sda", "type": "disk", "ptable": "msdos",
18 "serial": "DISK_1", "grub_device": "True"},19 "serial": "DISK_1", "grub_device": "True"},
1920
=== modified file 'tests/unittests/test_public.py'
--- tests/unittests/test_public.py 2017-07-28 20:54:10 +0000
+++ tests/unittests/test_public.py 2017-08-03 19:32:06 +0000
@@ -1,4 +1,3 @@
1from unittest import TestCase
21
3from curtin import block2from curtin import block
4from curtin import config3from curtin import config
@@ -6,9 +5,10 @@
6from curtin import util5from curtin import util
76
8from curtin.commands import curthooks7from curtin.commands import curthooks
98from .helpers import CiTestCase
109
11class TestPublicAPI(TestCase):10
11class TestPublicAPI(CiTestCase):
12 """Test entry points known to be used externally.12 """Test entry points known to be used externally.
1313
14 Curtin's only known external library user is the curthooks14 Curtin's only known external library user is the curthooks
1515
=== modified file 'tests/unittests/test_reporter.py'
--- tests/unittests/test_reporter.py 2016-06-22 15:27:45 +0000
+++ tests/unittests/test_reporter.py 2017-08-03 19:32:06 +0000
@@ -21,7 +21,6 @@
21 unicode_literals,21 unicode_literals,
22 )22 )
2323
24from unittest import TestCase
25from mock import patch24from mock import patch
2625
27from curtin.reporter.legacy import (26from curtin.reporter.legacy import (
@@ -39,13 +38,12 @@
39from curtin.reporter import handlers38from curtin.reporter import handlers
40from curtin import url_helper39from curtin import url_helper
41from curtin.reporter import events40from curtin.reporter import events
41from .helpers import CiTestCase
4242
43import os
44import tempfile
45import base6443import base64
4644
4745
48class TestLegacyReporter(TestCase):46class TestLegacyReporter(CiTestCase):
4947
50 @patch('curtin.reporter.legacy.LOG')48 @patch('curtin.reporter.legacy.LOG')
51 def test_load_reporter_logs_empty_cfg(self, mock_LOG):49 def test_load_reporter_logs_empty_cfg(self, mock_LOG):
@@ -72,7 +70,7 @@
72 self.assertTrue(mock_LOG.error.called)70 self.assertTrue(mock_LOG.error.called)
7371
7472
75class TestMAASReporter(TestCase):73class TestMAASReporter(CiTestCase):
76 def test_load_factory_raises_exception_wrong_options(self):74 def test_load_factory_raises_exception_wrong_options(self):
77 options = {'wrong': 'wrong'}75 options = {'wrong': 'wrong'}
78 self.assertRaises(76 self.assertRaises(
@@ -86,7 +84,7 @@
86 self.assertIsInstance(reporter, MAASReporter)84 self.assertIsInstance(reporter, MAASReporter)
8785
8886
89class TestReporter(TestCase):87class TestReporter(CiTestCase):
90 config = {'element1': {'type': 'webhook', 'level': 'INFO',88 config = {'element1': {'type': 'webhook', 'level': 'INFO',
91 'consumer_key': "ck_foo",89 'consumer_key': "ck_foo",
92 'consumer_secret': 'cs_foo',90 'consumer_secret': 'cs_foo',
@@ -175,39 +173,32 @@
175 @patch('curtin.reporter.events.report_event')173 @patch('curtin.reporter.events.report_event')
176 def test_report_finished_post_files(self, mock_report_event):174 def test_report_finished_post_files(self, mock_report_event):
177 test_data = b'abcdefg'175 test_data = b'abcdefg'
178 tmp = tempfile.mkstemp()176 tmpfname = self.tmp_path('testfile')
179 try:177 with open(tmpfname, 'wb') as fp:
180 with open(tmp[1], 'wb') as fp:178 fp.write(test_data)
181 fp.write(test_data)179 events.report_finish_event(self.ev_name, self.ev_desc,
182 events.report_finish_event(self.ev_name, self.ev_desc,180 post_files=[tmpfname])
183 post_files=[tmp[1]])181 event = self._get_reported_event(mock_report_event)
184 event = self._get_reported_event(mock_report_event)182 files = event.as_dict().get('files')
185 files = event.as_dict().get('files')183 self.assertTrue(len(files) == 1)
186 self.assertTrue(len(files) == 1)184 self.assertEqual(files[0].get('path'), tmpfname)
187 self.assertEqual(files[0].get('path'), tmp[1])185 self.assertEqual(files[0].get('encoding'), 'base64')
188 self.assertEqual(files[0].get('encoding'), 'base64')186 self.assertEqual(files[0].get('content'),
189 self.assertEqual(files[0].get('content'),187 base64.b64encode(test_data).decode())
190 base64.b64encode(test_data).decode())
191 finally:
192 os.remove(tmp[1])
193188
194 @patch('curtin.url_helper.OauthUrlHelper')189 @patch('curtin.url_helper.OauthUrlHelper')
195 def test_webhook_handler_post_files(self, mock_url_helper):190 def test_webhook_handler_post_files(self, mock_url_helper):
196 test_data = b'abcdefg'191 test_data = b'abcdefg'
197 tmp = tempfile.mkstemp()192 tmpfname = self.tmp_path('testfile')
198 tmpfname = tmp[1]193 with open(tmpfname, 'wb') as fp:
199 try:194 fp.write(test_data)
200 with open(tmpfname, 'wb') as fp:195 event = events.FinishReportingEvent('test_event_name',
201 fp.write(test_data)196 'test event description',
202 event = events.FinishReportingEvent('test_event_name',197 post_files=[tmpfname],
203 'test event description',198 level='INFO')
204 post_files=[tmpfname],199 webhook_handler = handlers.WebHookHandler('127.0.0.1:8000',
205 level='INFO')200 level='INFO')
206 webhook_handler = handlers.WebHookHandler('127.0.0.1:8000',201 webhook_handler.publish_event(event)
207 level='INFO')202 webhook_handler.oauth_helper.geturl.assert_called_with(
208 webhook_handler.publish_event(event)203 url='127.0.0.1:8000', data=event.as_dict(),
209 webhook_handler.oauth_helper.geturl.assert_called_with(204 headers=webhook_handler.headers, retries=None)
210 url='127.0.0.1:8000', data=event.as_dict(),
211 headers=webhook_handler.headers, retries=None)
212 finally:
213 os.remove(tmpfname)
214205
=== modified file 'tests/unittests/test_util.py'
--- tests/unittests/test_util.py 2017-06-09 20:54:25 +0000
+++ tests/unittests/test_util.py 2017-08-03 19:32:06 +0000
@@ -1,16 +1,14 @@
1from unittest import TestCase, skipIf1from unittest import skipIf
2import mock2import mock
3import os3import os
4import stat4import stat
5import shutil
6import tempfile
7from textwrap import dedent5from textwrap import dedent
86
9from curtin import util7from curtin import util
10from .helpers import simple_mocked_open8from .helpers import CiTestCase, simple_mocked_open
119
1210
13class TestLogTimer(TestCase):11class TestLogTimer(CiTestCase):
14 def test_logger_called(self):12 def test_logger_called(self):
15 data = {}13 data = {}
1614
@@ -24,16 +22,14 @@
24 self.assertIn("mymessage", data['msg'])22 self.assertIn("mymessage", data['msg'])
2523
2624
27class TestDisableDaemons(TestCase):25class TestDisableDaemons(CiTestCase):
28 prcpath = "usr/sbin/policy-rc.d"26 prcpath = "usr/sbin/policy-rc.d"
2927
30 def setUp(self):28 def setUp(self):
31 self.target = tempfile.mkdtemp()29 super(TestDisableDaemons, self).setUp()
30 self.target = self.tmp_dir()
32 self.temp_prc = os.path.join(self.target, self.prcpath)31 self.temp_prc = os.path.join(self.target, self.prcpath)
3332
34 def tearDown(self):
35 shutil.rmtree(self.target)
36
37 def test_disable_daemons_in_root_works(self):33 def test_disable_daemons_in_root_works(self):
38 ret = util.disable_daemons_in_root(self.target)34 ret = util.disable_daemons_in_root(self.target)
39 self.assertTrue(ret)35 self.assertTrue(ret)
@@ -55,8 +51,10 @@
55 self.assertTrue(os.path.exists(self.temp_prc))51 self.assertTrue(os.path.exists(self.temp_prc))
5652
5753
58class TestWhich(TestCase):54class TestWhich(CiTestCase):
55
59 def setUp(self):56 def setUp(self):
57 super(TestWhich, self).setUp()
60 self.orig_is_exe = util.is_exe58 self.orig_is_exe = util.is_exe
61 util.is_exe = self.my_is_exe59 util.is_exe = self.my_is_exe
62 self.orig_path = os.environ.get("PATH")60 self.orig_path = os.environ.get("PATH")
@@ -103,8 +101,10 @@
103 self.assertEqual(found, "/usr/bin2/fuzz")101 self.assertEqual(found, "/usr/bin2/fuzz")
104102
105103
106class TestLsbRelease(TestCase):104class TestLsbRelease(CiTestCase):
105
107 def setUp(self):106 def setUp(self):
107 super(TestLsbRelease, self).setUp()
108 self._reset_cache()108 self._reset_cache()
109109
110 def _reset_cache(self):110 def _reset_cache(self):
@@ -143,7 +143,7 @@
143 self.assertEqual(util.lsb_release(), expected)143 self.assertEqual(util.lsb_release(), expected)
144144
145145
146class TestSubp(TestCase):146class TestSubp(CiTestCase):
147147
148 stdin2err = ['bash', '-c', 'cat >&2']148 stdin2err = ['bash', '-c', 'cat >&2']
149 stdin2out = ['cat']149 stdin2out = ['cat']
@@ -162,10 +162,9 @@
162162
163 def setUp(self):163 def setUp(self):
164 super(TestSubp, self).setUp()164 super(TestSubp, self).setUp()
165 mock_getunsh = mock.patch(165 self.add_patch(
166 "curtin.util._get_unshare_pid_args", return_value=[])166 'curtin.util._get_unshare_pid_args', 'mock_get_unshare_pid_args',
167 self.mock_get_unshare_pid_args = mock_getunsh.start()167 return_value=[])
168 self.addCleanup(mock_getunsh.stop)
169168
170 def printf_cmd(self, *args):169 def printf_cmd(self, *args):
171 # bash's printf supports \xaa. So does /usr/bin/printf170 # bash's printf supports \xaa. So does /usr/bin/printf
@@ -382,19 +381,17 @@
382 self.assertEqual(expected, args[0])381 self.assertEqual(expected, args[0])
383382
384383
385class TestGetUnsharePidArgs(TestCase):384class TestGetUnsharePidArgs(CiTestCase):
386 """Test the internal implementation for when to unshare."""385 """Test the internal implementation for when to unshare."""
387386
388 def setUp(self):387 def setUp(self):
389 super(TestGetUnsharePidArgs, self).setUp()388 super(TestGetUnsharePidArgs, self).setUp()
390 mock_hasunsh = mock.patch(389 self.add_patch('curtin.util._has_unshare_pid', 'mock_has_unshare_pid',
391 "curtin.util._has_unshare_pid", return_value=True)390 return_value=True)
392 self.mock_has_unshare_pid = mock_hasunsh.start()391 # our trusty tox environment with mock 1.0.1 will stack trace
393 self.addCleanup(mock_hasunsh.stop)392 # if autospec is not disabled here.
394 mock_geteuid = mock.patch(393 self.add_patch('curtin.util.os.geteuid', 'mock_geteuid',
395 "curtin.util.os.geteuid", return_value=0)394 autospec=False, return_value=0)
396 self.mock_geteuid = mock_geteuid.start()
397 self.addCleanup(mock_geteuid.stop)
398395
399 def assertOff(self, result):396 def assertOff(self, result):
400 self.assertEqual([], result)397 self.assertEqual([], result)
@@ -455,7 +452,7 @@
455 self.assertOff(util._get_unshare_pid_args("", "/target", 0))452 self.assertOff(util._get_unshare_pid_args("", "/target", 0))
456453
457454
458class TestHuman2Bytes(TestCase):455class TestHuman2Bytes(CiTestCase):
459 GB = 1024 * 1024 * 1024456 GB = 1024 * 1024 * 1024
460 MB = 1024 * 1024457 MB = 1024 * 1024
461458
@@ -509,52 +506,42 @@
509 util.bytes2human(util.human2bytes(size_str)), size_str)506 util.bytes2human(util.human2bytes(size_str)), size_str)
510507
511508
512class TestSetUnExecutable(TestCase):509class TestSetUnExecutable(CiTestCase):
513 tmpf = None510 tmpf = None
514 tmpd = None511 tmpd = None
515512
516 def tearDown(self):513 def setUp(self):
517 if self.tmpf:514 super(CiTestCase, self).setUp()
518 if os.path.exists(self.tmpf):515 self.tmpd = self.tmp_dir()
519 os.unlink(self.tmpf)
520 self.tmpf = None
521 if self.tmpd:
522 shutil.rmtree(self.tmpd)
523 self.tmpd = None
524
525 def tempfile(self, data=None):
526 fp, self.tmpf = tempfile.mkstemp()
527 if data:
528 fp.write(data)
529 os.close(fp)
530 return self.tmpf
531516
532 def test_change_needed_returns_original_mode(self):517 def test_change_needed_returns_original_mode(self):
533 tmpf = self.tempfile()518 tmpf = self.tmp_path('testfile')
519 util.write_file(tmpf, '')
534 os.chmod(tmpf, 0o755)520 os.chmod(tmpf, 0o755)
535 ret = util.set_unexecutable(tmpf)521 ret = util.set_unexecutable(tmpf)
536 self.assertEqual(ret, 0o0755)522 self.assertEqual(ret, 0o0755)
537523
538 def test_no_change_needed_returns_none(self):524 def test_no_change_needed_returns_none(self):
539 tmpf = self.tempfile()525 tmpf = self.tmp_path('testfile')
526 util.write_file(tmpf, '')
540 os.chmod(tmpf, 0o600)527 os.chmod(tmpf, 0o600)
541 ret = util.set_unexecutable(tmpf)528 ret = util.set_unexecutable(tmpf)
542 self.assertEqual(ret, None)529 self.assertEqual(ret, None)
543530
544 def test_change_does_as_expected(self):531 def test_change_does_as_expected(self):
545 tmpf = self.tempfile()532 tmpf = self.tmp_path('testfile')
533 util.write_file(tmpf, '')
546 os.chmod(tmpf, 0o755)534 os.chmod(tmpf, 0o755)
547 ret = util.set_unexecutable(tmpf)535 ret = util.set_unexecutable(tmpf)
548 self.assertEqual(ret, 0o0755)536 self.assertEqual(ret, 0o0755)
549 self.assertEqual(stat.S_IMODE(os.stat(tmpf).st_mode), 0o0644)537 self.assertEqual(stat.S_IMODE(os.stat(tmpf).st_mode), 0o0644)
550538
551 def test_strict_no_exists_raises_exception(self):539 def test_strict_no_exists_raises_exception(self):
552 self.tmpd = tempfile.mkdtemp()
553 bogus = os.path.join(self.tmpd, 'bogus')540 bogus = os.path.join(self.tmpd, 'bogus')
554 self.assertRaises(ValueError, util.set_unexecutable, bogus, True)541 self.assertRaises(ValueError, util.set_unexecutable, bogus, True)
555542
556543
557class TestTargetPath(TestCase):544class TestTargetPath(CiTestCase):
558 def test_target_empty_string(self):545 def test_target_empty_string(self):
559 self.assertEqual("/etc/passwd", util.target_path("", "/etc/passwd"))546 self.assertEqual("/etc/passwd", util.target_path("", "/etc/passwd"))
560547
@@ -596,7 +583,7 @@
596 util.target_path("/target/", "///my/path/"))583 util.target_path("/target/", "///my/path/"))
597584
598585
599class TestRunInChroot(TestCase):586class TestRunInChroot(CiTestCase):
600 """Test the legacy 'RunInChroot'.587 """Test the legacy 'RunInChroot'.
601588
602 The test works by mocking ChrootableTarget's __enter__ to do nothing.589 The test works by mocking ChrootableTarget's __enter__ to do nothing.
@@ -626,7 +613,7 @@
626 m_subp.assert_called_with(cmd, target=target)613 m_subp.assert_called_with(cmd, target=target)
627614
628615
629class TestLoadFile(TestCase):616class TestLoadFile(CiTestCase):
630 """Test utility 'load_file'"""617 """Test utility 'load_file'"""
631618
632 def test_load_file_simple(self):619 def test_load_file_simple(self):
@@ -657,7 +644,7 @@
657 self.assertEqual(loaded_contents, contents)644 self.assertEqual(loaded_contents, contents)
658645
659646
660class TestIpAddress(TestCase):647class TestIpAddress(CiTestCase):
661 """Test utility 'is_valid_ip{,v4,v6}_address'"""648 """Test utility 'is_valid_ip{,v4,v6}_address'"""
662649
663 def test_is_valid_ipv6_address(self):650 def test_is_valid_ipv6_address(self):
@@ -682,10 +669,11 @@
682 '2002:4559:1FE2:0000:0000:0000:4559:1FE2'))669 '2002:4559:1FE2:0000:0000:0000:4559:1FE2'))
683670
684671
685class TestLoadCommandEnvironment(TestCase):672class TestLoadCommandEnvironment(CiTestCase):
673
686 def setUp(self):674 def setUp(self):
687 self.tmpd = tempfile.mkdtemp()675 super(TestLoadCommandEnvironment, self).setUp()
688 self.addCleanup(shutil.rmtree, self.tmpd)676 self.tmpd = self.tmp_dir()
689 all_names = {677 all_names = {
690 'CONFIG',678 'CONFIG',
691 'OUTPUT_FSTAB',679 'OUTPUT_FSTAB',
@@ -728,7 +716,7 @@
728 self.fail("unexpected key error raised: %s" % e)716 self.fail("unexpected key error raised: %s" % e)
729717
730718
731class TestWaitForRemoval(TestCase):719class TestWaitForRemoval(CiTestCase):
732 def test_wait_for_removal_missing_path(self):720 def test_wait_for_removal_missing_path(self):
733 with self.assertRaises(ValueError):721 with self.assertRaises(ValueError):
734 util.wait_for_removal(None)722 util.wait_for_removal(None)
@@ -796,14 +784,12 @@
796 ])784 ])
797785
798786
799class TestGetEFIBootMGR(TestCase):787class TestGetEFIBootMGR(CiTestCase):
800788
801 def setUp(self):789 def setUp(self):
802 super(TestGetEFIBootMGR, self).setUp()790 super(TestGetEFIBootMGR, self).setUp()
803 mock_chroot = mock.patch(791 self.add_patch(
804 'curtin.util.ChrootableTarget', autospec=False)792 'curtin.util.ChrootableTarget', 'mock_chroot', autospec=False)
805 self.mock_chroot = mock_chroot.start()
806 self.addCleanup(mock_chroot.stop)
807 self.mock_in_chroot = mock.MagicMock()793 self.mock_in_chroot = mock.MagicMock()
808 self.mock_in_chroot.__enter__.return_value = self.mock_in_chroot794 self.mock_in_chroot.__enter__.return_value = self.mock_in_chroot
809 self.in_chroot_subp_output = []795 self.in_chroot_subp_output = []
810796
=== modified file 'tests/unittests/test_version.py'
--- tests/unittests/test_version.py 2017-02-06 22:49:33 +0000
+++ tests/unittests/test_version.py 2017-08-03 19:32:06 +0000
@@ -1,28 +1,16 @@
1from unittest import TestCase
2import mock1import mock
3import subprocess2import subprocess
4import os3import os
54
6from curtin import version5from curtin import version
7from curtin import __version__ as old_version6from curtin import __version__ as old_version
87from .helpers import CiTestCase
98
10class CurtinVersionBase(TestCase):9
11 def setUp(self):10class TestCurtinVersion(CiTestCase):
12 super(CurtinVersionBase, self).setUp()11
1312 def setUp(self):
14 def add_patch(self, target, attr):13 super(TestCurtinVersion, self).setUp()
15 """Patches specified target object and sets it as attr on test
16 instance also schedules cleanup"""
17 m = mock.patch(target, autospec=True)
18 p = m.start()
19 self.addCleanup(m.stop)
20 setattr(self, attr, p)
21
22
23class TestCurtinVersion(CurtinVersionBase):
24
25 def setUp(self):
26 self.add_patch('subprocess.check_output', 'mock_subp')14 self.add_patch('subprocess.check_output', 'mock_subp')
27 self.add_patch('os.path', 'mock_path')15 self.add_patch('os.path', 'mock_path')
2816

Subscribers

People subscribed via source and target branches