annotate tests/test_cmdline_util.py @ 455:7dae98b84cdd tip master

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