PageRenderTime 30ms CodeModel.GetById 2ms app.highlight 24ms RepoModel.GetById 1ms app.codeStats 0ms

/tests/functional/runtest.py

https://bitbucket.org/ianb/silverlining/
Python | 168 lines | 153 code | 14 blank | 1 comment | 26 complexity | fc8959ac3325963db61075a2ba03fe16 MD5 | raw file
  1"""Functional test for Silver Lining."""
  2
  3import os
  4import time
  5import re
  6import urllib
  7from scripttest import TestFileEnvironment
  8from silversupport.shell import ssh
  9
 10here = os.path.dirname(os.path.abspath(__file__))
 11
 12
 13def get_environment():
 14    env = TestFileEnvironment(os.path.join(here, 'test-data'))
 15    return env
 16
 17stage_seq = ['create-node', 'setup-node', 'clean', 'update', 'update-path',
 18             'logs', 'query', 'activation', 'backup-update', 'backup-clear']
 19
 20
 21def run_stage(name, match):
 22    return match in stage_seq[stage_seq.index(name):]
 23
 24
 25def run_test(name, stage=None, ci=False, setup_node=False):
 26    try:
 27        if stage is None:
 28            if name:
 29                stage = 'clean'
 30            else:
 31                stage = 'setup-node'
 32        env = get_environment()
 33        if not name:
 34            name = 'functest%s.example.com' % int(time.time())
 35            print 'Creating node %s' % name
 36            print env.run('silver --yes create-node --wait %s' % name,
 37                          expect_stderr=True)
 38
 39        if run_stage(stage, 'setup-node') or setup_node:
 40            print 'Setting up node %s' % name
 41            print env.run('silver --yes setup-node %s' % name,
 42                          expect_stderr=True)
 43
 44        if run_stage(stage, 'clean'):
 45            print env.run('silver --yes deactivate --node=%s "*"' % name)
 46            print env.run('silver --yes clean-node %s' % name)
 47
 48        if run_stage(stage, 'update'):
 49            print 'Doing update'
 50            result = env.run('silver --yes update "%s" %s'
 51                             % (os.path.join(here, 'example-app'), name),
 52                             expect_stderr=True)
 53            print result
 54            assert 'env CONFIG_COUCHDB_DB=functest' in result.stdout, result.stdout
 55            assert 'env CONFIG_COUCHDB_HOST=127.0.0.1:5984' in result.stdout, result.stdout
 56            assert 'env CONFIG_FILES=/var/lib/silverlining/apps/functest' in result.stdout, result.stdout
 57            assert 'env CONFIG_PG_DBNAME=functest' in result.stdout, result.stdout
 58            assert 'env CONFIG_PG_HOST=' in result.stdout, result.stdout
 59            assert 'env CONFIG_PG_PASSWORD=' in result.stdout, result.stdout
 60            assert 'env CONFIG_PG_PORT=' in result.stdout, result.stdout
 61            assert 'env CONFIG_PG_SQLALCHEMY=postgres://postgres@/functest' in result.stdout, result.stdout
 62            assert 'env CONFIG_PG_USER=www-mgr' in result.stdout, result.stdout
 63            assert 'env CONFIG_WRITABLE_ROOT=/var/lib/silverlining/writable-roots/functest' in result.stdout, result.stdout
 64            assert 'env SILVER_VERSION=silverlining/' in result.stdout, result.stdout
 65            result = env.run('silver --yes update --debug-single-process "%s" %s'
 66                             % (os.path.join(here, 'example-app'), name),
 67                             expect_stderr=True)
 68            print result
 69            resp = urllib.urlopen('http://%s/update' % name).read()
 70            print 'Got HTTP response:\n%s' % resp
 71            assert ('SILVER_CANONICAL_HOSTNAME=%s' % name) in resp
 72            assert 'wsgi.multiprocess=True' in resp
 73            assert 'wsgi.multithread=True' in resp
 74            assert "path='' '/update'" in resp
 75            resp = urllib.urlopen('http://%s/static_file.txt' % name).read()
 76            print 'Got static HTTP response:\n%s' % resp
 77            assert resp.strip() == 'This is a test'
 78            resp = urllib.urlopen('http://%s/write-root' % name).read()
 79            assert resp.strip().startswith('WRITABLE_ROOT='), resp
 80            resp = urllib.urlopen('http://%s/test-writable.txt' % name).read()
 81            assert resp.strip() == 'test writable', resp
 82            resp = urllib.urlopen('http://%s/test-hosted.txt' % name).read()
 83            assert resp.strip() == 'test hosted', resp
 84
 85        if run_stage(stage, 'update-path'):
 86            print 'Doing update to path'
 87            result = env.run('silver --yes update "%s" %s/test'
 88                             % (os.path.join(here, 'example-app'), name),
 89                             expect_stderr=True)
 90            print result
 91            url = 'http://%s/test/update' % name
 92            resp = urllib.urlopen(url).read()
 93            print 'The actual HTTP response: (%s)' % url
 94            print resp
 95
 96        if run_stage(stage, 'logs'):
 97            print 'Doing log check'
 98            ssh('www-data', name, ['bash', '-c', 'rm /var/log/silverlining/apps/functest/*'])
 99            url = 'http://%s/test/update' % name
100            resp = urllib.urlopen(url).read()
101            text, _, _ = ssh('www-data', name,
102                             ['cat', '/var/log/silverlining/apps/functest/errors.log'],
103                             capture_stdout=True)
104            text_lines = ''.join(text.strip().splitlines(True)[1:-1]).strip()
105            assert text_lines == """\
106Executed application
107This is stdout
108This is stderr""", repr(text_lines)
109
110        if run_stage(stage, 'query'):
111            print 'Doing query'
112            result = env.run('silver --yes query %s' % name)
113            print result
114            assert 'Site: default-disabled' in result.stdout
115            assert 'default-disabled: disabled/' in result.stdout
116            assert 'functest' in result.stdout
117            assert re.search(r'functest.*?: %s/' % name, result.stdout)
118
119        if run_stage(stage, 'activation'):
120            print env.run('silver --yes deactivate %s/test' % name)
121            print env.run('silver --yes query %s' % name)
122            print env.run('silver --yes activate %s prev' % name)
123            print env.run('silver --yes query %s' % name)
124
125        if run_stage(stage, 'backup-update'):
126            print env.run('silver --yes deactivate --node=%s "*"' % name)
127            print env.run('silver --yes update "%s" %s'
128                          % (os.path.join(here, 'example-backup'), name),
129                          expect_stderr=True)
130            url = 'http://%s/' % name
131            resp = urllib.urlopen(url).read()
132            print resp
133            resp = env.run('silver --yes backup %s/ test-backup/' % name)
134            print resp
135            assert 'test-backup/mysql/mysql.dump' in resp.files_created
136            assert 'test-backup/files/files.tar' in resp.files_created
137
138        if run_stage(stage, 'backup-clear'):
139            print env.run('silver --yes clear %s' % name)
140            resp = env.run('silver --yes backup %s/ test-backup-cleared/' % name)
141            print resp
142            assert 'test_table' not in resp.files_created['test-backup-cleared/mysql/mysql.dump'].bytes
143            urllib.urlopen('http://'+name).read()
144            resp = env.run('silver --yes backup %s/ test-backup-bare/' % name)
145            print resp
146            assert 'test_table' in resp.files_created['test-backup-bare/mysql/mysql.dump'].bytes
147            print env.run('silver --yes clear %s' % name)
148            resp = env.run('silver --yes restore test-backup-bare/ %s' % name)
149            print resp
150            resp = env.run('silver --yes backup %s/ test-backup-restored/' % name)
151            assert 'test_table' in resp.files_created['test-backup-restored/mysql/mysql.dump'].bytes
152
153    finally:
154        print 'Name used: %s' % name
155        if ci:
156            print 'Cleaning up server'
157            env.run('silver --yes destroy-node %s' % name)
158
159if __name__ == '__main__':
160    import optparse
161    parser = optparse.OptionParser()
162    parser.add_option('--name')
163    parser.add_option('--stage')
164    parser.add_option('--ci', action='store_true')
165    parser.add_option('--setup-node', action='store_true')
166    options, args = parser.parse_args()
167    run_test(options.name, options.stage or None, options.ci,
168             setup_node=options.setup_node)