def test_invalid_service_name(mocker, fake_os_object):
    """Verify that the helper raises the correct exception when the caller
    provides an invalid OpenStack service name.

    Args:
        mocker (MockFixture): A wrapper to the Mock library.
        fake_os_object (namedtuple): An object that responds to an attribute
            lookup. ('id')
    """

    # Expect
    prop_name_exp = 'prop'
    prop_value_exp = 'value'

    # Setup
    service_name = 'oops'

    # Mock
    mocker.patch.object(openstack.connection, 'Connection', autospec=True)
    mock_os_api_conn = openstack.connection.Connection()

    # Test
    with pytest.raises(RuntimeError):
        expect_os_property(os_api_conn=mock_os_api_conn,
                           os_service=service_name,
                           os_object=fake_os_object,
                           os_prop_name=prop_name_exp,
                           expected_value=prop_value_exp)
def test_only_extended_props(mocker, fake_os_object):
    """Verify that the helper respects only searching extended properties.

    Args:
        mocker (MockFixture): A wrapper to the Mock library.
        fake_os_object (namedtuple): An object that responds to an attribute
            lookup. ('id')
    """

    # Expect
    prop_name_exp = 'prop'
    prop_value_exp = 'value'

    # Setup
    service_name = 'server'
    prop_dict = {
        prop_name_exp: 'wrong',
        'properties': {
            prop_name_exp: prop_value_exp
        }
    }

    # Mock
    mocker.patch.object(openstack.connection, 'Connection', autospec=True)
    mock_os_api_conn = openstack.connection.Connection()
    mock_os_api_conn.get_server.return_value = prop_dict

    # Test
    assert expect_os_property(os_api_conn=mock_os_api_conn,
                              os_service=service_name,
                              os_object=fake_os_object,
                              os_prop_name=prop_name_exp,
                              expected_value=prop_value_exp,
                              only_extended_props=True)
def test_expect_failure(mocker, fake_os_object):
    """Verify that the helper will return False when the expected property and
    value are NOT satisfied on a OpenStack resource.

    Args:
        mocker (MockFixture): A wrapper to the Mock library.
        fake_os_object (namedtuple): An object that responds to an attribute
            lookup. ('id')
    """

    # Expect
    prop_name_exp = 'prop'
    prop_value_exp = 'value'

    # Setup
    service_name = 'server'
    prop_dict = {prop_name_exp: 'wrong'}

    # Mock
    mocker.patch.object(openstack.connection, 'Connection', autospec=True)
    mock_os_api_conn = openstack.connection.Connection()
    mock_os_api_conn.get_server.return_value = prop_dict

    # Test
    assert not expect_os_property(os_api_conn=mock_os_api_conn,
                                  os_service=service_name,
                                  os_object=fake_os_object,
                                  os_prop_name=prop_name_exp,
                                  expected_value=prop_value_exp,
                                  retries=1)
def test_case_sensitive_mismatch(mocker, fake_os_object):
    """Verify that the helper respects matching only with case sensitivity when
    specified by the caller.

    Args:
        mocker (MockFixture): A wrapper to the Mock library.
        fake_os_object (namedtuple): An object that responds to an attribute
            lookup. ('id')
    """

    # Expect
    prop_name_exp = 'prop'
    prop_value_exp = 'value'

    # Setup
    service_name = 'server'
    prop_dict = {prop_name_exp: prop_value_exp.capitalize()}

    # Mock
    mocker.patch.object(openstack.connection, 'Connection', autospec=True)
    mock_os_api_conn = openstack.connection.Connection()
    mock_os_api_conn.get_server.return_value = prop_dict

    # Test
    assert not expect_os_property(os_api_conn=mock_os_api_conn,
                                  os_service=service_name,
                                  os_object=fake_os_object,
                                  os_prop_name=prop_name_exp,
                                  expected_value=prop_value_exp,
                                  case_insensitive=False,
                                  retries=1)
def test_case_insensitive_match(mocker, fake_os_object):
    """Verify that the helper matches expected value in regardless of casing.

    Args:
        mocker (MockFixture): A wrapper to the Mock library.
        fake_os_object (namedtuple): An object that responds to an attribute
            lookup. ('id')
    """

    # Expect
    prop_name_exp = 'prop'
    prop_value_exp = 'value'

    # Setup
    service_name = 'server'
    prop_dict = {prop_name_exp: prop_value_exp.capitalize()}

    # Mock
    mocker.patch.object(openstack.connection, 'Connection', autospec=True)
    mock_os_api_conn = openstack.connection.Connection()
    mock_os_api_conn.get_server.return_value = prop_dict

    # Test
    assert expect_os_property(os_api_conn=mock_os_api_conn,
                              os_service=service_name,
                              os_object=fake_os_object,
                              os_prop_name=prop_name_exp,
                              expected_value=prop_value_exp)
def test_create_bootable_volume(os_api_conn, create_volume,
                                openstack_properties):
    """Test to verify that a bootable volume can be created based on a
    Glance image.

    Args:
        os_api_conn (openstack.connection.Connection): An authorized API
            connection to the 'default' cloud on the OpenStack infrastructure.
        create_volume (def): A factory function for generating volumes.
        openstack_properties (dict): OpenStack facts and variables from Ansible
            which can be used to manipulate OpenStack objects.
    """

    # Create bootable volume.
    test_volume = create_volume(size=1,
                                image=openstack_properties['cirros_image'],
                                bootable=True)

    # Validate that image was created successfully.
    assert expect_os_property(retries=3,
                              os_object=test_volume,
                              os_service='volume',
                              os_api_conn=os_api_conn,
                              os_prop_name='is_bootable',
                              expected_value='true')
Example #7
0
    def _factory(size,
                 image=None,
                 retries=10,
                 timeout=600,
                 bootable=False,
                 show_warnings=True,
                 skip_teardown=False):
        """Create an OpenStack volume.

        Args:
            size (int): Size, in GB of the volume to create.
            image (openstack.image.v2.image.Image): Image name, ID or object
                from which to create the volume. Name or OpenStack ID is also
                acceptable.
            retries (int): The maximum number of validation retry attempts.
            timeout (int): Seconds to wait, defaults to 600.
            bootable (bool): Make this volume bootable.
            show_warnings (bool): Flag for displaying warnings while attempting
                validate server.(VERY NOISY!)
            skip_teardown (bool): Skip automatic teardown for this server
                instance.

        Returns:
            openstack.compute.v2.server.Server: FYI, this class is not visible
                to the outside user until it gets instantiated.
                (https://bit.ly/2rMu7iQ)

        Raises:
            openstack.connection.exceptions.OpenStackCloudException: The volume
                could not be created for some reason.
            openstack.connection.exceptions.OpenStackCloudTimeout: Wait time
                exceeded.
        """

        temp_volume = os_api_conn.create_volume(
            size=size,
            wait=True,
            name="test_volume_{}".format(helpers.generate_random_string()),
            image=image,
            timeout=timeout,
            bootable=bootable
        )

        # Verify that the volume is available.
        assert helpers.expect_os_property(retries=retries,
                                          os_object=temp_volume,
                                          os_service='volume',
                                          os_api_conn=os_api_conn,
                                          os_prop_name='status',
                                          show_warnings=show_warnings,
                                          expected_value='available')

        if not skip_teardown:
            volumes.append(temp_volume)  # Add volume to inventory for teardown.

        return temp_volume
Example #8
0
def test_snapshot_instance(os_api_conn, create_server, tiny_cirros_server,
                           openstack_properties):
    """Verify that a server can be created from a snapshot image.

    Args:
        os_api_conn (openstack.connection.Connection): An authorized API
            connection to the 'default' cloud on the OpenStack infrastructure.
        create_server (def): A factory function for generating servers.
        tiny_cirros_server (openstack.compute.v2.server.Server): Create a
            'm1.tiny' server instance with a Cirros image.
        openstack_properties(dict): OpenStack facts and variables from Ansible
            which can be used to manipulate OpenStack objects.
    """

    # Create snapshot image from server .
    snapshot_image = os_api_conn.create_image_snapshot(
        wait=True,
        name="snapshot_image_of_{}".format(tiny_cirros_server.name),
        server=tiny_cirros_server)

    # Validate that image was created successfully.
    assert expect_os_property(retries=10,
                              os_object=snapshot_image,
                              os_service='image',
                              os_api_conn=os_api_conn,
                              os_prop_name='status',
                              expected_value='active')

    # Create server from snapshot. (Automatically validated by fixture)
    snapshot_server = create_server(
        image=snapshot_image,
        flavor=openstack_properties['tiny_flavor'],
        network=openstack_properties['test_network'],
        key_name=openstack_properties['key_name'],
        security_groups=[openstack_properties['security_group']])

    # Validate server was created from the snapshot image.
    assert snapshot_server.image.id == snapshot_image.id
Example #9
0
    def _factory(flavor,
                 network,
                 key_name,
                 security_groups,
                 image=None,
                 retries=10,
                 auto_ip=True,
                 timeout=600,
                 boot_volume=None,
                 show_warnings=True,
                 skip_teardown=False,
                 availability_zone=None):
        """Create an OpenStack instance.

        Note: this function uses an exponential back-off for retries which means
        the more retries specified the longer the wait between each retry. The
        total wait time is on the fibonacci sequence. (https://bit.ly/1ee23o9)

        Args:
            flavor (openstack.compute.v2.flavor.Flavor): The flavor property as
                returned from server. (https://bit.ly/2Lxwqzv)
                Name or OpenStack ID is also acceptable.
            network (openstack.network.v2.network.Network): Network dict or name
                or ID to attach the server to. Mutually exclusive with the nics
                parameter. Can also be be a list of network names or IDs or
                network dicts. (https://bit.ly/2A104IL)
            key_name (str): The name of an associated keypair.
            security_groups(list): A list of security group names.
            image (openstack.image.v2.image.Image): The image property as
                returned from server. image is required unless boot_volume is
                given. Name or OpenStack ID is also acceptable.
                (https://bit.ly/2UXESvW)
            retries (int): The maximum number of validation retry attempts.
            auto_ip (bool): Flag for specifying whether a floating IP should be
                attached to the instance automatically.
            timeout (int): Seconds to wait, defaults to 600.
            boot_volume (openstack.image.v2.volume.Volume): Volume to boot from.
                Name or OpenStack ID is also acceptable.
                (https://bit.ly/2ReINW7)
            show_warnings (bool): Flag for displaying warnings while attempting
                validate server.(VERY NOISY!)
            skip_teardown (bool): Skip automatic teardown for this server
                instance.
            availability_zone (str): Name of the availability zone for instance
                placement.

        Returns:
            openstack.compute.v2.server.Server: FYI, this class is not visible
                to the outside user until it gets instantiated.
                (https://bit.ly/2rMu7iQ)

        Raises:
            openstack.connection.exceptions.OpenStackCloudException: The server
                could not be created for some reason.
            RuntimeError: Mutually exclusive required arguments 'boot_volume' or
                'image' are not set properly!

        Example:
            >>> conn = openstack.connect(cloud='default')
            >>> image = conn.compute.find_image('test_image')
            >>> flavor = conn.compute.find_flavor('test_flavor')
            >>> network = conn.network.find_network('test_network')
            >>> key_pair_name = 'test_keypair'
            >>> security_groups = ['test-security-group']
            >>>
            >>> server = _factory(name='test_server',
            >>>                   image=image,
            >>>                   flavor=flavor,
            >>>                   network=network,
            >>>                   key_name=key_pair_name,
            >>>                   security_groups=security_groups)

            See https://bit.ly/2EDWA2S for more details.
        """

        # Configure mutually exclusive arguments.
        if image is not None and boot_volume is None:
            extra_args = {'image': image}
        elif boot_volume is not None and image is None:
            extra_args = {'boot_volume': boot_volume}
        else:
            raise RuntimeError("Mutually exclusive required arguments "
                               "'boot_volume' or 'image' are not set properly!")

        if availability_zone:
            extra_args['availability_zone'] = availability_zone

        temp_server = os_api_conn.create_server(
            wait=True,
            name="test_server_{}".format(helpers.generate_random_string()),
            flavor=flavor,
            auto_ip=False,
            network=network,
            timeout=timeout,
            key_name=key_name,
            security_groups=security_groups,
            **extra_args
        )

        # Sometimes the OpenStack object is not fully built even after waiting.
        sleep(2)

        shared_args = {'retries': retries,
                       'os_object': temp_server,
                       'os_service': 'server',
                       'os_api_conn': os_api_conn,
                       'show_warnings': show_warnings}

        # Verify that the server is on and running.
        assert helpers.expect_os_property(os_prop_name='status',
                                          expected_value='ACTIVE',
                                          **shared_args)

        assert helpers.expect_os_property(os_prop_name='OS-EXT-STS:power_state',
                                          expected_value='1',
                                          **shared_args)

        assert helpers.expect_os_property(os_prop_name='OS-EXT-STS:vm_state',
                                          expected_value='active',
                                          **shared_args)

        # Create floating IP address and attach to test server.
        if auto_ip:
            # TODO: The 'auto_ip' feature of 'create_server' is broken.
            #   (ASC-1416)
            # Delete all unattached floating IPs.
            os_api_conn.delete_unattached_floating_ips(retry=3)

            floating_ip = os_api_conn.create_floating_ip(
                wait=True,
                server=temp_server,
                network=openstack_properties['network_name'],
                timeout=600
            )

            temp_server['accessIPv4'] = floating_ip.floating_ip_address
            temp_server['access_ipv4'] = floating_ip.floating_ip_address

        if not skip_teardown:
            servers.append(temp_server)  # Add server to inventory for teardown.

        return temp_server