-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge "Add test for create/delete Namespace inside "Metadata Definiti…
…ons""
- Loading branch information
Showing
6 changed files
with
315 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
127 changes: 127 additions & 0 deletions
127
openstack_dashboard/test/integration_tests/pages/admin/system/metadatadefinitionspage.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
# 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 json | ||
|
||
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 | ||
|
||
|
||
class MetadatadefinitionsTable(tables.TableRegion): | ||
name = "namespaces" | ||
CREATE_NAMESPACE_FORM_FIELDS = ( | ||
"source_type", "direct_input", "metadef_file", "public", "protected") | ||
|
||
@tables.bind_table_action('import') | ||
def import_namespace(self, create_button): | ||
create_button.click() | ||
return forms.FormRegion( | ||
self.driver, | ||
self.conf, | ||
field_mappings=self.CREATE_NAMESPACE_FORM_FIELDS) | ||
|
||
@tables.bind_table_action('delete') | ||
def delete_namespace(self, delete_button): | ||
delete_button.click() | ||
return forms.BaseFormRegion(self.driver, self.conf) | ||
|
||
|
||
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' | ||
|
||
boolean_mapping = {True: 'Yes', False: 'No'} | ||
|
||
def __init__(self, driver, conf): | ||
super(MetadatadefinitionsPage, self).__init__(driver, conf) | ||
self._page_title = "Metadata Definitions" | ||
|
||
def _get_row_with_namespace_name(self, name): | ||
return self.namespaces_table.get_row( | ||
self.NAMESPACE_TABLE_NAME_COLUMN, | ||
name) | ||
|
||
@property | ||
def namespaces_table(self): | ||
return MetadatadefinitionsTable(self.driver, self.conf) | ||
|
||
def json_load_template(self, namespace_template_name): | ||
"""Read template for namespace creation | ||
:param namespace_template_name: Path to template | ||
:return = json data container | ||
""" | ||
try: | ||
with open(namespace_template_name, 'r') as template: | ||
json_template = json.load(template) | ||
except Exception: | ||
raise EOFError("Can not read template file: [{0}]".format( | ||
namespace_template_name)) | ||
return json_template | ||
|
||
def import_namespace( | ||
self, namespace_source_type, namespace_json_container, | ||
is_public=True, is_protected=False): | ||
|
||
create_namespace_form = self.namespaces_table.import_namespace() | ||
create_namespace_form.source_type.value = namespace_source_type | ||
if namespace_source_type == 'raw': | ||
json_template_dump = json.dumps(namespace_json_container) | ||
create_namespace_form.direct_input.text = json_template_dump | ||
elif namespace_source_type == 'file': | ||
metadeffile = namespace_json_container | ||
create_namespace_form.metadef_file.choose(metadeffile) | ||
|
||
if is_public: | ||
create_namespace_form.public.mark() | ||
if is_protected: | ||
create_namespace_form.protected.mark() | ||
|
||
create_namespace_form.submit() | ||
|
||
def delete_namespace(self, name): | ||
row = self._get_row_with_namespace_name(name) | ||
row.mark() | ||
confirm_delete_namespaces_form = \ | ||
self.namespaces_table.delete_namespace() | ||
confirm_delete_namespaces_form.submit() | ||
|
||
def is_namespace_present(self, name): | ||
return bool(self._get_row_with_namespace_name(name)) | ||
|
||
def is_public_set_correct(self, name, exp_value, row=None): | ||
if type(exp_value) != bool: | ||
raise ValueError('Expected value "exp_value" is not boolean') | ||
if not row: | ||
row = self._get_row_with_namespace_name(name) | ||
cell = row.cells[self.NAMESPACE_TABLE_PUBLIC_COLUMN] | ||
return self._is_text_visible(cell, self.boolean_mapping[exp_value]) | ||
|
||
def is_protected_set_correct(self, name, exp_value, row=None): | ||
if type(exp_value) != bool: | ||
raise ValueError('Expected value "exp_value" is not boolean') | ||
if not row: | ||
row = self._get_row_with_namespace_name(name) | ||
cell = row.cells[self.NAMESPACE_TABLE_PROTECTED_COLUMN] | ||
return self._is_text_visible(cell, self.boolean_mapping[exp_value]) | ||
|
||
def is_resource_type_set_correct(self, name, expected_resources, row=None): | ||
if not row: | ||
row = self._get_row_with_namespace_name(name) | ||
cell = row.cells[self.NAMESPACE_TABLE_RESOURCE_TYPES_COLUMN] | ||
return all( | ||
[self._is_text_visible(cell, res, strict=False) | ||
for res in expected_resources]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
openstack_dashboard/test/integration_tests/tests/test-data/empty_namespace.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
{ | ||
"namespace": "1A_TestNamespace", | ||
"display_name": "1A_TestNamespace", | ||
"description": "Description for TestNamespace", | ||
"resource_type_associations": [ | ||
{ | ||
"name": "OS::Nova::Flavor" | ||
}, | ||
{ | ||
"name": "OS::Glance::Image" | ||
} | ||
], | ||
"properties": { | ||
"prop1": { | ||
"default": "20", | ||
"type": "integer", | ||
"description": "More info here", | ||
"title": "My property1" | ||
} | ||
} | ||
} |
158 changes: 158 additions & 0 deletions
158
openstack_dashboard/test/integration_tests/tests/test_metadata_definitions.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
# 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 os | ||
|
||
from openstack_dashboard.test.integration_tests import helpers | ||
from openstack_dashboard.test.integration_tests.regions import messages | ||
|
||
|
||
class TestMetadataDefinitions(helpers.AdminTestCase): | ||
|
||
NAMESPACE_TEMPLATE_PATH = os.path.join( | ||
os.path.dirname(__file__), | ||
'test-data/empty_namespace.json') | ||
|
||
PUBLIC = 'public' | ||
PROTECTED = 'protected' | ||
|
||
def namespace_create_with_checks( | ||
self, namespace_name, page, template_json_container, | ||
expected_namespace_res=None, template_source_type='raw', | ||
is_public=True, is_protected=False, template_path=None, | ||
checks=(PUBLIC, PROTECTED)): | ||
"""Create NameSpace and run checks | ||
:param namespace_name: Display name of namespace in template | ||
:param page: Connection point | ||
:param template_json_container: JSON container with NameSpace content | ||
:param expected_namespace_res: Resources from template | ||
:param template_source_type: 'raw' or 'file' | ||
:param is_public: True or False | ||
:param is_protected: If True- you can't delete it from GUI | ||
:param checks: Put name of columns if you need to check actual | ||
representation of 'public' and/or 'protected' value. | ||
To disable leave it empty: '' OR put None | ||
:param template_path: Full path to NameSpace template file | ||
:return: Nothing | ||
""" | ||
if template_source_type == 'file': | ||
template_json_container = template_path | ||
|
||
page.import_namespace( | ||
namespace_json_container=template_json_container, | ||
is_public=is_public, | ||
is_protected=is_protected, | ||
namespace_source_type=template_source_type) | ||
# Checks | ||
self.assertTrue(page.find_message_and_dismiss(messages.SUCCESS)) | ||
self.assertFalse(page.find_message_and_dismiss(messages.ERROR)) | ||
self.assertTrue(page.is_namespace_present(namespace_name)) | ||
row = page._get_row_with_namespace_name(namespace_name) | ||
if checks: | ||
if self.PUBLIC in checks: | ||
self.assertTrue( | ||
page.is_public_set_correct(namespace_name, is_public, row)) | ||
elif self.PROTECTED in checks: | ||
self.assertTrue( | ||
page.is_protected_set_correct(namespace_name, is_protected, | ||
row)) | ||
if expected_namespace_res: | ||
self.assertTrue(page.is_resource_type_set_correct( | ||
namespace_name, expected_namespace_res, row)) | ||
|
||
def namespace_delete_with_checks(self, namespace_name, page): | ||
"""Delete NameSpace and run checks | ||
:param namespace_name: Display name of namespace in template | ||
:param page: Connection point | ||
:return: Nothing | ||
""" | ||
page.delete_namespace(name=namespace_name) | ||
# Checks | ||
self.assertTrue(page.find_message_and_dismiss(messages.SUCCESS)) | ||
self.assertFalse(page.find_message_and_dismiss(messages.ERROR)) | ||
self.assertFalse(page.is_namespace_present(namespace_name)) | ||
|
||
def test_namespace_create_delete(self): | ||
"""Tests the NameSpace creation and deletion functionality: | ||
* Actions: | ||
* 1) Login to Horizon Dashboard as admin user. | ||
* 2) Navigate to Admin -> System -> Metadata Definitions. | ||
* 3) Click "Import Namespace" button. Wait for Create Network dialog. | ||
* 4) Enter settings for new Namespace: | ||
* - Namespace Definition Source: 'raw' or 'file' | ||
* - Namespace JSON location; | ||
* - Public: Yes or No; | ||
* - Protected: No (check box not enabled). | ||
* 5) Press "Import Namespace" button. | ||
* 6) Check that new Namespace was successfully created. | ||
* 7) Check that new Namespace is present in the table. | ||
* 8) Check that values in table on page "Metadata Definitions" are | ||
* the same as in Namespace JSON template and as in step (4): | ||
* - Name | ||
* - Public | ||
* - Protected | ||
* - Resource Types | ||
* 9) Select Namespace in table and press "Delete Namespace" button. | ||
* 10) In "Confirm Delete Namespace" window press "Delete Namespace". | ||
* 11) Check that new Namespace was successfully deleted. | ||
* 12) Check that new Namespace is not present in the table. | ||
""" | ||
namespaces_page = self.home_pg.go_to_system_metadatadefinitionspage() | ||
|
||
template_json_container = namespaces_page.json_load_template( | ||
namespace_template_name=self.NAMESPACE_TEMPLATE_PATH) | ||
# Get name from template file | ||
namespace_name = template_json_container['display_name'] | ||
# Get resources from template to check representation in GUI | ||
namespace_res_type = \ | ||
template_json_container['resource_type_associations'] | ||
namespace_res_type = \ | ||
[x['name'] for x in namespace_res_type] | ||
|
||
# Create / Delete NameSpaces with checks | ||
kwargs = {'namespace_name': namespace_name, | ||
'page': namespaces_page, | ||
'is_protected': False, | ||
'template_json_container': template_json_container, | ||
'template_path': self.NAMESPACE_TEMPLATE_PATH} | ||
|
||
self.namespace_create_with_checks( | ||
template_source_type='raw', | ||
is_public=True, | ||
expected_namespace_res=namespace_res_type, | ||
checks=(self.PUBLIC, self.PROTECTED), | ||
**kwargs) | ||
self.namespace_delete_with_checks(namespace_name, namespaces_page) | ||
|
||
self.namespace_create_with_checks( | ||
template_source_type='raw', | ||
is_public=False, | ||
expected_namespace_res=None, | ||
checks=(self.PUBLIC,), | ||
**kwargs) | ||
self.namespace_delete_with_checks(namespace_name, namespaces_page) | ||
|
||
self.namespace_create_with_checks( | ||
template_source_type='file', | ||
is_public=True, | ||
expected_namespace_res=namespace_res_type, | ||
checks=(self.PUBLIC, self.PROTECTED), | ||
**kwargs) | ||
self.namespace_delete_with_checks(namespace_name, namespaces_page) | ||
|
||
self.namespace_create_with_checks( | ||
template_source_type='file', | ||
is_public=False, | ||
expected_namespace_res=None, | ||
checks=(self.PUBLIC,), | ||
**kwargs) | ||
self.namespace_delete_with_checks(namespace_name, namespaces_page) |