Fix router integration tests
The aim of this PS is to fix skipped router integration tests listed below: - test_router_add_delete_interface (Partial-Bug: #1792028) - test_router_delete_interface_by_row (Partial-Bug: #1792028) - test_router_overview_data (Partial-Bug: #1792028) - test_router_create_admin (Partial-Bug: #1792028) Change-Id: I82b15d347831762808b17fbda8c944a1ee5de564
This commit is contained in:
parent
d74d91e5a9
commit
558f6701ab
@ -88,6 +88,12 @@ NetworkGroup = [
|
||||
cfg.StrOpt('network_cidr',
|
||||
default='10.100.0.0/16',
|
||||
help='The cidr block to allocate tenant ipv4 subnets from'),
|
||||
cfg.StrOpt(
|
||||
'external_network',
|
||||
# Devstack default external network is 'public' but it
|
||||
# can be changed as per available external network.
|
||||
default='public',
|
||||
help='The external network for a router creation.'),
|
||||
]
|
||||
|
||||
AvailableServiceGroup = [
|
||||
|
@ -80,6 +80,10 @@ unique_last_password_count=2
|
||||
[network]
|
||||
# The cidr block to allocate tenant ipv4 subnets from (string value)
|
||||
network_cidr=10.100.0.0/16
|
||||
# The external network for a router creation(string value)
|
||||
# Devstack default external network is 'public' but it can be changed
|
||||
# as per available external network.
|
||||
external_network=public
|
||||
|
||||
[service_available]
|
||||
# Whether is Neutron expected to be available (boolean value)
|
||||
|
@ -17,19 +17,18 @@ from openstack_dashboard.test.integration_tests.pages import basepage
|
||||
|
||||
class NetworkOverviewPage(basepage.BaseNavigationPage):
|
||||
|
||||
DEFAULT_NETWORK_NAME = 'public'
|
||||
_network_dd_name_locator = (by.By.CSS_SELECTOR, 'dt[title*="Name"]+dd')
|
||||
|
||||
_network_dd_name_locator = (by.By.CSS_SELECTOR,
|
||||
'dt[title*="Name"]+dd')
|
||||
|
||||
_network_dd_status_locator = (by.By.CSS_SELECTOR,
|
||||
'dt[title*="Status"]+dd')
|
||||
_network_dd_status_locator = (by.By.CSS_SELECTOR, 'dt[title*="Status"]+dd')
|
||||
|
||||
def __init__(self, driver, conf):
|
||||
super(NetworkOverviewPage, self).__init__(driver, conf)
|
||||
self._page_title = 'Network Details'
|
||||
self._external_network = conf.network.external_network
|
||||
|
||||
def is_network_name_present(self, network_name=DEFAULT_NETWORK_NAME):
|
||||
def is_network_name_present(self, network_name=None):
|
||||
if network_name is None:
|
||||
network_name = self._external_network
|
||||
dd_text = self._get_element(*self._network_dd_name_locator).text
|
||||
return dd_text == network_name
|
||||
|
||||
|
@ -10,7 +10,6 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
from selenium.webdriver.common import by
|
||||
|
||||
from openstack_dashboard.test.integration_tests.pages import basepage
|
||||
@ -28,8 +27,7 @@ class InterfacesTable(tables.TableRegion):
|
||||
return forms.FormRegion(
|
||||
self.driver,
|
||||
self.conf,
|
||||
field_mappings=self.CREATE_INTERFACE_FORM_FIELDS
|
||||
)
|
||||
field_mappings=self.CREATE_INTERFACE_FORM_FIELDS)
|
||||
|
||||
@tables.bind_table_action('delete')
|
||||
def delete_interface(self, delete_button):
|
||||
@ -46,37 +44,49 @@ class RouterInterfacesPage(basepage.BaseNavigationPage):
|
||||
|
||||
INTERFACES_TABLE_STATUS_COLUMN = 'Status'
|
||||
INTERFACES_TABLE_NAME_COLUMN = 'Name'
|
||||
DEFAULT_IPv4_ADDRESS = '10.0.0.10'
|
||||
DEFAULT_SUBNET = 'private: 10.0.0.0/26 (private-subnet)'
|
||||
|
||||
_breadcrumb_routers_locator = (by.By.CSS_SELECTOR,
|
||||
'ol.breadcrumb>li>' +
|
||||
'a[href*="/dashboard/project/routers"]')
|
||||
INTERFACES_TABLE_FIXED_IPS_COLUMN = 'Fixed IPs'
|
||||
DEFAULT_IPv4_ADDRESS = '10.100.0.1'
|
||||
_interface_subnet_selector = (by.By.CSS_SELECTOR, 'div > .themable-select')
|
||||
_breadcrumb_routers_locator = (
|
||||
by.By.CSS_SELECTOR,
|
||||
'ol.breadcrumb>li>' + 'a[href*="/project/routers"]')
|
||||
|
||||
def __init__(self, driver, conf, router_name):
|
||||
super(RouterInterfacesPage, self).__init__(driver, conf)
|
||||
self._page_title = router_name
|
||||
|
||||
def _get_row_with_interface_name(self, name):
|
||||
return self.interfaces_table.get_row(self.INTERFACES_TABLE_NAME_COLUMN,
|
||||
name)
|
||||
|
||||
def _get_row_with_ip_address(self):
|
||||
return self.interfaces_table.get_row(
|
||||
self.INTERFACES_TABLE_NAME_COLUMN, name)
|
||||
self.INTERFACES_TABLE_FIXED_IPS_COLUMN, self.DEFAULT_IPv4_ADDRESS)
|
||||
|
||||
@property
|
||||
def subnet_selector(self):
|
||||
src_elem = self._get_element(*self._interface_subnet_selector)
|
||||
return forms.ThemableSelectFormFieldRegion(
|
||||
self.driver,
|
||||
self.conf,
|
||||
src_elem=src_elem,
|
||||
strict_options_match=False)
|
||||
|
||||
@property
|
||||
def interfaces_table(self):
|
||||
return InterfacesTable(self.driver, self.conf)
|
||||
|
||||
@property
|
||||
def interfaces_names(self):
|
||||
return map(lambda row: row.cells[self.
|
||||
INTERFACES_TABLE_NAME_COLUMN].text,
|
||||
self.interfaces_table.rows)
|
||||
def interface_name(self):
|
||||
row = self._get_row_with_ip_address()
|
||||
return row.cells[self.INTERFACES_TABLE_NAME_COLUMN].text
|
||||
|
||||
def switch_to_routers_page(self):
|
||||
self._get_element(*self._breadcrumb_routers_locator).click()
|
||||
|
||||
def create_interface(self):
|
||||
def create_interface(self, subnet):
|
||||
interface_form = self.interfaces_table.create_interface()
|
||||
interface_form.subnet_id.text = self.DEFAULT_SUBNET
|
||||
self.subnet_selector.text = subnet
|
||||
interface_form.ip_address.text = self.DEFAULT_IPv4_ADDRESS
|
||||
interface_form.submit()
|
||||
|
||||
|
@ -10,7 +10,6 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
from selenium.common import exceptions
|
||||
|
||||
from selenium.webdriver.common import by
|
||||
@ -26,14 +25,14 @@ from openstack_dashboard.test.integration_tests.regions import tables
|
||||
|
||||
class RoutersTable(tables.TableRegion):
|
||||
name = "routers"
|
||||
CREATE_ROUTER_FORM_FIELDS = ("name", "admin_state_up",
|
||||
"external_network")
|
||||
CREATE_ROUTER_FORM_FIELDS = ("name", "admin_state_up", "external_network")
|
||||
SET_GATEWAY_FORM_FIELDS = ("network_id",)
|
||||
|
||||
@tables.bind_table_action('create')
|
||||
def create_router(self, create_button):
|
||||
create_button.click()
|
||||
return forms.FormRegion(self.driver, self.conf,
|
||||
return forms.FormRegion(self.driver,
|
||||
self.conf,
|
||||
field_mappings=self.CREATE_ROUTER_FORM_FIELDS)
|
||||
|
||||
@tables.bind_table_action('delete')
|
||||
@ -49,14 +48,14 @@ class RoutersTable(tables.TableRegion):
|
||||
@tables.bind_row_action('setgateway')
|
||||
def set_gateway(self, set_gateway_button, row):
|
||||
set_gateway_button.click()
|
||||
return forms.FormRegion(self.driver, self.conf,
|
||||
return forms.FormRegion(self.driver,
|
||||
self.conf,
|
||||
field_mappings=self.SET_GATEWAY_FORM_FIELDS)
|
||||
|
||||
|
||||
class RoutersPage(basepage.BaseNavigationPage):
|
||||
|
||||
DEFAULT_ADMIN_STATE_UP = 'True'
|
||||
DEFAULT_EXTERNAL_NETWORK = 'public'
|
||||
ROUTERS_TABLE_NAME_COLUMN = 'Name'
|
||||
ROUTERS_TABLE_STATUS_COLUMN = 'Status'
|
||||
ROUTERS_TABLE_NETWORK_COLUMN = 'External Network'
|
||||
@ -67,29 +66,26 @@ class RoutersPage(basepage.BaseNavigationPage):
|
||||
def __init__(self, driver, conf):
|
||||
super(RoutersPage, self).__init__(driver, conf)
|
||||
self._page_title = "Routers"
|
||||
self._external_network = conf.network.external_network
|
||||
|
||||
def _get_row_with_router_name(self, name):
|
||||
return self.routers_table.get_row(
|
||||
self.ROUTERS_TABLE_NAME_COLUMN, name)
|
||||
return self.routers_table.get_row(self.ROUTERS_TABLE_NAME_COLUMN, name)
|
||||
|
||||
@property
|
||||
def routers_table(self):
|
||||
return RoutersTable(self.driver, self.conf)
|
||||
|
||||
def create_router(self, name, admin_state_up=DEFAULT_ADMIN_STATE_UP,
|
||||
external_network=DEFAULT_EXTERNAL_NETWORK):
|
||||
def create_router(self, name, admin_state_up=DEFAULT_ADMIN_STATE_UP):
|
||||
create_router_form = self.routers_table.create_router()
|
||||
create_router_form.name.text = name
|
||||
create_router_form.admin_state_up.value = admin_state_up
|
||||
create_router_form.external_network.text = external_network
|
||||
create_router_form.external_network.text = self._external_network
|
||||
create_router_form.submit()
|
||||
|
||||
def set_gateway(self, router_id,
|
||||
network_name=DEFAULT_EXTERNAL_NETWORK):
|
||||
def set_gateway(self, router_id):
|
||||
row = self._get_row_with_router_name(router_id)
|
||||
|
||||
set_gateway_form = self.routers_table.set_gateway(row)
|
||||
set_gateway_form.network_id.text = network_name
|
||||
set_gateway_form.network_id.text = self._external_network
|
||||
set_gateway_form.submit()
|
||||
|
||||
def clear_gateway(self, name):
|
||||
@ -111,6 +107,7 @@ class RoutersPage(basepage.BaseNavigationPage):
|
||||
|
||||
def cell_getter():
|
||||
return row.cells[self.ROUTERS_TABLE_STATUS_COLUMN]
|
||||
|
||||
try:
|
||||
self._wait_till_text_present_in_element(cell_getter, 'Active')
|
||||
except exceptions.TimeoutException:
|
||||
@ -122,19 +119,22 @@ class RoutersPage(basepage.BaseNavigationPage):
|
||||
|
||||
def cell_getter():
|
||||
return row.cells[self.ROUTERS_TABLE_NETWORK_COLUMN]
|
||||
|
||||
try:
|
||||
self._wait_till_text_present_in_element(cell_getter, '-')
|
||||
except exceptions.TimeoutException:
|
||||
return False
|
||||
return True
|
||||
|
||||
def is_gateway_set(self, name, network_name=DEFAULT_EXTERNAL_NETWORK):
|
||||
def is_gateway_set(self, name):
|
||||
row = self._get_row_with_router_name(name)
|
||||
|
||||
def cell_getter():
|
||||
return row.cells[self.ROUTERS_TABLE_NETWORK_COLUMN]
|
||||
|
||||
try:
|
||||
self._wait_till_text_present_in_element(cell_getter, network_name)
|
||||
self._wait_till_text_present_in_element(cell_getter,
|
||||
self._external_network)
|
||||
except exceptions.TimeoutException:
|
||||
return False
|
||||
return True
|
||||
|
@ -54,7 +54,6 @@ class FieldFactory(baseregion.BaseRegion):
|
||||
|
||||
class MetaBaseFormFieldRegion(type):
|
||||
"""Register form field class in FieldFactory."""
|
||||
|
||||
def __init__(cls, name, bases, dct):
|
||||
FieldFactory.register_field_cls(cls, bases)
|
||||
super(MetaBaseFormFieldRegion, cls).__init__(name, bases, dct)
|
||||
@ -231,8 +230,8 @@ class ThemableSelectFormFieldRegion(BaseFormFieldRegion):
|
||||
_dropdown_menu_locator = (by.By.CSS_SELECTOR, 'ul.dropdown-menu > li > a')
|
||||
|
||||
def __init__(self, driver, conf, strict_options_match=True, **kwargs):
|
||||
super(ThemableSelectFormFieldRegion, self).__init__(
|
||||
driver, conf, **kwargs)
|
||||
super(ThemableSelectFormFieldRegion,
|
||||
self).__init__(driver, conf, **kwargs)
|
||||
self.strict_options_match = strict_options_match
|
||||
|
||||
@property
|
||||
@ -264,7 +263,7 @@ class ThemableSelectFormFieldRegion(BaseFormFieldRegion):
|
||||
if self.strict_options_match:
|
||||
match = text == str(option.text.strip())
|
||||
else:
|
||||
match = option.text.startswith(text)
|
||||
match = text in str(option.text.strip())
|
||||
if match:
|
||||
option.click()
|
||||
return
|
||||
@ -348,6 +347,8 @@ class FormRegion(BaseFormRegion):
|
||||
self.fields_src_elem = self._get_element(*self._fields_locator)
|
||||
fields = self._get_form_fields()
|
||||
for accessor_name, accessor_expr in self.field_mappings.items():
|
||||
if accessor_expr not in fields:
|
||||
continue
|
||||
if isinstance(accessor_expr, six.string_types):
|
||||
self._dynamic_properties[accessor_name] = fields[accessor_expr]
|
||||
else: # it is a class
|
||||
@ -426,8 +427,9 @@ class TabbedFormRegion(FormRegion):
|
||||
|
||||
def __init__(self, driver, conf, field_mappings=None, default_tab=0):
|
||||
self.current_tab = default_tab
|
||||
super(TabbedFormRegion, self).__init__(
|
||||
driver, conf, field_mappings=field_mappings)
|
||||
super(TabbedFormRegion, self).__init__(driver,
|
||||
conf,
|
||||
field_mappings=field_mappings)
|
||||
|
||||
def _prepare_mappings(self, field_mappings):
|
||||
return [
|
||||
@ -444,6 +446,8 @@ class TabbedFormRegion(FormRegion):
|
||||
fields = self._get_form_fields()
|
||||
current_tab_mappings = self.field_mappings[tab_index]
|
||||
for accessor_name, accessor_expr in current_tab_mappings.items():
|
||||
if accessor_expr not in fields:
|
||||
continue
|
||||
if isinstance(accessor_expr, six.string_types):
|
||||
self._dynamic_properties[accessor_name] = fields[accessor_expr]
|
||||
else: # it is a class
|
||||
@ -456,8 +460,9 @@ class TabbedFormRegion(FormRegion):
|
||||
|
||||
@property
|
||||
def tabs(self):
|
||||
return menus.TabbedMenuRegion(
|
||||
self.driver, self.conf, src_elem=self.src_elem)
|
||||
return menus.TabbedMenuRegion(self.driver,
|
||||
self.conf,
|
||||
src_elem=self.src_elem)
|
||||
|
||||
|
||||
class DateFormRegion(BaseFormRegion):
|
||||
|
@ -19,6 +19,8 @@ from openstack_dashboard.test.integration_tests.regions import messages
|
||||
@decorators.services_required("neutron")
|
||||
class TestRouters(helpers.TestCase):
|
||||
ROUTER_NAME = helpers.gen_random_resource_name("router")
|
||||
NETWORK_NAME = helpers.gen_random_resource_name("network")
|
||||
SUBNET_NAME = helpers.gen_random_resource_name("subnet")
|
||||
|
||||
@property
|
||||
def routers_page(self):
|
||||
@ -54,15 +56,15 @@ class TestRouters(helpers.TestCase):
|
||||
self._delete_router()
|
||||
|
||||
def _create_interface(self, interfaces_page):
|
||||
interfaces_page.create_interface()
|
||||
interface_name = interfaces_page.interfaces_names[0]
|
||||
interfaces_page.create_interface(self.SUBNET_NAME)
|
||||
self.assertTrue(
|
||||
interfaces_page.find_message_and_dismiss(messages.SUCCESS))
|
||||
self.assertFalse(
|
||||
interfaces_page.find_message_and_dismiss(messages.ERROR))
|
||||
interface_name = interfaces_page.interface_name
|
||||
self.assertTrue(interfaces_page.is_interface_present(interface_name))
|
||||
self.assertTrue(interfaces_page.is_interface_status(
|
||||
interface_name, 'Down'))
|
||||
self.assertTrue(
|
||||
interfaces_page.is_interface_status(interface_name, 'Down'))
|
||||
|
||||
def _delete_interface(self, interfaces_page, interface_name):
|
||||
interfaces_page.delete_interface(interface_name)
|
||||
@ -72,7 +74,18 @@ class TestRouters(helpers.TestCase):
|
||||
interfaces_page.find_message_and_dismiss(messages.ERROR))
|
||||
self.assertFalse(interfaces_page.is_interface_present(interface_name))
|
||||
|
||||
@decorators.skip_because(bugs=['1792028'])
|
||||
def _create_subnet(self):
|
||||
networks_page = self.home_pg.go_to_project_network_networkspage()
|
||||
networks_page.create_network(self.NETWORK_NAME, self.SUBNET_NAME)
|
||||
self.assertTrue(
|
||||
networks_page.find_message_and_dismiss(messages.SUCCESS))
|
||||
|
||||
def _delete_subnet(self):
|
||||
networks_page = self.home_pg.go_to_project_network_networkspage()
|
||||
networks_page.delete_network(self.NETWORK_NAME)
|
||||
self.assertTrue(
|
||||
networks_page.find_message_and_dismiss(messages.SUCCESS))
|
||||
|
||||
def test_router_add_delete_interface(self):
|
||||
"""Tests the router interface creation and deletion functionalities:
|
||||
|
||||
@ -87,6 +100,8 @@ class TestRouters(helpers.TestCase):
|
||||
* Switches to the routers view by clicking on the breadcrumb link
|
||||
* Follows the steps to delete the router
|
||||
"""
|
||||
self._create_subnet()
|
||||
|
||||
self._create_router()
|
||||
|
||||
routers_page = self.routers_page
|
||||
@ -96,7 +111,7 @@ class TestRouters(helpers.TestCase):
|
||||
|
||||
self._create_interface(router_interfaces_page)
|
||||
|
||||
interface_name = router_interfaces_page.interfaces_names[0]
|
||||
interface_name = router_interfaces_page.interface_name
|
||||
|
||||
self._delete_interface(router_interfaces_page, interface_name)
|
||||
|
||||
@ -104,7 +119,8 @@ class TestRouters(helpers.TestCase):
|
||||
|
||||
self._delete_router()
|
||||
|
||||
@decorators.skip_because(bugs=['1792028'])
|
||||
self._delete_subnet()
|
||||
|
||||
def test_router_delete_interface_by_row(self):
|
||||
"""Tests the router interface creation and deletion by row action:
|
||||
|
||||
@ -118,6 +134,8 @@ class TestRouters(helpers.TestCase):
|
||||
* Switches to the routers view by clicking on the breadcrumb link
|
||||
* Follows the steps to delete the router
|
||||
"""
|
||||
self._create_subnet()
|
||||
|
||||
self._create_router()
|
||||
|
||||
routers_page = self.routers_page
|
||||
@ -127,7 +145,7 @@ class TestRouters(helpers.TestCase):
|
||||
|
||||
self._create_interface(router_interfaces_page)
|
||||
|
||||
interface_name = router_interfaces_page.interfaces_names[0]
|
||||
interface_name = router_interfaces_page.interface_name
|
||||
|
||||
router_interfaces_page.delete_interface_by_row_action(interface_name)
|
||||
|
||||
@ -135,7 +153,8 @@ class TestRouters(helpers.TestCase):
|
||||
|
||||
self._delete_router()
|
||||
|
||||
@decorators.skip_because(bugs=['1792028'])
|
||||
self._delete_subnet()
|
||||
|
||||
def test_router_overview_data(self):
|
||||
self._create_router()
|
||||
|
||||
@ -162,7 +181,6 @@ class TestRouters(helpers.TestCase):
|
||||
class TestAdminRouters(helpers.AdminTestCase):
|
||||
ROUTER_NAME = helpers.gen_random_resource_name("router")
|
||||
|
||||
@decorators.skip_because(bugs=['1792028'])
|
||||
@decorators.services_required("neutron")
|
||||
def test_router_create_admin(self):
|
||||
"""tests the router creation and deletion functionalities:
|
||||
|
Loading…
Reference in New Issue
Block a user