##// END OF EJS Templates
testapp: moved login/csrf session methods into TestApp itself....
marcink -
r2374:e331d3e6 default
parent child Browse files
Show More
@@ -1,411 +1,429 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2017 RhodeCode GmbH
3 # Copyright (C) 2010-2017 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import threading
21 import threading
22 import time
22 import time
23 import logging
23 import logging
24 import os.path
24 import os.path
25 import subprocess32
25 import subprocess32
26 import tempfile
26 import tempfile
27 import urllib2
27 import urllib2
28 from lxml.html import fromstring, tostring
28 from lxml.html import fromstring, tostring
29 from lxml.cssselect import CSSSelector
29 from lxml.cssselect import CSSSelector
30 from urlparse import urlparse, parse_qsl
30 from urlparse import urlparse, parse_qsl
31 from urllib import unquote_plus
31 from urllib import unquote_plus
32 import webob
32 import webob
33
33
34 from webtest.app import TestResponse, TestApp, string_types
34 from webtest.app import TestResponse, TestApp, string_types
35 from webtest.compat import print_stderr
35 from webtest.compat import print_stderr
36
36
37 import pytest
37 import pytest
38 import rc_testdata
38 import rc_testdata
39
39
40 from rhodecode.model.db import User, Repository
40 from rhodecode.model.db import User, Repository
41 from rhodecode.model.meta import Session
41 from rhodecode.model.meta import Session
42 from rhodecode.model.scm import ScmModel
42 from rhodecode.model.scm import ScmModel
43 from rhodecode.lib.vcs.backends.svn.repository import SubversionRepository
43 from rhodecode.lib.vcs.backends.svn.repository import SubversionRepository
44 from rhodecode.lib.vcs.backends.base import EmptyCommit
44 from rhodecode.lib.vcs.backends.base import EmptyCommit
45
45 from rhodecode.tests import login_user_session
46
46
47 log = logging.getLogger(__name__)
47 log = logging.getLogger(__name__)
48
48
49
49
50 class CustomTestResponse(TestResponse):
50 class CustomTestResponse(TestResponse):
51 def _save_output(self, out):
51 def _save_output(self, out):
52 f = tempfile.NamedTemporaryFile(
52 f = tempfile.NamedTemporaryFile(
53 delete=False, prefix='rc-test-', suffix='.html')
53 delete=False, prefix='rc-test-', suffix='.html')
54 f.write(out)
54 f.write(out)
55 return f.name
55 return f.name
56
56
57 def mustcontain(self, *strings, **kw):
57 def mustcontain(self, *strings, **kw):
58 """
58 """
59 Assert that the response contains all of the strings passed
59 Assert that the response contains all of the strings passed
60 in as arguments.
60 in as arguments.
61
61
62 Equivalent to::
62 Equivalent to::
63
63
64 assert string in res
64 assert string in res
65 """
65 """
66 if 'no' in kw:
66 if 'no' in kw:
67 no = kw['no']
67 no = kw['no']
68 del kw['no']
68 del kw['no']
69 if isinstance(no, string_types):
69 if isinstance(no, string_types):
70 no = [no]
70 no = [no]
71 else:
71 else:
72 no = []
72 no = []
73 if kw:
73 if kw:
74 raise TypeError(
74 raise TypeError(
75 "The only keyword argument allowed is 'no'")
75 "The only keyword argument allowed is 'no' got %s" % kw)
76
76
77 f = self._save_output(str(self))
77 f = self._save_output(str(self))
78
78
79 for s in strings:
79 for s in strings:
80 if not s in self:
80 if not s in self:
81 print_stderr("Actual response (no %r):" % s)
81 print_stderr("Actual response (no %r):" % s)
82 print_stderr(str(self))
82 print_stderr(str(self))
83 raise IndexError(
83 raise IndexError(
84 "Body does not contain string %r, output saved as %s" % (
84 "Body does not contain string %r, output saved as %s" % (
85 s, f))
85 s, f))
86
86
87 for no_s in no:
87 for no_s in no:
88 if no_s in self:
88 if no_s in self:
89 print_stderr("Actual response (has %r)" % no_s)
89 print_stderr("Actual response (has %r)" % no_s)
90 print_stderr(str(self))
90 print_stderr(str(self))
91 raise IndexError(
91 raise IndexError(
92 "Body contains bad string %r, output saved as %s" % (
92 "Body contains bad string %r, output saved as %s" % (
93 no_s, f))
93 no_s, f))
94
94
95 def assert_response(self):
95 def assert_response(self):
96 return AssertResponse(self)
96 return AssertResponse(self)
97
97
98 def get_session_from_response(self):
98 def get_session_from_response(self):
99 """
99 """
100 This returns the session from a response object.
100 This returns the session from a response object.
101 """
101 """
102
102
103 from pyramid_beaker import session_factory_from_settings
103 from pyramid_beaker import session_factory_from_settings
104 session = session_factory_from_settings(
104 session = session_factory_from_settings(
105 self.test_app.app.config.get_settings())
105 self.test_app.app.config.get_settings())
106 return session(self.request)
106 return session(self.request)
107
107
108
108
109 class TestRequest(webob.BaseRequest):
109 class TestRequest(webob.BaseRequest):
110
110
111 # for py.test
111 # for py.test
112 disabled = True
112 disabled = True
113 ResponseClass = CustomTestResponse
113 ResponseClass = CustomTestResponse
114
114
115 def add_response_callback(self, callback):
115 def add_response_callback(self, callback):
116 pass
116 pass
117
117
118
118
119 class CustomTestApp(TestApp):
119 class CustomTestApp(TestApp):
120 """
120 """
121 Custom app to make mustcontain more usefull
121 Custom app to make mustcontain more usefull, and extract special methods
122 """
122 """
123 RequestClass = TestRequest
123 RequestClass = TestRequest
124 rc_login_data = {}
125 rc_current_session = None
126
127 def login(self, username=None, password=None):
128 from rhodecode.lib import auth
129
130 if username and password:
131 session = login_user_session(self, username, password)
132 else:
133 session = login_user_session(self)
134
135 self.rc_login_data['csrf_token'] = auth.get_csrf_token(session)
136 self.rc_current_session = session
137 return session['rhodecode_user']
138
139 @property
140 def csrf_token(self):
141 return self.rc_login_data['csrf_token']
124
142
125
143
126 def set_anonymous_access(enabled):
144 def set_anonymous_access(enabled):
127 """(Dis)allows anonymous access depending on parameter `enabled`"""
145 """(Dis)allows anonymous access depending on parameter `enabled`"""
128 user = User.get_default_user()
146 user = User.get_default_user()
129 user.active = enabled
147 user.active = enabled
130 Session().add(user)
148 Session().add(user)
131 Session().commit()
149 Session().commit()
132 time.sleep(1.5) # must sleep for cache (1s to expire)
150 time.sleep(1.5) # must sleep for cache (1s to expire)
133 log.info('anonymous access is now: %s', enabled)
151 log.info('anonymous access is now: %s', enabled)
134 assert enabled == User.get_default_user().active, (
152 assert enabled == User.get_default_user().active, (
135 'Cannot set anonymous access')
153 'Cannot set anonymous access')
136
154
137
155
138 def check_xfail_backends(node, backend_alias):
156 def check_xfail_backends(node, backend_alias):
139 # Using "xfail_backends" here intentionally, since this marks work
157 # Using "xfail_backends" here intentionally, since this marks work
140 # which is "to be done" soon.
158 # which is "to be done" soon.
141 skip_marker = node.get_marker('xfail_backends')
159 skip_marker = node.get_marker('xfail_backends')
142 if skip_marker and backend_alias in skip_marker.args:
160 if skip_marker and backend_alias in skip_marker.args:
143 msg = "Support for backend %s to be developed." % (backend_alias, )
161 msg = "Support for backend %s to be developed." % (backend_alias, )
144 msg = skip_marker.kwargs.get('reason', msg)
162 msg = skip_marker.kwargs.get('reason', msg)
145 pytest.xfail(msg)
163 pytest.xfail(msg)
146
164
147
165
148 def check_skip_backends(node, backend_alias):
166 def check_skip_backends(node, backend_alias):
149 # Using "skip_backends" here intentionally, since this marks work which is
167 # Using "skip_backends" here intentionally, since this marks work which is
150 # not supported.
168 # not supported.
151 skip_marker = node.get_marker('skip_backends')
169 skip_marker = node.get_marker('skip_backends')
152 if skip_marker and backend_alias in skip_marker.args:
170 if skip_marker and backend_alias in skip_marker.args:
153 msg = "Feature not supported for backend %s." % (backend_alias, )
171 msg = "Feature not supported for backend %s." % (backend_alias, )
154 msg = skip_marker.kwargs.get('reason', msg)
172 msg = skip_marker.kwargs.get('reason', msg)
155 pytest.skip(msg)
173 pytest.skip(msg)
156
174
157
175
158 def extract_git_repo_from_dump(dump_name, repo_name):
176 def extract_git_repo_from_dump(dump_name, repo_name):
159 """Create git repo `repo_name` from dump `dump_name`."""
177 """Create git repo `repo_name` from dump `dump_name`."""
160 repos_path = ScmModel().repos_path
178 repos_path = ScmModel().repos_path
161 target_path = os.path.join(repos_path, repo_name)
179 target_path = os.path.join(repos_path, repo_name)
162 rc_testdata.extract_git_dump(dump_name, target_path)
180 rc_testdata.extract_git_dump(dump_name, target_path)
163 return target_path
181 return target_path
164
182
165
183
166 def extract_hg_repo_from_dump(dump_name, repo_name):
184 def extract_hg_repo_from_dump(dump_name, repo_name):
167 """Create hg repo `repo_name` from dump `dump_name`."""
185 """Create hg repo `repo_name` from dump `dump_name`."""
168 repos_path = ScmModel().repos_path
186 repos_path = ScmModel().repos_path
169 target_path = os.path.join(repos_path, repo_name)
187 target_path = os.path.join(repos_path, repo_name)
170 rc_testdata.extract_hg_dump(dump_name, target_path)
188 rc_testdata.extract_hg_dump(dump_name, target_path)
171 return target_path
189 return target_path
172
190
173
191
174 def extract_svn_repo_from_dump(dump_name, repo_name):
192 def extract_svn_repo_from_dump(dump_name, repo_name):
175 """Create a svn repo `repo_name` from dump `dump_name`."""
193 """Create a svn repo `repo_name` from dump `dump_name`."""
176 repos_path = ScmModel().repos_path
194 repos_path = ScmModel().repos_path
177 target_path = os.path.join(repos_path, repo_name)
195 target_path = os.path.join(repos_path, repo_name)
178 SubversionRepository(target_path, create=True)
196 SubversionRepository(target_path, create=True)
179 _load_svn_dump_into_repo(dump_name, target_path)
197 _load_svn_dump_into_repo(dump_name, target_path)
180 return target_path
198 return target_path
181
199
182
200
183 def assert_message_in_log(log_records, message, levelno, module):
201 def assert_message_in_log(log_records, message, levelno, module):
184 messages = [
202 messages = [
185 r.message for r in log_records
203 r.message for r in log_records
186 if r.module == module and r.levelno == levelno
204 if r.module == module and r.levelno == levelno
187 ]
205 ]
188 assert message in messages
206 assert message in messages
189
207
190
208
191 def _load_svn_dump_into_repo(dump_name, repo_path):
209 def _load_svn_dump_into_repo(dump_name, repo_path):
192 """
210 """
193 Utility to populate a svn repository with a named dump
211 Utility to populate a svn repository with a named dump
194
212
195 Currently the dumps are in rc_testdata. They might later on be
213 Currently the dumps are in rc_testdata. They might later on be
196 integrated with the main repository once they stabilize more.
214 integrated with the main repository once they stabilize more.
197 """
215 """
198 dump = rc_testdata.load_svn_dump(dump_name)
216 dump = rc_testdata.load_svn_dump(dump_name)
199 load_dump = subprocess32.Popen(
217 load_dump = subprocess32.Popen(
200 ['svnadmin', 'load', repo_path],
218 ['svnadmin', 'load', repo_path],
201 stdin=subprocess32.PIPE, stdout=subprocess32.PIPE,
219 stdin=subprocess32.PIPE, stdout=subprocess32.PIPE,
202 stderr=subprocess32.PIPE)
220 stderr=subprocess32.PIPE)
203 out, err = load_dump.communicate(dump)
221 out, err = load_dump.communicate(dump)
204 if load_dump.returncode != 0:
222 if load_dump.returncode != 0:
205 log.error("Output of load_dump command: %s", out)
223 log.error("Output of load_dump command: %s", out)
206 log.error("Error output of load_dump command: %s", err)
224 log.error("Error output of load_dump command: %s", err)
207 raise Exception(
225 raise Exception(
208 'Failed to load dump "%s" into repository at path "%s".'
226 'Failed to load dump "%s" into repository at path "%s".'
209 % (dump_name, repo_path))
227 % (dump_name, repo_path))
210
228
211
229
212 class AssertResponse(object):
230 class AssertResponse(object):
213 """
231 """
214 Utility that helps to assert things about a given HTML response.
232 Utility that helps to assert things about a given HTML response.
215 """
233 """
216
234
217 def __init__(self, response):
235 def __init__(self, response):
218 self.response = response
236 self.response = response
219
237
220 def get_imports(self):
238 def get_imports(self):
221 return fromstring, tostring, CSSSelector
239 return fromstring, tostring, CSSSelector
222
240
223 def one_element_exists(self, css_selector):
241 def one_element_exists(self, css_selector):
224 self.get_element(css_selector)
242 self.get_element(css_selector)
225
243
226 def no_element_exists(self, css_selector):
244 def no_element_exists(self, css_selector):
227 assert not self._get_elements(css_selector)
245 assert not self._get_elements(css_selector)
228
246
229 def element_equals_to(self, css_selector, expected_content):
247 def element_equals_to(self, css_selector, expected_content):
230 element = self.get_element(css_selector)
248 element = self.get_element(css_selector)
231 element_text = self._element_to_string(element)
249 element_text = self._element_to_string(element)
232 assert expected_content in element_text
250 assert expected_content in element_text
233
251
234 def element_contains(self, css_selector, expected_content):
252 def element_contains(self, css_selector, expected_content):
235 element = self.get_element(css_selector)
253 element = self.get_element(css_selector)
236 assert expected_content in element.text_content()
254 assert expected_content in element.text_content()
237
255
238 def element_value_contains(self, css_selector, expected_content):
256 def element_value_contains(self, css_selector, expected_content):
239 element = self.get_element(css_selector)
257 element = self.get_element(css_selector)
240 assert expected_content in element.value
258 assert expected_content in element.value
241
259
242 def contains_one_link(self, link_text, href):
260 def contains_one_link(self, link_text, href):
243 fromstring, tostring, CSSSelector = self.get_imports()
261 fromstring, tostring, CSSSelector = self.get_imports()
244 doc = fromstring(self.response.body)
262 doc = fromstring(self.response.body)
245 sel = CSSSelector('a[href]')
263 sel = CSSSelector('a[href]')
246 elements = [
264 elements = [
247 e for e in sel(doc) if e.text_content().strip() == link_text]
265 e for e in sel(doc) if e.text_content().strip() == link_text]
248 assert len(elements) == 1, "Did not find link or found multiple links"
266 assert len(elements) == 1, "Did not find link or found multiple links"
249 self._ensure_url_equal(elements[0].attrib.get('href'), href)
267 self._ensure_url_equal(elements[0].attrib.get('href'), href)
250
268
251 def contains_one_anchor(self, anchor_id):
269 def contains_one_anchor(self, anchor_id):
252 fromstring, tostring, CSSSelector = self.get_imports()
270 fromstring, tostring, CSSSelector = self.get_imports()
253 doc = fromstring(self.response.body)
271 doc = fromstring(self.response.body)
254 sel = CSSSelector('#' + anchor_id)
272 sel = CSSSelector('#' + anchor_id)
255 elements = sel(doc)
273 elements = sel(doc)
256 assert len(elements) == 1, 'cannot find 1 element {}'.format(anchor_id)
274 assert len(elements) == 1, 'cannot find 1 element {}'.format(anchor_id)
257
275
258 def _ensure_url_equal(self, found, expected):
276 def _ensure_url_equal(self, found, expected):
259 assert _Url(found) == _Url(expected)
277 assert _Url(found) == _Url(expected)
260
278
261 def get_element(self, css_selector):
279 def get_element(self, css_selector):
262 elements = self._get_elements(css_selector)
280 elements = self._get_elements(css_selector)
263 assert len(elements) == 1, 'cannot find 1 element {}'.format(css_selector)
281 assert len(elements) == 1, 'cannot find 1 element {}'.format(css_selector)
264 return elements[0]
282 return elements[0]
265
283
266 def get_elements(self, css_selector):
284 def get_elements(self, css_selector):
267 return self._get_elements(css_selector)
285 return self._get_elements(css_selector)
268
286
269 def _get_elements(self, css_selector):
287 def _get_elements(self, css_selector):
270 fromstring, tostring, CSSSelector = self.get_imports()
288 fromstring, tostring, CSSSelector = self.get_imports()
271 doc = fromstring(self.response.body)
289 doc = fromstring(self.response.body)
272 sel = CSSSelector(css_selector)
290 sel = CSSSelector(css_selector)
273 elements = sel(doc)
291 elements = sel(doc)
274 return elements
292 return elements
275
293
276 def _element_to_string(self, element):
294 def _element_to_string(self, element):
277 fromstring, tostring, CSSSelector = self.get_imports()
295 fromstring, tostring, CSSSelector = self.get_imports()
278 return tostring(element)
296 return tostring(element)
279
297
280
298
281 class _Url(object):
299 class _Url(object):
282 """
300 """
283 A url object that can be compared with other url orbjects
301 A url object that can be compared with other url orbjects
284 without regard to the vagaries of encoding, escaping, and ordering
302 without regard to the vagaries of encoding, escaping, and ordering
285 of parameters in query strings.
303 of parameters in query strings.
286
304
287 Inspired by
305 Inspired by
288 http://stackoverflow.com/questions/5371992/comparing-two-urls-in-python
306 http://stackoverflow.com/questions/5371992/comparing-two-urls-in-python
289 """
307 """
290
308
291 def __init__(self, url):
309 def __init__(self, url):
292 parts = urlparse(url)
310 parts = urlparse(url)
293 _query = frozenset(parse_qsl(parts.query))
311 _query = frozenset(parse_qsl(parts.query))
294 _path = unquote_plus(parts.path)
312 _path = unquote_plus(parts.path)
295 parts = parts._replace(query=_query, path=_path)
313 parts = parts._replace(query=_query, path=_path)
296 self.parts = parts
314 self.parts = parts
297
315
298 def __eq__(self, other):
316 def __eq__(self, other):
299 return self.parts == other.parts
317 return self.parts == other.parts
300
318
301 def __hash__(self):
319 def __hash__(self):
302 return hash(self.parts)
320 return hash(self.parts)
303
321
304
322
305 def run_test_concurrently(times, raise_catched_exc=True):
323 def run_test_concurrently(times, raise_catched_exc=True):
306 """
324 """
307 Add this decorator to small pieces of code that you want to test
325 Add this decorator to small pieces of code that you want to test
308 concurrently
326 concurrently
309
327
310 ex:
328 ex:
311
329
312 @test_concurrently(25)
330 @test_concurrently(25)
313 def my_test_function():
331 def my_test_function():
314 ...
332 ...
315 """
333 """
316 def test_concurrently_decorator(test_func):
334 def test_concurrently_decorator(test_func):
317 def wrapper(*args, **kwargs):
335 def wrapper(*args, **kwargs):
318 exceptions = []
336 exceptions = []
319
337
320 def call_test_func():
338 def call_test_func():
321 try:
339 try:
322 test_func(*args, **kwargs)
340 test_func(*args, **kwargs)
323 except Exception as e:
341 except Exception as e:
324 exceptions.append(e)
342 exceptions.append(e)
325 if raise_catched_exc:
343 if raise_catched_exc:
326 raise
344 raise
327 threads = []
345 threads = []
328 for i in range(times):
346 for i in range(times):
329 threads.append(threading.Thread(target=call_test_func))
347 threads.append(threading.Thread(target=call_test_func))
330 for t in threads:
348 for t in threads:
331 t.start()
349 t.start()
332 for t in threads:
350 for t in threads:
333 t.join()
351 t.join()
334 if exceptions:
352 if exceptions:
335 raise Exception(
353 raise Exception(
336 'test_concurrently intercepted %s exceptions: %s' % (
354 'test_concurrently intercepted %s exceptions: %s' % (
337 len(exceptions), exceptions))
355 len(exceptions), exceptions))
338 return wrapper
356 return wrapper
339 return test_concurrently_decorator
357 return test_concurrently_decorator
340
358
341
359
342 def wait_for_url(url, timeout=10):
360 def wait_for_url(url, timeout=10):
343 """
361 """
344 Wait until URL becomes reachable.
362 Wait until URL becomes reachable.
345
363
346 It polls the URL until the timeout is reached or it became reachable.
364 It polls the URL until the timeout is reached or it became reachable.
347 If will call to `py.test.fail` in case the URL is not reachable.
365 If will call to `py.test.fail` in case the URL is not reachable.
348 """
366 """
349 timeout = time.time() + timeout
367 timeout = time.time() + timeout
350 last = 0
368 last = 0
351 wait = 0.1
369 wait = 0.1
352
370
353 while timeout > last:
371 while timeout > last:
354 last = time.time()
372 last = time.time()
355 if is_url_reachable(url):
373 if is_url_reachable(url):
356 break
374 break
357 elif (last + wait) > time.time():
375 elif (last + wait) > time.time():
358 # Go to sleep because not enough time has passed since last check.
376 # Go to sleep because not enough time has passed since last check.
359 time.sleep(wait)
377 time.sleep(wait)
360 else:
378 else:
361 pytest.fail("Timeout while waiting for URL {}".format(url))
379 pytest.fail("Timeout while waiting for URL {}".format(url))
362
380
363
381
364 def is_url_reachable(url):
382 def is_url_reachable(url):
365 try:
383 try:
366 urllib2.urlopen(url)
384 urllib2.urlopen(url)
367 except urllib2.URLError:
385 except urllib2.URLError:
368 return False
386 return False
369 return True
387 return True
370
388
371
389
372 def repo_on_filesystem(repo_name):
390 def repo_on_filesystem(repo_name):
373 from rhodecode.lib import vcs
391 from rhodecode.lib import vcs
374 from rhodecode.tests import TESTS_TMP_PATH
392 from rhodecode.tests import TESTS_TMP_PATH
375 repo = vcs.get_vcs_instance(
393 repo = vcs.get_vcs_instance(
376 os.path.join(TESTS_TMP_PATH, repo_name), create=False)
394 os.path.join(TESTS_TMP_PATH, repo_name), create=False)
377 return repo is not None
395 return repo is not None
378
396
379
397
380 def commit_change(
398 def commit_change(
381 repo, filename, content, message, vcs_type, parent=None, newfile=False):
399 repo, filename, content, message, vcs_type, parent=None, newfile=False):
382 from rhodecode.tests import TEST_USER_ADMIN_LOGIN
400 from rhodecode.tests import TEST_USER_ADMIN_LOGIN
383
401
384 repo = Repository.get_by_repo_name(repo)
402 repo = Repository.get_by_repo_name(repo)
385 _commit = parent
403 _commit = parent
386 if not parent:
404 if not parent:
387 _commit = EmptyCommit(alias=vcs_type)
405 _commit = EmptyCommit(alias=vcs_type)
388
406
389 if newfile:
407 if newfile:
390 nodes = {
408 nodes = {
391 filename: {
409 filename: {
392 'content': content
410 'content': content
393 }
411 }
394 }
412 }
395 commit = ScmModel().create_nodes(
413 commit = ScmModel().create_nodes(
396 user=TEST_USER_ADMIN_LOGIN, repo=repo,
414 user=TEST_USER_ADMIN_LOGIN, repo=repo,
397 message=message,
415 message=message,
398 nodes=nodes,
416 nodes=nodes,
399 parent_commit=_commit,
417 parent_commit=_commit,
400 author=TEST_USER_ADMIN_LOGIN,
418 author=TEST_USER_ADMIN_LOGIN,
401 )
419 )
402 else:
420 else:
403 commit = ScmModel().commit_change(
421 commit = ScmModel().commit_change(
404 repo=repo.scm_instance(), repo_name=repo.repo_name,
422 repo=repo.scm_instance(), repo_name=repo.repo_name,
405 commit=parent, user=TEST_USER_ADMIN_LOGIN,
423 commit=parent, user=TEST_USER_ADMIN_LOGIN,
406 author=TEST_USER_ADMIN_LOGIN,
424 author=TEST_USER_ADMIN_LOGIN,
407 message=message,
425 message=message,
408 content=content,
426 content=content,
409 f_path=filename
427 f_path=filename
410 )
428 )
411 return commit
429 return commit
General Comments 0
You need to be logged in to leave comments. Login now