##// END OF EJS Templates
tests: use pytest fail when vcs_operations cannot start required components
marcink -
r2461:e0c700db default
parent child Browse files
Show More
@@ -1,194 +1,194 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2010-2017 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU Affero General Public License
15 15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 21
22 22 import os
23 23 import time
24 24 import tempfile
25 25 import pytest
26 26 import subprocess32
27 27 import configobj
28 28
29 29 from urllib2 import urlopen, URLError
30 30 from pyramid.compat import configparser
31 31
32 32
33 33 from rhodecode.tests import TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS
34 34 from rhodecode.tests.utils import is_url_reachable
35 35
36 36
37 37 def get_port(pyramid_config):
38 38 config = configparser.ConfigParser()
39 39 config.read(pyramid_config)
40 40 return config.get('server:main', 'port')
41 41
42 42
43 43 def get_host_url(pyramid_config):
44 44 """Construct the host url using the port in the test configuration."""
45 45 return '127.0.0.1:%s' % get_port(pyramid_config)
46 46
47 47
48 48 def assert_no_running_instance(url):
49 49 if is_url_reachable(url):
50 50 print("Hint: Usually this means another instance of server "
51 51 "is running in the background at %s." % url)
52 52 pytest.fail(
53 53 "Port is not free at %s, cannot start server at" % url)
54 54
55 55
56 56 class ServerBase(object):
57 57 _args = []
58 58 log_file_name = 'NOT_DEFINED.log'
59 59 status_url_tmpl = 'http://{host}:{port}'
60 60
61 61 def __init__(self, config_file, log_file):
62 62 self.config_file = config_file
63 63 config_data = configobj.ConfigObj(config_file)
64 64 self._config = config_data['server:main']
65 65
66 66 self._args = []
67 67 self.log_file = log_file or os.path.join(
68 68 tempfile.gettempdir(), self.log_file_name)
69 69 self.process = None
70 70 self.server_out = None
71 71 print("Using the {} configuration:{}".format(
72 72 self.__class__.__name__, config_file))
73 73
74 74 if not os.path.isfile(config_file):
75 75 raise RuntimeError('Failed to get config at {}'.format(config_file))
76 76
77 77 @property
78 78 def command(self):
79 79 return ' '.join(self._args)
80 80
81 81 @property
82 82 def http_url(self):
83 83 template = 'http://{host}:{port}/'
84 84 return template.format(**self._config)
85 85
86 86 def host_url(self):
87 87 return 'http://' + get_host_url(self.config_file)
88 88
89 89 def get_rc_log(self):
90 90 with open(self.log_file) as f:
91 91 return f.read()
92 92
93 93 def wait_until_ready(self, timeout=15):
94 94 host = self._config['host']
95 95 port = self._config['port']
96 96 status_url = self.status_url_tmpl.format(host=host, port=port)
97 97 start = time.time()
98 98
99 99 while time.time() - start < timeout:
100 100 try:
101 101 urlopen(status_url)
102 102 break
103 103 except URLError:
104 104 time.sleep(0.2)
105 105 else:
106 pytest.exit(
106 pytest.fail(
107 107 "Starting the {} failed or took more than {} "
108 108 "seconds. cmd: `{}`".format(
109 109 self.__class__.__name__, timeout, self.command))
110 110
111 111 def shutdown(self):
112 112 self.process.kill()
113 113 self.server_out.flush()
114 114 self.server_out.close()
115 115
116 116 def get_log_file_with_port(self):
117 117 log_file = list(self.log_file.partition('.log'))
118 118 log_file.insert(1, get_port(self.config_file))
119 119 log_file = ''.join(log_file)
120 120 return log_file
121 121
122 122
123 123 class RcVCSServer(ServerBase):
124 124 """
125 125 Represents a running VCSServer instance.
126 126 """
127 127
128 128 log_file_name = 'rc-vcsserver.log'
129 129 status_url_tmpl = 'http://{host}:{port}/status'
130 130
131 131 def __init__(self, config_file, log_file=None):
132 132 super(RcVCSServer, self).__init__(config_file, log_file)
133 133 self._args = [
134 134 'gunicorn', '--paste', self.config_file]
135 135
136 136 def start(self):
137 137 env = os.environ.copy()
138 138
139 139 self.log_file = self.get_log_file_with_port()
140 140 self.server_out = open(self.log_file, 'w')
141 141
142 142 host_url = self.host_url()
143 143 assert_no_running_instance(host_url)
144 144
145 145 print('rhodecode-vcsserver starting at: {}'.format(host_url))
146 146 print('rhodecode-vcsserver command: {}'.format(self.command))
147 147 print('rhodecode-vcsserver logfile: {}'.format(self.log_file))
148 148
149 149 self.process = subprocess32.Popen(
150 150 self._args, bufsize=0, env=env,
151 151 stdout=self.server_out, stderr=self.server_out)
152 152
153 153
154 154 class RcWebServer(ServerBase):
155 155 """
156 156 Represents a running RCE web server used as a test fixture.
157 157 """
158 158
159 159 log_file_name = 'rc-web.log'
160 160 status_url_tmpl = 'http://{host}:{port}/_admin/ops/ping'
161 161
162 162 def __init__(self, config_file, log_file=None):
163 163 super(RcWebServer, self).__init__(config_file, log_file)
164 164 self._args = [
165 165 'gunicorn', '--worker-class', 'gevent', '--paste', config_file]
166 166
167 167 def start(self):
168 168 env = os.environ.copy()
169 169 env['RC_NO_TMP_PATH'] = '1'
170 170
171 171 self.log_file = self.get_log_file_with_port()
172 172 self.server_out = open(self.log_file, 'w')
173 173
174 174 host_url = self.host_url()
175 175 assert_no_running_instance(host_url)
176 176
177 177 print('rhodecode-web starting at: {}'.format(host_url))
178 178 print('rhodecode-web command: {}'.format(self.command))
179 179 print('rhodecode-web logfile: {}'.format(self.log_file))
180 180
181 181 self.process = subprocess32.Popen(
182 182 self._args, bufsize=0, env=env,
183 183 stdout=self.server_out, stderr=self.server_out)
184 184
185 185 def repo_clone_url(self, repo_name, **kwargs):
186 186 params = {
187 187 'user': TEST_USER_ADMIN_LOGIN,
188 188 'passwd': TEST_USER_ADMIN_PASS,
189 189 'host': get_host_url(self.config_file),
190 190 'cloned_repo': repo_name,
191 191 }
192 192 params.update(**kwargs)
193 193 _url = 'http://%(user)s:%(passwd)s@%(host)s/%(cloned_repo)s' % params
194 194 return _url
General Comments 0
You need to be logged in to leave comments. Login now