gitlab-org--gitlab-foss/scheduled_job_fixture.rb

193 lines
5.6 KiB
Ruby

##
# ###
# IMPORTANT
# - Enable the feature flag `ci_enable_scheduled_build` on rails console! You can do `Feature.enable('ci_enable_scheduled_build')`
# This feature is off by default!
#
#
# This is a debug script to reproduce specific scenarios for scheduled jobs (https://gitlab.com/gitlab-org/gitlab-ce/issues/51352)
# By using this script, you don't need to setup GitLab runner.
# This script is specifically made for FE/UX engineers. They can quickly check how scheduled jobs behave.
#
# *** THIS IS NOT TO BE MERGED ***
#
# ### How to use ###
#
# ### Prerequisite
# 1. Create a project (for example with path `incremental-rollout`)
# 1. Create a .gitlab-ci.yml with the following content
#
=begin
stages:
- build
- test
- production
- rollout 10%
- rollout 50%
- rollout 100%
- cleanup
build:
stage: build
script: sleep 1s
test:
stage: test
script: sleep 3s
rollout 10%:
stage: rollout 10%
script: date
when: delayed
start_in: 10 seconds
allow_failure: false
rollout 50%:
stage: rollout 50%
script: date
when: delayed
start_in: 10 seconds
allow_failure: false
rollout 100%:
stage: rollout 100%
script: date
when: delayed
start_in: 10 seconds
allow_failure: false
cleanup:
stage: cleanup
script: date
=end
#
# ### How to load this script
#
# ```
# bundle exec rails console # Login to rails console
# require '/path/to/scheduled_job_fixture.rb' # Load this script
# ```
#
# ### Reproduce the scenario ~ when all stages succeeded ~
#
# 1. ScheduledJobFixture.new(16, 1).create_pipeline('master')
# 1. ScheduledJobFixture.new(16, 1).finish_stage_until('test')
# 1. Wait until rollout 10% job is triggered
# 1. ScheduledJobFixture.new(16, 1).finish_stage_until('rollout 10%')
# 1. Wait until rollout 50% job is triggered
# 1. ScheduledJobFixture.new(16, 1).finish_stage_until('rollout 50%')
# 1. Wait until rollout 100% job is triggered
# 1. ScheduledJobFixture.new(16, 1).finish_stage_until('rollout 100%')
# 1. ScheduledJobFixture.new(16, 1).finish_stage_until('cleanup')
#
# Expectation: Users see a succeccful pipeline
#
# ### Reproduce the scenario ~ when rollout 10% jobs failed ~
#
# 1. ScheduledJobFixture.new(16, 1).create_pipeline('master')
# 1. ScheduledJobFixture.new(16, 1).finish_stage_until('test')
# 1. Wait until rollout 10% job is triggered
# 1. ScheduledJobFixture.new(16, 1).drop_jobs('rollout 10%')
#
# Expectation: Following stages should be skipped.
#
# ### Reproduce the scenario ~ when user clicked cancel button before build job finished ~
#
# 1. ScheduledJobFixture.new(16, 1).create_pipeline('master')
# 1. ScheduledJobFixture.new(16, 1).cancel_pipeline
#
# Expectation: All stages should be canceled.
#
# ### Reproduce the scenario ~ when user canceled the pipeline after rollout 10% job is scheduled ~
#
# 1. ScheduledJobFixture.new(16, 1).create_pipeline('master')
# 1. ScheduledJobFixture.new(16, 1).finish_stage_until('test')
# 1. Run next command before rollout 10% job is triggered
# 1. ScheduledJobFixture.new(16, 1).cancel_pipeline
#
# Expectation: rollout 10% job will be canceled. Following stages will be skipped.
#
# ### Reproduce the scenario ~ when user canceled rollout 10% job after rollout 10% job is scheduled ~
#
# 1. ScheduledJobFixture.new(16, 1).create_pipeline('master')
# 1. ScheduledJobFixture.new(16, 1).finish_stage_until('test')
# 1. Run next command before rollout 10% job is triggered
# 1. ScheduledJobFixture.new(16, 1).cancel_jobs('rollout 10%')
#
# Expectation: rollout 10% job will be canceled. Following stages will be skipped.
#
# ### Reproduce the scenario ~ when user played rollout 10% job immidiately ~
#
# 1. ScheduledJobFixture.new(16, 1).create_pipeline('master')
# 1. ScheduledJobFixture.new(16, 1).finish_stage_until('test')
# 1. Play rollout 10% job before rollout 10% job is triggered
#
# Expectation: rollout 10% becomes pending immidiately
#
# ### Reproduce the scenario ~ when rollout 10% job is allowed to fail ~
#
# 1. Set `allow_failure: true` to rollout 10% job
# 1. ScheduledJobFixture.new(16, 1).create_pipeline('master')
# 1. ScheduledJobFixture.new(16, 1).finish_stage_until('test')
# 1. Wait until rollout 10% job is triggered
# 1. ScheduledJobFixture.new(16, 1).drop_jobs('rollout 10%')
#
# Expectation: rollout 50% job should be triggered
#
class ScheduledJobFixture
attr_reader :project
attr_reader :user
include GitlabRoutingHelper
def initialize(project_id, user_id)
@project = Project.find_by_id(project_id)
@user = User.find_by_id(user_id)
end
def create_pipeline(ref)
pipeline = Ci::CreatePipelineService.new(project, user, ref: ref).execute(:web)
Rails.application.routes.url_helpers.namespace_project_pipeline_url(project.namespace, project, pipeline)
end
def finish_stage_until(stage_name)
pipeline = Ci::Pipeline.last
pipeline.stages.order(:id).each do |stage|
stage.builds.map(&:success)
stage.update_status
pipeline.update_status
return if stage.name == stage_name
end
end
def run_jobs(stage_name)
pipeline = Ci::Pipeline.last
stage = pipeline.stages.find_by_name(stage_name)
stage.builds.map(&:run)
stage.update_status
pipeline.update_status
end
def drop_jobs(stage_name)
pipeline = Ci::Pipeline.last
stage = pipeline.stages.find_by_name(stage_name)
stage.builds.map(&:drop)
stage.update_status
pipeline.update_status
end
def cancel_jobs(stage_name)
pipeline = Ci::Pipeline.last
stage = pipeline.stages.find_by_name(stage_name)
stage.builds.map(&:cancel)
stage.update_status
pipeline.update_status
end
def cancel_pipeline
Ci::Pipeline.last.cancel_running
end
end