|
| 1 | +import uuid |
| 2 | + |
1 | 3 | from unittest.mock import Mock |
2 | 4 |
|
3 | 5 | from openstack_mcp_server.tools.image_tools import ImageTools |
| 6 | +from openstack_mcp_server.tools.request.image import CreateImage |
| 7 | +from openstack_mcp_server.tools.response.image import Image |
4 | 8 |
|
5 | 9 |
|
6 | 10 | class TestImageTools: |
7 | 11 | """Test cases for ImageTools class.""" |
8 | 12 |
|
| 13 | + @staticmethod |
| 14 | + def image_factory(**overrides): |
| 15 | + defaults = { |
| 16 | + "id": str(uuid.uuid4()), |
| 17 | + "name": "test-image", |
| 18 | + "checksum": "abc123", |
| 19 | + "container_format": "bare", |
| 20 | + "disk_format": "qcow2", |
| 21 | + "file": None, |
| 22 | + "min_disk": 1, |
| 23 | + "min_ram": 512, |
| 24 | + "os_hash_algo": "sha512", |
| 25 | + "os_hash_value": "hash123", |
| 26 | + "size": 1073741824, |
| 27 | + "virtual_size": None, |
| 28 | + "owner": str(uuid.uuid4()), |
| 29 | + "visibility": "public", |
| 30 | + "hw_rng_model": None, |
| 31 | + "status": "active", |
| 32 | + "schema": "/v2/schemas/image", |
| 33 | + "protected": False, |
| 34 | + "os_hidden": False, |
| 35 | + "tags": [], |
| 36 | + "properties": None, |
| 37 | + "created_at": "2025-01-01T00:00:00Z", |
| 38 | + "updated_at": "2025-01-01T00:00:00Z", |
| 39 | + "owner_specified.openstack.md5": "a1b2c3d4e5f6", |
| 40 | + "owner_specified.openstack.sha256": "a1b2c3d", |
| 41 | + "owner_specified.openstack.object": "image", |
| 42 | + } |
| 43 | + for key, value in overrides.items(): |
| 44 | + if value is not None: |
| 45 | + defaults[key] = value |
| 46 | + |
| 47 | + return defaults |
| 48 | + |
9 | 49 | def test_get_image_images_success(self, mock_get_openstack_conn_image): |
10 | 50 | """Test getting image images successfully.""" |
11 | 51 | mock_conn = mock_get_openstack_conn_image |
@@ -80,3 +120,113 @@ def test_get_image_images_with_empty_name( |
80 | 120 | assert " (img-empty-name) - Status: active" in result # Empty name |
81 | 121 |
|
82 | 122 | mock_conn.image.images.assert_called_once() |
| 123 | + |
| 124 | + def test_create_image_success_with_volume_id( |
| 125 | + self, |
| 126 | + mock_get_openstack_conn_image, |
| 127 | + ): |
| 128 | + """Test creating an image from a volume ID.""" |
| 129 | + volume_id = "6cf57d8d-00ca-43ff-ae6f-56912b69528a" # Example volume ID |
| 130 | + |
| 131 | + mock_image = self.image_factory() |
| 132 | + mock_get_openstack_conn_image.block_storage.create_image.return_value = Mock( |
| 133 | + id=mock_image["id"], |
| 134 | + ) |
| 135 | + mock_get_openstack_conn_image.get_image.return_value = mock_image |
| 136 | + |
| 137 | + # Create an instance with volume ID |
| 138 | + image_tools = ImageTools() |
| 139 | + image_data = CreateImage( |
| 140 | + name=mock_image["name"], |
| 141 | + volume=volume_id, |
| 142 | + allow_duplicates=False, |
| 143 | + container=mock_image["container_format"], |
| 144 | + disk_format=mock_image["disk_format"], |
| 145 | + container_format=mock_image["container_format"], |
| 146 | + min_disk=mock_image["min_disk"], |
| 147 | + ) |
| 148 | + |
| 149 | + expected_output = Image(**mock_image) |
| 150 | + |
| 151 | + created_image = image_tools.create_image(image_data) |
| 152 | + |
| 153 | + # Verify the created image |
| 154 | + assert created_image == expected_output |
| 155 | + assert mock_get_openstack_conn_image.block_storage.create_image.called_once_with( |
| 156 | + name=mock_image["name"], |
| 157 | + volume=volume_id, |
| 158 | + allow_duplicates=False, |
| 159 | + container=mock_image["container_format"], |
| 160 | + disk_format=mock_image["disk_format"], |
| 161 | + wait=False, |
| 162 | + timeout=3600, |
| 163 | + ) |
| 164 | + |
| 165 | + assert mock_get_openstack_conn_image.get_image.called_once_with( |
| 166 | + mock_image["id"], |
| 167 | + ) |
| 168 | + |
| 169 | + def test_create_image_success_with_import_options( |
| 170 | + self, |
| 171 | + mock_get_openstack_conn_image, |
| 172 | + ): |
| 173 | + """Test creating an image with import options.""" |
| 174 | + create_image_data = CreateImage( |
| 175 | + name="example_image", |
| 176 | + container="bare", |
| 177 | + disk_format="qcow2", |
| 178 | + container_format="bare", |
| 179 | + min_disk=10, |
| 180 | + min_ram=512, |
| 181 | + tags=["example", "test"], |
| 182 | + import_options=CreateImage.ImportOptions( |
| 183 | + import_method="web-download", |
| 184 | + uri="https://example.com/image.qcow2", |
| 185 | + ), |
| 186 | + allow_duplicates=False, |
| 187 | + ) |
| 188 | + |
| 189 | + mock_image = self.image_factory(**create_image_data.__dict__) |
| 190 | + mock_create_image = Mock(id=mock_image["id"]) |
| 191 | + |
| 192 | + mock_get_openstack_conn_image.image.create_image.return_value = ( |
| 193 | + mock_create_image |
| 194 | + ) |
| 195 | + mock_get_openstack_conn_image.image.import_image.return_value = None |
| 196 | + mock_get_openstack_conn_image.get_image.return_value = mock_image |
| 197 | + |
| 198 | + # Create an instance with import options |
| 199 | + image_tools = ImageTools() |
| 200 | + |
| 201 | + expected_output = Image(**mock_image) |
| 202 | + |
| 203 | + created_image = image_tools.create_image(create_image_data) |
| 204 | + |
| 205 | + # Verify the created image |
| 206 | + assert created_image == expected_output |
| 207 | + assert ( |
| 208 | + mock_get_openstack_conn_image.image.create_image.called_once_with( |
| 209 | + name=create_image_data.name, |
| 210 | + container=create_image_data.container, |
| 211 | + container_format=create_image_data.container_format, |
| 212 | + disk_format=create_image_data.disk_format, |
| 213 | + min_disk=create_image_data.min_disk, |
| 214 | + min_ram=create_image_data.min_ram, |
| 215 | + tags=create_image_data.tags, |
| 216 | + protected=create_image_data.protected, |
| 217 | + visibility=create_image_data.visibility, |
| 218 | + allow_duplicates=create_image_data.allow_duplicates, |
| 219 | + ) |
| 220 | + ) |
| 221 | + assert mock_get_openstack_conn_image.image.import_image.called_once_with( |
| 222 | + image=mock_create_image, |
| 223 | + method=create_image_data.import_options.import_method, |
| 224 | + uri=create_image_data.import_options.uri, |
| 225 | + stores=create_image_data.import_options.stores, |
| 226 | + remote_region=create_image_data.import_options.glance_region, |
| 227 | + remote_image_id=create_image_data.import_options.glance_image_id, |
| 228 | + remote_service_interface=create_image_data.import_options.glance_service_interface, |
| 229 | + ) |
| 230 | + assert mock_get_openstack_conn_image.get_image.called_once_with( |
| 231 | + mock_image["id"], |
| 232 | + ) |
0 commit comments