@@ -8487,3 +8487,96 @@ def test_run_workflow_use_cached_job_format_source_pick_param(self):
84878487 ).strip ()
84888488 == "2"
84898489 )
8490+
8491+ def test_run_workflow_use_cached_job_implicit_conversion_send_to_new_history (self ):
8492+ wf = """class: GalaxyWorkflow
8493+ inputs:
8494+ fastq_input:
8495+ type: data
8496+ steps:
8497+ grep:
8498+ # Grep1 requires fastqsanger, so fastqsanger.gz will be implicitly converted
8499+ tool_id: Grep1
8500+ in:
8501+ input: fastq_input
8502+ """
8503+ with self .dataset_populator .test_history () as history_id :
8504+ # Create a fastqsanger.gz dataset
8505+ compressed_path = self .test_data_resolver .get_filename ("1.fastqsanger.gz" )
8506+ with open (compressed_path , "rb" ) as fh :
8507+ dataset = self .dataset_populator .new_dataset (
8508+ history_id , content = fh , file_type = "fastqsanger.gz" , wait = True
8509+ )
8510+
8511+ # Upload workflow
8512+ workflow_id = self .workflow_populator .upload_yaml_workflow (wf )
8513+
8514+ # Run workflow first time
8515+ workflow_request : Dict [str , Any ] = {
8516+ "inputs" : json .dumps ({"fastq_input" : self ._ds_entry (dataset )}),
8517+ "history" : f"hist_id={ history_id } " ,
8518+ "inputs_by" : "name" ,
8519+ }
8520+ first_invocation_summary = self .workflow_populator .invoke_workflow_and_wait (
8521+ workflow_id , request = workflow_request
8522+ ).json ()
8523+ self .workflow_populator .wait_for_invocation_and_jobs (
8524+ history_id = first_invocation_summary ["history_id" ],
8525+ workflow_id = workflow_id ,
8526+ invocation_id = first_invocation_summary ["id" ],
8527+ assert_ok = True ,
8528+ )
8529+ first_invocation = self .workflow_populator .get_invocation (first_invocation_summary ["id" ], step_details = True )
8530+ first_job_id = first_invocation ["steps" ][1 ]["jobs" ][0 ]["id" ]
8531+ first_job_details = self .dataset_populator .get_job_details (first_job_id , full = True ).json ()
8532+ assert first_job_details ["state" ] == "ok"
8533+ assert not first_job_details ["copied_from_job_id" ]
8534+
8535+ # Verify implicit conversion happened (input to Grep1 should be fastqsanger, not fastqsanger.gz)
8536+ grep_input_id = first_job_details ["inputs" ]["input" ]["id" ]
8537+ grep_input = self .dataset_populator .get_history_dataset_details (
8538+ history_id = first_job_details ["history_id" ], content_id = grep_input_id
8539+ )
8540+ assert grep_input ["extension" ] == "fastqsanger" , "Expected implicit conversion to fastqsanger"
8541+ assert grep_input_id != dataset ["id" ], "Input should be implicitly converted dataset"
8542+
8543+ # Run workflow second time with use_cached_job and new_history_name
8544+ # Remove history parameter since we're specifying new_history_name
8545+ workflow_request .pop ("history" , None )
8546+ workflow_request ["use_cached_job" ] = True
8547+ workflow_request ["new_history_name" ] = self .dataset_populator .get_random_name ()
8548+ second_invocation_response = self .workflow_populator .invoke_workflow (workflow_id , request = workflow_request )
8549+ second_invocation_summary = second_invocation_response .json ()
8550+ second_history_id = second_invocation_summary ["history_id" ]
8551+ # Wait for the workflow to complete
8552+ self .workflow_populator .wait_for_invocation_and_jobs (
8553+ history_id = second_history_id ,
8554+ workflow_id = workflow_id ,
8555+ invocation_id = second_invocation_summary ["id" ],
8556+ assert_ok = True ,
8557+ )
8558+ second_invocation = self .workflow_populator .get_invocation (
8559+ second_invocation_summary ["id" ], step_details = True
8560+ )
8561+ second_job_id = second_invocation ["steps" ][1 ]["jobs" ][0 ]["id" ]
8562+ second_job_details = self .dataset_populator .get_job_details (second_job_id , full = True ).json ()
8563+
8564+ # Verify job was cached
8565+ assert second_job_details ["state" ] == "ok"
8566+ assert second_job_details ["copied_from_job_id" ] == first_job_id , "Second job should be cached from first"
8567+
8568+ # Verify the second invocation is in a different history
8569+ assert (
8570+ second_job_details ["history_id" ] != first_job_details ["history_id" ]
8571+ ), "Second invocation should be in a new history"
8572+
8573+ # Verify implicit conversion dataset was copied to the new history
8574+ cached_grep_input_id = second_job_details ["inputs" ]["input" ]["id" ]
8575+ cached_grep_input = self .dataset_populator .get_history_dataset_details (
8576+ history_id = second_job_details ["history_id" ], content_id = cached_grep_input_id
8577+ )
8578+ assert cached_grep_input ["extension" ] == "fastqsanger"
8579+ # The implicitly converted dataset should have a different HDA ID but same underlying dataset
8580+ assert (
8581+ cached_grep_input_id != grep_input_id
8582+ ), "Cached run should have copied the implicitly converted dataset to the new history"
0 commit comments