summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cinderclient/tests/unit/v3/fakes.py55
-rw-r--r--cinderclient/tests/unit/v3/test_attachments.py36
-rw-r--r--cinderclient/tests/unit/v3/test_shell.py6
-rw-r--r--cinderclient/v3/attachments.py4
4 files changed, 95 insertions, 6 deletions
diff --git a/cinderclient/tests/unit/v3/fakes.py b/cinderclient/tests/unit/v3/fakes.py
index 9fd614a..910633e 100644
--- a/cinderclient/tests/unit/v3/fakes.py
+++ b/cinderclient/tests/unit/v3/fakes.py
@@ -20,6 +20,42 @@ from cinderclient.tests.unit import fakes
from cinderclient.tests.unit.v2 import fakes as fake_v2
+fake_attachment = {'attachment': {
+ 'status': 'reserved',
+ 'detached_at': '',
+ 'connection_info': {},
+ 'attached_at': '',
+ 'attach_mode': None,
+ 'id': 'a232e9ae',
+ 'instance': 'e84fda45-4de4-4ce4-8f39-fc9d3b0aa05e',
+ 'volume_id': '557ad76c-ce54-40a3-9e91-c40d21665cc3', }}
+
+fake_connection_info = {
+ 'auth_password': 'i6h9E5HQqSkcGX3H',
+ 'attachment_id': 'a232e9ae',
+ 'target_discovered': False,
+ 'encrypted': False,
+ 'driver_volume_type': 'iscsi',
+ 'qos_specs': None,
+ 'target_iqn': 'iqn.2010-10.org.openstack:volume-557ad76c',
+ 'target_portal': '10.117.36.28:3260',
+ 'volume_id': '557ad76c-ce54-40a3-9e91-c40d21665cc3',
+ 'target_lun': 0,
+ 'access_mode': 'rw',
+ 'auth_username': 'MwRrnAFLHN7enw5R95yM',
+ 'auth_method': 'CHAP'}
+
+fake_connector = {
+ 'initiator': 'iqn.1993-08.org.debian:01:b79dbce99387',
+ 'mount_device': '/dev/vdb',
+ 'ip': '10.117.36.28',
+ 'platform': 'x86_64',
+ 'host': 'os-2',
+ 'do_local_attach': False,
+ 'os_type': 'linux2',
+ 'multipath': False}
+
+
def _stub_group(detailed=True, **kwargs):
group = {
"name": "test-1",
@@ -241,12 +277,9 @@ class FakeHTTPClient(fake_v2.FakeHTTPClient):
#
# Attachments
#
+
def post_attachments(self, **kw):
- return (202, {}, {
- 'attachment': {'instance': 1234,
- 'name': 'attachment-1',
- 'volume_id': 'fake_volume_1',
- 'status': 'reserved'}})
+ return (200, {}, fake_attachment)
def get_attachments(self, **kw):
return (200, {}, {
@@ -259,6 +292,16 @@ class FakeHTTPClient(fake_v2.FakeHTTPClient):
'volume_id': 'fake_volume_2',
'status': 'reserverd'}]})
+ def post_attachments_a232e9ae_action(self, **kw): # noqa: E501
+ attached_fake = fake_attachment
+ attached_fake['status'] = 'attached'
+ return (200, {}, attached_fake)
+
+ def post_attachments_1234_action(self, **kw): # noqa: E501
+ attached_fake = fake_attachment
+ attached_fake['status'] = 'attached'
+ return (200, {}, attached_fake)
+
def get_attachments_1234(self, **kw):
return (200, {}, {
'attachment': {'instance': 1234,
@@ -294,7 +337,7 @@ class FakeHTTPClient(fake_v2.FakeHTTPClient):
return (200, {}, {'group_type': {'id': 1,
'name': 'test-type-1',
'description': 'test_type-1-desc',
- 'group_specs': {u'key': u'value'}}})
+ 'group_specs': {'key': 'value'}}})
def get_group_types_2(self, **kw):
return (200, {}, {'group_type': {'id': 2,
diff --git a/cinderclient/tests/unit/v3/test_attachments.py b/cinderclient/tests/unit/v3/test_attachments.py
new file mode 100644
index 0000000..5fee5b4
--- /dev/null
+++ b/cinderclient/tests/unit/v3/test_attachments.py
@@ -0,0 +1,36 @@
+# Copyright (C) 2016 EMC Corporation.
+#
+# 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.
+
+from cinderclient.tests.unit import utils
+from cinderclient.tests.unit.v3 import fakes
+
+cs = fakes.FakeClient()
+
+
+class AttachmentsTest(utils.TestCase):
+
+ def test_create_attachment(self):
+ att = cs.attachments.create(
+ 'e84fda45-4de4-4ce4-8f39-fc9d3b0aa05e',
+ {},
+ '557ad76c-ce54-40a3-9e91-c40d21665cc3')
+ cs.assert_called('POST', '/attachments')
+ self.assertEqual(fakes.fake_attachment['attachment'], att)
+
+ def test_complete_attachment(self):
+ att = cs.attachments.complete(
+ 'a232e9ae')
+ self.assertTrue(att.ok)
diff --git a/cinderclient/tests/unit/v3/test_shell.py b/cinderclient/tests/unit/v3/test_shell.py
index a7be695..ce24763 100644
--- a/cinderclient/tests/unit/v3/test_shell.py
+++ b/cinderclient/tests/unit/v3/test_shell.py
@@ -376,6 +376,12 @@ class ShellTest(utils.TestCase):
self.assert_called('PUT', '/attachments/1234', body={'attachment':
body})
+ @ddt.unpack
+ def test_attachment_complete(self):
+ command = '--os-volume-api-version 3.44 attachment-complete 1234'
+ self.run_command(command)
+ self.assert_called('POST', '/attachments/1234/action', body=None)
+
def test_attachment_delete(self):
self.run_command('--os-volume-api-version 3.27 '
'attachment-delete 1234')
diff --git a/cinderclient/v3/attachments.py b/cinderclient/v3/attachments.py
index 6146626..aaa8bcf 100644
--- a/cinderclient/v3/attachments.py
+++ b/cinderclient/v3/attachments.py
@@ -12,6 +12,7 @@
"""Attachment interface."""
+from cinderclient import api_versions
from cinderclient import base
@@ -64,9 +65,12 @@ class VolumeAttachmentManager(base.ManagerWithFind):
"""Attachment update."""
body = {'attachment': {'connector': connector}}
resp = self._update('/attachments/%s' % id, body)
+ # NOTE(jdg): This kinda sucks,
+ # create returns a dict, but update returns an object :(
return self.resource_class(self, resp['attachment'], loaded=True,
resp=resp)
+ @api_versions.wraps('3.44')
def complete(self, attachment):
"""Mark the attachment as completed."""
resp, body = self._action_return_resp_and_body('os-complete',