Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(83)

Side by Side Diff: testing_support/local_rietveld.py

Issue 939523004: Copied files from depot_tools. (Closed) Base URL: https://chromium.googlesource.com/infra/testing/testing_support.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 #!/usr/bin/env python
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
4 # found in the LICENSE file.
5
6 """Setups a local Rietveld instance to test against a live server for
7 integration tests.
8
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.
11 """
12
13 import logging
14 import optparse
15 import os
16 import shutil
17 import socket
18 import sys
19 import tempfile
20 import time
21
22 try:
23 import subprocess2
24 except ImportError:
25 sys.path.append(
26 os.path.join(os.path.dirname(os.path.abspath(__file__)), '..'))
27 import subprocess2
iannucci 2015/02/19 00:22:39 this implies that this file should also go into in
pgervais 2015/02/19 00:45:57 This file is also not used by the CQ, removing.
28
29
30 class Failure(Exception):
31 pass
32
33
34 def test_port(port):
35 s = socket.socket()
36 try:
37 return s.connect_ex(('127.0.0.1', port)) == 0
38 finally:
39 s.close()
40
41
42 def find_free_port(start_port):
43 """Search for a free port starting at specified port."""
44 for port in xrange(start_port, (2<<16)):
45 if not test_port(port):
46 return port
47 raise Failure('Having issues finding an available port')
48
49
50 class LocalRietveld(object):
51 """Downloads everything needed to run a local instance of Rietveld."""
52
53 def __init__(self, base_dir=None):
54 # Paths
55 self.base_dir = base_dir
56 if not self.base_dir:
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
59 # everytime. This test is already annoyingly slow.
60 self.rietveld = os.path.join(self.base_dir, '_rietveld')
61 self.test_server = None
62 self.port = None
63 self.tempdir = None
64
65 # Find the GAE SDK
66 previous_dir = ''
67 self.sdk_path = ''
68 base_dir = self.base_dir
69 while base_dir != previous_dir:
70 previous_dir = base_dir
71 self.sdk_path = os.path.join(base_dir, 'google_appengine')
72 if not os.path.isfile(os.path.join(self.sdk_path, 'VERSION')):
73 base_dir = os.path.dirname(base_dir)
74 self.dev_app = os.path.join(self.sdk_path, 'dev_appserver.py')
75
76 def install_prerequisites(self):
77 # First, verify the Google AppEngine SDK is available.
78 if not os.path.isfile(self.dev_app):
79 raise Failure(
80 'Install google_appengine sdk in %s or higher up' % self.base_dir)
81
82 if os.path.isdir(os.path.join(self.rietveld, '.svn')):
83 # Left over from subversion. Delete it.
84 shutil.rmtree(self.rietveld)
85
86 # Second, checkout rietveld if not available.
87 rev = '9349cab9a3bb'
88 if not os.path.isdir(self.rietveld):
89 print('Checking out rietveld...')
90 try:
91 subprocess2.check_call(
92 [ 'hg', 'clone', '-q', '-u', rev, '-r', rev,
93 'https://code.google.com/p/rietveld/', self.rietveld])
94 except (OSError, subprocess2.CalledProcessError), e:
95 raise Failure(
96 'Failed to checkout rietveld. Do you have mercurial installed?\n'
97 '%s' % e)
98 else:
99 print('Syncing rietveld...')
100 try:
101 subprocess2.check_call(
102 ['hg', 'co', '-q', '-C', rev], cwd=self.rietveld)
103 except (OSError, subprocess2.CalledProcessError), e:
104 raise Failure('Failed to sync rietveld\n%s' % e)
105
106 def start_server(self, verbose=False):
107 self.install_prerequisites()
108 assert not self.tempdir
109 self.tempdir = tempfile.mkdtemp(prefix='rietveld_test')
110 self.port = find_free_port(10000)
111 admin_port = find_free_port(self.port + 1)
112 if verbose:
113 stdout = stderr = None
114 else:
115 stdout = subprocess2.PIPE
116 stderr = subprocess2.STDOUT
117 cmd = [
118 sys.executable,
119 self.dev_app,
120 '.',
121 '--port', str(self.port),
122 '--admin_port', str(admin_port),
123 '--storage', self.tempdir,
124 '--clear_search_indexes',
125 '--skip_sdk_update_check',
126 ]
127
128 # CHEAP TRICK
129 # 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
131 # remotely.
132 if os.environ.get('GAE_LISTEN_ALL', '') == 'true':
133 cmd.extend(('-a', '0.0.0.0'))
134 logging.info(' '.join(cmd))
135 self.test_server = subprocess2.Popen(
136 cmd, stdout=stdout, stderr=stderr, cwd=self.rietveld)
137 # Loop until port 127.0.0.1:port opens or the process dies.
138 while not test_port(self.port):
139 self.test_server.poll()
140 if self.test_server.returncode is not None:
141 if not verbose:
142 out = self.test_server.communicate()[0]
143 shutil.rmtree(self.tempdir)
144 self.tempdir = None
145 raise Failure(
146 'Test rietveld instance failed early on port %s\n%s' %
147 (self.port, out))
148 time.sleep(0.01)
149
150 def stop_server(self):
151 if self.test_server:
152 try:
153 self.test_server.kill()
154 except OSError:
155 pass
156 self.test_server.wait()
157 self.test_server = None
158 self.port = None
159 if self.tempdir:
160 shutil.rmtree(self.tempdir)
161 self.tempdir = None
162
163
164 def main():
165 parser = optparse.OptionParser()
166 parser.add_option('-v', '--verbose', action='store_true')
167 options, args = parser.parse_args()
168 if args:
169 parser.error('Unknown arguments: %s' % ' '.join(args))
170 instance = LocalRietveld()
171 try:
172 instance.start_server(verbose=options.verbose)
173 print 'Local rietveld instance started on port %d' % instance.port
174 while True:
175 time.sleep(0.1)
176 finally:
177 instance.stop_server()
178
179
180 if __name__ == '__main__':
181 main()
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698