Adds selenium and qunit integration into Django test suite.
Implements blueprint frontend-testing. Implements blueprint javascript-unit-tests. Adds selenium to buildout script and uses django-nose-selenium to integrate with Django's unit test machinery. Includes proof-of-implementation tests with both selenium and qunit. Change-Id: Ic7db4994be398c633a78dca7369359602c7d8f57
This commit is contained in:
parent
67a979ae99
commit
2532d25c08
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,5 +1,6 @@
|
|||||||
*.pyc
|
*.pyc
|
||||||
*.swp
|
*.swp
|
||||||
|
.selenium_log
|
||||||
.coverage
|
.coverage
|
||||||
coverage.xml
|
coverage.xml
|
||||||
pep8.txt
|
pep8.txt
|
||||||
@ -20,5 +21,5 @@ django-nova-syspanel/src/django_nova_syspanel.egg-info
|
|||||||
openstack-dashboard/.dashboard-venv
|
openstack-dashboard/.dashboard-venv
|
||||||
openstack-dashboard/local/dashboard_openstack.sqlite3
|
openstack-dashboard/local/dashboard_openstack.sqlite3
|
||||||
openstack-dashboard/local/local_settings.py
|
openstack-dashboard/local/local_settings.py
|
||||||
build/
|
docs/build/
|
||||||
docs/source/sourcecode
|
docs/source/sourcecode
|
||||||
|
@ -28,12 +28,18 @@ environments will be necessary but not necessarily as time consuming.
|
|||||||
I just want to run the tests!
|
I just want to run the tests!
|
||||||
=============================
|
=============================
|
||||||
|
|
||||||
Running both sets of unit tests quickly and easily is the main goal of this
|
Running the full set of unit tests quickly and easily is the main goal of this
|
||||||
script. All you need to do is::
|
script. All you need to do is::
|
||||||
|
|
||||||
./run_tests.sh
|
./run_tests.sh
|
||||||
|
|
||||||
Yep, that's it. Everything else the script can do is optional.
|
Yep, that's it. However, for a quicker test run you can skip the Selenium
|
||||||
|
tests by using the ``--skip-selenium`` flag::
|
||||||
|
|
||||||
|
./run_tests.sh --skip-selenium
|
||||||
|
|
||||||
|
This isn't recommended, but can be a timesaver when you only need to run
|
||||||
|
the code tests and not the frontend tests during development.
|
||||||
|
|
||||||
Give me metrics!
|
Give me metrics!
|
||||||
================
|
================
|
||||||
|
@ -6,6 +6,7 @@ parts =
|
|||||||
openstackx
|
openstackx
|
||||||
python-novaclient
|
python-novaclient
|
||||||
python-keystoneclient
|
python-keystoneclient
|
||||||
|
seleniumrc
|
||||||
develop = .
|
develop = .
|
||||||
versions = versions
|
versions = versions
|
||||||
|
|
||||||
@ -33,6 +34,8 @@ eggs =
|
|||||||
coverage
|
coverage
|
||||||
glance
|
glance
|
||||||
quantum
|
quantum
|
||||||
|
django-nose-selenium
|
||||||
|
CherryPy
|
||||||
interpreter = python
|
interpreter = python
|
||||||
|
|
||||||
|
|
||||||
@ -124,3 +127,7 @@ urls =
|
|||||||
#recipe = bazaarrecipe
|
#recipe = bazaarrecipe
|
||||||
#urls =
|
#urls =
|
||||||
# https://launchpad.net/~hudson-openstack/glance/trunk/ glance
|
# https://launchpad.net/~hudson-openstack/glance/trunk/ glance
|
||||||
|
|
||||||
|
|
||||||
|
[seleniumrc]
|
||||||
|
recipe=collective.recipe.seleniumrc
|
||||||
|
@ -43,6 +43,7 @@ def horizon_main_nav(context):
|
|||||||
""" Generates top-level dashboard navigation entries. """
|
""" Generates top-level dashboard navigation entries. """
|
||||||
if 'request' not in context:
|
if 'request' not in context:
|
||||||
return {}
|
return {}
|
||||||
|
current_dashboard = context['request'].horizon.get('dashboard', None)
|
||||||
dashboards = []
|
dashboards = []
|
||||||
for dash in Horizon.get_dashboards():
|
for dash in Horizon.get_dashboards():
|
||||||
if callable(dash.nav) and dash.nav(context):
|
if callable(dash.nav) and dash.nav(context):
|
||||||
@ -51,7 +52,7 @@ def horizon_main_nav(context):
|
|||||||
dashboards.append(dash)
|
dashboards.append(dash)
|
||||||
return {'components': dashboards,
|
return {'components': dashboards,
|
||||||
'user': context['request'].user,
|
'user': context['request'].user,
|
||||||
'current': context['request'].horizon['dashboard'].slug}
|
'current': getattr(current_dashboard, 'slug', None)}
|
||||||
|
|
||||||
|
|
||||||
@register.inclusion_tag('horizon/_subnav_list.html', takes_context=True)
|
@register.inclusion_tag('horizon/_subnav_list.html', takes_context=True)
|
||||||
|
@ -26,11 +26,13 @@ TESTSERVER = 'http://testserver'
|
|||||||
DATABASES = {
|
DATABASES = {
|
||||||
'default': {
|
'default': {
|
||||||
'ENGINE': 'django.db.backends.sqlite3',
|
'ENGINE': 'django.db.backends.sqlite3',
|
||||||
'NAME': '/tmp/horizon.db'}}
|
'NAME': '/tmp/horizon.db',
|
||||||
|
'TEST_NAME': '/tmp/test_horizon.db',}}
|
||||||
|
|
||||||
INSTALLED_APPS = (
|
INSTALLED_APPS = (
|
||||||
'django.contrib.sessions',
|
'django.contrib.sessions',
|
||||||
'django.contrib.messages',
|
'django.contrib.messages',
|
||||||
|
'django_nose',
|
||||||
'horizon',
|
'horizon',
|
||||||
'horizon.tests',
|
'horizon.tests',
|
||||||
'horizon.dashboards.nova',
|
'horizon.dashboards.nova',
|
||||||
@ -80,6 +82,8 @@ TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'
|
|||||||
NOSE_ARGS = ['--nocapture',
|
NOSE_ARGS = ['--nocapture',
|
||||||
'--cover-package=horizon',
|
'--cover-package=horizon',
|
||||||
'--cover-inclusive']
|
'--cover-inclusive']
|
||||||
|
# For nose-selenium integration
|
||||||
|
LIVE_SERVER_PORT = 8000
|
||||||
|
|
||||||
# django-mailer uses a different config attribute
|
# django-mailer uses a different config attribute
|
||||||
# even though it just wraps django.core.mail
|
# even though it just wraps django.core.mail
|
||||||
|
@ -86,6 +86,7 @@ INSTALLED_APPS = (
|
|||||||
'django.contrib.sessions',
|
'django.contrib.sessions',
|
||||||
'django.contrib.messages',
|
'django.contrib.messages',
|
||||||
'django.contrib.staticfiles',
|
'django.contrib.staticfiles',
|
||||||
|
'django_nose',
|
||||||
'horizon',
|
'horizon',
|
||||||
'horizon.dashboards.nova',
|
'horizon.dashboards.nova',
|
||||||
'horizon.dashboards.syspanel',
|
'horizon.dashboards.syspanel',
|
||||||
@ -137,4 +138,5 @@ if DEBUG:
|
|||||||
MIDDLEWARE_CLASSES += (
|
MIDDLEWARE_CLASSES += (
|
||||||
'debug_toolbar.middleware.DebugToolbarMiddleware',)
|
'debug_toolbar.middleware.DebugToolbarMiddleware',)
|
||||||
except ImportError:
|
except ImportError:
|
||||||
logging.info('Running in debug mode without debug_toolbar.')
|
_logger = logging.getLogger(__name__)
|
||||||
|
_logger.debug('Running in debug mode without debug_toolbar.')
|
||||||
|
226
openstack-dashboard/dashboard/static/qunit/qunit.css
Normal file
226
openstack-dashboard/dashboard/static/qunit/qunit.css
Normal file
@ -0,0 +1,226 @@
|
|||||||
|
/**
|
||||||
|
* QUnit 1.2.0pre - A JavaScript Unit Testing Framework
|
||||||
|
*
|
||||||
|
* http://docs.jquery.com/QUnit
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011 John Resig, Jörn Zaefferer
|
||||||
|
* Dual licensed under the MIT (MIT-LICENSE.txt)
|
||||||
|
* or GPL (GPL-LICENSE.txt) licenses.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** Font Family and Sizes */
|
||||||
|
|
||||||
|
#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {
|
||||||
|
font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
|
||||||
|
#qunit-tests { font-size: smaller; }
|
||||||
|
|
||||||
|
|
||||||
|
/** Resets */
|
||||||
|
|
||||||
|
#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Header */
|
||||||
|
|
||||||
|
#qunit-header {
|
||||||
|
padding: 0.5em 0 0.5em 1em;
|
||||||
|
|
||||||
|
color: #8699a4;
|
||||||
|
background-color: #0d3349;
|
||||||
|
|
||||||
|
font-size: 1.5em;
|
||||||
|
line-height: 1em;
|
||||||
|
font-weight: normal;
|
||||||
|
|
||||||
|
border-radius: 15px 15px 0 0;
|
||||||
|
-moz-border-radius: 15px 15px 0 0;
|
||||||
|
-webkit-border-top-right-radius: 15px;
|
||||||
|
-webkit-border-top-left-radius: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#qunit-header a {
|
||||||
|
text-decoration: none;
|
||||||
|
color: #c2ccd1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#qunit-header a:hover,
|
||||||
|
#qunit-header a:focus {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#qunit-banner {
|
||||||
|
height: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#qunit-testrunner-toolbar {
|
||||||
|
padding: 0.5em 0 0.5em 2em;
|
||||||
|
color: #5E740B;
|
||||||
|
background-color: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
#qunit-userAgent {
|
||||||
|
padding: 0.5em 0 0.5em 2.5em;
|
||||||
|
background-color: #2b81af;
|
||||||
|
color: #fff;
|
||||||
|
text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Tests: Pass/Fail */
|
||||||
|
|
||||||
|
#qunit-tests {
|
||||||
|
list-style-position: inside;
|
||||||
|
}
|
||||||
|
|
||||||
|
#qunit-tests li {
|
||||||
|
padding: 0.4em 0.5em 0.4em 2.5em;
|
||||||
|
border-bottom: 1px solid #fff;
|
||||||
|
list-style-position: inside;
|
||||||
|
}
|
||||||
|
|
||||||
|
#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#qunit-tests li strong {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#qunit-tests li a {
|
||||||
|
padding: 0.5em;
|
||||||
|
color: #c2ccd1;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
#qunit-tests li a:hover,
|
||||||
|
#qunit-tests li a:focus {
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
#qunit-tests ol {
|
||||||
|
margin-top: 0.5em;
|
||||||
|
padding: 0.5em;
|
||||||
|
|
||||||
|
background-color: #fff;
|
||||||
|
|
||||||
|
border-radius: 15px;
|
||||||
|
-moz-border-radius: 15px;
|
||||||
|
-webkit-border-radius: 15px;
|
||||||
|
|
||||||
|
box-shadow: inset 0px 2px 13px #999;
|
||||||
|
-moz-box-shadow: inset 0px 2px 13px #999;
|
||||||
|
-webkit-box-shadow: inset 0px 2px 13px #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
#qunit-tests table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
margin-top: .2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#qunit-tests th {
|
||||||
|
text-align: right;
|
||||||
|
vertical-align: top;
|
||||||
|
padding: 0 .5em 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#qunit-tests td {
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
#qunit-tests pre {
|
||||||
|
margin: 0;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
#qunit-tests del {
|
||||||
|
background-color: #e0f2be;
|
||||||
|
color: #374e0c;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#qunit-tests ins {
|
||||||
|
background-color: #ffcaca;
|
||||||
|
color: #500;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** Test Counts */
|
||||||
|
|
||||||
|
#qunit-tests b.counts { color: black; }
|
||||||
|
#qunit-tests b.passed { color: #5E740B; }
|
||||||
|
#qunit-tests b.failed { color: #710909; }
|
||||||
|
|
||||||
|
#qunit-tests li li {
|
||||||
|
margin: 0.5em;
|
||||||
|
padding: 0.4em 0.5em 0.4em 0.5em;
|
||||||
|
background-color: #fff;
|
||||||
|
border-bottom: none;
|
||||||
|
list-style-position: inside;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** Passing Styles */
|
||||||
|
|
||||||
|
#qunit-tests li li.pass {
|
||||||
|
color: #5E740B;
|
||||||
|
background-color: #fff;
|
||||||
|
border-left: 26px solid #C6E746;
|
||||||
|
}
|
||||||
|
|
||||||
|
#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; }
|
||||||
|
#qunit-tests .pass .test-name { color: #366097; }
|
||||||
|
|
||||||
|
#qunit-tests .pass .test-actual,
|
||||||
|
#qunit-tests .pass .test-expected { color: #999999; }
|
||||||
|
|
||||||
|
#qunit-banner.qunit-pass { background-color: #C6E746; }
|
||||||
|
|
||||||
|
/*** Failing Styles */
|
||||||
|
|
||||||
|
#qunit-tests li li.fail {
|
||||||
|
color: #710909;
|
||||||
|
background-color: #fff;
|
||||||
|
border-left: 26px solid #EE5757;
|
||||||
|
white-space: pre;
|
||||||
|
}
|
||||||
|
|
||||||
|
#qunit-tests > li:last-child {
|
||||||
|
border-radius: 0 0 15px 15px;
|
||||||
|
-moz-border-radius: 0 0 15px 15px;
|
||||||
|
-webkit-border-bottom-right-radius: 15px;
|
||||||
|
-webkit-border-bottom-left-radius: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#qunit-tests .fail { color: #000000; background-color: #EE5757; }
|
||||||
|
#qunit-tests .fail .test-name,
|
||||||
|
#qunit-tests .fail .module-name { color: #000000; }
|
||||||
|
|
||||||
|
#qunit-tests .fail .test-actual { color: #EE5757; }
|
||||||
|
#qunit-tests .fail .test-expected { color: green; }
|
||||||
|
|
||||||
|
#qunit-banner.qunit-fail { background-color: #EE5757; }
|
||||||
|
|
||||||
|
|
||||||
|
/** Result */
|
||||||
|
|
||||||
|
#qunit-testresult {
|
||||||
|
padding: 0.5em 0.5em 0.5em 2.5em;
|
||||||
|
|
||||||
|
color: #2b81af;
|
||||||
|
background-color: #D2E0E6;
|
||||||
|
|
||||||
|
border-bottom: 1px solid white;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Fixture */
|
||||||
|
|
||||||
|
#qunit-fixture {
|
||||||
|
position: absolute;
|
||||||
|
top: -10000px;
|
||||||
|
left: -10000px;
|
||||||
|
}
|
1597
openstack-dashboard/dashboard/static/qunit/qunit.js
Normal file
1597
openstack-dashboard/dashboard/static/qunit/qunit.js
Normal file
File diff suppressed because it is too large
Load Diff
17
openstack-dashboard/dashboard/templates/qunit.html
Normal file
17
openstack-dashboard/dashboard/templates/qunit.html
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title>QUnit Test Suite</title>
|
||||||
|
<link rel="stylesheet" href="{{ STATIC_URL }}qunit/qunit.css" type="text/css" media="screen">
|
||||||
|
<script type="text/javascript" src="{{ STATIC_URL }}qunit/qunit.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1 id="qunit-header">QUnit Test Suite</h1>
|
||||||
|
<h2 id="qunit-banner"></h2>
|
||||||
|
<div id="qunit-testrunner-toolbar"></div>
|
||||||
|
<h2 id="qunit-userAgent"></h2>
|
||||||
|
<ol id="qunit-tests"></ol>
|
||||||
|
<div id="qunit-fixture">test markup</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
12
openstack-dashboard/dashboard/tests.py
Normal file
12
openstack-dashboard/dashboard/tests.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
from django import test
|
||||||
|
from noseselenium.cases import SeleniumTestCaseMixin
|
||||||
|
|
||||||
|
class SeleniumTests(test.TestCase, SeleniumTestCaseMixin):
|
||||||
|
def test_splash(self):
|
||||||
|
self.selenium.open("/")
|
||||||
|
self.failUnless(self.selenium.is_text_present("User Name"))
|
||||||
|
|
||||||
|
def test_qunit(self):
|
||||||
|
self.selenium.open("/qunit/")
|
||||||
|
self.selenium.wait_for_page_to_load("2000")
|
||||||
|
self.failUnless(self.selenium.is_text_present("0 failed"))
|
@ -32,6 +32,7 @@ import horizon
|
|||||||
|
|
||||||
urlpatterns = patterns('',
|
urlpatterns = patterns('',
|
||||||
url(r'^$', 'dashboard.views.splash', name='splash'),
|
url(r'^$', 'dashboard.views.splash', name='splash'),
|
||||||
|
url(r'^qunit/$', 'dashboard.views.qunit_tests', name='qunit_tests'),
|
||||||
url(r'', include(horizon.urls)))
|
url(r'', include(horizon.urls)))
|
||||||
|
|
||||||
# Development static app and project media serving using the staticfiles app.
|
# Development static app and project media serving using the staticfiles app.
|
||||||
|
@ -29,6 +29,10 @@ import horizon
|
|||||||
from horizon.views import auth as auth_views
|
from horizon.views import auth as auth_views
|
||||||
|
|
||||||
|
|
||||||
|
def qunit_tests(request):
|
||||||
|
return shortcuts.render(request, "qunit.html")
|
||||||
|
|
||||||
|
|
||||||
def user_home(user):
|
def user_home(user):
|
||||||
if user.admin:
|
if user.admin:
|
||||||
return horizon.get_dashboard('syspanel').get_absolute_url()
|
return horizon.get_dashboard('syspanel').get_absolute_url()
|
||||||
@ -42,3 +46,5 @@ def splash(request):
|
|||||||
return handled
|
return handled
|
||||||
|
|
||||||
return shortcuts.render(request, 'splash.html', {'form': form})
|
return shortcuts.render(request, 'splash.html', {'form': form})
|
||||||
|
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ DATABASES = {
|
|||||||
'default': {
|
'default': {
|
||||||
'ENGINE': 'django.db.backends.sqlite3',
|
'ENGINE': 'django.db.backends.sqlite3',
|
||||||
'NAME': os.path.join(LOCAL_PATH, 'dashboard_openstack.sqlite3'),
|
'NAME': os.path.join(LOCAL_PATH, 'dashboard_openstack.sqlite3'),
|
||||||
|
'TEST_NAME': os.path.join(LOCAL_PATH, 'test.sqlite3'),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,6 +95,10 @@ LOGGING = {
|
|||||||
'handlers': ['console'],
|
'handlers': ['console'],
|
||||||
'propagate': False,
|
'propagate': False,
|
||||||
},
|
},
|
||||||
|
'nose.plugins.manager': {
|
||||||
|
'handlers': ['console'],
|
||||||
|
'propagate': False,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
coverage
|
coverage
|
||||||
|
CherryPy
|
||||||
Django==1.3
|
Django==1.3
|
||||||
django-mailer
|
django-mailer
|
||||||
django-nose==0.1.2
|
django-nose==0.1.2
|
||||||
|
django-nose-selenium
|
||||||
django-registration==0.7
|
django-registration==0.7
|
||||||
eventlet
|
eventlet
|
||||||
glance
|
glance
|
||||||
|
43
run_tests.sh
43
run_tests.sh
@ -14,6 +14,7 @@ function usage {
|
|||||||
echo " been added."
|
echo " been added."
|
||||||
echo " -p, --pep8 Just run pep8"
|
echo " -p, --pep8 Just run pep8"
|
||||||
echo " -y, --pylint Just run pylint"
|
echo " -y, --pylint Just run pylint"
|
||||||
|
echo " --skip-selenium Run unit tests but skip Selenium tests"
|
||||||
echo " --runserver Run the Django development server for"
|
echo " --runserver Run the Django development server for"
|
||||||
echo " openstack-dashboard in the virtual"
|
echo " openstack-dashboard in the virtual"
|
||||||
echo " environment."
|
echo " environment."
|
||||||
@ -36,6 +37,7 @@ function process_option {
|
|||||||
-y|--pylint) let just_pylint=1;;
|
-y|--pylint) let just_pylint=1;;
|
||||||
-f|--force) let force=1;;
|
-f|--force) let force=1;;
|
||||||
-c|--coverage) let with_coverage=1;;
|
-c|--coverage) let with_coverage=1;;
|
||||||
|
--skip-selenium) let selenium=-1;;
|
||||||
--docs) let just_docs=1;;
|
--docs) let just_docs=1;;
|
||||||
--runserver) let runserver=1;;
|
--runserver) let runserver=1;;
|
||||||
*) testargs="$testargs $1"
|
*) testargs="$testargs $1"
|
||||||
@ -89,6 +91,7 @@ always_venv=0
|
|||||||
never_venv=0
|
never_venv=0
|
||||||
force=0
|
force=0
|
||||||
with_coverage=0
|
with_coverage=0
|
||||||
|
selenium=0
|
||||||
testargs=""
|
testargs=""
|
||||||
django_wrapper=""
|
django_wrapper=""
|
||||||
dashboard_wrapper=""
|
dashboard_wrapper=""
|
||||||
@ -143,7 +146,25 @@ then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
function wait_for_selenium {
|
||||||
|
# Selenium can sometimes take several seconds to start.
|
||||||
|
STARTED=`grep -irn "Started SocketListener on 0.0.0.0:4444" .selenium_log`
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo "Selenium server started."
|
||||||
|
else
|
||||||
|
echo -n "."
|
||||||
|
sleep 1
|
||||||
|
wait_for_selenium
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
function run_tests {
|
function run_tests {
|
||||||
|
if [ $selenium -eq 0 ]; then
|
||||||
|
echo "Starting Selenium server..."
|
||||||
|
${django_wrapper} horizon/bin/seleniumrc > .selenium_log &
|
||||||
|
wait_for_selenium
|
||||||
|
fi
|
||||||
|
|
||||||
echo "Running Horizon application tests"
|
echo "Running Horizon application tests"
|
||||||
${django_wrapper} coverage erase
|
${django_wrapper} coverage erase
|
||||||
${django_wrapper} coverage run horizon/bin/test
|
${django_wrapper} coverage run horizon/bin/test
|
||||||
@ -156,14 +177,22 @@ function run_tests {
|
|||||||
cp local/local_settings.py local/local_settings.py.bak
|
cp local/local_settings.py local/local_settings.py.bak
|
||||||
fi
|
fi
|
||||||
cp local/local_settings.py.example local/local_settings.py
|
cp local/local_settings.py.example local/local_settings.py
|
||||||
|
|
||||||
|
if [ $selenium -eq 0 ]; then
|
||||||
|
${dashboard_wrapper} coverage run dashboard/manage.py test --with-selenium --with-cherrypyliveserver
|
||||||
|
else
|
||||||
${dashboard_wrapper} coverage run dashboard/manage.py test
|
${dashboard_wrapper} coverage run dashboard/manage.py test
|
||||||
|
fi
|
||||||
|
|
||||||
if [ -f local/local_settings.py.bak ]; then
|
if [ -f local/local_settings.py.bak ]; then
|
||||||
cp local/local_settings.py.bak local/local_settings.py
|
cp local/local_settings.py.bak local/local_settings.py
|
||||||
rm local/local_settings.py.bak
|
rm local/local_settings.py.bak
|
||||||
fi
|
fi
|
||||||
|
cd ..
|
||||||
|
|
||||||
# get results of the openstack-dashboard tests
|
# get results of the openstack-dashboard tests
|
||||||
DASHBOARD_RESULT=$?
|
DASHBOARD_RESULT=$?
|
||||||
cd ..
|
|
||||||
if [ $with_coverage -eq 1 ]; then
|
if [ $with_coverage -eq 1 ]; then
|
||||||
echo "Generating coverage reports"
|
echo "Generating coverage reports"
|
||||||
${django_wrapper} coverage combine
|
${django_wrapper} coverage combine
|
||||||
@ -171,6 +200,18 @@ function run_tests {
|
|||||||
${django_wrapper} coverage html -i --omit='/usr*,setup.py,*egg*' -d reports
|
${django_wrapper} coverage html -i --omit='/usr*,setup.py,*egg*' -d reports
|
||||||
exit $(($OPENSTACK_RESULT || $DASHBOARD_RESULT))
|
exit $(($OPENSTACK_RESULT || $DASHBOARD_RESULT))
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ $selenium -eq 0 ]; then
|
||||||
|
echo "Stopping Selenium server..."
|
||||||
|
SELENIUM_JOB=`ps -elf | grep "selenium" | grep -v grep`
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
kill `echo "${SELENIUM_JOB}" | awk '{print $4}'`
|
||||||
|
echo "Selenium process stopped."
|
||||||
|
else
|
||||||
|
echo "Selenium process not found. This may require manual claenup."
|
||||||
|
fi
|
||||||
|
rm -f .selenium_log
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
if [ $just_docs -eq 1 ]; then
|
if [ $just_docs -eq 1 ]; then
|
||||||
|
Loading…
Reference in New Issue
Block a user