2 Tests for command line interface wrapper.
4 These tests just check that the various command line parameters route to the
5 correct functionionality. They use a lot of monkeypatching to avoid executing
14 import nominatim.clicmd.api
15 import nominatim.clicmd.refresh
16 import nominatim.clicmd.admin
17 import nominatim.indexer.indexer
18 import nominatim.tools.refresh
19 import nominatim.tools.replication
20 from nominatim.errors import UsageError
21 from nominatim.db import status
23 def call_nominatim(*args):
24 return nominatim.cli.nominatim(module_dir='build/module',
25 osm2pgsql_path='build/osm2pgsql/osm2pgsql',
28 phpcgi_path='/usr/bin/php-cgi',
30 config_dir='settings',
33 class MockParamCapture:
34 """ Mock that records the parameters with which a function was called
35 as well as the number of calls.
37 def __init__(self, retval=0):
39 self.return_value = retval
41 def __call__(self, *args, **kwargs):
44 self.last_kwargs = kwargs
45 return self.return_value
48 def mock_run_legacy(monkeypatch):
49 mock = MockParamCapture()
50 monkeypatch.setattr(nominatim.cli, 'run_legacy_script', mock)
54 def test_cli_help(capsys):
55 """ Running nominatim tool without arguments prints help.
57 assert 1 == call_nominatim()
59 captured = capsys.readouterr()
60 assert captured.out.startswith('usage:')
63 @pytest.mark.parametrize("command,script", [
64 (('import', '--continue', 'load-data'), 'setup'),
65 (('freeze',), 'setup'),
66 (('special-phrases',), 'specialphrases'),
67 (('add-data', '--tiger-data', 'tiger'), 'setup'),
68 (('add-data', '--file', 'foo.osm'), 'update'),
69 (('export',), 'export')
71 def test_legacy_commands_simple(mock_run_legacy, command, script):
72 assert 0 == call_nominatim(*command)
74 assert mock_run_legacy.called == 1
75 assert mock_run_legacy.last_args[0] == script + '.php'
78 @pytest.mark.parametrize("params", [('--warm', ),
79 ('--warm', '--reverse-only'),
80 ('--warm', '--search-only'),
81 ('--check-database', )])
82 def test_admin_command_legacy(monkeypatch, params):
83 mock_run_legacy = MockParamCapture()
84 monkeypatch.setattr(nominatim.clicmd.admin, 'run_legacy_script', mock_run_legacy)
86 assert 0 == call_nominatim('admin', *params)
88 assert mock_run_legacy.called == 1
90 @pytest.mark.parametrize("func, params", [('analyse_indexing', ('--analyse-indexing', ))])
91 def test_admin_command_tool(temp_db, monkeypatch, func, params):
92 mock = MockParamCapture()
93 monkeypatch.setattr(nominatim.tools.admin, func, mock)
95 assert 0 == call_nominatim('admin', *params)
96 assert mock.called == 1
98 @pytest.mark.parametrize("name,oid", [('file', 'foo.osm'), ('diff', 'foo.osc'),
99 ('node', 12), ('way', 8), ('relation', 32)])
100 def test_add_data_command(mock_run_legacy, name, oid):
101 assert 0 == call_nominatim('add-data', '--' + name, str(oid))
103 assert mock_run_legacy.called == 1
104 assert mock_run_legacy.last_args == ('update.php', '--import-' + name, oid)
107 @pytest.mark.parametrize("params,do_bnds,do_ranks", [
109 (['--boundaries-only'], 1, 0),
110 (['--no-boundaries'], 0, 1),
111 (['--boundaries-only', '--no-boundaries'], 0, 0)])
112 def test_index_command(monkeypatch, temp_db_cursor, params, do_bnds, do_ranks):
113 temp_db_cursor.execute("CREATE TABLE import_status (indexed bool)")
114 bnd_mock = MockParamCapture()
115 monkeypatch.setattr(nominatim.indexer.indexer.Indexer, 'index_boundaries', bnd_mock)
116 rank_mock = MockParamCapture()
117 monkeypatch.setattr(nominatim.indexer.indexer.Indexer, 'index_by_rank', rank_mock)
119 assert 0 == call_nominatim('index', *params)
121 assert bnd_mock.called == do_bnds
122 assert rank_mock.called == do_ranks
125 @pytest.mark.parametrize("command,params", [
126 ('wiki-data', ('setup.php', '--import-wikipedia-articles')),
127 ('importance', ('update.php', '--recompute-importance')),
128 ('website', ('setup.php', '--setup-website')),
130 def test_refresh_legacy_command(monkeypatch, temp_db, command, params):
131 mock_run_legacy = MockParamCapture()
132 monkeypatch.setattr(nominatim.clicmd.refresh, 'run_legacy_script', mock_run_legacy)
134 assert 0 == call_nominatim('refresh', '--' + command)
136 assert mock_run_legacy.called == 1
137 assert len(mock_run_legacy.last_args) >= len(params)
138 assert mock_run_legacy.last_args[:len(params)] == params
140 @pytest.mark.parametrize("command,func", [
141 ('postcodes', 'update_postcodes'),
142 ('word-counts', 'recompute_word_counts'),
143 ('address-levels', 'load_address_levels_from_file'),
144 ('functions', 'create_functions'),
146 def test_refresh_command(monkeypatch, temp_db, command, func):
147 func_mock = MockParamCapture()
148 monkeypatch.setattr(nominatim.tools.refresh, func, func_mock)
150 assert 0 == call_nominatim('refresh', '--' + command)
151 assert func_mock.called == 1
154 def test_refresh_importance_computed_after_wiki_import(monkeypatch, temp_db):
155 mock_run_legacy = MockParamCapture()
156 monkeypatch.setattr(nominatim.clicmd.refresh, 'run_legacy_script', mock_run_legacy)
158 assert 0 == call_nominatim('refresh', '--importance', '--wiki-data')
160 assert mock_run_legacy.called == 2
161 assert mock_run_legacy.last_args == ('update.php', '--recompute-importance')
164 @pytest.mark.parametrize("params,func", [
165 (('--init', '--no-update-functions'), 'init_replication'),
166 (('--check-for-updates',), 'check_for_updates')
168 def test_replication_command(monkeypatch, temp_db, params, func):
169 func_mock = MockParamCapture()
170 monkeypatch.setattr(nominatim.tools.replication, func, func_mock)
172 assert 0 == call_nominatim('replication', *params)
173 assert func_mock.called == 1
176 def test_replication_update_bad_interval(monkeypatch, temp_db):
177 monkeypatch.setenv('NOMINATIM_REPLICATION_UPDATE_INTERVAL', 'xx')
179 assert call_nominatim('replication') == 1
182 def test_replication_update_bad_interval_for_geofabrik(monkeypatch, temp_db):
183 monkeypatch.setenv('NOMINATIM_REPLICATION_URL',
184 'https://download.geofabrik.de/europe/ireland-and-northern-ireland-updates')
186 assert call_nominatim('replication') == 1
189 @pytest.mark.parametrize("state, retval", [
190 (nominatim.tools.replication.UpdateState.UP_TO_DATE, 0),
191 (nominatim.tools.replication.UpdateState.NO_CHANGES, 3)
193 def test_replication_update_once_no_index(monkeypatch, temp_db, temp_db_conn,
194 status_table, state, retval):
195 status.set_status(temp_db_conn, date=dt.datetime.now(dt.timezone.utc), seq=1)
196 func_mock = MockParamCapture(retval=state)
197 monkeypatch.setattr(nominatim.tools.replication, 'update', func_mock)
199 assert retval == call_nominatim('replication', '--once', '--no-index')
202 def test_replication_update_continuous(monkeypatch, temp_db_conn, status_table):
203 status.set_status(temp_db_conn, date=dt.datetime.now(dt.timezone.utc), seq=1)
204 states = [nominatim.tools.replication.UpdateState.UP_TO_DATE,
205 nominatim.tools.replication.UpdateState.UP_TO_DATE]
206 monkeypatch.setattr(nominatim.tools.replication, 'update',
207 lambda *args, **kwargs: states.pop())
209 index_mock = MockParamCapture()
210 monkeypatch.setattr(nominatim.indexer.indexer.Indexer, 'index_boundaries', index_mock)
211 monkeypatch.setattr(nominatim.indexer.indexer.Indexer, 'index_by_rank', index_mock)
213 with pytest.raises(IndexError):
214 call_nominatim('replication')
216 assert index_mock.called == 4
219 def test_replication_update_continuous_no_change(monkeypatch, temp_db_conn, status_table):
220 status.set_status(temp_db_conn, date=dt.datetime.now(dt.timezone.utc), seq=1)
221 states = [nominatim.tools.replication.UpdateState.NO_CHANGES,
222 nominatim.tools.replication.UpdateState.UP_TO_DATE]
223 monkeypatch.setattr(nominatim.tools.replication, 'update',
224 lambda *args, **kwargs: states.pop())
226 index_mock = MockParamCapture()
227 monkeypatch.setattr(nominatim.indexer.indexer.Indexer, 'index_boundaries', index_mock)
228 monkeypatch.setattr(nominatim.indexer.indexer.Indexer, 'index_by_rank', index_mock)
230 sleep_mock = MockParamCapture()
231 monkeypatch.setattr(time, 'sleep', sleep_mock)
233 with pytest.raises(IndexError):
234 call_nominatim('replication')
236 assert index_mock.called == 2
237 assert sleep_mock.called == 1
238 assert sleep_mock.last_args[0] == 60
241 def test_serve_command(monkeypatch):
242 func = MockParamCapture()
243 monkeypatch.setattr(nominatim.cli, 'run_php_server', func)
245 call_nominatim('serve')
247 assert func.called == 1
249 @pytest.mark.parametrize("params", [
250 ('search', '--query', 'new'),
251 ('reverse', '--lat', '0', '--lon', '0'),
252 ('lookup', '--id', 'N1'),
253 ('details', '--node', '1'),
254 ('details', '--way', '1'),
255 ('details', '--relation', '1'),
256 ('details', '--place_id', '10001'),
259 def test_api_commands_simple(monkeypatch, params):
260 mock_run_api = MockParamCapture()
261 monkeypatch.setattr(nominatim.clicmd.api, 'run_api_script', mock_run_api)
263 assert 0 == call_nominatim(*params)
265 assert mock_run_api.called == 1
266 assert mock_run_api.last_args[0] == params[0]