/tests/functional/runtest.py

https://bitbucket.org/ianb/silverlining/ · Python · 168 lines · 147 code · 20 blank · 1 comment · 20 complexity · fc8959ac3325963db61075a2ba03fe16 MD5 · raw file

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