diff --git a/openstack_dashboard/test/integration_tests/helpers.py b/openstack_dashboard/test/integration_tests/helpers.py index 4db10ea57f..605257c434 100644 --- a/openstack_dashboard/test/integration_tests/helpers.py +++ b/openstack_dashboard/test/integration_tests/helpers.py @@ -335,3 +335,7 @@ class AdminTestCase(TestCase, AssertsMixin): TEST_USER_NAME = TestCase.CONFIG.identity.admin_username TEST_PASSWORD = TestCase.CONFIG.identity.admin_password HOME_PROJECT = BaseTestCase.CONFIG.identity.admin_home_project + + def setUp(self): + super(AdminTestCase, self).setUp() + self.home_pg.go_to_admin_overviewpage() diff --git a/openstack_dashboard/test/integration_tests/pages/admin/compute/flavorspage.py b/openstack_dashboard/test/integration_tests/pages/admin/compute/flavorspage.py index a0166df3d5..efdaa07a8f 100644 --- a/openstack_dashboard/test/integration_tests/pages/admin/compute/flavorspage.py +++ b/openstack_dashboard/test/integration_tests/pages/admin/compute/flavorspage.py @@ -150,7 +150,7 @@ class FlavorsPage(basepage.BaseNavigationPage): class FlavorsPageNG(FlavorsPage): _resource_page_header_locator = (by.By.CSS_SELECTOR, - 'hz-resource-panel hz-page-header h1') + '.page-header > h1') @property def header(self): diff --git a/openstack_dashboard/test/integration_tests/pages/admin/system/defaultspage.py b/openstack_dashboard/test/integration_tests/pages/admin/system/defaultspage.py index 5ea0abb5b5..21b238fdf2 100644 --- a/openstack_dashboard/test/integration_tests/pages/admin/system/defaultspage.py +++ b/openstack_dashboard/test/integration_tests/pages/admin/system/defaultspage.py @@ -10,6 +10,8 @@ # 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 from openstack_dashboard.test.integration_tests.regions import forms from openstack_dashboard.test.integration_tests.regions import tables @@ -18,35 +20,43 @@ from openstack_dashboard.test.integration_tests.regions import tables class DefaultQuotasTable(tables.TableRegion): name = "compute_quotas" - UPDATE_DEFAULTS_FORM_FIELDS = ( - "injected_file_content_bytes", - "metadata_items", - "ram", - "key_pairs", - "injected_file_path_bytes", - "instances", - "injected_files", - "cores", - "server_groups", - "server_group_members" - ) + UPDATE_DEFAULTS_FORM_FIELDS = (("injected_file_content_bytes", + "metadata_items", "ram", + "key_pairs", + "injected_file_path_bytes", + "instances", "injected_files", + "cores", "server_groups", + "server_group_members"), + ("volumes", "gigabytes", + "snapshots")) @tables.bind_table_action('update_compute_defaults') def update(self, update_button): update_button.click() - return forms.FormRegion( + return forms.TabbedFormRegion( self.driver, self.conf, - None, - field_mappings=self.UPDATE_DEFAULTS_FORM_FIELDS - ) + self.UPDATE_DEFAULTS_FORM_FIELDS) + + +class DefaultVolumeQuotasTable(DefaultQuotasTable): + name = "volume_quotas" + + @tables.bind_table_action('update_volume_defaults') + def update(self, update_button): + update_button.click() + return forms.TabbedFormRegion( + self.driver, + self.conf, + self.UPDATE_DEFAULTS_FORM_FIELDS) class DefaultsPage(basepage.BaseNavigationPage): QUOTAS_TABLE_NAME_COLUMN = 'Quota Name' QUOTAS_TABLE_LIMIT_COLUMN = 'Limit' - DEFAULT_QUOTA_NAMES = [ + VOLUMES_TAB_INDEX = 1 + DEFAULT_COMPUTE_QUOTA_NAMES = [ 'Injected File Content Bytes', 'Metadata Items', 'Server Group Members', @@ -58,31 +68,60 @@ class DefaultsPage(basepage.BaseNavigationPage): 'Injected Files', 'VCPUs' ] + DEFAULT_VOLUME_QUOTA_NAMES = [ + 'Volumes', + 'Total Size of Volumes and Snapshots (GiB)', + 'Volume Snapshots', + ] + _volume_quotas_tab_locator = (by.By.CSS_SELECTOR, + 'a[href*="defaults__volume_quotas"]') def __init__(self, driver, conf): super(DefaultsPage, self).__init__(driver, conf) self._page_title = "Defaults" - def _get_quota_row(self, name): - return self.default_quotas_table.get_row( + def _get_compute_quota_row(self, name): + return self.default_compute_quotas_table.get_row( + self.QUOTAS_TABLE_NAME_COLUMN, name) + + def _get_volume_quota_row(self, name): + return self.default_volume_quotas_table.get_row( self.QUOTAS_TABLE_NAME_COLUMN, name) @property - def default_quotas_table(self): + def default_compute_quotas_table(self): return DefaultQuotasTable(self.driver, self.conf) @property - def quota_values(self): + def default_volume_quotas_table(self): + return DefaultVolumeQuotasTable(self.driver, self.conf) + + @property + def compute_quota_values(self): quota_dict = {} - for row in self.default_quotas_table.rows: + for row in self.default_compute_quotas_table.rows: if row.cells[self.QUOTAS_TABLE_NAME_COLUMN].text in \ - self.DEFAULT_QUOTA_NAMES: + self.DEFAULT_COMPUTE_QUOTA_NAMES: quota_dict[row.cells[self.QUOTAS_TABLE_NAME_COLUMN].text] =\ int(row.cells[self.QUOTAS_TABLE_LIMIT_COLUMN].text) return quota_dict - def update_defaults(self, add_up): - update_form = self.default_quotas_table.update() + @property + def volume_quota_values(self): + quota_dict = {} + for row in self.default_volume_quotas_table.rows: + if row.cells[self.QUOTAS_TABLE_NAME_COLUMN].text in \ + self.DEFAULT_VOLUME_QUOTA_NAMES: + quota_dict[row.cells[self.QUOTAS_TABLE_NAME_COLUMN].text] =\ + int(row.cells[self.QUOTAS_TABLE_LIMIT_COLUMN].text) + return quota_dict + + @property + def volume_quotas_tab(self): + return self._get_element(*self._volume_quotas_tab_locator) + + def update_compute_defaults(self, add_up): + update_form = self.default_compute_quotas_table.update() update_form.injected_file_content_bytes.value = \ int(update_form.injected_file_content_bytes.value) + add_up @@ -99,6 +138,7 @@ class DefaultsPage(basepage.BaseNavigationPage): update_form.key_pairs.value = int(update_form.key_pairs.value) + add_up update_form.injected_file_path_bytes.value = \ int(update_form.injected_file_path_bytes.value) + add_up + update_form.instances.value = int(update_form.instances.value) + add_up update_form.injected_files.value = int( update_form.injected_files.value) + add_up @@ -106,6 +146,21 @@ class DefaultsPage(basepage.BaseNavigationPage): update_form.submit() - def is_quota_a_match(self, quota_name, limit): - row = self._get_quota_row(quota_name) + def update_volume_defaults(self, add_up): + update_form = self.default_volume_quotas_table.update() + update_form.switch_to(self.VOLUMES_TAB_INDEX) + update_form.volumes.value = int(update_form.volumes.value) + add_up + update_form.gigabytes.value = int(update_form.gigabytes.value) + add_up + update_form.snapshots.value = int(update_form.snapshots.value) + add_up + update_form.submit() + + def is_compute_quota_a_match(self, quota_name, limit): + row = self._get_compute_quota_row(quota_name) return row.cells[self.QUOTAS_TABLE_LIMIT_COLUMN].text == str(limit) + + def is_volume_quota_a_match(self, quota_name, limit): + row = self._get_volume_quota_row(quota_name) + return row.cells[self.QUOTAS_TABLE_LIMIT_COLUMN].text == str(limit) + + def go_to_volume_quotas_tab(self): + self.volume_quotas_tab.click() diff --git a/openstack_dashboard/test/integration_tests/tests/test_defaults.py b/openstack_dashboard/test/integration_tests/tests/test_defaults.py index ad09eaf09e..ea97bfae94 100644 --- a/openstack_dashboard/test/integration_tests/tests/test_defaults.py +++ b/openstack_dashboard/test/integration_tests/tests/test_defaults.py @@ -32,8 +32,8 @@ class TestDefaults(helpers.AdminTestCase): 3) Verifies that the updated values are present in the Compute Quota Defaults table """ - default_quota_values = self.defaults_page.quota_values - self.defaults_page.update_defaults(self.add_up) + default_quota_values = self.defaults_page.compute_quota_values + self.defaults_page.update_compute_defaults(self.add_up) self.assertTrue( self.defaults_page.find_message_and_dismiss(messages.SUCCESS)) @@ -44,7 +44,36 @@ class TestDefaults(helpers.AdminTestCase): for quota_name in default_quota_values: self.assertTrue( - self.defaults_page.is_quota_a_match( + self.defaults_page.is_compute_quota_a_match( + quota_name, + default_quota_values[quota_name] + self.add_up + )) + + def test_update_volume_defaults(self): + """Tests the Update Default Volume Quotas functionality: + + 1) Login as Admin and go to Admin > System > Defaults + 2) Clicks on Volume Quotas tab + 3) Updates default volume Quotas by adding a random + number between 1 and 10 + 4) Verifies that the updated values are present in the + Volume Quota Defaults table + """ + + self.defaults_page.go_to_volume_quotas_tab() + default_quota_values = self.defaults_page.volume_quota_values + self.defaults_page.update_volume_defaults(self.add_up) + + self.assertTrue( + self.defaults_page.find_message_and_dismiss(messages.SUCCESS)) + self.assertFalse( + self.defaults_page.find_message_and_dismiss(messages.ERROR)) + + self.assertGreater(len(default_quota_values), 0) + + for quota_name in default_quota_values: + self.assertTrue( + self.defaults_page.is_volume_quota_a_match( quota_name, default_quota_values[quota_name] + self.add_up )) diff --git a/openstack_dashboard/test/integration_tests/tests/test_flavors.py b/openstack_dashboard/test/integration_tests/tests/test_flavors.py index 7de48a7ef4..591424eb4c 100644 --- a/openstack_dashboard/test/integration_tests/tests/test_flavors.py +++ b/openstack_dashboard/test/integration_tests/tests/test_flavors.py @@ -10,13 +10,10 @@ # 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 -@decorators.config_option_required('flavors.panel_type', 'angular', - message="Legacy Panels not tested") class TestFlavorAngular(helpers.AdminTestCase): @property def flavors_page(self): @@ -30,8 +27,6 @@ class TestFlavorAngular(helpers.AdminTestCase): self.assertEqual(flavors_page.header.text, 'Flavors') -@decorators.config_option_required('flavors.panel_type', 'legacy', - message="Angular Panels not tested") class TestFlavors(helpers.AdminTestCase): FLAVOR_NAME = helpers.gen_random_resource_name("flavor") @@ -64,10 +59,6 @@ class TestFlavors(helpers.AdminTestCase): self.assertFalse( self.flavors_page.is_flavor_present(self.FLAVOR_NAME)) - def test_flavor_header(self): - header_text = self.driver.find_element_by_tag_name('h1').text - self.assertEqual(header_text, 'Flavors') - def test_flavor_module_exists(self): js_cmd = "$('html').append('
'"\ " + angular.module('horizon.app.core.flavors').name"\ diff --git a/openstack_dashboard/test/integration_tests/tests/test_projects.py b/openstack_dashboard/test/integration_tests/tests/test_projects.py index d5bb5cab53..7f4e640e9d 100644 --- a/openstack_dashboard/test/integration_tests/tests/test_projects.py +++ b/openstack_dashboard/test/integration_tests/tests/test_projects.py @@ -18,14 +18,12 @@ from openstack_dashboard.test.integration_tests.regions import messages PROJECT_NAME = helpers.gen_random_resource_name("project") -@decorators.skip_because(bugs=['1777359']) class TestCreateDeleteProject(helpers.AdminTestCase): def setUp(self): super(TestCreateDeleteProject, self).setUp() self.projects_page = self.home_pg.go_to_identity_projectspage() - @decorators.skip_because(bugs=['1777359']) def test_create_delete_project(self): self.projects_page.create_project(PROJECT_NAME) self.assertTrue(