##// END OF EJS Templates
tests: refactor TestINI to different name so it doesn't confuse pytest.
marcink -
r131:39302703 default
parent child Browse files
Show More
@@ -1,71 +1,71 b''
1 # RhodeCode VCSServer provides access to different vcs backends via network.
1 # RhodeCode VCSServer provides access to different vcs backends via network.
2 # Copyright (C) 2014-2016 RodeCode GmbH
2 # Copyright (C) 2014-2016 RodeCode GmbH
3 #
3 #
4 # This program is free software; you can redistribute it and/or modify
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 3 of the License, or
6 # the Free Software Foundation; either version 3 of the License, or
7 # (at your option) any later version.
7 # (at your option) any later version.
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 General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software Foundation,
15 # along with this program; if not, write to the Free Software Foundation,
16 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
17
18 import os
18 import os
19 import shutil
19 import shutil
20 import tempfile
20 import tempfile
21
21
22 import configobj
22 import configobj
23
23
24
24
25 class TestINI(object):
25 class ContextINI(object):
26 """
26 """
27 Allows to create a new test.ini file as a copy of existing one with edited
27 Allows to create a new test.ini file as a copy of existing one with edited
28 data. If existing file is not present, it creates a new one. Example usage::
28 data. If existing file is not present, it creates a new one. Example usage::
29
29
30 with TestINI('test.ini', [{'section': {'key': 'val'}}]) as new_test_ini_path:
30 with TestINI('test.ini', [{'section': {'key': 'val'}}]) as new_test_ini_path:
31 print 'vcsserver --config=%s' % new_test_ini
31 print 'vcsserver --config=%s' % new_test_ini
32 """
32 """
33
33
34 def __init__(self, ini_file_path, ini_params, new_file_prefix=None,
34 def __init__(self, ini_file_path, ini_params, new_file_prefix=None,
35 destroy=True):
35 destroy=True):
36 self.ini_file_path = ini_file_path
36 self.ini_file_path = ini_file_path
37 self.ini_params = ini_params
37 self.ini_params = ini_params
38 self.new_path = None
38 self.new_path = None
39 self.new_path_prefix = new_file_prefix or 'test'
39 self.new_path_prefix = new_file_prefix or 'test'
40 self.destroy = destroy
40 self.destroy = destroy
41
41
42 def __enter__(self):
42 def __enter__(self):
43 _, pref = tempfile.mkstemp()
43 _, pref = tempfile.mkstemp()
44 loc = tempfile.gettempdir()
44 loc = tempfile.gettempdir()
45 self.new_path = os.path.join(loc, '{}_{}_{}'.format(
45 self.new_path = os.path.join(loc, '{}_{}_{}'.format(
46 pref, self.new_path_prefix, self.ini_file_path))
46 pref, self.new_path_prefix, self.ini_file_path))
47
47
48 # copy ini file and modify according to the params, if we re-use a file
48 # copy ini file and modify according to the params, if we re-use a file
49 if os.path.isfile(self.ini_file_path):
49 if os.path.isfile(self.ini_file_path):
50 shutil.copy(self.ini_file_path, self.new_path)
50 shutil.copy(self.ini_file_path, self.new_path)
51 else:
51 else:
52 # create new dump file for configObj to write to.
52 # create new dump file for configObj to write to.
53 with open(self.new_path, 'wb'):
53 with open(self.new_path, 'wb'):
54 pass
54 pass
55
55
56 config = configobj.ConfigObj(
56 config = configobj.ConfigObj(
57 self.new_path, file_error=True, write_empty_values=True)
57 self.new_path, file_error=True, write_empty_values=True)
58
58
59 for data in self.ini_params:
59 for data in self.ini_params:
60 section, ini_params = data.items()[0]
60 section, ini_params = data.items()[0]
61 key, val = ini_params.items()[0]
61 key, val = ini_params.items()[0]
62 if section not in config:
62 if section not in config:
63 config[section] = {}
63 config[section] = {}
64 config[section][key] = val
64 config[section][key] = val
65
65
66 config.write()
66 config.write()
67 return self.new_path
67 return self.new_path
68
68
69 def __exit__(self, exc_type, exc_val, exc_tb):
69 def __exit__(self, exc_type, exc_val, exc_tb):
70 if self.destroy:
70 if self.destroy:
71 os.remove(self.new_path)
71 os.remove(self.new_path)
@@ -1,132 +1,132 b''
1 # RhodeCode VCSServer provides access to different vcs backends via network.
1 # RhodeCode VCSServer provides access to different vcs backends via network.
2 # Copyright (C) 2014-2016 RodeCode GmbH
2 # Copyright (C) 2014-2016 RodeCode GmbH
3 #
3 #
4 # This program is free software; you can redistribute it and/or modify
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 3 of the License, or
6 # the Free Software Foundation; either version 3 of the License, or
7 # (at your option) any later version.
7 # (at your option) any later version.
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 General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software Foundation,
15 # along with this program; if not, write to the Free Software Foundation,
16 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
17
18 import subprocess
18 import subprocess
19 import StringIO
19 import StringIO
20 import time
20 import time
21
21
22 import pytest
22 import pytest
23
23
24 from fixture import TestINI
24 from fixture import ContextINI
25
25
26
26
27 @pytest.mark.parametrize("arguments, expected_texts", [
27 @pytest.mark.parametrize("arguments, expected_texts", [
28 (['--threadpool=192'], [
28 (['--threadpool=192'], [
29 'threadpool_size: 192',
29 'threadpool_size: 192',
30 'worker pool of size 192 created',
30 'worker pool of size 192 created',
31 'Threadpool size set to 192']),
31 'Threadpool size set to 192']),
32 (['--locale=fake'], [
32 (['--locale=fake'], [
33 'Cannot set locale, not configuring the locale system']),
33 'Cannot set locale, not configuring the locale system']),
34 (['--timeout=5'], [
34 (['--timeout=5'], [
35 'Timeout for RPC calls set to 5.0 seconds']),
35 'Timeout for RPC calls set to 5.0 seconds']),
36 (['--log-level=info'], [
36 (['--log-level=info'], [
37 'log_level: info']),
37 'log_level: info']),
38 (['--port={port}'], [
38 (['--port={port}'], [
39 'port: {port}',
39 'port: {port}',
40 'created daemon on localhost:{port}']),
40 'created daemon on localhost:{port}']),
41 (['--host=127.0.0.1', '--port={port}'], [
41 (['--host=127.0.0.1', '--port={port}'], [
42 'port: {port}',
42 'port: {port}',
43 'host: 127.0.0.1',
43 'host: 127.0.0.1',
44 'created daemon on 127.0.0.1:{port}']),
44 'created daemon on 127.0.0.1:{port}']),
45 (['--config=/bad/file'], ['OSError: File /bad/file does not exist']),
45 (['--config=/bad/file'], ['OSError: File /bad/file does not exist']),
46 ])
46 ])
47 def test_vcsserver_calls(arguments, expected_texts, vcsserver_port):
47 def test_vcsserver_calls(arguments, expected_texts, vcsserver_port):
48 port_argument = '--port={port}'
48 port_argument = '--port={port}'
49 if port_argument not in arguments:
49 if port_argument not in arguments:
50 arguments.append(port_argument)
50 arguments.append(port_argument)
51 arguments = _replace_port(arguments, vcsserver_port)
51 arguments = _replace_port(arguments, vcsserver_port)
52 expected_texts = _replace_port(expected_texts, vcsserver_port)
52 expected_texts = _replace_port(expected_texts, vcsserver_port)
53 output = call_vcs_server_with_arguments(arguments)
53 output = call_vcs_server_with_arguments(arguments)
54 for text in expected_texts:
54 for text in expected_texts:
55 assert text in output
55 assert text in output
56
56
57
57
58 def _replace_port(values, port):
58 def _replace_port(values, port):
59 return [value.format(port=port) for value in values]
59 return [value.format(port=port) for value in values]
60
60
61
61
62 def test_vcsserver_with_config(vcsserver_port):
62 def test_vcsserver_with_config(vcsserver_port):
63 ini_def = [
63 ini_def = [
64 {'DEFAULT': {'host': '127.0.0.1'}},
64 {'DEFAULT': {'host': '127.0.0.1'}},
65 {'DEFAULT': {'threadpool_size': '111'}},
65 {'DEFAULT': {'threadpool_size': '111'}},
66 {'DEFAULT': {'port': vcsserver_port}},
66 {'DEFAULT': {'port': vcsserver_port}},
67 ]
67 ]
68
68
69 with TestINI('test.ini', ini_def) as new_test_ini_path:
69 with ContextINI('test.ini', ini_def) as new_test_ini_path:
70 output = call_vcs_server_with_arguments(
70 output = call_vcs_server_with_arguments(
71 ['--config=' + new_test_ini_path])
71 ['--config=' + new_test_ini_path])
72
72
73 expected_texts = [
73 expected_texts = [
74 'host: 127.0.0.1',
74 'host: 127.0.0.1',
75 'Threadpool size set to 111',
75 'Threadpool size set to 111',
76 ]
76 ]
77 for text in expected_texts:
77 for text in expected_texts:
78 assert text in output
78 assert text in output
79
79
80
80
81 def test_vcsserver_with_config_cli_overwrite(vcsserver_port):
81 def test_vcsserver_with_config_cli_overwrite(vcsserver_port):
82 ini_def = [
82 ini_def = [
83 {'DEFAULT': {'host': '127.0.0.1'}},
83 {'DEFAULT': {'host': '127.0.0.1'}},
84 {'DEFAULT': {'port': vcsserver_port}},
84 {'DEFAULT': {'port': vcsserver_port}},
85 {'DEFAULT': {'threadpool_size': '111'}},
85 {'DEFAULT': {'threadpool_size': '111'}},
86 {'DEFAULT': {'timeout': '0'}},
86 {'DEFAULT': {'timeout': '0'}},
87 ]
87 ]
88 with TestINI('test.ini', ini_def) as new_test_ini_path:
88 with ContextINI('test.ini', ini_def) as new_test_ini_path:
89 output = call_vcs_server_with_arguments([
89 output = call_vcs_server_with_arguments([
90 '--config=' + new_test_ini_path,
90 '--config=' + new_test_ini_path,
91 '--host=128.0.0.1',
91 '--host=128.0.0.1',
92 '--threadpool=256',
92 '--threadpool=256',
93 '--timeout=5'])
93 '--timeout=5'])
94 expected_texts = [
94 expected_texts = [
95 'host: 128.0.0.1',
95 'host: 128.0.0.1',
96 'Threadpool size set to 256',
96 'Threadpool size set to 256',
97 'Timeout for RPC calls set to 5.0 seconds',
97 'Timeout for RPC calls set to 5.0 seconds',
98 ]
98 ]
99 for text in expected_texts:
99 for text in expected_texts:
100 assert text in output
100 assert text in output
101
101
102
102
103 def call_vcs_server_with_arguments(args):
103 def call_vcs_server_with_arguments(args):
104 vcs = subprocess.Popen(
104 vcs = subprocess.Popen(
105 ["vcsserver"] + args,
105 ["vcsserver"] + args,
106 stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
106 stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
107
107
108 output = read_output_until(
108 output = read_output_until(
109 "Starting vcsserver.main", vcs.stdout)
109 "Starting vcsserver.main", vcs.stdout)
110 vcs.terminate()
110 vcs.terminate()
111 return output
111 return output
112
112
113
113
114 def call_vcs_server_with_non_existing_config_file(args):
114 def call_vcs_server_with_non_existing_config_file(args):
115 vcs = subprocess.Popen(
115 vcs = subprocess.Popen(
116 ["vcsserver", "--config=/tmp/bad"] + args,
116 ["vcsserver", "--config=/tmp/bad"] + args,
117 stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
117 stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
118 output = read_output_until(
118 output = read_output_until(
119 "Starting vcsserver.main", vcs.stdout)
119 "Starting vcsserver.main", vcs.stdout)
120 vcs.terminate()
120 vcs.terminate()
121 return output
121 return output
122
122
123
123
124 def read_output_until(expected, source, timeout=5):
124 def read_output_until(expected, source, timeout=5):
125 ts = time.time()
125 ts = time.time()
126 buf = StringIO.StringIO()
126 buf = StringIO.StringIO()
127 while time.time() - ts < timeout:
127 while time.time() - ts < timeout:
128 line = source.readline()
128 line = source.readline()
129 buf.write(line)
129 buf.write(line)
130 if expected in line:
130 if expected in line:
131 break
131 break
132 return buf.getvalue()
132 return buf.getvalue()
General Comments 0
You need to be logged in to leave comments. Login now