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 |