amine@269
|
1 import os
|
amine@403
|
2 from collections import namedtuple
|
amine@403
|
3 from tempfile import TemporaryDirectory
|
amine@403
|
4 from unittest.mock import patch
|
amine@403
|
5
|
amine@400
|
6 import pytest
|
amine@267
|
7
|
amine@267
|
8 from auditok.cmdline_util import (
|
amine@273
|
9 _AUDITOK_LOGGER,
|
amine@403
|
10 KeywordArguments,
|
amine@403
|
11 initialize_workers,
|
amine@267
|
12 make_kwargs,
|
amine@267
|
13 make_logger,
|
amine@267
|
14 )
|
amine@271
|
15 from auditok.workers import (
|
amine@403
|
16 CommandLineWorker,
|
amine@403
|
17 PlayerWorker,
|
amine@403
|
18 PrintWorker,
|
amine@403
|
19 RegionSaverWorker,
|
amine@271
|
20 StreamSaverWorker,
|
amine@271
|
21 )
|
amine@267
|
22
|
amine@400
|
23 _ArgsNamespace = namedtuple(
|
amine@400
|
24 "_ArgsNamespace",
|
amine@267
|
25 [
|
amine@267
|
26 "input",
|
amine@292
|
27 "max_read",
|
amine@267
|
28 "analysis_window",
|
amine@267
|
29 "sampling_rate",
|
amine@267
|
30 "sample_width",
|
amine@267
|
31 "channels",
|
amine@267
|
32 "use_channel",
|
amine@267
|
33 "input_format",
|
amine@267
|
34 "output_format",
|
amine@267
|
35 "large_file",
|
amine@267
|
36 "frame_per_buffer",
|
amine@267
|
37 "input_device_index",
|
amine@267
|
38 "save_stream",
|
amine@292
|
39 "save_detections_as",
|
amine@267
|
40 "plot",
|
amine@267
|
41 "save_image",
|
amine@267
|
42 "min_duration",
|
amine@267
|
43 "max_duration",
|
amine@267
|
44 "max_silence",
|
amine@267
|
45 "drop_trailing_silence",
|
amine@267
|
46 "strict_min_duration",
|
amine@267
|
47 "energy_threshold",
|
amine@267
|
48 "echo",
|
amine@292
|
49 "progress_bar",
|
amine@267
|
50 "command",
|
amine@267
|
51 "quiet",
|
amine@267
|
52 "printf",
|
amine@267
|
53 "time_format",
|
amine@267
|
54 "timestamp_format",
|
amine@267
|
55 ],
|
amine@267
|
56 )
|
amine@267
|
57
|
amine@267
|
58
|
amine@400
|
59 @pytest.mark.parametrize(
|
amine@400
|
60 "save_stream, save_detections_as, plot, save_image, use_channel, exp_use_channel, exp_record",
|
amine@400
|
61 [
|
amine@400
|
62 # no_record
|
amine@400
|
63 ("stream.ogg", None, False, None, "mix", "mix", False),
|
amine@400
|
64 # no_record_plot
|
amine@400
|
65 ("stream.ogg", None, True, None, None, None, False),
|
amine@400
|
66 # no_record_save_image
|
amine@400
|
67 ("stream.ogg", None, True, "image.png", None, None, False),
|
amine@400
|
68 # record_plot
|
amine@400
|
69 (None, None, True, None, None, None, True),
|
amine@400
|
70 # record_save_image
|
amine@400
|
71 (None, None, False, "image.png", None, None, True),
|
amine@400
|
72 # int_use_channel
|
amine@400
|
73 ("stream.ogg", None, False, None, "1", 1, False),
|
amine@400
|
74 # save_detections_as
|
amine@400
|
75 ("stream.ogg", "{id}.wav", False, None, None, None, False),
|
amine@400
|
76 ],
|
amine@400
|
77 ids=[
|
amine@400
|
78 "no_record",
|
amine@400
|
79 "no_record_plot",
|
amine@400
|
80 "no_record_save_image",
|
amine@400
|
81 "record_plot",
|
amine@400
|
82 "record_save_image",
|
amine@400
|
83 "int_use_channel",
|
amine@400
|
84 "save_detections_as",
|
amine@400
|
85 ],
|
amine@400
|
86 )
|
amine@400
|
87 def test_make_kwargs(
|
amine@400
|
88 save_stream,
|
amine@400
|
89 save_detections_as,
|
amine@400
|
90 plot,
|
amine@400
|
91 save_image,
|
amine@400
|
92 use_channel,
|
amine@400
|
93 exp_use_channel,
|
amine@400
|
94 exp_record,
|
amine@400
|
95 ):
|
amine@400
|
96 args = (
|
amine@400
|
97 "file",
|
amine@400
|
98 30,
|
amine@400
|
99 0.01,
|
amine@400
|
100 16000,
|
amine@400
|
101 2,
|
amine@400
|
102 2,
|
amine@400
|
103 use_channel,
|
amine@400
|
104 "raw",
|
amine@400
|
105 "ogg",
|
amine@400
|
106 True,
|
amine@400
|
107 None,
|
amine@400
|
108 1,
|
amine@267
|
109 save_stream,
|
amine@292
|
110 save_detections_as,
|
amine@267
|
111 plot,
|
amine@267
|
112 save_image,
|
amine@400
|
113 0.2,
|
amine@400
|
114 10,
|
amine@400
|
115 0.3,
|
amine@400
|
116 False,
|
amine@400
|
117 False,
|
amine@400
|
118 55,
|
amine@400
|
119 )
|
amine@400
|
120 misc = (
|
amine@400
|
121 False,
|
amine@400
|
122 False,
|
amine@400
|
123 None,
|
amine@400
|
124 True,
|
amine@400
|
125 None,
|
amine@400
|
126 "TIME_FORMAT",
|
amine@400
|
127 "TIMESTAMP_FORMAT",
|
amine@400
|
128 )
|
amine@400
|
129 args_ns = _ArgsNamespace(*(args + misc))
|
amine@267
|
130
|
amine@400
|
131 io_kwargs = {
|
amine@400
|
132 "input": "file",
|
amine@400
|
133 "max_read": 30,
|
amine@400
|
134 "block_dur": 0.01,
|
amine@400
|
135 "sampling_rate": 16000,
|
amine@400
|
136 "sample_width": 2,
|
amine@400
|
137 "channels": 2,
|
amine@400
|
138 "use_channel": exp_use_channel,
|
amine@400
|
139 "save_stream": save_stream,
|
amine@400
|
140 "save_detections_as": save_detections_as,
|
amine@400
|
141 "audio_format": "raw",
|
amine@400
|
142 "export_format": "ogg",
|
amine@400
|
143 "large_file": True,
|
amine@400
|
144 "frames_per_buffer": None,
|
amine@400
|
145 "input_device_index": 1,
|
amine@400
|
146 "record": exp_record,
|
amine@400
|
147 }
|
amine@267
|
148
|
amine@400
|
149 split_kwargs = {
|
amine@400
|
150 "min_dur": 0.2,
|
amine@400
|
151 "max_dur": 10,
|
amine@400
|
152 "max_silence": 0.3,
|
amine@400
|
153 "drop_trailing_silence": False,
|
amine@400
|
154 "strict_min_dur": False,
|
amine@400
|
155 "energy_threshold": 55,
|
amine@400
|
156 }
|
amine@267
|
157
|
amine@400
|
158 miscellaneous = {
|
amine@400
|
159 "echo": False,
|
amine@400
|
160 "command": None,
|
amine@400
|
161 "progress_bar": False,
|
amine@400
|
162 "quiet": True,
|
amine@400
|
163 "printf": None,
|
amine@400
|
164 "time_format": "TIME_FORMAT",
|
amine@400
|
165 "timestamp_format": "TIMESTAMP_FORMAT",
|
amine@400
|
166 }
|
amine@267
|
167
|
amine@400
|
168 expected = KeywordArguments(io_kwargs, split_kwargs, miscellaneous)
|
amine@400
|
169 kwargs = make_kwargs(args_ns)
|
amine@400
|
170 assert kwargs == expected
|
amine@267
|
171
|
amine@268
|
172
|
amine@400
|
173 def test_make_logger_stderr_and_file(capsys):
|
amine@400
|
174 with TemporaryDirectory() as tmpdir:
|
amine@400
|
175 file = os.path.join(tmpdir, "file.log")
|
amine@400
|
176 logger = make_logger(stderr=True, file=file)
|
amine@400
|
177 assert logger.name == _AUDITOK_LOGGER
|
amine@400
|
178 assert len(logger.handlers) == 2
|
amine@400
|
179 assert logger.handlers[1].stream.name == file
|
amine@400
|
180 logger.info("This is a debug message")
|
amine@400
|
181 captured = capsys.readouterr()
|
amine@400
|
182 assert "This is a debug message" in captured.err
|
amine@400
|
183
|
amine@400
|
184
|
amine@400
|
185 def test_make_logger_None():
|
amine@400
|
186 logger = make_logger(stderr=False, file=None)
|
amine@400
|
187 assert logger is None
|
amine@400
|
188
|
amine@400
|
189
|
amine@400
|
190 def test_initialize_workers_all():
|
amine@400
|
191 with patch("auditok.cmdline_util.player_for") as patched_player_for:
|
amine@269
|
192 with TemporaryDirectory() as tmpdir:
|
amine@400
|
193 export_filename = os.path.join(tmpdir, "output.wav")
|
amine@271
|
194 reader, observers = initialize_workers(
|
amine@271
|
195 input="tests/data/test_16KHZ_mono_400Hz.wav",
|
amine@400
|
196 save_stream=export_filename,
|
amine@400
|
197 export_format="wave",
|
amine@400
|
198 save_detections_as="{id}.wav",
|
amine@400
|
199 echo=True,
|
amine@400
|
200 progress_bar=False,
|
amine@400
|
201 command="some command",
|
amine@400
|
202 quiet=False,
|
amine@400
|
203 printf="abcd",
|
amine@400
|
204 time_format="%S",
|
amine@400
|
205 timestamp_format="%h:%M:%S",
|
amine@400
|
206 )
|
amine@400
|
207 reader.stop()
|
amine@400
|
208 assert patched_player_for.called
|
amine@400
|
209 assert isinstance(reader, StreamSaverWorker)
|
amine@400
|
210 for obs, cls in zip(
|
amine@400
|
211 observers,
|
amine@400
|
212 [
|
amine@400
|
213 RegionSaverWorker,
|
amine@400
|
214 PlayerWorker,
|
amine@400
|
215 CommandLineWorker,
|
amine@400
|
216 PrintWorker,
|
amine@400
|
217 ],
|
amine@400
|
218 ):
|
amine@400
|
219 assert isinstance(obs, cls)
|
amine@400
|
220
|
amine@400
|
221
|
amine@400
|
222 def test_initialize_workers_no_RegionSaverWorker():
|
amine@400
|
223 with patch("auditok.cmdline_util.player_for") as patched_player_for:
|
amine@400
|
224 with TemporaryDirectory() as tmpdir:
|
amine@400
|
225 export_filename = os.path.join(tmpdir, "output.wav")
|
amine@400
|
226 reader, observers = initialize_workers(
|
amine@400
|
227 input="tests/data/test_16KHZ_mono_400Hz.wav",
|
amine@400
|
228 save_stream=export_filename,
|
amine@271
|
229 export_format="wave",
|
amine@271
|
230 save_detections_as=None,
|
amine@271
|
231 echo=True,
|
amine@271
|
232 progress_bar=False,
|
amine@400
|
233 command="some command",
|
amine@400
|
234 quiet=False,
|
amine@400
|
235 printf="abcd",
|
amine@400
|
236 time_format="%S",
|
amine@400
|
237 timestamp_format="%h:%M:%S",
|
amine@400
|
238 )
|
amine@400
|
239 reader.stop()
|
amine@400
|
240 assert patched_player_for.called
|
amine@400
|
241 assert isinstance(reader, StreamSaverWorker)
|
amine@400
|
242 for obs, cls in zip(
|
amine@400
|
243 observers, [PlayerWorker, CommandLineWorker, PrintWorker]
|
amine@400
|
244 ):
|
amine@400
|
245 assert isinstance(obs, cls)
|
amine@400
|
246
|
amine@400
|
247
|
amine@400
|
248 def test_initialize_workers_no_PlayerWorker():
|
amine@400
|
249 with patch("auditok.cmdline_util.player_for") as patched_player_for:
|
amine@400
|
250 with TemporaryDirectory() as tmpdir:
|
amine@400
|
251 export_filename = os.path.join(tmpdir, "output.wav")
|
amine@400
|
252 reader, observers = initialize_workers(
|
amine@400
|
253 input="tests/data/test_16KHZ_mono_400Hz.wav",
|
amine@400
|
254 save_stream=export_filename,
|
amine@400
|
255 export_format="wave",
|
amine@400
|
256 save_detections_as="{id}.wav",
|
amine@400
|
257 echo=False,
|
amine@400
|
258 progress_bar=False,
|
amine@400
|
259 command="some command",
|
amine@400
|
260 quiet=False,
|
amine@400
|
261 printf="abcd",
|
amine@400
|
262 time_format="%S",
|
amine@400
|
263 timestamp_format="%h:%M:%S",
|
amine@400
|
264 )
|
amine@400
|
265 reader.stop()
|
amine@400
|
266 assert not patched_player_for.called
|
amine@400
|
267 assert isinstance(reader, StreamSaverWorker)
|
amine@400
|
268 for obs, cls in zip(
|
amine@400
|
269 observers,
|
amine@400
|
270 [RegionSaverWorker, CommandLineWorker, PrintWorker],
|
amine@400
|
271 ):
|
amine@400
|
272 assert isinstance(obs, cls)
|
amine@400
|
273
|
amine@400
|
274
|
amine@400
|
275 def test_initialize_workers_no_CommandLineWorker():
|
amine@400
|
276 with patch("auditok.cmdline_util.player_for") as patched_player_for:
|
amine@400
|
277 with TemporaryDirectory() as tmpdir:
|
amine@400
|
278 export_filename = os.path.join(tmpdir, "output.wav")
|
amine@400
|
279 reader, observers = initialize_workers(
|
amine@400
|
280 input="tests/data/test_16KHZ_mono_400Hz.wav",
|
amine@400
|
281 save_stream=export_filename,
|
amine@400
|
282 export_format="wave",
|
amine@400
|
283 save_detections_as="{id}.wav",
|
amine@400
|
284 echo=True,
|
amine@400
|
285 progress_bar=False,
|
amine@271
|
286 command=None,
|
amine@400
|
287 quiet=False,
|
amine@400
|
288 printf="abcd",
|
amine@400
|
289 time_format="%S",
|
amine@400
|
290 timestamp_format="%h:%M:%S",
|
amine@400
|
291 )
|
amine@400
|
292 reader.stop()
|
amine@400
|
293 assert patched_player_for.called
|
amine@400
|
294 assert isinstance(reader, StreamSaverWorker)
|
amine@400
|
295 for obs, cls in zip(
|
amine@400
|
296 observers, [RegionSaverWorker, PlayerWorker, PrintWorker]
|
amine@400
|
297 ):
|
amine@400
|
298 assert isinstance(obs, cls)
|
amine@400
|
299
|
amine@400
|
300
|
amine@400
|
301 def test_initialize_workers_no_PrintWorker():
|
amine@400
|
302 with patch("auditok.cmdline_util.player_for") as patched_player_for:
|
amine@400
|
303 with TemporaryDirectory() as tmpdir:
|
amine@400
|
304 export_filename = os.path.join(tmpdir, "output.wav")
|
amine@400
|
305 reader, observers = initialize_workers(
|
amine@400
|
306 input="tests/data/test_16KHZ_mono_400Hz.wav",
|
amine@400
|
307 save_stream=export_filename,
|
amine@400
|
308 export_format="wave",
|
amine@400
|
309 save_detections_as="{id}.wav",
|
amine@400
|
310 echo=True,
|
amine@400
|
311 progress_bar=False,
|
amine@400
|
312 command="some command",
|
amine@271
|
313 quiet=True,
|
amine@271
|
314 printf="abcd",
|
amine@271
|
315 time_format="%S",
|
amine@271
|
316 timestamp_format="%h:%M:%S",
|
amine@271
|
317 )
|
amine@400
|
318 reader.stop()
|
amine@400
|
319 assert patched_player_for.called
|
amine@400
|
320 assert isinstance(reader, StreamSaverWorker)
|
amine@400
|
321 for obs, cls in zip(
|
amine@400
|
322 observers,
|
amine@400
|
323 [RegionSaverWorker, PlayerWorker, CommandLineWorker],
|
amine@400
|
324 ):
|
amine@400
|
325 assert isinstance(obs, cls)
|
amine@337
|
326
|
amine@337
|
327
|
amine@400
|
328 def test_initialize_workers_no_observers():
|
amine@400
|
329 with patch("auditok.cmdline_util.player_for") as patched_player_for:
|
amine@400
|
330 reader, observers = initialize_workers(
|
amine@400
|
331 input="tests/data/test_16KHZ_mono_400Hz.wav",
|
amine@400
|
332 save_stream=None,
|
amine@400
|
333 export_format="wave",
|
amine@400
|
334 save_detections_as=None,
|
amine@400
|
335 echo=True,
|
amine@400
|
336 progress_bar=False,
|
amine@400
|
337 command=None,
|
amine@400
|
338 quiet=True,
|
amine@400
|
339 printf="abcd",
|
amine@400
|
340 time_format="%S",
|
amine@400
|
341 timestamp_format="%h:%M:%S",
|
amine@400
|
342 )
|
amine@400
|
343 assert patched_player_for.called
|
amine@400
|
344 assert not isinstance(reader, StreamSaverWorker)
|
amine@400
|
345 assert len(observers) == 1
|