diff options
| author | Gorka Eguileor <geguileo@redhat.com> | 2016-10-17 14:39:33 +0200 |
|---|---|---|
| committer | Gorka Eguileor <geguileo@redhat.com> | 2017-10-03 11:03:28 +0200 |
| commit | 8fce74056fa4afd03149ede9d4b8786cc78ada3e (patch) | |
| tree | 7c10f8bca19f71a315b0d02e87d1a4e67ec94845 /cinderclient/tests/unit | |
| parent | 6c214eeec096be25d3f231fa71bb32a9a22c75cf (diff) | |
| download | python-cinderclient-8fce74056fa4afd03149ede9d4b8786cc78ada3e.tar.gz | |
Add cluster support in migration and manage
This patch adds support for API microversion 3.16, which allows us to
pass --cluster optional argument to migration and manage operations.
For this, a new type of CLI argument is added, the mutually exclusive
arguments that can be used similarly to the utils.arg decorator, but
with utils.exclusive_arg decorator.
Implements: blueprint cinder-volume-active-active-support
Change-Id: If004715b9887d2a0f9fc630b44d6e11a4a8b778d
Diffstat (limited to 'cinderclient/tests/unit')
| -rw-r--r-- | cinderclient/tests/unit/v2/fakes.py | 9 | ||||
| -rw-r--r-- | cinderclient/tests/unit/v2/test_volumes.py | 32 | ||||
| -rw-r--r-- | cinderclient/tests/unit/v3/test_shell.py | 126 | ||||
| -rw-r--r-- | cinderclient/tests/unit/v3/test_volumes.py | 32 |
4 files changed, 184 insertions, 15 deletions
diff --git a/cinderclient/tests/unit/v2/fakes.py b/cinderclient/tests/unit/v2/fakes.py index 3e24793..4edf02a 100644 --- a/cinderclient/tests/unit/v2/fakes.py +++ b/cinderclient/tests/unit/v2/fakes.py @@ -543,6 +543,15 @@ class FakeHTTPClient(base_client.HTTPClient): raise AssertionError("Unexpected action: %s" % action) return (resp, {}, _body) + def get_volumes_fake(self, **kw): + r = {'volume': self.get_volumes_detail(id='fake')[2]['volumes'][0]} + return (200, {}, r) + + def post_volumes_fake_action(self, body, **kw): + _body = None + resp = 202 + return (resp, {}, _body) + def post_volumes_5678_action(self, body, **kw): return self.post_volumes_1234_action(body, **kw) diff --git a/cinderclient/tests/unit/v2/test_volumes.py b/cinderclient/tests/unit/v2/test_volumes.py index 6e5fd2f..60549ea 100644 --- a/cinderclient/tests/unit/v2/test_volumes.py +++ b/cinderclient/tests/unit/v2/test_volumes.py @@ -15,11 +15,13 @@ # License for the specific language governing permissions and limitations # under the License. +from cinderclient import api_versions from cinderclient.tests.unit import utils from cinderclient.tests.unit.v2 import fakes from cinderclient.v2.volumes import Volume cs = fakes.FakeClient() +cs3 = fakes.FakeClient(api_versions.APIVersion('3.15')) class VolumesTest(utils.TestCase): @@ -211,23 +213,23 @@ class VolumesTest(utils.TestCase): self._assert_request_id(vol) def test_migrate(self): - v = cs.volumes.get('1234') + v = cs3.volumes.get('1234') self._assert_request_id(v) - vol = cs.volumes.migrate_volume(v, 'dest', False, False) - cs.assert_called('POST', '/volumes/1234/action', - {'os-migrate_volume': {'host': 'dest', - 'force_host_copy': False, + vol = cs3.volumes.migrate_volume(v, 'dest', False, False) + cs3.assert_called('POST', '/volumes/1234/action', + {'os-migrate_volume': {'host': 'dest', + 'force_host_copy': False, 'lock_volume': False}}) self._assert_request_id(vol) def test_migrate_with_lock_volume(self): - v = cs.volumes.get('1234') + v = cs3.volumes.get('1234') self._assert_request_id(v) - vol = cs.volumes.migrate_volume(v, 'dest', False, True) - cs.assert_called('POST', '/volumes/1234/action', - {'os-migrate_volume': {'host': 'dest', - 'force_host_copy': False, - 'lock_volume': True}}) + vol = cs3.volumes.migrate_volume(v, 'dest', False, True) + cs3.assert_called('POST', '/volumes/1234/action', + {'os-migrate_volume': {'host': 'dest', + 'force_host_copy': False, + 'lock_volume': True}}) self._assert_request_id(vol) def test_metadata_update_all(self): @@ -260,19 +262,19 @@ class VolumesTest(utils.TestCase): self._assert_request_id(vol) def test_volume_manage(self): - vol = cs.volumes.manage('host1', {'k': 'v'}) + vol = cs3.volumes.manage('host1', {'k': 'v'}) expected = {'host': 'host1', 'name': None, 'availability_zone': None, 'description': None, 'metadata': None, 'ref': {'k': 'v'}, 'volume_type': None, 'bootable': False} - cs.assert_called('POST', '/os-volume-manage', {'volume': expected}) + cs3.assert_called('POST', '/os-volume-manage', {'volume': expected}) self._assert_request_id(vol) def test_volume_manage_bootable(self): - vol = cs.volumes.manage('host1', {'k': 'v'}, bootable=True) + vol = cs3.volumes.manage('host1', {'k': 'v'}, bootable=True) expected = {'host': 'host1', 'name': None, 'availability_zone': None, 'description': None, 'metadata': None, 'ref': {'k': 'v'}, 'volume_type': None, 'bootable': True} - cs.assert_called('POST', '/os-volume-manage', {'volume': expected}) + cs3.assert_called('POST', '/os-volume-manage', {'volume': expected}) self._assert_request_id(vol) def test_volume_list_manageable(self): diff --git a/cinderclient/tests/unit/v3/test_shell.py b/cinderclient/tests/unit/v3/test_shell.py index 87567dc..f756ec1 100644 --- a/cinderclient/tests/unit/v3/test_shell.py +++ b/cinderclient/tests/unit/v3/test_shell.py @@ -1007,3 +1007,129 @@ class ShellTest(utils.TestCase): columns = ['ID', 'Volume ID', 'Status', 'Name', 'Size', 'User ID'] mock_print_list.assert_called_once_with(mock.ANY, columns, sortby_index=0) + + @mock.patch('cinderclient.v3.volumes.Volume.migrate_volume') + def test_migrate_volume_before_3_16(self, v3_migrate_mock): + self.run_command('--os-volume-api-version 3.15 ' + 'migrate 1234 fakehost') + + v3_migrate_mock.assert_called_once_with( + 'fakehost', False, False, None) + + @mock.patch('cinderclient.v3.volumes.Volume.migrate_volume') + def test_migrate_volume_3_16(self, v3_migrate_mock): + self.run_command('--os-volume-api-version 3.16 ' + 'migrate 1234 fakehost') + self.assertEqual(4, len(v3_migrate_mock.call_args[0])) + + def test_migrate_volume_with_cluster_before_3_16(self): + self.assertRaises(exceptions.UnsupportedAttribute, + self.run_command, + '--os-volume-api-version 3.15 ' + 'migrate 1234 fakehost --cluster fakecluster') + + @mock.patch('cinderclient.shell.CinderClientArgumentParser.error') + def test_migrate_volume_mutual_exclusion(self, error_mock): + error_mock.side_effect = SystemExit + self.assertRaises(SystemExit, + self.run_command, + '--os-volume-api-version 3.16 ' + 'migrate 1234 fakehost --cluster fakecluster') + msg = 'argument --cluster: not allowed with argument <host>' + error_mock.assert_called_once_with(msg) + + @mock.patch('cinderclient.shell.CinderClientArgumentParser.error') + def test_migrate_volume_missing_required(self, error_mock): + error_mock.side_effect = SystemExit + self.assertRaises(SystemExit, + self.run_command, + '--os-volume-api-version 3.16 ' + 'migrate 1234') + msg = 'one of the arguments <host> --cluster is required' + error_mock.assert_called_once_with(msg) + + def test_migrate_volume_host(self): + self.run_command('--os-volume-api-version 3.16 ' + 'migrate 1234 fakehost') + expected = {'os-migrate_volume': {'force_host_copy': False, + 'lock_volume': False, + 'host': 'fakehost'}} + self.assert_called('POST', '/volumes/1234/action', body=expected) + + def test_migrate_volume_cluster(self): + self.run_command('--os-volume-api-version 3.16 ' + 'migrate 1234 --cluster mycluster') + expected = {'os-migrate_volume': {'force_host_copy': False, + 'lock_volume': False, + 'cluster': 'mycluster'}} + self.assert_called('POST', '/volumes/1234/action', body=expected) + + def test_migrate_volume_bool_force(self): + self.run_command('--os-volume-api-version 3.16 ' + 'migrate 1234 fakehost --force-host-copy ' + '--lock-volume') + expected = {'os-migrate_volume': {'force_host_copy': True, + 'lock_volume': True, + 'host': 'fakehost'}} + self.assert_called('POST', '/volumes/1234/action', body=expected) + + def test_migrate_volume_bool_force_false(self): + # Set both --force-host-copy and --lock-volume to False. + self.run_command('--os-volume-api-version 3.16 ' + 'migrate 1234 fakehost --force-host-copy=False ' + '--lock-volume=False') + expected = {'os-migrate_volume': {'force_host_copy': 'False', + 'lock_volume': 'False', + 'host': 'fakehost'}} + self.assert_called('POST', '/volumes/1234/action', body=expected) + + # Do not set the values to --force-host-copy and --lock-volume. + self.run_command('--os-volume-api-version 3.16 ' + 'migrate 1234 fakehost') + expected = {'os-migrate_volume': {'force_host_copy': False, + 'lock_volume': False, + 'host': 'fakehost'}} + self.assert_called('POST', '/volumes/1234/action', + body=expected) + + @ddt.data({'bootable': False, 'by_id': False, 'cluster': None}, + {'bootable': True, 'by_id': False, 'cluster': None}, + {'bootable': False, 'by_id': True, 'cluster': None}, + {'bootable': True, 'by_id': True, 'cluster': None}, + {'bootable': True, 'by_id': True, 'cluster': 'clustername'}) + @ddt.unpack + def test_volume_manage(self, bootable, by_id, cluster): + cmd = ('--os-volume-api-version 3.16 ' + 'manage host1 some_fake_name --name foo --description bar ' + '--volume-type baz --availability-zone az ' + '--metadata k1=v1 k2=v2') + if by_id: + cmd += ' --id-type source-id' + if bootable: + cmd += ' --bootable' + if cluster: + cmd += ' --cluster ' + cluster + + self.run_command(cmd) + ref = 'source-id' if by_id else 'source-name' + expected = {'volume': {'host': 'host1', + 'ref': {ref: 'some_fake_name'}, + 'name': 'foo', + 'description': 'bar', + 'volume_type': 'baz', + 'availability_zone': 'az', + 'metadata': {'k1': 'v1', 'k2': 'v2'}, + 'bootable': bootable}} + if cluster: + expected['cluster'] = cluster + self.assert_called_anytime('POST', '/os-volume-manage', body=expected) + + def test_volume_manage_before_3_16(self): + """Cluster optional argument was not acceptable.""" + self.assertRaises(exceptions.UnsupportedAttribute, + self.run_command, + 'manage host1 some_fake_name ' + '--cluster clustername' + '--name foo --description bar --bootable ' + '--volume-type baz --availability-zone az ' + '--metadata k1=v1 k2=v2') diff --git a/cinderclient/tests/unit/v3/test_volumes.py b/cinderclient/tests/unit/v3/test_volumes.py index ff75700..75eb30f 100644 --- a/cinderclient/tests/unit/v3/test_volumes.py +++ b/cinderclient/tests/unit/v3/test_volumes.py @@ -27,6 +27,7 @@ from cinderclient.v3 import volumes from six.moves.urllib import parse cs = fakes.FakeClient() +cs3 = fakes.FakeClient(api_versions.APIVersion('3.16')) @ddt.ddt @@ -145,3 +146,34 @@ class VolumesTest(utils.TestCase): request_url = '/scheduler-stats/get_pools?detail=True&name=pool1' cs.assert_called('GET', request_url) self._assert_request_id(vol) + + def test_migrate_host(self): + v = cs3.volumes.get('1234') + self._assert_request_id(v) + vol = cs3.volumes.migrate_volume(v, 'host_dest', False, False) + cs3.assert_called('POST', '/volumes/1234/action', + {'os-migrate_volume': {'host': 'host_dest', + 'force_host_copy': False, + 'lock_volume': False}}) + self._assert_request_id(vol) + + def test_migrate_with_lock_volume(self): + v = cs3.volumes.get('1234') + self._assert_request_id(v) + vol = cs3.volumes.migrate_volume(v, 'dest', False, True) + cs3.assert_called('POST', '/volumes/1234/action', + {'os-migrate_volume': {'host': 'dest', + 'force_host_copy': False, + 'lock_volume': True}}) + self._assert_request_id(vol) + + def test_migrate_cluster(self): + v = cs3.volumes.get('fake') + self._assert_request_id(v) + vol = cs3.volumes.migrate_volume(v, 'host_dest', False, False, + 'cluster_dest') + cs3.assert_called('POST', '/volumes/fake/action', + {'os-migrate_volume': {'cluster': 'cluster_dest', + 'force_host_copy': False, + 'lock_volume': False}}) + self._assert_request_id(vol) |
