Commit d1045bff authored by Felipe Artur's avatar Felipe Artur

Backfill TestReports issue_id column

Backfill requirements_management_test_reports.issue_id column
on database. Part of the deprecation of Requirement objects
in favor of work items(issues).

Changelog: other
parent 23b4f600
# frozen_string_literal: true
class SchedulePopulateTestReportsIssueId < Gitlab::Database::Migration[1.0]
MIGRATION = 'PopulateTestReportsIssueId'
DELAY_INTERVAL = 2.minutes.to_i
BATCH_SIZE = 30
disable_ddl_transaction!
def up
queue_background_migration_jobs_by_range_at_intervals(
define_batchable_model('requirements_management_test_reports').where(issue_id: nil),
MIGRATION,
DELAY_INTERVAL,
batch_size: BATCH_SIZE,
track_jobs: true
)
end
def down
# no-op
end
end
55ad00b1cf70f5d1a3f033efccf64c2c273ad03f65823a2281869849571ab35b
\ No newline at end of file
# frozen_string_literal: true
module EE
module Gitlab
module BackgroundMigration
# Backfills RequirementsManagement::TestReport issue_id column
# Part of the plan to migrate requirements to work items(issues)
# More information at: https://gitlab.com/groups/gitlab-org/-/epics/7148
module PopulateTestReportsIssueId
def perform(start_id, end_id)
sql = <<~SQL
UPDATE requirements_management_test_reports AS test_reports
SET issue_id = requirements.issue_id
FROM requirements
WHERE test_reports.requirement_id = requirements.id
AND test_reports.issue_id IS NULL
AND test_reports.id BETWEEN #{start_id} AND #{end_id}
SQL
ActiveRecord::Base.connection.execute(sql)
mark_job_as_succeeded(start_id, end_id)
end
private
def mark_job_as_succeeded(*arguments)
::Gitlab::Database::BackgroundMigrationJob.mark_all_as_succeeded(
self.class.name.demodulize,
arguments
)
end
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::BackgroundMigration::PopulateTestReportsIssueId, schema: 20211220174504 do
let(:issues) { table(:issues) }
let(:requirements) { table(:requirements) }
let(:namespaces) { table(:namespaces) }
let(:users) { table(:users) }
let(:projects) { table(:projects) }
let(:test_reports) { table(:requirements_management_test_reports) }
let!(:group) { namespaces.create!(name: 'gitlab', path: 'gitlab-org') }
let!(:project) { projects.create!(namespace_id: group.id, name: 'gitlab', path: 'gitlab') }
let!(:user) { users.create!(email: 'author@example.com', notification_email: 'author@example.com', name: 'author', username: 'author', projects_limit: 10, state: 'active') }
let!(:issue_1) { issues.create!(iid: 10, state_id: 1, project_id: project.id) }
let!(:issue_2) { issues.create!(iid: 11, state_id: 2, project_id: project.id) }
let!(:requirement_1) { requirements.create!(iid: 10, project_id: project.id, author_id: user.id, issue_id: issue_1.id, title: 'r 1', state: 1, created_at: 2.days.ago, updated_at: 1.day.ago) }
let!(:requirement_2) { requirements.create!(iid: 11, project_id: project.id, author_id: user.id, issue_id: issue_2.id, title: 'r 1', state: 1, created_at: 2.days.ago, updated_at: 1.day.ago) }
let!(:test_report_1) { test_reports.create!(requirement_id: requirement_1.id, state: 1) }
let!(:test_report_2) { test_reports.create!(requirement_id: requirement_2.id, state: 1, issue_id: issue_1.id) }
let!(:test_report_3) { test_reports.create!(requirement_id: requirement_2.id, state: 2) }
let!(:test_report_4) { test_reports.create!(requirement_id: requirement_1.id, state: 2) }
let(:migration) { described_class::MIGRATION }
it 'links test reports to requirement issues' do
expect do
described_class.new.perform(test_report_1.id, test_report_3.id)
end
.to change { test_report_1.reload.issue_id }.from(nil).to(requirement_1.issue_id)
.and not_change { test_report_2.reload.issue_id }
.and change { test_report_3.reload.issue_id }.from(nil).to(requirement_2.issue_id)
.and not_change { test_report_4.reload.issue_id }
end
end
# frozen_string_literal: true
require 'spec_helper'
require Rails.root.join('db', 'post_migrate', '20220110171049_schedule_populate_test_reports_issue_id.rb')
RSpec.describe SchedulePopulateTestReportsIssueId do
let(:issues) { table(:issues) }
let(:requirements) { table(:requirements) }
let(:namespaces) { table(:namespaces) }
let(:users) { table(:users) }
let(:projects) { table(:projects) }
let(:test_reports) { table(:requirements_management_test_reports) }
let!(:group) { namespaces.create!(name: 'gitlab', path: 'gitlab-org') }
let!(:project) { projects.create!(namespace_id: group.id, name: 'gitlab', path: 'gitlab') }
let!(:user) { users.create!(email: 'author@example.com', notification_email: 'author@example.com', name: 'author', username: 'author', projects_limit: 10, state: 'active') }
let!(:issue_1) { issues.create!(iid: 10, state_id: 1, project_id: project.id) }
let!(:issue_2) { issues.create!(iid: 11, state_id: 2, project_id: project.id) }
let!(:requirement_1) { requirements.create!(iid: 10, project_id: project.id, author_id: user.id, issue_id: issue_1.id, title: 'r 1', state: 1, created_at: 2.days.ago, updated_at: 1.day.ago) }
let!(:requirement_2) { requirements.create!(iid: 11, project_id: project.id, author_id: user.id, issue_id: issue_2.id, title: 'r 1', state: 1, created_at: 2.days.ago, updated_at: 1.day.ago) }
let!(:test_report_1) { test_reports.create!(requirement_id: requirement_1.id, state: 1) }
let!(:test_report_2) { test_reports.create!(requirement_id: requirement_2.id, state: 1, issue_id: issue_1.id) }
let!(:test_report_3) { test_reports.create!(requirement_id: requirement_2.id, state: 2) }
let!(:test_report_4) { test_reports.create!(requirement_id: requirement_1.id, state: 2) }
let!(:test_report_5) { test_reports.create!(requirement_id: requirement_1.id, state: 1) }
let(:migration) { described_class::MIGRATION }
before do
Sidekiq::Worker.clear_all
stub_const("#{described_class.name}::BATCH_SIZE", 2)
end
it 'schedules jobs correctly for test reports with null issue_id' do
Sidekiq::Testing.fake! do
freeze_time do
migrate!
expect(migration).to be_scheduled_delayed_migration(120.seconds, test_report_1.id, test_report_3.id)
expect(migration).to be_scheduled_delayed_migration(240.seconds, test_report_4.id, test_report_5.id)
expect(BackgroundMigrationWorker.jobs.size).to eq(2)
end
end
end
end
# frozen_string_literal: true
# rubocop: disable Style/Documentation
module Gitlab
module BackgroundMigration
class PopulateTestReportsIssueId
def perform(start_id, stop_id)
# NO OP
end
end
end
end
Gitlab::BackgroundMigration::PopulateTestReportsIssueId.prepend_mod
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment