Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-03-25 03:08:11 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-03-25 03:08:11 +0300
commit23bc19cb73aad969c9636b8b935111645e809e54 (patch)
tree887c9e014f8345f577769db4f75315ca59853b98 /db/fixtures
parentc4db541c1b2c97ab1eda354ea3899489fe5c33e5 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'db/fixtures')
-rw-r--r--db/fixtures/development/17_cycle_analytics.rb342
1 files changed, 153 insertions, 189 deletions
diff --git a/db/fixtures/development/17_cycle_analytics.rb b/db/fixtures/development/17_cycle_analytics.rb
index 2bf3c918006..1bdaabad704 100644
--- a/db/fixtures/development/17_cycle_analytics.rb
+++ b/db/fixtures/development/17_cycle_analytics.rb
@@ -1,240 +1,204 @@
+# frozen_string_literal: true
+
require './spec/support/sidekiq_middleware'
require './spec/support/helpers/test_env'
+# Usage:
+#
+# Simple invocation always creates a new project:
+#
+# FILTER=cycle_analytics SEED_CYCLE_ANALYTICS=1 bundle exec rake db:seed_fu
+#
+# Create more issues/MRs:
+#
+# CYCLE_ANALYTICS_ISSUE_COUNT=100 FILTER=cycle_analytics SEED_CYCLE_ANALYTICS=1 bundle exec rake db:seed_fu
+#
+# Run for an existing project
+#
+# CYCLE_ANALYTICS_SEED_PROJECT_ID=10 FILTER=cycle_analytics SEED_CYCLE_ANALYTICS=1 bundle exec rake db:seed_fu
+
class Gitlab::Seeder::CycleAnalytics
- def initialize(project, perf: false)
- @project = project
- @user = User.admins.first
- @issue_count = perf ? 1000 : ENV.fetch('CYCLE_ANALYTICS_ISSUE_COUNT', 5).to_i
+ attr_reader :project, :issues, :merge_requests, :developers
+
+ FLAG = 'SEED_CYCLE_ANALYTICS'
+ PERF_TEST = 'CYCLE_ANALYTICS_PERF_TEST'
+
+ ISSUE_STAGE_MAX_DURATION_IN_HOURS = 72
+ PLAN_STAGE_MAX_DURATION_IN_HOURS = 48
+ CODE_STAGE_MAX_DURATION_IN_HOURS = 72
+ TEST_STAGE_MAX_DURATION_IN_HOURS = 5
+ REVIEW_STAGE_MAX_DURATION_IN_HOURS = 72
+ DEPLOYMENT_MAX_DURATION_IN_HOURS = 48
+
+ def self.seeder_base_on_env(project)
+ if ENV[FLAG]
+ self.new(project: project)
+ elsif ENV[PERF_TEST]
+ self.new(project: project, perf: true)
+ end
end
- def seed_metrics!
- @issue_count.times do |index|
- # Issue
- Timecop.travel 5.days.from_now
- title = "#{FFaker::Product.brand}-#{FFaker::Product.brand}-#{rand(1000)}"
- issue = Issue.create(project: @project, title: title, author: @user)
- issue_metrics = issue.metrics
-
- # Milestones / Labels
- Timecop.travel 5.days.from_now
-
- if index.even?
- issue_metrics.first_associated_with_milestone_at = rand(6..12).hours.from_now
- else
- issue_metrics.first_added_to_board_at = rand(6..12).hours.from_now
- end
-
- # Commit
- Timecop.travel 5.days.from_now
- issue_metrics.first_mentioned_in_commit_at = rand(6..12).hours.from_now
-
- # MR
- Timecop.travel 5.days.from_now
- branch_name = "#{FFaker::Product.brand}-#{FFaker::Product.brand}-#{rand(1000)}"
- @project.repository.add_branch(@user, branch_name, 'master')
- merge_request = MergeRequest.create(target_project: @project, source_project: @project, source_branch: branch_name, target_branch: 'master', title: branch_name, author: @user)
- merge_request_metrics = merge_request.metrics
-
- # MR closing issues
- Timecop.travel 5.days.from_now
- MergeRequestsClosingIssues.create!(issue: issue, merge_request: merge_request)
-
- # Merge
- Timecop.travel 5.days.from_now
- merge_request_metrics.merged_at = rand(6..12).hours.from_now
-
- # Start build
- Timecop.travel 5.days.from_now
- merge_request_metrics.latest_build_started_at = rand(6..12).hours.from_now
-
- # Finish build
- Timecop.travel 5.days.from_now
- merge_request_metrics.latest_build_finished_at = rand(6..12).hours.from_now
-
- # Deploy to production
- Timecop.travel 5.days.from_now
- merge_request_metrics.first_deployed_to_production_at = rand(6..12).hours.from_now
-
- issue_metrics.save!
- merge_request_metrics.save!
-
- print '.'
- end
+ def initialize(project: nil, perf: false)
+ @project = project || create_new_vsm_project
+ @issue_count = perf ? 1000 : ENV.fetch('CYCLE_ANALYTICS_ISSUE_COUNT', 5).to_i
+ @issues = []
+ @merge_requests = []
+ @developers = []
end
def seed!
- Sidekiq::Worker.skipping_transaction_check do
- Sidekiq::Testing.inline! do
- issues = create_issues
- puts '.'
-
- # Stage 1
- Timecop.travel 5.days.from_now
- add_milestones_and_list_labels(issues)
- print '.'
-
- # Stage 2
- Timecop.travel 5.days.from_now
- branches = mention_in_commits(issues)
- print '.'
-
- # Stage 3
- Timecop.travel 5.days.from_now
- merge_requests = create_merge_requests_closing_issues(issues, branches)
- print '.'
-
- # Stage 4
- Timecop.travel 5.days.from_now
- run_builds(merge_requests)
- print '.'
-
- # Stage 5
- Timecop.travel 5.days.from_now
- merge_merge_requests(merge_requests)
- print '.'
-
- # Stage 6 / 7
- Timecop.travel 5.days.from_now
- deploy_to_production(merge_requests)
- print '.'
- end
- end
-
- print '.'
+ create_developers!
+ create_issues!
+
+ seed_issue_stage!
+ seed_plan_stage!
+ seed_code_stage!
+ seed_test_stage!
+ seed_review_stage!
+ seed_staging_stage!
+
+ puts "Successfully seeded '#{project.full_path}' for Value Stream Management!"
+ puts "URL: #{Rails.application.routes.url_helpers.project_url(project)}"
end
private
- def create_issues
- Array.new(@issue_count) do
- issue_params = {
- title: "Value Stream Analytics: #{FFaker::Lorem.sentence(6)}",
- description: FFaker::Lorem.sentence,
- state: 'opened',
- assignees: [@project.team.users.sample]
- }
-
- Issues::CreateService.new(@project, @project.team.users.sample, issue_params).execute
- end
- end
-
- def add_milestones_and_list_labels(issues)
- issues.shuffle.map.with_index do |issue, index|
- Timecop.travel 12.hours.from_now
+ def seed_issue_stage!
+ issues.each do |issue|
+ time = within_end_time(issue.created_at + rand(ISSUE_STAGE_MAX_DURATION_IN_HOURS).hours)
- if index.even?
- issue.update(milestone: @project.milestones.sample)
+ if issue.id.even?
+ issue.metrics.update!(first_associated_with_milestone_at: time)
else
- label_name = "#{FFaker::Product.brand}-#{FFaker::Product.brand}-#{rand(1000)}"
- list_label = FactoryBot.create(:label, title: label_name, project: issue.project)
- FactoryBot.create(:list, board: FactoryBot.create(:board, project: issue.project), label: list_label)
- issue.update(labels: [list_label])
+ issue.metrics.update!(first_added_to_board_at: time)
end
-
- issue
end
end
- def mention_in_commits(issues)
- issues.map do |issue|
- Timecop.travel 12.hours.from_now
+ def seed_plan_stage!
+ issues.each do |issue|
+ plan_stage_start = issue.metrics.first_associated_with_milestone_at || issue.metrics.first_added_to_board_at
- branch_name = filename = "#{FFaker::Product.brand}-#{FFaker::Product.brand}-#{rand(1000)}"
+ first_mentioned_in_commit_at = within_end_time(plan_stage_start + rand(PLAN_STAGE_MAX_DURATION_IN_HOURS).hours)
+ issue.metrics.update!(first_mentioned_in_commit_at: first_mentioned_in_commit_at)
+ end
+ end
- issue.project.repository.add_branch(@user, branch_name, 'master')
+ def seed_code_stage!
+ issues.each do |issue|
+ merge_request = FactoryBot.create(
+ :merge_request,
+ target_project: project,
+ source_project: project,
+ source_branch: "#{issue.iid}-feature-branch",
+ target_branch: 'master',
+ author: developers.sample,
+ created_at: within_end_time(issue.metrics.first_mentioned_in_commit_at + rand(CODE_STAGE_MAX_DURATION_IN_HOURS).hours)
+ )
- commit_sha = issue.project.repository.create_file(@user, filename, "content", message: "Commit for #{issue.to_reference}", branch_name: branch_name)
- issue.project.repository.commit(commit_sha)
+ @merge_requests << merge_request
- ::Git::BranchPushService.new(
- issue.project,
- @user,
- change: {
- oldrev: issue.project.repository.commit("master").sha,
- newrev: commit_sha,
- ref: 'refs/heads/master'
- }
- ).execute
+ MergeRequestsClosingIssues.create!(issue: issue, merge_request: merge_request)
+ end
+ end
- branch_name
+ def seed_test_stage!
+ merge_requests.each do |merge_request|
+ pipeline = FactoryBot.create(:ci_pipeline, :success, project: project)
+ build = FactoryBot.create(:ci_build, pipeline: pipeline, project: project, user: developers.sample)
+
+ merge_request.metrics.update!(
+ latest_build_started_at: merge_request.created_at,
+ latest_build_finished_at: within_end_time(merge_request.created_at + TEST_STAGE_MAX_DURATION_IN_HOURS.hours),
+ pipeline_id: build.commit_id
+ )
end
end
- def create_merge_requests_closing_issues(issues, branches)
- issues.zip(branches).map do |issue, branch|
- Timecop.travel 12.hours.from_now
+ def seed_review_stage!
+ merge_requests.each do |merge_request|
+ merge_request.metrics.update!(merged_at: within_end_time(merge_request.created_at + REVIEW_STAGE_MAX_DURATION_IN_HOURS.hours))
+ end
+ end
- opts = {
- title: 'Value Stream Analytics merge_request',
- description: "Fixes #{issue.to_reference}",
- source_branch: branch,
- target_branch: 'master'
- }
+ def seed_staging_stage!
+ merge_requests.each do |merge_request|
+ merge_request.metrics.update!(first_deployed_to_production_at: within_end_time(merge_request.metrics.merged_at + DEPLOYMENT_MAX_DURATION_IN_HOURS.hours))
+ end
+ end
- MergeRequests::CreateService.new(issue.project, @user, opts).execute
+ def create_issues!
+ @issue_count.times do
+ Timecop.travel start_time + rand(5).days do
+ title = "#{FFaker::Product.brand}-#{suffix}"
+ @issues << Issue.create!(project: project, title: title, author: developers.sample)
+ end
end
end
- def run_builds(merge_requests)
- merge_requests.each do |merge_request|
- Timecop.travel 12.hours.from_now
+ def create_developers!
+ 5.times do |i|
+ user = FactoryBot.create(
+ :user,
+ name: "VSM User#{i}",
+ username: "vsm-user-#{i}-#{suffix}",
+ email: "vsm-user-#{i}@#{suffix}.com"
+ )
- service = Ci::CreatePipelineService.new(merge_request.project,
- @user,
- ref: "refs/heads/#{merge_request.source_branch}")
- pipeline = service.execute(:push, ignore_skip_ci: true, save_on_errors: false)
+ project.group.add_developer(user)
+ project.add_developer(user)
- pipeline.builds.each(&:enqueue) # make sure all pipelines in pending state
- pipeline.builds.each(&:run!)
- pipeline.update_legacy_status
+ @developers << user
end
end
- def merge_merge_requests(merge_requests)
- merge_requests.each do |merge_request|
- Timecop.travel 12.hours.from_now
+ def create_new_vsm_project
+ project = FactoryBot.create(
+ :project,
+ name: "Value Stream Management Project #{suffix}",
+ path: "vsmp-#{suffix}",
+ creator: admin,
+ namespace: FactoryBot.create(
+ :group,
+ name: "Value Stream Management Group (#{suffix})",
+ path: "vsmg-#{suffix}"
+ )
+ )
+
+ project.create_repository
+ project
+ end
- MergeRequests::MergeService.new(merge_request.project, @user).execute(merge_request)
- end
+ def admin
+ @admin ||= User.admins.first
end
- def deploy_to_production(merge_requests)
- merge_requests.each do |merge_request|
- next unless merge_request.head_pipeline
+ def suffix
+ @suffix ||= Time.now.to_i
+ end
- Timecop.travel 12.hours.from_now
+ def start_time
+ @start_time ||= 25.days.ago
+ end
- job = merge_request.head_pipeline.builds.where.not(environment: nil).last
+ def end_time
+ @end_time ||= Time.now
+ end
- job.success!
- job.pipeline.update_legacy_status
- end
+ def within_end_time(time)
+ [time, end_time].min
end
end
Gitlab::Seeder.quiet do
- flag = 'SEED_CYCLE_ANALYTICS'
-
- if ENV[flag]
- Project.not_mass_generated.find_each do |project|
- # This seed naively assumes that every project has a repository, and every
- # repository has a `master` branch, which may be the case for a pristine
- # GDK seed, but is almost never true for a GDK that's actually had
- # development performed on it.
- next unless project.repository_exists?
- next unless project.repository.commit('master')
-
- seeder = Gitlab::Seeder::CycleAnalytics.new(project)
- seeder.seed!
- end
- elsif ENV['CYCLE_ANALYTICS_PERF_TEST']
- seeder = Gitlab::Seeder::CycleAnalytics.new(Project.order(:id).first, perf: true)
+ project_id = ENV['CYCLE_ANALYTICS_SEED_PROJECT_ID']
+ project = Project.find(project_id) if project_id
+
+ seeder = Gitlab::Seeder::CycleAnalytics.seeder_base_on_env(project)
+
+ if seeder
seeder.seed!
- elsif ENV['CYCLE_ANALYTICS_POPULATE_METRICS_DIRECTLY']
- seeder = Gitlab::Seeder::CycleAnalytics.new(Project.order(:id).first, perf: true)
- seeder.seed_metrics!
else
- puts "Skipped. Use the `#{flag}` environment variable to enable."
+ puts "Skipped. Use the `#{Gitlab::Seeder::CycleAnalytics::FLAG}` environment variable to enable."
end
end