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: |