Fix skipped integration tests for securitygroup, namespace, usersettings

The aim of this PS is to fix existing skipped integration
tests listed below:
 - test_namespace_create_delete (Partial-Bug: #1774697)
 - test_securitygroup_create_delete (Partial-Bug: #1792028)
 - test_managerules_create_delete_by_table (Partial-Bug: #1792028)
 - test_managerules_create_delete_by_row (Partial-Bug: #1792028)
 - test_password_change (Related-Bug: #1776678)
 - test_show_message_after_logout (Related-Bug: #1776678)

Change-Id: Ifcbab546e81059f90b500337df565c20ac50bbbb
This commit is contained in:
Pallav Gupta 2019-09-13 19:49:09 +05:30
parent bcdff69221
commit a945d41812
9 changed files with 97 additions and 50 deletions

View File

@ -57,6 +57,18 @@ IdentityGroup = [
default='admin',
help="Name of the role that grants admin rights to a user in "
"his project"),
cfg.IntOpt('unique_last_password_count',
# The default value is chosen to match the value of
# [security_compliance] unique_last_password_count in DevStack
# as the first target of the integration tests is the gate.
# Note that the default value of unique_last_password_count
# in keystone may differ, so you might need
# to change this parameter.
default=2,
help=("The number of passwords for a user that must be unique "
"before an old password can be used. "
"This should match the keystone configuration option "
"'[security_compliance] unique_last_password_count'.")),
]
ImageGroup = [

View File

@ -72,6 +72,11 @@ default_keystone_role=Member
# Name of the role that grants admin rights to a user in his project
default_keystone_admin_role=admin
# The number of passwords for a user that must be unique before an old
# password can be used. This should match the keystone configuration option
# '[security_compliance] unique_last_password_count'. (integer value)
unique_last_password_count=2
[network]
# The cidr block to allocate tenant ipv4 subnets from (string value)
network_cidr=10.100.0.0/16

View File

@ -38,11 +38,11 @@ class MetadatadefinitionsTable(tables.TableRegion):
class MetadatadefinitionsPage(basepage.BaseNavigationPage):
NAMESPACE_TABLE_NAME_COLUMN = 'display_name'
NAMESPACE_TABLE_DESCRIPTION_COLUMN = 'description'
NAMESPACE_TABLE_RESOURCE_TYPES_COLUMN = 'resource_type_names'
NAMESPACE_TABLE_PUBLIC_COLUMN = 'public'
NAMESPACE_TABLE_PROTECTED_COLUMN = 'protected'
NAMESPACE_TABLE_NAME_COLUMN = 'Name'
NAMESPACE_TABLE_DESCRIPTION_COLUMN = 'Description'
NAMESPACE_TABLE_RESOURCE_TYPES_COLUMN = 'Resource Types'
NAMESPACE_TABLE_PUBLIC_COLUMN = 'Public'
NAMESPACE_TABLE_PROTECTED_COLUMN = 'Protected'
boolean_mapping = {True: 'Yes', False: 'No'}

View File

@ -73,6 +73,7 @@ class LoginPage(pageobject.PageObject):
def _do_login(self, user, password, login_method):
if self.conf.identity.domain:
self.domain[0].clear()
self.domain[0].send_keys(self.conf.identity.domain)
if user == self.conf.identity.admin_username:
if password is None:

View File

@ -25,7 +25,8 @@ class SecurityGroupsTable(tables.TableRegion):
def create_group(self, create_button):
create_button.click()
return forms.FormRegion(
self.driver, self.conf,
self.driver,
self.conf,
field_mappings=self.CREATE_SECURITYGROUP_FORM_FIELDS)
@tables.bind_table_action('delete')
@ -61,6 +62,8 @@ class SecuritygroupsPage(basepage.BaseNavigationPage):
if description is not None:
create_securitygroups_form.description.text = description
create_securitygroups_form.submit()
if 'Manage Security Group Rules' in self.driver.title:
return ManageRulesPage(self.driver, self.conf)
def delete_securitygroup(self, name):
row = self._get_row_with_securitygroup_name(name)

View File

@ -9,8 +9,11 @@
# 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 collections
import collections
import os
from django.utils import html
from selenium.common import exceptions
from selenium.webdriver.common import by
import selenium.webdriver.support.ui as Support
@ -85,7 +88,6 @@ class BaseFormFieldRegion(baseregion.BaseRegion):
class CheckBoxMixin(object):
@property
def label(self):
id_attribute = self.element.get_attribute('id')
@ -116,7 +118,7 @@ class ChooseFileFormFieldRegion(BaseFormFieldRegion):
_element_locator_str_suffix = 'div > input[type=file]'
def choose(self, path):
self.element.send_keys(path)
self.element.send_keys(os.path.join(os.getcwd(), path))
class BaseTextFormFieldRegion(BaseFormFieldRegion):
@ -215,7 +217,9 @@ class SelectFormFieldRegion(BaseFormFieldRegion):
@value.setter
def value(self, value):
self.element.select_by_value(value)
js_cmd = "$('[name=\"%s\"]').val(\"%s\").change();" % (
self.name, html.escape(value))
self.driver.execute_script(js_cmd)
class ThemableSelectFormFieldRegion(BaseFormFieldRegion):
@ -264,8 +268,9 @@ class ThemableSelectFormFieldRegion(BaseFormFieldRegion):
if match:
option.click()
return
raise ValueError('Widget "%s" does have an option with text "%s"'
% (self.name, text))
raise ValueError(
'Widget "%s" does not have an option with text "%s"' %
(self.name, text))
@value.setter
def value(self, value):
@ -275,8 +280,9 @@ class ThemableSelectFormFieldRegion(BaseFormFieldRegion):
if value == option.get_attribute('data-select-value'):
option.click()
return
raise ValueError('Widget "%s" does have an option with value "%s"'
% (self.name, value))
raise ValueError(
'Widget "%s" does not have an option with value "%s"' %
(self.name, value))
class BaseFormRegion(baseregion.BaseRegion):
@ -424,8 +430,10 @@ class TabbedFormRegion(FormRegion):
driver, conf, field_mappings=field_mappings)
def _prepare_mappings(self, field_mappings):
return [super(TabbedFormRegion, self)._prepare_mappings(tab_mappings)
for tab_mappings in field_mappings]
return [
super(TabbedFormRegion, self)._prepare_mappings(tab_mappings)
for tab_mappings in field_mappings
]
def _init_form_fields(self):
self.switch_to(self.current_tab)
@ -448,8 +456,8 @@ 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):
@ -541,8 +549,8 @@ class ItemTextDescription(baseregion.BaseRegion):
keys = []
values = []
for section in self._get_elements(*self._separator_locator):
keys.extend([x.text for x in
section.find_elements(*self._key_locator)])
values.extend([x.text for x in
section.find_elements(*self._value_locator)])
keys.extend(
[x.text for x in section.find_elements(*self._key_locator)])
values.extend(
[x.text for x in section.find_elements(*self._value_locator)])
return dict(zip(keys, values))

View File

@ -12,7 +12,6 @@
import os
from openstack_dashboard.test.integration_tests import decorators
from openstack_dashboard.test.integration_tests import helpers
from openstack_dashboard.test.integration_tests.regions import messages
@ -84,7 +83,6 @@ class TestMetadataDefinitions(helpers.AdminTestCase):
self.assertFalse(page.find_message_and_dismiss(messages.ERROR))
self.assertFalse(page.is_namespace_present(namespace_name))
@decorators.skip_because(bugs=['1774697'])
def test_namespace_create_delete(self):
"""Tests the NameSpace creation and deletion functionality:

View File

@ -12,7 +12,6 @@
import random
from openstack_dashboard.test.integration_tests import decorators
from openstack_dashboard.test.integration_tests import helpers
from openstack_dashboard.test.integration_tests.regions import messages
@ -28,10 +27,18 @@ class TestSecuritygroup(helpers.TestCase):
def _create_securitygroup(self):
page = self.securitygroup_page
page.create_securitygroup(self.SEC_GROUP_NAME)
self.assertTrue(page.find_message_and_dismiss(messages.SUCCESS))
self.assertFalse(page.find_message_and_dismiss(messages.ERROR))
self.assertTrue(page.is_securitygroup_present(self.SEC_GROUP_NAME))
rule_page = page.create_securitygroup(self.SEC_GROUP_NAME)
if rule_page:
self.assertTrue(
rule_page.find_message_and_dismiss(messages.SUCCESS))
self.assertFalse(
rule_page.find_message_and_dismiss(messages.ERROR))
page = self.securitygroup_page
self.assertTrue(page.is_securitygroup_present(self.SEC_GROUP_NAME))
else:
self.assertTrue(page.find_message_and_dismiss(messages.SUCCESS))
self.assertFalse(page.find_message_and_dismiss(messages.ERROR))
self.assertTrue(page.is_securitygroup_present(self.SEC_GROUP_NAME))
def _delete_securitygroup(self):
page = self.securitygroup_page
@ -63,7 +70,6 @@ class TestSecuritygroup(helpers.TestCase):
self.assertFalse(page.find_message_and_dismiss(messages.ERROR))
self.assertFalse(page.is_port_present(self.RULE_PORT))
@decorators.skip_because(bugs=['1792028'])
def test_securitygroup_create_delete(self):
"""tests the security group creation and deletion functionalities:
@ -76,7 +82,6 @@ class TestSecuritygroup(helpers.TestCase):
self._create_securitygroup()
self._delete_securitygroup()
@decorators.skip_because(bugs=['1792028'])
def test_managerules_create_delete_by_row(self):
"""tests the manage rules creation and deletion functionalities:
@ -95,7 +100,6 @@ class TestSecuritygroup(helpers.TestCase):
self._delete_rule_by_row_action()
self._delete_securitygroup()
@decorators.skip_because(bugs=['1792028'])
def test_managerules_create_delete_by_table(self):
"""tests the manage rules creation and deletion functionalities:

View File

@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack_dashboard.test.integration_tests import decorators
from openstack_dashboard.test.integration_tests import helpers
from openstack_dashboard.test.integration_tests.regions import messages
@ -20,8 +19,8 @@ class TestDashboardHelp(helpers.TestCase):
"""Verifies Help link redirects to the right URL."""
self.home_pg.go_to_help_page()
self.home_pg._wait_until(
lambda _: self.home_pg.is_nth_window_opened(2))
self.home_pg._wait_until(lambda _: self.home_pg.is_nth_window_opened(2)
)
self.home_pg.switch_window()
self.home_pg.is_help_page()
@ -50,14 +49,28 @@ class TestPasswordChange(helpers.TestCase):
def _reset_password(self):
passwordchange_page = self.home_pg.go_to_settings_changepasswordpage()
passwordchange_page.reset_to_default_password(self.NEW_PASSWORD)
# Per unique_last_password policy, we need to do unique password reset
# before resetting default password.
unique_last_password_count = int(
self.CONFIG.identity.unique_last_password_count)
old_password = int(self.NEW_PASSWORD)
for x in range(1, unique_last_password_count):
new_password = old_password + 1
passwordchange_page = self.home_pg.\
go_to_settings_changepasswordpage()
passwordchange_page.change_password(
str(old_password), str(new_password))
self.home_pg = self.login_pg.login(
user=self.TEST_USER_NAME, password=new_password)
old_password = new_password
passwordchange_page = self.home_pg.go_to_settings_changepasswordpage()
passwordchange_page.reset_to_default_password(old_password)
def _login(self):
self.login_pg.login()
self.assertTrue(self.home_pg.is_logged_in,
"Failed to login with default password")
@decorators.skip_because(bugs=['1776678'])
def test_password_change(self):
# Changes the password, verifies it was indeed changed and
# resets to default password.
@ -67,15 +80,14 @@ class TestPasswordChange(helpers.TestCase):
passwordchange_page.change_password(self.TEST_PASSWORD,
self.NEW_PASSWORD)
self.home_pg = self.login_pg.login(user=self.TEST_USER_NAME,
password=self.NEW_PASSWORD)
self.home_pg = self.login_pg.login(
user=self.TEST_USER_NAME, password=self.NEW_PASSWORD)
self.assertTrue(self.home_pg.is_logged_in,
"Failed to login with new password")
finally:
self._reset_password()
self._login()
@decorators.skip_because(bugs=['1776678'])
def test_show_message_after_logout(self):
# Ensure an informational message is shown on the login page
# after the user is logged out.
@ -88,8 +100,8 @@ class TestPasswordChange(helpers.TestCase):
self.login_pg.is_logout_reason_displayed(),
"The logout reason message was not found on the login page")
finally:
self.login_pg.login(user=self.TEST_USER_NAME,
password=self.NEW_PASSWORD)
self.login_pg.login(
user=self.TEST_USER_NAME, password=self.NEW_PASSWORD)
self._reset_password()
self._login()
@ -103,13 +115,14 @@ class TestUserSettings(helpers.TestCase):
user_settings = (("Language", changed_settings["language"], language),
("Timezone", changed_settings["timezone"], timezone),
("Pagesize", changed_settings["pagesize"], pagesize),
("Loglines", changed_settings["loglines"], loglines))
("Pagesize", changed_settings["pagesize"],
pagesize), ("Loglines", changed_settings["loglines"],
loglines))
for (setting, expected, observed) in user_settings:
self.assertEqual(expected, observed,
"expected %s: %s, instead found: %s"
% (setting, expected, observed))
self.assertEqual(
expected, observed, "expected %s: %s, instead found: %s" %
(setting, expected, observed))
def test_user_settings_change(self):
"""tests the user's settings options:
@ -121,7 +134,6 @@ class TestUserSettings(helpers.TestCase):
* verifies all changes were successfully executed
"""
settings_page = self.home_pg.go_to_settings_usersettingspage()
settings_page.change_language("es")
self.assertTrue(
settings_page.find_message_and_dismiss(messages.SUCCESS))
@ -146,8 +158,12 @@ class TestUserSettings(helpers.TestCase):
self.assertFalse(
settings_page.find_message_and_dismiss(messages.ERROR))
changed_settings = {"language": "es", "timezone": "Asia/Jerusalem",
"pagesize": "30", "loglines": "50"}
changed_settings = {
"language": "es",
"timezone": "Asia/Jerusalem",
"pagesize": "30",
"loglines": "50"
}
self.verify_user_settings_change(settings_page, changed_settings)
settings_page.return_to_default_settings()