cf18199571
The upload-to-image operation downloads (using stream-optimized HTTP NFC transfer) the virtual disk corresponding to the volume to a pipe from where the glance image client reads the data for upload. Due to a recent change in the glance image client, success in seeking the input file object results in forgoing the chunked transfer in favor of regular transfer. The glance image client expects an IOError if the input file object is a pipe. Currently the pipe seek() is a NOP and this results in upload-to-image failure. This changes fixes such failures by throwing an IOError indicating an illegal seek. Change-Id: I2e69fc4103559d49d2cee16ea04787a252dbf879 Closes-Bug: #1295239
68 lines
2.1 KiB
Python
68 lines
2.1 KiB
Python
# Copyright (c) 2014 VMware, Inc.
|
|
# All Rights Reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
"""
|
|
Unit tests for image transfer utility classes.
|
|
"""
|
|
|
|
import math
|
|
|
|
import mock
|
|
|
|
from cinder import test
|
|
from cinder.volume.drivers.vmware import io_util
|
|
|
|
|
|
class ThreadSafePipeTest(test.TestCase):
|
|
"""Tests for ThreadSafePipe."""
|
|
|
|
def test_read(self):
|
|
max_size = 10
|
|
chunk_size = 10
|
|
max_transfer_size = 30
|
|
queue = io_util.ThreadSafePipe(max_size, max_transfer_size)
|
|
|
|
def get_side_effect():
|
|
return [1] * chunk_size
|
|
|
|
queue.get = mock.Mock(side_effect=get_side_effect)
|
|
while True:
|
|
data_item = queue.read(chunk_size)
|
|
if not data_item:
|
|
break
|
|
|
|
self.assertEqual(max_transfer_size, queue.transferred)
|
|
exp_calls = [mock.call()] * int(math.ceil(float(max_transfer_size) /
|
|
chunk_size))
|
|
self.assertEqual(exp_calls, queue.get.call_args_list)
|
|
|
|
def test_write(self):
|
|
queue = io_util.ThreadSafePipe(10, 30)
|
|
queue.put = mock.Mock()
|
|
write_count = 10
|
|
for _ in range(0, write_count):
|
|
queue.write([1])
|
|
exp_calls = [mock.call([1])] * write_count
|
|
self.assertEqual(exp_calls, queue.put.call_args_list)
|
|
|
|
def test_seek(self):
|
|
queue = io_util.ThreadSafePipe(10, 30)
|
|
self.assertRaises(IOError, queue.seek, 0)
|
|
|
|
def test_tell(self):
|
|
max_transfer_size = 30
|
|
queue = io_util.ThreadSafePipe(10, 30)
|
|
self.assertEqual(max_transfer_size, queue.tell())
|