Make it possible to use PluginLoader without store
[cascardo/ipsilon.git] / tests / dbupgrades.py
1 #!/usr/bin/python
2 #
3 # Copyright (C) 2014 Ipsilon project Contributors, for license see COPYING
4
5 from helpers.common import IpsilonTestBase  # pylint: disable=relative-import
6 from helpers.http import HttpSessions  # pylint: disable=relative-import
7 import os
8 import pwd
9 import sys
10 import signal
11 import subprocess
12 import ipsilon.util.data
13
14 idp_g = {'TEMPLATES': '${TESTDIR}/templates/install',
15          'CONFDIR': '${TESTDIR}/etc',
16          'DATADIR': '${TESTDIR}/lib',
17          'CACHEDIR': '${TESTDIR}/cache',
18          'HTTPDCONFD': '${TESTDIR}/${NAME}/conf.d',
19          'STATICDIR': '${ROOTDIR}',
20          'BINDIR': '${ROOTDIR}/ipsilon',
21          'WSGI_SOCKET_PREFIX': '${TESTDIR}/${NAME}/logs/wsgi'}
22
23
24 idp_a = {'hostname': '${ADDRESS}:${PORT}',
25          'admin_user': '${TEST_USER}',
26          'system_user': '${TEST_USER}',
27          'instance': '${NAME}',
28          'secure': 'no',
29          'testauth': 'yes',
30          'pam': 'no',
31          'gssapi': 'no',
32          'ipa': 'no',
33          'server_debugging': 'True'}
34
35
36 class IpsilonTest(IpsilonTestBase):
37
38     def __init__(self):
39         super(IpsilonTest, self).__init__('dbupgrades', __file__)
40
41     def setup_servers(self, env=None):
42         pass
43
44     def test_upgrade_from(self, env, old_version):
45         # Setup IDP Server
46         print "Installing IDP server to test upgrade from %i" % old_version
47         name = 'idp_v%i' % old_version
48         addr = '127.0.0.%i' % (10 + old_version)
49         port = str(45080 + old_version)
50         idp = self.generate_profile(idp_g, idp_a, name, addr, port)
51         conf = self.setup_idp_server(idp, name, addr, port, env)
52
53         # Move database of old_version into place
54         cfgfile = os.path.join(self.testdir, 'etc', name, 'ipsilon.conf')
55         db_indir = os.path.join(self.rootdir, 'tests', 'blobs', 'old_dbs',
56                                 'v%i' % old_version)
57         db_outdir = os.path.join(self.testdir, 'lib', name)
58
59         if old_version > 0:
60             for database in ['adminconfig',
61                              'openid',
62                              'saml2.sessions.db',
63                              'transactions',
64                              'userprefs']:
65                 db_in = os.path.join(db_indir, '%s.sqlite.dump' % database)
66                 db_out = os.path.join(db_outdir, '%s.sqlite' % database)
67                 os.unlink(db_out)
68                 cmd = ['/bin/sqlite3', db_out, '.read %s' % db_in]
69                 subprocess.check_call(cmd)
70
71             # Upgrade that database
72             cmd = [os.path.join(self.rootdir,
73                                 'ipsilon/install/ipsilon-upgrade-database'),
74                    cfgfile]
75             subprocess.check_call(cmd,
76                                   cwd=os.path.join(self.testdir, 'lib', name),
77                                   env=env)
78
79         # Check some version-specific changes, to see if the upgrade went OK
80         if old_version == 0:
81             # Check all features in a newly created database
82             # Let's verify if at least one index was created
83             test_db = os.path.join(db_outdir, 'adminconfig.sqlite')
84             p = subprocess.Popen(['/bin/sqlite3', test_db, '.dump'],
85                                  stdout=subprocess.PIPE)
86             output, _ = p.communicate()
87             if p.returncode:
88                 print 'Sqlite dump failed'
89                 sys.exit(1)
90             if 'CREATE INDEX' not in output:
91                 raise Exception('Database upgrade did not introduce index')
92             if 'PRIMARY KEY' not in output:
93                 raise Exception('Database upgrade did not introduce primary ' +
94                                 'key')
95         elif old_version == 1:
96             # In 1 -> 2, we added indexes and primary keys
97             # Let's verify if at least one index was created
98             test_db = os.path.join(db_outdir, 'adminconfig.sqlite')
99             p = subprocess.Popen(['/bin/sqlite3', test_db, '.dump'],
100                                  stdout=subprocess.PIPE)
101             output, _ = p.communicate()
102             if p.returncode:
103                 print 'Sqlite dump failed'
104                 sys.exit(1)
105             if 'CREATE INDEX' not in output:
106                 raise Exception('Database upgrade did not introduce index')
107             # SQLite did not support creating primary keys, so we can't test
108
109         # Start the httpd server
110         http_server = self.start_http_server(conf, env)
111
112         # Now attempt to use the upgraded database
113         exe = self.execname
114         if exe.endswith('c'):
115             exe = exe[:-1]
116         exe = [exe]
117         exe.append(str(old_version))
118         exe.append(name)
119         exe.append('%s:%s' % (addr, port))
120         exit_code = subprocess.call(exe, env=env)
121         if exit_code:
122             sys.exit(exit_code)
123
124         # Now kill the last http server
125         os.killpg(http_server.pid, signal.SIGTERM)
126         self.processes.remove(http_server)
127
128     def run(self, env):
129         for version in range(ipsilon.util.data.CURRENT_SCHEMA_VERSION):
130             self.test_upgrade_from(env, version)
131
132
133 if __name__ == '__main__':
134     from_version = sys.argv[1]
135     idpname = sys.argv[2]
136     url = sys.argv[3]
137
138     user = pwd.getpwuid(os.getuid())[0]
139
140     sess = HttpSessions()
141     sess.add_server(idpname, 'http://%s' % url, user,
142                     'ipsilon')
143
144     print "dbupgrades: From v%s: Authenticate to IDP ..." % from_version,
145     try:
146         sess.auth_to_idp(idpname)
147     except Exception, e:  # pylint: disable=broad-except
148         print >> sys.stderr, " ERROR: %s" % repr(e)
149         sys.exit(1)
150     print " SUCCESS"