"Fossies" - the Fresh Open Source Software Archive

Member "ironic-16.0.3/ironic/tests/unit/common/test_images.py" (18 Jan 2021, 47223 Bytes) of package /linux/misc/openstack/ironic-16.0.3.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "test_images.py": 16.0.2_vs_16.0.3.

    1 # coding=utf-8
    2 
    3 # Copyright 2013 Hewlett-Packard Development Company, L.P.
    4 # All Rights Reserved.
    5 #
    6 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
    7 #    not use this file except in compliance with the License. You may obtain
    8 #    a copy of the License at
    9 #
   10 #         http://www.apache.org/licenses/LICENSE-2.0
   11 #
   12 #    Unless required by applicable law or agreed to in writing, software
   13 #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
   14 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
   15 #    License for the specific language governing permissions and limitations
   16 #    under the License.
   17 
   18 import builtins
   19 import io
   20 import os
   21 import shutil
   22 from unittest import mock
   23 
   24 from ironic_lib import disk_utils
   25 from ironic_lib import utils as ironic_utils
   26 from oslo_concurrency import processutils
   27 from oslo_config import cfg
   28 
   29 from ironic.common import exception
   30 from ironic.common.glance_service import service_utils as glance_utils
   31 from ironic.common import image_service
   32 from ironic.common import images
   33 from ironic.common import utils
   34 from ironic.tests import base
   35 
   36 CONF = cfg.CONF
   37 
   38 
   39 class IronicImagesTestCase(base.TestCase):
   40 
   41     class FakeImgInfo(object):
   42         pass
   43 
   44     @mock.patch.object(image_service, 'get_image_service', autospec=True)
   45     @mock.patch.object(builtins, 'open', autospec=True)
   46     def test_fetch_image_service(self, open_mock, image_service_mock):
   47         mock_file_handle = mock.MagicMock(spec=io.BytesIO)
   48         mock_file_handle.__enter__.return_value = 'file'
   49         open_mock.return_value = mock_file_handle
   50 
   51         images.fetch('context', 'image_href', 'path')
   52 
   53         open_mock.assert_called_once_with('path', 'wb')
   54         image_service_mock.assert_called_once_with('image_href',
   55                                                    context='context')
   56         image_service_mock.return_value.download.assert_called_once_with(
   57             'image_href', 'file')
   58 
   59     @mock.patch.object(image_service, 'get_image_service', autospec=True)
   60     @mock.patch.object(images, 'image_to_raw', autospec=True)
   61     @mock.patch.object(builtins, 'open', autospec=True)
   62     def test_fetch_image_service_force_raw(self, open_mock, image_to_raw_mock,
   63                                            image_service_mock):
   64         mock_file_handle = mock.MagicMock(spec=io.BytesIO)
   65         mock_file_handle.__enter__.return_value = 'file'
   66         open_mock.return_value = mock_file_handle
   67 
   68         images.fetch('context', 'image_href', 'path', force_raw=True)
   69 
   70         open_mock.assert_called_once_with('path', 'wb')
   71         image_service_mock.return_value.download.assert_called_once_with(
   72             'image_href', 'file')
   73         image_to_raw_mock.assert_called_once_with(
   74             'image_href', 'path', 'path.part')
   75 
   76     @mock.patch.object(disk_utils, 'qemu_img_info', autospec=True)
   77     def test_image_to_raw_no_file_format(self, qemu_img_info_mock):
   78         info = self.FakeImgInfo()
   79         info.file_format = None
   80         qemu_img_info_mock.return_value = info
   81 
   82         e = self.assertRaises(exception.ImageUnacceptable, images.image_to_raw,
   83                               'image_href', 'path', 'path_tmp')
   84         qemu_img_info_mock.assert_called_once_with('path_tmp')
   85         self.assertIn("'qemu-img info' parsing failed.", str(e))
   86 
   87     @mock.patch.object(disk_utils, 'qemu_img_info', autospec=True)
   88     def test_image_to_raw_backing_file_present(self, qemu_img_info_mock):
   89         info = self.FakeImgInfo()
   90         info.file_format = 'raw'
   91         info.backing_file = 'backing_file'
   92         qemu_img_info_mock.return_value = info
   93 
   94         e = self.assertRaises(exception.ImageUnacceptable, images.image_to_raw,
   95                               'image_href', 'path', 'path_tmp')
   96         qemu_img_info_mock.assert_called_once_with('path_tmp')
   97         self.assertIn("fmt=raw backed by: backing_file", str(e))
   98 
   99     @mock.patch.object(os, 'rename', autospec=True)
  100     @mock.patch.object(os, 'unlink', autospec=True)
  101     @mock.patch.object(disk_utils, 'convert_image', autospec=True)
  102     @mock.patch.object(disk_utils, 'qemu_img_info', autospec=True)
  103     def test_image_to_raw(self, qemu_img_info_mock, convert_image_mock,
  104                           unlink_mock, rename_mock):
  105         CONF.set_override('force_raw_images', True)
  106         info = self.FakeImgInfo()
  107         info.file_format = 'fmt'
  108         info.backing_file = None
  109         qemu_img_info_mock.return_value = info
  110 
  111         def convert_side_effect(source, dest, out_format):
  112             info.file_format = 'raw'
  113         convert_image_mock.side_effect = convert_side_effect
  114 
  115         images.image_to_raw('image_href', 'path', 'path_tmp')
  116 
  117         qemu_img_info_mock.assert_has_calls([mock.call('path_tmp'),
  118                                              mock.call('path.converted')])
  119         convert_image_mock.assert_called_once_with('path_tmp',
  120                                                    'path.converted', 'raw')
  121         unlink_mock.assert_called_once_with('path_tmp')
  122         rename_mock.assert_called_once_with('path.converted', 'path')
  123 
  124     @mock.patch.object(os, 'unlink', autospec=True)
  125     @mock.patch.object(disk_utils, 'convert_image', autospec=True)
  126     @mock.patch.object(disk_utils, 'qemu_img_info', autospec=True)
  127     def test_image_to_raw_not_raw_after_conversion(self, qemu_img_info_mock,
  128                                                    convert_image_mock,
  129                                                    unlink_mock):
  130         CONF.set_override('force_raw_images', True)
  131         info = self.FakeImgInfo()
  132         info.file_format = 'fmt'
  133         info.backing_file = None
  134         qemu_img_info_mock.return_value = info
  135 
  136         self.assertRaises(exception.ImageConvertFailed, images.image_to_raw,
  137                           'image_href', 'path', 'path_tmp')
  138         qemu_img_info_mock.assert_has_calls([mock.call('path_tmp'),
  139                                              mock.call('path.converted')])
  140         convert_image_mock.assert_called_once_with('path_tmp',
  141                                                    'path.converted', 'raw')
  142         unlink_mock.assert_called_once_with('path_tmp')
  143 
  144     @mock.patch.object(os, 'rename', autospec=True)
  145     @mock.patch.object(disk_utils, 'qemu_img_info', autospec=True)
  146     def test_image_to_raw_already_raw_format(self, qemu_img_info_mock,
  147                                              rename_mock):
  148         info = self.FakeImgInfo()
  149         info.file_format = 'raw'
  150         info.backing_file = None
  151         qemu_img_info_mock.return_value = info
  152 
  153         images.image_to_raw('image_href', 'path', 'path_tmp')
  154 
  155         qemu_img_info_mock.assert_called_once_with('path_tmp')
  156         rename_mock.assert_called_once_with('path_tmp', 'path')
  157 
  158     @mock.patch.object(image_service, 'get_image_service', autospec=True)
  159     def test_image_show_no_image_service(self, image_service_mock):
  160         images.image_show('context', 'image_href')
  161         image_service_mock.assert_called_once_with('image_href',
  162                                                    context='context')
  163         image_service_mock.return_value.show.assert_called_once_with(
  164             'image_href')
  165 
  166     def test_image_show_image_service(self):
  167         image_service_mock = mock.MagicMock()
  168         images.image_show('context', 'image_href', image_service_mock)
  169         image_service_mock.show.assert_called_once_with('image_href')
  170 
  171     @mock.patch.object(images, 'image_show', autospec=True)
  172     def test_download_size(self, show_mock):
  173         show_mock.return_value = {'size': 123456}
  174         size = images.download_size('context', 'image_href', 'image_service')
  175         self.assertEqual(123456, size)
  176         show_mock.assert_called_once_with('context', 'image_href',
  177                                           'image_service')
  178 
  179     @mock.patch.object(disk_utils, 'qemu_img_info', autospec=True)
  180     def test_converted_size(self, qemu_img_info_mock):
  181         info = self.FakeImgInfo()
  182         info.virtual_size = 1
  183         qemu_img_info_mock.return_value = info
  184         size = images.converted_size('path')
  185         qemu_img_info_mock.assert_called_once_with('path')
  186         self.assertEqual(1, size)
  187 
  188     @mock.patch.object(images, 'get_image_properties', autospec=True)
  189     @mock.patch.object(glance_utils, 'is_glance_image', autospec=True)
  190     def test_is_whole_disk_image_no_img_src(self, mock_igi, mock_gip):
  191         instance_info = {'image_source': ''}
  192         iwdi = images.is_whole_disk_image('context', instance_info)
  193         self.assertIsNone(iwdi)
  194         self.assertFalse(mock_igi.called)
  195         self.assertFalse(mock_gip.called)
  196 
  197     @mock.patch.object(images, 'get_image_properties', autospec=True)
  198     @mock.patch.object(glance_utils, 'is_glance_image', autospec=True)
  199     def test_is_whole_disk_image_partition_image(self, mock_igi, mock_gip):
  200         mock_igi.return_value = True
  201         mock_gip.return_value = {'kernel_id': 'kernel',
  202                                  'ramdisk_id': 'ramdisk'}
  203         instance_info = {'image_source': 'glance://partition_image'}
  204         image_source = instance_info['image_source']
  205         is_whole_disk_image = images.is_whole_disk_image('context',
  206                                                          instance_info)
  207         self.assertFalse(is_whole_disk_image)
  208         mock_igi.assert_called_once_with(image_source)
  209         mock_gip.assert_called_once_with('context', image_source)
  210 
  211     @mock.patch.object(images, 'get_image_properties', autospec=True)
  212     @mock.patch.object(glance_utils, 'is_glance_image', autospec=True)
  213     def test_is_whole_disk_image_whole_disk_image(self, mock_igi, mock_gip):
  214         mock_igi.return_value = True
  215         mock_gip.return_value = {}
  216         instance_info = {'image_source': 'glance://whole_disk_image'}
  217         image_source = instance_info['image_source']
  218         is_whole_disk_image = images.is_whole_disk_image('context',
  219                                                          instance_info)
  220         self.assertTrue(is_whole_disk_image)
  221         mock_igi.assert_called_once_with(image_source)
  222         mock_gip.assert_called_once_with('context', image_source)
  223 
  224     @mock.patch.object(images, 'get_image_properties', autospec=True)
  225     @mock.patch.object(glance_utils, 'is_glance_image', autospec=True)
  226     def test_is_whole_disk_image_partition_non_glance(self, mock_igi,
  227                                                       mock_gip):
  228         mock_igi.return_value = False
  229         instance_info = {'image_source': 'partition_image',
  230                          'kernel': 'kernel',
  231                          'ramdisk': 'ramdisk'}
  232         is_whole_disk_image = images.is_whole_disk_image('context',
  233                                                          instance_info)
  234         self.assertFalse(is_whole_disk_image)
  235         self.assertFalse(mock_gip.called)
  236         mock_igi.assert_called_once_with(instance_info['image_source'])
  237 
  238     @mock.patch.object(images, 'get_image_properties', autospec=True)
  239     @mock.patch.object(glance_utils, 'is_glance_image', autospec=True)
  240     def test_is_whole_disk_image_whole_disk_non_glance(self, mock_igi,
  241                                                        mock_gip):
  242         mock_igi.return_value = False
  243         instance_info = {'image_source': 'whole_disk_image'}
  244         is_whole_disk_image = images.is_whole_disk_image('context',
  245                                                          instance_info)
  246         self.assertTrue(is_whole_disk_image)
  247         self.assertFalse(mock_gip.called)
  248         mock_igi.assert_called_once_with(instance_info['image_source'])
  249 
  250 
  251 class FsImageTestCase(base.TestCase):
  252 
  253     @mock.patch.object(builtins, 'open', autospec=True)
  254     @mock.patch.object(shutil, 'copyfile', autospec=True)
  255     @mock.patch.object(os, 'makedirs', autospec=True)
  256     def test__create_root_fs(self, mkdir_mock, cp_mock, open_mock):
  257         files_info = {
  258             'a1': 'b1',
  259             'a2': 'b2',
  260             'a3': 'sub_dir/b3',
  261             b'a4': 'b4'}
  262 
  263         images._create_root_fs('root_dir', files_info)
  264 
  265         cp_mock.assert_any_call('a1', 'root_dir/b1')
  266         cp_mock.assert_any_call('a2', 'root_dir/b2')
  267         cp_mock.assert_any_call('a3', 'root_dir/sub_dir/b3')
  268 
  269         open_mock.assert_called_once_with('root_dir/b4', 'wb')
  270         fp = open_mock.return_value.__enter__.return_value
  271         fp.write.assert_called_once_with(b'a4')
  272 
  273         mkdir_mock.assert_any_call('root_dir', exist_ok=True)
  274         mkdir_mock.assert_any_call('root_dir/sub_dir', exist_ok=True)
  275 
  276     @mock.patch.object(images, '_create_root_fs', autospec=True)
  277     @mock.patch.object(utils, 'tempdir', autospec=True)
  278     @mock.patch.object(utils, 'write_to_file', autospec=True)
  279     @mock.patch.object(ironic_utils, 'dd', autospec=True)
  280     @mock.patch.object(utils, 'umount', autospec=True)
  281     @mock.patch.object(utils, 'mount', autospec=True)
  282     @mock.patch.object(ironic_utils, 'mkfs', autospec=True)
  283     def test_create_vfat_image(
  284             self, mkfs_mock, mount_mock, umount_mock, dd_mock, write_mock,
  285             tempdir_mock, create_root_fs_mock):
  286 
  287         mock_file_handle = mock.MagicMock(spec=io.BytesIO)
  288         mock_file_handle.__enter__.return_value = 'tempdir'
  289         tempdir_mock.return_value = mock_file_handle
  290 
  291         parameters = {'p1': 'v1'}
  292         files_info = {'a': 'b'}
  293         images.create_vfat_image('tgt_file', parameters=parameters,
  294                                  files_info=files_info, parameters_file='qwe',
  295                                  fs_size_kib=1000)
  296 
  297         dd_mock.assert_called_once_with('/dev/zero',
  298                                         'tgt_file',
  299                                         'count=1',
  300                                         'bs=1000KiB')
  301 
  302         mkfs_mock.assert_called_once_with('vfat', 'tgt_file',
  303                                           label="ir-vfd-dev")
  304         mount_mock.assert_called_once_with('tgt_file', 'tempdir',
  305                                            '-o', 'umask=0')
  306 
  307         parameters_file_path = os.path.join('tempdir', 'qwe')
  308         write_mock.assert_called_once_with(parameters_file_path, 'p1=v1')
  309         create_root_fs_mock.assert_called_once_with('tempdir', files_info)
  310         umount_mock.assert_called_once_with('tempdir')
  311 
  312     @mock.patch.object(images, '_create_root_fs', autospec=True)
  313     @mock.patch.object(utils, 'tempdir', autospec=True)
  314     @mock.patch.object(ironic_utils, 'dd', autospec=True)
  315     @mock.patch.object(utils, 'umount', autospec=True)
  316     @mock.patch.object(utils, 'mount', autospec=True)
  317     @mock.patch.object(ironic_utils, 'mkfs', autospec=True)
  318     def test_create_vfat_image_always_umount(
  319             self, mkfs_mock, mount_mock, umount_mock, dd_mock,
  320             tempdir_mock, create_root_fs_mock):
  321 
  322         mock_file_handle = mock.MagicMock(spec=io.BytesIO)
  323         mock_file_handle.__enter__.return_value = 'tempdir'
  324         tempdir_mock.return_value = mock_file_handle
  325         files_info = {'a': 'b'}
  326         create_root_fs_mock.side_effect = OSError()
  327         self.assertRaises(exception.ImageCreationFailed,
  328                           images.create_vfat_image, 'tgt_file',
  329                           files_info=files_info)
  330 
  331         umount_mock.assert_called_once_with('tempdir')
  332 
  333     @mock.patch.object(ironic_utils, 'dd', autospec=True)
  334     def test_create_vfat_image_dd_fails(self, dd_mock):
  335 
  336         dd_mock.side_effect = processutils.ProcessExecutionError
  337         self.assertRaises(exception.ImageCreationFailed,
  338                           images.create_vfat_image, 'tgt_file')
  339 
  340     @mock.patch.object(utils, 'tempdir', autospec=True)
  341     @mock.patch.object(ironic_utils, 'dd', autospec=True)
  342     @mock.patch.object(ironic_utils, 'mkfs', autospec=True)
  343     def test_create_vfat_image_mkfs_fails(self, mkfs_mock, dd_mock,
  344                                           tempdir_mock):
  345 
  346         mock_file_handle = mock.MagicMock(spec=io.BytesIO)
  347         mock_file_handle.__enter__.return_value = 'tempdir'
  348         tempdir_mock.return_value = mock_file_handle
  349 
  350         mkfs_mock.side_effect = processutils.ProcessExecutionError
  351         self.assertRaises(exception.ImageCreationFailed,
  352                           images.create_vfat_image, 'tgt_file')
  353 
  354     @mock.patch.object(images, '_create_root_fs', autospec=True)
  355     @mock.patch.object(utils, 'tempdir', autospec=True)
  356     @mock.patch.object(ironic_utils, 'dd', autospec=True)
  357     @mock.patch.object(utils, 'umount', autospec=True)
  358     @mock.patch.object(utils, 'mount', autospec=True)
  359     @mock.patch.object(ironic_utils, 'mkfs', autospec=True)
  360     def test_create_vfat_image_umount_fails(
  361             self, mkfs_mock, mount_mock, umount_mock, dd_mock,
  362             tempdir_mock, create_root_fs_mock):
  363 
  364         mock_file_handle = mock.MagicMock(spec=io.BytesIO)
  365         mock_file_handle.__enter__.return_value = 'tempdir'
  366         tempdir_mock.return_value = mock_file_handle
  367         umount_mock.side_effect = processutils.ProcessExecutionError
  368 
  369         self.assertRaises(exception.ImageCreationFailed,
  370                           images.create_vfat_image, 'tgt_file')
  371 
  372     @mock.patch.object(utils, 'umount', autospec=True)
  373     def test__umount_without_raise(self, umount_mock):
  374 
  375         umount_mock.side_effect = processutils.ProcessExecutionError
  376         images._umount_without_raise('mountdir')
  377         umount_mock.assert_called_once_with('mountdir')
  378 
  379     def test__generate_isolinux_cfg(self):
  380 
  381         kernel_params = ['key1=value1', 'key2']
  382         options = {'kernel': '/vmlinuz', 'ramdisk': '/initrd'}
  383         expected_cfg = ("default boot\n"
  384                         "\n"
  385                         "label boot\n"
  386                         "kernel /vmlinuz\n"
  387                         "append initrd=/initrd text key1=value1 key2 --")
  388         cfg = images._generate_cfg(kernel_params,
  389                                    CONF.isolinux_config_template,
  390                                    options)
  391         self.assertEqual(expected_cfg, cfg)
  392 
  393     def test__generate_grub_cfg(self):
  394         kernel_params = ['key1=value1', 'key2']
  395         options = {'linux': '/vmlinuz', 'initrd': '/initrd'}
  396         expected_cfg = ("set default=0\n"
  397                         "set timeout=5\n"
  398                         "set hidden_timeout_quiet=false\n"
  399                         "\n"
  400                         "menuentry \"boot_partition\" {\n"
  401                         "linuxefi /vmlinuz key1=value1 key2 --\n"
  402                         "initrdefi /initrd\n"
  403                         "}")
  404 
  405         cfg = images._generate_cfg(kernel_params,
  406                                    CONF.grub_config_template,
  407                                    options)
  408         self.assertEqual(expected_cfg, cfg)
  409 
  410     @mock.patch.object(os.path, 'relpath', autospec=True)
  411     @mock.patch.object(os, 'walk', autospec=True)
  412     @mock.patch.object(utils, 'mount', autospec=True)
  413     def test__mount_deploy_iso(self, mount_mock,
  414                                walk_mock, relpath_mock):
  415         walk_mock.return_value = [('/tmpdir1/EFI/ubuntu', [], ['grub.cfg']),
  416                                   ('/tmpdir1/isolinux', [],
  417                                    ['efiboot.img', 'isolinux.bin',
  418                                     'isolinux.cfg'])]
  419         relpath_mock.side_effect = ['EFI/ubuntu/grub.cfg',
  420                                     'isolinux/efiboot.img']
  421 
  422         images._mount_deploy_iso('path/to/deployiso', 'tmpdir1')
  423         mount_mock.assert_called_once_with('path/to/deployiso',
  424                                            'tmpdir1', '-o', 'loop')
  425         walk_mock.assert_called_once_with('tmpdir1')
  426 
  427     @mock.patch.object(images, '_umount_without_raise', autospec=True)
  428     @mock.patch.object(os.path, 'relpath', autospec=True)
  429     @mock.patch.object(os, 'walk', autospec=True)
  430     @mock.patch.object(utils, 'mount', autospec=True)
  431     def test__mount_deploy_iso_fail_no_esp_imageimg(self, mount_mock,
  432                                                     walk_mock, relpath_mock,
  433                                                     umount_mock):
  434         walk_mock.return_value = [('/tmpdir1/EFI/ubuntu', [], ['grub.cfg']),
  435                                   ('/tmpdir1/isolinux', [],
  436                                    ['isolinux.bin', 'isolinux.cfg'])]
  437         relpath_mock.side_effect = 'EFI/ubuntu/grub.cfg'
  438 
  439         self.assertRaises(exception.ImageCreationFailed,
  440                           images._mount_deploy_iso,
  441                           'path/to/deployiso', 'tmpdir1')
  442         mount_mock.assert_called_once_with('path/to/deployiso',
  443                                            'tmpdir1', '-o', 'loop')
  444         walk_mock.assert_called_once_with('tmpdir1')
  445         umount_mock.assert_called_once_with('tmpdir1')
  446 
  447     @mock.patch.object(images, '_umount_without_raise', autospec=True)
  448     @mock.patch.object(os.path, 'relpath', autospec=True)
  449     @mock.patch.object(os, 'walk', autospec=True)
  450     @mock.patch.object(utils, 'mount', autospec=True)
  451     def test__mount_deploy_iso_fails_no_grub_cfg(self, mount_mock,
  452                                                  walk_mock, relpath_mock,
  453                                                  umount_mock):
  454         walk_mock.return_value = [('/tmpdir1/EFI/ubuntu', '', []),
  455                                   ('/tmpdir1/isolinux', '',
  456                                    ['efiboot.img', 'isolinux.bin',
  457                                     'isolinux.cfg'])]
  458         relpath_mock.side_effect = 'isolinux/efiboot.img'
  459 
  460         self.assertRaises(exception.ImageCreationFailed,
  461                           images._mount_deploy_iso,
  462                           'path/to/deployiso', 'tmpdir1')
  463         mount_mock.assert_called_once_with('path/to/deployiso',
  464                                            'tmpdir1', '-o', 'loop')
  465         walk_mock.assert_called_once_with('tmpdir1')
  466         umount_mock.assert_called_once_with('tmpdir1')
  467 
  468     @mock.patch.object(utils, 'mount', autospec=True)
  469     def test__mount_deploy_iso_fail_with_ExecutionError(self, mount_mock):
  470         mount_mock.side_effect = processutils.ProcessExecutionError
  471         self.assertRaises(exception.ImageCreationFailed,
  472                           images._mount_deploy_iso,
  473                           'path/to/deployiso', 'tmpdir1')
  474 
  475     @mock.patch.object(images, '_umount_without_raise', autospec=True)
  476     @mock.patch.object(images, '_create_root_fs', autospec=True)
  477     @mock.patch.object(utils, 'write_to_file', autospec=True)
  478     @mock.patch.object(utils, 'execute', autospec=True)
  479     @mock.patch.object(images, '_mount_deploy_iso', autospec=True)
  480     @mock.patch.object(utils, 'tempdir', autospec=True)
  481     @mock.patch.object(images, '_generate_cfg', autospec=True)
  482     def test_create_esp_image_for_uefi_with_deploy_iso(
  483             self, gen_cfg_mock, tempdir_mock, mount_mock, execute_mock,
  484             write_to_file_mock, create_root_fs_mock, umount_mock):
  485 
  486         files_info = {
  487             'path/to/kernel': 'vmlinuz',
  488             'path/to/ramdisk': 'initrd',
  489             'sourceabspath/to/efiboot.img': 'path/to/efiboot.img',
  490             'path/to/grub': 'relpath/to/grub.cfg'
  491         }
  492 
  493         grubcfg = "grubcfg"
  494         grub_file = 'tmpdir/relpath/to/grub.cfg'
  495         gen_cfg_mock.side_effect = (grubcfg,)
  496 
  497         params = ['a=b', 'c']
  498         grub_options = {'linux': '/vmlinuz',
  499                         'initrd': '/initrd'}
  500 
  501         uefi_path_info = {
  502             'sourceabspath/to/efiboot.img': 'path/to/efiboot.img',
  503             'path/to/grub': 'relpath/to/grub.cfg'}
  504         grub_rel_path = 'relpath/to/grub.cfg'
  505         e_img_rel_path = 'path/to/efiboot.img'
  506         mock_file_handle = mock.MagicMock(spec=io.BytesIO)
  507         mock_file_handle.__enter__.return_value = 'tmpdir'
  508         mock_file_handle1 = mock.MagicMock(spec=io.BytesIO)
  509         mock_file_handle1.__enter__.return_value = 'mountdir'
  510         tempdir_mock.side_effect = mock_file_handle, mock_file_handle1
  511         mount_mock.return_value = (uefi_path_info,
  512                                    e_img_rel_path, grub_rel_path)
  513 
  514         images.create_esp_image_for_uefi('tgt_file',
  515                                          'path/to/kernel',
  516                                          'path/to/ramdisk',
  517                                          deploy_iso='path/to/deploy_iso',
  518                                          kernel_params=params)
  519         mount_mock.assert_called_once_with('path/to/deploy_iso', 'mountdir')
  520         create_root_fs_mock.assert_called_once_with('tmpdir', files_info)
  521         gen_cfg_mock.assert_any_call(params, CONF.grub_config_template,
  522                                      grub_options)
  523         write_to_file_mock.assert_any_call(grub_file, grubcfg)
  524         execute_mock.assert_called_once_with(
  525             'mkisofs', '-r', '-V', 'VMEDIA_BOOT_ISO', '-l', '-e',
  526             'path/to/efiboot.img', '-no-emul-boot', '-o', 'tgt_file', 'tmpdir')
  527         umount_mock.assert_called_once_with('mountdir')
  528 
  529     @mock.patch.object(utils, 'write_to_file', autospec=True)
  530     @mock.patch.object(images, '_create_root_fs', autospec=True)
  531     @mock.patch.object(utils, 'execute', autospec=True)
  532     @mock.patch.object(utils, 'tempdir', autospec=True)
  533     @mock.patch.object(images, '_generate_cfg', autospec=True)
  534     def test_create_esp_image_for_uefi_with_esp_image(
  535             self, gen_cfg_mock, tempdir_mock, execute_mock,
  536             create_root_fs_mock, write_to_file_mock):
  537 
  538         files_info = {
  539             'path/to/kernel': 'vmlinuz',
  540             'path/to/ramdisk': 'initrd',
  541             'sourceabspath/to/efiboot.img': 'boot/grub/efiboot.img',
  542             '/dev/null': 'EFI/MYBOOT/grub.cfg',
  543         }
  544 
  545         grub_cfg_file = '/EFI/MYBOOT/grub.cfg'
  546         CONF.set_override('grub_config_path', grub_cfg_file)
  547         grubcfg = "grubcfg"
  548         gen_cfg_mock.side_effect = (grubcfg,)
  549 
  550         params = ['a=b', 'c']
  551         grub_options = {'linux': '/vmlinuz',
  552                         'initrd': '/initrd'}
  553 
  554         mock_file_handle = mock.MagicMock(spec=io.BytesIO)
  555         mock_file_handle.__enter__.return_value = 'tmpdir'
  556         mock_file_handle1 = mock.MagicMock(spec=io.BytesIO)
  557         mock_file_handle1.__enter__.return_value = 'mountdir'
  558         tempdir_mock.side_effect = mock_file_handle, mock_file_handle1
  559         mountdir_grub_cfg_path = 'tmpdir' + grub_cfg_file
  560 
  561         images.create_esp_image_for_uefi(
  562             'tgt_file', 'path/to/kernel', 'path/to/ramdisk',
  563             esp_image='sourceabspath/to/efiboot.img',
  564             kernel_params=params)
  565         create_root_fs_mock.assert_called_once_with('tmpdir', files_info)
  566         gen_cfg_mock.assert_any_call(params, CONF.grub_config_template,
  567                                      grub_options)
  568         write_to_file_mock.assert_any_call(mountdir_grub_cfg_path, grubcfg)
  569         execute_mock.assert_called_once_with(
  570             'mkisofs', '-r', '-V', 'VMEDIA_BOOT_ISO', '-l', '-e',
  571             'boot/grub/efiboot.img', '-no-emul-boot', '-o', 'tgt_file',
  572             'tmpdir')
  573 
  574     @mock.patch.object(images, '_create_root_fs', autospec=True)
  575     @mock.patch.object(utils, 'write_to_file', autospec=True)
  576     @mock.patch.object(utils, 'tempdir', autospec=True)
  577     @mock.patch.object(utils, 'execute', autospec=True)
  578     @mock.patch.object(images, '_generate_cfg', autospec=True)
  579     def _test_create_isolinux_image_for_bios(
  580             self, gen_cfg_mock, execute_mock, tempdir_mock,
  581             write_to_file_mock, create_root_fs_mock, ldlinux_path=None,
  582             inject_files=None):
  583 
  584         mock_file_handle = mock.MagicMock(spec=io.BytesIO)
  585         mock_file_handle.__enter__.return_value = 'tmpdir'
  586         tempdir_mock.return_value = mock_file_handle
  587 
  588         cfg = "cfg"
  589         cfg_file = 'tmpdir/isolinux/isolinux.cfg'
  590         gen_cfg_mock.return_value = cfg
  591 
  592         params = ['a=b', 'c']
  593         isolinux_options = {'kernel': '/vmlinuz',
  594                             'ramdisk': '/initrd'}
  595 
  596         images.create_isolinux_image_for_bios('tgt_file',
  597                                               'path/to/kernel',
  598                                               'path/to/ramdisk',
  599                                               kernel_params=params,
  600                                               inject_files=inject_files)
  601 
  602         files_info = {
  603             'path/to/kernel': 'vmlinuz',
  604             'path/to/ramdisk': 'initrd',
  605             CONF.isolinux_bin: 'isolinux/isolinux.bin'
  606         }
  607         if inject_files:
  608             files_info.update(inject_files)
  609         if ldlinux_path:
  610             files_info[ldlinux_path] = 'isolinux/ldlinux.c32'
  611         create_root_fs_mock.assert_called_once_with('tmpdir', files_info)
  612         gen_cfg_mock.assert_called_once_with(params,
  613                                              CONF.isolinux_config_template,
  614                                              isolinux_options)
  615         write_to_file_mock.assert_called_once_with(cfg_file, cfg)
  616         execute_mock.assert_called_once_with(
  617             'mkisofs', '-r', '-V',
  618             "VMEDIA_BOOT_ISO", '-cache-inodes', '-J', '-l',
  619             '-no-emul-boot', '-boot-load-size',
  620             '4', '-boot-info-table', '-b', 'isolinux/isolinux.bin',
  621             '-o', 'tgt_file', 'tmpdir')
  622 
  623     @mock.patch.object(os.path, 'isfile', autospec=True)
  624     def test_create_isolinux_image_for_bios(self, mock_isfile):
  625         mock_isfile.return_value = False
  626         self._test_create_isolinux_image_for_bios()
  627 
  628     def test_create_isolinux_image_for_bios_conf_ldlinux(self):
  629         CONF.set_override('ldlinux_c32', 'path/to/ldlinux.c32')
  630         self._test_create_isolinux_image_for_bios(
  631             ldlinux_path='path/to/ldlinux.c32')
  632 
  633     @mock.patch.object(os.path, 'isfile', autospec=True)
  634     def test_create_isolinux_image_for_bios_default_ldlinux(self, mock_isfile):
  635         mock_isfile.side_effect = [False, True]
  636         self._test_create_isolinux_image_for_bios(
  637             ldlinux_path='/usr/share/syslinux/ldlinux.c32')
  638 
  639     @mock.patch.object(os.path, 'isfile', autospec=True)
  640     def test_create_isolinux_image_for_bios_inject_files(self, mock_isfile):
  641         mock_isfile.return_value = False
  642         self._test_create_isolinux_image_for_bios(
  643             inject_files={'/source': 'target'})
  644 
  645     @mock.patch.object(images, '_umount_without_raise', autospec=True)
  646     @mock.patch.object(images, '_create_root_fs', autospec=True)
  647     @mock.patch.object(utils, 'tempdir', autospec=True)
  648     @mock.patch.object(utils, 'execute', autospec=True)
  649     @mock.patch.object(os, 'walk', autospec=True)
  650     def test_create_esp_image_uefi_rootfs_fails(
  651             self, walk_mock, utils_mock, tempdir_mock,
  652             create_root_fs_mock, umount_mock):
  653 
  654         mock_file_handle = mock.MagicMock(spec=io.BytesIO)
  655         mock_file_handle.__enter__.return_value = 'tmpdir'
  656         mock_file_handle1 = mock.MagicMock(spec=io.BytesIO)
  657         mock_file_handle1.__enter__.return_value = 'mountdir'
  658         tempdir_mock.side_effect = mock_file_handle, mock_file_handle1
  659         create_root_fs_mock.side_effect = IOError
  660 
  661         self.assertRaises(exception.ImageCreationFailed,
  662                           images.create_esp_image_for_uefi,
  663                           'tgt_file',
  664                           'path/to/kernel',
  665                           'path/to/ramdisk',
  666                           deploy_iso='path/to/deployiso')
  667         umount_mock.assert_called_once_with('mountdir')
  668 
  669     @mock.patch.object(images, '_create_root_fs', autospec=True)
  670     @mock.patch.object(utils, 'tempdir', autospec=True)
  671     @mock.patch.object(utils, 'execute', autospec=True)
  672     @mock.patch.object(os, 'walk', autospec=True)
  673     def test_create_isolinux_image_bios_rootfs_fails(self, walk_mock,
  674                                                      utils_mock,
  675                                                      tempdir_mock,
  676                                                      create_root_fs_mock):
  677         create_root_fs_mock.side_effect = IOError
  678 
  679         self.assertRaises(exception.ImageCreationFailed,
  680                           images.create_isolinux_image_for_bios,
  681                           'tgt_file', 'path/to/kernel',
  682                           'path/to/ramdisk')
  683 
  684     @mock.patch.object(images, '_umount_without_raise', autospec=True)
  685     @mock.patch.object(images, '_create_root_fs', autospec=True)
  686     @mock.patch.object(utils, 'write_to_file', autospec=True)
  687     @mock.patch.object(utils, 'tempdir', autospec=True)
  688     @mock.patch.object(utils, 'execute', autospec=True)
  689     @mock.patch.object(images, '_mount_deploy_iso', autospec=True)
  690     @mock.patch.object(images, '_generate_cfg', autospec=True)
  691     def test_create_esp_image_mkisofs_fails(
  692             self, gen_cfg_mock, mount_mock, utils_mock, tempdir_mock,
  693             write_to_file_mock, create_root_fs_mock, umount_mock):
  694         mock_file_handle = mock.MagicMock(spec=io.BytesIO)
  695         mock_file_handle.__enter__.return_value = 'tmpdir'
  696         mock_file_handle1 = mock.MagicMock(spec=io.BytesIO)
  697         mock_file_handle1.__enter__.return_value = 'mountdir'
  698         tempdir_mock.side_effect = mock_file_handle, mock_file_handle1
  699         mount_mock.return_value = ({'a': 'a'}, 'b', 'c')
  700         utils_mock.side_effect = processutils.ProcessExecutionError
  701 
  702         self.assertRaises(exception.ImageCreationFailed,
  703                           images.create_esp_image_for_uefi,
  704                           'tgt_file',
  705                           'path/to/kernel',
  706                           'path/to/ramdisk',
  707                           deploy_iso='path/to/deployiso')
  708         umount_mock.assert_called_once_with('mountdir')
  709 
  710     @mock.patch.object(images, '_create_root_fs', autospec=True)
  711     @mock.patch.object(utils, 'write_to_file', autospec=True)
  712     @mock.patch.object(utils, 'tempdir', autospec=True)
  713     @mock.patch.object(utils, 'execute', autospec=True)
  714     @mock.patch.object(images, '_generate_cfg', autospec=True)
  715     def test_create_isolinux_image_bios_mkisofs_fails(self,
  716                                                       gen_cfg_mock,
  717                                                       utils_mock,
  718                                                       tempdir_mock,
  719                                                       write_to_file_mock,
  720                                                       create_root_fs_mock):
  721         mock_file_handle = mock.MagicMock(spec=io.BytesIO)
  722         mock_file_handle.__enter__.return_value = 'tmpdir'
  723         tempdir_mock.return_value = mock_file_handle
  724         utils_mock.side_effect = processutils.ProcessExecutionError
  725 
  726         self.assertRaises(exception.ImageCreationFailed,
  727                           images.create_isolinux_image_for_bios,
  728                           'tgt_file', 'path/to/kernel',
  729                           'path/to/ramdisk')
  730 
  731     @mock.patch.object(images, 'create_esp_image_for_uefi', autospec=True)
  732     @mock.patch.object(images, 'fetch', autospec=True)
  733     @mock.patch.object(utils, 'tempdir', autospec=True)
  734     def test_create_boot_iso_for_uefi_deploy_iso(
  735             self, tempdir_mock, fetch_images_mock, create_isolinux_mock):
  736         mock_file_handle = mock.MagicMock(spec=io.BytesIO)
  737         mock_file_handle.__enter__.return_value = 'tmpdir'
  738         tempdir_mock.return_value = mock_file_handle
  739 
  740         images.create_boot_iso(
  741             'ctx', 'output_file', 'kernel-uuid',
  742             'ramdisk-uuid', deploy_iso_href='deploy_iso-uuid',
  743             root_uuid='root-uuid', kernel_params='kernel-params',
  744             boot_mode='uefi')
  745 
  746         fetch_images_mock.assert_any_call(
  747             'ctx', 'kernel-uuid', 'tmpdir/kernel-uuid')
  748         fetch_images_mock.assert_any_call(
  749             'ctx', 'ramdisk-uuid', 'tmpdir/ramdisk-uuid')
  750         fetch_images_mock.assert_any_call(
  751             'ctx', 'deploy_iso-uuid', 'tmpdir/deploy_iso-uuid')
  752 
  753         params = ['root=UUID=root-uuid', 'kernel-params']
  754         create_isolinux_mock.assert_called_once_with(
  755             'output_file', 'tmpdir/kernel-uuid', 'tmpdir/ramdisk-uuid',
  756             deploy_iso='tmpdir/deploy_iso-uuid',
  757             esp_image=None, kernel_params=params, inject_files=None)
  758 
  759     @mock.patch.object(images, 'create_esp_image_for_uefi', autospec=True)
  760     @mock.patch.object(images, 'fetch', autospec=True)
  761     @mock.patch.object(utils, 'tempdir', autospec=True)
  762     def test_create_boot_iso_for_uefi_esp_image(
  763             self, tempdir_mock, fetch_images_mock, create_isolinux_mock):
  764         mock_file_handle = mock.MagicMock(spec=io.BytesIO)
  765         mock_file_handle.__enter__.return_value = 'tmpdir'
  766         tempdir_mock.return_value = mock_file_handle
  767 
  768         images.create_boot_iso(
  769             'ctx', 'output_file', 'kernel-uuid',
  770             'ramdisk-uuid', esp_image_href='efiboot-uuid',
  771             root_uuid='root-uuid', kernel_params='kernel-params',
  772             boot_mode='uefi')
  773 
  774         fetch_images_mock.assert_any_call(
  775             'ctx', 'kernel-uuid', 'tmpdir/kernel-uuid')
  776         fetch_images_mock.assert_any_call(
  777             'ctx', 'ramdisk-uuid', 'tmpdir/ramdisk-uuid')
  778         fetch_images_mock.assert_any_call(
  779             'ctx', 'efiboot-uuid', 'tmpdir/efiboot-uuid')
  780 
  781         params = ['root=UUID=root-uuid', 'kernel-params']
  782         create_isolinux_mock.assert_called_once_with(
  783             'output_file', 'tmpdir/kernel-uuid', 'tmpdir/ramdisk-uuid',
  784             deploy_iso=None, esp_image='tmpdir/efiboot-uuid',
  785             kernel_params=params, inject_files=None)
  786 
  787     @mock.patch.object(images, 'create_esp_image_for_uefi', autospec=True)
  788     @mock.patch.object(images, 'fetch', autospec=True)
  789     @mock.patch.object(utils, 'tempdir', autospec=True)
  790     def test_create_boot_iso_for_uefi_deploy_iso_for_hrefs(
  791             self, tempdir_mock, fetch_images_mock, create_isolinux_mock):
  792         mock_file_handle = mock.MagicMock(spec=io.BytesIO)
  793         mock_file_handle.__enter__.return_value = 'tmpdir'
  794         tempdir_mock.return_value = mock_file_handle
  795 
  796         images.create_boot_iso(
  797             'ctx', 'output_file', 'http://kernel-href', 'http://ramdisk-href',
  798             deploy_iso_href='http://deploy_iso-href',
  799             root_uuid='root-uuid', kernel_params='kernel-params',
  800             boot_mode='uefi')
  801 
  802         expected_calls = [mock.call('ctx', 'http://kernel-href',
  803                                     'tmpdir/kernel-href'),
  804                           mock.call('ctx', 'http://ramdisk-href',
  805                                     'tmpdir/ramdisk-href'),
  806                           mock.call('ctx', 'http://deploy_iso-href',
  807                                     'tmpdir/deploy_iso-href')]
  808         fetch_images_mock.assert_has_calls(expected_calls)
  809         params = ['root=UUID=root-uuid', 'kernel-params']
  810         create_isolinux_mock.assert_called_once_with(
  811             'output_file', 'tmpdir/kernel-href', 'tmpdir/ramdisk-href',
  812             deploy_iso='tmpdir/deploy_iso-href',
  813             esp_image=None, kernel_params=params, inject_files=None)
  814 
  815     @mock.patch.object(images, 'create_esp_image_for_uefi', autospec=True)
  816     @mock.patch.object(images, 'fetch', autospec=True)
  817     @mock.patch.object(utils, 'tempdir', autospec=True)
  818     def test_create_boot_iso_for_uefi_esp_image_for_hrefs(
  819             self, tempdir_mock, fetch_images_mock, create_isolinux_mock):
  820         mock_file_handle = mock.MagicMock(spec=io.BytesIO)
  821         mock_file_handle.__enter__.return_value = 'tmpdir'
  822         tempdir_mock.return_value = mock_file_handle
  823 
  824         images.create_boot_iso(
  825             'ctx', 'output_file', 'http://kernel-href', 'http://ramdisk-href',
  826             esp_image_href='http://efiboot-href',
  827             root_uuid='root-uuid', kernel_params='kernel-params',
  828             boot_mode='uefi')
  829 
  830         expected_calls = [mock.call('ctx', 'http://kernel-href',
  831                                     'tmpdir/kernel-href'),
  832                           mock.call('ctx', 'http://ramdisk-href',
  833                                     'tmpdir/ramdisk-href'),
  834                           mock.call('ctx', 'http://efiboot-href',
  835                                     'tmpdir/efiboot-href')]
  836         fetch_images_mock.assert_has_calls(expected_calls)
  837         params = ['root=UUID=root-uuid', 'kernel-params']
  838         create_isolinux_mock.assert_called_once_with(
  839             'output_file', 'tmpdir/kernel-href', 'tmpdir/ramdisk-href',
  840             deploy_iso=None, esp_image='tmpdir/efiboot-href',
  841             kernel_params=params, inject_files=None)
  842 
  843     @mock.patch.object(images, 'create_isolinux_image_for_bios', autospec=True)
  844     @mock.patch.object(images, 'fetch', autospec=True)
  845     @mock.patch.object(utils, 'tempdir', autospec=True)
  846     def test_create_boot_iso_for_bios(
  847             self, tempdir_mock, fetch_images_mock, create_isolinux_mock):
  848         mock_file_handle = mock.MagicMock(spec=io.BytesIO)
  849         mock_file_handle.__enter__.return_value = 'tmpdir'
  850         tempdir_mock.return_value = mock_file_handle
  851 
  852         images.create_boot_iso('ctx', 'output_file', 'kernel-uuid',
  853                                'ramdisk-uuid', 'deploy_iso-uuid',
  854                                'efiboot-uuid', 'root-uuid',
  855                                'kernel-params', 'bios')
  856 
  857         fetch_images_mock.assert_any_call(
  858             'ctx', 'kernel-uuid', 'tmpdir/kernel-uuid')
  859         fetch_images_mock.assert_any_call(
  860             'ctx', 'ramdisk-uuid', 'tmpdir/ramdisk-uuid')
  861 
  862         # Note (NobodyCam): the original assert asserted that fetch_images
  863         #                   was not called with parameters, this did not
  864         #                   work, So I instead assert that there were only
  865         #                   Two calls to the mock validating the above
  866         #                   asserts.
  867         self.assertEqual(2, fetch_images_mock.call_count)
  868 
  869         params = ['root=UUID=root-uuid', 'kernel-params']
  870         create_isolinux_mock.assert_called_once_with(
  871             'output_file', 'tmpdir/kernel-uuid', 'tmpdir/ramdisk-uuid',
  872             kernel_params=params, inject_files=None)
  873 
  874     @mock.patch.object(images, 'create_isolinux_image_for_bios', autospec=True)
  875     @mock.patch.object(images, 'fetch', autospec=True)
  876     @mock.patch.object(utils, 'tempdir', autospec=True)
  877     def test_create_boot_iso_for_bios_with_no_boot_mode(self, tempdir_mock,
  878                                                         fetch_images_mock,
  879                                                         create_isolinux_mock):
  880         mock_file_handle = mock.MagicMock(spec=io.BytesIO)
  881         mock_file_handle.__enter__.return_value = 'tmpdir'
  882         tempdir_mock.return_value = mock_file_handle
  883 
  884         images.create_boot_iso('ctx', 'output_file', 'kernel-uuid',
  885                                'ramdisk-uuid', 'deploy_iso-uuid',
  886                                'efiboot-uuid', 'root-uuid',
  887                                'kernel-params', None)
  888 
  889         fetch_images_mock.assert_any_call(
  890             'ctx', 'kernel-uuid', 'tmpdir/kernel-uuid')
  891         fetch_images_mock.assert_any_call(
  892             'ctx', 'ramdisk-uuid', 'tmpdir/ramdisk-uuid')
  893 
  894         params = ['root=UUID=root-uuid', 'kernel-params']
  895         create_isolinux_mock.assert_called_once_with(
  896             'output_file', 'tmpdir/kernel-uuid', 'tmpdir/ramdisk-uuid',
  897             kernel_params=params, inject_files=None)
  898 
  899     @mock.patch.object(images, 'create_isolinux_image_for_bios', autospec=True)
  900     @mock.patch.object(images, 'fetch', autospec=True)
  901     @mock.patch.object(utils, 'tempdir', autospec=True)
  902     def test_create_boot_iso_for_existing_iso(self, tempdir_mock,
  903                                               fetch_images_mock,
  904                                               create_isolinux_mock):
  905         mock_file_handle = mock.MagicMock(spec=io.BytesIO)
  906         mock_file_handle.__enter__.return_value = 'tmpdir'
  907         tempdir_mock.return_value = mock_file_handle
  908         base_iso = 'http://fake.local:1234/fake.iso'
  909         images.create_boot_iso('ctx', 'output_file', 'kernel-uuid',
  910                                'ramdisk-uuid', 'deploy_iso-uuid',
  911                                'efiboot-uuid', None,
  912                                None, None, base_iso=base_iso)
  913 
  914         fetch_images_mock.assert_any_call(
  915             'ctx', base_iso, 'output_file')
  916 
  917         create_isolinux_mock.assert_not_called()
  918 
  919     @mock.patch.object(image_service, 'get_image_service', autospec=True)
  920     def test_get_glance_image_properties_no_such_prop(self,
  921                                                       image_service_mock):
  922 
  923         prop_dict = {'properties': {'p1': 'v1',
  924                                     'p2': 'v2'}}
  925 
  926         image_service_obj_mock = image_service_mock.return_value
  927         image_service_obj_mock.show.return_value = prop_dict
  928 
  929         ret_val = images.get_image_properties('con', 'uuid',
  930                                               ['p1', 'p2', 'p3'])
  931         image_service_mock.assert_called_once_with('uuid', context='con')
  932         image_service_obj_mock.show.assert_called_once_with('uuid')
  933         self.assertEqual({'p1': 'v1',
  934                           'p2': 'v2',
  935                           'p3': None}, ret_val)
  936 
  937     @mock.patch.object(image_service, 'get_image_service', autospec=True)
  938     def test_get_glance_image_properties_default_all(
  939             self, image_service_mock):
  940 
  941         prop_dict = {'properties': {'p1': 'v1',
  942                                     'p2': 'v2'}}
  943 
  944         image_service_obj_mock = image_service_mock.return_value
  945         image_service_obj_mock.show.return_value = prop_dict
  946 
  947         ret_val = images.get_image_properties('con', 'uuid')
  948         image_service_mock.assert_called_once_with('uuid', context='con')
  949         image_service_obj_mock.show.assert_called_once_with('uuid')
  950         self.assertEqual({'p1': 'v1',
  951                           'p2': 'v2'}, ret_val)
  952 
  953     @mock.patch.object(image_service, 'get_image_service', autospec=True)
  954     def test_get_glance_image_properties_with_prop_subset(
  955             self, image_service_mock):
  956 
  957         prop_dict = {'properties': {'p1': 'v1',
  958                                     'p2': 'v2',
  959                                     'p3': 'v3'}}
  960 
  961         image_service_obj_mock = image_service_mock.return_value
  962         image_service_obj_mock.show.return_value = prop_dict
  963 
  964         ret_val = images.get_image_properties('con', 'uuid',
  965                                               ['p1', 'p3'])
  966         image_service_mock.assert_called_once_with('uuid', context='con')
  967         image_service_obj_mock.show.assert_called_once_with('uuid')
  968         self.assertEqual({'p1': 'v1',
  969                           'p3': 'v3'}, ret_val)
  970 
  971     @mock.patch.object(image_service, 'GlanceImageService', autospec=True)
  972     def test_get_temp_url_for_glance_image(self, image_service_mock):
  973 
  974         direct_url = 'swift+http://host/v1/AUTH_xx/con/obj'
  975         image_info = {'id': 'qwe', 'properties': {'direct_url': direct_url}}
  976         glance_service_mock = image_service_mock.return_value
  977         glance_service_mock.swift_temp_url.return_value = 'temp-url'
  978         glance_service_mock.show.return_value = image_info
  979 
  980         temp_url = images.get_temp_url_for_glance_image('context',
  981                                                         'glance_uuid')
  982 
  983         glance_service_mock.show.assert_called_once_with('glance_uuid')
  984         self.assertEqual('temp-url', temp_url)