--- tests/test_build_qcow2_image.py | 269 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 269 insertions(+) create mode 100644 tests/test_build_qcow2_image.py diff --git a/tests/test_build_qcow2_image.py b/tests/test_build_qcow2_image.py new file mode 100644 index 0000000..09323c6 --- /dev/null +++ b/tests/test_build_qcow2_image.py @@ -0,0 +1,269 @@ +# Authors: Radostin Stoyanov <rstoyanov1@xxxxxxxxx> +# +# Copyright (C) 2017 Radostin Stoyanov +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + + +""" +Unit tests for functions defined in virtBootstrap.utils.Build_QCOW2_Image +""" + +from tests import unittest +from tests import mock +from tests import utils + + +# pylint: disable=invalid-name +class TestBuild_QCOW2_Image(unittest.TestCase): + """ + Ensures that methods defined in the Build_QCOW2_Image class work + as expected. + """ + + ################################### + # Tests for: __init__() + ################################### + def test_argument_assignment(self): + """ + Ensures that __init__() assigns the arguments' values to instance + variables. + """ + kwargs = { + 'tar_files': ['foo', 'bar'], + 'progress': mock.Mock(), + 'dest': 'dest' + } + + m_guestfs = mock.Mock() + m_guestfs.list_devices.return_value = ['/dev/sda'] + + with mock.patch('virtBootstrap.utils.guestfs') as m_libguestfs: + m_libguestfs.GuestFS.return_value = m_guestfs + + with mock.patch.multiple( + 'virtBootstrap.utils.Build_QCOW2_Image', + create_base_qcow2_layer=mock.DEFAULT, + create_backing_chains=mock.DEFAULT, + ): + src_instance = utils.Build_QCOW2_Image(**kwargs) + + # The length of qcow2 files should be equal to the number of tar files + self.assertEqual( + len(src_instance.qcow2_files), + len(kwargs['tar_files']) + ) + + self.assertIs(src_instance.tar_files, kwargs['tar_files']) + self.assertIs(src_instance.progress, kwargs['progress']) + self.assertIs(src_instance.g, m_guestfs) + + ################################### + # Tests for: create_disk() + ################################### + def test_create_disk(self): + """ + Ensures that create_disk() calls disk_create() and add_drive_opts() + with correct parameters when backing file is not specified. + """ + qcow2_file = 'layer-0.qcow2' + m_self = mock.Mock(spec=utils.Build_QCOW2_Image) + + m_self.g = mock.Mock() + m_self.fmt = utils.DEFAULT_OUTPUT_FORMAT + + utils.Build_QCOW2_Image.create_disk(m_self, qcow2_file) + + m_self.g.disk_create.assert_called_once_with( + qcow2_file, + utils.DEFAULT_OUTPUT_FORMAT, + utils.DEF_BASE_IMAGE_SIZE, + None, # backingfile + None # backingformat + ) + m_self.g.add_drive_opts.assert_called_once_with( + qcow2_file, + False, # readonly + m_self.fmt + ) + + def test_create_disk_with_backing_file(self): + """ + Ensures that create_disk() calls disk_create() and add_drive_opts() + with correct parameters when backing file is specified. + """ + qcow2_file = 'layer-1.qcow2' + backingfile = 'layer-0.qcow2' + + m_self = mock.Mock(spec=utils.Build_QCOW2_Image) + m_self.g = mock.Mock() + m_self.fmt = utils.DEFAULT_OUTPUT_FORMAT + + utils.Build_QCOW2_Image.create_disk( + m_self, + qcow2_file, + backingfile + ) + + m_self.g.disk_create.assert_called_once_with( + qcow2_file, + utils.DEFAULT_OUTPUT_FORMAT, + -1, # size + backingfile, + m_self.fmt # backingformat + ) + m_self.g.add_drive_opts.assert_called_once_with( + qcow2_file, + False, # readonly + m_self.fmt + ) + + ################################### + # Tests for: tar_in() + ################################### + def test_tar_in(self): + """ + Ensures that tar_in() calls mount(), tar_in() and unmount() + in this order and with correct parameters. + """ + tar_file = 'foo.tar' + dev = '/dev/sda' + + m_self = mock.Mock(spec=utils.Build_QCOW2_Image) + m_self.g = mock.Mock() + + with mock.patch( + 'virtBootstrap.utils.get_compression_type' + ) as m_get_compression_type: + utils.Build_QCOW2_Image.tar_in(m_self, tar_file, dev) + + self.assertEqual( + m_self.g.method_calls, + [ + mock.call.mount(dev, '/'), + mock.call.tar_in( + tar_file, + '/', + m_get_compression_type(tar_file), + xattrs=True, + selinux=True, + acls=True + ), + mock.call.umount('/') + ] + ) + + ################################### + # Tests for: create_base_qcow2_layer() + ################################### + def test_create_base_qcow2_layer(self): + """ + Ensures that create_base_qcow2_layer() calls create_disk(), + g.launch(), g.mkfs(), tar_in() and g.shutdown() in this order + and with correct parameters. + """ + tar_file = 'foo.tar' + qcow2_file = 'layer-0.qcow2' + dev = '/dev/sda' + + m_self = mock.Mock(spec=utils.Build_QCOW2_Image) + m_self.g = mock.Mock() + m_self.progress = mock.Mock() + m_self.g.list_devices.return_value = [dev] + + utils.Build_QCOW2_Image.create_base_qcow2_layer( + m_self, + tar_file, + qcow2_file + ) + + self.assertEqual( + m_self.mock_calls, + [ + mock.call.progress( + 'Creating base layer', + logger=utils.logger + ), + mock.call.create_disk(qcow2_file), + mock.call.g.launch(), + mock.call.g.list_devices(), + mock.call.progress( + 'Formating disk image', + logger=utils.logger + ), + mock.call.g.mkfs('ext3', dev), + mock.call.tar_in(tar_file, dev), + mock.call.progress( + 'Extracting content of base layer', + logger=utils.logger + ), + mock.call.g.shutdown() + ] + ) + + ################################### + # Tests for: create_backing_chains() + ################################### + def test_create_backing_chains(self): + """ + Ensures that create_backing_chains() calls with correct parameters: + - create_disk() n-1 times + - g.launch() + - tar_in() n-1 times + + Where n is the number of layers + """ + n = 5 + m_self = mock.Mock(spec=utils.Build_QCOW2_Image) + m_self.progress = mock.Mock() + m_self.g = mock.Mock() + + devices = ['dev%d' % i for i in range(n)] + m_self.g.list_devices.return_value = devices + m_self.qcow2_files = ['bar%d.qcow2' % i for i in range(n)] + m_self.tar_files = ['foo%d.tar' % i for i in range(n)] + + utils.Build_QCOW2_Image.create_backing_chains(m_self) + + expected_calls = [] + + # Append create_disk() calls + for i in range(1, n): + expected_calls.extend(( + mock.call.progress( + 'Creating layer %d' % i, + logger=utils.logger + ), + mock.call.create_disk( + m_self.qcow2_files[i], + backingfile=m_self.qcow2_files[i - 1] + ) + )) + + expected_calls.extend(( + mock.call.g.launch(), + mock.call.g.list_devices() + )) + + # Append tar_in() calls + for i, tar_file in enumerate(m_self.tar_files[1:]): + expected_calls.extend(( + mock.call.progress( + 'Extracting content of layer %d' % (i + 1), + logger=utils.logger + ), + mock.call.tar_in(tar_file, devices[i]) + )) + + self.assertEqual(m_self.method_calls, expected_calls) -- 2.13.3 _______________________________________________ virt-tools-list mailing list virt-tools-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/virt-tools-list