~ubuntu-branches/ubuntu/wily/python-oslo.vmware/wily

« back to all changes in this revision

Viewing changes to tests/test_image_transfer.py

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2015-08-11 09:25:22 UTC
  • mfrom: (1.1.12) (2.1.3 experimental)
  • Revision ID: package-import@ubuntu.com-20150811092522-6epbeuzn6a0jt750
Tags: 1.18.0-2ubuntu1
* Resync with Debian experimental.
* d/pydist-overrides: Map suds-jurko -> suds to ease backporting.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (c) 2014 VMware, Inc.
2
 
# All Rights Reserved.
3
 
#
4
 
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
5
 
#    not use this file except in compliance with the License. You may obtain
6
 
#    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, WITHOUT
12
 
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
 
#    License for the specific language governing permissions and limitations
14
 
#    under the License.
15
 
 
16
 
"""
17
 
Unit tests for functions and classes for image transfer.
18
 
"""
19
 
 
20
 
import math
21
 
 
22
 
from eventlet import greenthread
23
 
from eventlet import timeout
24
 
import mock
25
 
 
26
 
from oslo.vmware import exceptions
27
 
from oslo.vmware import image_transfer
28
 
from oslo.vmware import rw_handles
29
 
from oslo_vmware import image_transfer as new_image_transfer
30
 
from tests import base
31
 
 
32
 
 
33
 
class BlockingQueueTest(base.TestCase):
34
 
    """Tests for BlockingQueue."""
35
 
 
36
 
    def test_read(self):
37
 
        max_size = 10
38
 
        chunk_size = 10
39
 
        max_transfer_size = 30
40
 
        queue = image_transfer.BlockingQueue(max_size, max_transfer_size)
41
 
 
42
 
        def get_side_effect():
43
 
            return [1] * chunk_size
44
 
 
45
 
        queue.get = mock.Mock(side_effect=get_side_effect)
46
 
        while True:
47
 
            data_item = queue.read(chunk_size)
48
 
            if not data_item:
49
 
                break
50
 
 
51
 
        self.assertEqual(max_transfer_size, queue._transferred)
52
 
        exp_calls = [mock.call()] * int(math.ceil(float(max_transfer_size) /
53
 
                                                  chunk_size))
54
 
        self.assertEqual(exp_calls, queue.get.call_args_list)
55
 
 
56
 
    def test_write(self):
57
 
        queue = image_transfer.BlockingQueue(10, 30)
58
 
        queue.put = mock.Mock()
59
 
        write_count = 10
60
 
        for _ in range(0, write_count):
61
 
            queue.write([1])
62
 
        exp_calls = [mock.call([1])] * write_count
63
 
        self.assertEqual(exp_calls, queue.put.call_args_list)
64
 
 
65
 
    def test_seek(self):
66
 
        queue = image_transfer.BlockingQueue(10, 30)
67
 
        self.assertRaises(IOError, queue.seek, 5)
68
 
 
69
 
    def test_tell(self):
70
 
        queue = image_transfer.BlockingQueue(10, 30)
71
 
        self.assertEqual(0, queue.tell())
72
 
        queue.get = mock.Mock(return_value=[1] * 10)
73
 
        queue.read(10)
74
 
        self.assertEqual(10, queue.tell())
75
 
 
76
 
 
77
 
class ImageWriterTest(base.TestCase):
78
 
    """Tests for ImageWriter class."""
79
 
 
80
 
    def _create_image_writer(self):
81
 
        self.image_service = mock.Mock()
82
 
        self.context = mock.Mock()
83
 
        self.input_file = mock.Mock()
84
 
        self.image_id = mock.Mock()
85
 
        return image_transfer.ImageWriter(self.context, self.input_file,
86
 
                                          self.image_service, self.image_id)
87
 
 
88
 
    @mock.patch.object(greenthread, 'sleep')
89
 
    def test_start(self, mock_sleep):
90
 
        writer = self._create_image_writer()
91
 
        status_list = ['queued', 'saving', 'active']
92
 
 
93
 
        def image_service_show_side_effect(context, image_id):
94
 
            status = status_list.pop(0)
95
 
            return {'status': status}
96
 
 
97
 
        self.image_service.show.side_effect = image_service_show_side_effect
98
 
        exp_calls = [mock.call(self.context, self.image_id)] * len(status_list)
99
 
        writer.start()
100
 
        self.assertTrue(writer.wait())
101
 
        self.image_service.update.assert_called_once_with(self.context,
102
 
                                                          self.image_id, {},
103
 
                                                          data=self.input_file)
104
 
        self.assertEqual(exp_calls, self.image_service.show.call_args_list)
105
 
 
106
 
    def test_start_with_killed_status(self):
107
 
        writer = self._create_image_writer()
108
 
 
109
 
        def image_service_show_side_effect(_context, _image_id):
110
 
            return {'status': 'killed'}
111
 
 
112
 
        self.image_service.show.side_effect = image_service_show_side_effect
113
 
        writer.start()
114
 
        self.assertRaises(exceptions.ImageTransferException,
115
 
                          writer.wait)
116
 
        self.image_service.update.assert_called_once_with(self.context,
117
 
                                                          self.image_id, {},
118
 
                                                          data=self.input_file)
119
 
        self.image_service.show.assert_called_once_with(self.context,
120
 
                                                        self.image_id)
121
 
 
122
 
    def test_start_with_unknown_status(self):
123
 
        writer = self._create_image_writer()
124
 
 
125
 
        def image_service_show_side_effect(_context, _image_id):
126
 
            return {'status': 'unknown'}
127
 
 
128
 
        self.image_service.show.side_effect = image_service_show_side_effect
129
 
        writer.start()
130
 
        self.assertRaises(exceptions.ImageTransferException,
131
 
                          writer.wait)
132
 
        self.image_service.update.assert_called_once_with(self.context,
133
 
                                                          self.image_id, {},
134
 
                                                          data=self.input_file)
135
 
        self.image_service.show.assert_called_once_with(self.context,
136
 
                                                        self.image_id)
137
 
 
138
 
    def test_start_with_image_service_show_exception(self):
139
 
        writer = self._create_image_writer()
140
 
        self.image_service.show.side_effect = RuntimeError()
141
 
        writer.start()
142
 
        self.assertRaises(exceptions.ImageTransferException, writer.wait)
143
 
        self.image_service.update.assert_called_once_with(self.context,
144
 
                                                          self.image_id, {},
145
 
                                                          data=self.input_file)
146
 
        self.image_service.show.assert_called_once_with(self.context,
147
 
                                                        self.image_id)
148
 
 
149
 
 
150
 
class FileReadWriteTaskTest(base.TestCase):
151
 
    """Tests for FileReadWriteTask class."""
152
 
 
153
 
    def test_start(self):
154
 
        data_items = [[1] * 10, [1] * 20, [1] * 5, []]
155
 
 
156
 
        def input_file_read_side_effect(arg):
157
 
            self.assertEqual(arg, rw_handles.READ_CHUNKSIZE)
158
 
            data = data_items[input_file_read_side_effect.i]
159
 
            input_file_read_side_effect.i += 1
160
 
            return data
161
 
 
162
 
        input_file_read_side_effect.i = 0
163
 
        input_file = mock.Mock()
164
 
        input_file.read.side_effect = input_file_read_side_effect
165
 
        output_file = mock.Mock()
166
 
        rw_task = image_transfer.FileReadWriteTask(input_file, output_file)
167
 
        rw_task.start()
168
 
        self.assertTrue(rw_task.wait())
169
 
        self.assertEqual(len(data_items), input_file.read.call_count)
170
 
 
171
 
        exp_calls = []
172
 
        for i in range(0, len(data_items)):
173
 
            exp_calls.append(mock.call(data_items[i]))
174
 
        self.assertEqual(exp_calls, output_file.write.call_args_list)
175
 
 
176
 
        self.assertEqual(len(data_items),
177
 
                         input_file.update_progress.call_count)
178
 
        self.assertEqual(len(data_items),
179
 
                         output_file.update_progress.call_count)
180
 
 
181
 
    def test_start_with_read_exception(self):
182
 
        input_file = mock.Mock()
183
 
        input_file.read.side_effect = RuntimeError()
184
 
        output_file = mock.Mock()
185
 
        rw_task = image_transfer.FileReadWriteTask(input_file, output_file)
186
 
        rw_task.start()
187
 
        self.assertRaises(exceptions.ImageTransferException, rw_task.wait)
188
 
        input_file.read.assert_called_once_with(rw_handles.READ_CHUNKSIZE)
189
 
 
190
 
 
191
 
class ImageTransferUtilityTest(base.TestCase):
192
 
    """Tests for image_transfer utility methods."""
193
 
 
194
 
    @mock.patch.object(timeout, 'Timeout')
195
 
    @mock.patch('oslo_vmware.image_transfer.ImageWriter')
196
 
    @mock.patch('oslo_vmware.image_transfer.FileReadWriteTask')
197
 
    @mock.patch('oslo_vmware.image_transfer.BlockingQueue')
198
 
    def test_start_transfer(self, fake_BlockingQueue, fake_FileReadWriteTask,
199
 
                            fake_ImageWriter, fake_Timeout):
200
 
 
201
 
        context = mock.Mock()
202
 
        read_file_handle = mock.Mock()
203
 
        read_file_handle.close = mock.Mock()
204
 
        image_service = mock.Mock()
205
 
        image_id = mock.Mock()
206
 
        blocking_queue = mock.Mock()
207
 
 
208
 
        write_file_handle1 = mock.Mock()
209
 
        write_file_handle1.close = mock.Mock()
210
 
        write_file_handle2 = None
211
 
        write_file_handles = [write_file_handle1, write_file_handle2]
212
 
 
213
 
        timeout_secs = 10
214
 
        blocking_queue_size = 10
215
 
        image_meta = {}
216
 
        max_data_size = 30
217
 
 
218
 
        fake_BlockingQueue.return_value = blocking_queue
219
 
        fake_timer = mock.Mock()
220
 
        fake_timer.cancel = mock.Mock()
221
 
        fake_Timeout.return_value = fake_timer
222
 
 
223
 
        for write_file_handle in write_file_handles:
224
 
            new_image_transfer._start_transfer(
225
 
                context,
226
 
                timeout_secs,
227
 
                read_file_handle,
228
 
                max_data_size,
229
 
                write_file_handle=write_file_handle,
230
 
                image_service=image_service,
231
 
                image_id=image_id,
232
 
                image_meta=image_meta)
233
 
 
234
 
        exp_calls = [mock.call(blocking_queue_size,
235
 
                               max_data_size)] * len(write_file_handles)
236
 
        self.assertEqual(exp_calls,
237
 
                         fake_BlockingQueue.call_args_list)
238
 
 
239
 
        exp_calls2 = [mock.call(read_file_handle, blocking_queue),
240
 
                      mock.call(blocking_queue, write_file_handle1),
241
 
                      mock.call(read_file_handle, blocking_queue)]
242
 
        self.assertEqual(exp_calls2,
243
 
                         fake_FileReadWriteTask.call_args_list)
244
 
 
245
 
        exp_calls3 = mock.call(context, blocking_queue, image_service,
246
 
                               image_id, image_meta)
247
 
        self.assertEqual(exp_calls3,
248
 
                         fake_ImageWriter.call_args)
249
 
 
250
 
        exp_calls4 = [mock.call(timeout_secs)] * len(write_file_handles)
251
 
        self.assertEqual(exp_calls4,
252
 
                         fake_Timeout.call_args_list)
253
 
 
254
 
        self.assertEqual(len(write_file_handles),
255
 
                         fake_timer.cancel.call_count)
256
 
 
257
 
        self.assertEqual(len(write_file_handles),
258
 
                         read_file_handle.close.call_count)
259
 
 
260
 
        write_file_handle1.close.assert_called_once()
261
 
 
262
 
    @mock.patch('oslo_vmware.rw_handles.FileWriteHandle')
263
 
    @mock.patch('oslo_vmware.rw_handles.ImageReadHandle')
264
 
    @mock.patch('oslo_vmware.image_transfer._start_transfer')
265
 
    def test_download_flat_image(
266
 
            self,
267
 
            fake_transfer,
268
 
            fake_rw_handles_ImageReadHandle,
269
 
            fake_rw_handles_FileWriteHandle):
270
 
 
271
 
        context = mock.Mock()
272
 
        image_id = mock.Mock()
273
 
        image_service = mock.Mock()
274
 
        image_service.download = mock.Mock()
275
 
        image_service.download.return_value = 'fake_iter'
276
 
 
277
 
        fake_ImageReadHandle = 'fake_ImageReadHandle'
278
 
        fake_FileWriteHandle = 'fake_FileWriteHandle'
279
 
        cookies = []
280
 
        timeout_secs = 10
281
 
        image_size = 1000
282
 
        host = '127.0.0.1'
283
 
        port = 443
284
 
        dc_path = 'dc1'
285
 
        ds_name = 'ds1'
286
 
        file_path = '/fake_path'
287
 
 
288
 
        fake_rw_handles_ImageReadHandle.return_value = fake_ImageReadHandle
289
 
        fake_rw_handles_FileWriteHandle.return_value = fake_FileWriteHandle
290
 
 
291
 
        image_transfer.download_flat_image(
292
 
            context,
293
 
            timeout_secs,
294
 
            image_service,
295
 
            image_id,
296
 
            image_size=image_size,
297
 
            host=host,
298
 
            port=port,
299
 
            data_center_name=dc_path,
300
 
            datastore_name=ds_name,
301
 
            cookies=cookies,
302
 
            file_path=file_path)
303
 
 
304
 
        image_service.download.assert_called_once_with(context, image_id)
305
 
 
306
 
        fake_rw_handles_ImageReadHandle.assert_called_once_with('fake_iter')
307
 
 
308
 
        fake_rw_handles_FileWriteHandle.assert_called_once_with(
309
 
            host,
310
 
            port,
311
 
            dc_path,
312
 
            ds_name,
313
 
            cookies,
314
 
            file_path,
315
 
            image_size,
316
 
            cacerts=None)
317
 
 
318
 
        fake_transfer.assert_called_once_with(
319
 
            context,
320
 
            timeout_secs,
321
 
            fake_ImageReadHandle,
322
 
            image_size,
323
 
            write_file_handle=fake_FileWriteHandle)
324
 
 
325
 
    @mock.patch('oslo_vmware.rw_handles.VmdkWriteHandle')
326
 
    @mock.patch('oslo_vmware.image_transfer._start_transfer')
327
 
    def test_download_stream_optimized_data(self, fake_transfer,
328
 
                                            fake_rw_handles_VmdkWriteHandle):
329
 
 
330
 
        context = mock.Mock()
331
 
        session = mock.Mock()
332
 
        read_handle = mock.Mock()
333
 
        timeout_secs = 10
334
 
        image_size = 1000
335
 
        host = '127.0.0.1'
336
 
        port = 443
337
 
        resource_pool = 'rp-1'
338
 
        vm_folder = 'folder-1'
339
 
        vm_import_spec = None
340
 
 
341
 
        fake_VmdkWriteHandle = mock.Mock()
342
 
        fake_VmdkWriteHandle.get_imported_vm = mock.Mock()
343
 
        fake_rw_handles_VmdkWriteHandle.return_value = fake_VmdkWriteHandle
344
 
 
345
 
        image_transfer.download_stream_optimized_data(
346
 
            context,
347
 
            timeout_secs,
348
 
            read_handle,
349
 
            session=session,
350
 
            host=host,
351
 
            port=port,
352
 
            resource_pool=resource_pool,
353
 
            vm_folder=vm_folder,
354
 
            vm_import_spec=vm_import_spec,
355
 
            image_size=image_size)
356
 
 
357
 
        fake_rw_handles_VmdkWriteHandle.assert_called_once_with(
358
 
            session,
359
 
            host,
360
 
            port,
361
 
            resource_pool,
362
 
            vm_folder,
363
 
            vm_import_spec,
364
 
            image_size)
365
 
 
366
 
        fake_transfer.assert_called_once_with(
367
 
            context,
368
 
            timeout_secs,
369
 
            read_handle,
370
 
            image_size,
371
 
            write_file_handle=fake_VmdkWriteHandle)
372
 
 
373
 
        fake_VmdkWriteHandle.get_imported_vm.assert_called_once()
374
 
 
375
 
    @mock.patch('oslo_vmware.rw_handles.ImageReadHandle')
376
 
    @mock.patch('oslo_vmware.image_transfer.download_stream_optimized_data')
377
 
    def test_download_stream_optimized_image(
378
 
            self, fake_download_stream_optimized_data,
379
 
            fake_rw_handles_ImageReadHandle):
380
 
 
381
 
        context = mock.Mock()
382
 
        session = mock.Mock()
383
 
        image_id = mock.Mock()
384
 
        timeout_secs = 10
385
 
        image_size = 1000
386
 
        host = '127.0.0.1'
387
 
        port = 443
388
 
        resource_pool = 'rp-1'
389
 
        vm_folder = 'folder-1'
390
 
        vm_import_spec = None
391
 
 
392
 
        fake_iter = 'fake_iter'
393
 
        image_service = mock.Mock()
394
 
        image_service.download = mock.Mock()
395
 
        image_service.download.return_value = fake_iter
396
 
 
397
 
        fake_ImageReadHandle = 'fake_ImageReadHandle'
398
 
        fake_rw_handles_ImageReadHandle.return_value = fake_ImageReadHandle
399
 
 
400
 
        image_transfer.download_stream_optimized_image(
401
 
            context,
402
 
            timeout_secs,
403
 
            image_service,
404
 
            image_id,
405
 
            session=session,
406
 
            host=host,
407
 
            port=port,
408
 
            resource_pool=resource_pool,
409
 
            vm_folder=vm_folder,
410
 
            vm_import_spec=vm_import_spec,
411
 
            image_size=image_size)
412
 
 
413
 
        image_service.download.assert_called_once_with(context, image_id)
414
 
 
415
 
        fake_rw_handles_ImageReadHandle.assert_called_once_with(fake_iter)
416
 
 
417
 
        fake_download_stream_optimized_data.assert_called_once_with(
418
 
            context,
419
 
            timeout_secs,
420
 
            fake_ImageReadHandle,
421
 
            session=session,
422
 
            host=host,
423
 
            port=port,
424
 
            resource_pool=resource_pool,
425
 
            vm_folder=vm_folder,
426
 
            vm_import_spec=vm_import_spec,
427
 
            image_size=image_size)
428
 
 
429
 
    @mock.patch('oslo_vmware.image_transfer._start_transfer')
430
 
    @mock.patch('oslo_vmware.rw_handles.VmdkReadHandle')
431
 
    def test_copy_stream_optimized_disk(
432
 
            self, vmdk_read_handle, start_transfer):
433
 
 
434
 
        read_handle = mock.sentinel.read_handle
435
 
        vmdk_read_handle.return_value = read_handle
436
 
 
437
 
        context = mock.sentinel.context
438
 
        timeout = mock.sentinel.timeout
439
 
        write_handle = mock.Mock(name='/cinder/images/tmpAbcd.vmdk')
440
 
        session = mock.sentinel.session
441
 
        host = mock.sentinel.host
442
 
        port = mock.sentinel.port
443
 
        vm = mock.sentinel.vm
444
 
        vmdk_file_path = mock.sentinel.vmdk_file_path
445
 
        vmdk_size = mock.sentinel.vmdk_size
446
 
 
447
 
        image_transfer.copy_stream_optimized_disk(
448
 
            context, timeout, write_handle, session=session, host=host,
449
 
            port=port, vm=vm, vmdk_file_path=vmdk_file_path,
450
 
            vmdk_size=vmdk_size)
451
 
 
452
 
        vmdk_read_handle.assert_called_once_with(
453
 
            session, host, port, vm, vmdk_file_path, vmdk_size)
454
 
        start_transfer.assert_called_once_with(
455
 
            context, timeout, read_handle, vmdk_size,
456
 
            write_file_handle=write_handle)
457
 
 
458
 
    @mock.patch('oslo_vmware.rw_handles.VmdkReadHandle')
459
 
    @mock.patch('oslo_vmware.image_transfer._start_transfer')
460
 
    def test_upload_image(self, fake_transfer, fake_rw_handles_VmdkReadHandle):
461
 
 
462
 
        context = mock.Mock()
463
 
        image_id = mock.Mock()
464
 
        owner_id = mock.Mock()
465
 
        session = mock.Mock()
466
 
        vm = mock.Mock()
467
 
        image_service = mock.Mock()
468
 
 
469
 
        timeout_secs = 10
470
 
        image_size = 1000
471
 
        host = '127.0.0.1'
472
 
        port = 443
473
 
        file_path = '/fake_path'
474
 
        is_public = False
475
 
        image_name = 'fake_image'
476
 
        image_version = 1
477
 
 
478
 
        fake_VmdkReadHandle = 'fake_VmdkReadHandle'
479
 
        fake_rw_handles_VmdkReadHandle.return_value = fake_VmdkReadHandle
480
 
 
481
 
        image_transfer.upload_image(context,
482
 
                                    timeout_secs,
483
 
                                    image_service,
484
 
                                    image_id,
485
 
                                    owner_id,
486
 
                                    session=session,
487
 
                                    host=host,
488
 
                                    port=port,
489
 
                                    vm=vm,
490
 
                                    vmdk_file_path=file_path,
491
 
                                    vmdk_size=image_size,
492
 
                                    is_public=is_public,
493
 
                                    image_name=image_name,
494
 
                                    image_version=image_version)
495
 
 
496
 
        fake_rw_handles_VmdkReadHandle.assert_called_once_with(session,
497
 
                                                               host,
498
 
                                                               port,
499
 
                                                               vm,
500
 
                                                               file_path,
501
 
                                                               image_size)
502
 
 
503
 
        image_metadata = {'disk_format': 'vmdk',
504
 
                          'is_public': is_public,
505
 
                          'name': image_name,
506
 
                          'status': 'active',
507
 
                          'container_format': 'bare',
508
 
                          'size': 0,
509
 
                          'properties': {'vmware_image_version': image_version,
510
 
                                         'vmware_disktype': 'streamOptimized',
511
 
                                         'owner_id': owner_id}}
512
 
 
513
 
        fake_transfer.assert_called_once_with(context,
514
 
                                              timeout_secs,
515
 
                                              fake_VmdkReadHandle,
516
 
                                              0,
517
 
                                              image_service=image_service,
518
 
                                              image_id=image_id,
519
 
                                              image_meta=image_metadata)