silverlining / tests / functional /

"""Functional test for Silver Lining."""

import os
import time
import re
import urllib
from scripttest import TestFileEnvironment
from import ssh

here = os.path.dirname(os.path.abspath(__file__))

def get_environment():
    env = TestFileEnvironment(os.path.join(here, 'test-data'))
    return env

stage_seq = ['create-node', 'setup-node', 'clean', 'update', 'update-path',
             'logs', 'query', 'activation', 'backup-update', 'backup-clear']

def run_stage(name, match):
    return match in stage_seq[stage_seq.index(name):]

def run_test(name, stage=None, ci=False, setup_node=False):
        if stage is None:
            if name:
                stage = 'clean'
                stage = 'setup-node'
        env = get_environment()
        if not name:
            name = '' % int(time.time())
            print 'Creating node %s' % name
            print'silver --yes create-node --wait %s' % name,

        if run_stage(stage, 'setup-node') or setup_node:
            print 'Setting up node %s' % name
            print'silver --yes setup-node %s' % name,

        if run_stage(stage, 'clean'):
            print'silver --yes deactivate --node=%s "*"' % name)
            print'silver --yes clean-node %s' % name)

        if run_stage(stage, 'update'):
            print 'Doing update'
            result ='silver --yes update "%s" %s'
                             % (os.path.join(here, 'example-app'), name),
            print result
            assert 'env CONFIG_COUCHDB_DB=functest' in result.stdout, result.stdout
            assert 'env CONFIG_COUCHDB_HOST=' in result.stdout, result.stdout
            assert 'env CONFIG_FILES=/var/lib/silverlining/apps/functest' in result.stdout, result.stdout
            assert 'env CONFIG_PG_DBNAME=functest' in result.stdout, result.stdout
            assert 'env CONFIG_PG_HOST=' in result.stdout, result.stdout
            assert 'env CONFIG_PG_PASSWORD=' in result.stdout, result.stdout
            assert 'env CONFIG_PG_PORT=' in result.stdout, result.stdout
            assert 'env CONFIG_PG_SQLALCHEMY=postgres://postgres@/functest' in result.stdout, result.stdout
            assert 'env CONFIG_PG_USER=www-mgr' in result.stdout, result.stdout
            assert 'env CONFIG_WRITABLE_ROOT=/var/lib/silverlining/writable-roots/functest' in result.stdout, result.stdout
            assert 'env SILVER_VERSION=silverlining/' in result.stdout, result.stdout
            result ='silver --yes update --debug-single-process "%s" %s'
                             % (os.path.join(here, 'example-app'), name),
            print result
            resp = urllib.urlopen('http://%s/update' % name).read()
            print 'Got HTTP response:\n%s' % resp
            assert ('SILVER_CANONICAL_HOSTNAME=%s' % name) in resp
            assert 'wsgi.multiprocess=True' in resp
            assert 'wsgi.multithread=True' in resp
            assert "path='' '/update'" in resp
            resp = urllib.urlopen('http://%s/static_file.txt' % name).read()
            print 'Got static HTTP response:\n%s' % resp
            assert resp.strip() == 'This is a test'
            resp = urllib.urlopen('http://%s/write-root' % name).read()
            assert resp.strip().startswith('WRITABLE_ROOT='), resp
            resp = urllib.urlopen('http://%s/test-writable.txt' % name).read()
            assert resp.strip() == 'test writable', resp
            resp = urllib.urlopen('http://%s/test-hosted.txt' % name).read()
            assert resp.strip() == 'test hosted', resp

        if run_stage(stage, 'update-path'):
            print 'Doing update to path'
            result ='silver --yes update "%s" %s/test'
                             % (os.path.join(here, 'example-app'), name),
            print result
            url = 'http://%s/test/update' % name
            resp = urllib.urlopen(url).read()
            print 'The actual HTTP response: (%s)' % url
            print resp

        if run_stage(stage, 'logs'):
            print 'Doing log check'
            ssh('www-data', name, ['bash', '-c', 'rm /var/log/silverlining/apps/functest/*'])
            url = 'http://%s/test/update' % name
            resp = urllib.urlopen(url).read()
            text, _, _ = ssh('www-data', name,
                             ['cat', '/var/log/silverlining/apps/functest/errors.log'],
            text_lines = ''.join(text.strip().splitlines(True)[1:-1]).strip()
            assert text_lines == """\
Executed application
This is stdout
This is stderr""", repr(text_lines)

        if run_stage(stage, 'query'):
            print 'Doing query'
            result ='silver --yes query %s' % name)
            print result
            assert 'Site: default-disabled' in result.stdout
            assert 'default-disabled: disabled/' in result.stdout
            assert 'functest' in result.stdout
            assert'functest.*?: %s/' % name, result.stdout)

        if run_stage(stage, 'activation'):
            print'silver --yes deactivate %s/test' % name)
            print'silver --yes query %s' % name)
            print'silver --yes activate %s prev' % name)
            print'silver --yes query %s' % name)

        if run_stage(stage, 'backup-update'):
            print'silver --yes deactivate --node=%s "*"' % name)
            print'silver --yes update "%s" %s'
                          % (os.path.join(here, 'example-backup'), name),
            url = 'http://%s/' % name
            resp = urllib.urlopen(url).read()
            print resp
            resp ='silver --yes backup %s/ test-backup/' % name)
            print resp
            assert 'test-backup/mysql/mysql.dump' in resp.files_created
            assert 'test-backup/files/files.tar' in resp.files_created

        if run_stage(stage, 'backup-clear'):
            print'silver --yes clear %s' % name)
            resp ='silver --yes backup %s/ test-backup-cleared/' % name)
            print resp
            assert 'test_table' not in resp.files_created['test-backup-cleared/mysql/mysql.dump'].bytes
            resp ='silver --yes backup %s/ test-backup-bare/' % name)
            print resp
            assert 'test_table' in resp.files_created['test-backup-bare/mysql/mysql.dump'].bytes
            print'silver --yes clear %s' % name)
            resp ='silver --yes restore test-backup-bare/ %s' % name)
            print resp
            resp ='silver --yes backup %s/ test-backup-restored/' % name)
            assert 'test_table' in resp.files_created['test-backup-restored/mysql/mysql.dump'].bytes

        print 'Name used: %s' % name
        if ci:
            print 'Cleaning up server'
  'silver --yes destroy-node %s' % name)

if __name__ == '__main__':
    import optparse
    parser = optparse.OptionParser()
    parser.add_option('--ci', action='store_true')
    parser.add_option('--setup-node', action='store_true')
    options, args = parser.parse_args()
    run_test(, options.stage or None,,
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.