Merge "Avoid duplicated maintenance of integration test config"

This commit is contained in:
Zuul 2020-01-27 01:44:33 +00:00 committed by Gerrit Code Review
commit 9724c7c58d
5 changed files with 95 additions and 56 deletions

1
.gitignore vendored
View File

@ -25,6 +25,7 @@ openstack_dashboard/local/*
openstack_dashboard/local/local_settings.d/* openstack_dashboard/local/local_settings.d/*
!openstack_dashboard/local/local_settings.d/*.example !openstack_dashboard/local/local_settings.d/*.example
openstack_dashboard/test/.secret_key_store openstack_dashboard/test/.secret_key_store
openstack_dashboard/test/integration_tests/horizon.conf.sample
openstack_dashboard/test/integration_tests/local-horizon.conf openstack_dashboard/test/integration_tests/local-horizon.conf
openstack_dashboard/test/integration_tests/test_reports/ openstack_dashboard/test/integration_tests/test_reports/
openstack_dashboard/wsgi/horizon.wsgi openstack_dashboard/wsgi/horizon.wsgi

View File

@ -8,8 +8,16 @@ Running the integration tests
#. Set up an OpenStack server #. Set up an OpenStack server
#. Update the configuration file at `horizon.conf` or add overrides #. Prepare the configuration file at `local-horizon.conf` if you need
to that file in `local-horizon.conf` which is ignored by git. to change the default configurations.
Note that `horizon.conf` can be used for the same purpose too
from the historical reason.
You can generate a sample configuration file by the following command::
$ oslo-config-generator \
--namespace openstack_dashboard_integration_tests
--output-file openstack_dashboard/test/integration_tests/horizon.conf.sample
#. Run the tests. :: #. Run the tests. ::

View File

@ -18,45 +18,44 @@ from oslo_config import cfg
DashboardGroup = [ DashboardGroup = [
cfg.StrOpt('dashboard_url', cfg.StrOpt('dashboard_url',
default='http://localhost/dashboard/', default='http://localhost/dashboard/',
help="Where the dashboard can be found"), help='Where the dashboard can be found'),
cfg.StrOpt('help_url', cfg.StrOpt('help_url',
default='https://docs.openstack.org/', default='https://docs.openstack.org/',
help="Dashboard help page url"), help='Dashboard help page url'),
] ]
IdentityGroup = [ IdentityGroup = [
cfg.StrOpt('username', cfg.StrOpt('username',
default='demo', default='demo',
help="Username to use for non-admin API requests."), help='Username to use for non-admin API requests.'),
cfg.StrOpt('password', cfg.StrOpt('password',
default='secretadmin', default='secretadmin',
help="API key to use when authenticating.", help='API key to use when authenticating.',
secret=True), secret=True),
cfg.StrOpt('domain', cfg.StrOpt('domain',
default=None, default=None,
help="Domain name to use if required for login"), help='Domain name to use if required for login'),
cfg.StrOpt('home_project', cfg.StrOpt('home_project',
default='demo', default='demo',
help="Project to keep all objects belonging to a regular user." help='Project to keep all objects belonging to a regular user.'
), ),
cfg.StrOpt('admin_username', cfg.StrOpt('admin_username',
default='admin', default='admin',
help="Administrative Username to use for admin API " help='Administrative Username to use for admin API requests.'),
"requests."),
cfg.StrOpt('admin_password', cfg.StrOpt('admin_password',
default='secretadmin', default='secretadmin',
help="API key to use when authenticating as admin.", help='API key to use when authenticating as admin.',
secret=True), secret=True),
cfg.StrOpt('admin_home_project', cfg.StrOpt('admin_home_project',
default='admin', default='admin',
help="Project to keep all objects belonging to an admin user."), help='Project to keep all objects belonging to an admin user.'),
cfg.StrOpt('default_keystone_role', cfg.StrOpt('default_keystone_role',
default='member', default='member',
help="Name of default role every user gets in his new project"), help='Name of default role every user gets in his new project.'),
cfg.StrOpt('default_keystone_admin_role', cfg.StrOpt('default_keystone_admin_role',
default='admin', default='admin',
help="Name of the role that grants admin rights to a user in " help=('Name of the role that grants admin rights to a user in '
"his project"), 'his project')),
cfg.IntOpt('unique_last_password_count', cfg.IntOpt('unique_last_password_count',
# The default value is chosen to match the value of # The default value is chosen to match the value of
# [security_compliance] unique_last_password_count in DevStack # [security_compliance] unique_last_password_count in DevStack
@ -65,10 +64,10 @@ IdentityGroup = [
# in keystone may differ, so you might need # in keystone may differ, so you might need
# to change this parameter. # to change this parameter.
default=2, default=2,
help=("The number of passwords for a user that must be unique " help=('The number of passwords for a user that must be unique '
"before an old password can be used. " 'before an old password can be used. '
"This should match the keystone configuration option " 'This should match the keystone configuration option '
"'[security_compliance] unique_last_password_count'.")), '"[security_compliance] unique_last_password_count".')),
] ]
ImageGroup = [ ImageGroup = [
@ -98,28 +97,38 @@ NetworkGroup = [
AvailableServiceGroup = [ AvailableServiceGroup = [
cfg.BoolOpt('neutron', cfg.BoolOpt('neutron',
default=True), default=True,
help='Whether neutron is expected to be available'),
] ]
SeleniumGroup = [ SeleniumGroup = [
cfg.FloatOpt('message_implicit_wait', cfg.FloatOpt(
default=0.1, 'message_implicit_wait',
help="Time to wait for confirmation modal in seconds"), default=0.1,
cfg.IntOpt('implicit_wait', help='Timeout in seconds to wait for message confirmation modal'),
default=10, cfg.IntOpt(
help="Implicit wait timeout in seconds"), 'implicit_wait',
cfg.IntOpt('explicit_wait', default=10,
default=90, help=('Implicit timeout to wait until element become available, '
help="Explicit wait timeout in seconds"), 'It is used for every find_element, find_elements call.')),
cfg.IntOpt('page_timeout', cfg.IntOpt(
default=60, 'explicit_wait',
help="Page load timeout in seconds"), default=90,
cfg.StrOpt('screenshots_directory', help=('Explicit timeout is used for long lasting operations, '
default="integration_tests_screenshots", 'Methods using explicit timeout are usually prefixed with '
help="Output screenshot directory"), '"wait"')),
cfg.BoolOpt('maximize_browser', cfg.IntOpt(
default=True, 'page_timeout',
help="Is the browser size maximized for each test?"), default=60,
help='Timeout in seconds to wait for a page to become available'),
cfg.StrOpt(
'screenshots_directory',
default='integration_tests_screenshots',
help='Output directory for screenshots'),
cfg.BoolOpt(
'maximize_browser',
default=True,
help='Maximize the browser window at the start of each test or not'),
] ]
FlavorsGroup = [ FlavorsGroup = [
@ -137,13 +146,13 @@ ScenarioGroup = [
InstancesGroup = [ InstancesGroup = [
cfg.StrOpt('available_zone', cfg.StrOpt('available_zone',
default='nova', default='nova',
help="Zone to be selected for launch Instances"), help='Availability zone to be selected for launch instances'),
cfg.StrOpt('image_name', cfg.StrOpt('image_name',
default='cirros-0.4.0-x86_64-disk (12.1 MB)', default='cirros-0.4.0-x86_64-disk (12.1 MB)',
help="Boot Source to be selected for launch Instances"), help='Boot Source to be selected for launch Instances'),
cfg.StrOpt('flavor', cfg.StrOpt('flavor',
default='m1.tiny', default='m1.tiny',
help="Flavor to be selected for launch Instances"), help='Flavor to be selected for launch instances'),
] ]
VolumeGroup = [ VolumeGroup = [
@ -156,14 +165,18 @@ VolumeGroup = [
] ]
PluginGroup = [ PluginGroup = [
cfg.BoolOpt('is_plugin', cfg.BoolOpt(
default='False', 'is_plugin',
help="Set to true if this is a plugin"), default='False',
cfg.MultiStrOpt('plugin_page_path', help='Set to true if this is a plugin'),
default='', cfg.MultiStrOpt(
help='Additional path to look for plugin page content'), 'plugin_page_path',
cfg.MultiStrOpt('plugin_page_structure', default='',
default='') help='Additional path to look for plugin page content'),
cfg.MultiStrOpt(
'plugin_page_structure',
default='',
help=('JSON string to define the page structure for the plugin')),
] ]
@ -172,13 +185,11 @@ def _get_config_files():
os.path.abspath(os.path.dirname(os.path.dirname(__file__))), os.path.abspath(os.path.dirname(os.path.dirname(__file__))),
'integration_tests') 'integration_tests')
conf_file = os.environ.get('HORIZON_INTEGRATION_TESTS_CONFIG_FILE', conf_file = os.environ.get('HORIZON_INTEGRATION_TESTS_CONFIG_FILE',
"%s/horizon.conf" % conf_dir) '%s/horizon.conf' % conf_dir)
config_files = [conf_file]
local_config = os.environ.get('HORIZON_INTEGRATION_TESTS_LOCAL_CONFIG', local_config = os.environ.get('HORIZON_INTEGRATION_TESTS_LOCAL_CONFIG',
"%s/local-horizon.conf" % conf_dir) '%s/local-horizon.conf' % conf_dir)
if os.path.isfile(local_config): config_files = [conf_file, local_config]
config_files.append(local_config) return [f for f in config_files if os.path.isfile(f)]
return config_files
def get_config(): def get_config():
@ -197,3 +208,19 @@ def get_config():
cfg.CONF.register_opts(VolumeGroup, group="volume") cfg.CONF.register_opts(VolumeGroup, group="volume")
return cfg.CONF return cfg.CONF
def list_opts():
return [
("dashboard", DashboardGroup),
("selenium", SeleniumGroup),
("flavors", FlavorsGroup),
("image", ImageGroup),
("identity", IdentityGroup),
("network", NetworkGroup),
("service_available", AvailableServiceGroup),
("scenario", ScenarioGroup),
("launch_instances", InstancesGroup),
("plugin", PluginGroup),
("volume", VolumeGroup),
]

View File

@ -54,6 +54,7 @@ add_comments = Translators:
[entry_points] [entry_points]
oslo.config.opts = oslo.config.opts =
openstack_dashboard = openstack_dashboard.utils.config:list_options openstack_dashboard = openstack_dashboard.utils.config:list_options
openstack_dashboard_integration_tests = openstack_dashboard.test.integration_tests.config:list_opts
# We use a custom extractor to find translatable strings in AngularJS templates. # We use a custom extractor to find translatable strings in AngularJS templates.
# See http://babel.pocoo.org/docs/messages/#referencing-extraction-methods for # See http://babel.pocoo.org/docs/messages/#referencing-extraction-methods for
# details on how this works. # details on how this works.

View File

@ -88,7 +88,9 @@ setenv =
PYTHONHASHSEED=0 PYTHONHASHSEED=0
INTEGRATION_TESTS=1 INTEGRATION_TESTS=1
SELENIUM_HEADLESS=1 SELENIUM_HEADLESS=1
commands = {envpython} {toxinidir}/manage.py test openstack_dashboard --settings=openstack_dashboard.test.settings --verbosity 2 --tag integration {posargs} commands =
oslo-config-generator --namespace openstack_dashboard_integration_tests
{envpython} {toxinidir}/manage.py test openstack_dashboard --settings=openstack_dashboard.test.settings --verbosity 2 --tag integration {posargs}
[testenv:npm] [testenv:npm]
passenv = passenv =