Add test_sahara_image_registry

Add simple test for page under /Project/Data Processing/Image Registry,
that registers and unregisters an image in the Sahara registry.

Infrastructure changes needed by the test:
 - new page object with basic handling of the Image Registry page;
 - new ssh_user config option with the cloud-init username for the
   image (named after the corresponding tempest option);
 - new parameter in get_row() table method for exact match;
 - add "wait-until-active" method for the Image page;
 - enable sahara service by default in horizon.conf.

Partially implements blueprint: selenium-integration-testing
Co-Authored-By: Luigi Toscano <ltoscano@redhat.com>

Change-Id: I1e389f0baff655f8f06a0a6cbb4a10b9a68dd444
This commit is contained in:
Tomas Novacik 2015-02-27 15:11:33 +01:00 committed by Luigi Toscano
parent 734cc8b6a2
commit 7b16bbf920
6 changed files with 148 additions and 4 deletions

View File

@ -69,6 +69,12 @@ SeleniumGroup = [
help="Page load timeout in seconds"),
]
ScenarioGroup = [
cfg.StrOpt('ssh_user',
default='cirros',
help='ssh username for image file'),
]
def _get_config_files():
conf_dir = os.path.join(
@ -87,5 +93,6 @@ def get_config():
cfg.CONF.register_opts(AvailableServiceGroup, group="service_available")
cfg.CONF.register_opts(SeleniumGroup, group="selenium")
cfg.CONF.register_opts(ImageGroup, group="image")
cfg.CONF.register_opts(ScenarioGroup, group="scenario")
return cfg.CONF

View File

@ -50,4 +50,8 @@ admin_password=secretadmin
# Whether is Sahara expected to be available (boolean
# value)
#sahara=False
sahara=True
[scenario]
# ssh username for image file (string value)
ssh_user=cirros

View File

@ -105,3 +105,6 @@ class ImagesPage(basepage.BaseNavigationPage):
row = self._get_row_with_image_name(name)
return row.cells[self.IMAGES_TABLE_STATUS_COLUMN_INDEX].text == \
'Active'
def wait_until_image_active(self, name):
self._wait_until(lambda x: self.is_image_active(name))

View File

@ -0,0 +1,78 @@
# 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.
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
class ImageregistryPage(basepage.BaseNavigationPage):
_image_table_locator = (by.By.CSS_SELECTOR, 'table#image_registry')
_unregister_form_locator = (by.By.CSS_SELECTOR, 'div.modal-dialog')
_register_form_locator = (by.By.CSS_SELECTOR, 'div.modal-dialog')
IMAGE_TABLE_ACTIONS = ("register_image", "unregister_images")
IMAGE_TABLE_ROW_ACTIONS = {
tables.ComplexActionRowRegion.PRIMARY_ACTION: "edit_tags",
tables.ComplexActionRowRegion.SECONDARY_ACTIONS: ("unregister_image",)
}
TABLE_IMAGE_COLUMN = 0
REGISTER_FORM_IMAGE = "image"
REGISTER_FORM_USER_NAME = "user_name"
REGISTER_FORM_DESCRIPTION = "description"
REGISTER_FORM_FIELDS = (REGISTER_FORM_IMAGE, REGISTER_FORM_USER_NAME,
REGISTER_FORM_DESCRIPTION)
def __init__(self, driver, conf):
super(ImageregistryPage, self).__init__(driver, conf)
self._page_title = "Data Processing"
def _get_row_with_image_name(self, name):
return self.image_table.get_row(self.TABLE_IMAGE_COLUMN, name)
@property
def image_table(self):
src_elem = self._get_element(*self._image_table_locator)
return tables.ComplexActionTableRegion(self.driver, self.conf,
src_elem,
self.IMAGE_TABLE_ACTIONS,
self.IMAGE_TABLE_ROW_ACTIONS)
@property
def unregister_form(self):
src_elem = self._get_element(*self._unregister_form_locator)
return forms.BaseFormRegion(self.driver, self.conf, src_elem)
@property
def register_form(self):
src_elem = self._get_element(*self._register_form_locator)
return forms.FormRegion(self.driver, self.conf, src_elem,
self.REGISTER_FORM_FIELDS)
def is_image_registered(self, name):
return bool(self._get_row_with_image_name(name))
def unregister_image(self, name):
self._get_row_with_image_name(name).mark()
self.image_table.unregister_images.click()
self.unregister_form.submit.click()
def register_image(self, image, user_name, description):
self.image_table.register_image.click()
self.register_form.image.text = image
self.register_form.user_name.text = user_name
self.register_form.description.text = description
self.register_form.submit.click()

View File

@ -141,10 +141,17 @@ class BasicTableRegion(baseregion.BaseRegion):
self._set_search_field(value)
self._click_search_btn()
def get_row(self, column_index, text):
"""Get row that contains in specified column specified text."""
def get_row(self, column_index, text, exact_match=True):
"""Get row that contains specified text in specified column.
In case exact_match is set to True, text contained in row must equal
searched text, otherwise occurrence of searched text in the column
text will result in row match.
"""
for row in self.rows:
if text in row.cells[column_index].text:
if exact_match and text == row.cells[column_index].text:
return row
if not exact_match and text in row.cells[column_index].text:
return row
return None

View File

@ -0,0 +1,45 @@
# 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.
from openstack_dashboard.test.integration_tests import helpers
from openstack_dashboard.test.integration_tests.tests import decorators
IMAGE_NAME = helpers.gen_random_resource_name("image")
@decorators.services_required("sahara")
class TestSaharaImageRegistry(helpers.TestCase):
def setUp(self):
super(TestSaharaImageRegistry, self).setUp()
image_pg = self.home_pg.go_to_compute_imagespage()
image_pg.create_image(IMAGE_NAME)
image_pg.wait_until_image_active(IMAGE_NAME)
def test_image_register_unregister(self):
"""Test the image registration in Sahara."""
image_reg_pg = self.home_pg.go_to_dataprocessing_imageregistrypage()
image_reg_pg.register_image(IMAGE_NAME, self.conf.scenario.ssh_user,
"Test description")
self.assertTrue(image_reg_pg.is_image_registered(IMAGE_NAME),
"Image was not registered.")
self.assertFalse(image_reg_pg.is_error_message_present(),
"Error message occurred during image creation.")
image_reg_pg.unregister_image(IMAGE_NAME)
self.assertFalse(image_reg_pg.is_error_message_present())
self.assertFalse(image_reg_pg.is_image_registered(IMAGE_NAME),
"Image was not unregistered.")
def tearDown(self):
image_pg = self.home_pg.go_to_compute_imagespage()
image_pg.delete_image(IMAGE_NAME)
super(TestSaharaImageRegistry, self).tearDown()