PageRenderTime 36ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/tests/functional/runtest.py

https://bitbucket.org/ianb/silverlining/
Python | 168 lines | 153 code | 14 blank | 1 comment | 12 complexity | fc8959ac3325963db61075a2ba03fe16 MD5 | raw file
Possible License(s): GPL-2.0
  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)