From 24255ad0dde608a19d371a27c13714098097f185 Mon Sep 17 00:00:00 2001 From: whoami-rajat Date: Thu, 13 Dec 2018 11:15:09 +0530 Subject: [PATCH] Fix: Restore output 'VolumeBackupsRestore' object is not iterable VolumeBackupsRetore object has '_info' attribute which contains the output data of the restore command which should be returned instead of the 'VolumeBackupsRestore' object. Change-Id: I64b75649c1ac9c24e05a197f7280975564b4d386 Story: 2004740 Task: 28811 --- .zuul.yaml | 4 +- .../tests/functional/volume/v2/test_backup.py | 58 +++++++++++++++++++ .../tests/unit/volume/v2/test_backup.py | 6 +- openstackclient/volume/v2/backup.py | 4 +- 4 files changed, 67 insertions(+), 5 deletions(-) create mode 100644 openstackclient/tests/functional/volume/v2/test_backup.py diff --git a/.zuul.yaml b/.zuul.yaml index 356a97e6d5..9a94dd934b 100644 --- a/.zuul.yaml +++ b/.zuul.yaml @@ -166,11 +166,11 @@ s-container: false s-object: false s-proxy: false - # As swift is not available for this job, c-backup service won't be functional. + # As swift is not available for this job, c-bak service won't be functional. # The backup related tests can be handled by other jobs having swift enabled. # The backup service along with swift services can be enabled once swift is # compatible with py3 - c-backup: false + c-bak: false tox_envlist: functional tox_install_siblings: true diff --git a/openstackclient/tests/functional/volume/v2/test_backup.py b/openstackclient/tests/functional/volume/v2/test_backup.py new file mode 100644 index 0000000000..e4890b00ea --- /dev/null +++ b/openstackclient/tests/functional/volume/v2/test_backup.py @@ -0,0 +1,58 @@ +# 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. + +import json +import uuid + +from openstackclient.tests.functional.volume.v2 import common + + +class VolumeBackupTests(common.BaseVolumeTests): + """Functional tests for volume backups. """ + + def setUp(self): + super(VolumeBackupTests, self).setUp() + self.backup_enabled = False + serv_list = json.loads(self.openstack('volume service list -f json')) + for service in serv_list: + if service['Binary'] == 'cinder-backup': + if service['Status'] == 'enabled': + self.backup_enabled = True + + def test_volume_backup_restore(self): + """Test restore backup""" + if not self.backup_enabled: + self.skipTest('Backup service is not enabled') + vol_id = uuid.uuid4().hex + # create a volume + json.loads(self.openstack( + 'volume create -f json ' + + '--size 1 ' + + vol_id + )) + # create a backup + backup = json.loads(self.openstack( + 'volume backup create -f json ' + + vol_id + )) + + self.wait_for_status("volume", vol_id, "available") + self.wait_for_status("backup", backup['id'], "available") + # restore the backup + backup_restored = json.loads(self.openstack( + 'volume backup restore -f json %s %s' + % (backup['id'], vol_id))) + self.assertEqual(backup_restored['backup_id'], backup['id']) + self.wait_for_status("backup", backup['id'], "available") + self.wait_for_status("volume", backup_restored['volume_id'], + "available") + self.addCleanup(self.openstack, 'volume delete %s' % vol_id) diff --git a/openstackclient/tests/unit/volume/v2/test_backup.py b/openstackclient/tests/unit/volume/v2/test_backup.py index a8e81c7eb8..9a2ce71809 100644 --- a/openstackclient/tests/unit/volume/v2/test_backup.py +++ b/openstackclient/tests/unit/volume/v2/test_backup.py @@ -367,7 +367,9 @@ class TestBackupRestore(TestBackup): self.backups_mock.get.return_value = self.backup self.volumes_mock.get.return_value = self.volume - self.restores_mock.restore.return_value = None + self.restores_mock.restore.return_value = ( + volume_fakes.FakeVolume.create_one_volume( + {'id': self.volume['id']})) # Get the command object to mock self.cmd = backup.RestoreVolumeBackup(self.app, None) @@ -385,7 +387,7 @@ class TestBackupRestore(TestBackup): result = self.cmd.take_action(parsed_args) self.restores_mock.restore.assert_called_with(self.backup.id, self.backup.volume_id) - self.assertIsNone(result) + self.assertIsNotNone(result) class TestBackupSet(TestBackup): diff --git a/openstackclient/volume/v2/backup.py b/openstackclient/volume/v2/backup.py index 60633a7080..d4aec8d747 100644 --- a/openstackclient/volume/v2/backup.py +++ b/openstackclient/volume/v2/backup.py @@ -319,7 +319,9 @@ class RestoreVolumeBackup(command.ShowOne): backup = utils.find_resource(volume_client.backups, parsed_args.backup) destination_volume = utils.find_resource(volume_client.volumes, parsed_args.volume) - return volume_client.restores.restore(backup.id, destination_volume.id) + backup = volume_client.restores.restore(backup.id, + destination_volume.id) + return zip(*sorted(six.iteritems(backup._info))) class RestoreBackup(RestoreVolumeBackup):