annotate tests/test_cmdline_util.py @ 420:f874558779b9

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