import datetime import pytest from src.db.database import Database from src.error.exceptions import (BatchOperationException, MaxRunCountReachedException) from src.manager.jskult_batch_status_manager import JskultBatchStatusManager class TestJskultBatchStatusManager: @pytest.fixture(scope='function', autouse=True) def backup_hdke_tbl_record(self): """ テスト実行前にテーブルのバックアップを取得する。 テスト実行後にバックアップから復元する。 """ # Setup db = Database.get_instance() db.connect() # ステータス管理テーブル backup_status_manage_records = db.execute_select( 'SELECT * FROM internal07.jskult_batch_status_manage') db.execute('DELETE FROM internal07.jskult_batch_status_manage') # 日付テーブル backup_hdke_tbl = db.execute_select('SELECT * FROM src07.hdke_tbl') db.execute('DELETE FROM src07.hdke_tbl') yield # Teardown # ステータス管理テーブルを復元 db.execute('DELETE FROM internal07.jskult_batch_status_manage') if len(backup_status_manage_records) != 0: db.execute(""" INSERT INTO internal07.jskult_batch_status_manage (process_name,process_date,process_type,process_status,total_run_count,max_run_count_flg,ins_user,ins_date,upd_user,upd_date) VALUES (:process_name,:process_date,:process_type,:process_status,:total_run_count,:max_run_count_flg,:ins_user,:ins_date,:upd_user,:upd_date) """, backup_status_manage_records) # 日付テーブルを復元 if len(backup_hdke_tbl) != 0: db.execute('DELETE FROM src07.hdke_tbl') db.execute(""" INSERT INTO src07.hdke_tbl (syor_date, bch_actf, dump_sts_kbn, creater, create_date, updater, update_date) VALUES (:syor_date, :bch_actf, :dump_sts_kbn, CURRENT_USER(), CURRENT_TIMESTAMP(), NULL, NULL) """, { 'syor_date': backup_hdke_tbl[0]['syor_date'], 'bch_actf': backup_hdke_tbl[0]['bch_actf'], 'dump_sts_kbn': backup_hdke_tbl[0]['dump_sts_kbn'], }) db.disconnect() def test_set_process_status_record_not_exists(self): """ ステータス管理テーブルのレコードが0件のとき、INSERTされること """ # Arrange # 日付テーブルを登録 db = Database.get_instance() db.connect() db.execute(""" INSERT INTO src07.hdke_tbl (syor_date, bch_actf, dump_sts_kbn, creater, create_date, updater, update_date) VALUES ('20250530', '1', '2', CURRENT_USER(), CURRENT_TIMESTAMP(), NULL, NULL) """) # Act sut = JskultBatchStatusManager( 'unittest_process_name', 'unittest_process_type', 3, 33 ) sut.set_process_status('start') # Assert actual = db.execute_select(""" SELECT process_name, process_date, process_type, process_status FROM internal07.jskult_batch_status_manage """)[0] assert actual['process_name'] == 'unittest_process_name' assert datetime.datetime.strftime( actual['process_date'], '%Y/%m/%d') == '2025/05/30' assert actual['process_type'] == 'unittest_process_type' assert actual['process_status'] == 'start' def test_set_process_status_record_exists(self): """ ステータス管理テーブルのレコードが1件のとき、UPDATEされること """ # Arrange # 日付テーブルを登録 db = Database.get_instance() db.connect() db.execute(""" INSERT INTO src07.hdke_tbl (syor_date, bch_actf, dump_sts_kbn, creater, create_date, updater, update_date) VALUES ('20250530', '1', '2', CURRENT_USER(), CURRENT_TIMESTAMP(), NULL, NULL) """) # バッチステータス管理テーブルを登録 db.execute(""" INSERT INTO internal07.jskult_batch_status_manage (process_name, process_date, process_type, process_status, total_run_count, max_run_count_flg) VALUES ('unittest_process_name', '2025-05-30','unittest_process_type', 'retry', '1', '0') """) # Act sut = JskultBatchStatusManager( 'unittest_process_name', 'unittest_process_type', 3, 33 ) sut.set_process_status('doing') # Assert actual = db.execute_select(""" SELECT process_name, process_date, process_type, process_status FROM internal07.jskult_batch_status_manage """)[0] assert actual['process_name'] == 'unittest_process_name' assert datetime.datetime.strftime( actual['process_date'], '%Y/%m/%d') == '2025/05/30' assert actual['process_type'] == 'unittest_process_type' assert actual['process_status'] == 'doing' def test_set_process_status_raise_exception(self): """ ステータス管理テーブルのレコードが0件のとき、INSERTされること """ # Arrange # 日付テーブルを登録 db = Database.get_instance() db.connect() db.execute(""" INSERT INTO src07.hdke_tbl (syor_date, bch_actf, dump_sts_kbn, creater, create_date, updater, update_date) VALUES ('20250530', '1', '2', CURRENT_USER(), CURRENT_TIMESTAMP(), NULL, NULL) """) # Act # 処理名と管理区分をNoneで初期化 sut = JskultBatchStatusManager( None, None, 3, 33 ) # SQL実行時にNOT NULL制約に引っかかる with pytest.raises(BatchOperationException): sut.set_process_status(None) def test_can_run_post_process_success(self): """ 完了しているデータ取り込み件数と受信ファイル数が一致している場合、trueが返却されること 起動回数が+1されていること """ # Arrange # 日付テーブルを登録 db = Database.get_instance() db.connect() db.execute(""" INSERT INTO src07.hdke_tbl (syor_date, bch_actf, dump_sts_kbn, creater, create_date, updater, update_date) VALUES ('20250530', '1', '2', CURRENT_USER(), CURRENT_TIMESTAMP(), NULL, NULL) """) # バッチステータス管理テーブルを登録 db.execute(""" INSERT INTO internal07.jskult_batch_status_manage (process_name, process_date, process_type, process_status, total_run_count, max_run_count_flg) VALUES ('unittest_process_name', '2025-05-30', 'unittest_process_type', 'start', '0', '0'), ('data_import_process_1', '2025-05-30','data_import', 'done', '0', '0'), ('data_import_process_2', '2025-05-30','data_import', 'done', '0', '0'), ('data_import_process_3', '2025-05-30','data_import', 'done', '0', '0') """) # Act sut = JskultBatchStatusManager( 'unittest_process_name', 'unittest_process_type', 3, 3 ) actual = sut.can_run_post_process() # Assert assert actual is True actual_record = db.execute_select(""" SELECT total_run_count FROM internal07.jskult_batch_status_manage WHERE process_name = 'unittest_process_name' AND process_date = '2025-05-30' """)[0] assert actual_record['total_run_count'] == 1 def test_can_run_post_process_failed(self): """ 完了しているデータ取り込み件数と受信ファイル数が一致していない場合、falseが返却されること 起動回数が+1されていること """ # Arrange # 日付テーブルを登録 db = Database.get_instance() db.connect() db.execute(""" INSERT INTO src07.hdke_tbl (syor_date, bch_actf, dump_sts_kbn, creater, create_date, updater, update_date) VALUES ('20250530', '1', '2', CURRENT_USER(), CURRENT_TIMESTAMP(), NULL, NULL) """) # バッチステータス管理テーブルを登録 db.execute(""" INSERT INTO internal07.jskult_batch_status_manage (process_name, process_date, process_type, process_status, total_run_count, max_run_count_flg) VALUES ('unittest_process_name', '2025-05-30', 'unittest_process_type', 'start', '0', '0'), ('data_import_process_1', '2025-05-30','data_import', 'done', '0', '0'), ('data_import_process_2', '2025-05-30','data_import', 'done', '0', '0'), ('data_import_process_3', '2025-05-30','data_import', 'done', '0', '0') """) # Act sut = JskultBatchStatusManager( 'unittest_process_name', 'unittest_process_type', 3, 4 ) actual = sut.can_run_post_process() # Assert assert actual is False actual_record = db.execute_select(""" SELECT total_run_count FROM internal07.jskult_batch_status_manage WHERE process_name = 'unittest_process_name' AND process_date = '2025-05-30' """)[0] assert actual_record['total_run_count'] == 1 def test_can_run_post_process_raise_operation_exception(self): """ 自分自身のレコードが存在しない場合、例外が送出されること """ # Arrange # 日付テーブルを登録 db = Database.get_instance() db.connect() db.execute(""" INSERT INTO src07.hdke_tbl (syor_date, bch_actf, dump_sts_kbn, creater, create_date, updater, update_date) VALUES ('20250530', '1', '2', CURRENT_USER(), CURRENT_TIMESTAMP(), NULL, NULL) """) # バッチステータス管理テーブルを登録しない # Act sut = JskultBatchStatusManager( 'unittest_process_name', 'unittest_process_type', 3, 4 ) with pytest.raises(BatchOperationException): sut.can_run_post_process() def test_can_run_post_process_raise_max_run_count_reached_exception(self): """ 完了しているデータ取り込み件数と受信ファイル数が一致していないかつ、最大起動回数に到達している場合、例外が送出されること 最大起動回数フラグが1になっていること """ # Arrange # 日付テーブルを登録 db = Database.get_instance() db.connect() db.execute(""" INSERT INTO src07.hdke_tbl (syor_date, bch_actf, dump_sts_kbn, creater, create_date, updater, update_date) VALUES ('20250530', '1', '2', CURRENT_USER(), CURRENT_TIMESTAMP(), NULL, NULL) """) # バッチステータス管理テーブルを登録 db.execute(""" INSERT INTO internal07.jskult_batch_status_manage (process_name, process_date, process_type, process_status, total_run_count, max_run_count_flg) VALUES ('unittest_process_name', '2025-05-30', 'unittest_process_type', 'start', '2', '0'), ('data_import_process_1', '2025-05-30','data_import', 'done', '0', '0'), ('data_import_process_2', '2025-05-30','data_import', 'done', '0', '0'), ('data_import_process_3', '2025-05-30','data_import', 'done', '0', '0') """) # Act sut = JskultBatchStatusManager( 'unittest_process_name', 'unittest_process_type', 3, 4 ) with pytest.raises(MaxRunCountReachedException): sut.can_run_post_process() # Assert actual_record = db.execute_select(""" SELECT max_run_count_flg FROM internal07.jskult_batch_status_manage WHERE process_name = 'unittest_process_name' AND process_date = '2025-05-30' """)[0] assert actual_record['max_run_count_flg'] == 1 def test_can_run_business_day_update_success(self): """ 後続処理3件が完了している場合、trueが返却されること 起動回数が+1されていること """ # Arrange # 日付テーブルを登録 db = Database.get_instance() db.connect() db.execute(""" INSERT INTO src07.hdke_tbl (syor_date, bch_actf, dump_sts_kbn, creater, create_date, updater, update_date) VALUES ('20250530', '1', '2', CURRENT_USER(), CURRENT_TIMESTAMP(), NULL, NULL) """) # バッチステータス管理テーブルを登録 db.execute(""" INSERT INTO internal07.jskult_batch_status_manage (process_name, process_date, process_type, process_status, total_run_count, max_run_count_flg) VALUES ('jskult-batch-business-day-update', '2025-05-30', 'update_business_day', 'start', '0', '0'), ('jskult-batch-trn-result-data-bio-lot', '2025-05-30','post_process', 'done', '1', '0'), ('jskult-batch-dcf-inst-merge-io', '2025-05-30','post_process', 'done', '1', '0'), ('jskult-batch-mst-inst-all', '2025-05-30','post_process', 'done', '1', '0') """) # Act sut = JskultBatchStatusManager( 'jskult-batch-business-day-update', 'business_day_update', 3, 3 ) actual = sut.can_run_business_day_update() # Assert assert actual is True actual_record = db.execute_select(""" SELECT total_run_count FROM internal07.jskult_batch_status_manage WHERE process_name = 'jskult-batch-business-day-update' AND process_date = '2025-05-30' """)[0] assert actual_record['total_run_count'] == 1 def test_can_run_business_day_update_failed_because_bio_lot_doing(self): """ 後続処理3件のうち、生物由来ロット分解が終了していない場合、falseが返却されること 起動回数が+1されていること """ # Arrange # 日付テーブルを登録 db = Database.get_instance() db.connect() db.execute(""" INSERT INTO src07.hdke_tbl (syor_date, bch_actf, dump_sts_kbn, creater, create_date, updater, update_date) VALUES ('20250530', '1', '2', CURRENT_USER(), CURRENT_TIMESTAMP(), NULL, NULL) """) # バッチステータス管理テーブルを登録 db.execute(""" INSERT INTO internal07.jskult_batch_status_manage (process_name, process_date, process_type, process_status, total_run_count, max_run_count_flg) VALUES ('jskult-batch-business-day-update', '2025-05-30', 'update_business_day', 'start', '0', '0'), ('jskult-batch-trn-result-data-bio-lot', '2025-05-30','post_process', 'doing', '1', '0'), ('jskult-batch-dcf-inst-merge-io', '2025-05-30','post_process', 'done', '1', '0'), ('jskult-batch-mst-inst-all', '2025-05-30','post_process', 'done', '1', '0') """) # Act sut = JskultBatchStatusManager( 'jskult-batch-business-day-update', 'update_business_day', 3, 3 ) actual = sut.can_run_business_day_update() # Assert assert actual is False actual_record = db.execute_select(""" SELECT total_run_count FROM internal07.jskult_batch_status_manage WHERE process_name = 'jskult-batch-business-day-update' AND process_date = '2025-05-30' """)[0] assert actual_record['total_run_count'] == 1 def test_can_run_business_day_update_failed_because_dcf_inst_merge_io_doing(self): """ 後続処理3件のうち、DCF削除新規マスタ作成が終了していない場合、falseが返却されること 起動回数が+1されていること """ # Arrange # 日付テーブルを登録 db = Database.get_instance() db.connect() db.execute(""" INSERT INTO src07.hdke_tbl (syor_date, bch_actf, dump_sts_kbn, creater, create_date, updater, update_date) VALUES ('20250530', '1', '2', CURRENT_USER(), CURRENT_TIMESTAMP(), NULL, NULL) """) # バッチステータス管理テーブルを登録 db.execute(""" INSERT INTO internal07.jskult_batch_status_manage (process_name, process_date, process_type, process_status, total_run_count, max_run_count_flg) VALUES ('jskult-batch-business-day-update', '2025-05-30', 'update_business_day', 'start', '0', '0'), ('jskult-batch-trn-result-data-bio-lot', '2025-05-30','post_process', 'done', '1', '0'), ('jskult-batch-dcf-inst-merge-io', '2025-05-30','post_process', 'doing', '1', '0'), ('jskult-batch-mst-inst-all', '2025-05-30','post_process', 'done', '1', '0') """) # Act sut = JskultBatchStatusManager( 'jskult-batch-business-day-update', 'update_business_day', 3, 3 ) actual = sut.can_run_business_day_update() # Assert assert actual is False actual_record = db.execute_select(""" SELECT total_run_count FROM internal07.jskult_batch_status_manage WHERE process_name = 'jskult-batch-business-day-update' AND process_date = '2025-05-30' """)[0] assert actual_record['total_run_count'] == 1 def test_can_run_business_day_update_failed_because_mst_inst_all_doing(self): """ 後続処理3件のうち、メルク施設マスタ作成が終了していない場合、falseが返却されること 起動回数が+1されていること """ # Arrange # 日付テーブルを登録 db = Database.get_instance() db.connect() db.execute(""" INSERT INTO src07.hdke_tbl (syor_date, bch_actf, dump_sts_kbn, creater, create_date, updater, update_date) VALUES ('20250530', '1', '2', CURRENT_USER(), CURRENT_TIMESTAMP(), NULL, NULL) """) # バッチステータス管理テーブルを登録 db.execute(""" INSERT INTO internal07.jskult_batch_status_manage (process_name, process_date, process_type, process_status, total_run_count, max_run_count_flg) VALUES ('jskult-batch-business-day-update', '2025-05-30', 'update_business_day', 'start', '0', '0'), ('jskult-batch-trn-result-data-bio-lot', '2025-05-30','post_process', 'done', '1', '0'), ('jskult-batch-dcf-inst-merge-io', '2025-05-30','post_process', 'done', '1', '0'), ('jskult-batch-mst-inst-all', '2025-05-30','post_process', 'doing', '1', '0') """) # Act sut = JskultBatchStatusManager( 'jskult-batch-business-day-update', 'update_business_day', 3, 3 ) actual = sut.can_run_business_day_update() # Assert assert actual is False actual_record = db.execute_select(""" SELECT total_run_count FROM internal07.jskult_batch_status_manage WHERE process_name = 'jskult-batch-business-day-update' AND process_date = '2025-05-30' """)[0] assert actual_record['total_run_count'] == 1 def test_can_run_business_day_update_raise_operation_exception(self): """ 自分自身のレコードが存在しない場合、例外が送出されること """ # Arrange # 日付テーブルを登録 db = Database.get_instance() db.connect() db.execute(""" INSERT INTO src07.hdke_tbl (syor_date, bch_actf, dump_sts_kbn, creater, create_date, updater, update_date) VALUES ('20250530', '1', '2', CURRENT_USER(), CURRENT_TIMESTAMP(), NULL, NULL) """) # バッチステータス管理テーブルを登録しない # Act sut = JskultBatchStatusManager( 'unittest_process_name', 'unittest_process_type', 3, 4 ) with pytest.raises(BatchOperationException): sut.can_run_business_day_update() def test_can_run_business_day_update_raise_max_run_count_reached_exception(self): """ 後続処理3件のいずれかが終了していないかつ、最大起動回数に到達している場合、例外が送出されること 最大起動回数フラグが1になっていること """ # Arrange # 日付テーブルを登録 db = Database.get_instance() db.connect() db.execute(""" INSERT INTO src07.hdke_tbl (syor_date, bch_actf, dump_sts_kbn, creater, create_date, updater, update_date) VALUES ('20250530', '1', '2', CURRENT_USER(), CURRENT_TIMESTAMP(), NULL, NULL) """) # バッチステータス管理テーブルを登録 db.execute(""" INSERT INTO internal07.jskult_batch_status_manage (process_name, process_date, process_type, process_status, total_run_count, max_run_count_flg) VALUES ('jskult-batch-business-day-update', '2025-05-30', 'update_business_day', 'start', '2', '0'), ('jskult-batch-trn-result-data-bio-lot', '2025-05-30','post_process', 'doing', '1', '0'), ('jskult-batch-dcf-inst-merge-io', '2025-05-30','post_process', 'done', '1', '0'), ('jskult-batch-mst-inst-all', '2025-05-30','post_process', 'done', '1', '0') """) # Act sut = JskultBatchStatusManager( 'jskult-batch-business-day-update', 'update_business_day', 3, 4 ) with pytest.raises(MaxRunCountReachedException): sut.can_run_business_day_update() # Assert actual_record = db.execute_select(""" SELECT max_run_count_flg FROM internal07.jskult_batch_status_manage WHERE process_name = 'jskult-batch-business-day-update' AND process_date = '2025-05-30' """)[0] assert actual_record['max_run_count_flg'] == 1 def test_is_done_ultmarc_import_success(self): """ アルトマーク取込が完了している場合、trueが返却されること """ # Arrange # 日付テーブルを登録 db = Database.get_instance() db.connect() db.execute(""" INSERT INTO src07.hdke_tbl (syor_date, bch_actf, dump_sts_kbn, creater, create_date, updater, update_date) VALUES ('20250530', '1', '2', CURRENT_USER(), CURRENT_TIMESTAMP(), NULL, NULL) """) # バッチステータス管理テーブルを登録 db.execute(""" INSERT INTO internal07.jskult_batch_status_manage (process_name, process_date, process_type, process_status, total_run_count, max_run_count_flg) VALUES ('unittest_process_name', '2025-05-30', 'unittest_process_type', 'start', '0', '0'), ('jskult-batch-ultmarc-io', '2025-05-30','data_import', 'done', '0', '0') """) # Act sut = JskultBatchStatusManager( 'unittest_process_name', 'unittest_process_type', 3, 3 ) actual = sut.is_done_ultmarc_import() # Assert assert actual is True def test_is_done_ultmarc_import_failed(self): """ アルトマーク取込が完了していない場合、falseが返却されること """ # Arrange # 日付テーブルを登録 db = Database.get_instance() db.connect() db.execute(""" INSERT INTO src07.hdke_tbl (syor_date, bch_actf, dump_sts_kbn, creater, create_date, updater, update_date) VALUES ('20250530', '1', '2', CURRENT_USER(), CURRENT_TIMESTAMP(), NULL, NULL) """) # バッチステータス管理テーブルを登録 db.execute(""" INSERT INTO internal07.jskult_batch_status_manage (process_name, process_date, process_type, process_status, total_run_count, max_run_count_flg) VALUES ('unittest_process_name', '2025-05-30', 'unittest_process_type', 'start', '0', '0'), ('jskult-batch-ultmarc-io', '2025-05-30','data_import', 'start', '0', '0') """) # Act sut = JskultBatchStatusManager( 'unittest_process_name', 'unittest_process_type', 3, 3 ) actual = sut.is_done_ultmarc_import() # Assert assert actual is False