#    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 nova.tests import fixtures as nova_fixtures
from nova.tests.functional import integrated_helpers


class TestMultiattachVolumes(integrated_helpers._IntegratedTestBase):
    """Functional tests for creating a server from a multiattach volume
    and attaching a multiattach volume to a server.

    Uses the CinderFixture fixture with a specific volume ID
    to represent a multiattach volume.
    """
    # These are all used in _IntegratedTestBase.
    api_major_version = 'v2.1'
    microversion = '2.60'
    _image_ref_parameter = 'imageRef'
    _flavor_ref_parameter = 'flavorRef'

    def setUp(self):
        # Everything has been upgraded to the latest code to support
        # multiattach.
        self.useFixture(nova_fixtures.AllServicesCurrent())
        super(TestMultiattachVolumes, self).setUp()
        self.useFixture(nova_fixtures.CinderFixture(self))

    def test_boot_from_volume_and_attach_to_second_server(self):
        """This scenario creates a server from the multiattach volume, waits
        for it to be ACTIVE, and then attaches the volume to another server.
        """
        volume_id = nova_fixtures.CinderFixture.MULTIATTACH_VOL
        create_req = self._build_server(
            image_uuid='', flavor_id='1', networks='none')
        create_req['block_device_mapping_v2'] = [{
            'uuid': volume_id,
            'source_type': 'volume',
            'destination_type': 'volume',
            'delete_on_termination': False,
            'boot_index': 0
        }]
        server = self.api.post_server({'server': create_req})
        self._wait_for_state_change(server, 'ACTIVE')
        # Make sure the volume is attached to the first server.
        attachments = self.api.api_get(
            '/servers/%s/os-volume_attachments' % server['id']).body[
            'volumeAttachments']
        self.assertEqual(1, len(attachments))
        self.assertEqual(server['id'], attachments[0]['serverId'])
        self.assertEqual(volume_id, attachments[0]['volumeId'])

        # Now create a second server and attach the same volume to that.
        server2 = self._create_server(
            image_uuid='155d900f-4e14-4e4c-a73d-069cbf4541e6',
            flavor_id='1',
            networks='none')
        # Attach the volume to the second server.
        self.api.api_post('/servers/%s/os-volume_attachments' % server2['id'],
                          {'volumeAttachment': {'volumeId': volume_id}})
        # Make sure the volume is attached to the second server.
        attachments = self.api.api_get(
            '/servers/%s/os-volume_attachments' % server2['id']).body[
            'volumeAttachments']
        self.assertEqual(1, len(attachments))
        self.assertEqual(server2['id'], attachments[0]['serverId'])
        self.assertEqual(volume_id, attachments[0]['volumeId'])
