[virt-tools-list] [virt-bootstrap] [PATCH v4 12/26] tests: Add unit tests for Build_QCOW2_Image

Radostin Stoyanov rstoyanov1 at gmail.com
Thu Aug 3 13:13:10 UTC 2017


---
 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 at gmail.com>
+#
+# 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




More information about the virt-tools-list mailing list