Merge "Fix router integration tests"

This commit is contained in:
Zuul 2019-10-05 19:03:11 +00:00 committed by Gerrit Code Review
commit 6a8dabece6
7 changed files with 100 additions and 58 deletions

View File

@ -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 = [

View File

@ -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)

View File

@ -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

View File

@ -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()

View File

@ -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

View File

@ -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):

View File

@ -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: