Moved run_test logic into abstract class.
Useful for testing in some custom environment, e.g. during backend writing. Example using of new class is at http://paste.openstack.org/show/2180/. This script runs all unittests with the real LDAP connection. The config template is at http://paste.openstack.org/show/2181/. Change-Id: I4d89e8c4e9458cd982d73dd973d2da63989f4c93
This commit is contained in:
parent
920298f5e8
commit
eb803079d6
|
@ -0,0 +1,107 @@
|
|||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import tempfile
|
||||
import time
|
||||
|
||||
TEST_DIR = os.path.abspath(os.path.dirname(__file__))
|
||||
BASE_DIR = os.path.abspath(os.path.join(TEST_DIR, '..', '..'))
|
||||
|
||||
|
||||
def execute(cmd, raise_error=True):
|
||||
"""
|
||||
Executes a command in a subprocess. Returns a tuple
|
||||
of (exitcode, out, err), where out is the string output
|
||||
from stdout and err is the string output from stderr when
|
||||
executing the command.
|
||||
|
||||
:param cmd: Command string to execute
|
||||
:param raise_error: If returncode is not 0 (success), then
|
||||
raise a RuntimeError? Default: True)
|
||||
"""
|
||||
|
||||
env = os.environ.copy()
|
||||
# Make sure that we use the programs in the
|
||||
# current source directory's bin/ directory.
|
||||
env['PATH'] = os.path.join(BASE_DIR, 'bin') + ':' + env['PATH']
|
||||
|
||||
process = subprocess.Popen(cmd,
|
||||
shell=True,
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
env=env)
|
||||
result = process.communicate()
|
||||
(out, err) = result
|
||||
exitcode = process.returncode
|
||||
if process.returncode != 0 and raise_error:
|
||||
msg = "Command %(cmd)s did not succeed. Returned an exit "\
|
||||
"code of %(exitcode)d."\
|
||||
"\n\nSTDOUT: %(out)s"\
|
||||
"\n\nSTDERR: %(err)s" % locals()
|
||||
raise RuntimeError(msg)
|
||||
return exitcode, out, err
|
||||
|
||||
|
||||
class KeystoneTest(object):
|
||||
CONF_PARAMS = {'test_dir': TEST_DIR}
|
||||
|
||||
def clear_database(self):
|
||||
"""Remove any test databases or files generated by previous tests."""
|
||||
for fname in self.test_files:
|
||||
fpath = os.path.join(TEST_DIR, fname)
|
||||
if os.path.exists(fpath):
|
||||
print "Removing test file %s" % fname
|
||||
os.unlink(fpath)
|
||||
|
||||
def construct_temp_conf_file(self):
|
||||
"""Populates a configuration template, and writes to a file pointer."""
|
||||
template_fpath = os.path.join(TEST_DIR, 'etc', self.config_name)
|
||||
conf_contents = open(template_fpath).read()
|
||||
conf_contents = conf_contents % self.CONF_PARAMS
|
||||
self.conf_fp = tempfile.NamedTemporaryFile()
|
||||
self.conf_fp.write(conf_contents)
|
||||
self.conf_fp.flush()
|
||||
|
||||
def setUp(self):
|
||||
self.clear_database()
|
||||
self.construct_temp_conf_file()
|
||||
|
||||
# Populate the test database
|
||||
print "Populating registry and token databases..."
|
||||
execute('sampledata.sh -c %s' % self.conf_fp.name)
|
||||
|
||||
# run the keystone server
|
||||
print "Starting the keystone server..."
|
||||
self.server = subprocess.Popen(
|
||||
[os.path.join(BASE_DIR, 'bin/keystone'), '-c', self.conf_fp.name])
|
||||
|
||||
# blatent hack.
|
||||
time.sleep(3)
|
||||
if self.server.poll() is not None:
|
||||
raise RuntimeError('Failed to start server')
|
||||
|
||||
def tearDown(self):
|
||||
# kill the keystone server
|
||||
print "Stopping the keystone server..."
|
||||
self.server.kill()
|
||||
self.clear_database()
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
self.setUp()
|
||||
except:
|
||||
self.clear_database()
|
||||
raise
|
||||
try:
|
||||
# discover and run tests
|
||||
print "Running tests..."
|
||||
if '--with-coverage' in sys.argv:
|
||||
print "running coverage"
|
||||
execute('coverage run %s discover -t %s -s %s' %
|
||||
('/usr/bin/unit2', BASE_DIR, TEST_DIR))
|
||||
else:
|
||||
execute('unit2 discover -f -t %s -s %s' %
|
||||
(BASE_DIR, TEST_DIR))
|
||||
finally:
|
||||
self.tearDown()
|
129
run_tests.py
129
run_tests.py
|
@ -1,122 +1,31 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
"""Manages execution of keystone test suites"""
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import tempfile
|
||||
import time
|
||||
|
||||
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
|
||||
TEST_DIR = os.path.join(BASE_DIR, 'keystone', 'test')
|
||||
|
||||
CONFIG_FILES = (
|
||||
'sql.conf.template',
|
||||
# not passing 'memcache.conf.template',
|
||||
'ldap.conf.template')
|
||||
|
||||
TEST_FILES = (
|
||||
'keystone.db',
|
||||
'keystone.token.db',
|
||||
'ldap.db',
|
||||
'ldap.db.db')
|
||||
from keystone.test import KeystoneTest
|
||||
|
||||
|
||||
def execute(cmd, raise_error=True):
|
||||
"""
|
||||
Executes a command in a subprocess. Returns a tuple
|
||||
of (exitcode, out, err), where out is the string output
|
||||
from stdout and err is the string output from stderr when
|
||||
executing the command.
|
||||
|
||||
:param cmd: Command string to execute
|
||||
:param raise_error: If returncode is not 0 (success), then
|
||||
raise a RuntimeError? Default: True)
|
||||
"""
|
||||
|
||||
env = os.environ.copy()
|
||||
# Make sure that we use the programs in the
|
||||
# current source directory's bin/ directory.
|
||||
env['PATH'] = os.path.join(BASE_DIR, 'bin') + ':' + env['PATH']
|
||||
|
||||
process = subprocess.Popen(cmd,
|
||||
shell=True,
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
env=env)
|
||||
result = process.communicate()
|
||||
(out, err) = result
|
||||
exitcode = process.returncode
|
||||
if process.returncode != 0 and raise_error:
|
||||
msg = "Command %(cmd)s did not succeed. Returned an exit "\
|
||||
"code of %(exitcode)d."\
|
||||
"\n\nSTDOUT: %(out)s"\
|
||||
"\n\nSTDERR: %(err)s" % locals()
|
||||
raise RuntimeError(msg)
|
||||
return exitcode, out, err
|
||||
class SQLTest(KeystoneTest):
|
||||
config_name = 'sql.conf.template'
|
||||
test_files = ('keystone.db',)
|
||||
|
||||
|
||||
def remove_test_files():
|
||||
"""Remove any test databases or files generated by previous tests."""
|
||||
for fname in TEST_FILES:
|
||||
fpath = os.path.join(TEST_DIR, fname)
|
||||
if os.path.exists(fpath):
|
||||
print "Removing test file %s" % fname
|
||||
os.unlink(fpath)
|
||||
class MemcacheTest(KeystoneTest):
|
||||
config_name = 'memcache.conf.template'
|
||||
test_files = ('keystone.db',)
|
||||
|
||||
|
||||
def construct_temp_conf_file(temp_fp, config_name):
|
||||
"""Populates a configuration template, and writes to a file pointer."""
|
||||
template_fpath = os.path.join(TEST_DIR, 'etc', config_name)
|
||||
conf_contents = open(template_fpath).read()
|
||||
conf_contents = conf_contents % {'test_dir': TEST_DIR}
|
||||
temp_fp.write(conf_contents)
|
||||
temp_fp.flush()
|
||||
class LDAPTest(KeystoneTest):
|
||||
config_name = 'ldap.conf.template'
|
||||
test_files = ('keystone.db', 'ldap.db', 'ldap.db.db',)
|
||||
|
||||
TESTS = [
|
||||
SQLTest,
|
||||
# not running MemcacheTest,
|
||||
LDAPTest,
|
||||
]
|
||||
|
||||
if __name__ == '__main__':
|
||||
for config in CONFIG_FILES:
|
||||
print 'Using config file', CONFIG_FILES.index(config) + 1, 'of', \
|
||||
str(len(CONFIG_FILES)) + ':', config
|
||||
|
||||
remove_test_files()
|
||||
|
||||
try:
|
||||
# Create a configuration file to supply to the keystone
|
||||
# server for the test run
|
||||
with tempfile.NamedTemporaryFile() as conf_fp:
|
||||
construct_temp_conf_file(conf_fp, config)
|
||||
|
||||
# Populate the test database
|
||||
print "Populating registry and token databases..."
|
||||
execute('sampledata.sh -c %s' % conf_fp.name)
|
||||
|
||||
# run the keystone server
|
||||
print "Starting the keystone server..."
|
||||
server = subprocess.Popen(
|
||||
[os.path.join(BASE_DIR, 'bin/keystone'),
|
||||
'-c', conf_fp.name])
|
||||
|
||||
# blatent hack.
|
||||
time.sleep(3)
|
||||
if server.poll() is not None:
|
||||
print >> sys.stderr, 'Failed to start server'
|
||||
sys.exit(-1)
|
||||
|
||||
try:
|
||||
# discover and run tests
|
||||
print "Running tests..."
|
||||
if '--with-coverage' in sys.argv:
|
||||
print "running coverage"
|
||||
execute('coverage run %s discover -t %s -s %s' %
|
||||
('/usr/bin/unit2', BASE_DIR, TEST_DIR))
|
||||
else:
|
||||
execute('unit2 discover -t %s -s %s' %
|
||||
(BASE_DIR, TEST_DIR))
|
||||
finally:
|
||||
#kill the keystone server
|
||||
print "Stopping the keystone server..."
|
||||
server.kill()
|
||||
finally:
|
||||
remove_test_files()
|
||||
for test_num, test_cls in enumerate(TESTS):
|
||||
print 'Starting test %d of %d with config: %s' % \
|
||||
(test_num + 1, len(TESTS), test_cls.config_name)
|
||||
test_cls().run()
|
||||
|
|
Loading…
Reference in New Issue