annotate tests/test_workers.py @ 278:b9d52cf32c89

Refactor CommandLineWorker
author Amine Sehili <amine.sehili@gmail.com>
date Sun, 29 Sep 2019 10:03:24 +0100
parents 0a5374fcb700
children 87bb649f5d3a
rev   line source
amine@274 1 import os
amine@274 2 from unittest import TestCase
amine@274 3 from unittest.mock import patch, call
amine@274 4 from tempfile import TemporaryDirectory
amine@274 5 from genty import genty, genty_dataset
amine@274 6 from auditok import AudioDataSource
amine@274 7 from auditok.cmdline_util import make_logger
amine@274 8 from auditok.workers import (
amine@274 9 TokenizerWorker,
amine@274 10 StreamSaverWorker,
amine@274 11 RegionSaverWorker,
amine@274 12 PlayerWorker,
amine@274 13 CommandLineWorker,
amine@274 14 PrintWorker,
amine@274 15 )
amine@274 16
amine@274 17
amine@274 18 @genty
amine@274 19 class TestWorkers(TestCase):
amine@275 20 def setUp(self):
amine@275 21
amine@275 22 self.reader = AudioDataSource(
amine@274 23 input="tests/data/test_split_10HZ_mono.raw",
amine@274 24 block_dur=0.1,
amine@274 25 sr=10,
amine@274 26 sw=2,
amine@274 27 ch=1,
amine@274 28 )
amine@275 29 self.expected = [
amine@275 30 (0.2, 1.6),
amine@275 31 (1.7, 3.1),
amine@275 32 (3.4, 5.4),
amine@275 33 (5.4, 7.4),
amine@275 34 (7.4, 7.6),
amine@275 35 ]
amine@275 36
amine@275 37 def tearDown(self):
amine@275 38 self.reader.close()
amine@275 39
amine@275 40 def test_TokenizerWorker(self):
amine@275 41
amine@274 42 with TemporaryDirectory() as tmpdir:
amine@274 43 file = os.path.join(tmpdir, "file.log")
amine@274 44 logger = make_logger(file=file, name="test_TokenizerWorker")
amine@274 45 tokenizer = TokenizerWorker(
amine@275 46 self.reader,
amine@274 47 logger=logger,
amine@274 48 min_dur=0.3,
amine@274 49 max_dur=2,
amine@274 50 max_silence=0.2,
amine@274 51 drop_trailing_silence=False,
amine@274 52 strict_min_dur=False,
amine@274 53 eth=50,
amine@274 54 )
amine@275 55 tokenizer.start_all()
amine@275 56 tokenizer.join()
amine@274 57 # Get logged text
amine@274 58 with open(file) as fp:
amine@274 59 log_lines = fp.readlines()
amine@274 60
amine@274 61 log_fmt = "[DET]: Detection {} (start: {:.3f}, "
amine@274 62 log_fmt += "end: {:.3f}, duration: {:.3f})"
amine@275 63 self.assertEqual(len(tokenizer.detections), len(self.expected))
amine@274 64 for i, (det, exp, log_line) in enumerate(
amine@275 65 zip(tokenizer.detections, self.expected, log_lines), 1
amine@274 66 ):
amine@274 67 start, end = exp
amine@274 68 exp_log_line = log_fmt.format(i, start, end, end - start)
amine@274 69 self.assertAlmostEqual(det.start, start)
amine@274 70 self.assertAlmostEqual(det.end, end)
amine@274 71 # remove timestamp part and strip new line
amine@274 72 self.assertEqual(log_line[28:].strip(), exp_log_line)
amine@275 73
amine@277 74 def test_RegionSaverWorker(self):
amine@277 75 filename_format = (
amine@277 76 "Region_{id}_{start:.6f}-{end:.3f}_{duration:.3f}.wav"
amine@277 77 )
amine@277 78 with TemporaryDirectory() as tmpdir:
amine@277 79 file = os.path.join(tmpdir, "file.log")
amine@277 80 logger = make_logger(file=file, name="test_RegionSaverWorker")
amine@277 81 observers = [RegionSaverWorker(filename_format, logger=logger)]
amine@277 82 tokenizer = TokenizerWorker(
amine@277 83 self.reader,
amine@277 84 logger=logger,
amine@277 85 observers=observers,
amine@277 86 min_dur=0.3,
amine@277 87 max_dur=2,
amine@277 88 max_silence=0.2,
amine@277 89 drop_trailing_silence=False,
amine@277 90 strict_min_dur=False,
amine@277 91 eth=50,
amine@277 92 )
amine@277 93 with patch("auditok.core.AudioRegion.save") as patched_save:
amine@277 94 tokenizer.start_all()
amine@277 95 tokenizer.join()
amine@277 96 tokenizer._observers[0].join()
amine@277 97 # Get logged text
amine@277 98 with open(file) as fp:
amine@277 99 log_lines = [
amine@277 100 line
amine@277 101 for line in fp.readlines()
amine@277 102 if line.startswith("[SAVE]")
amine@277 103 ]
amine@277 104
amine@277 105 # Asser PrintWorker ran as expected
amine@277 106 expected_save_calls = [
amine@277 107 call(
amine@277 108 filename_format.format(
amine@277 109 id=i, start=exp[0], end=exp[1], duration=exp[1] - exp[0]
amine@277 110 ),
amine@277 111 None,
amine@277 112 )
amine@277 113 for i, exp in enumerate(self.expected, 1)
amine@277 114 ]
amine@277 115
amine@277 116 # get calls to 'AudioRegion.save'
amine@277 117 mock_calls = [
amine@277 118 c for i, c in enumerate(patched_save.mock_calls) if i % 2 == 0
amine@277 119 ]
amine@277 120 self.assertEqual(mock_calls, expected_save_calls)
amine@277 121 self.assertEqual(len(tokenizer.detections), len(self.expected))
amine@277 122
amine@277 123 log_fmt = '[SAVE]: Detection {id} saved as "{filename}"'
amine@277 124 for i, (det, exp, log_line) in enumerate(
amine@277 125 zip(tokenizer.detections, self.expected, log_lines), 1
amine@277 126 ):
amine@277 127 start, end = exp
amine@277 128 expected_filename = filename_format.format(
amine@277 129 id=i, start=start, end=end, duration=end - start
amine@277 130 )
amine@277 131 exp_log_line = log_fmt.format(i, expected_filename)
amine@277 132 self.assertAlmostEqual(det.start, start)
amine@277 133 self.assertAlmostEqual(det.end, end)
amine@277 134 # remove timestamp part and strip new line
amine@277 135 self.assertEqual(log_line[28:].strip(), exp_log_line)
amine@277 136
amine@275 137 def test_PrintWorker(self):
amine@275 138 observers = [
amine@275 139 PrintWorker(print_format="[{id}] {start} {end}, dur: {duration}")
amine@275 140 ]
amine@275 141 tokenizer = TokenizerWorker(
amine@275 142 self.reader,
amine@275 143 observers=observers,
amine@275 144 min_dur=0.3,
amine@275 145 max_dur=2,
amine@275 146 max_silence=0.2,
amine@275 147 drop_trailing_silence=False,
amine@275 148 strict_min_dur=False,
amine@275 149 eth=50,
amine@275 150 )
amine@275 151 with patch("builtins.print") as patched_print:
amine@275 152 tokenizer.start_all()
amine@275 153 tokenizer.join()
amine@275 154 tokenizer._observers[0].join()
amine@275 155
amine@275 156 # Asser PrintWorker ran as expected
amine@275 157 expected_print_calls = [
amine@275 158 call(
amine@275 159 "[{}] {:.3f} {:.3f}, dur: {:.3f}".format(
amine@275 160 i, *exp, exp[1] - exp[0]
amine@275 161 )
amine@275 162 )
amine@275 163 for i, exp in enumerate(self.expected, 1)
amine@275 164 ]
amine@275 165 self.assertEqual(patched_print.mock_calls, expected_print_calls)
amine@275 166 self.assertEqual(len(tokenizer.detections), len(self.expected))
amine@275 167
amine@275 168 for det, exp in zip(tokenizer.detections, self.expected):
amine@275 169 start, end = exp
amine@275 170 self.assertAlmostEqual(det.start, start)
amine@275 171 self.assertAlmostEqual(det.end, end)