summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2014-06-16 16:26:31 -0400
committerSimo Sorce <simo@redhat.com>2014-06-17 14:51:44 -0400
commitfca4035996c93f8f05ea3837133961e28a1248d6 (patch)
treef8909f1ec4c77ea4b0f65ff23f2ff237947ac795 /tests
parentb2e02899bf037e26a572e6ea53dce37c9f8b0ee0 (diff)
downloadipsilon-fca4035996c93f8f05ea3837133961e28a1248d6.tar.gz
ipsilon-fca4035996c93f8f05ea3837133961e28a1248d6.tar.xz
ipsilon-fca4035996c93f8f05ea3837133961e28a1248d6.zip
Change test executables into modules
Create a common tests framework and convert tests into modules loaded at runtime using the ipsilon plugin framework. Signed-off-by: Simo Sorce <simo@redhat.com>
Diffstat (limited to 'tests')
-rwxr-xr-xtests/helpers/common.py138
-rw-r--r--tests/test1.cfg37
-rwxr-xr-xtests/test1.py90
-rwxr-xr-xtests/tests.py216
4 files changed, 259 insertions, 222 deletions
diff --git a/tests/helpers/common.py b/tests/helpers/common.py
new file mode 100755
index 0000000..d020a3c
--- /dev/null
+++ b/tests/helpers/common.py
@@ -0,0 +1,138 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2014 Simo Sorce <simo@redhat.com>
+#
+# see file 'COPYING' for use and warranty information
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+import ConfigParser
+import io
+from ipsilon.util.plugin import PluginObject
+import os
+import pwd
+import shutil
+import signal
+from string import Template
+import subprocess
+
+
+class IpsilonTestBase(PluginObject):
+
+ def __init__(self, name, execname):
+ super(IpsilonTestBase, self).__init__()
+ self.name = name
+ self.execname = execname
+ self.rootdir = os.getcwd()
+ self.testdir = None
+ self.testuser = pwd.getpwuid(os.getuid())[0]
+ self.processes = []
+
+ def force_remove(self, op, name, info):
+ os.chmod(name, 0700)
+ os.remove(name)
+
+ def setup_base(self, path, test):
+ self.testdir = os.path.join(path, test.name)
+ if os.path.exists(self.testdir):
+ shutil.rmtree(self.testdir, onerror=self.force_remove)
+ os.makedirs(self.testdir)
+ shutil.copytree(os.path.join(self.rootdir, 'templates'),
+ os.path.join(self.testdir, 'templates'))
+ os.mkdir(os.path.join(self.testdir, 'etc'))
+ os.mkdir(os.path.join(self.testdir, 'lib'))
+ os.mkdir(os.path.join(self.testdir, 'lib', test.name))
+ os.mkdir(os.path.join(self.testdir, 'log'))
+
+ def generate_profile(self, global_opts, args_opts, name, addr, port):
+ newconf = ConfigParser.ConfigParser()
+ newconf.add_section('globals')
+ for k in global_opts.keys():
+ newconf.set('globals', k, global_opts[k])
+ newconf.add_section('arguments')
+ for k in args_opts.keys():
+ newconf.set('arguments', k, args_opts[k])
+
+ profile = io.BytesIO()
+ newconf.write(profile)
+
+ t = Template(profile.getvalue())
+ text = t.substitute({'NAME': name, 'ADDRESS': addr, 'PORT': port,
+ 'TESTDIR': self.testdir,
+ 'ROOTDIR': self.rootdir,
+ 'TEST_USER': self.testuser})
+
+ filename = os.path.join(self.testdir, '%s_profile.cfg' % name)
+ with open(filename, 'wb') as f:
+ f.write(text)
+
+ return filename
+
+ def setup_http(self, name, addr, port):
+ httpdir = os.path.join(self.testdir, name)
+ os.mkdir(httpdir)
+ os.mkdir(os.path.join(httpdir, 'conf.d'))
+ os.mkdir(os.path.join(httpdir, 'html'))
+ os.mkdir(os.path.join(httpdir, 'logs'))
+ os.symlink('/etc/httpd/modules', os.path.join(httpdir, 'modules'))
+
+ with open(os.path.join(self.rootdir, 'tests/httpd.conf')) as f:
+ t = Template(f.read())
+ text = t.substitute({'HTTPROOT': httpdir,
+ 'HTTPADDR': addr,
+ 'HTTPPORT': port})
+ filename = os.path.join(httpdir, 'httpd.conf')
+ with open(filename, 'w+') as f:
+ f.write(text)
+
+ return filename
+
+ def setup_idp_server(self, profile, name, addr, port, env):
+ http_conf_file = self.setup_http(name, addr, port)
+ cmd = [os.path.join(self.rootdir,
+ 'ipsilon/install/ipsilon-server-install'),
+ '--config-profile=%s' % profile]
+ subprocess.check_call(cmd, env=env)
+ os.symlink(os.path.join(self.rootdir, 'ipsilon'),
+ os.path.join(self.testdir, 'lib', name, 'ipsilon'))
+
+ return http_conf_file
+
+ def setup_sp_server(self, profile, name, addr, port, env):
+ http_conf_file = self.setup_http(name, addr, port)
+ cmd = [os.path.join(self.rootdir,
+ 'ipsilon/install/ipsilon-client-install'),
+ '--config-profile=%s' % profile]
+ subprocess.check_call(cmd, env=env)
+
+ return http_conf_file
+
+ def start_http_server(self, conf, env):
+ p = subprocess.Popen(['/usr/sbin/httpd', '-DFOREGROUND', '-f', conf],
+ env=env, preexec_fn=os.setsid)
+ self.processes.append(p)
+
+ def wait(self):
+ for p in self.processes:
+ os.killpg(p.pid, signal.SIGTERM)
+
+ def setup_servers(self, env=None):
+ raise NotImplementedError()
+
+ def run(self, env):
+ exe = self.execname
+ if exe.endswith('c'):
+ exe = exe[:-1]
+ return subprocess.call([exe], env=env)
diff --git a/tests/test1.cfg b/tests/test1.cfg
deleted file mode 100644
index 01402f5..0000000
--- a/tests/test1.cfg
+++ /dev/null
@@ -1,37 +0,0 @@
-[tests]
-servers=idp1:127.0.0.10:45080
-clients=sp1:127.0.0.11:45081
-
-[idp1_globals]
-TEMPLATES=${TESTDIR}/templates/install
-CONFDIR=${TESTDIR}/etc
-DATADIR=${TESTDIR}/lib
-HTTPDCONFD=${TESTDIR}/idp1/conf.d
-STATICDIR=${ROOTDIR}
-BINDIR=${ROOTDIR}/ipsilon
-WSGI_SOCKET_PREFIX=${TESTDIR}/idp1/logs/wsgi
-
-[idp1_arguments]
-hostname=127.0.0.10:45080
-admin_user=${TEST_USER}
-system_user=${TEST_USER}
-instance=idp1
-secure=no
-testauth=yes
-pam=no
-krb=no
-ipa=no
-server_debugging=True
-
-[sp1_globals]
-HTTPDCONFD=${TESTDIR}/sp1/conf.d
-SAML2_TEMPLATE=${TESTDIR}/templates/install/saml2/sp.conf
-SAML2_CONFFILE=${TESTDIR}/sp1/conf.d/ipsilon-saml.conf
-SAML2_HTTPDIR=${TESTDIR}/sp1/saml2
-
-[sp1_arguments]
-hostname=127.0.0.11:45081
-saml_idp_metadata=http://127.0.0.10:45080/idp1/saml2/metadata
-saml_secure_setup=False
-saml_auth=/sp
-httpd_user=${TEST_USER}
diff --git a/tests/test1.py b/tests/test1.py
index 411ac6e..34b9c88 100755
--- a/tests/test1.py
+++ b/tests/test1.py
@@ -18,20 +18,104 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-from helpers import http # pylint: disable=relative-import
+from helpers.common import IpsilonTestBase # pylint: disable=relative-import
+from helpers.http import HttpSessions # pylint: disable=relative-import
import os
import pwd
import sys
+from string import Template
+
+
+idp_g = {'TEMPLATES': '${TESTDIR}/templates/install',
+ 'CONFDIR': '${TESTDIR}/etc',
+ 'DATADIR': '${TESTDIR}/lib',
+ 'HTTPDCONFD': '${TESTDIR}/${NAME}/conf.d',
+ 'STATICDIR': '${ROOTDIR}',
+ 'BINDIR': '${ROOTDIR}/ipsilon',
+ 'WSGI_SOCKET_PREFIX': '${TESTDIR}/${NAME}/logs/wsgi'}
+
+
+idp_a = {'hostname': '${ADDRESS}:${PORT}',
+ 'admin_user': '${TEST_USER}',
+ 'system_user': '${TEST_USER}',
+ 'instance': '${NAME}',
+ 'secure': 'no',
+ 'testauth': 'yes',
+ 'pam': 'no',
+ 'krb': 'no',
+ 'ipa': 'no',
+ 'server_debugging': 'True'}
+
+
+sp_g = {'HTTPDCONFD': '${TESTDIR}/${NAME}/conf.d',
+ 'SAML2_TEMPLATE': '${TESTDIR}/templates/install/saml2/sp.conf',
+ 'SAML2_CONFFILE': '${TESTDIR}/${NAME}/conf.d/ipsilon-saml.conf',
+ 'SAML2_HTTPDIR': '${TESTDIR}/${NAME}/saml2'}
+
+
+sp_a = {'hostname': '${ADDRESS}:${PORT}',
+ 'saml_idp_metadata': 'http://127.0.0.10:45080/idp1/saml2/metadata',
+ 'saml_secure_setup': 'False',
+ 'saml_auth': '/sp',
+ 'httpd_user': '${TEST_USER}'}
+
+
+def fixup_sp_httpd(httpdir):
+ location = """
+
+Alias /sp ${HTTPDIR}/sp
+
+<Directory ${HTTPDIR}/sp>
+ Require all granted
+</Directory>
+"""
+ index = """WORKS!"""
+
+ t = Template(location)
+ text = t.substitute({'HTTPDIR': httpdir})
+ with open(httpdir + '/conf.d/ipsilon-saml.conf', 'a') as f:
+ f.write(text)
+
+ os.mkdir(httpdir + '/sp')
+ with open(httpdir + '/sp/index.html', 'w') as f:
+ f.write(index)
+
+
+class IpsilonTest(IpsilonTestBase):
+
+ def __init__(self):
+ super(IpsilonTest, self).__init__('test1', __file__)
+
+ def setup_servers(self, env=None):
+ print "Installing IDP server"
+ name = 'idp1'
+ addr = '127.0.0.10'
+ port = '45080'
+ idp = self.generate_profile(idp_g, idp_a, name, addr, port)
+ conf = self.setup_idp_server(idp, name, addr, port, env)
+
+ print "Starting IDP's httpd server"
+ self.start_http_server(conf, env)
+
+ print "Installing SP server"
+ name = 'sp1'
+ addr = '127.0.0.11'
+ port = '45081'
+ sp = self.generate_profile(sp_g, sp_a, name, addr, port)
+ conf = self.setup_sp_server(sp, name, addr, port, env)
+ fixup_sp_httpd(os.path.dirname(conf))
+
+ print "Starting SP's httpd server"
+ self.start_http_server(conf, env)
if __name__ == '__main__':
- basedir = sys.argv[1]
idpname = 'idp1'
spname = 'sp1'
user = pwd.getpwuid(os.getuid())[0]
- sess = http.HttpSessions()
+ sess = HttpSessions()
sess.add_server(idpname, 'http://127.0.0.10:45080', user, 'ipsilon')
sess.add_server(spname, 'http://127.0.0.11:45081')
diff --git a/tests/tests.py b/tests/tests.py
index 6fa880d..4690442 100755
--- a/tests/tests.py
+++ b/tests/tests.py
@@ -18,21 +18,27 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import argparse
-import ConfigParser
from datetime import datetime
+import inspect
+from ipsilon.util import plugin
import logging
import os
-import pwd
-import shutil
-import signal
-import subprocess
import sys
-from string import Template
+import subprocess
+import traceback
logger = None
+class Tests(object):
+
+ def __init__(self):
+ p = plugin.Plugins()
+ (pathname, dummy) = os.path.split(inspect.getfile(Tests))
+ self.plugins = p.get_plugins(pathname, 'IpsilonTest')
+
+
def parse_args():
parser = argparse.ArgumentParser(description='Ipsilon Tests Environment')
parser.add_argument('--path', default='%s/testdir' % os.getcwd(),
@@ -46,12 +52,12 @@ def parse_args():
return vars(parser.parse_args())
-def openlogs(path, test):
+def openlogs(path, name):
global logger # pylint: disable=W0603
logger = logging.getLogger()
try:
datestr = datetime.now().strftime("%Y-%m-%d_%H:%M:%S")
- filename = '%s/test-%s-%s.log' % (path, test, datestr)
+ filename = '%s/test-%s-%s.log' % (path, name, datestr)
lh = logging.FileHandler(filename)
except IOError, e:
print >> sys.stderr, 'Unable to open %s (%s)' % (filename, str(e))
@@ -62,115 +68,6 @@ def openlogs(path, test):
logger.setLevel(logging.DEBUG)
-def force_remove(op, name, info):
- os.chmod(name, 0700)
- os.remove(name)
-
-
-def setup_http(httpdir, addr, port):
- os.mkdir(httpdir)
- os.mkdir(httpdir + '/conf.d')
- os.mkdir(httpdir + '/html')
- os.mkdir(httpdir + '/logs')
- os.symlink('/etc/httpd/modules', httpdir + '/modules')
-
- with open('tests/httpd.conf') as f:
- t = Template(f.read())
- text = t.substitute({'HTTPROOT': httpdir,
- 'HTTPADDR': addr, 'HTTPPORT': port})
- with open(httpdir + '/httpd.conf', 'w+') as f:
- f.write(text)
-
-
-def setup_test(path, test):
- profile = 'tests/%s.cfg' % test
- if not os.path.exists(profile):
- raise ValueError('Unrecognized test name [%s]' % test)
-
- opts = {}
- config = ConfigParser.ConfigParser()
- config.read(profile)
- if 'tests' not in config.sections():
- raise ValueError('Missing [tests] in profile [%s]' % test)
- T = config.options('tests')
- for t in T:
- opts[t] = config.get('tests', t)
-
- base = '%s/%s' % (path, test)
- if os.path.exists(base):
- shutil.rmtree(base, onerror=force_remove)
- os.makedirs(base)
- shutil.copytree('templates', base + '/templates')
- os.mkdir(base + '/etc')
- os.mkdir(base + '/lib')
- os.mkdir(base + '/lib/' + test)
- os.mkdir(base + '/log')
-
- with open(profile) as f:
- t = Template(f.read())
- text = t.substitute({'TESTDIR': base, 'ROOTDIR': os.getcwd(),
- 'TEST_USER': pwd.getpwuid(os.getuid())[0]})
- with open(base + '/profile.cfg', 'w+') as f:
- f.write(text)
-
- opts['basedir'] = base
- return opts
-
-
-def generate_profile(profile, name):
- config = ConfigParser.ConfigParser()
- config.read(profile)
-
- global_section = '%s_globals' % name
- global_options = {}
- if global_section in config.sections():
- G = config.options(global_section)
- for g in G:
- global_options[g] = config.get(global_section, g)
-
- args_section = '%s_arguments' % name
- args_options = {}
- if args_section in config.sections():
- A = config.options(args_section)
- for a in A:
- args_options[a] = config.get(args_section, a)
-
- newconf = ConfigParser.ConfigParser()
- newconf.add_section('globals')
- for k in global_options.keys():
- newconf.set('globals', k, global_options[k])
- newconf.add_section('arguments')
- for k in args_options.keys():
- newconf.set('arguments', k, args_options[k])
-
- filename = os.path.join(os.path.dirname(profile), '%s_profile.cfg' % name)
- with open(filename, 'wb') as f:
- newconf.write(f)
-
- return filename
-
-
-def fixup_sp_httpd(httpdir):
- location = """
-
-Alias /sp ${HTTPDIR}/sp
-
-<Directory ${HTTPDIR}/sp>
- Require all granted
-</Directory>
-"""
- index = """WORKS!"""
-
- t = Template(location)
- text = t.substitute({'HTTPDIR': httpdir})
- with open(httpdir + '/conf.d/ipsilon-saml.conf', 'a') as f:
- f.write(text)
-
- os.mkdir(httpdir + '/sp')
- with open(httpdir + '/sp/index.html', 'w') as f:
- f.write(index)
-
-
def try_wrappers(base, wrappers):
if wrappers == 'no':
return {}
@@ -192,83 +89,38 @@ def try_wrappers(base, wrappers):
return wenv
+
if __name__ == '__main__':
args = parse_args()
+ tests = Tests()
+ if args['test'] not in tests.plugins:
+ print >> sys.stderr, "Unknown test [%s]" % args['test']
+ sys.exit(1)
+ test = tests.plugins[args['test']]
+
if not os.path.exists(args['path']):
os.makedirs(args['path'])
+
openlogs(args['path'], args['test'])
- options = setup_test(args['path'], args['test'])
- basedir = options['basedir']
+ test.setup_base(args['path'], test)
- env = try_wrappers(basedir, args['wrappers'])
- env['PYTHONPATH'] = './'
+ env = try_wrappers(test.testdir, args['wrappers'])
+ env['PYTHONPATH'] = test.rootdir
- srvs = []
try:
- for h in options['servers'].split(','):
- sname, saddr, sport = h.split(':')
- basehttpdir = '%s/%s' % (basedir, sname)
- setup_http(basehttpdir, saddr, sport)
-
- print "Installing IDP server %s" % sname
- sprofile = generate_profile('%s/profile.cfg' % basedir, sname)
- p = subprocess.Popen(['./ipsilon/install/ipsilon-server-install',
- '--config-profile=%s' % sprofile], env=env,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- stdout, stderr = p.communicate()
- logger.error(stderr)
- logger.info(stdout)
- if p.returncode:
- sys.exit(p.returncode)
-
- os.symlink('%s/ipsilon' % os.getcwd(),
- '%s/lib/%s/ipsilon' % (basedir, sname))
-
- print "Starting httpd server in %s" % basehttpdir
- srv = subprocess.Popen(['/usr/sbin/httpd', '-DFOREGROUND',
- '-f', basehttpdir + '/httpd.conf'],
- env=env, preexec_fn=os.setsid)
- srvs.append(srv)
-
- for h in options['clients'].split(','):
- sname, saddr, sport = h.split(':')
- basehttpdir = '%s/%s' % (basedir, sname)
- setup_http(basehttpdir, saddr, sport)
-
- print "Installing SP server %s" % sname
- sprofile = generate_profile('%s/profile.cfg' % basedir, sname)
- p = subprocess.Popen(['./ipsilon/install/ipsilon-client-install',
- '--config-profile=%s' % sprofile], env=env,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- stdout, stderr = p.communicate()
- logger.error(stderr)
- logger.info(stdout)
- if p.returncode:
- sys.exit(p.returncode)
-
- fixup_sp_httpd(basehttpdir)
-
- print "Starting httpd server in %s" % basehttpdir
- srv = subprocess.Popen(['/usr/sbin/httpd', '-DFOREGROUND',
- '-f', basehttpdir + '/httpd.conf'],
- env=env, preexec_fn=os.setsid)
- srvs.append(srv)
-
- print "Testing installation"
- if os.path.exists('tests/%s.py' % args['test']):
- code = subprocess.call(['./tests/%s.py' % args['test'], basedir],
- env=env)
- if code:
- sys.exit(code)
- except Exception: # pylint: disable=broad-except
+ test.setup_servers(env)
+
+ code = test.run(env)
+ if code:
+ sys.exit(code)
+ except Exception, e: # pylint: disable=broad-except
+ print >> sys.stderr, "Error: %s" % repr(e)
+ traceback.print_exc(None, sys.stderr)
sys.exit(1)
finally:
- for srv in srvs:
- os.killpg(srv.pid, signal.SIGTERM)
+ test.wait()
print "FINISHED"