| Index: git_cl/test/local_rietveld.py
|
| diff --git a/git_cl/test/local_rietveld.py b/git_cl/test/local_rietveld.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..95e27b60b3bac41052abc90a99a90ac47df97b3e
|
| --- /dev/null
|
| +++ b/git_cl/test/local_rietveld.py
|
| @@ -0,0 +1,132 @@
|
| +# Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
| +# Use of this source code is governed by a BSD-style license that can be
|
| +# found in the LICENSE file.
|
| +
|
| +"""Setups a local Rietveld instance to test against a live server for
|
| +integration tests.
|
| +
|
| +It makes sure Google AppEngine SDK is found, download Rietveld and Django code
|
| +if necessary and starts the server on a free inbound TCP port.
|
| +"""
|
| +
|
| +import os
|
| +import socket
|
| +import subprocess
|
| +import time
|
| +
|
| +
|
| +class Failure(Exception):
|
| + pass
|
| +
|
| +
|
| +def test_port(port):
|
| + s = socket.socket()
|
| + try:
|
| + return s.connect_ex(('127.0.0.1', port)) == 0
|
| + finally:
|
| + s.close()
|
| +
|
| +
|
| +def find_free_port():
|
| + # Test to find an available port starting at 8080.
|
| + port = 8080
|
| + max_val = (2<<16)
|
| + while test_port(port) and port < max_val:
|
| + port += 1
|
| + if port == max_val:
|
| + raise Failure('Having issues finding an available port')
|
| + return port
|
| +
|
| +
|
| +class LocalRietveld(object):
|
| + """Downloads everything needed to run a local instance of Rietveld."""
|
| +
|
| + def __init__(self, base_dir=None):
|
| + # Paths
|
| + self.base_dir = base_dir
|
| + if not self.base_dir:
|
| + self.base_dir = os.path.dirname(os.path.abspath(__file__))
|
| + self.base_dir = os.path.realpath(os.path.join(self.base_dir, '..'))
|
| + self.sdk_path = os.path.abspath(
|
| + os.path.join(self.base_dir, '..', '..', 'google_appengine'))
|
| + self.dev_app = os.path.join(self.sdk_path, 'dev_appserver.py')
|
| + self.rietveld = os.path.join(self.base_dir, 'test', 'rietveld')
|
| + self.django_path = os.path.join(self.rietveld, 'django')
|
| + self.test_server = None
|
| + self.port = None
|
| + # Generate a friendly environment.
|
| + self.env = os.environ.copy()
|
| + self.env['LANGUAGE'] = 'en'
|
| + if self.env.get('PYTHONPATH'):
|
| + self.env['PYTHONPATH'] = (
|
| + self.env['PYTHONPATH'].rstrip(os.pathsep) + os.pathsep +
|
| + self.django_path)
|
| + else:
|
| + self.env['PYTHONPATH'] = self.django_path
|
| +
|
| + def install_prerequisites(self):
|
| + # First, verify the Google AppEngine SDK is available.
|
| + if not os.path.isfile(self.dev_app):
|
| + raise Failure('Install google_appengine sdk in %s' % self.sdk_path)
|
| +
|
| + def call(*args, **kwargs):
|
| + kwargs['env'] = self.env
|
| + x = subprocess.Popen(*args, **kwargs)
|
| + x.communicate()
|
| + return x.returncode == 0
|
| +
|
| + # Second, checkout rietveld and django if not available.
|
| + if not os.path.isdir(self.rietveld):
|
| + print('Checking out rietveld...')
|
| + if not call(
|
| + ['svn', 'co', '-q',
|
| + 'http://rietveld.googlecode.com/svn/trunk@563',
|
| + self.rietveld]):
|
| + raise Failure('Failed to checkout rietveld')
|
| + if not os.path.isdir(self.django_path):
|
| + print('Checking out django...')
|
| + if not call(
|
| + ['svn', 'co', '-q',
|
| + 'http://code.djangoproject.com/'
|
| + 'svn/django/branches/releases/1.0.X/django@13637',
|
| + self.django_path]):
|
| + raise Failure('Failed to checkout django')
|
| +
|
| + def start_server(self, verbose=False):
|
| + self.install_prerequisites()
|
| + self.port = find_free_port()
|
| + if verbose:
|
| + stdout = None
|
| + stderr = None
|
| + else:
|
| + stdout = subprocess.PIPE
|
| + stderr = subprocess.PIPE
|
| + output = []
|
| + self.test_server = subprocess.Popen(
|
| + [self.dev_app, self.rietveld, '--port=%d' % self.port,
|
| + '--datastore_path=' + os.path.join(self.rietveld, 'tmp.db'), '-c'],
|
| + stdout=stdout, stderr=stderr, env=self.env)
|
| + # Loop until port 127.0.0.1:port opens or the process dies.
|
| + while not test_port(self.port):
|
| + self.test_server.poll()
|
| + if self.test_server.returncode is not None:
|
| + raise Failure(
|
| + 'Test rietveld instance failed early on port %s' %
|
| + self.port)
|
| + time.sleep(0.001)
|
| +
|
| + def stop_server(self):
|
| + if self.test_server:
|
| + self.test_server.kill()
|
| + self.test_server = None
|
| + self.port = None
|
| +
|
| +
|
| +def main():
|
| + print LocalRietveld().start_server()
|
| +
|
| +
|
| +if __name__ == '__main__':
|
| + main()
|
| +
|
| +# vim: ts=4:sw=4:tw=80:et:
|
|
|