def test_check_concurrency(self): # Pipeline without concurrency defaults to infinite concurrency pipeline = PipelineFactory() pipeline_run = PipelineRunFactory(pipeline=pipeline) assert pipeline_run.check_concurrency() is True # Pipeline with concurrency and pipeline run with operation runs pipeline.concurrency = 2 pipeline.save() # No running operation runs assert pipeline_run.check_concurrency() is True # One operation run operation_run1 = OperationRunFactory(pipeline_run=pipeline_run) assert pipeline_run.check_concurrency() is True # One operation run with RUNNING status operation_run1.status = OperationStatuses.RUNNING operation_run1.save() assert pipeline_run.check_concurrency() is True # Second operation run operation_run2 = OperationRunFactory(pipeline_run=pipeline_run) assert pipeline_run.check_concurrency() is True # Second operation run with RUNNING status operation_run2.status = OperationStatuses.RUNNING operation_run2.save() assert pipeline_run.check_concurrency() is False
def test_pipeline_run_creation_sets_created_status(self): assert PipelineRunStatus.objects.count() == 0 # Assert `new_pipeline_run_status` task is also called pipeline_run = PipelineRunFactory() assert PipelineRunStatus.objects.filter( pipeline_run=pipeline_run).count() == 1 assert pipeline_run.last_status == PipelineLifeCycle.CREATED
def test_dag_property(self): pipeline_run = PipelineRunFactory() operation_runs = [ OperationRunFactory(pipeline_run=pipeline_run) for _ in range(4) ] operation_runs[0].upstream_runs.set(operation_runs[2:]) operation_runs[1].upstream_runs.set(operation_runs[2:]) operation_by_ids = {op.id: op for op in operation_runs} assert pipeline_run.dag == ({ operation_runs[0].id: set(), operation_runs[1].id: set(), operation_runs[2].id: {operation_runs[0].id, operation_runs[1].id}, operation_runs[3].id: {operation_runs[0].id, operation_runs[1].id}, }, operation_by_ids) # Add operations outside the dag operation_run1 = OperationRunFactory() operation_run1.downstream_runs.set( [operation_runs[1], operation_runs[2], operation_runs[3]]) operation_run2 = OperationRunFactory() operation_run2.upstream_runs.set( [operation_runs[0], operation_runs[2]]) assert pipeline_run.dag == ({ operation_runs[0].id: { operation_run2.id, }, operation_runs[1].id: set(), operation_runs[2].id: {operation_runs[0].id, operation_runs[1].id, operation_run2.id}, operation_runs[3].id: {operation_runs[0].id, operation_runs[1].id}, }, operation_by_ids)
def setUp(self): super().setUp() self.pipeline_run = PipelineRunFactory() self.tested_events = { pipeline_run_events.PIPELINE_RUN_CREATED, pipeline_run_events.PIPELINE_RUN_UPDATED, pipeline_run_events.PIPELINE_RUN_DELETED, pipeline_run_events.PIPELINE_RUN_CLEANED_TRIGGERED, pipeline_run_events.PIPELINE_RUN_VIEWED, pipeline_run_events.PIPELINE_RUN_ARCHIVED, pipeline_run_events.PIPELINE_RUN_RESTORED, pipeline_run_events.PIPELINE_RUN_DELETED_TRIGGERED, pipeline_run_events.PIPELINE_RUN_STOPPED, pipeline_run_events.PIPELINE_RUN_STOPPED_TRIGGERED, pipeline_run_events.PIPELINE_RUN_SKIPPED, pipeline_run_events.PIPELINE_RUN_SKIPPED_TRIGGERED, pipeline_run_events.PIPELINE_RUN_RESUMED, pipeline_run_events.PIPELINE_RUN_RESTARTED, pipeline_run_events.PIPELINE_RUN_RESTARTED_TRIGGERED, pipeline_run_events.PIPELINE_RUN_RESUMED_TRIGGERED, pipeline_run_events.PIPELINE_RUN_NEW_STATUS, pipeline_run_events.PIPELINE_RUN_SUCCEEDED, pipeline_run_events.PIPELINE_RUN_FAILED, pipeline_run_events.PIPELINE_RUN_DONE, }
def test_stopping_pipeline_run_stops_operation_runs(self): pipeline_run = PipelineRunFactory() for _ in range(2): OperationRunFactory(pipeline_run=pipeline_run) assert pipeline_run.statuses.count() == 1 assert pipeline_run.last_status == PipelineStatuses.CREATED assert OperationRunStatus.objects.filter().count() == 2 assert set(OperationRunStatus.objects.values_list( 'status', flat=True)) == {OperationStatuses.CREATED, } # Set pipeline run to stopped pipeline_run.on_stop() assert pipeline_run.statuses.count() == 2 assert pipeline_run.last_status == PipelineStatuses.STOPPED # Operation run are also stopped assert OperationRunStatus.objects.filter().count() == 4 assert set(OperationRunStatus.objects.values_list( 'status', flat=True)) == {OperationStatuses.CREATED, OperationStatuses.STOPPED}
def test_check_concurrency(self): # Pipeline without concurrency defaults to infinite concurrency pipeline = PipelineFactory() pipeline_run = PipelineRunFactory(pipeline=pipeline) assert pipeline_run.check_concurrency() is True # Pipeline with concurrency and pipeline run with operation runs pipeline.concurrency = 2 pipeline.save() # No running operation runs assert pipeline_run.check_concurrency() is True # One operation run operation_run1 = OperationRunFactory(pipeline_run=pipeline_run) assert pipeline_run.check_concurrency() is True # One operation run with RUNNING status OperationRunStatus.objects.create(status=OperationStatuses.RUNNING, operation_run=operation_run1) assert pipeline_run.check_concurrency() is True # Second operation run operation_run2 = OperationRunFactory(pipeline_run=pipeline_run) assert pipeline_run.check_concurrency() is True # Second operation run with RUNNING status OperationRunStatus.objects.create(status=OperationStatuses.RUNNING, operation_run=operation_run2) assert pipeline_run.check_concurrency() is False
def test_skipping_pipeline_run_stops_operation_runs(self): pipeline_run = PipelineRunFactory() for _ in range(2): op_run = OperationRunFactory(pipeline_run=pipeline_run) assert start_operation_run(op_run) is False assert pipeline_run.statuses.count() == 1 assert pipeline_run.last_status == PipelineLifeCycle.CREATED assert JobStatus.objects.filter().count() == 2 assert set(JobStatus.objects.values_list('status', flat=True)) == { OperationStatuses.CREATED, } # Set pipeline run to skipped with patch('scheduler.tasks.jobs.jobs_stop.apply_async' ) as spawner_mock_stop: pipeline_run.on_skip() assert pipeline_run.statuses.count() == 2 assert pipeline_run.last_status == PipelineLifeCycle.SKIPPED # Operation run are also skipped assert JobStatus.objects.filter().count( ) + spawner_mock_stop.call_count == 6 assert set(JobStatus.objects.values_list('status', flat=True)) == { OperationStatuses.CREATED, OperationStatuses.SKIPPED }