From df06b43c3c6dd67063a973f3472c4556816c000a Mon Sep 17 00:00:00 2001 From: ChristianOertlin Date: Tue, 3 Sep 2024 10:07:11 +0200 Subject: [PATCH] fix(new delivery service calls in CLI) (#3673) # description add new service to cli --- cg/cli/deliver/base.py | 210 ++++++---------- cg/constants/delivery.py | 8 + cg/constants/process.py | 1 + .../deliver_files_service.py | 43 +++- .../deliver_files_service_factory.py | 15 +- tests/cli/deliver/test_deliver_base.py | 80 +------ tests/cli/deliver/test_rsync_base.py | 3 - tests/cli/deliver/test_run_deliver_cmd.py | 224 ++---------------- .../test_delivery_file_service_builder.py | 8 +- 9 files changed, 161 insertions(+), 431 deletions(-) diff --git a/cg/cli/deliver/base.py b/cg/cli/deliver/base.py index f7abd498d7..74106751d5 100644 --- a/cg/cli/deliver/base.py +++ b/cg/cli/deliver/base.py @@ -8,42 +8,27 @@ from cg.apps.tb import TrailblazerAPI from cg.cli.utils import CLICK_CONTEXT_SETTINGS from cg.constants.cli_options import DRY_RUN -from cg.constants.delivery import PIPELINE_ANALYSIS_OPTIONS, PIPELINE_ANALYSIS_TAG_MAP -from cg.meta.deliver import DeliverAPI, DeliverTicketAPI +from cg.constants.delivery import FileDeliveryOption from cg.meta.rsync.rsync_api import RsyncAPI from cg.models.cg_config import CGConfig -from cg.services.fastq_concatenation_service.fastq_concatenation_service import ( - FastqConcatenationService, +from cg.services.file_delivery.deliver_files_service.deliver_files_service import ( + DeliverFilesService, +) +from cg.services.file_delivery.deliver_files_service.deliver_files_service_factory import ( + DeliveryServiceFactory, ) from cg.store.models import Case -from cg.store.store import Store LOG = logging.getLogger(__name__) DELIVERY_TYPE = click.option( "-d", "--delivery-type", - multiple=True, - type=click.Choice(PIPELINE_ANALYSIS_OPTIONS), - required=True, -) -FORCE_ALL = click.option( - "--force-all", - help=( - "Force delivery of all sample files " - "- disregarding of amount of reads or previous deliveries" - ), - is_flag=True, -) -TICKET_ID_ARG = click.argument("ticket", type=str, required=True) - -IGNORE_MISSING_BUNDLES = click.option( - "-i", - "--ignore-missing-bundles", - help="Ignore errors due to missing case bundles", - is_flag=True, - default=False, + multiple=False, + type=click.Choice(choices=[option for option in FileDeliveryOption]), + required=False, ) +TICKET_ID_ARG = click.option("-t", "--ticket", type=str, required=True) @click.group(context_settings=CLICK_CONTEXT_SETTINGS) @@ -52,74 +37,10 @@ def deliver(): LOG.info("Running CG deliver") -@deliver.command(name="analysis") -@DRY_RUN -@DELIVERY_TYPE -@click.option("-c", "--case-id", help="Deliver the files for a specific case") -@click.option( - "-t", "--ticket", type=str, help="Deliver the files for ALL cases connected to a ticket" -) -@FORCE_ALL -@IGNORE_MISSING_BUNDLES -@click.pass_obj -def deliver_analysis( - context: CGConfig, - case_id: str | None, - ticket: str | None, - delivery_type: list[str], - dry_run: bool, - force_all: bool, - ignore_missing_bundles: bool, -): - """Deliver analysis files to customer inbox - - Files can be delivered either on case level or for all cases connected to a ticket. - Any of those needs to be specified. - """ - if not (case_id or ticket): - LOG.info("Please provide a case-id or ticket-id") - return - - inbox: str = context.delivery_path - if not inbox: - LOG.info("Please specify the root path for where files should be delivered") - return - - status_db: Store = context.status_db - for delivery in delivery_type: - deliver_api = DeliverAPI( - store=status_db, - hk_api=context.housekeeper_api, - case_tags=PIPELINE_ANALYSIS_TAG_MAP[delivery]["case_tags"], - sample_tags=PIPELINE_ANALYSIS_TAG_MAP[delivery]["sample_tags"], - project_base_path=Path(inbox), - delivery_type=delivery, - force_all=force_all, - ignore_missing_bundles=ignore_missing_bundles, - fastq_file_service=FastqConcatenationService(), - ) - deliver_api.set_dry_run(dry_run) - cases: list[Case] = [] - if case_id: - case_obj: Case = status_db.get_case_by_internal_id(internal_id=case_id) - if not case_obj: - LOG.warning(f"Could not find case {case_id}") - return - cases.append(case_obj) - else: - cases: list[Case] = status_db.get_cases_by_ticket_id(ticket_id=ticket) - if not cases: - LOG.warning(f"Could not find cases for ticket {ticket}") - return - - for case_obj in cases: - deliver_api.deliver_files(case_obj=case_obj) - - @deliver.command(name="rsync") -@DRY_RUN -@TICKET_ID_ARG @click.pass_obj +@TICKET_ID_ARG +@DRY_RUN def rsync(context: CGConfig, ticket: str, dry_run: bool): """The folder generated using the "cg deliver analysis" command will be rsynced with this function to the customers inbox on the delivery server @@ -133,60 +54,77 @@ def rsync(context: CGConfig, ticket: str, dry_run: bool): ) -@deliver.command(name="concatenate") +@deliver.command(name="case") +@click.pass_obj +@click.option( + "-c", + "--case-id", + required=True, + help="Deliver the files for a specific case", +) +@DELIVERY_TYPE @DRY_RUN -@TICKET_ID_ARG -@click.pass_context -def concatenate(context: click.Context, ticket: str, dry_run: bool): - """The fastq files in the folder generated using "cg deliver analysis" - will be concatenated into one forward and one reverse fastq file +def deliver_case( + context: CGConfig, + case_id: str, + delivery_type: FileDeliveryOption, + dry_run: bool, +): """ - cg_context: CGConfig = context.obj - deliver_ticket_api = DeliverTicketAPI(config=cg_context) - deliver_ticket_api.concatenate_fastq_files(ticket=ticket, dry_run=dry_run) + Deliver all case files based on delivery type to the customer inbox on the HPC + """ + inbox: str = context.delivery_path + rsync_api: RsyncAPI = RsyncAPI(config=context) + service_builder = DeliveryServiceFactory( + store=context.status_db, + hk_api=context.housekeeper_api, + tb_service=context.trailblazer_api, + rsync_service=rsync_api, + ) + case: Case = context.status_db.get_case_by_internal_id(internal_id=case_id) + if not case: + LOG.error(f"Could not find case with id {case_id}") + return + delivery_service: DeliverFilesService = service_builder.build_delivery_service( + delivery_type=delivery_type if delivery_type else case.data_delivery, + workflow=case.workflow, + ) + delivery_service.deliver_files_for_case( + case=case, delivery_base_path=Path(inbox), dry_run=dry_run + ) @deliver.command(name="ticket") +@click.pass_obj +@TICKET_ID_ARG @DELIVERY_TYPE @DRY_RUN -@FORCE_ALL -@IGNORE_MISSING_BUNDLES -@click.option( - "-t", - "--ticket", - type=str, - help="Deliver and rsync the files for ALL cases connected to a ticket", - required=True, -) -@click.pass_context def deliver_ticket( - context: click.Context, - delivery_type: list[str], - dry_run: bool, - force_all: bool, + context: CGConfig, ticket: str, - ignore_missing_bundles: bool, + delivery_type: FileDeliveryOption, + dry_run: bool, ): - """Will first collect hard links in the customer inbox then - concatenate fastq files if needed and finally send the folder - from customer inbox hasta to the customer inbox on the delivery server """ - cg_context: CGConfig = context.obj - deliver_ticket_api = DeliverTicketAPI(config=cg_context) - is_upload_needed = deliver_ticket_api.check_if_upload_is_needed(ticket=ticket) - if is_upload_needed or force_all: - LOG.info("Delivering files to customer inbox on the HPC") - context.invoke( - deliver_analysis, - delivery_type=delivery_type, - dry_run=dry_run, - force_all=force_all, - ticket=ticket, - ignore_missing_bundles=ignore_missing_bundles, - ) - else: - LOG.info("Files already delivered to customer inbox on the HPC") - return + Deliver all case files based on delivery type to the customer inbox on the HPC for cases connected to a ticket. + """ + inbox: str = context.delivery_path + rsync_api: RsyncAPI = RsyncAPI(config=context) + service_builder = DeliveryServiceFactory( + store=context.status_db, + hk_api=context.housekeeper_api, + tb_service=context.trailblazer_api, + rsync_service=rsync_api, + ) - deliver_ticket_api.report_missing_samples(ticket=ticket, dry_run=dry_run) - context.invoke(rsync, ticket=ticket, dry_run=dry_run) + cases: list[Case] = context.status_db.get_cases_by_ticket_id(ticket_id=ticket) + if not cases: + LOG.error(f"Could not find case connected to ticket {ticket}") + return + delivery_service: DeliverFilesService = service_builder.build_delivery_service( + delivery_type=delivery_type if delivery_type else cases[0].data_delivery, + workflow=cases[0].workflow, + ) + delivery_service.deliver_files_for_ticket( + ticket_id=ticket, delivery_base_path=Path(inbox), dry_run=dry_run + ) diff --git a/cg/constants/delivery.py b/cg/constants/delivery.py index e3c04ae1fc..5c1166546a 100644 --- a/cg/constants/delivery.py +++ b/cg/constants/delivery.py @@ -1,5 +1,7 @@ """Constants for delivery.""" +from enum import StrEnum + from cg.constants.constants import Workflow from cg.constants.housekeeper_tags import ( AlignmentFileTag, @@ -206,3 +208,9 @@ INBOX_NAME: str = "inbox" OUTBOX_NAME: str = "outbox" + + +class FileDeliveryOption(StrEnum): + FASTQ: str = "fastq" + ANALYSIS: str = "analysis" + FASTQ_ANALYSIS: str = "fastq-analysis" diff --git a/cg/constants/process.py b/cg/constants/process.py index 58c17ddecd..c2793f0581 100644 --- a/cg/constants/process.py +++ b/cg/constants/process.py @@ -3,3 +3,4 @@ EXIT_SUCCESS = 0 EXIT_WARNING = 8 EXIT_FAIL = 1 +EXIT_PARSE_ERROR = 2 diff --git a/cg/services/file_delivery/deliver_files_service/deliver_files_service.py b/cg/services/file_delivery/deliver_files_service/deliver_files_service.py index 977a49dbb2..7b9e4b9d35 100644 --- a/cg/services/file_delivery/deliver_files_service/deliver_files_service.py +++ b/cg/services/file_delivery/deliver_files_service/deliver_files_service.py @@ -1,4 +1,7 @@ from pathlib import Path + +from cg.apps.tb import TrailblazerAPI +from cg.meta.rsync import RsyncAPI from cg.services.file_delivery.fetch_file_service.fetch_delivery_files_service import ( FetchDeliveryFilesService, ) @@ -9,6 +12,9 @@ from cg.services.file_delivery.move_files_service.move_delivery_files_service import ( MoveDeliveryFilesService, ) +from cg.store.exc import EntryNotFoundError +from cg.store.models import Case +from cg.store.store import Store class DeliverFilesService: @@ -24,15 +30,46 @@ def __init__( delivery_file_manager_service: FetchDeliveryFilesService, move_file_service: MoveDeliveryFilesService, file_formatter_service: DeliveryFileFormattingService, + rsync_service: RsyncAPI, + tb_service: TrailblazerAPI, + status_db: Store, ): self.file_manager = delivery_file_manager_service self.file_mover = move_file_service self.file_formatter = file_formatter_service + self.status_db = status_db + self.rsync_service = rsync_service + self.tb_service = tb_service - def deliver_files_for_case(self, case_id: str, delivery_base_path: Path) -> None: - """Deliver the files to the customer folder.""" - delivery_files: DeliveryFiles = self.file_manager.get_files_to_deliver(case_id) + def deliver_files_for_case( + self, case: Case, delivery_base_path: Path, dry_run: bool = False + ) -> None: + """Deliver the files for a case to the customer folder.""" + delivery_files: DeliveryFiles = self.file_manager.get_files_to_deliver( + case_id=case.internal_id + ) moved_files: DeliveryFiles = self.file_mover.move_files( delivery_files=delivery_files, delivery_base_path=delivery_base_path ) self.file_formatter.format_files(moved_files) + slurm_id: int = self.rsync_service.run_rsync_on_slurm( + ticket=case.latest_ticket, dry_run=dry_run + ) + self.rsync_service.add_to_trailblazer_api( + tb_api=self.tb_service, + slurm_job_id=slurm_id, + ticket=case.latest_ticket, + dry_run=dry_run, + ) + + def deliver_files_for_ticket( + self, ticket_id: str, delivery_base_path: Path, dry_run: bool = False + ) -> None: + """Deliver the files for all cases in a ticket to the customer folder.""" + cases: list[Case] = self.status_db.get_cases_by_ticket_id(ticket_id) + if not cases: + raise EntryNotFoundError(f"No cases found for ticket {ticket_id}") + for case in cases: + self.deliver_files_for_case( + case=case, delivery_base_path=delivery_base_path, dry_run=dry_run + ) diff --git a/cg/services/file_delivery/deliver_files_service/deliver_files_service_factory.py b/cg/services/file_delivery/deliver_files_service/deliver_files_service_factory.py index 77c971855c..d57bc0464e 100644 --- a/cg/services/file_delivery/deliver_files_service/deliver_files_service_factory.py +++ b/cg/services/file_delivery/deliver_files_service/deliver_files_service_factory.py @@ -1,7 +1,9 @@ """Module for the factory of the deliver files service.""" from cg.apps.housekeeper.hk import HousekeeperAPI +from cg.apps.tb import TrailblazerAPI from cg.constants import Workflow, DataDelivery +from cg.meta.rsync import RsyncAPI from cg.services.fastq_concatenation_service.fastq_concatenation_service import ( FastqConcatenationService, ) @@ -51,9 +53,17 @@ class DeliveryServiceFactory: """Class to build the delivery services based on workflow and delivery type.""" - def __init__(self, store: Store, hk_api: HousekeeperAPI): + def __init__( + self, + store: Store, + hk_api: HousekeeperAPI, + rsync_service: RsyncAPI, + tb_service: TrailblazerAPI, + ): self.store = store self.hk_api = hk_api + self.rsync_service = rsync_service + self.tb_service = tb_service @staticmethod def _get_file_tag_fetcher(delivery_type: DataDelivery) -> FetchDeliveryFileTagsService: @@ -103,4 +113,7 @@ def build_delivery_service( delivery_file_manager_service=file_fetcher, move_file_service=MoveDeliveryFilesService(), file_formatter_service=file_formatter, + status_db=self.store, + rsync_service=self.rsync_service, + tb_service=self.tb_service, ) diff --git a/tests/cli/deliver/test_deliver_base.py b/tests/cli/deliver/test_deliver_base.py index 553192689b..6114588d56 100644 --- a/tests/cli/deliver/test_deliver_base.py +++ b/tests/cli/deliver/test_deliver_base.py @@ -6,7 +6,6 @@ from cg.cli.deliver.base import deliver as deliver_cmd from cg.constants import EXIT_SUCCESS -from cg.meta.deliver import DeliverTicketAPI from cg.models.cg_config import CGConfig @@ -29,12 +28,10 @@ def test_run_deliver_analysis_help(cli_runner: CliRunner, base_context: CGConfig # GIVEN a context with store and housekeeper information # WHEN running cg deliver help - result = cli_runner.invoke(deliver_cmd, ["analysis", "--help"], obj=base_context) + result = cli_runner.invoke(deliver_cmd, ["case", "--help"], obj=base_context) # THEN assert the command exists without problems assert result.exit_code == EXIT_SUCCESS - # THEN assert the information is printed - assert "Deliver analysis files to customer inbox" in result.output def test_run_deliver_ticket_help(cli_runner: CliRunner, base_context: CGConfig): @@ -45,87 +42,20 @@ def test_run_deliver_ticket_help(cli_runner: CliRunner, base_context: CGConfig): # WHEN running cg deliver help result = cli_runner.invoke(deliver_cmd, ["ticket", "--help"], obj=base_context) - # THEN assert the command exists without problems - assert result.exit_code == EXIT_SUCCESS - # THEN assert the information is printed - assert "Will first collect hard links" in result.output - - -def test_run_deliver_delivered_ticket( - cli_runner: CliRunner, cg_context: CGConfig, mocker, caplog, ticket_id -): - """Test for when files are already delivered to customer inbox the HPC""" - caplog.set_level(logging.INFO) - - # GIVEN a cli runner - - # GIVEN uploading data to the delivery server is not needed - mocker.patch.object(DeliverTicketAPI, "check_if_upload_is_needed") - DeliverTicketAPI.check_if_upload_is_needed.return_value = False - - # WHEN running cg deliver ticket - result = cli_runner.invoke( - deliver_cmd, - ["ticket", "--dry-run", "--ticket", ticket_id, "--delivery-type", "fastq"], - obj=cg_context, - ) - # THEN assert the command exists without problems assert result.exit_code == EXIT_SUCCESS - # THEN assert that files are already delivered to the customer inbox on the HPC - assert "Files already delivered to customer inbox on the HPC" in caplog.text - -def test_deliver_ticket_with_force_all_flag( - cli_runner: CliRunner, cg_context: CGConfig, mocker, caplog, ticket_id -): - """Test that when the --force-all flag is used, - the files are delivered to the customer inbox on the HPC""" - caplog.set_level(logging.INFO) - - # GIVEN a cli runner - - # GIVEN uploading data to the delivery server is not needed - mocker.patch.object(DeliverTicketAPI, "check_if_upload_is_needed") - DeliverTicketAPI.check_if_upload_is_needed.return_value = False - - # WHEN running cg deliver ticket with --force-all flag - cli_runner.invoke( - deliver_cmd, - [ - "ticket", - "--dry-run", - "--ticket", - ticket_id, - "--delivery-type", - "fastq", - "--force-all", - ], - obj=cg_context, - ) - - # THEN assert that the text is not present in the log - assert "Files already delivered to customer inbox on the HPC" not in caplog.text - assert "Delivering files to customer inbox on the HPC" in caplog.text - - -def test_run_deliver_ticket(cli_runner: CliRunner, cg_context: CGConfig, mocker, caplog, ticket_id): +def test_run_deliver_ticket(cli_runner: CliRunner, cg_context: CGConfig, ticket_id): """Test for delivering tu customer inbox""" - caplog.set_level(logging.INFO) - # GIVEN a cli runner - # GIVEN uploading data to the delivery server is needed - mocker.patch.object(DeliverTicketAPI, "check_if_upload_is_needed") - DeliverTicketAPI.check_if_upload_is_needed.return_value = True - # WHEN running cg deliver ticket - cli_runner.invoke( + result = cli_runner.invoke( deliver_cmd, - ["ticket", "--dry-run", "--ticket", ticket_id, "--delivery-type", "fastq"], + ["ticket", "--dry-run", "--ticket", ticket_id], obj=cg_context, ) # THEN assert that files are delivered - assert "Delivering files to customer inbox on the HPC" in caplog.text + assert result.exit_code == EXIT_SUCCESS diff --git a/tests/cli/deliver/test_rsync_base.py b/tests/cli/deliver/test_rsync_base.py index a7221b6af4..32fc362d8b 100644 --- a/tests/cli/deliver/test_rsync_base.py +++ b/tests/cli/deliver/test_rsync_base.py @@ -31,6 +31,3 @@ def test_run_rsync_command_no_case(cg_context: CGConfig, cli_runner, helpers, ca # THEN command failed successfully assert result.exit_code != EXIT_SUCCESS - - # THEN process generates error message that case cant be found - assert "Could not find any cases for ticket" in caplog.text diff --git a/tests/cli/deliver/test_run_deliver_cmd.py b/tests/cli/deliver/test_run_deliver_cmd.py index bd6b3f2d49..96cd9b1624 100644 --- a/tests/cli/deliver/test_run_deliver_cmd.py +++ b/tests/cli/deliver/test_run_deliver_cmd.py @@ -5,244 +5,50 @@ from click.testing import CliRunner -from cg.cli.deliver.base import deliver_analysis, deliver_ticket -from cg.constants.process import EXIT_SUCCESS +from cg.cli.deliver.base import deliver_case, deliver_ticket +from cg.constants.process import EXIT_SUCCESS, EXIT_FAIL, EXIT_PARSE_ERROR from cg.models.cg_config import CGConfig from cg.store.store import Store def test_run_deliver_with_help(cli_runner: CliRunner, base_context: CGConfig): # GIVEN a cli runner and a base context + # WHEN running the deliver command with help text - result = cli_runner.invoke(deliver_analysis, ["--help"], obj=base_context) + result = cli_runner.invoke(deliver_case, ["--help"], obj=base_context) # THEN assert the command exits without problems assert result.exit_code == 0 - # THEN assert that the help text is displayed - assert "Deliver analysis files to customer inbox" in result.output -def test_run_deliver_without_specifying_case_or_ticket( - cli_runner: CliRunner, base_context: CGConfig, caplog -): +def test_run_deliver_without_specifying_case(cli_runner: CliRunner, base_context: CGConfig, caplog): caplog.set_level(logging.INFO) # GIVEN a cli runner and a base context # WHEN running the deliver command with help text - result = cli_runner.invoke(deliver_analysis, ["--delivery-type", "mip-dna"], obj=base_context) + result = cli_runner.invoke(deliver_case, obj=base_context) # THEN assert the command exits without problems - assert result.exit_code == 0 - # THEN assert that the help text is displayed - assert "Please provide a case-id or ticket-id" in caplog.text + assert result.exit_code == EXIT_PARSE_ERROR def test_run_deliver_non_existing_case( - cli_runner: CliRunner, base_context: CGConfig, case_id: str, caplog + cli_runner: CliRunner, + cg_context: CGConfig, + case_id: str, ): """Test to run the deliver command when the provided case does not exist""" - caplog.set_level(logging.WARNING) # GIVEN a cli runner and a base context + # GIVEN a case_id that does not exist in the database - store: Store = base_context.status_db + store: Store = cg_context.status_db assert store.get_case_by_internal_id(internal_id=case_id) is None # WHEN running the deliver command with the non existing case result = cli_runner.invoke( - deliver_analysis, - ["--case-id", case_id, "--delivery-type", "mip-dna"], - obj=base_context, + deliver_case, + ["--case-id", case_id], + obj=cg_context, ) # THEN assert the command exits without problems assert result.exit_code == 0 - # THEN assert that the correct warning is displayed - assert f"Could not find case {case_id}" in caplog.text - - -def test_delivery_with_dry_run( - cli_runner: CliRunner, - populated_mip_context: CGConfig, - case_id: str, - delivery_inbox: Path, - caplog, -): - """Test to run the delivery command with dry run enabled""" - caplog.set_level(logging.DEBUG) - # GIVEN a cli runner - # GIVEN a context with a case that have files in housekeeper to deliver - # GIVEN that the delivery path does not exist - assert delivery_inbox.exists() is False - - # WHEN running the deliver analysis command in dry run mode - cli_runner.invoke( - deliver_analysis, - ["--case-id", case_id, "--delivery-type", "mip-dna", "--dry-run"], - obj=populated_mip_context, - ) - - # THEN assert that the path to the delivery folder was not created - assert delivery_inbox.exists() is False - - # THEN assert that it is communicated that at least one file would be linked - assert "Would hard link file" in caplog.text - - -def test_delivery_path_created( - cli_runner: CliRunner, populated_mip_context: CGConfig, case_id: str, delivery_inbox: Path -): - """Test that the delivery path is created when running the deliver analysis command""" - # GIVEN a context with a case that have files in housekeeper to deliver - # GIVEN a cli runner - # GIVEN that the delivery file does not exist - assert delivery_inbox.exists() is False - - # WHEN running the deliver analysis command - cli_runner.invoke( - deliver_analysis, - ["--case-id", case_id, "--delivery-type", "mip-dna"], - obj=populated_mip_context, - ) - - # THEN assert that the path to the delivery folder was created - assert delivery_inbox.exists() is True - - -def test_delivery_ticket_id( - cli_runner: CliRunner, - populated_mip_context: CGConfig, - delivery_inbox: Path, - ticket_id: str, -): - """Test that to run the deliver command with ticket nr""" - # GIVEN a context with a case that have files in housekeeper to deliver - # GIVEN a cli runner - # GIVEN that the delivery file does not exist - assert delivery_inbox.exists() is False - - # WHEN running the deliver analysis command - cli_runner.invoke( - deliver_analysis, - ["--ticket", ticket_id, "--delivery-type", "mip-dna"], - obj=populated_mip_context, - ) - - # THEN assert that the path to the delivery folder was created - assert delivery_inbox.exists() is True - - -def test_run_deliver_multiple_delivery_flags( - cli_runner: CliRunner, - populated_mip_context: CGConfig, - case_id: str, - deliver_vcf_path: Path, - deliver_fastq_path: Path, - caplog, -): - """Test to run the deliver command when the provided case does not exist""" - caplog.set_level(logging.WARNING) - # GIVEN a context with a case that has files and a sample with a file, in housekeeper to deliver - # GIVEN a cli runner - # WHEN running the deliver command with multiple delivery flags - - assert deliver_vcf_path.exists() is False - assert deliver_fastq_path.exists() is False - - result = cli_runner.invoke( - deliver_analysis, - ["--case-id", case_id, "--delivery-type", "fastq", "--delivery-type", "mip-dna"], - obj=populated_mip_context, - ) - - # THEN assert the command exits without problems - assert result.exit_code == 0 - # THEN assert that the case file was delivered to the inbox - assert deliver_vcf_path.exists() is True - # THEN assert that the sample file was delivered to the inbox - assert deliver_fastq_path.exists() is True - - -def test_case_file_is_delivered( - populated_mip_context: CGConfig, case_id: str, deliver_vcf_path: Path, cli_runner: CliRunner -): - """Test that the a case file is delivered when running the delivery command""" - # GIVEN a context with a case that have files in housekeeper to deliver - # GIVEN a cli runner - # GIVEN that a case vcf does not exist - assert deliver_vcf_path.exists() is False - - # WHEN running the deliver analysis command - cli_runner.invoke( - deliver_analysis, - ["--case-id", case_id, "--delivery-type", "mip-dna"], - obj=populated_mip_context, - ) - - # THEN assert that the case file was delivered to the inbox - assert deliver_vcf_path.exists() is True - - -def test_delivering_analysis_with_missing_bundle_errors( - cli_runner: CliRunner, - context_with_missing_bundle: CGConfig, - ticket_id: str, -): - """Test that the deliver command fails when a bundle is missing.""" - # GIVEN a context with a case that does not have files in housekeeper to deliver. - # GIVEN a cli runner - # WHEN running the deliver analysis command - result = cli_runner.invoke( - deliver_analysis, - ["--ticket", ticket_id, "--delivery-type", "mip-dna"], - obj=context_with_missing_bundle, - ) - - # THEN assert that the command failed - assert result.exit_code is not EXIT_SUCCESS - - -def test_delivering_analysis_with_missing_bundle_ignoring_errors( - cli_runner: CliRunner, - context_with_missing_bundle: CGConfig, - delivery_inbox: Path, - ticket_id: str, -): - """Test that it is possible to deliver analysis with a missing bundle using the --ignore-missing-bundles flag.""" - # GIVEN a context without files in housekeeper to deliver. - # GIVEN a cli runner - # GIVEN that the delivery file does not exist - assert delivery_inbox.exists() is False - - # WHEN running the deliver analysis command - cli_runner.invoke( - deliver_analysis, - ["--ticket", ticket_id, "--ignore-missing-bundles", "--delivery-type", "mip-dna"], - obj=context_with_missing_bundle, - ) - - # THEN assert that the path to the delivery folder was created - assert delivery_inbox.exists() is True - - -def test_deliver_ticket_with_missing_bundle( - cli_runner: CliRunner, context_with_missing_bundle: CGConfig, caplog, ticket_id -): - caplog.set_level(logging.INFO) - - # GIVEN a cli runner - # WHEN running cg deliver ticket - result = cli_runner.invoke( - deliver_ticket, - [ - "--ticket", - ticket_id, - "--dry-run", - "--ignore-missing-bundles", - "--delivery-type", - "mip-dna", - ], - obj=context_with_missing_bundle, - ) - - # THEN assert that the command succeeded and files are delivered - assert result.exit_code is EXIT_SUCCESS - assert "Delivering files to customer inbox on the HPC" in caplog.text diff --git a/tests/services/file_delivery/delivery_file_service/test_delivery_file_service_builder.py b/tests/services/file_delivery/delivery_file_service/test_delivery_file_service_builder.py index 1965b0a31a..4739beea62 100644 --- a/tests/services/file_delivery/delivery_file_service/test_delivery_file_service_builder.py +++ b/tests/services/file_delivery/delivery_file_service/test_delivery_file_service_builder.py @@ -1,5 +1,5 @@ import pytest -from unittest.mock import MagicMock, patch +from unittest.mock import MagicMock from cg.constants import Workflow, DataDelivery from cg.services.file_delivery.deliver_files_service.deliver_files_service import ( @@ -69,9 +69,9 @@ def test_build_delivery_service( expected_sample_file_formatter, ): # GIVEN a delivery service builder with mocked store and hk_api - store_mock = MagicMock() - hk_api_mock = MagicMock() - builder = DeliveryServiceFactory(store=store_mock, hk_api=hk_api_mock) + builder = DeliveryServiceFactory( + store=MagicMock(), hk_api=MagicMock(), rsync_service=MagicMock(), tb_service=MagicMock() + ) # WHEN building a delivery service delivery_service: DeliverFilesService = builder.build_delivery_service(