21
21
22
22
from nova .compute import utils as compute_utils
23
23
from nova import exception
24
- from nova .image import format_inspector
25
24
from nova import test
26
25
from nova .virt import images
27
26
@@ -101,15 +100,16 @@ def test_qemu_img_info_with_disk_not_found(self, exists, mocked_execute):
101
100
mocked_execute .assert_called_once ()
102
101
103
102
@mock .patch .object (images , 'IMAGE_API' )
104
- @mock .patch ('nova.image.format_inspector.get_inspector ' )
103
+ @mock .patch ('nova.image.format_inspector.detect_file_format ' )
105
104
@mock .patch .object (images , 'convert_image' ,
106
105
side_effect = exception .ImageUnacceptable )
107
106
@mock .patch .object (images , 'qemu_img_info' )
108
107
@mock .patch .object (images , 'fetch' )
109
108
def test_fetch_to_raw_errors (self , convert_image , qemu_img_info , fetch ,
110
- get_inspector , glance ):
111
- inspector = get_inspector . return_value . from_file .return_value
109
+ mock_detect , glance ):
110
+ inspector = mock_detect .return_value
112
111
inspector .safety_check .return_value = True
112
+ inspector .__str__ .return_value = 'qcow2'
113
113
glance .get .return_value = {'disk_format' : 'qcow2' }
114
114
qemu_img_info .backing_file = None
115
115
qemu_img_info .file_format = 'qcow2'
@@ -120,16 +120,17 @@ def test_fetch_to_raw_errors(self, convert_image, qemu_img_info, fetch,
120
120
None , 'href123' , '/no/path' )
121
121
122
122
@mock .patch .object (images , 'IMAGE_API' )
123
- @mock .patch ('nova.image.format_inspector.get_inspector ' )
123
+ @mock .patch ('nova.image.format_inspector.detect_file_format ' )
124
124
@mock .patch .object (images , 'convert_image' ,
125
125
side_effect = exception .ImageUnacceptable )
126
126
@mock .patch .object (images , 'qemu_img_info' )
127
127
@mock .patch .object (images , 'fetch' )
128
128
def test_fetch_to_raw_data_file (self , convert_image , qemu_img_info_fn ,
129
- fetch , mock_gi , mock_glance ):
129
+ fetch , mock_detect , mock_glance ):
130
130
mock_glance .get .return_value = {'disk_format' : 'qcow2' }
131
- inspector = mock_gi . return_value . from_file .return_value
131
+ inspector = mock_detect .return_value
132
132
inspector .safety_check .return_value = True
133
+ inspector .__str__ .return_value = 'qcow2'
133
134
# NOTE(danms): the above test needs the following line as well, as it
134
135
# is broken without it.
135
136
qemu_img_info = qemu_img_info_fn .return_value
@@ -142,16 +143,17 @@ def test_fetch_to_raw_data_file(self, convert_image, qemu_img_info_fn,
142
143
images .fetch_to_raw ,
143
144
None , 'href123' , '/no/path' )
144
145
145
- @mock .patch ('nova.image.format_inspector.get_inspector ' )
146
+ @mock .patch ('nova.image.format_inspector.detect_file_format ' )
146
147
@mock .patch .object (images , 'IMAGE_API' )
147
148
@mock .patch ('os.rename' )
148
149
@mock .patch .object (images , 'qemu_img_info' )
149
150
@mock .patch .object (images , 'fetch' )
150
151
def test_fetch_to_raw_from_raw (self , fetch , qemu_img_info_fn , mock_rename ,
151
- mock_glance , mock_gi ):
152
+ mock_glance , mock_detect ):
152
153
# Make sure we support a case where we fetch an already-raw image and
153
154
# qemu-img returns None for "format_specific".
154
155
mock_glance .get .return_value = {'disk_format' : 'raw' }
156
+ mock_detect .return_value .__str__ .return_value = 'raw'
155
157
qemu_img_info = qemu_img_info_fn .return_value
156
158
qemu_img_info .file_format = 'raw'
157
159
qemu_img_info .backing_file = None
@@ -215,14 +217,15 @@ def test_convert_image_vmdk_allowed_list_checking(self):
215
217
format = 'json' ))
216
218
217
219
@mock .patch .object (images , 'IMAGE_API' )
218
- @mock .patch ('nova.image.format_inspector.get_inspector ' )
220
+ @mock .patch ('nova.image.format_inspector.detect_file_format ' )
219
221
@mock .patch .object (images , 'fetch' )
220
222
@mock .patch ('nova.privsep.qemu.unprivileged_qemu_img_info' )
221
- def test_fetch_checks_vmdk_rules (self , mock_info , mock_fetch , mock_gi ,
223
+ def test_fetch_checks_vmdk_rules (self , mock_info , mock_fetch , mock_detect ,
222
224
mock_glance ):
223
225
mock_glance .get .return_value = {'disk_format' : 'vmdk' }
224
- inspector = mock_gi . return_value . from_file .return_value
226
+ inspector = mock_detect .return_value
225
227
inspector .safety_check .return_value = True
228
+ inspector .__str__ .return_value = 'vmdk'
226
229
info = {'format' : 'vmdk' ,
227
230
'format-specific' : {
228
231
'type' : 'vmdk' ,
@@ -235,22 +238,54 @@ def test_fetch_checks_vmdk_rules(self, mock_info, mock_fetch, mock_gi,
235
238
images .fetch_to_raw , None , 'foo' , 'anypath' )
236
239
self .assertIn ('Invalid VMDK create-type specified' , str (e ))
237
240
241
+ @mock .patch ('os.rename' )
238
242
@mock .patch .object (images , 'IMAGE_API' )
239
243
@mock .patch ('nova.image.format_inspector.get_inspector' )
244
+ @mock .patch ('nova.image.format_inspector.detect_file_format' )
245
+ @mock .patch .object (images , 'fetch' )
246
+ @mock .patch ('nova.privsep.qemu.unprivileged_qemu_img_info' )
247
+ def test_fetch_iso_is_raw (
248
+ self , mock_info , mock_fetch , mock_detect_file_format , mock_gi ,
249
+ mock_glance , mock_rename ):
250
+ mock_glance .get .return_value = {'disk_format' : 'iso' }
251
+ inspector = mock_gi .return_value .from_file .return_value
252
+ inspector .safety_check .return_value = True
253
+ inspector .__str__ .return_value = 'iso'
254
+ mock_detect_file_format .return_value = inspector
255
+ # qemu-img does not have a parser for iso so it is treated as raw
256
+ info = {
257
+ "virtual-size" : 356352 ,
258
+ "filename" : "foo.iso" ,
259
+ "format" : "raw" ,
260
+ "actual-size" : 356352 ,
261
+ "dirty-flag" : False
262
+ }
263
+ mock_info .return_value = jsonutils .dumps (info )
264
+ with mock .patch ('os.path.exists' , return_value = True ):
265
+ images .fetch_to_raw (None , 'foo' , 'anypath' )
266
+ # Make sure we called info with -f raw for an iso, since qemu-img does
267
+ # not support iso
268
+ mock_info .assert_called_once_with ('anypath.part' , format = None )
269
+ # Make sure that since we considered this to be a raw file, we did the
270
+ # just-rename-don't-convert path
271
+ mock_rename .assert_called_once_with ('anypath.part' , 'anypath' )
272
+
273
+ @mock .patch .object (images , 'IMAGE_API' )
274
+ @mock .patch ('nova.image.format_inspector.detect_file_format' )
240
275
@mock .patch .object (images , 'qemu_img_info' )
241
276
@mock .patch .object (images , 'fetch' )
242
- def test_fetch_to_raw_inspector (self , fetch , qemu_img_info , mock_gi ,
277
+ def test_fetch_to_raw_inspector (self , fetch , qemu_img_info , mock_detect ,
243
278
mock_glance ):
244
279
# Image claims to be qcow2, is qcow2, but fails safety check, so we
245
280
# abort before qemu-img-info
246
281
mock_glance .get .return_value = {'disk_format' : 'qcow2' }
247
- inspector = mock_gi . return_value . from_file .return_value
282
+ inspector = mock_detect .return_value
248
283
inspector .safety_check .return_value = False
284
+ inspector .__str__ .return_value = 'qcow2'
249
285
self .assertRaises (exception .ImageUnacceptable ,
250
286
images .fetch_to_raw , None , 'href123' , '/no.path' )
251
287
qemu_img_info .assert_not_called ()
252
- mock_gi .assert_called_once_with ('qcow2' )
253
- mock_gi .return_value .from_file .assert_called_once_with ('/no.path.part' )
288
+ mock_detect .assert_called_once_with ('/no.path.part' )
254
289
inspector .safety_check .assert_called_once_with ()
255
290
mock_glance .get .assert_called_once_with (None , 'href123' )
256
291
@@ -264,18 +299,17 @@ def test_fetch_to_raw_inspector(self, fetch, qemu_img_info, mock_gi,
264
299
# Image claims to be qcow2 in glance, but the image is something else,
265
300
# so we abort before qemu-img-info
266
301
qemu_img_info .reset_mock ()
267
- mock_gi .reset_mock ()
302
+ mock_detect .reset_mock ()
268
303
inspector .safety_check .reset_mock ()
269
- mock_gi .return_value .from_file .side_effect = (
270
- format_inspector .ImageFormatError )
304
+ mock_detect .return_value .__str__ .return_value = 'vmdk'
271
305
self .assertRaises (exception .ImageUnacceptable ,
272
306
images .fetch_to_raw , None , 'href123' , '/no.path' )
273
- mock_gi .assert_called_once_with ('qcow2 ' )
274
- inspector .safety_check .assert_not_called ()
307
+ mock_detect .assert_called_once_with ('/no.path.part ' )
308
+ inspector .safety_check .assert_called_once_with ()
275
309
qemu_img_info .assert_not_called ()
276
310
277
311
@mock .patch .object (images , 'IMAGE_API' )
278
- @mock .patch ('nova.image.format_inspector.get_inspector ' )
312
+ @mock .patch ('nova.image.format_inspector.detect_file_format ' )
279
313
@mock .patch .object (images , 'qemu_img_info' )
280
314
@mock .patch .object (images , 'fetch' )
281
315
def test_fetch_to_raw_inspector_disabled (self , fetch , qemu_img_info ,
@@ -288,36 +322,41 @@ def test_fetch_to_raw_inspector_disabled(self, fetch, qemu_img_info,
288
322
# If deep inspection is disabled, we should never call the inspector
289
323
mock_gi .assert_not_called ()
290
324
# ... and we let qemu-img detect the format itself.
291
- qemu_img_info .assert_called_once_with ('/no.path.part' ,
292
- format = None )
325
+ qemu_img_info .assert_called_once_with ('/no.path.part' )
293
326
mock_glance .get .assert_not_called ()
294
327
295
328
@mock .patch .object (images , 'IMAGE_API' )
296
329
@mock .patch .object (images , 'qemu_img_info' )
297
- def test_fetch_inspect_ami (self , imginfo , glance ):
330
+ @mock .patch ('nova.image.format_inspector.detect_file_format' )
331
+ def test_fetch_inspect_ami (self , detect , imginfo , glance ):
298
332
glance .get .return_value = {'disk_format' : 'ami' }
333
+ detect .return_value .__str__ .return_value = 'raw'
299
334
self .assertRaises (exception .ImageUnacceptable ,
300
335
images .fetch_to_raw , None , 'href123' , '/no.path' )
301
336
# Make sure 'ami was translated into 'raw' before we call qemu-img
302
- imginfo .assert_called_once_with ('/no.path.part' , format = 'raw' )
337
+ imginfo .assert_called_once_with ('/no.path.part' )
303
338
304
339
@mock .patch .object (images , 'IMAGE_API' )
305
340
@mock .patch .object (images , 'qemu_img_info' )
306
- def test_fetch_inspect_aki (self , imginfo , glance ):
341
+ @mock .patch ('nova.image.format_inspector.detect_file_format' )
342
+ def test_fetch_inspect_aki (self , detect , imginfo , glance ):
307
343
glance .get .return_value = {'disk_format' : 'aki' }
344
+ detect .return_value .__str__ .return_value = 'raw'
308
345
self .assertRaises (exception .ImageUnacceptable ,
309
346
images .fetch_to_raw , None , 'href123' , '/no.path' )
310
347
# Make sure 'aki was translated into 'raw' before we call qemu-img
311
- imginfo .assert_called_once_with ('/no.path.part' , format = 'raw' )
348
+ imginfo .assert_called_once_with ('/no.path.part' )
312
349
313
350
@mock .patch .object (images , 'IMAGE_API' )
314
351
@mock .patch .object (images , 'qemu_img_info' )
315
- def test_fetch_inspect_ari (self , imginfo , glance ):
352
+ @mock .patch ('nova.image.format_inspector.detect_file_format' )
353
+ def test_fetch_inspect_ari (self , detect , imginfo , glance ):
316
354
glance .get .return_value = {'disk_format' : 'ari' }
355
+ detect .return_value .__str__ .return_value = 'raw'
317
356
self .assertRaises (exception .ImageUnacceptable ,
318
357
images .fetch_to_raw , None , 'href123' , '/no.path' )
319
358
# Make sure 'aki was translated into 'raw' before we call qemu-img
320
- imginfo .assert_called_once_with ('/no.path.part' , format = 'raw' )
359
+ imginfo .assert_called_once_with ('/no.path.part' )
321
360
322
361
@mock .patch .object (images , 'IMAGE_API' )
323
362
@mock .patch .object (images , 'qemu_img_info' )
@@ -330,13 +369,16 @@ def test_fetch_inspect_unknown_format(self, imginfo, glance):
330
369
331
370
@mock .patch .object (images , 'IMAGE_API' )
332
371
@mock .patch .object (images , 'qemu_img_info' )
333
- @mock .patch ('nova.image.format_inspector.get_inspector ' )
334
- def test_fetch_inspect_disagrees_qemu (self , mock_gi , imginfo , glance ):
372
+ @mock .patch ('nova.image.format_inspector.detect_file_format ' )
373
+ def test_fetch_inspect_disagrees_qemu (self , mock_detect , imginfo , glance ):
335
374
glance .get .return_value = {'disk_format' : 'qcow2' }
375
+ mock_detect .return_value .__str__ .return_value = 'qcow2'
336
376
# Glance and inspector think it is a qcow2 file, but qemu-img does not
337
- # agree. It was forced to interpret as a qcow2, but returned no
338
- # format information as a result.
377
+ # agree.
339
378
imginfo .return_value .data_file = None
340
- self .assertRaises (exception .ImageUnacceptable ,
341
- images .fetch_to_raw , None , 'href123' , '/no.path' )
342
- imginfo .assert_called_once_with ('/no.path.part' , format = 'qcow2' )
379
+ imginfo .return_value .file_format = 'vmdk'
380
+ ex = self .assertRaises (exception .ImageUnacceptable ,
381
+ images .fetch_to_raw ,
382
+ None , 'href123' , '/no.path' )
383
+ self .assertIn ('content does not match disk_format' , str (ex ))
384
+ imginfo .assert_called_once_with ('/no.path.part' )
0 commit comments