| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """Setups a local Rietveld instance to test against a live server for | 6 """Setups a local Rietveld instance to test against a live server for |
| 7 integration tests. | 7 integration tests. |
| 8 | 8 |
| 9 It makes sure Google AppEngine SDK is found, download Rietveld and Django code | 9 It makes sure Google AppEngine SDK is found, download Rietveld and Django code |
| 10 if necessary and starts the server on a free inbound TCP port. | 10 if necessary and starts the server on a free inbound TCP port. |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 """Downloads everything needed to run a local instance of Rietveld.""" | 51 """Downloads everything needed to run a local instance of Rietveld.""" |
| 52 | 52 |
| 53 def __init__(self, base_dir=None): | 53 def __init__(self, base_dir=None): |
| 54 # Paths | 54 # Paths |
| 55 self.base_dir = base_dir | 55 self.base_dir = base_dir |
| 56 if not self.base_dir: | 56 if not self.base_dir: |
| 57 self.base_dir = os.path.dirname(os.path.abspath(__file__)) | 57 self.base_dir = os.path.dirname(os.path.abspath(__file__)) |
| 58 # TODO(maruel): This should be in /tmp but that would mean having to fetch | 58 # TODO(maruel): This should be in /tmp but that would mean having to fetch |
| 59 # everytime. This test is already annoyingly slow. | 59 # everytime. This test is already annoyingly slow. |
| 60 self.rietveld = os.path.join(self.base_dir, '_rietveld') | 60 self.rietveld = os.path.join(self.base_dir, '_rietveld') |
| 61 self.rietveld_app = os.path.join( |
| 62 self.rietveld, 'appengine', 'chromium_rietveld') |
| 61 self.test_server = None | 63 self.test_server = None |
| 62 self.port = None | 64 self.port = None |
| 63 self.tempdir = None | 65 self.tempdir = None |
| 64 | 66 |
| 65 # Find the GAE SDK | 67 # Find the GAE SDK |
| 66 previous_dir = '' | 68 previous_dir = '' |
| 67 self.sdk_path = '' | 69 self.sdk_path = '' |
| 68 base_dir = self.base_dir | 70 base_dir = self.base_dir |
| 69 while base_dir != previous_dir: | 71 while base_dir != previous_dir: |
| 70 previous_dir = base_dir | 72 previous_dir = base_dir |
| 71 self.sdk_path = os.path.join(base_dir, 'google_appengine') | 73 self.sdk_path = os.path.join(base_dir, 'google_appengine') |
| 72 if not os.path.isfile(os.path.join(self.sdk_path, 'VERSION')): | 74 if not os.path.isfile(os.path.join(self.sdk_path, 'VERSION')): |
| 73 base_dir = os.path.dirname(base_dir) | 75 base_dir = os.path.dirname(base_dir) |
| 74 self.dev_app = os.path.join(self.sdk_path, 'dev_appserver.py') | 76 self.dev_app = os.path.join(self.sdk_path, 'dev_appserver.py') |
| 75 | 77 |
| 76 def install_prerequisites(self): | 78 def install_prerequisites(self): |
| 77 # First, verify the Google AppEngine SDK is available. | 79 # First, verify the Google AppEngine SDK is available. |
| 78 if not os.path.isfile(self.dev_app): | 80 if not os.path.isfile(self.dev_app): |
| 79 raise Failure( | 81 raise Failure( |
| 80 'Install google_appengine sdk in %s or higher up' % self.base_dir) | 82 'Install google_appengine sdk in %s or higher up' % self.base_dir) |
| 81 | 83 |
| 82 if os.path.isdir(os.path.join(self.rietveld, '.svn')): | 84 if os.path.isdir(os.path.join(self.rietveld, '.svn')): |
| 83 # Left over from subversion. Delete it. | 85 # Left over from subversion. Delete it. |
| 86 print('Deleting deprecated subversion rietveld files...') |
| 87 shutil.rmtree(self.rietveld) |
| 88 |
| 89 if os.path.isdir(os.path.join(self.rietveld, '.hg')): |
| 90 # Left over from mercurial. Delete it. |
| 91 print('Deleting deprecated mercurial rietveld files...') |
| 84 shutil.rmtree(self.rietveld) | 92 shutil.rmtree(self.rietveld) |
| 85 | 93 |
| 86 # Second, checkout rietveld if not available. | 94 # Second, checkout rietveld if not available. |
| 87 rev = '9349cab9a3bb' | |
| 88 if not os.path.isdir(self.rietveld): | 95 if not os.path.isdir(self.rietveld): |
| 89 print('Checking out rietveld...') | 96 print('Checking out rietveld...') |
| 90 try: | 97 try: |
| 98 subprocess2.check_call(['git', 'init', self.rietveld]) |
| 91 subprocess2.check_call( | 99 subprocess2.check_call( |
| 92 [ 'hg', 'clone', '-q', '-u', rev, '-r', rev, | 100 ['git', 'remote', 'add', '-f', 'origin', |
| 93 'https://code.google.com/p/rietveld/', self.rietveld]) | 101 'https://chromium.googlesource.com/infra/infra.git'], |
| 102 cwd=self.rietveld) |
| 103 subprocess2.check_call( |
| 104 ['git', 'config', 'core.sparseCheckout', 'true'], |
| 105 cwd=self.rietveld) |
| 106 with file(os.path.join(self.rietveld, '.git/info/sparse-checkout'), |
| 107 'w') as sparse_file: |
| 108 sparse_file.write('appengine/chromium_rietveld') |
| 109 subprocess2.check_call( |
| 110 ['git', 'pull', 'origin', 'master'], |
| 111 cwd=self.rietveld) |
| 94 except (OSError, subprocess2.CalledProcessError), e: | 112 except (OSError, subprocess2.CalledProcessError), e: |
| 95 raise Failure( | 113 raise Failure('Failed to clone rietveld. \n%s' % e) |
| 96 'Failed to checkout rietveld. Do you have mercurial installed?\n' | |
| 97 '%s' % e) | |
| 98 else: | 114 else: |
| 99 print('Syncing rietveld...') | 115 print('Syncing rietveld...') |
| 100 try: | 116 try: |
| 101 subprocess2.check_call( | 117 subprocess2.check_call( |
| 102 ['hg', 'co', '-q', '-C', rev], cwd=self.rietveld) | 118 ['git', 'pull', 'origin', 'master'], |
| 119 cwd=self.rietveld) |
| 103 except (OSError, subprocess2.CalledProcessError), e: | 120 except (OSError, subprocess2.CalledProcessError), e: |
| 104 raise Failure('Failed to sync rietveld\n%s' % e) | 121 raise Failure('Failed to sync rietveld\n%s' % e) |
| 105 | 122 |
| 106 def start_server(self, verbose=False): | 123 def start_server(self, verbose=False): |
| 107 self.install_prerequisites() | 124 self.install_prerequisites() |
| 108 assert not self.tempdir | 125 assert not self.tempdir |
| 109 self.tempdir = tempfile.mkdtemp(prefix='rietveld_test') | 126 self.tempdir = tempfile.mkdtemp(prefix='rietveld_test') |
| 110 self.port = find_free_port(10000) | 127 self.port = find_free_port(10000) |
| 111 admin_port = find_free_port(self.port + 1) | 128 admin_port = find_free_port(self.port + 1) |
| 112 if verbose: | 129 if verbose: |
| 113 stdout = stderr = None | 130 stdout = stderr = None |
| 114 else: | 131 else: |
| 115 stdout = subprocess2.PIPE | 132 stdout = subprocess2.PIPE |
| 116 stderr = subprocess2.STDOUT | 133 stderr = subprocess2.STDOUT |
| 117 cmd = [ | 134 cmd = [ |
| 118 sys.executable, | 135 sys.executable, |
| 119 self.dev_app, | 136 self.dev_app, |
| 120 '.', | 137 './app.yaml', # Explicitly specify file to avoid bringing up backends. |
| 121 '--port', str(self.port), | 138 '--port', str(self.port), |
| 122 '--admin_port', str(admin_port), | 139 '--admin_port', str(admin_port), |
| 123 '--storage', self.tempdir, | 140 '--storage', self.tempdir, |
| 124 '--clear_search_indexes', | 141 '--clear_search_indexes', |
| 125 '--skip_sdk_update_check', | 142 '--skip_sdk_update_check', |
| 126 ] | 143 ] |
| 127 | 144 |
| 128 # CHEAP TRICK | 145 # CHEAP TRICK |
| 129 # By default you only want to bind on loopback but I'm testing over a | 146 # By default you only want to bind on loopback but I'm testing over a |
| 130 # headless computer so it's useful to be able to access the test instance | 147 # headless computer so it's useful to be able to access the test instance |
| 131 # remotely. | 148 # remotely. |
| 132 if os.environ.get('GAE_LISTEN_ALL', '') == 'true': | 149 if os.environ.get('GAE_LISTEN_ALL', '') == 'true': |
| 133 cmd.extend(('-a', '0.0.0.0')) | 150 cmd.extend(('-a', '0.0.0.0')) |
| 134 logging.info(' '.join(cmd)) | 151 logging.info(' '.join(cmd)) |
| 135 self.test_server = subprocess2.Popen( | 152 self.test_server = subprocess2.Popen( |
| 136 cmd, stdout=stdout, stderr=stderr, cwd=self.rietveld) | 153 cmd, stdout=stdout, stderr=stderr, cwd=self.rietveld_app) |
| 137 # Loop until port 127.0.0.1:port opens or the process dies. | 154 # Loop until port 127.0.0.1:port opens or the process dies. |
| 138 while not test_port(self.port): | 155 while not test_port(self.port): |
| 139 self.test_server.poll() | 156 self.test_server.poll() |
| 140 if self.test_server.returncode is not None: | 157 if self.test_server.returncode is not None: |
| 141 if not verbose: | 158 if not verbose: |
| 142 out = self.test_server.communicate()[0] | 159 out = self.test_server.communicate()[0] |
| 143 shutil.rmtree(self.tempdir) | 160 shutil.rmtree(self.tempdir) |
| 144 self.tempdir = None | 161 self.tempdir = None |
| 145 raise Failure( | 162 raise Failure( |
| 146 'Test rietveld instance failed early on port %s\n%s' % | 163 'Test rietveld instance failed early on port %s\n%s' % |
| (...skipping 25 matching lines...) Expand all Loading... |
| 172 instance.start_server(verbose=options.verbose) | 189 instance.start_server(verbose=options.verbose) |
| 173 print 'Local rietveld instance started on port %d' % instance.port | 190 print 'Local rietveld instance started on port %d' % instance.port |
| 174 while True: | 191 while True: |
| 175 time.sleep(0.1) | 192 time.sleep(0.1) |
| 176 finally: | 193 finally: |
| 177 instance.stop_server() | 194 instance.stop_server() |
| 178 | 195 |
| 179 | 196 |
| 180 if __name__ == '__main__': | 197 if __name__ == '__main__': |
| 181 main() | 198 main() |
| OLD | NEW |