dfilppi | 9981f55 | 2017-08-07 20:10:53 +0000 | [diff] [blame^] | 1 | ######### |
| 2 | # Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved |
| 3 | # |
| 4 | # Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | # you may not use this file except in compliance with the License. |
| 6 | # You may obtain a copy of the License at |
| 7 | # |
| 8 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | # |
| 10 | # Unless required by applicable law or agreed to in writing, software |
| 11 | # distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | # * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | # * See the License for the specific language governing permissions and |
| 14 | # * limitations under the License. |
| 15 | |
| 16 | import mock |
| 17 | import os |
| 18 | import tempfile |
| 19 | import unittest |
| 20 | |
| 21 | import glance_plugin |
| 22 | from glance_plugin import image |
| 23 | |
| 24 | from cloudify.mocks import MockCloudifyContext |
| 25 | from cloudify.test_utils import workflow_test |
| 26 | from cloudify.exceptions import NonRecoverableError |
| 27 | |
| 28 | |
| 29 | def ctx_mock(image_dict): |
| 30 | return MockCloudifyContext( |
| 31 | node_id='d', |
| 32 | properties=image_dict) |
| 33 | |
| 34 | |
| 35 | class TestCheckImage(unittest.TestCase): |
| 36 | |
| 37 | @mock.patch('glance_plugin.image.ctx', |
| 38 | ctx_mock({'image': {}})) |
| 39 | def test_check_image_no_file_no_url(self): |
| 40 | # Test if it throws exception no file & no url |
| 41 | self.assertRaises(NonRecoverableError, |
| 42 | image._validate_image) |
| 43 | |
| 44 | @mock.patch('glance_plugin.image.ctx', |
| 45 | ctx_mock({'image_url': 'test-url', 'image': {'data': '.'}})) |
| 46 | def test_check_image_and_url(self): |
| 47 | # Test if it throws exception file & url |
| 48 | self.assertRaises(NonRecoverableError, |
| 49 | image._validate_image) |
| 50 | |
| 51 | @mock.patch('glance_plugin.image.ctx', |
| 52 | ctx_mock({'image_url': 'test-url', 'image': {}})) |
| 53 | def test_check_image_url(self): |
| 54 | # test if it passes no file & url |
| 55 | http_connection_mock = mock.MagicMock() |
| 56 | http_connection_mock.return_value.getresponse.return_value.status = 200 |
| 57 | with mock.patch('httplib.HTTPConnection', http_connection_mock): |
| 58 | glance_plugin.image._validate_image() |
| 59 | |
| 60 | def test_check_image_file(self): |
| 61 | # test if it passes file & no url |
| 62 | image_file_path = tempfile.mkstemp()[1] |
| 63 | with mock.patch('glance_plugin.image.ctx', |
| 64 | ctx_mock({'image': {'data': image_file_path}})): |
| 65 | glance_plugin.image._validate_image() |
| 66 | |
| 67 | @mock.patch('glance_plugin.image.ctx', |
| 68 | ctx_mock({'image': {'data': '/test/path'}})) |
| 69 | # test when open file throws IO error |
| 70 | def test_check_image_bad_file(self): |
| 71 | open_name = '%s.open' % __name__ |
| 72 | with mock.patch(open_name, create=True) as mock_open: |
| 73 | mock_open.side_effect = [mock_open(read_data='Data').return_value] |
| 74 | self.assertRaises(NonRecoverableError, |
| 75 | glance_plugin.image._validate_image) |
| 76 | |
| 77 | @mock.patch('glance_plugin.image.ctx', |
| 78 | ctx_mock({'image_url': '?', 'image': {}})) |
| 79 | # test when bad url |
| 80 | def test_check_image_bad_url(self): |
| 81 | http_connection_mock = mock.MagicMock() |
| 82 | http_connection_mock.return_value.getresponse.return_value.status = 400 |
| 83 | with mock.patch('httplib.HTTPConnection', http_connection_mock): |
| 84 | self.assertRaises(NonRecoverableError, |
| 85 | glance_plugin.image._validate_image) |
| 86 | |
| 87 | |
| 88 | class TestValidateProperties(unittest.TestCase): |
| 89 | |
| 90 | @mock.patch('glance_plugin.image.ctx', |
| 91 | ctx_mock({'image': {'container_format': 'bare'}})) |
| 92 | def test_check_image_container_format_no_disk_format(self): |
| 93 | # Test if it throws exception no file & no url |
| 94 | self.assertRaises(NonRecoverableError, |
| 95 | image._validate_image_dictionary) |
| 96 | |
| 97 | @mock.patch('glance_plugin.image.ctx', |
| 98 | ctx_mock({'image': {'disk_format': 'qcow2'}})) |
| 99 | def test_check_image_no_container_format_disk_format(self): |
| 100 | # Test if it throws exception no container_format & disk_format |
| 101 | self.assertRaises(NonRecoverableError, |
| 102 | image._validate_image_dictionary) |
| 103 | |
| 104 | @mock.patch('glance_plugin.image.ctx', |
| 105 | ctx_mock({'image': {}})) |
| 106 | def test_check_image_no_container_format_no_disk_format(self): |
| 107 | # Test if it throws exception no container_format & no disk_format |
| 108 | self.assertRaises(NonRecoverableError, |
| 109 | image._validate_image_dictionary) |
| 110 | |
| 111 | @mock.patch('glance_plugin.image.ctx', |
| 112 | ctx_mock( |
| 113 | {'image': |
| 114 | {'container_format': 'bare', |
| 115 | 'disk_format': 'qcow2'}})) |
| 116 | def test_check_image_container_format_disk_format(self): |
| 117 | # Test if it do not throw exception container_format & disk_format |
| 118 | image._validate_image_dictionary() |
| 119 | |
| 120 | |
| 121 | class TestStartImage(unittest.TestCase): |
| 122 | blueprint_path = os.path.join('resources', |
| 123 | 'test-image-start.yaml') |
| 124 | |
| 125 | @mock.patch('glance_plugin.image.create') |
| 126 | @workflow_test(blueprint_path, copy_plugin_yaml=True) |
| 127 | def test_image_lifecycle_start(self, cfy_local, *_): |
| 128 | test_vars = { |
| 129 | 'counter': 0, |
| 130 | 'image': mock.MagicMock() |
| 131 | } |
| 132 | |
| 133 | def _mock_get_image_by_ctx(*_): |
| 134 | i = test_vars['image'] |
| 135 | if test_vars['counter'] == 0: |
| 136 | i.status = 'different image status' |
| 137 | else: |
| 138 | i.status = glance_plugin.image.IMAGE_STATUS_ACTIVE |
| 139 | test_vars['counter'] += 1 |
| 140 | return i |
| 141 | |
| 142 | with mock.patch('openstack_plugin_common.GlanceClient'): |
| 143 | with mock.patch('glance_plugin.image._get_image_by_ctx', |
| 144 | side_effect=_mock_get_image_by_ctx): |
| 145 | cfy_local.execute('install', task_retries=3) |
| 146 | |
| 147 | self.assertEqual(2, test_vars['counter']) |
| 148 | self.assertEqual(0, test_vars['image'].start.call_count) |