diff --git a/db/docs/batched_background_migrations/backfill_jira_tracker_data_sharding_key.yml b/db/docs/batched_background_migrations/backfill_jira_tracker_data_sharding_key.yml index ce3167e908af7d9d46132f5f7d7d1b3708a8ad57..6698ef878d7c6fc0e0aea53c4633e557ccaf9362 100644 --- a/db/docs/batched_background_migrations/backfill_jira_tracker_data_sharding_key.yml +++ b/db/docs/batched_background_migrations/backfill_jira_tracker_data_sharding_key.yml @@ -7,4 +7,4 @@ feature_category: integrations introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/197199 milestone: '18.4' queued_migration_version: 20250818084641 -finalized_by: # version of the migration that finalized this BBM +finalized_by: '20251006104739' diff --git a/db/docs/jira_tracker_data.yml b/db/docs/jira_tracker_data.yml index 2dbf419e26f771a707d73b9bb752764d209e2337..4fd19fd7c6666e664d1352b4887c0011bce3141a 100644 --- a/db/docs/jira_tracker_data.yml +++ b/db/docs/jira_tracker_data.yml @@ -8,5 +8,8 @@ description: Data related to the Jira integration. introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/1f332ae8da994509232c7601074b25514ad23c52 milestone: '12.0' gitlab_schema: gitlab_main_org -sharding_key_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/558259 table_size: small +sharding_key: + project_id: projects + group_id: namespaces + organization_id: organizations diff --git a/db/post_migrate/20250930134216_add_jira_tracker_data_index_on_id_group_id_organization_id.rb b/db/post_migrate/20250930134216_add_jira_tracker_data_index_on_id_group_id_organization_id.rb new file mode 100644 index 0000000000000000000000000000000000000000..3fdc9f4ac7a629d0517be5cb920206b67bbefc04 --- /dev/null +++ b/db/post_migrate/20250930134216_add_jira_tracker_data_index_on_id_group_id_organization_id.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +class AddJiraTrackerDataIndexOnIdGroupIdOrganizationId < Gitlab::Database::Migration[2.3] + milestone '18.5' + disable_ddl_transaction! + + INDEX_NAME = 'tmp_idx_jira_tracker_data_on_id_group_id_organization_id' + + def up + add_concurrent_index( + :jira_tracker_data, + :id, + where: 'group_id IS NOT NULL AND organization_id IS NOT NULL', + name: INDEX_NAME + ) + end + + def down + remove_concurrent_index_by_name :jira_tracker_data, INDEX_NAME + end +end diff --git a/db/post_migrate/20250930134220_add_jira_tracker_data_index_on_id_project_id_organization_id.rb b/db/post_migrate/20250930134220_add_jira_tracker_data_index_on_id_project_id_organization_id.rb new file mode 100644 index 0000000000000000000000000000000000000000..4b6dc36a06f1213aa44cf9ede3144b5fa064f91b --- /dev/null +++ b/db/post_migrate/20250930134220_add_jira_tracker_data_index_on_id_project_id_organization_id.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +class AddJiraTrackerDataIndexOnIdProjectIdOrganizationId < Gitlab::Database::Migration[2.3] + milestone '18.5' + disable_ddl_transaction! + + INDEX_NAME = 'tmp_idx_jira_tracker_data_on_id_project_id_organization_id' + + def up + add_concurrent_index( + :jira_tracker_data, + :id, + where: 'project_id IS NOT NULL AND organization_id IS NOT NULL', + name: INDEX_NAME + ) + end + + def down + remove_concurrent_index_by_name :jira_tracker_data, INDEX_NAME + end +end diff --git a/db/post_migrate/20250930134225_add_jira_tracker_data_multiple_column_not_null_constraint.rb b/db/post_migrate/20250930134225_add_jira_tracker_data_multiple_column_not_null_constraint.rb new file mode 100644 index 0000000000000000000000000000000000000000..e387a8eec290e1e3679a2669a95e2599cd383048 --- /dev/null +++ b/db/post_migrate/20250930134225_add_jira_tracker_data_multiple_column_not_null_constraint.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +class AddJiraTrackerDataMultipleColumnNotNullConstraint < Gitlab::Database::Migration[2.3] + milestone '18.5' + disable_ddl_transaction! + + def up + add_multi_column_not_null_constraint( + :jira_tracker_data, + :project_id, + :group_id, + :organization_id, + validate: false + ) + end + + def down + remove_multi_column_not_null_constraint( + :jira_tracker_data, + :project_id, + :group_id, + :organization_id + ) + end +end diff --git a/db/post_migrate/20250930134230_backfill_group_jira_tracker_data_organization_id.rb b/db/post_migrate/20250930134230_backfill_group_jira_tracker_data_organization_id.rb new file mode 100644 index 0000000000000000000000000000000000000000..61a9d1a34fe5e44a808adf60c77d43f9d67ef2f0 --- /dev/null +++ b/db/post_migrate/20250930134230_backfill_group_jira_tracker_data_organization_id.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +class BackfillGroupJiraTrackerDataOrganizationId < Gitlab::Database::Migration[2.3] + milestone '18.5' + restrict_gitlab_migration gitlab_schema: :gitlab_main_org + disable_ddl_transaction! + + BATCH_SIZE = 1000 + + def up + jira_tracker_data = define_batchable_model('jira_tracker_data') + + jira_tracker_data + .where.not(group_id: nil) + .where.not(organization_id: nil) + .each_batch(of: BATCH_SIZE) do |batch| + batch.update_all(organization_id: nil) + end + end + + def down + # no-op + end +end diff --git a/db/post_migrate/20250930134235_backfill_project_jira_tracker_data_organization_id.rb b/db/post_migrate/20250930134235_backfill_project_jira_tracker_data_organization_id.rb new file mode 100644 index 0000000000000000000000000000000000000000..8ae57284a532daf3d74598d82484686ea374cd02 --- /dev/null +++ b/db/post_migrate/20250930134235_backfill_project_jira_tracker_data_organization_id.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +class BackfillProjectJiraTrackerDataOrganizationId < Gitlab::Database::Migration[2.3] + milestone '18.5' + restrict_gitlab_migration gitlab_schema: :gitlab_main_org + disable_ddl_transaction! + + BATCH_SIZE = 1000 + + def up + jira_tracker_data = define_batchable_model('jira_tracker_data') + + jira_tracker_data + .where.not(project_id: nil) + .where.not(organization_id: nil) + .each_batch(of: BATCH_SIZE) do |batch| + batch.update_all(organization_id: nil) + end + end + + def down + # no-op + end +end diff --git a/db/post_migrate/20250930134240_validate_jira_tracker_data_multiple_column_not_null_constraint.rb b/db/post_migrate/20250930134240_validate_jira_tracker_data_multiple_column_not_null_constraint.rb new file mode 100644 index 0000000000000000000000000000000000000000..7ffd86ab6c4d5d8c14170aa867e44b66850abab1 --- /dev/null +++ b/db/post_migrate/20250930134240_validate_jira_tracker_data_multiple_column_not_null_constraint.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +class ValidateJiraTrackerDataMultipleColumnNotNullConstraint < Gitlab::Database::Migration[2.3] + milestone '18.5' + + CONSTRAINT_NAME = 'check_eca1fbd6bd' + + def up + validate_multi_column_not_null_constraint( + :jira_tracker_data, + :project_id, + :group_id, + :organization_id, + constraint_name: CONSTRAINT_NAME + ) + end + + def down + # no-op + end +end diff --git a/db/post_migrate/20250930134245_remove_jira_tracker_data_index_on_id_group_id_organization_id.rb b/db/post_migrate/20250930134245_remove_jira_tracker_data_index_on_id_group_id_organization_id.rb new file mode 100644 index 0000000000000000000000000000000000000000..a4403aeb05532cfe8fce4cc897483c307f75a572 --- /dev/null +++ b/db/post_migrate/20250930134245_remove_jira_tracker_data_index_on_id_group_id_organization_id.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +class RemoveJiraTrackerDataIndexOnIdGroupIdOrganizationId < Gitlab::Database::Migration[2.3] + milestone '18.5' + disable_ddl_transaction! + + INDEX_NAME = 'tmp_idx_jira_tracker_data_on_id_group_id_organization_id' + + def up + remove_concurrent_index_by_name :jira_tracker_data, INDEX_NAME + end + + def down + add_concurrent_index( + :jira_tracker_data, + :id, + where: 'group_id IS NOT NULL AND organization_id IS NOT NULL', + name: INDEX_NAME + ) + end +end diff --git a/db/post_migrate/20250930134250_remove_jira_tracker_data_index_on_id_project_id_organization_id.rb b/db/post_migrate/20250930134250_remove_jira_tracker_data_index_on_id_project_id_organization_id.rb new file mode 100644 index 0000000000000000000000000000000000000000..feeeeb1f8a0c937a7752513fa984328e61865387 --- /dev/null +++ b/db/post_migrate/20250930134250_remove_jira_tracker_data_index_on_id_project_id_organization_id.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +class RemoveJiraTrackerDataIndexOnIdProjectIdOrganizationId < Gitlab::Database::Migration[2.3] + milestone '18.5' + disable_ddl_transaction! + + INDEX_NAME = 'tmp_idx_jira_tracker_data_on_id_project_id_organization_id' + + def up + remove_concurrent_index_by_name :jira_tracker_data, INDEX_NAME + end + + def down + add_concurrent_index( + :jira_tracker_data, + :id, + where: 'project_id IS NOT NULL AND organization_id IS NOT NULL', + name: INDEX_NAME + ) + end +end diff --git a/db/post_migrate/20251006104739_finalize_backfill_jira_tracker_data_sharding_key.rb b/db/post_migrate/20251006104739_finalize_backfill_jira_tracker_data_sharding_key.rb new file mode 100644 index 0000000000000000000000000000000000000000..6bae01b05318be06c9a584d0837c13ddac6afae4 --- /dev/null +++ b/db/post_migrate/20251006104739_finalize_backfill_jira_tracker_data_sharding_key.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +class FinalizeBackfillJiraTrackerDataShardingKey < Gitlab::Database::Migration[2.3] + milestone '18.5' + disable_ddl_transaction! + restrict_gitlab_migration gitlab_schema: :gitlab_main_org + + def up + ensure_batched_background_migration_is_finished( + job_class_name: 'BackfillJiraTrackerDataShardingKey', + table_name: :jira_tracker_data, + column_name: :id, + job_arguments: [], + finalize: true + ) + end + + def down; end +end diff --git a/db/schema_migrations/20250930134216 b/db/schema_migrations/20250930134216 new file mode 100644 index 0000000000000000000000000000000000000000..f52bb0ab80919ff67fbd01120bc59e66b84695a8 --- /dev/null +++ b/db/schema_migrations/20250930134216 @@ -0,0 +1 @@ +40fe1d93503a054bb7f11d929ff324b02a757421ce6e9da6b194334049a8f7b2 \ No newline at end of file diff --git a/db/schema_migrations/20250930134220 b/db/schema_migrations/20250930134220 new file mode 100644 index 0000000000000000000000000000000000000000..08429ed19b55ec85513f28374533a8cb6b9a09b3 --- /dev/null +++ b/db/schema_migrations/20250930134220 @@ -0,0 +1 @@ +35b61b57731eecefa8495ff06583be305d194cdee0a623607c44daa8f8a2d6ca \ No newline at end of file diff --git a/db/schema_migrations/20250930134225 b/db/schema_migrations/20250930134225 new file mode 100644 index 0000000000000000000000000000000000000000..d3c2d22f6b4d8d4064b6b83f5ce262dfd7ac74c7 --- /dev/null +++ b/db/schema_migrations/20250930134225 @@ -0,0 +1 @@ +ab306d746698954a0fa9946d435ecf20dc89d0c38c3e1c798469651735ebfe02 \ No newline at end of file diff --git a/db/schema_migrations/20250930134230 b/db/schema_migrations/20250930134230 new file mode 100644 index 0000000000000000000000000000000000000000..3d31e1fe20df9df3a50ef4d4cb8281d3fbd1e9cb --- /dev/null +++ b/db/schema_migrations/20250930134230 @@ -0,0 +1 @@ +1a184fba7636c37e77d7b9fe19eb2ae207d4bef93abcbe8fd31b0bf8e920e36e \ No newline at end of file diff --git a/db/schema_migrations/20250930134235 b/db/schema_migrations/20250930134235 new file mode 100644 index 0000000000000000000000000000000000000000..968c51ef62e1140b66d51122e7d3aba3bfaa7e52 --- /dev/null +++ b/db/schema_migrations/20250930134235 @@ -0,0 +1 @@ +983bf2a71e0a4cd564bfd90284c306af41f6b62d9984ad4c7a60aa96f00213b0 \ No newline at end of file diff --git a/db/schema_migrations/20250930134240 b/db/schema_migrations/20250930134240 new file mode 100644 index 0000000000000000000000000000000000000000..91b37da91dab5db263776c4a904e773f2b822eb4 --- /dev/null +++ b/db/schema_migrations/20250930134240 @@ -0,0 +1 @@ +9875bf5a8b745cbb8ed4ce512417dc489b2acf510e061f479538b9b244597233 \ No newline at end of file diff --git a/db/schema_migrations/20250930134245 b/db/schema_migrations/20250930134245 new file mode 100644 index 0000000000000000000000000000000000000000..676657eec49961d568b7224f39cd6a68ddae3ba9 --- /dev/null +++ b/db/schema_migrations/20250930134245 @@ -0,0 +1 @@ +c2ff243078391f0b2ccf1319687ed4d8c9c55a8b5d271cc650c213428185e8b3 \ No newline at end of file diff --git a/db/schema_migrations/20250930134250 b/db/schema_migrations/20250930134250 new file mode 100644 index 0000000000000000000000000000000000000000..e6c7d47ee284451af76a11da5f744195e0509e01 --- /dev/null +++ b/db/schema_migrations/20250930134250 @@ -0,0 +1 @@ +f498697a2983c0f2c3ffabe1b8af5c525a04f464cf2b915edde0e8c79b583990 \ No newline at end of file diff --git a/db/schema_migrations/20251006104739 b/db/schema_migrations/20251006104739 new file mode 100644 index 0000000000000000000000000000000000000000..28d0bc94f04fda99a70c31d1028a2bd7d3d7f7bd --- /dev/null +++ b/db/schema_migrations/20251006104739 @@ -0,0 +1 @@ +7022970024ba227991a71ba7c25ed0008eef194ee25522071ec91fcee7c824c9 \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 080cfa1218a0f7d9677b2716b394072efc2927c6..458fdd1ce91b9aab2d9c65530e81f31ed9c1923f 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -18865,7 +18865,8 @@ CREATE TABLE jira_tracker_data ( CONSTRAINT check_214cf6a48b CHECK ((char_length(project_key) <= 255)), CONSTRAINT check_4cc5bbc801 CHECK ((char_length(jira_issue_prefix) <= 255)), CONSTRAINT check_9863a0a5fd CHECK ((char_length(jira_issue_regex) <= 255)), - CONSTRAINT check_b5ab881f50 CHECK ((char_length(jira_allowed_statuses_string) <= 1024)) + CONSTRAINT check_b5ab881f50 CHECK ((char_length(jira_allowed_statuses_string) <= 1024)), + CONSTRAINT check_eca1fbd6bd CHECK ((num_nonnulls(group_id, organization_id, project_id) = 1)) ); CREATE SEQUENCE jira_tracker_data_id_seq diff --git a/spec/lib/gitlab/database/sharding_key_spec.rb b/spec/lib/gitlab/database/sharding_key_spec.rb index 1b76e6dac27ea4ae67e496adac5b6f419c913f0f..a24242e59e2df3f102db1ab42be155b707f3f6ad 100644 --- a/spec/lib/gitlab/database/sharding_key_spec.rb +++ b/spec/lib/gitlab/database/sharding_key_spec.rb @@ -312,7 +312,6 @@ "ci_runner_taggings_group_type" => "https://gitlab.com/gitlab-org/gitlab/-/issues/549027", "ci_runner_taggings_project_type" => "https://gitlab.com/gitlab-org/gitlab/-/issues/549028", "customer_relations_contacts" => "https://gitlab.com/gitlab-org/gitlab/-/issues/549029", - "jira_tracker_data" => "https://gitlab.com/gitlab-org/gitlab/-/issues/549032", "abuse_reports" => "https://gitlab.com/gitlab-org/gitlab/-/issues/553435", "abuse_report_labels" => "https://gitlab.com/gitlab-org/gitlab/-/issues/553427", "abuse_report_events" => "https://gitlab.com/gitlab-org/gitlab/-/issues/553429", diff --git a/spec/migrations/backfill_group_jira_tracker_data_organization_id_spec.rb b/spec/migrations/backfill_group_jira_tracker_data_organization_id_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..e8607e8a0d8a048723841a7b36d65ab27ea1e0e9 --- /dev/null +++ b/spec/migrations/backfill_group_jira_tracker_data_organization_id_spec.rb @@ -0,0 +1,107 @@ +# frozen_string_literal: true + +require 'spec_helper' + +require_migration! + +RSpec.describe BackfillGroupJiraTrackerDataOrganizationId, feature_category: :integrations do + let(:organizations) { table(:organizations) } + let(:jira_tracker_data) { table(:jira_tracker_data) } + let(:namespaces) { table(:namespaces) } + let(:projects) { table(:projects) } + let(:integrations) { table(:integrations) } + + let!(:organization) { organizations.create!(id: 1, name: 'Default', path: 'default') } + let!(:group) { namespaces.create!(name: 'bar', path: 'bar', type: 'Group', organization_id: 1) } + + let!(:project) do + projects.create!( + name: 'baz', + path: 'baz', + organization_id: 1, + namespace_id: group.id, + project_namespace_id: group.id + ) + end + + let!(:integration) do + integrations.create!(group_id: group.id, type_new: 'Integrations::Jira') + end + + let(:tracker_data_to_backfill) do + jira_tracker_data.create!(group_id: group.id, integration_id: integration.id, organization_id: organization.id) + end + + let(:another_tracker_data_to_backfill) do + jira_tracker_data.create!(group_id: group.id, integration_id: integration.id, organization_id: organization.id) + end + + let(:valid_tracker_data) do + jira_tracker_data.create!(group_id: group.id, integration_id: integration.id) + end + + let(:project_tracker_data) do + jira_tracker_data.create!(project_id: project.id, integration_id: integration.id) + end + + let(:organization_tracker_data) do + instance_integration = integrations.create!( + instance: true, + organization_id: organization.id, + type_new: 'Integrations::Jira' + ) + + jira_tracker_data.create!(organization_id: organization.id, integration_id: instance_integration.id) + end + + before do + ApplicationRecord.connection.execute('ALTER TABLE jira_tracker_data DROP CONSTRAINT IF EXISTS check_eca1fbd6bd;') + end + + after do + ApplicationRecord + .connection + .execute( + 'ALTER TABLE jira_tracker_data ADD CONSTRAINT check_eca1fbd6bd ' \ + 'CHECK ((num_nonnulls(group_id, organization_id, project_id) = 1)) NOT VALID;' + ) + end + + describe "#up" do + it 'sets organization_id to nil for group jira_tracker_data that have it' do + expect(tracker_data_to_backfill.group_id).to eq(group.id) + expect(tracker_data_to_backfill.organization_id).to eq(organization.id) + + expect(another_tracker_data_to_backfill.group_id).to eq(group.id) + expect(another_tracker_data_to_backfill.organization_id).to eq(organization.id) + + expect(valid_tracker_data.group_id).to eq(group.id) + expect(valid_tracker_data.organization_id).to be_nil + + expect(project_tracker_data.project_id).to eq(project.id) + expect(project_tracker_data.organization_id).to be_nil + + expect(organization_tracker_data.organization_id).to eq(organization.id) + expect(organization_tracker_data.project_id).to be_nil + expect(organization_tracker_data.group_id).to be_nil + + migrate! + + expect(tracker_data_to_backfill.reload.group_id).to eq(group.id) + expect(tracker_data_to_backfill.reload.organization_id).to be_nil + + expect(another_tracker_data_to_backfill.reload.group_id).to eq(group.id) + expect(another_tracker_data_to_backfill.reload.organization_id).to be_nil + + expect(valid_tracker_data.reload.group_id).to eq(group.id) + expect(valid_tracker_data.reload.organization_id).to be_nil + + expect(project_tracker_data.reload.project_id).to eq(project.id) + expect(project_tracker_data.reload.organization_id).to be_nil + + expect(organization_tracker_data.reload.organization_id).to eq(organization.id) + expect(organization_tracker_data.reload.project_id).to be_nil + expect(organization_tracker_data.reload.group_id).to be_nil + end + end +end diff --git a/spec/migrations/backfill_project_jira_tracker_data_organization_id_spec.rb b/spec/migrations/backfill_project_jira_tracker_data_organization_id_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..9b23fc3671c1003bdb22d444dd0d754c1bad6d85 --- /dev/null +++ b/spec/migrations/backfill_project_jira_tracker_data_organization_id_spec.rb @@ -0,0 +1,108 @@ +# frozen_string_literal: true + +require 'spec_helper' + +require_migration! + +RSpec.describe BackfillProjectJiraTrackerDataOrganizationId, feature_category: :integrations do + let(:organizations) { table(:organizations) } + let(:jira_tracker_data) { table(:jira_tracker_data) } + let(:namespaces) { table(:namespaces) } + let(:projects) { table(:projects) } + let(:integrations) { table(:integrations) } + + let!(:organization) { organizations.create!(id: 1, name: 'Default', path: 'default') } + let!(:group) { namespaces.create!(name: 'bar', path: 'bar', type: 'Group', organization_id: 1) } + + let!(:project) do + projects.create!( + name: 'baz', + path: 'baz', + organization_id: 1, + namespace_id: group.id, + project_namespace_id: group.id + ) + end + + let!(:integration) do + integrations.create!(project_id: project.id, type_new: 'Integrations::Jira') + end + + let(:tracker_data_to_backfill) do + jira_tracker_data.create!(project_id: project.id, integration_id: integration.id, organization_id: organization.id) + end + + let(:another_tracker_data_to_backfill) do + jira_tracker_data.create!(project_id: project.id, integration_id: integration.id, organization_id: organization.id) + end + + let(:valid_tracker_data) do + jira_tracker_data.create!(project_id: project.id, integration_id: integration.id) + end + + let(:group_tracker_data) do + group_integration = integrations.create!(group_id: group.id, type_new: 'Integrations::Jira') + jira_tracker_data.create!(group_id: group.id, integration_id: group_integration.id) + end + + let(:organization_tracker_data) do + instance_integration = integrations.create!( + instance: true, + organization_id: organization.id, + type_new: 'Integrations::Jira' + ) + + jira_tracker_data.create!(organization_id: organization.id, integration_id: instance_integration.id) + end + + before do + ApplicationRecord.connection.execute('ALTER TABLE jira_tracker_data DROP CONSTRAINT IF EXISTS check_eca1fbd6bd;') + end + + after do + ApplicationRecord + .connection + .execute( + 'ALTER TABLE jira_tracker_data ADD CONSTRAINT check_eca1fbd6bd ' \ + 'CHECK ((num_nonnulls(group_id, organization_id, project_id) = 1));' + ) + end + + describe "#up" do + it 'sets organization_id to nil for project jira_tracker_data that have it' do + expect(tracker_data_to_backfill.project_id).to eq(project.id) + expect(tracker_data_to_backfill.organization_id).to eq(organization.id) + + expect(another_tracker_data_to_backfill.project_id).to eq(project.id) + expect(another_tracker_data_to_backfill.organization_id).to eq(organization.id) + + expect(valid_tracker_data.project_id).to eq(project.id) + expect(valid_tracker_data.organization_id).to be_nil + + expect(group_tracker_data.group_id).to eq(group.id) + expect(group_tracker_data.organization_id).to be_nil + + expect(organization_tracker_data.organization_id).to eq(organization.id) + expect(organization_tracker_data.project_id).to be_nil + expect(organization_tracker_data.group_id).to be_nil + + migrate! + + expect(tracker_data_to_backfill.reload.project_id).to eq(project.id) + expect(tracker_data_to_backfill.reload.organization_id).to be_nil + + expect(another_tracker_data_to_backfill.reload.project_id).to eq(project.id) + expect(another_tracker_data_to_backfill.reload.organization_id).to be_nil + + expect(valid_tracker_data.reload.project_id).to eq(project.id) + expect(valid_tracker_data.reload.organization_id).to be_nil + + expect(group_tracker_data.reload.group_id).to eq(group.id) + expect(group_tracker_data.reload.organization_id).to be_nil + + expect(organization_tracker_data.reload.organization_id).to eq(organization.id) + expect(organization_tracker_data.reload.project_id).to be_nil + expect(organization_tracker_data.reload.group_id).to be_nil + end + end +end