##// END OF EJS Templates
tests: use gunicorn for testing. This is close to production testing...
marcink -
r2453:9cd85ffa default
parent child Browse files
Show More
@@ -171,7 +171,7 b' def rc_web_server('
171 171
172 172 host_url = 'http://' + get_host_url(rc_web_server_config)
173 173 assert_no_running_instance(host_url)
174 command = ['pserve', rc_web_server_config]
174 command = ['gunicorn', '--worker-class', 'gevent', '--paste', rc_web_server_config]
175 175
176 176 print('Starting rhodecode server: {}'.format(host_url))
177 177 print('Command: {}'.format(command))
@@ -22,6 +22,8 b' import os'
22 22 import json
23 23 import platform
24 24 import socket
25 import tempfile
26
25 27 import subprocess32
26 28 import time
27 29 from urllib2 import urlopen, URLError
@@ -34,6 +36,9 b' import pyramid.paster'
34 36 from rhodecode.lib.pyramid_utils import get_app_config
35 37 from rhodecode.tests.fixture import TestINI
36 38 import rhodecode
39 from rhodecode.tests.other.vcs_operations.conftest import get_host_url, get_port
40
41 VCSSERVER_LOG = os.path.join(tempfile.gettempdir(), 'rc-vcsserver.log')
37 42
38 43
39 44 def _parse_json(value):
@@ -204,10 +209,11 b' class HttpVCSServer(VCSServer):'
204 209 Represents a running VCSServer instance.
205 210 """
206 211 def __init__(self, config_file):
212 self.config_file = config_file
207 213 config_data = configobj.ConfigObj(config_file)
208 214 self._config = config_data['server:main']
209 215
210 args = ['pserve', config_file]
216 args = ['gunicorn', '--workers', '1', '--paste', config_file]
211 217 self._args = args
212 218
213 219 @property
@@ -216,7 +222,21 b' class HttpVCSServer(VCSServer):'
216 222 return template.format(**self._config)
217 223
218 224 def start(self):
219 self.process = subprocess32.Popen(self._args)
225 env = os.environ.copy()
226 host_url = 'http://' + get_host_url(self.config_file)
227
228 rc_log = list(VCSSERVER_LOG.partition('.log'))
229 rc_log.insert(1, get_port(self.config_file))
230 rc_log = ''.join(rc_log)
231
232 server_out = open(rc_log, 'w')
233
234 command = ' '.join(self._args)
235 print('Starting rhodecode-vcsserver: {}'.format(host_url))
236 print('Command: {}'.format(command))
237 print('Logfile: {}'.format(rc_log))
238 self.process = subprocess32.Popen(
239 self._args, bufsize=0, env=env, stdout=server_out, stderr=server_out)
220 240
221 241 def wait_until_ready(self, timeout=30):
222 242 host = self._config['host']
@@ -46,27 +46,12 b' debug = true'
46 46 host = 0.0.0.0
47 47 port = 5000
48 48
49 ##################################
50 ## WAITRESS WSGI SERVER ##
51 ## Recommended for Development ##
52 ##################################
53
54 use = egg:waitress#main
55 ## number of worker threads
56 threads = 5
57 ## MAX BODY SIZE 100GB
58 max_request_body_size = 107374182400
59 ## Use poll instead of select, fixes file descriptors limits problems.
60 ## May not work on old windows systems.
61 asyncore_use_poll = true
62
63
64 49 ##########################
65 50 ## GUNICORN WSGI SERVER ##
66 51 ##########################
67 52 ## run with gunicorn --log-config rhodecode.ini --paste rhodecode.ini
68 53
69 #use = egg:gunicorn#main
54 use = egg:gunicorn#main
70 55 ## Sets the number of process workers. You must set `instance_id = *`
71 56 ## when this option is set to more than one worker, recommended
72 57 ## value is (2 * NUMBER_OF_CPUS + 1), eg 2CPU = 5 workers
@@ -90,66 +75,6 b' asyncore_use_poll = true'
90 75 ## gets killed and restarted. Set to 6hrs
91 76 #timeout = 21600
92 77
93 ## UWSGI ##
94 ## run with uwsgi --ini-paste-logged <inifile.ini>
95 #[uwsgi]
96 #socket = /tmp/uwsgi.sock
97 #master = true
98 #http = 127.0.0.1:5000
99
100 ## set as deamon and redirect all output to file
101 #daemonize = ./uwsgi_rhodecode.log
102
103 ## master process PID
104 #pidfile = ./uwsgi_rhodecode.pid
105
106 ## stats server with workers statistics, use uwsgitop
107 ## for monitoring, `uwsgitop 127.0.0.1:1717`
108 #stats = 127.0.0.1:1717
109 #memory-report = true
110
111 ## log 5XX errors
112 #log-5xx = true
113
114 ## Set the socket listen queue size.
115 #listen = 256
116
117 ## Gracefully Reload workers after the specified amount of managed requests
118 ## (avoid memory leaks).
119 #max-requests = 1000
120
121 ## enable large buffers
122 #buffer-size=65535
123
124 ## socket and http timeouts ##
125 #http-timeout=3600
126 #socket-timeout=3600
127
128 ## Log requests slower than the specified number of milliseconds.
129 #log-slow = 10
130
131 ## Exit if no app can be loaded.
132 #need-app = true
133
134 ## Set lazy mode (load apps in workers instead of master).
135 #lazy = true
136
137 ## scaling ##
138 ## set cheaper algorithm to use, if not set default will be used
139 #cheaper-algo = spare
140
141 ## minimum number of workers to keep at all times
142 #cheaper = 1
143
144 ## number of workers to spawn at startup
145 #cheaper-initial = 1
146
147 ## maximum number of workers that can be spawned
148 #workers = 4
149
150 ## how many workers should be spawned at a time
151 #cheaper-step = 1
152
153 78 ## prefix middleware for RhodeCode.
154 79 ## recommended when using proxy setup.
155 80 ## allows to set RhodeCode under a prefix in server.
@@ -18,8 +18,8 b''
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 import time
21 22 import shutil
22 import time
23 23 import datetime
24 24
25 25 import pytest
@@ -29,7 +29,6 b' from rhodecode.lib.vcs.backends.base imp'
29 29 from rhodecode.lib.vcs.nodes import FileNode
30 30 from rhodecode.tests import get_new_dir
31 31 from rhodecode.tests.utils import check_skip_backends, check_xfail_backends
32 from rhodecode.tests.vcs.base import BackendTestMixin
33 32
34 33
35 34 @pytest.fixture()
@@ -61,7 +60,7 b' def vcs_repository_support('
61 60 cls.Backend = cls.backend_class = repo.__class__
62 61 cls.imc = repo.in_memory_commit
63 62
64 return (backend_alias, repo)
63 return backend_alias, repo
65 64
66 65
67 66 @pytest.fixture(scope='class')
@@ -88,6 +87,7 b' class VcsRepoContainer(object):'
88 87 def get_repo(self, test_class, backend_alias):
89 88 if backend_alias not in self._repos:
90 89 repo = _create_empty_repository(test_class, backend_alias)
90
91 91 self._cleanup_paths.append(repo.path)
92 92 self._repos[backend_alias] = repo
93 93 return self._repos[backend_alias]
@@ -106,7 +106,8 b' def _create_empty_repository(cls, backen'
106 106 repo_path = get_new_dir(str(time.time()))
107 107 repo = Backend(repo_path, create=True)
108 108 if hasattr(cls, '_get_commits'):
109 cls.tip = _add_commits_to_repo(repo, cls._get_commits())
109 commits = cls._get_commits()
110 cls.tip = _add_commits_to_repo(repo, commits)
110 111
111 112 return repo
112 113
@@ -132,7 +133,7 b' def config():'
132 133
133 134 def _add_commits_to_repo(repo, commits):
134 135 imc = repo.in_memory_commit
135 commit = None
136 tip = None
136 137
137 138 for commit in commits:
138 139 for node in commit.get('added', []):
@@ -142,13 +143,13 b' def _add_commits_to_repo(repo, commits):'
142 143 for node in commit.get('removed', []):
143 144 imc.remove(FileNode(node.path))
144 145
145 commit = imc.commit(
146 tip = imc.commit(
146 147 message=unicode(commit['message']),
147 148 author=unicode(commit['author']),
148 149 date=commit['date'],
149 150 branch=commit.get('branch'))
150 151
151 return commit
152 return tip
152 153
153 154
154 155 @pytest.fixture
@@ -198,7 +199,7 b' def generate_repo_with_commits(vcs_repo)'
198 199 def hg_repo(request, vcs_repo):
199 200 repo = vcs_repo
200 201
201 commits = BackendTestMixin._get_commits()
202 commits = repo._get_commits()
202 203 _add_commits_to_repo(repo, commits)
203 204
204 205 return repo
@@ -207,3 +208,50 b' def hg_repo(request, vcs_repo):'
207 208 @pytest.fixture
208 209 def hg_commit(hg_repo):
209 210 return hg_repo.get_commit()
211
212
213 class BackendTestMixin(object):
214 """
215 This is a backend independent test case class which should be created
216 with ``type`` method.
217
218 It is required to set following attributes at subclass:
219
220 - ``backend_alias``: alias of used backend (see ``vcs.BACKENDS``)
221 - ``repo_path``: path to the repository which would be created for set of
222 tests
223 - ``recreate_repo_per_test``: If set to ``False``, repo would NOT be
224 created
225 before every single test. Defaults to ``True``.
226 """
227 recreate_repo_per_test = True
228
229 @classmethod
230 def _get_commits(cls):
231 commits = [
232 {
233 'message': u'Initial commit',
234 'author': u'Joe Doe <joe.doe@example.com>',
235 'date': datetime.datetime(2010, 1, 1, 20),
236 'added': [
237 FileNode('foobar', content='Foobar'),
238 FileNode('foobar2', content='Foobar II'),
239 FileNode('foo/bar/baz', content='baz here!'),
240 ],
241 },
242 {
243 'message': u'Changes...',
244 'author': u'Jane Doe <jane.doe@example.com>',
245 'date': datetime.datetime(2010, 1, 1, 21),
246 'added': [
247 FileNode('some/new.txt', content='news...'),
248 ],
249 'changed': [
250 FileNode('foobar', 'Foobar I'),
251 ],
252 'removed': [],
253 },
254 ]
255 return commits
256
257
@@ -32,9 +32,10 b' import pytest'
32 32 from rhodecode.lib.vcs.backends import base
33 33 from rhodecode.lib.vcs.exceptions import ImproperArchiveTypeError, VCSError
34 34 from rhodecode.lib.vcs.nodes import FileNode
35 from rhodecode.tests.vcs.base import BackendTestMixin
35 from rhodecode.tests.vcs.conftest import BackendTestMixin
36 36
37 37
38 @pytest.mark.usefixtures("vcs_repository_support")
38 39 class TestArchives(BackendTestMixin):
39 40
40 41 @pytest.fixture(autouse=True)
@@ -48,7 +49,7 b' class TestArchives(BackendTestMixin):'
48 49 @classmethod
49 50 def _get_commits(cls):
50 51 start_date = datetime.datetime(2010, 1, 1, 20)
51 for x in xrange(5):
52 for x in range(5):
52 53 yield {
53 54 'message': 'Commit %d' % x,
54 55 'author': 'Joe Doe <joe.doe@example.com>',
@@ -68,7 +69,7 b' class TestArchives(BackendTestMixin):'
68 69 out_file.extractall(out_dir)
69 70 out_file.close()
70 71
71 for x in xrange(5):
72 for x in range(5):
72 73 node_path = '%d/file_%d.txt' % (x, x)
73 74 with open(os.path.join(out_dir, 'repo/' + node_path)) as f:
74 75 file_content = f.read()
@@ -80,7 +81,7 b' class TestArchives(BackendTestMixin):'
80 81 self.tip.archive_repo(self.temp_file, kind='zip', prefix='repo')
81 82 out = zipfile.ZipFile(self.temp_file)
82 83
83 for x in xrange(5):
84 for x in range(5):
84 85 node_path = '%d/file_%d.txt' % (x, x)
85 86 decompressed = StringIO.StringIO()
86 87 decompressed.write(out.read('repo/' + node_path))
@@ -98,7 +99,7 b' class TestArchives(BackendTestMixin):'
98 99 raw_id = self.tip.raw_id
99 100 assert 'rev:%s' % raw_id in metafile
100 101
101 for x in xrange(5):
102 for x in range(5):
102 103 node_path = '%d/file_%d.txt' % (x, x)
103 104 decompressed = StringIO.StringIO()
104 105 decompressed.write(out.read('repo/' + node_path))
@@ -23,9 +23,10 b' import datetime'
23 23 import pytest
24 24
25 25 from rhodecode.lib.vcs.nodes import FileNode
26 from rhodecode.tests.vcs.base import BackendTestMixin
26 from rhodecode.tests.vcs.conftest import BackendTestMixin
27 27
28 28
29 @pytest.mark.usefixtures("vcs_repository_support")
29 30 class TestBranches(BackendTestMixin):
30 31
31 32 def test_empty_repository_has_no_branches(self, vcsbackend):
@@ -32,7 +32,7 b' from rhodecode.lib.vcs.nodes import ('
32 32 FileNode, AddedFileNodesGenerator,
33 33 ChangedFileNodesGenerator, RemovedFileNodesGenerator)
34 34 from rhodecode.tests import get_new_dir
35 from rhodecode.tests.vcs.base import BackendTestMixin
35 from rhodecode.tests.vcs.conftest import BackendTestMixin
36 36
37 37
38 38 class TestBaseChangeset:
@@ -42,13 +42,14 b' class TestBaseChangeset:'
42 42 pytest.deprecated_call(BaseChangeset)
43 43
44 44
45 class TestEmptyCommit:
45 class TestEmptyCommit(object):
46 46
47 47 def test_branch_without_alias_returns_none(self):
48 48 commit = EmptyCommit()
49 49 assert commit.branch is None
50 50
51 51
52 @pytest.mark.usefixtures("vcs_repository_support")
52 53 class TestCommitsInNonEmptyRepo(BackendTestMixin):
53 54 recreate_repo_per_test = True
54 55
@@ -197,6 +198,7 b' class TestCommitsInNonEmptyRepo(BackendT'
197 198 assert [commit] == repo.get_commit(commit_idx=test_idx).children
198 199
199 200
201 @pytest.mark.usefixtures("vcs_repository_support")
200 202 class TestCommits(BackendTestMixin):
201 203 recreate_repo_per_test = False
202 204
@@ -501,6 +503,7 b' def test_commit_is_link(vcsbackend, file'
501 503 assert link_status is expected
502 504
503 505
506 @pytest.mark.usefixtures("vcs_repository_support")
504 507 class TestCommitsChanges(BackendTestMixin):
505 508 recreate_repo_per_test = False
506 509
@@ -22,7 +22,7 b' import datetime'
22 22 import pytest
23 23
24 24 from rhodecode.lib.vcs.nodes import FileNode
25 from rhodecode.tests.vcs.base import BackendTestMixin
25 from rhodecode.tests.vcs.conftest import BackendTestMixin
26 26
27 27
28 28 class TestGetDiffValidation:
@@ -68,6 +68,7 b' class TestGetDiffValidation:'
68 68 path='trunk/example.py', path1='branches/argparse/example.py')
69 69
70 70
71 @pytest.mark.usefixtures("vcs_repository_support")
71 72 class TestRepositoryGetDiff(BackendTestMixin):
72 73
73 74 recreate_repo_per_test = False
@@ -405,6 +406,7 b' new file mode 10644'
405 406 assert diff.raw == expected_diff
406 407
407 408
409 @pytest.mark.usefixtures("vcs_repository_support")
408 410 class TestGetDiffBinary(BackendTestMixin):
409 411
410 412 recreate_repo_per_test = False
@@ -19,10 +19,13 b''
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 21 import datetime
22
23 import pytest
22 24 from rhodecode.lib.vcs.nodes import FileNode
23 from rhodecode.tests.vcs.base import BackendTestMixin
25 from rhodecode.tests.vcs.conftest import BackendTestMixin
24 26
25 27
28 @pytest.mark.usefixtures("vcs_repository_support")
26 29 class TestFileNodeUnicodePath(BackendTestMixin):
27 30
28 31 fname = 'ąśðąęłąć.txt'
@@ -24,9 +24,10 b' import pytest'
24 24
25 25 from rhodecode.lib.vcs.exceptions import CommitDoesNotExistError
26 26 from rhodecode.lib.vcs.nodes import FileNode
27 from rhodecode.tests.vcs.base import BackendTestMixin
27 from rhodecode.tests.vcs.conftest import BackendTestMixin
28 28
29 29
30 @pytest.mark.usefixtures("vcs_repository_support")
30 31 class TestGetitem(BackendTestMixin):
31 32
32 33 @classmethod
@@ -19,10 +19,12 b''
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20 import datetime
21 21
22 import pytest
22 23 from rhodecode.lib.vcs.nodes import FileNode
23 from rhodecode.tests.vcs.base import BackendTestMixin
24 from rhodecode.tests.vcs.conftest import BackendTestMixin
24 25
25 26
27 @pytest.mark.usefixtures("vcs_repository_support")
26 28 class TestGetslice(BackendTestMixin):
27 29
28 30 @classmethod
@@ -35,7 +35,7 b' from rhodecode.lib.vcs.exceptions import'
35 35 from rhodecode.lib.vcs.nodes import (
36 36 NodeKind, FileNode, DirNode, NodeState, SubModuleNode)
37 37 from rhodecode.tests import TEST_GIT_REPO, TEST_GIT_REPO_CLONE, get_new_dir
38 from rhodecode.tests.vcs.base import BackendTestMixin
38 from rhodecode.tests.vcs.conftest import BackendTestMixin
39 39
40 40
41 41 pytestmark = pytest.mark.backends("git")
@@ -1030,6 +1030,7 b' class TestLargeFileRepo(object):'
1030 1030 assert lf_node.name == '1MB.zip'
1031 1031
1032 1032
1033 @pytest.mark.usefixtures("vcs_repository_support")
1033 1034 class TestGitSpecificWithRepo(BackendTestMixin):
1034 1035
1035 1036 @classmethod
@@ -1092,6 +1093,7 b' class TestGitSpecificWithRepo(BackendTes'
1092 1093 self.repo._get_commit_id(1), '--', 'foo'])
1093 1094
1094 1095
1096 @pytest.mark.usefixtures("vcs_repository_support")
1095 1097 class TestGitRegression(BackendTestMixin):
1096 1098
1097 1099 @classmethod
@@ -31,7 +31,7 b' from rhodecode.lib.vcs.exceptions import'
31 31 NodeAlreadyRemovedError, NodeAlreadyChangedError, NodeDoesNotExistError,
32 32 NodeNotChangedError)
33 33 from rhodecode.lib.vcs.nodes import DirNode, FileNode
34 from rhodecode.tests.vcs.base import BackendTestMixin
34 from rhodecode.tests.vcs.conftest import BackendTestMixin
35 35
36 36
37 37 @pytest.fixture
@@ -57,6 +57,7 b' def nodes():'
57 57 return nodes
58 58
59 59
60 @pytest.mark.usefixtures("vcs_repository_support")
60 61 class TestInMemoryCommit(BackendTestMixin):
61 62 """
62 63 This is a backend independent test case class which should be created
@@ -27,7 +27,7 b' from rhodecode.lib.vcs.nodes import File'
27 27 from rhodecode.lib.vcs.nodes import Node
28 28 from rhodecode.lib.vcs.nodes import NodeError
29 29 from rhodecode.lib.vcs.nodes import NodeKind
30 from rhodecode.tests.vcs.base import BackendTestMixin
30 from rhodecode.tests.vcs.conftest import BackendTestMixin
31 31
32 32
33 33 @pytest.fixture()
@@ -248,7 +248,7 b' class TestNodeBasics:'
248 248 assert (1, 1) == py_node.lines(count_empty=True)
249 249
250 250
251 class TestNodeContent:
251 class TestNodeContent(object):
252 252
253 253 def test_if_binary(self, binary_filenode):
254 254 filenode = binary_filenode('calendar.jpg')
@@ -263,6 +263,7 b' class TestNodeContent:'
263 263 assert tar_node.mimetype == 'application/x-tar'
264 264
265 265
266 @pytest.mark.usefixtures("vcs_repository_support")
266 267 class TestNodesCommits(BackendTestMixin):
267 268
268 269 def test_node_last_commit(self, generate_repo_with_commits):
@@ -29,9 +29,10 b' from rhodecode.lib.vcs.backends.base imp'
29 29 Config, BaseInMemoryCommit, Reference, MergeResponse, MergeFailureReason)
30 30 from rhodecode.lib.vcs.exceptions import VCSError, RepositoryError
31 31 from rhodecode.lib.vcs.nodes import FileNode
32 from rhodecode.tests.vcs.base import BackendTestMixin
32 from rhodecode.tests.vcs.conftest import BackendTestMixin
33 33
34 34
35 @pytest.mark.usefixtures("vcs_repository_support")
35 36 class TestRepositoryBase(BackendTestMixin):
36 37 recreate_repo_per_test = False
37 38
@@ -148,6 +149,7 b' class TestRepositoryBase(BackendTestMixi'
148 149 assert self.repo._get_url(url)
149 150
150 151
152 @pytest.mark.usefixtures("vcs_repository_support")
151 153 class TestDeprecatedRepositoryAPI(BackendTestMixin):
152 154 recreate_repo_per_test = False
153 155
@@ -450,6 +452,7 b' class TestRepositoryMerge:'
450 452 ref, self, ref, 'workspace_id', 'user name', 'user@email.com')
451 453
452 454
455 @pytest.mark.usefixtures("vcs_repository_support")
453 456 class TestRepositoryStrip(BackendTestMixin):
454 457 recreate_repo_per_test = True
455 458
@@ -20,7 +20,7 b''
20 20
21 21 import pytest
22 22
23 from rhodecode.tests.vcs.base import BackendTestMixin
23 from rhodecode.tests.vcs.conftest import BackendTestMixin
24 24 from rhodecode.lib.vcs.exceptions import (
25 25 TagAlreadyExistError, TagDoesNotExistError)
26 26
@@ -28,6 +28,7 b' from rhodecode.lib.vcs.exceptions import'
28 28 pytestmark = pytest.mark.backends("git", "hg")
29 29
30 30
31 @pytest.mark.usefixtures("vcs_repository_support")
31 32 class TestTags(BackendTestMixin):
32 33
33 34 def test_new_tag(self):
@@ -18,8 +18,8 b''
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 import os
21 22 import datetime
22 import os
23 23 import subprocess32
24 24
25 25 import pytest
@@ -33,7 +33,7 b' from rhodecode.lib.vcs.utils.paths impor'
33 33
34 34
35 35 @pytest.mark.usefixtures("baseapp")
36 class TestPaths:
36 class TestPaths(object):
37 37
38 38 def _test_get_dirs_for_path(self, path, expected):
39 39 """
@@ -69,7 +69,7 b' class TestPaths:'
69 69 assert set(get_scms_for_path(new)) == set(['git', 'hg'])
70 70
71 71
72 class TestGetScm:
72 class TestGetScm(object):
73 73
74 74 def test_existing_repository(self, vcs_repository_support):
75 75 alias, repo = vcs_repository_support
@@ -98,7 +98,7 b' class TestGetScm:'
98 98 get_scm(tmpdir.strpath)
99 99
100 100
101 class TestParseDatetime:
101 class TestParseDatetime(object):
102 102
103 103 def test_datetime_text(self):
104 104 assert parse_datetime('2010-04-07 21:29:41') == \
@@ -186,7 +186,7 b' class TestParseDatetime:'
186 186 ('Mr Double Name withemail@email.com ',
187 187 'Mr Double Name', 'withemail@email.com'),
188 188 ])
189 class TestAuthorExtractors:
189 class TestAuthorExtractors(object):
190 190
191 191 def test_author_email(self, test_str, name, email):
192 192 assert email == author_email(test_str)
@@ -8,7 +8,6 b' use = egg:rhodecode-vcsserver'
8 8
9 9 pyramid.default_locale_name = en
10 10 pyramid.includes =
11 pyramid.reload_templates = true
12 11
13 12 # default locale used by VCS systems
14 13 locale = en_US.UTF-8
@@ -22,10 +21,11 b' beaker.cache.repo_object.expire = 300'
22 21 beaker.cache.repo_object.enabled = true
23 22
24 23 [server:main]
25 use = egg:waitress#main
26 24 host = 127.0.0.1
27 25 port = 9900
28 26
27 use = egg:gunicorn#main
28
29 29 ################################
30 30 ### LOGGING CONFIGURATION ####
31 31 ################################
1 NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now