3 # Copyright (C) 2014 Simo Sorce <simo@redhat.com>
5 # see file 'COPYING' for use and warranty information
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
22 from datetime import datetime
30 from string import Template
37 parser = argparse.ArgumentParser(description='Ipsilon Tests Environment')
38 parser.add_argument('--path', default='%s/testdir' % os.getcwd(),
39 help="Directory in which tests are run")
40 parser.add_argument('--test', default='test1',
41 help="The test to run")
42 parser.add_argument('--wrappers', default='auto',
43 choices=['yes', 'no', 'auto'],
44 help="Run the tests with socket wrappers")
46 return vars(parser.parse_args())
49 def openlogs(path, test):
50 global logger # pylint: disable=W0603
51 logger = logging.getLogger()
53 datestr = datetime.now().strftime("%Y-%m-%d_%H:%M:%S")
54 filename = '%s/test-%s-%s.log' % (path, test, datestr)
55 lh = logging.FileHandler(filename)
57 print >> sys.stderr, 'Unable to open %s (%s)' % (filename, str(e))
58 lh = logging.StreamHandler(sys.stderr)
59 formatter = logging.Formatter('[%(asctime)s] %(message)s')
60 lh.setFormatter(formatter)
62 logger.setLevel(logging.DEBUG)
65 def force_remove(op, name, info):
70 def setup_http(httpdir, addr, port):
72 os.mkdir(httpdir + '/conf.d')
73 os.mkdir(httpdir + '/html')
74 os.mkdir(httpdir + '/logs')
75 os.symlink('/etc/httpd/modules', httpdir + '/modules')
77 with open('tests/httpd.conf') as f:
78 t = Template(f.read())
79 text = t.substitute({'HTTPROOT': httpdir,
80 'HTTPADDR': addr, 'HTTPPORT': port})
81 with open(httpdir + '/httpd.conf', 'w+') as f:
85 def setup_test(path, test):
86 profile = 'tests/%s.cfg' % test
87 if not os.path.exists(profile):
88 raise ValueError('Unrecognized test name [%s]' % test)
91 config = ConfigParser.ConfigParser()
93 if 'tests' not in config.sections():
94 raise ValueError('Missing [tests] in profile [%s]' % test)
95 T = config.options('tests')
97 opts[t] = config.get('tests', t)
99 base = '%s/%s' % (path, test)
100 if os.path.exists(base):
101 shutil.rmtree(base, onerror=force_remove)
103 shutil.copytree('templates', base + '/templates')
104 os.mkdir(base + '/etc')
105 os.mkdir(base + '/lib')
106 os.mkdir(base + '/lib/' + test)
107 os.mkdir(base + '/log')
109 with open(profile) as f:
110 t = Template(f.read())
111 text = t.substitute({'TESTDIR': base, 'ROOTDIR': os.getcwd(),
112 'TEST_USER': pwd.getpwuid(os.getuid())[0]})
113 with open(base + '/profile.cfg', 'w+') as f:
116 opts['basedir'] = base
120 def generate_profile(profile, name):
121 config = ConfigParser.ConfigParser()
124 global_section = '%s_globals' % name
126 if global_section in config.sections():
127 G = config.options(global_section)
129 global_options[g] = config.get(global_section, g)
131 args_section = '%s_arguments' % name
133 if args_section in config.sections():
134 A = config.options(args_section)
136 args_options[a] = config.get(args_section, a)
138 newconf = ConfigParser.ConfigParser()
139 newconf.add_section('globals')
140 for k in global_options.keys():
141 newconf.set('globals', k, global_options[k])
142 newconf.add_section('arguments')
143 for k in args_options.keys():
144 newconf.set('arguments', k, args_options[k])
146 filename = os.path.join(os.path.dirname(profile), '%s_profile.cfg' % name)
147 with open(filename, 'wb') as f:
153 def fixup_sp_httpd(httpdir):
156 Alias /sp ${HTTPDIR}/sp
158 <Directory ${HTTPDIR}/sp>
164 t = Template(location)
165 text = t.substitute({'HTTPDIR': httpdir})
166 with open(httpdir + '/conf.d/ipsilon-saml.conf', 'a') as f:
169 os.mkdir(httpdir + '/sp')
170 with open(httpdir + '/sp/index.html', 'w') as f:
174 def try_wrappers(base, wrappers):
178 pkgcfg = subprocess.Popen(['pkg-config', '--exists', 'socket_wrapper'])
180 if pkgcfg.returncode != 0:
181 if wrappers == 'auto':
184 raise ValueError('Socket Wrappers not available')
186 wrapdir = os.path.join(base, 'wrapdir')
189 wenv = {'LD_PRELOAD': 'libsocket_wrapper.so',
190 'SOCKET_WRAPPER_DIR': wrapdir,
191 'SOCKET_WRAPPER_DEFAULT_IFACE': '9'}
195 if __name__ == '__main__':
199 if not os.path.exists(args['path']):
200 os.makedirs(args['path'])
201 openlogs(args['path'], args['test'])
203 options = setup_test(args['path'], args['test'])
204 basedir = options['basedir']
206 env = try_wrappers(basedir, args['wrappers'])
207 env['PYTHONPATH'] = './'
211 for h in options['servers'].split(','):
212 sname, saddr, sport = h.split(':')
213 basehttpdir = '%s/%s' % (basedir, sname)
214 setup_http(basehttpdir, saddr, sport)
216 print "Installing IDP server %s" % sname
217 sprofile = generate_profile('%s/profile.cfg' % basedir, sname)
218 p = subprocess.Popen(['./ipsilon/install/ipsilon-server-install',
219 '--config-profile=%s' % sprofile], env=env,
220 stdout=subprocess.PIPE,
221 stderr=subprocess.PIPE)
222 stdout, stderr = p.communicate()
226 sys.exit(p.returncode)
228 os.symlink('%s/ipsilon' % os.getcwd(),
229 '%s/lib/%s/ipsilon' % (basedir, sname))
231 print "Starting httpd server in %s" % basehttpdir
232 srv = subprocess.Popen(['/usr/sbin/httpd', '-DFOREGROUND',
233 '-f', basehttpdir + '/httpd.conf'],
234 env=env, preexec_fn=os.setsid)
237 for h in options['clients'].split(','):
238 sname, saddr, sport = h.split(':')
239 basehttpdir = '%s/%s' % (basedir, sname)
240 setup_http(basehttpdir, saddr, sport)
242 print "Installing SP server %s" % sname
243 sprofile = generate_profile('%s/profile.cfg' % basedir, sname)
244 p = subprocess.Popen(['./ipsilon/install/ipsilon-client-install',
245 '--config-profile=%s' % sprofile], env=env,
246 stdout=subprocess.PIPE,
247 stderr=subprocess.PIPE)
248 stdout, stderr = p.communicate()
252 sys.exit(p.returncode)
254 fixup_sp_httpd(basehttpdir)
256 print "Starting httpd server in %s" % basehttpdir
257 srv = subprocess.Popen(['/usr/sbin/httpd', '-DFOREGROUND',
258 '-f', basehttpdir + '/httpd.conf'],
259 env=env, preexec_fn=os.setsid)
262 print "Testing installation"
263 if os.path.exists('tests/%s.py' % args['test']):
264 code = subprocess.call(['./tests/%s.py' % args['test'], basedir],
268 except Exception: # pylint: disable=broad-except
272 os.killpg(srv.pid, signal.SIGTERM)