Newer
Older
from tempfile import TemporaryDirectory, NamedTemporaryFile
from pathlib import Path
from unittest import TestCase
from unittest.mock import patch
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
from sohstationviewer.controller.processing import (
loadData,
readChannels,
detectDataType,
getDataTypeFromFile
)
from sohstationviewer.database.extractData import signatureChannels
from PySide2 import QtWidgets
from sohstationviewer.model.mseed.mseed import MSeed
from sohstationviewer.model.reftek.reftek import RT130
TEST_DATA_DIR = Path(__file__).resolve().parent.parent.joinpath('test_data')
rt130_dir = TEST_DATA_DIR.joinpath('RT130-sample/2017149.92EB/2017150')
q330_dir = TEST_DATA_DIR.joinpath('Q330-sample/day_vols_AX08')
centaur_dir = TEST_DATA_DIR.joinpath('Centaur-sample/SOH')
pegasus_dir = TEST_DATA_DIR.joinpath('Pegasus-sample/Pegasus_SVC4/soh')
class TestLoadDataAndReadChannels(TestCase):
"""Test suite for loadData and readChannels."""
def setUp(self) -> None:
"""Set up test fixtures."""
patcher = patch.object(QtWidgets, 'QTextBrowser')
self.addCleanup(patcher.stop)
self.widget_stub = patcher.start()
# The actual value can be 'Q330', 'Centaur', or 'Pegasus'.
# The code that uses this string only cares that it is not 'RT130',
# though, so we are setting it to a stub value.
self.mseed_dtype = 'MSeed'
def test_load_data_rt130_good_dir(self):
"""
Test basic functionality of loadData - the given directory can be
loaded without issues. Test RT130.
"""
self.assertIsInstance(
loadData('RT130', self.widget_stub, [rt130_dir]),
RT130
)
def test_load_data_mseed_q330_good_data_dir(self):
"""
Test basic functionality of loadData - the given directory can be
loaded without issues. Test MSeed.
"""
self.assertIsInstance(
loadData(self.mseed_dtype, self.widget_stub, [q330_dir]),
MSeed
)
self.assertIsInstance(
loadData(self.mseed_dtype, self.widget_stub, [centaur_dir]),
MSeed
)
self.assertIsInstance(
loadData(self.mseed_dtype, self.widget_stub, [pegasus_dir]),
MSeed
)
def test_load_data_no_dir(self):
"""Test basic functionality of loadData - no directory was given."""
no_dir_given = []
self.assertIsNone(loadData('RT130', self.widget_stub, no_dir_given))
self.assertIsNone(
loadData(self.mseed_dtype, self.widget_stub, no_dir_given))
def test_load_data_dir_does_not_exist(self):
"""
Test basic functionality of loadData - the given directory does not
exist.
"""
empty_name_dir = ['']
non_existent_dir = ['dir_that_does_not_exist']
self.assertIsNone(
loadData('RT130', self.widget_stub, empty_name_dir))
self.assertIsNone(
loadData('RT130', self.widget_stub, non_existent_dir))
self.assertIsNone(
loadData(self.mseed_dtype, self.widget_stub, empty_name_dir))
self.assertIsNone(
loadData(self.mseed_dtype, self.widget_stub, non_existent_dir))
def test_load_data_empty_dir(self):
"""
Test basic functionality of loadData - the given directory is empty.
"""
with TemporaryDirectory() as empty_dir:
self.assertIsNone(
loadData('RT130', self.widget_stub, [empty_dir]))
self.assertIsNone(
loadData(self.mseed_dtype, self.widget_stub, [empty_dir]))
def test_load_data_empty_data_dir(self):
"""
Test basic functionality of loadData - the given directory
contains a data folder but no data file.
"""
with TemporaryDirectory() as outer_dir:
with TemporaryDirectory(dir=outer_dir) as data_dir:
self.assertIsNone(
loadData('RT130', self.widget_stub, [data_dir]))
self.assertIsNone(
loadData(self.mseed_dtype, self.widget_stub, [outer_dir]))
def test_load_data_data_type_mismatch(self):
"""
Test basic functionality of loadData - the data type given does not
match the type of the data contained in the given directory.
"""
self.assertIsNone(
loadData('RT130', self.widget_stub, [q330_dir]))
self.assertIsNone(
loadData(self.mseed_dtype, self.widget_stub, [rt130_dir]))
def test_load_data_data_traceback_error(self):
"""
Test basic functionality of loadData - when there is an error
on loading data, the traceback info will be printed out
"""
f = io.StringIO()
with redirect_stdout(f):
self.assertIsNone(loadData('RT130', None, [q330_dir]))
output = f.getvalue()
self.assertIn(
f"Warning: Dir {q330_dir} "
f"can't be read due to error: Traceback",
output
)
with redirect_stdout(f):
self.assertIsNone(
loadData(self.mseed_dtype, None, [rt130_dir]))
output = f.getvalue()
self.assertIn(
f"Warning: Dir {rt130_dir} "
f"can't be read due to error: Traceback",
output
)
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
def test_read_channels_mseed_dir(self):
"""
Test basic functionality of loadData - the given directory contains
MSeed data.
"""
q330_channels = {'VKI', 'VM1'}
self.assertSetEqual(readChannels(self.widget_stub, [q330_dir]),
q330_channels)
centaur_channels = {'VDT', 'VM3', 'EX3', 'GEL', 'VEC', 'EX2', 'LCE',
'EX1', 'GLA', 'LCQ', 'GPL', 'GNS', 'GST', 'VCO',
'GAN', 'GLO', 'VPB', 'VEI', 'VM2', 'VM1'}
self.assertSetEqual(readChannels(self.widget_stub, [centaur_dir]),
centaur_channels)
pegasus_channels = {'VDT', 'VM1', 'VE1'}
self.assertSetEqual(readChannels(self.widget_stub, [pegasus_dir]),
pegasus_channels)
def test_read_channels_rt130_dir(self):
"""
Test basic functionality of loadData - the given directory contains
RT130 data.
"""
with self.assertRaises(Exception):
readChannels(self.widget_stub, [rt130_dir])
def test_read_channels_no_dir(self):
"""
Test basic functionality of readChannels - no directory was given.
"""
no_dir = []
with self.assertRaises(Exception):
readChannels(self.widget_stub, no_dir)
def test_read_channels_dir_does_not_exist(self):
"""
Test basic functionality of readChannels - the given directory does not
exist.
"""
empty_name_dir = ['']
non_existent_dir = ['non_existent_dir']
with self.assertRaises(Exception):
readChannels(self.widget_stub, empty_name_dir)
with self.assertRaises(Exception):
readChannels(self.widget_stub, non_existent_dir)
def test_read_channels_empty_dir(self):
"""
Test basic functionality of readChannels - the given directory is
empty.
"""
with TemporaryDirectory() as empty_dir:
with self.assertRaises(Exception):
readChannels(self.widget_stub, [empty_dir])
def test_read_channels_empty_data_dir(self):
"""
Test basic functionality of readChannels - the given directory
contains a data folder but no data file.
"""
with TemporaryDirectory() as outer_dir:
with TemporaryDirectory(dir=outer_dir):
with self.assertRaises(Exception):
readChannels(self.widget_stub, [outer_dir])
class TestDetectDataType(TestCase):
"""Test suite for detectDataType and getDataTypeFromFile functions."""
def setUp(self) -> None:
"""Set up text fixtures."""
widget_patcher = patch.object(QtWidgets, 'QTextBrowser')
self.addCleanup(widget_patcher.stop)
self.widget_stub = widget_patcher.start()
func_patcher = patch('sohstationviewer.controller.processing.'
'getDataTypeFromFile')
self.addCleanup(func_patcher.stop)
self.mock_get_data_type_from_file = func_patcher.start()
self.dir1 = TemporaryDirectory()
self.dir2 = TemporaryDirectory()
self.file1 = NamedTemporaryFile(dir=self.dir1.name)
self.file2 = NamedTemporaryFile(dir=self.dir2.name)
def tearDown(self) -> None:
"""Teardown text fixtures."""
del self.file1, self.file2
self.dir1.cleanup()
self.dir2.cleanup()
def test_one_directory_not_unknown_data_type(self):
"""
Test basic functionality of detectDataType - only one directory was
given and the data type it contains can be detected.
"""
expected_data_type = ('RT130', '_')
self.mock_get_data_type_from_file.return_value = expected_data_type
self.assertEqual(
detectDataType(self.widget_stub, [self.dir1.name]),
expected_data_type[0]
)
def test_same_data_type_and_channel(self):
"""
Test basic functionality of detectDataType - the given directories
contain the same data type and the data type was detected using the
same channel.
"""
expected_data_type = ('RT130', '_')
self.mock_get_data_type_from_file.return_value = expected_data_type
self.assertEqual(
detectDataType(self.widget_stub, [self.dir1.name, self.dir2.name]),
expected_data_type[0]
)
def test_same_data_type_different_channel(self):
"""
Test basic functionality of detectDataType - the given directories
contain the same data type but the data type was detected using
different channels.
"""
returned_data_types = [('Q330', 'OCF'), ('Q330', 'VEP')]
self.mock_get_data_type_from_file.side_effect = returned_data_types
self.assertEqual(
detectDataType(self.widget_stub, [self.dir1.name, self.dir2.name]),
returned_data_types[0][0]
)
def test_different_data_types(self):
"""
Test basic functionality of detectDataType - the given directories
contain different data types.
"""
returned_data_types = [('RT130', '_'), ('Q330', 'VEP')]
self.mock_get_data_type_from_file.side_effect = returned_data_types
self.assertIsNone(
detectDataType(self.widget_stub, [self.dir1.name, self.dir2.name])
)
def test_unknown_data_type(self):
"""
Test basic functionality of detectDataType - can't detect any data
type.
"""
unknown_data_type = ('Unknown', '_')
self.mock_get_data_type_from_file.return_value = unknown_data_type
self.assertIsNone(detectDataType(self.widget_stub, [self.dir1.name]))
class TestGetDataTypeFromFile(TestCase):
"""Test suite for getDataTypeFromFile"""
def test_rt130_data(self):
"""
Test basic functionality of getDataTypeFromFile - given file contains
RT130 data.
"""
rt130_file = Path(rt130_dir).joinpath(
'92EB/0/000000000_00000000')
expected_data_type = ('RT130', '_')
self.assertTupleEqual(
getDataTypeFromFile(rt130_file, signatureChannels()),
expected_data_type
)
def test_cannot_detect_data_type(self):
"""
Test basic functionality of getDataTypeFromFile - cannot detect data
type contained in given file.
"""
test_file = NamedTemporaryFile()
self.assertIsNone(
getDataTypeFromFile(test_file.name, signatureChannels()))
def test_mseed_data(self):
"""
Test basic functionality of getDataTypeFromFile - given file contains
MSeed data.
"""
q330_file = q330_dir.joinpath('AX08.XA..VKI.2021.186')
centaur_file = centaur_dir.joinpath(
'XX.3734.SOH.centaur-3_3734..20180817_000000.miniseed.miniseed')
pegasus_file = pegasus_dir.joinpath(
'2020/XX/KC01/VE1.D/XX.KC01..VE1.D.2020.129')
q330_data_type = ('Q330', 'VKI')
centaur_data_type = ('Centaur', 'GEL')
pegasus_data_type = ('Pegasus', 'VE1')
sig_chan = signatureChannels()
self.assertTupleEqual(getDataTypeFromFile(q330_file, sig_chan),
q330_data_type)
self.assertTupleEqual(getDataTypeFromFile(centaur_file, sig_chan),
centaur_data_type)
self.assertTupleEqual(getDataTypeFromFile(pegasus_file, sig_chan),
pegasus_data_type)
def test_file_does_not_exist(self):
"""
Test basic functionality of getDataTypeFromFile - given file does not
exist.
"""
empty_name_file = ''
non_existent_file = 'non_existent_dir'
with self.assertRaises(FileNotFoundError):
getDataTypeFromFile(empty_name_file, signatureChannels())
with self.assertRaises(FileNotFoundError):
getDataTypeFromFile(non_existent_file, signatureChannels())