diff --git a/openstack_dashboard/test/selenium/integration/test_floatingips.py b/openstack_dashboard/test/selenium/integration/test_floatingips.py new file mode 100644 index 0000000000..dd4c4b0497 --- /dev/null +++ b/openstack_dashboard/test/selenium/integration/test_floatingips.py @@ -0,0 +1,166 @@ +# 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 re + +from oslo_utils import uuidutils +import pytest +import test_instances + +from openstack_dashboard.test.selenium import widgets + +# Imported fixtures +instance_name = test_instances.instance_name +new_instance_demo = test_instances.new_instance_demo + + +@pytest.fixture +def floatingip_description(): + return('horizon_floatingip_description_%s' + % uuidutils.generate_uuid(dashed=False)) + + +@pytest.fixture +def new_floating_ip(openstack_demo, config): + floatingip = openstack_demo.network.create_ip( + floating_network_id=openstack_demo.network.find_network( + config.network.external_network).id + ) + yield floatingip + openstack_demo.network.delete_ip(floatingip) + + +@pytest.fixture +def clear_floatingip_using_description(openstack_demo, floatingip_description): + yield None + floatingips_list = openstack_demo.network.get( + "/floatingips").json()["floatingips"] + ip_address = None + for floatingip_data in floatingips_list: + if floatingip_data['description'] == floatingip_description: + ip_address = floatingip_data['floating_ip_address'] + break + openstack_demo.network.delete_ip( + openstack_demo.network.find_ip(ip_address)) + + +@pytest.fixture +def clear_floatingip_using_ip(openstack_demo, new_instance_demo): + yield None + openstack_demo.network.delete_ip( + openstack_demo.network.find_ip(new_instance_demo.public_v4)) + + +def test_allocate_floatingip(login, driver, config, openstack_demo, + clear_floatingip_using_description, + floatingip_description): + login('user') + url = '/'.join(( + config.dashboard.dashboard_url, + 'project', + 'floating_ips', + )) + driver.get(url) + driver.find_element_by_link_text("Allocate IP To Project").click() + floatingip_form = driver.find_element_by_css_selector(".modal-dialog form") + floatingip_form.find_element_by_id("id_description").send_keys( + floatingip_description) + floatingip_form.find_element_by_css_selector(".btn-primary").click() + messages = widgets.get_and_dismiss_messages(driver) + if len(messages) > 1: + message = [msg for msg in messages if + "Success: Allocated Floating IP" in msg][0] + else: + message = messages[0] + assert 'Success: Allocated Floating IP' in message + ip_address = re.search(r"\d+\.\d+\.\d+\.\d+", message) + assert ip_address is not None + floating_ip_address = ip_address.group() + assert openstack_demo.network.find_ip(floating_ip_address) is not None + + +def test_release_floatingip(login, driver, openstack_demo, config, + new_floating_ip): + login('user') + url = '/'.join(( + config.dashboard.dashboard_url, + 'project', + 'floating_ips', + )) + driver.get(url) + rows = driver.find_elements_by_css_selector( + f"table#floating_ips tr[data-display=" + f"'{new_floating_ip.floating_ip_address}']") + assert len(rows) == 1 + actions_column = rows[0].find_element_by_css_selector("td.actions_column") + widgets.select_from_dropdown(actions_column, "Release Floating IP") + widgets.confirm_modal(driver) + messages = widgets.get_and_dismiss_messages(driver) + assert(f"Success: Released Floating IP: " + f"{new_floating_ip.floating_ip_address}" in messages) + assert openstack_demo.network.find_ip( + new_floating_ip.floating_ip_address) is None + + +@pytest.mark.parametrize('new_instance_demo', [(1, "private", False)], + indirect=True) +def test_associate_floatingip(login, driver, openstack_demo, new_floating_ip, + config, instance_name, new_instance_demo): + login('user') + url = '/'.join(( + config.dashboard.dashboard_url, + 'project', + 'floating_ips', + )) + driver.get(url) + rows = driver.find_elements_by_css_selector( + f"table#floating_ips tr[data-display=" + f"'{new_floating_ip.floating_ip_address}']") + assert len(rows) == 1 + rows[0].find_element_by_css_selector(".data-table-action").click() + associateip_form = driver.find_element_by_css_selector( + "form .modal-content") + widgets.select_from_specific_dropdown_in_form( + associateip_form, "id_ip_id", new_floating_ip.floating_ip_address) + widgets.select_from_specific_dropdown_in_form( + associateip_form, "id_port_id", + f"{instance_name}: {new_instance_demo.private_v4}") + associateip_form.find_element_by_css_selector(".btn-primary").click() + messages = widgets.get_and_dismiss_messages(driver) + assert(f"Success: IP address {new_floating_ip.floating_ip_address}" + f" associated." in messages) + assert(new_instance_demo.id == openstack_demo.network.find_ip( + new_floating_ip.floating_ip_address).port_details['device_id']) + + +@pytest.mark.parametrize('new_instance_demo', [(1, "private", True)], + indirect=True) +def test_disassociate_floatingip(login, driver, openstack_demo, config, + instance_name, new_instance_demo, + clear_floatingip_using_ip): + login('user') + url = '/'.join(( + config.dashboard.dashboard_url, + 'project', + 'floating_ips', + )) + driver.get(url) + rows = driver.find_elements_by_css_selector( + f"table#floating_ips tr[data-display=" + f"'{new_instance_demo.public_v4}']") + assert len(rows) == 1 + rows[0].find_element_by_css_selector(".data-table-action").click() + widgets.confirm_modal(driver) + messages = widgets.get_and_dismiss_messages(driver) + assert(f"Success: Successfully disassociated Floating IP: " + f"{new_instance_demo.public_v4}" in messages) + assert openstack_demo.compute.find_server(instance_name).public_v4 == "" diff --git a/openstack_dashboard/test/selenium/integration/test_instances.py b/openstack_dashboard/test/selenium/integration/test_instances.py index af3e32dc0e..d420d63d06 100644 --- a/openstack_dashboard/test/selenium/integration/test_instances.py +++ b/openstack_dashboard/test/selenium/integration/test_instances.py @@ -23,22 +23,27 @@ from openstack_dashboard.test.selenium import widgets volume_name = test_volumes.volume_name new_volume_demo = test_volumes.new_volume_demo +default_network = "shared" + @pytest.fixture def instance_name(): return 'horizon_instance_%s' % uuidutils.generate_uuid(dashed=False) -@pytest.fixture(params=[1]) +@pytest.fixture(params=[(1, default_network, False)]) def new_instance_demo(request, instance_name, openstack_demo, config): - count = request.param + count = request.param[0] + network_param = request.param[1] + auto_ip_param = request.param[2] instance = openstack_demo.create_server( instance_name, image=config.image.images_list[0], flavor=config.launch_instances.flavor, availability_zone=config.launch_instances.available_zone, - network=config.network.external_network, + network=network_param, + auto_ip=auto_ip_param, wait=True, max_count=count, ) @@ -50,16 +55,19 @@ def new_instance_demo(request, instance_name, openstack_demo, config): openstack_demo.delete_server(instance_name) -@pytest.fixture(params=[1]) +@pytest.fixture(params=[(1, default_network, False)]) def new_instance_admin(request, instance_name, openstack_admin, config): - count = request.param + count = request.param[0] + network_param = request.param[1] + auto_ip_param = request.param[2] instance = openstack_admin.create_server( instance_name, image=config.image.images_list[0], flavor=config.launch_instances.flavor, availability_zone=config.launch_instances.available_zone, - network=config.network.external_network, + network=network_param, + auto_ip=auto_ip_param, wait=True, max_count=count, ) @@ -125,7 +133,7 @@ def delete_volume_on_instance_delete(driver, required_state): def test_create_instance_demo(login, driver, instance_name, openstack_demo, clear_instance_demo, config): image = config.image.images_list[0] - network = config.network.external_network + network = default_network flavor = config.launch_instances.flavor login('user') @@ -177,7 +185,7 @@ def test_create_instance_from_volume_demo(login, driver, instance_name, volume_name, new_volume_demo, clear_instance_demo, config, openstack_demo): - network = config.network.external_network + network = default_network flavor = config.launch_instances.flavor volume_name = volume_name[0] @@ -243,7 +251,8 @@ def test_delete_instance_demo(login, driver, instance_name, openstack_demo, assert openstack_demo.compute.find_server(instance_name) is None -@pytest.mark.parametrize('new_instance_demo', [2], indirect=True) +@pytest.mark.parametrize('new_instance_demo', [(2, default_network, False)], + indirect=True) def test_instance_pagination_demo(login, driver, instance_name, new_instance_demo, change_page_size_demo, config): @@ -300,7 +309,7 @@ def test_instance_pagination_demo(login, driver, instance_name, def test_create_instance_admin(login, driver, instance_name, openstack_admin, clear_instance_admin, config): image = config.image.images_list[0] - network = config.network.external_network + network = default_network flavor = config.launch_instances.flavor login('admin') @@ -362,7 +371,8 @@ def test_delete_instance_admin(login, driver, instance_name, openstack_admin, assert openstack_admin.compute.find_server(instance_name) is None -@pytest.mark.parametrize('new_instance_admin', [2], indirect=True) +@pytest.mark.parametrize('new_instance_admin', [(2, default_network, False)], + indirect=True) def test_instance_pagination_admin(login, driver, instance_name, new_instance_admin, change_page_size_admin, config):