From b99c27d54c4382a392d31564faf29f446397f4df Mon Sep 17 00:00:00 2001 From: "shimoda.m@nds-tyo.co.jp" Date: Wed, 17 Aug 2022 14:10:36 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=E3=83=87=E3=83=BC=E3=82=BF=E5=8F=96?= =?UTF-8?q?=E5=BE=97=E3=81=AE=E3=83=AA=E3=83=88=E3=83=A9=E3=82=A4=E3=83=86?= =?UTF-8?q?=E3=82=B9=E3=83=88=E3=82=92=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tests/test_fetch_crm_data_process.py | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) diff --git a/ecs/crm-datafetch/tests/test_fetch_crm_data_process.py b/ecs/crm-datafetch/tests/test_fetch_crm_data_process.py index 3145ba32..5d35ac58 100644 --- a/ecs/crm-datafetch/tests/test_fetch_crm_data_process.py +++ b/ecs/crm-datafetch/tests/test_fetch_crm_data_process.py @@ -320,3 +320,119 @@ class TestFetchCrmDataProcess: assert e.value.func_name == FETCH_JP_NAME # リトライ例外のオブジェクトIDが違うため、in句で比較 assert f'[Account] の件数取得に失敗しました エラー内容:[RetryError' in e.value.args[0] + + @pytest.mark.parametrize('timeout_env_name, exception, expect_message', [ + ('CRM_AUTH_TIMEOUT', ConnectTimeout('接続タイムアウト'), 'W-FETCH-04 CRMの接続処理がタイムアウトしため、リトライします:[1] エラー内容:[接続タイムアウト]'), + ('CRM_FETCH_RECORD_TIMEOUT', ReadTimeout('読み取りタイムアウト'), 'W-FETCH-05 [Account] のレコード取得処理がタイムアウトしたため、リトライします:[1] エラー内容:[読み取りタイムアウト]'), + ('CRM_AUTH_TIMEOUT', Exception('予期せぬ例外'), 'W-FETCH-06 [Account] のレコード取得に失敗したため、リトライします エラー内容:[予期せぬ例外]'), + ], ids=['connection_timeout', 'read_timeout', 'unexpected_exception']) + def test_raise_fetch_sf_data_with_retry_success(self, monkeypatch, caplog, timeout_env_name, exception, expect_message): + """ + Cases: + 1. レコード取得処理で接続タイムアウト例外が発生した場合、リトライした結果復旧し、正常終了すること + 2. レコード取得処理で読み取りタイムアウト例外が発生した場合、リトライした結果復旧し、正常終了すること + 3. レコード取得処理で予期せぬ例外が発生した場合、リトライした結果復旧し、正常終了すること + Arranges: + - レコード取得処理の最大リトライ試行回数を3に設定する + - timeout_env_nameに指定されたリトライタイムアウト時間の秒数を1に設定する + - レコード取得処理の初回に接続タイムアウト例外が発生するようにする + Expects: + - 正常終了する + - データレコード取得に失敗した胸のエラーが出力されない + """ + + monkeypatch.setattr('src.fetch_crm_data_process.CRM_GET_RECORD_COUNT_MAX_RETRY_ATTEMPT', 3) + monkeypatch.setattr('src.fetch_crm_data_process.CRM_GET_RECORD_COUNT_RETRY_MAX_INTERVAL', 1) + monkeypatch.setattr('src.fetch_crm_data_process.CRM_GET_RECORD_COUNT_RETRY_MIN_INTERVAL', 1) + monkeypatch.setattr('src.fetch_crm_data_process.CRM_GET_RECORD_COUNT_RETRY_INTERVAL', 1) + monkeypatch.setattr(f'src.fetch_crm_data_process.{timeout_env_name}', 1) + # Arrange + with patch('src.fetch_crm_data_process.CounterObject', ) as mock_counter, \ + patch('src.fetch_crm_data_process.SOQLBuilder') as mock_soql_builder, \ + patch('src.fetch_crm_data_process.SalesforceApiClient') as mock_api_client: + # モック化 + mock_counter_inst = mock_counter.return_value + mock_counter_inst.describe.side_effect = [1, 2, 3] + mock_counter_inst.increment.side_effect = [2, 3, 4] + mock_builder_inst = mock_soql_builder.return_value + mock_builder_inst.create_count_soql.return_value = '' + mock_builder_inst.create_fetch_soql.return_value = '' + mock_client_inst = mock_api_client.return_value + mock_client_inst.fetch_sf_count.return_value = 1 + mock_client_inst.fetch_sf_data.side_effect = [exception, common_expect] + # Act + fetch_crm_data_process(common_target_object, common_last_fetch_datetime) + + # Assert + + assert mock_counter_inst.describe.call_count == 1 + assert mock_counter_inst.increment.call_count == 1 + + assert generate_log_message_tuple( + log_level=logging.WARNING, + log_message=expect_message) in caplog.record_tuples + called_log_counts = len([log for log in caplog.messages if log == expect_message]) + assert called_log_counts == 1 + assert generate_log_message_tuple(log_message='I-FETCH-06 [Account] のCRMからのデータ取得処理を終了します') in caplog.record_tuples + + @pytest.mark.parametrize('timeout_env_name, exception, expect_message', [ + ('CRM_AUTH_TIMEOUT', ConnectTimeout('接続タイムアウト'), 'W-FETCH-04 CRMの接続処理がタイムアウトしため、リトライします:[1] エラー内容:[接続タイムアウト]'), + ('CRM_FETCH_RECORD_TIMEOUT', ReadTimeout('読み取りタイムアウト'), 'W-FETCH-05 [Account] のレコード取得処理がタイムアウトしたため、リトライします:[1] エラー内容:[読み取りタイムアウト]'), + ('CRM_AUTH_TIMEOUT', Exception('予期せぬ例外'), 'W-FETCH-06 [Account] のレコード取得に失敗したため、リトライします エラー内容:[予期せぬ例外]'), + ], ids=['connection_timeout', 'read_timeout', 'unexpected_exception']) + def test_raise_fetch_sf_data_with_retry_fail(self, monkeypatch, caplog, timeout_env_name, exception, expect_message): + """ + Cases: + 1. レコード取得処理で接続タイムアウト例外が発生した場合、リトライした結果復旧せず、異常終了すること + 2. レコード取得処理で読み取りタイムアウト例外が発生した場合、リトライした結果復旧せず、異常終了すること + 3. レコード取得処理で予期せぬ例外が発生した場合、リトライした結果復旧せず、異常終了すること + Arranges: + - レコード取得処理の最大リトライ試行回数を3に設定する + - timeout_env_nameに指定されたリトライタイムアウト時間の秒数を1に設定する + - レコード取得処理の1回目、2回目、3回目で接続タイムアウト例外が発生するようにする + Expects: + - 異常終了する + - データレコード取得に失敗した旨のエラーが出力される + """ + + monkeypatch.setattr('src.fetch_crm_data_process.CRM_FETCH_RECORD_MAX_RETRY_ATTEMPT', 3) + monkeypatch.setattr('src.fetch_crm_data_process.CRM_FETCH_RECORD_RETRY_MAX_INTERVAL', 1) + monkeypatch.setattr('src.fetch_crm_data_process.CRM_FETCH_RECORD_RETRY_MIN_INTERVAL', 1) + monkeypatch.setattr('src.fetch_crm_data_process.CRM_FETCH_RECORD_RETRY_INTERVAL', 1) + monkeypatch.setattr(f'src.fetch_crm_data_process.{timeout_env_name}', 1) + # Arrange + with patch('src.fetch_crm_data_process.CounterObject', ) as mock_counter, \ + patch('src.fetch_crm_data_process.SOQLBuilder') as mock_soql_builder, \ + patch('src.fetch_crm_data_process.SalesforceApiClient') as mock_api_client: + # モック化 + mock_counter_inst = mock_counter.return_value + mock_counter_inst.describe.side_effect = [1, 2, 3] + mock_counter_inst.increment.side_effect = [2, 3, 4] + mock_builder_inst = mock_soql_builder.return_value + mock_builder_inst.create_count_soql.return_value = '' + mock_builder_inst.create_fetch_soql.return_value = '' + mock_client_inst = mock_api_client.return_value + mock_client_inst.fetch_sf_count.return_value = 1 + mock_client_inst.fetch_sf_data.side_effect = [exception, exception, exception] + # Act + with pytest.raises(SalesforceAPIException) as e: + fetch_crm_data_process(common_target_object, common_last_fetch_datetime) + + # Assert + + # 取得は3回行われる + assert mock_counter_inst.describe.call_count == 3 + # 足し込みは2回のみ + assert mock_counter_inst.increment.call_count == 2 + + assert generate_log_message_tuple( + log_level=logging.WARNING, + log_message=expect_message) in caplog.record_tuples + called_log_counts = len([log for log in caplog.messages if log == expect_message]) + assert called_log_counts == 2 + assert generate_log_message_tuple(log_message='I-FETCH-06 [Account] のCRMからのデータ取得処理を終了します') not in caplog.record_tuples + + assert e.value.error_id == 'E-FETCH-02' + assert e.value.func_name == FETCH_JP_NAME + # リトライ例外のオブジェクトIDが違うため、in句で比較 + assert f'[Account] のレコード取得に失敗しました エラー内容:[RetryError' in e.value.args[0]