def test_public_url(create_url_mock, app, pipeline): create_url_mock.return_value = "http://example.com/presigned" pipeline_run = PipelineRun(sequence=1) pipeline.pipeline_runs.append(pipeline_run) artifact = PipelineRunArtifact(name="example.txt") pipeline_run.pipeline_run_artifacts.append(artifact) db.session.add(pipeline) db.session.commit() assert artifact.public_url() == "http://example.com/presigned"
def test_update_workflow_run_RUNNING_square(delay_mock, copy_mock, app, pipeline, workflow_square): (workflow_run, pipeline_runs) = _configure_run_state(workflow_square, RunStateEnum.COMPLETED, delay_mock) workflow_run.workflow_run_states.append( services.create_workflow_run_state(RunStateEnum.RUNNING)) assert workflow_run.run_state_enum() == RunStateEnum.RUNNING copy_mock.assert_has_calls([ call(pipeline_runs[0].pipeline_run_artifacts[0], pipeline_runs[1]), call(pipeline_runs[0].pipeline_run_artifacts[0], pipeline_runs[2]), ]) assert pipeline_runs[1].run_state_enum() == RunStateEnum.NOT_STARTED assert pipeline_runs[2].run_state_enum() == RunStateEnum.NOT_STARTED assert pipeline_runs[3].run_state_enum() == RunStateEnum.QUEUED assert delay_mock.call_count == 2 # when one of the second ones finishes - the third one gets its artifact, # but it doesn't start (b/c it needs artifacts from both!) delay_mock.reset_mock() copy_mock.reset_mock() pipeline_runs[1].pipeline_run_artifacts.append( PipelineRunArtifact(name="anotherfile.txt")) pipeline_runs[1].pipeline_run_states.append( create_pipeline_run_state(RunStateEnum.COMPLETED)) services.update_workflow_run(pipeline_runs[1]) assert workflow_run.run_state_enum() == RunStateEnum.RUNNING copy_mock.assert_called_once_with( pipeline_runs[1].pipeline_run_artifacts[0], pipeline_runs[3]) assert pipeline_runs[3].run_state_enum() == RunStateEnum.QUEUED # when the third one finishes - the fourth starts b/c it has all its inputs delay_mock.reset_mock() copy_mock.reset_mock() pipeline_runs[2].pipeline_run_artifacts.append( PipelineRunArtifact(name="anotherfile.txt")) pipeline_runs[2].pipeline_run_states.append( create_pipeline_run_state(RunStateEnum.COMPLETED)) services.update_workflow_run(pipeline_runs[2]) assert workflow_run.run_state_enum() == RunStateEnum.RUNNING copy_mock.assert_called_once_with( pipeline_runs[2].pipeline_run_artifacts[0], pipeline_runs[3]) assert pipeline_runs[3].run_state_enum() == RunStateEnum.NOT_STARTED # Finally, when the last run finishes, the workflow is finished delay_mock.reset_mock() copy_mock.reset_mock() pipeline_runs[3].pipeline_run_states.append( create_pipeline_run_state(RunStateEnum.COMPLETED)) services.update_workflow_run(pipeline_runs[3]) assert workflow_run.run_state_enum() == RunStateEnum.COMPLETED assert not copy_mock.called
def test_copy_pipeline_run_artifact( urlopen_mock, create_url_mock, upload_stream_mock, pipeline ): create_url_mock.return_value = "http://example.com/presigned" urlopen_mock.return_value = io.BytesIO(b"this is data") another_run = services.create_pipeline_run( pipeline.uuid, VALID_CALLBACK_INPUT, True ) pipeline_run = services.create_pipeline_run( pipeline.uuid, VALID_CALLBACK_INPUT, True ) artifact = PipelineRunArtifact(name="ex.csv", pipeline_run=pipeline_run) db.session.add(artifact) db.session.commit() services.copy_pipeline_run_artifact(artifact, another_run) assert len(another_run.pipeline_run_inputs) == 1 assert another_run.pipeline_run_inputs[0].filename == "ex.csv" assert another_run.pipeline_run_inputs[0].url == "http://example.com/presigned"
def _configure_run_state(workflow, run_state_enum, delay_mock): """ Update first PipelineRun to run_state_enum and call update_workflow_run() """ services.create_workflow_run( workflow.uuid, { "callback_url": "http://example.com/cb", "inputs": [], }, ) pipeline_runs = [ wpr.pipeline_run for wpr in workflow.workflow_runs[0].workflow_pipeline_runs ] pipeline_runs[0].pipeline_run_states.append( create_pipeline_run_state(run_state_enum)) pipeline_runs[0].pipeline_run_artifacts.append( PipelineRunArtifact(name="afile.txt")) db.session.commit() delay_mock.reset_mock() return (services.update_workflow_run(pipeline_runs[0]), pipeline_runs)
def test_update_workflow_run_RUNNING_line(delay_mock, copy_mock, app, pipeline, workflow_line): (workflow_run, pipeline_runs) = _configure_run_state(workflow_line, RunStateEnum.COMPLETED, delay_mock) workflow_run.workflow_run_states.append( services.create_workflow_run_state(RunStateEnum.RUNNING)) assert workflow_run.run_state_enum() == RunStateEnum.RUNNING copy_mock.assert_called_once_with( pipeline_runs[0].pipeline_run_artifacts[0], pipeline_runs[1]) assert pipeline_runs[1].run_state_enum() == RunStateEnum.NOT_STARTED assert pipeline_runs[2].run_state_enum() == RunStateEnum.QUEUED delay_mock.assert_called_once() # when the second run finished it'll start the last one delay_mock.reset_mock() copy_mock.reset_mock() pipeline_runs[1].pipeline_run_artifacts.append( PipelineRunArtifact(name="anotherfile.txt")) pipeline_runs[1].pipeline_run_states.append( create_pipeline_run_state(RunStateEnum.COMPLETED)) services.update_workflow_run(pipeline_runs[1]) assert workflow_run.run_state_enum() == RunStateEnum.RUNNING copy_mock.assert_called_once_with( pipeline_runs[1].pipeline_run_artifacts[0], pipeline_runs[2]) assert pipeline_runs[2].run_state_enum() == RunStateEnum.NOT_STARTED # Finally, when the last run finishes, the workflow is finished delay_mock.reset_mock() copy_mock.reset_mock() pipeline_runs[2].pipeline_run_states.append( create_pipeline_run_state(RunStateEnum.COMPLETED)) services.update_workflow_run(pipeline_runs[2]) assert workflow_run.run_state_enum() == RunStateEnum.COMPLETED assert not copy_mock.called
def test_get_pipeline_run(client, pipeline, client_application, mock_execute_pipeline): db.session.commit() pipeline_run = create_pipeline_run(pipeline.uuid, VALID_CALLBACK_INPUT) artifact = PipelineRunArtifact(name="test.pdf") artifact.public_url = Mock() artifact.public_url.return_value = "http://fake.example.com/url" pipeline_run.pipeline_run_artifacts.append(artifact) db.session.commit() result = client.get( "/v1/pipelines/no-id/runs/no-id", headers={ROLES_KEY: client_application.api_key}, ) assert result.status_code == 404 # no such pipeline_run_id result = client.get( f"/v1/pipelines/{pipeline.uuid}/runs/no-id", headers={ROLES_KEY: client_application.api_key}, ) assert result.status_code == 404 # successfully fetch a pipeline_run result = client.get( f"/v1/pipelines/{pipeline.uuid}/runs/{pipeline_run.uuid}", headers={ROLES_KEY: client_application.api_key}, ) assert result.status_code == 200 assert result.json == { "uuid": pipeline_run.uuid, "sequence": pipeline_run.sequence, "created_at": to_iso8601(pipeline_run.created_at), "inputs": [], "states": [ { "state": RunStateEnum.QUEUED.name, "created_at": to_iso8601(pipeline_run.pipeline_run_states[0].created_at), }, { "state": RunStateEnum.NOT_STARTED.name, "created_at": to_iso8601(pipeline_run.pipeline_run_states[1].created_at), }, ], "artifacts": [{ "uuid": artifact.uuid, "name": "test.pdf", "url": "http://fake.example.com/url", }], } # fails if the pipeline is deleted. pipeline.is_deleted = True db.session.commit() result = client.get( f"/v1/pipelines/{pipeline.uuid}/runs/{pipeline_run.uuid}", headers={ROLES_KEY: client_application.api_key}, ) assert result.status_code == 404