/tests/functional/runtest.py
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)