#!/usr/bin/env python # -*- coding: utf-8 -*- """Tests for `data2passcal` package.""" from __future__ import division, print_function import ftplib import os import sys import unittest import data2passcal.data2passcal as d2p if sys.version_info < (3, 3): from mock import patch else: from unittest.mock import patch VERSION = '2024.2.0.1' SEND4REAL = os.environ.get('SEND4REAL', 'False') print("SEND4REAL=False by default. If one wants to test sending data to " "PASSCAL for 'real', set SEND4REAL=True as environment variable. " "ex: SEND4REAL=True python -m unittest test_data2passcal") TEST_DIR = os.path.dirname(os.path.realpath(__file__)) + '/test_data' MS_FILELIST = ['ST00.AB..BHZ.2007.160', 'ST00.AB..BHZ.2007.161', 'ST00.AB..BHZ.2007.162', 'ST00.AB..BHZ.2007.163', 'ST00.AB..BHZ.2007.164'] d2p.FTP_TIMEOUT = 1 d2p.FTP_RECONNECT_WAIT = 0.01 d2p.FTP_CONNECT_ATTEMPTS = 2 d2p.FTP_SEND_ATTEMPTS = 2 class TestData2passcal(unittest.TestCase): """Tests for `data2passcal` package.""" def test_scan_dir(self): """ Test basic functionality of scan_dir function """ filelist = [os.path.join(TEST_DIR, f) for f in MS_FILELIST] if sys.version_info < (3, 2): self.assertItemsEqual(filelist, d2p.scan_dir(TEST_DIR), 'scan_dir did not find the correct file(s)') else: self.assertCountEqual(filelist, d2p.scan_dir(TEST_DIR), 'scan_dir did not find the correct file(s)') def test_ismseed(self): """Test basic functionality of ismseed function""" filelist = [os.path.join(TEST_DIR, f) for f in MS_FILELIST] for f in filelist: self.assertTrue(d2p.ismseed(f), '{} is not a miniseed file' .format(os.path.basename(f))) @patch('data2passcal.data2passcal.ftplib.FTP', autospec=True) def test_get_FTP_mock(self, mock_ftp_constructor): """Mock test creating ftp connection to PASSCAL""" mock_ftp = mock_ftp_constructor.return_value d2p.get_FTP() self.assertLess(mock_ftp_constructor.call_count, d2p.FTP_CONNECT_ATTEMPTS, 'Number of ftp connection attempts exceeeds {}' .format(d2p.FTP_CONNECT_ATTEMPTS)) mock_ftp.quit() @patch('data2passcal.data2passcal.urlopen', autospec=True) @patch('data2passcal.data2passcal.ftplib.FTP', autospec=True) def test_get_FTP_failure_mock(self, mock_ftp_constructor, mock_urlopen): """ Mock test failure to create ftp connection to PASSCAL and exercise get_FTP() """ mock_ftp_constructor.return_value = ftplib.error_temp d2p.get_FTP() self.assertGreater(mock_ftp_constructor.call_count, 1, "ftplib.FTP() called only once - get_FTP() not " "fully exercised!") @patch('data2passcal.data2passcal.ftplib.FTP', autospec=True) def test_send_data_mock(self, mock_ftp_constructor): """Mock test sending MSEED files (test data) to PASSCAL's QC system""" mock_ftp = mock_ftp_constructor.return_value filelist = [os.path.join(TEST_DIR, f) for f in MS_FILELIST[0:2]] d2p.send2passcal(filelist) self.assertTrue(mock_ftp.storbinary.called, 'No data sent') self.assertEqual(mock_ftp.storbinary.call_count, len(filelist), 'Failed to send all files - Sent {0} of {1}' .format(mock_ftp.storbinary.call_count, len(filelist))) files_sent = [] for x in mock_ftp.storbinary.call_args_list: args, kwargs = x files_sent.append(args[0].split(' ')[1]) for f in MS_FILELIST[0:2]: self.assertLess(files_sent.count(f), d2p.FTP_SEND_ATTEMPTS, 'Attempted to send file {0} more than {1} times' .format(f, d2p.FTP_SEND_ATTEMPTS)) @patch('data2passcal.data2passcal.os._exit', autospec=True) @patch('data2passcal.data2passcal.urlopen', autospec=True) @patch('data2passcal.data2passcal.ftplib.FTP', autospec=True) def test_send_data_failure_mock(self, mock_ftp_constructor, mock_urlopen, mock_exit): """ Mock test failure to create ftp connection to PASSCAL and exercise send_data() """ mock_ftp_constructor.return_value = ftplib.error_temp filelist = [os.path.join(TEST_DIR, f) for f in MS_FILELIST[0:2]] d2p.send2passcal(filelist) self.assertTrue(mock_exit.called, "os._exit(1) never called - " "send_data() not fully exercised!") @unittest.skipIf(SEND4REAL == 'False', "skipping real send2passcal test") def test_send_data(self): """Test sending MSEED files (test data) to PASSCAL's QC system""" ftp = d2p.get_FTP() filelist = [os.path.join(TEST_DIR, f) for f in MS_FILELIST[0:2]] d2p.send2passcal(filelist) wdir = ftp.pwd() try: files_sent = [os.path.basename(x) for x in ftp.nlst(wdir)] except ftplib.error_perm() as resp: if str(resp) == "550 No files found": print("No files found in this directory") else: raise for f in MS_FILELIST[0:2]: self.assertIn(f, files_sent, 'File {} was not sent to PASSCAL' .format(f)) ftp.quit() if __name__ == '__main__': unittest.main()