summaryrefslogtreecommitdiff
path: root/spec/services/ci/pipeline_processing
diff options
context:
space:
mode:
Diffstat (limited to 'spec/services/ci/pipeline_processing')
-rw-r--r--spec/services/ci/pipeline_processing/atomic_processing_service/status_collection_spec.rb15
-rw-r--r--spec/services/ci/pipeline_processing/atomic_processing_service_spec.rb6
-rw-r--r--spec/services/ci/pipeline_processing/legacy_processing_service_spec.rb19
-rw-r--r--spec/services/ci/pipeline_processing/shared_processing_service.rb25
-rw-r--r--spec/services/ci/pipeline_processing/shared_processing_service_tests_with_yaml.rb57
-rw-r--r--spec/services/ci/pipeline_processing/test_cases/dag_build_allow_failure_test_on_failure.yml47
-rw-r--r--spec/services/ci/pipeline_processing/test_cases/dag_build_fails.yml39
-rw-r--r--spec/services/ci/pipeline_processing/test_cases/dag_build_fails_deploy_needs_test.yml39
-rw-r--r--spec/services/ci/pipeline_processing/test_cases/dag_build_fails_deploy_needs_test_when_always.yml43
-rw-r--r--spec/services/ci/pipeline_processing/test_cases/dag_build_fails_other_build_succeeds.yml62
-rw-r--r--spec/services/ci/pipeline_processing/test_cases/dag_build_fails_other_build_succeeds_deploy_always.yml63
-rw-r--r--spec/services/ci/pipeline_processing/test_cases/dag_build_fails_test_allow_failure.yml40
-rw-r--r--spec/services/ci/pipeline_processing/test_cases/dag_build_fails_test_always.yml35
-rw-r--r--spec/services/ci/pipeline_processing/test_cases/dag_build_fails_test_on_failure.yml35
-rw-r--r--spec/services/ci/pipeline_processing/test_cases/dag_build_succeeds_test_on_failure.yml35
-rw-r--r--spec/services/ci/pipeline_processing/test_cases/dag_builds_succeed_test_on_failure.yml63
-rw-r--r--spec/services/ci/pipeline_processing/test_cases/dag_builds_succeed_test_on_failure_deploy_always.yml64
-rw-r--r--spec/services/ci/pipeline_processing/test_cases/dag_test_allow_failure_true.yml43
-rw-r--r--spec/services/ci/pipeline_processing/test_cases/dag_test_manual_allow_failure_false.yml66
-rw-r--r--spec/services/ci/pipeline_processing/test_cases/dag_test_manual_allow_failure_true.yml58
-rw-r--r--spec/services/ci/pipeline_processing/test_cases/dag_test_manual_allow_failure_true_deploy_always.yml27
-rw-r--r--spec/services/ci/pipeline_processing/test_cases/dag_test_manual_allow_failure_true_deploy_on_failure.yml48
-rw-r--r--spec/services/ci/pipeline_processing/test_cases/dag_test_manual_allow_failure_true_other_test_succeeds.yml42
-rw-r--r--spec/services/ci/pipeline_processing/test_cases/dag_test_on_failure_with_failure.yml66
-rw-r--r--spec/services/ci/pipeline_processing/test_cases/dag_test_on_failure_with_success.yml40
-rw-r--r--spec/services/ci/pipeline_processing/test_cases/stage_build_allow_failure_test_on_failure.yml53
-rw-r--r--spec/services/ci/pipeline_processing/test_cases/stage_build_fails.yml38
-rw-r--r--spec/services/ci/pipeline_processing/test_cases/stage_build_fails_test_allow_failure.yml39
-rw-r--r--spec/services/ci/pipeline_processing/test_cases/stage_test_manual_allow_failure_false.yml65
-rw-r--r--spec/services/ci/pipeline_processing/test_cases/stage_test_manual_allow_failure_true.yml54
-rw-r--r--spec/services/ci/pipeline_processing/test_cases/stage_test_manual_allow_failure_true_deploy_on_failure.yml44
-rw-r--r--spec/services/ci/pipeline_processing/test_cases/stage_test_on_failure_with_failure.yml52
-rw-r--r--spec/services/ci/pipeline_processing/test_cases/stage_test_on_failure_with_success.yml52
33 files changed, 1463 insertions, 11 deletions
diff --git a/spec/services/ci/pipeline_processing/atomic_processing_service/status_collection_spec.rb b/spec/services/ci/pipeline_processing/atomic_processing_service/status_collection_spec.rb
index b487730d07f..de3c7713ac8 100644
--- a/spec/services/ci/pipeline_processing/atomic_processing_service/status_collection_spec.rb
+++ b/spec/services/ci/pipeline_processing/atomic_processing_service/status_collection_spec.rb
@@ -18,7 +18,7 @@ describe Ci::PipelineProcessing::AtomicProcessingService::StatusCollection do
it 'does update existing status of processable' do
collection.set_processable_status(test_a.id, 'success', 100)
- expect(collection.status_for_names(['test-a'])).to eq('success')
+ expect(collection.status_for_names(['test-a'], dag: false)).to eq('success')
end
it 'ignores a missing processable' do
@@ -33,15 +33,18 @@ describe Ci::PipelineProcessing::AtomicProcessingService::StatusCollection do
end
describe '#status_for_names' do
- where(:names, :status) do
- %w[build-a] | 'success'
- %w[build-a build-b] | 'failed'
- %w[build-a test-a] | 'running'
+ where(:names, :status, :dag) do
+ %w[build-a] | 'success' | false
+ %w[build-a build-b] | 'failed' | false
+ %w[build-a test-a] | 'running' | false
+ %w[build-a] | 'success' | true
+ %w[build-a build-b] | 'failed' | true
+ %w[build-a test-a] | 'pending' | true
end
with_them do
it 'returns composite status of given names' do
- expect(collection.status_for_names(names)).to eq(status)
+ expect(collection.status_for_names(names, dag: dag)).to eq(status)
end
end
end
diff --git a/spec/services/ci/pipeline_processing/atomic_processing_service_spec.rb b/spec/services/ci/pipeline_processing/atomic_processing_service_spec.rb
index cbeb45b92ff..3b66ecff196 100644
--- a/spec/services/ci/pipeline_processing/atomic_processing_service_spec.rb
+++ b/spec/services/ci/pipeline_processing/atomic_processing_service_spec.rb
@@ -2,13 +2,19 @@
require 'spec_helper'
require_relative 'shared_processing_service.rb'
+require_relative 'shared_processing_service_tests_with_yaml.rb'
describe Ci::PipelineProcessing::AtomicProcessingService do
before do
stub_feature_flags(ci_atomic_processing: true)
+
+ # This feature flag is implicit
+ # Atomic Processing does not process statuses differently
+ stub_feature_flags(ci_composite_status: true)
end
it_behaves_like 'Pipeline Processing Service'
+ it_behaves_like 'Pipeline Processing Service Tests With Yaml'
private
diff --git a/spec/services/ci/pipeline_processing/legacy_processing_service_spec.rb b/spec/services/ci/pipeline_processing/legacy_processing_service_spec.rb
index 09b462b7600..fd491bf461b 100644
--- a/spec/services/ci/pipeline_processing/legacy_processing_service_spec.rb
+++ b/spec/services/ci/pipeline_processing/legacy_processing_service_spec.rb
@@ -2,13 +2,30 @@
require 'spec_helper'
require_relative 'shared_processing_service.rb'
+require_relative 'shared_processing_service_tests_with_yaml.rb'
describe Ci::PipelineProcessing::LegacyProcessingService do
before do
stub_feature_flags(ci_atomic_processing: false)
end
- it_behaves_like 'Pipeline Processing Service'
+ context 'when ci_composite_status is enabled' do
+ before do
+ stub_feature_flags(ci_composite_status: true)
+ end
+
+ it_behaves_like 'Pipeline Processing Service'
+ it_behaves_like 'Pipeline Processing Service Tests With Yaml'
+ end
+
+ context 'when ci_composite_status is disabled' do
+ before do
+ stub_feature_flags(ci_composite_status: false)
+ end
+
+ it_behaves_like 'Pipeline Processing Service'
+ it_behaves_like 'Pipeline Processing Service Tests With Yaml'
+ end
private
diff --git a/spec/services/ci/pipeline_processing/shared_processing_service.rb b/spec/services/ci/pipeline_processing/shared_processing_service.rb
index ffe5eacfc48..29fa43001ae 100644
--- a/spec/services/ci/pipeline_processing/shared_processing_service.rb
+++ b/spec/services/ci/pipeline_processing/shared_processing_service.rb
@@ -816,10 +816,10 @@ shared_examples 'Pipeline Processing Service' do
context 'when a needed job is skipped', :sidekiq_inline do
let!(:linux_build) { create_build('linux:build', stage: 'build', stage_idx: 0) }
let!(:linux_rspec) { create_build('linux:rspec', stage: 'test', stage_idx: 1) }
- let!(:deploy) do
- create_build('deploy', stage: 'deploy', stage_idx: 2, scheduling_type: :dag, needs: [
- create(:ci_build_need, name: 'linux:rspec')
- ])
+ let!(:deploy) { create_build('deploy', stage: 'deploy', stage_idx: 2, scheduling_type: :dag) }
+
+ before do
+ create(:ci_build_need, build: deploy, name: 'linux:build')
end
it 'skips the jobs depending on it' do
@@ -836,6 +836,23 @@ shared_examples 'Pipeline Processing Service' do
end
end
+ context 'when a needed job is manual', :sidekiq_inline do
+ let!(:linux_build) { create_build('linux:build', stage: 'build', stage_idx: 0, when: 'manual', allow_failure: true) }
+ let!(:deploy) { create_build('deploy', stage: 'deploy', stage_idx: 1, scheduling_type: :dag) }
+
+ before do
+ create(:ci_build_need, build: deploy, name: 'linux:build')
+ end
+
+ it 'makes deploy DAG to be waiting for optional manual to finish' do
+ expect(process_pipeline).to be_truthy
+
+ expect(stages).to eq(%w(skipped created))
+ expect(all_builds.manual).to contain_exactly(linux_build)
+ expect(all_builds.created).to contain_exactly(deploy)
+ end
+ end
+
private
def all_builds
diff --git a/spec/services/ci/pipeline_processing/shared_processing_service_tests_with_yaml.rb b/spec/services/ci/pipeline_processing/shared_processing_service_tests_with_yaml.rb
new file mode 100644
index 00000000000..93f83f0ea3b
--- /dev/null
+++ b/spec/services/ci/pipeline_processing/shared_processing_service_tests_with_yaml.rb
@@ -0,0 +1,57 @@
+# frozen_string_literal: true
+
+shared_context 'Pipeline Processing Service Tests With Yaml' do
+ where(:test_file_path) do
+ Dir.glob(Rails.root.join('spec/services/ci/pipeline_processing/test_cases/*.yml'))
+ end
+
+ with_them do
+ let(:test_file) { YAML.load_file(test_file_path) }
+
+ let(:user) { create(:user) }
+ let(:project) { create(:project, :repository) }
+ let(:pipeline) { Ci::CreatePipelineService.new(project, user, ref: 'master').execute(:pipeline) }
+
+ before do
+ stub_ci_pipeline_yaml_file(YAML.dump(test_file['config']))
+ stub_not_protect_default_branch
+ project.add_developer(user)
+ end
+
+ it 'follows transitions' do
+ expect(pipeline).to be_persisted
+ Sidekiq::Worker.drain_all # ensure that all async jobs are executed
+ check_expectation(test_file.dig('init', 'expect'), "init")
+
+ test_file['transitions'].each_with_index do |transition, idx|
+ event_on_jobs(transition['event'], transition['jobs'])
+ Sidekiq::Worker.drain_all # ensure that all async jobs are executed
+ check_expectation(transition['expect'], "transition:#{idx}")
+ end
+ end
+
+ private
+
+ def check_expectation(expectation, message)
+ expect(current_state.deep_stringify_keys).to eq(expectation), message
+ end
+
+ def current_state
+ # reload pipeline and all relations
+ pipeline.reload
+
+ {
+ pipeline: pipeline.status,
+ stages: pipeline.ordered_stages.pluck(:name, :status).to_h,
+ jobs: pipeline.statuses.latest.pluck(:name, :status).to_h
+ }
+ end
+
+ def event_on_jobs(event, job_names)
+ statuses = pipeline.statuses.latest.by_name(job_names).to_a
+ expect(statuses.count).to eq(job_names.count) # ensure that we have the same counts
+
+ statuses.each { |status| status.public_send("#{event}!") }
+ end
+ end
+end
diff --git a/spec/services/ci/pipeline_processing/test_cases/dag_build_allow_failure_test_on_failure.yml b/spec/services/ci/pipeline_processing/test_cases/dag_build_allow_failure_test_on_failure.yml
new file mode 100644
index 00000000000..cfc456387ff
--- /dev/null
+++ b/spec/services/ci/pipeline_processing/test_cases/dag_build_allow_failure_test_on_failure.yml
@@ -0,0 +1,47 @@
+config:
+ build:
+ stage: build
+ allow_failure: true
+ script: exit 1
+
+ test:
+ stage: test
+ when: on_failure
+ script: exit 0
+ needs: [build]
+
+ deploy:
+ stage: deploy
+ script: exit 0
+ needs: [test]
+
+init:
+ expect:
+ pipeline: pending
+ stages:
+ build: pending
+ test: created
+ deploy: created
+ jobs:
+ build: pending
+ test: created
+ deploy: created
+
+transitions:
+ - event: drop
+ jobs: [build]
+ expect:
+ pipeline: success
+ stages:
+ build: success
+ test: skipped
+ deploy: skipped
+ jobs:
+ build: failed
+ test: skipped
+ deploy: skipped
+
+# TODO: What is the real expected behavior here?
+# Is `needs` keyword a requirement indicator or just a helper to build dependency tree?
+# How should it behave `when: on_failure` with `needs`?
+# Further discussions: https://gitlab.com/gitlab-org/gitlab/-/issues/213080
diff --git a/spec/services/ci/pipeline_processing/test_cases/dag_build_fails.yml b/spec/services/ci/pipeline_processing/test_cases/dag_build_fails.yml
new file mode 100644
index 00000000000..e71ef194c5f
--- /dev/null
+++ b/spec/services/ci/pipeline_processing/test_cases/dag_build_fails.yml
@@ -0,0 +1,39 @@
+config:
+ build:
+ stage: build
+ script: exit 1
+
+ test:
+ stage: test
+ script: exit 0
+ needs: [build]
+
+ deploy:
+ stage: deploy
+ script: exit 0
+
+init:
+ expect:
+ pipeline: pending
+ stages:
+ build: pending
+ test: created
+ deploy: created
+ jobs:
+ build: pending
+ test: created
+ deploy: created
+
+transitions:
+ - event: drop
+ jobs: [build]
+ expect:
+ pipeline: failed
+ stages:
+ build: failed
+ test: skipped
+ deploy: skipped
+ jobs:
+ build: failed
+ test: skipped
+ deploy: skipped
diff --git a/spec/services/ci/pipeline_processing/test_cases/dag_build_fails_deploy_needs_test.yml b/spec/services/ci/pipeline_processing/test_cases/dag_build_fails_deploy_needs_test.yml
new file mode 100644
index 00000000000..40a80f6f53b
--- /dev/null
+++ b/spec/services/ci/pipeline_processing/test_cases/dag_build_fails_deploy_needs_test.yml
@@ -0,0 +1,39 @@
+config:
+ build:
+ stage: build
+ script: exit 1
+
+ test:
+ stage: test
+ script: exit 0
+
+ deploy:
+ stage: deploy
+ script: exit 0
+ needs: [test]
+
+init:
+ expect:
+ pipeline: pending
+ stages:
+ build: pending
+ test: created
+ deploy: created
+ jobs:
+ build: pending
+ test: created
+ deploy: created
+
+transitions:
+ - event: drop
+ jobs: [build]
+ expect:
+ pipeline: failed
+ stages:
+ build: failed
+ test: skipped
+ deploy: skipped
+ jobs:
+ build: failed
+ test: skipped
+ deploy: skipped
diff --git a/spec/services/ci/pipeline_processing/test_cases/dag_build_fails_deploy_needs_test_when_always.yml b/spec/services/ci/pipeline_processing/test_cases/dag_build_fails_deploy_needs_test_when_always.yml
new file mode 100644
index 00000000000..b0904a027f8
--- /dev/null
+++ b/spec/services/ci/pipeline_processing/test_cases/dag_build_fails_deploy_needs_test_when_always.yml
@@ -0,0 +1,43 @@
+config:
+ build:
+ stage: build
+ script: exit 1
+
+ test:
+ stage: test
+ script: exit 0
+
+ deploy:
+ stage: deploy
+ script: exit 0
+ when: always
+ needs: [test]
+
+init:
+ expect:
+ pipeline: pending
+ stages:
+ build: pending
+ test: created
+ deploy: created
+ jobs:
+ build: pending
+ test: created
+ deploy: created
+
+transitions:
+ - event: drop
+ jobs: [build]
+ expect:
+ pipeline: running
+ stages:
+ build: failed
+ test: skipped
+ deploy: pending
+ jobs:
+ build: failed
+ test: skipped
+ deploy: pending
+
+# TODO: `test` is actually skipped, but we run `deploy`. Should we?
+# Further discussions: https://gitlab.com/gitlab-org/gitlab/-/issues/213080
diff --git a/spec/services/ci/pipeline_processing/test_cases/dag_build_fails_other_build_succeeds.yml b/spec/services/ci/pipeline_processing/test_cases/dag_build_fails_other_build_succeeds.yml
new file mode 100644
index 00000000000..a133023b12d
--- /dev/null
+++ b/spec/services/ci/pipeline_processing/test_cases/dag_build_fails_other_build_succeeds.yml
@@ -0,0 +1,62 @@
+config:
+ build_1:
+ stage: build
+ script: exit 0
+
+ build_2:
+ stage: build
+ script: exit 1
+
+ test:
+ stage: test
+ script: exit 0
+
+ deploy:
+ stage: deploy
+ script: exit 0
+ needs: [build_1, test]
+
+init:
+ expect:
+ pipeline: pending
+ stages:
+ build: pending
+ test: created
+ deploy: created
+ jobs:
+ build_1: pending
+ build_2: pending
+ test: created
+ deploy: created
+
+transitions:
+ - event: success
+ jobs: [build_1]
+ expect:
+ pipeline: running
+ stages:
+ build: running
+ test: created
+ deploy: created
+ jobs:
+ build_1: success
+ build_2: pending
+ test: created
+ deploy: created
+
+ - event: drop
+ jobs: [build_2]
+ expect:
+ pipeline: running
+ stages:
+ build: failed
+ test: skipped
+ deploy: pending
+ jobs:
+ build_1: success
+ build_2: failed
+ test: skipped
+ deploy: pending
+
+# TODO: should we run deploy?
+# Further discussions: https://gitlab.com/gitlab-org/gitlab/-/issues/213080
diff --git a/spec/services/ci/pipeline_processing/test_cases/dag_build_fails_other_build_succeeds_deploy_always.yml b/spec/services/ci/pipeline_processing/test_cases/dag_build_fails_other_build_succeeds_deploy_always.yml
new file mode 100644
index 00000000000..4c676761e5c
--- /dev/null
+++ b/spec/services/ci/pipeline_processing/test_cases/dag_build_fails_other_build_succeeds_deploy_always.yml
@@ -0,0 +1,63 @@
+config:
+ build_1:
+ stage: build
+ script: exit 0
+
+ build_2:
+ stage: build
+ script: exit 1
+
+ test:
+ stage: test
+ script: exit 0
+
+ deploy:
+ stage: deploy
+ script: exit 0
+ when: always
+ needs: [build_1, test]
+
+init:
+ expect:
+ pipeline: pending
+ stages:
+ build: pending
+ test: created
+ deploy: created
+ jobs:
+ build_1: pending
+ build_2: pending
+ test: created
+ deploy: created
+
+transitions:
+ - event: success
+ jobs: [build_1]
+ expect:
+ pipeline: running
+ stages:
+ build: running
+ test: created
+ deploy: created
+ jobs:
+ build_1: success
+ build_2: pending
+ test: created
+ deploy: created
+
+ - event: drop
+ jobs: [build_2]
+ expect:
+ pipeline: running
+ stages:
+ build: failed
+ test: skipped
+ deploy: pending
+ jobs:
+ build_1: success
+ build_2: failed
+ test: skipped
+ deploy: pending
+
+# TODO: what's the actual expected behavior here?
+# Further discussions: https://gitlab.com/gitlab-org/gitlab/-/issues/213080
diff --git a/spec/services/ci/pipeline_processing/test_cases/dag_build_fails_test_allow_failure.yml b/spec/services/ci/pipeline_processing/test_cases/dag_build_fails_test_allow_failure.yml
new file mode 100644
index 00000000000..ea7046262c3
--- /dev/null
+++ b/spec/services/ci/pipeline_processing/test_cases/dag_build_fails_test_allow_failure.yml
@@ -0,0 +1,40 @@
+config:
+ build:
+ stage: build
+ script: exit 1
+
+ test:
+ stage: test
+ allow_failure: true
+ script: exit 1
+
+ deploy:
+ stage: deploy
+ script: exit 0
+ needs: [test]
+
+init:
+ expect:
+ pipeline: pending
+ stages:
+ build: pending
+ test: created
+ deploy: created
+ jobs:
+ build: pending
+ test: created
+ deploy: created
+
+transitions:
+ - event: drop
+ jobs: [build]
+ expect:
+ pipeline: failed
+ stages:
+ build: failed
+ test: skipped
+ deploy: skipped
+ jobs:
+ build: failed
+ test: skipped
+ deploy: skipped
diff --git a/spec/services/ci/pipeline_processing/test_cases/dag_build_fails_test_always.yml b/spec/services/ci/pipeline_processing/test_cases/dag_build_fails_test_always.yml
new file mode 100644
index 00000000000..8860f565cc7
--- /dev/null
+++ b/spec/services/ci/pipeline_processing/test_cases/dag_build_fails_test_always.yml
@@ -0,0 +1,35 @@
+config:
+ build:
+ stage: build
+ script: exit 1
+
+ test:
+ stage: test
+ when: always
+ script: exit 0
+ needs: [build]
+
+init:
+ expect:
+ pipeline: pending
+ stages:
+ build: pending
+ test: created
+ jobs:
+ build: pending
+ test: created
+
+transitions:
+ - event: drop
+ jobs: [build]
+ expect:
+ pipeline: running
+ stages:
+ build: failed
+ test: pending
+ jobs:
+ build: failed
+ test: pending
+
+# TODO: Should we run `test`?
+# Further discussions: https://gitlab.com/gitlab-org/gitlab/-/issues/213080
diff --git a/spec/services/ci/pipeline_processing/test_cases/dag_build_fails_test_on_failure.yml b/spec/services/ci/pipeline_processing/test_cases/dag_build_fails_test_on_failure.yml
new file mode 100644
index 00000000000..3fa5a8034a2
--- /dev/null
+++ b/spec/services/ci/pipeline_processing/test_cases/dag_build_fails_test_on_failure.yml
@@ -0,0 +1,35 @@
+config:
+ build:
+ stage: build
+ script: exit 1
+
+ test:
+ stage: test
+ when: on_failure
+ script: exit 0
+ needs: [build]
+
+init:
+ expect:
+ pipeline: pending
+ stages:
+ build: pending
+ test: created
+ jobs:
+ build: pending
+ test: created
+
+transitions:
+ - event: drop
+ jobs: [build]
+ expect:
+ pipeline: running
+ stages:
+ build: failed
+ test: pending
+ jobs:
+ build: failed
+ test: pending
+
+# TODO: Should we run `test`?
+# Further discussions: https://gitlab.com/gitlab-org/gitlab/-/issues/213080
diff --git a/spec/services/ci/pipeline_processing/test_cases/dag_build_succeeds_test_on_failure.yml b/spec/services/ci/pipeline_processing/test_cases/dag_build_succeeds_test_on_failure.yml
new file mode 100644
index 00000000000..700d4440802
--- /dev/null
+++ b/spec/services/ci/pipeline_processing/test_cases/dag_build_succeeds_test_on_failure.yml
@@ -0,0 +1,35 @@
+config:
+ build:
+ stage: build
+ script: exit 0
+
+ test:
+ stage: test
+ when: on_failure
+ script: exit 0
+ needs: [build]
+
+init:
+ expect:
+ pipeline: pending
+ stages:
+ build: pending
+ test: created
+ jobs:
+ build: pending
+ test: created
+
+transitions:
+ - event: success
+ jobs: [build]
+ expect:
+ pipeline: success
+ stages:
+ build: success
+ test: skipped
+ jobs:
+ build: success
+ test: skipped
+
+# TODO: Should we run `test`?
+# Further discussions: https://gitlab.com/gitlab-org/gitlab/-/issues/213080
diff --git a/spec/services/ci/pipeline_processing/test_cases/dag_builds_succeed_test_on_failure.yml b/spec/services/ci/pipeline_processing/test_cases/dag_builds_succeed_test_on_failure.yml
new file mode 100644
index 00000000000..f324525bd56
--- /dev/null
+++ b/spec/services/ci/pipeline_processing/test_cases/dag_builds_succeed_test_on_failure.yml
@@ -0,0 +1,63 @@
+config:
+ build_1:
+ stage: build
+ script: exit 0
+
+ build_2:
+ stage: build
+ script: exit 0
+
+ test:
+ stage: test
+ script: exit 0
+ when: on_failure
+
+ deploy:
+ stage: deploy
+ script: exit 0
+ needs: [build_1, test]
+
+init:
+ expect:
+ pipeline: pending
+ stages:
+ build: pending
+ test: created
+ deploy: created
+ jobs:
+ build_1: pending
+ build_2: pending
+ test: created
+ deploy: created
+
+transitions:
+ - event: success
+ jobs: [build_1, build_2]
+ expect:
+ pipeline: running
+ stages:
+ build: success
+ test: skipped
+ deploy: pending
+ jobs:
+ build_1: success
+ build_2: success
+ test: skipped
+ deploy: pending
+
+ - event: success
+ jobs: [deploy]
+ expect:
+ pipeline: success
+ stages:
+ build: success
+ test: skipped
+ deploy: success
+ jobs:
+ build_1: success
+ build_2: success
+ test: skipped
+ deploy: success
+
+# TODO: should we run deploy?
+# Further discussions: https://gitlab.com/gitlab-org/gitlab/-/issues/213080
diff --git a/spec/services/ci/pipeline_processing/test_cases/dag_builds_succeed_test_on_failure_deploy_always.yml b/spec/services/ci/pipeline_processing/test_cases/dag_builds_succeed_test_on_failure_deploy_always.yml
new file mode 100644
index 00000000000..9986dbaa215
--- /dev/null
+++ b/spec/services/ci/pipeline_processing/test_cases/dag_builds_succeed_test_on_failure_deploy_always.yml
@@ -0,0 +1,64 @@
+config:
+ build_1:
+ stage: build
+ script: exit 0
+
+ build_2:
+ stage: build
+ script: exit 0
+
+ test:
+ stage: test
+ script: exit 0
+ when: on_failure
+
+ deploy:
+ stage: deploy
+ script: exit 0
+ when: always
+ needs: [build_1, test]
+
+init:
+ expect:
+ pipeline: pending
+ stages:
+ build: pending
+ test: created
+ deploy: created
+ jobs:
+ build_1: pending
+ build_2: pending
+ test: created
+ deploy: created
+
+transitions:
+ - event: success
+ jobs: [build_1, build_2]
+ expect:
+ pipeline: running
+ stages:
+ build: success
+ test: skipped
+ deploy: pending
+ jobs:
+ build_1: success
+ build_2: success
+ test: skipped
+ deploy: pending
+
+ - event: success
+ jobs: [deploy]
+ expect:
+ pipeline: success
+ stages:
+ build: success
+ test: skipped
+ deploy: success
+ jobs:
+ build_1: success
+ build_2: success
+ test: skipped
+ deploy: success
+
+# TODO: should we run deploy?
+# Further discussions: https://gitlab.com/gitlab-org/gitlab/-/issues/213080
diff --git a/spec/services/ci/pipeline_processing/test_cases/dag_test_allow_failure_true.yml b/spec/services/ci/pipeline_processing/test_cases/dag_test_allow_failure_true.yml
new file mode 100644
index 00000000000..8d4d9d403f1
--- /dev/null
+++ b/spec/services/ci/pipeline_processing/test_cases/dag_test_allow_failure_true.yml
@@ -0,0 +1,43 @@
+config:
+ test:
+ stage: test
+ allow_failure: true
+ script: exit 1
+
+ deploy:
+ stage: deploy
+ script: exit 0
+ needs: [test]
+
+init:
+ expect:
+ pipeline: pending
+ stages:
+ test: pending
+ deploy: created
+ jobs:
+ test: pending
+ deploy: created
+
+transitions:
+ - event: drop
+ jobs: [test]
+ expect:
+ pipeline: pending
+ stages:
+ test: success
+ deploy: pending
+ jobs:
+ test: failed
+ deploy: pending
+
+ - event: success
+ jobs: [deploy]
+ expect:
+ pipeline: success
+ stages:
+ test: success
+ deploy: success
+ jobs:
+ test: failed
+ deploy: success
diff --git a/spec/services/ci/pipeline_processing/test_cases/dag_test_manual_allow_failure_false.yml b/spec/services/ci/pipeline_processing/test_cases/dag_test_manual_allow_failure_false.yml
new file mode 100644
index 00000000000..1d61cd24f8c
--- /dev/null
+++ b/spec/services/ci/pipeline_processing/test_cases/dag_test_manual_allow_failure_false.yml
@@ -0,0 +1,66 @@
+config:
+ test:
+ stage: test
+ when: manual
+ allow_failure: false
+ script: exit 0
+
+ deploy:
+ stage: deploy
+ script: exit 0
+ needs: [test]
+
+init:
+ expect:
+ pipeline: manual
+ stages:
+ test: manual
+ deploy: created
+ jobs:
+ test: manual
+ deploy: created
+
+transitions:
+ - event: enqueue
+ jobs: [test]
+ expect:
+ pipeline: pending
+ stages:
+ test: pending
+ deploy: created
+ jobs:
+ test: pending
+ deploy: created
+
+ - event: run
+ jobs: [test]
+ expect:
+ pipeline: running
+ stages:
+ test: running
+ deploy: created
+ jobs:
+ test: running
+ deploy: created
+
+ - event: success
+ jobs: [test]
+ expect:
+ pipeline: running
+ stages:
+ test: success
+ deploy: pending
+ jobs:
+ test: success
+ deploy: pending
+
+ - event: success
+ jobs: [deploy]
+ expect:
+ pipeline: success
+ stages:
+ test: success
+ deploy: success
+ jobs:
+ test: success
+ deploy: success
diff --git a/spec/services/ci/pipeline_processing/test_cases/dag_test_manual_allow_failure_true.yml b/spec/services/ci/pipeline_processing/test_cases/dag_test_manual_allow_failure_true.yml
new file mode 100644
index 00000000000..d8ca563b141
--- /dev/null
+++ b/spec/services/ci/pipeline_processing/test_cases/dag_test_manual_allow_failure_true.yml
@@ -0,0 +1,58 @@
+config:
+ test:
+ stage: test
+ when: manual
+ allow_failure: true
+ script: exit 1
+
+ deploy:
+ stage: deploy
+ script: exit 0
+ needs: [test]
+
+init:
+ expect:
+ pipeline: created
+ stages:
+ test: skipped
+ deploy: created
+ jobs:
+ test: manual
+ deploy: created
+
+transitions:
+ - event: enqueue
+ jobs: [test]
+ expect:
+ pipeline: pending
+ stages:
+ test: pending
+ deploy: created
+ jobs:
+ test: pending
+ deploy: created
+
+ - event: run
+ jobs: [test]
+ expect:
+ pipeline: running
+ stages:
+ test: running
+ deploy: created
+ jobs:
+ test: running
+ deploy: created
+
+ - event: drop
+ jobs: [test]
+ expect:
+ pipeline: running
+ stages:
+ test: success
+ deploy: pending
+ jobs:
+ test: failed
+ deploy: pending
+
+# TOOD: should we run deploy?
+# Further discussions: https://gitlab.com/gitlab-org/gitlab/-/issues/213080
diff --git a/spec/services/ci/pipeline_processing/test_cases/dag_test_manual_allow_failure_true_deploy_always.yml b/spec/services/ci/pipeline_processing/test_cases/dag_test_manual_allow_failure_true_deploy_always.yml
new file mode 100644
index 00000000000..ba0a20f49a7
--- /dev/null
+++ b/spec/services/ci/pipeline_processing/test_cases/dag_test_manual_allow_failure_true_deploy_always.yml
@@ -0,0 +1,27 @@
+config:
+ test:
+ stage: test
+ when: manual
+ allow_failure: true
+ script: exit 1
+
+ deploy:
+ stage: deploy
+ when: always
+ script: exit 0
+ needs: [test]
+
+init:
+ expect:
+ pipeline: created
+ stages:
+ test: skipped
+ deploy: created
+ jobs:
+ test: manual
+ deploy: created
+
+transitions: []
+
+# TODO: should we run `deploy`?
+# Further discussions: https://gitlab.com/gitlab-org/gitlab/-/issues/213080
diff --git a/spec/services/ci/pipeline_processing/test_cases/dag_test_manual_allow_failure_true_deploy_on_failure.yml b/spec/services/ci/pipeline_processing/test_cases/dag_test_manual_allow_failure_true_deploy_on_failure.yml
new file mode 100644
index 00000000000..d375c6a49e0
--- /dev/null
+++ b/spec/services/ci/pipeline_processing/test_cases/dag_test_manual_allow_failure_true_deploy_on_failure.yml
@@ -0,0 +1,48 @@
+config:
+ test:
+ stage: test
+ when: manual
+ allow_failure: true
+ script: exit 1
+
+ deploy:
+ stage: deploy
+ when: on_failure
+ script: exit 0
+ needs: [test]
+
+init:
+ expect:
+ pipeline: created
+ stages:
+ test: skipped
+ deploy: created
+ jobs:
+ test: manual
+ deploy: created
+
+transitions:
+ - event: enqueue
+ jobs: [test]
+ expect:
+ pipeline: pending
+ stages:
+ test: pending
+ deploy: created
+ jobs:
+ test: pending
+ deploy: created
+
+ - event: drop
+ jobs: [test]
+ expect:
+ pipeline: success
+ stages:
+ test: success
+ deploy: skipped
+ jobs:
+ test: failed
+ deploy: skipped
+
+# TODO: should we run `deploy`?
+# Further discussions: https://gitlab.com/gitlab-org/gitlab/-/issues/213080
diff --git a/spec/services/ci/pipeline_processing/test_cases/dag_test_manual_allow_failure_true_other_test_succeeds.yml b/spec/services/ci/pipeline_processing/test_cases/dag_test_manual_allow_failure_true_other_test_succeeds.yml
new file mode 100644
index 00000000000..34073b92ccc
--- /dev/null
+++ b/spec/services/ci/pipeline_processing/test_cases/dag_test_manual_allow_failure_true_other_test_succeeds.yml
@@ -0,0 +1,42 @@
+config:
+ test1:
+ stage: test
+ script: exit 0
+
+ test2:
+ stage: test
+ when: manual
+ allow_failure: true
+ script: exit 1
+
+ deploy:
+ stage: deploy
+ script: exit 0
+ needs: [test1, test2]
+
+init:
+ expect:
+ pipeline: pending
+ stages:
+ test: pending
+ deploy: created
+ jobs:
+ test1: pending
+ test2: manual
+ deploy: created
+
+transitions:
+ - event: success
+ jobs: [test1]
+ expect:
+ pipeline: running
+ stages:
+ test: success
+ deploy: created
+ jobs:
+ test1: success
+ test2: manual
+ deploy: created
+
+# TODO: should deploy run?
+# Further discussions: https://gitlab.com/gitlab-org/gitlab/-/issues/213080
diff --git a/spec/services/ci/pipeline_processing/test_cases/dag_test_on_failure_with_failure.yml b/spec/services/ci/pipeline_processing/test_cases/dag_test_on_failure_with_failure.yml
new file mode 100644
index 00000000000..5ace621e89c
--- /dev/null
+++ b/spec/services/ci/pipeline_processing/test_cases/dag_test_on_failure_with_failure.yml
@@ -0,0 +1,66 @@
+config:
+ build:
+ stage: build
+ script: exit 1
+
+ test:
+ stage: test
+ when: on_failure
+ script: exit 0
+
+ deploy:
+ stage: deploy
+ script: exit 0
+ needs: [test]
+
+init:
+ expect:
+ pipeline: pending
+ stages:
+ build: pending
+ test: created
+ deploy: created
+ jobs:
+ build: pending
+ test: created
+ deploy: created
+
+transitions:
+ - event: drop
+ jobs: [build]
+ expect:
+ pipeline: running
+ stages:
+ build: failed
+ test: pending
+ deploy: created
+ jobs:
+ build: failed
+ test: pending
+ deploy: created
+
+ - event: success
+ jobs: [test]
+ expect:
+ pipeline: running
+ stages:
+ build: failed
+ test: success
+ deploy: pending
+ jobs:
+ build: failed
+ test: success
+ deploy: pending
+
+ - event: success
+ jobs: [deploy]
+ expect:
+ pipeline: failed
+ stages:
+ build: failed
+ test: success
+ deploy: success
+ jobs:
+ build: failed
+ test: success
+ deploy: success
diff --git a/spec/services/ci/pipeline_processing/test_cases/dag_test_on_failure_with_success.yml b/spec/services/ci/pipeline_processing/test_cases/dag_test_on_failure_with_success.yml
new file mode 100644
index 00000000000..19524cfd3e4
--- /dev/null
+++ b/spec/services/ci/pipeline_processing/test_cases/dag_test_on_failure_with_success.yml
@@ -0,0 +1,40 @@
+config:
+ build:
+ stage: build
+ script: exit 0
+
+ test:
+ stage: test
+ when: on_failure
+ script: exit 0
+
+ deploy:
+ stage: deploy
+ script: exit 0
+ needs: [test]
+
+init:
+ expect:
+ pipeline: pending
+ stages:
+ build: pending
+ test: created
+ deploy: created
+ jobs:
+ build: pending
+ test: created
+ deploy: created
+
+transitions:
+ - event: success
+ jobs: [build]
+ expect:
+ pipeline: success
+ stages:
+ build: success
+ test: skipped
+ deploy: skipped
+ jobs:
+ build: success
+ test: skipped
+ deploy: skipped
diff --git a/spec/services/ci/pipeline_processing/test_cases/stage_build_allow_failure_test_on_failure.yml b/spec/services/ci/pipeline_processing/test_cases/stage_build_allow_failure_test_on_failure.yml
new file mode 100644
index 00000000000..3e081d4411b
--- /dev/null
+++ b/spec/services/ci/pipeline_processing/test_cases/stage_build_allow_failure_test_on_failure.yml
@@ -0,0 +1,53 @@
+config:
+ build:
+ stage: build
+ allow_failure: true
+ script: exit 1
+
+ test:
+ stage: test
+ when: on_failure
+ script: exit 0
+
+ deploy:
+ stage: deploy
+ script: exit 0
+
+init:
+ expect:
+ pipeline: pending
+ stages:
+ build: pending
+ test: created
+ deploy: created
+ jobs:
+ build: pending
+ test: created
+ deploy: created
+
+transitions:
+ - event: drop
+ jobs: [build]
+ expect:
+ pipeline: pending
+ stages:
+ build: success
+ test: skipped
+ deploy: pending
+ jobs:
+ build: failed
+ test: skipped
+ deploy: pending
+
+ - event: success
+ jobs: [deploy]
+ expect:
+ pipeline: success
+ stages:
+ build: success
+ test: skipped
+ deploy: success
+ jobs:
+ build: failed
+ test: skipped
+ deploy: success
diff --git a/spec/services/ci/pipeline_processing/test_cases/stage_build_fails.yml b/spec/services/ci/pipeline_processing/test_cases/stage_build_fails.yml
new file mode 100644
index 00000000000..0618abf3524
--- /dev/null
+++ b/spec/services/ci/pipeline_processing/test_cases/stage_build_fails.yml
@@ -0,0 +1,38 @@
+config:
+ build:
+ stage: build
+ script: exit 1
+
+ test:
+ stage: test
+ script: exit 0
+
+ deploy:
+ stage: deploy
+ script: exit 0
+
+init:
+ expect:
+ pipeline: pending
+ stages:
+ build: pending
+ test: created
+ deploy: created
+ jobs:
+ build: pending
+ test: created
+ deploy: created
+
+transitions:
+ - event: drop
+ jobs: [build]
+ expect:
+ pipeline: failed
+ stages:
+ build: failed
+ test: skipped
+ deploy: skipped
+ jobs:
+ build: failed
+ test: skipped
+ deploy: skipped
diff --git a/spec/services/ci/pipeline_processing/test_cases/stage_build_fails_test_allow_failure.yml b/spec/services/ci/pipeline_processing/test_cases/stage_build_fails_test_allow_failure.yml
new file mode 100644
index 00000000000..362ac6e4239
--- /dev/null
+++ b/spec/services/ci/pipeline_processing/test_cases/stage_build_fails_test_allow_failure.yml
@@ -0,0 +1,39 @@
+config:
+ build:
+ stage: build
+ script: exit 1
+
+ test:
+ stage: test
+ allow_failure: true
+ script: exit 1
+
+ deploy:
+ stage: deploy
+ script: exit 0
+
+init:
+ expect:
+ pipeline: pending
+ stages:
+ build: pending
+ test: created
+ deploy: created
+ jobs:
+ build: pending
+ test: created
+ deploy: created
+
+transitions:
+ - event: drop
+ jobs: [build]
+ expect:
+ pipeline: failed
+ stages:
+ build: failed
+ test: skipped
+ deploy: skipped
+ jobs:
+ build: failed
+ test: skipped
+ deploy: skipped
diff --git a/spec/services/ci/pipeline_processing/test_cases/stage_test_manual_allow_failure_false.yml b/spec/services/ci/pipeline_processing/test_cases/stage_test_manual_allow_failure_false.yml
new file mode 100644
index 00000000000..2ffa35b56d7
--- /dev/null
+++ b/spec/services/ci/pipeline_processing/test_cases/stage_test_manual_allow_failure_false.yml
@@ -0,0 +1,65 @@
+config:
+ test:
+ stage: test
+ when: manual
+ allow_failure: false
+ script: exit 0
+
+ deploy:
+ stage: deploy
+ script: exit 0
+
+init:
+ expect:
+ pipeline: manual
+ stages:
+ test: manual
+ deploy: created
+ jobs:
+ test: manual
+ deploy: created
+
+transitions:
+ - event: enqueue
+ jobs: [test]
+ expect:
+ pipeline: pending
+ stages:
+ test: pending
+ deploy: created
+ jobs:
+ test: pending
+ deploy: created
+
+ - event: run
+ jobs: [test]
+ expect:
+ pipeline: running
+ stages:
+ test: running
+ deploy: created
+ jobs:
+ test: running
+ deploy: created
+
+ - event: success
+ jobs: [test]
+ expect:
+ pipeline: running
+ stages:
+ test: success
+ deploy: pending
+ jobs:
+ test: success
+ deploy: pending
+
+ - event: success
+ jobs: [deploy]
+ expect:
+ pipeline: success
+ stages:
+ test: success
+ deploy: success
+ jobs:
+ test: success
+ deploy: success
diff --git a/spec/services/ci/pipeline_processing/test_cases/stage_test_manual_allow_failure_true.yml b/spec/services/ci/pipeline_processing/test_cases/stage_test_manual_allow_failure_true.yml
new file mode 100644
index 00000000000..088fab5ca09
--- /dev/null
+++ b/spec/services/ci/pipeline_processing/test_cases/stage_test_manual_allow_failure_true.yml
@@ -0,0 +1,54 @@
+config:
+ test:
+ stage: test
+ when: manual
+ allow_failure: true
+ script: exit 1
+
+ deploy:
+ stage: deploy
+ script: exit 0
+
+init:
+ expect:
+ pipeline: pending
+ stages:
+ test: skipped
+ deploy: pending
+ jobs:
+ test: manual
+ deploy: pending
+
+transitions:
+ - event: success
+ jobs: [deploy]
+ expect:
+ pipeline: success
+ stages:
+ test: skipped
+ deploy: success
+ jobs:
+ test: manual
+ deploy: success
+
+ - event: enqueue
+ jobs: [test]
+ expect:
+ pipeline: running
+ stages:
+ test: pending
+ deploy: success
+ jobs:
+ test: pending
+ deploy: success
+
+ - event: drop
+ jobs: [test]
+ expect:
+ pipeline: success
+ stages:
+ test: success
+ deploy: success
+ jobs:
+ test: failed
+ deploy: success
diff --git a/spec/services/ci/pipeline_processing/test_cases/stage_test_manual_allow_failure_true_deploy_on_failure.yml b/spec/services/ci/pipeline_processing/test_cases/stage_test_manual_allow_failure_true_deploy_on_failure.yml
new file mode 100644
index 00000000000..2b30316aef6
--- /dev/null
+++ b/spec/services/ci/pipeline_processing/test_cases/stage_test_manual_allow_failure_true_deploy_on_failure.yml
@@ -0,0 +1,44 @@
+config:
+ test:
+ stage: test
+ when: manual
+ allow_failure: true
+ script: exit 1
+
+ deploy:
+ stage: deploy
+ when: on_failure
+ script: exit 0
+
+init:
+ expect:
+ pipeline: skipped
+ stages:
+ test: skipped
+ deploy: skipped
+ jobs:
+ test: manual
+ deploy: skipped
+
+transitions:
+ - event: enqueue
+ jobs: [test]
+ expect:
+ pipeline: pending
+ stages:
+ test: pending
+ deploy: skipped
+ jobs:
+ test: pending
+ deploy: skipped
+
+ - event: drop
+ jobs: [test]
+ expect:
+ pipeline: success
+ stages:
+ test: success
+ deploy: skipped
+ jobs:
+ test: failed
+ deploy: skipped
diff --git a/spec/services/ci/pipeline_processing/test_cases/stage_test_on_failure_with_failure.yml b/spec/services/ci/pipeline_processing/test_cases/stage_test_on_failure_with_failure.yml
new file mode 100644
index 00000000000..1751cbb2023
--- /dev/null
+++ b/spec/services/ci/pipeline_processing/test_cases/stage_test_on_failure_with_failure.yml
@@ -0,0 +1,52 @@
+config:
+ build:
+ stage: build
+ script: exit 1
+
+ test:
+ stage: test
+ when: on_failure
+ script: exit 0
+
+ deploy:
+ stage: deploy
+ script: exit 0
+
+init:
+ expect:
+ pipeline: pending
+ stages:
+ build: pending
+ test: created
+ deploy: created
+ jobs:
+ build: pending
+ test: created
+ deploy: created
+
+transitions:
+ - event: drop
+ jobs: [build]
+ expect:
+ pipeline: running
+ stages:
+ build: failed
+ test: pending
+ deploy: created
+ jobs:
+ build: failed
+ test: pending
+ deploy: created
+
+ - event: success
+ jobs: [test]
+ expect:
+ pipeline: failed
+ stages:
+ build: failed
+ test: success
+ deploy: skipped
+ jobs:
+ build: failed
+ test: success
+ deploy: skipped
diff --git a/spec/services/ci/pipeline_processing/test_cases/stage_test_on_failure_with_success.yml b/spec/services/ci/pipeline_processing/test_cases/stage_test_on_failure_with_success.yml
new file mode 100644
index 00000000000..15afe1ce8e1
--- /dev/null
+++ b/spec/services/ci/pipeline_processing/test_cases/stage_test_on_failure_with_success.yml
@@ -0,0 +1,52 @@
+config:
+ build:
+ stage: build
+ script: exit 0
+
+ test:
+ stage: test
+ when: on_failure
+ script: exit 0
+
+ deploy:
+ stage: deploy
+ script: exit 0
+
+init:
+ expect:
+ pipeline: pending
+ stages:
+ build: pending
+ test: created
+ deploy: created
+ jobs:
+ build: pending
+ test: created
+ deploy: created
+
+transitions:
+ - event: success
+ jobs: [build]
+ expect:
+ pipeline: running
+ stages:
+ build: success
+ test: skipped
+ deploy: pending
+ jobs:
+ build: success
+ test: skipped
+ deploy: pending
+
+ - event: success
+ jobs: [deploy]
+ expect:
+ pipeline: success
+ stages:
+ build: success
+ test: skipped
+ deploy: success
+ jobs:
+ build: success
+ test: skipped
+ deploy: success