Commit f35bac57 authored by Robert Speicher's avatar Robert Speicher

Merge branch '40744-idempotent-ids' into 'master'

Use the DatabaseCleaner 'deletion' strategy instead of 'truncation'

Closes #30783

See merge request gitlab-org/gitlab-ce!16516
parents 8fe314e4 2fe57353
require 'database_cleaner'
DatabaseCleaner[:active_record].strategy = :truncation
DatabaseCleaner[:active_record].strategy = :deletion
Spinach.hooks.before_scenario do
DatabaseCleaner.start
......
......@@ -108,7 +108,7 @@ describe 'Merge request > User resolves diff notes and discussions', :js do
it 'shows resolved discussion when toggled' do
find(".timeline-content .discussion[data-discussion-id='#{note.discussion_id}'] .discussion-toggle-button").click
expect(page.find(".timeline-content #note_#{note.noteable_id}")).to be_visible
expect(page.find(".timeline-content #note_#{note.id}")).to be_visible
end
end
......
......@@ -10,9 +10,10 @@ describe('Pipelines table in Commits and Merge requests', () => {
preloadFixtures(jsonFixtureName);
beforeEach(() => {
PipelinesTable = Vue.extend(pipelinesTable);
const pipelines = getJSONFixture(jsonFixtureName).pipelines;
pipeline = pipelines.find(p => p.id === 1);
PipelinesTable = Vue.extend(pipelinesTable);
pipeline = pipelines.find(p => p.user !== null && p.commit !== null);
});
describe('successful request', () => {
......
......@@ -24,9 +24,10 @@ describe('Pipelines Table Row', () => {
beforeEach(() => {
const pipelines = getJSONFixture(jsonFixtureName).pipelines;
pipeline = pipelines.find(p => p.id === 1);
pipelineWithoutAuthor = pipelines.find(p => p.id === 2);
pipelineWithoutCommit = pipelines.find(p => p.id === 3);
pipeline = pipelines.find(p => p.user !== null && p.commit !== null);
pipelineWithoutAuthor = pipelines.find(p => p.user == null && p.commit !== null);
pipelineWithoutCommit = pipelines.find(p => p.user == null && p.commit == null);
});
afterEach(() => {
......
......@@ -11,9 +11,10 @@ describe('Pipelines Table', () => {
preloadFixtures(jsonFixtureName);
beforeEach(() => {
PipelinesTableComponent = Vue.extend(pipelinesTableComp);
const pipelines = getJSONFixture(jsonFixtureName).pipelines;
pipeline = pipelines.find(p => p.id === 1);
PipelinesTableComponent = Vue.extend(pipelinesTableComp);
pipeline = pipelines.find(p => p.user !== null && p.commit !== null);
});
describe('table', () => {
......
require 'spec_helper'
describe Gitlab::BackgroundMigration::DeserializeMergeRequestDiffsAndCommits, :truncate, :migration, schema: 20171114162227 do
describe Gitlab::BackgroundMigration::DeserializeMergeRequestDiffsAndCommits, :migration, schema: 20171114162227 do
let(:merge_request_diffs) { table(:merge_request_diffs) }
let(:merge_requests) { table(:merge_requests) }
......
require 'spec_helper'
describe Gitlab::BackgroundMigration::MigrateSystemUploadsToNewFolder do
describe Gitlab::BackgroundMigration::MigrateSystemUploadsToNewFolder, :delete do
let(:migration) { described_class.new }
before do
......@@ -8,7 +8,7 @@ describe Gitlab::BackgroundMigration::MigrateSystemUploadsToNewFolder do
end
describe '#perform' do
it 'renames the path of system-uploads', :truncate do
it 'renames the path of system-uploads' do
upload = create(:upload, model: create(:project), path: 'uploads/system/project/avatar.jpg')
migration.perform('uploads/system/', 'uploads/-/system/')
......
require 'spec_helper'
describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameBase, :truncate do
describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameBase, :delete do
let(:migration) { FakeRenameReservedPathMigrationV1.new }
let(:subject) { described_class.new(['the-path'], migration) }
......
require 'spec_helper'
describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces, :truncate do
describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces, :delete do
let(:migration) { FakeRenameReservedPathMigrationV1.new }
let(:subject) { described_class.new(['the-path'], migration) }
let(:namespace) { create(:group, name: 'the-path') }
......
require 'spec_helper'
describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameProjects, :truncate do
describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameProjects, :delete do
let(:migration) { FakeRenameReservedPathMigrationV1.new }
let(:subject) { described_class.new(['the-path'], migration) }
let(:project) do
......
......@@ -13,7 +13,7 @@ shared_examples 'renames child namespaces' do |type|
end
end
describe Gitlab::Database::RenameReservedPathsMigration::V1, :truncate do
describe Gitlab::Database::RenameReservedPathsMigration::V1, :delete do
let(:subject) { FakeRenameReservedPathMigrationV1.new }
before do
......
require 'spec_helper'
require Rails.root.join('db', 'post_migrate', '20170508170547_add_head_pipeline_for_each_merge_request.rb')
describe AddHeadPipelineForEachMergeRequest, :truncate do
describe AddHeadPipelineForEachMergeRequest, :delete do
include ProjectForksHelper
let(:migration) { described_class.new }
......
......@@ -3,7 +3,7 @@
require 'spec_helper'
require Rails.root.join('db', 'post_migrate', '20170803090603_calculate_conv_dev_index_percentages.rb')
describe CalculateConvDevIndexPercentages, truncate: true do
describe CalculateConvDevIndexPercentages, :delete do
let(:migration) { described_class.new }
let!(:conv_dev_index) do
create(:conversational_development_index_metric,
......
require 'spec_helper'
require Rails.root.join('db', 'post_migrate', '20170518231126_fix_wrongly_renamed_routes.rb')
describe FixWronglyRenamedRoutes, :truncate, :migration do
describe FixWronglyRenamedRoutes, :migration do
let(:subject) { described_class.new }
let(:namespaces_table) { table(:namespaces) }
let(:projects_table) { table(:projects) }
......
......@@ -8,10 +8,10 @@ describe MigrateIssuesToGhostUser, :migration do
let(:users) { table(:users) }
before do
projects.create!(name: 'gitlab')
project = projects.create!(name: 'gitlab')
user = users.create(email: 'test@example.com')
issues.create(title: 'Issue 1', author_id: nil, project_id: 1)
issues.create(title: 'Issue 2', author_id: user.id, project_id: 1)
issues.create(title: 'Issue 1', author_id: nil, project_id: project.id)
issues.create(title: 'Issue 2', author_id: user.id, project_id: project.id)
end
context 'when ghost user exists' do
......
......@@ -3,7 +3,7 @@
require 'spec_helper'
require Rails.root.join('db', 'post_migrate', '20170324160416_migrate_user_activities_to_users_last_activity_on.rb')
describe MigrateUserActivitiesToUsersLastActivityOn, :clean_gitlab_redis_shared_state, :truncate do
describe MigrateUserActivitiesToUsersLastActivityOn, :clean_gitlab_redis_shared_state, :delete do
let(:migration) { described_class.new }
let!(:user_active_1) { create(:user) }
let!(:user_active_2) { create(:user) }
......
......@@ -3,7 +3,7 @@
require 'spec_helper'
require Rails.root.join('db', 'post_migrate', '20170406142253_migrate_user_project_view.rb')
describe MigrateUserProjectView, :truncate do
describe MigrateUserProjectView, :delete do
let(:migration) { described_class.new }
let!(:user) { create(:user, project_view: 'readme') }
......
require 'spec_helper'
require Rails.root.join('db', 'post_migrate', '20170815060945_remove_duplicate_mr_events.rb')
describe RemoveDuplicateMrEvents, truncate: true do
describe RemoveDuplicateMrEvents, :delete do
let(:migration) { described_class.new }
describe '#up' do
......
......@@ -5,8 +5,8 @@ require Rails.root.join('db', 'post_migrate', '20170313133418_rename_more_reserv
# This migration uses multiple threads, and thus different transactions. This
# means data created in this spec may not be visible to some threads. To work
# around this we use the TRUNCATE cleaning strategy.
describe RenameMoreReservedProjectNames, truncate: true do
# around this we use the DELETE cleaning strategy.
describe RenameMoreReservedProjectNames, :delete do
let(:migration) { described_class.new }
let!(:project) { create(:project) }
......
......@@ -5,8 +5,8 @@ require Rails.root.join('db', 'post_migrate', '20161221153951_rename_reserved_pr
# This migration uses multiple threads, and thus different transactions. This
# means data created in this spec may not be visible to some threads. To work
# around this we use the TRUNCATE cleaning strategy.
describe RenameReservedProjectNames, truncate: true do
# around this we use the DELETE cleaning strategy.
describe RenameReservedProjectNames, :delete do
let(:migration) { described_class.new }
let!(:project) { create(:project) }
......
require 'spec_helper'
require Rails.root.join('db', 'post_migrate', '20170518200835_rename_users_with_renamed_namespace.rb')
describe RenameUsersWithRenamedNamespace, truncate: true do
describe RenameUsersWithRenamedNamespace, :delete do
it 'renames a user that had their namespace renamed to the namespace path' do
other_user = create(:user, username: 'kodingu')
other_user1 = create(:user, username: 'api0')
......
require 'spec_helper'
require Rails.root.join('db', 'post_migrate', '20170503004427_update_retried_for_ci_build.rb')
describe UpdateRetriedForCiBuild, truncate: true do
describe UpdateRetriedForCiBuild, :delete do
let(:pipeline) { create(:ci_pipeline) }
let!(:build_old) { create(:ci_build, pipeline: pipeline, name: 'test') }
let!(:build_new) { create(:ci_build, pipeline: pipeline, name: 'test') }
......
require 'spec_helper'
describe Avatarable do
subject { create(:project, avatar: fixture_file_upload(File.join(Rails.root, 'spec/fixtures/dk.png'))) }
set(:project) { create(:project, avatar: fixture_file_upload(File.join(Rails.root, 'spec/fixtures/dk.png'))) }
let(:gitlab_host) { "https://gitlab.example.com" }
let(:relative_url_root) { "/gitlab" }
let(:asset_host) { "https://gitlab-assets.example.com" }
let(:asset_host) { 'https://gitlab-assets.example.com' }
before do
stub_config_setting(base_url: gitlab_host)
......@@ -15,29 +15,32 @@ describe Avatarable do
describe '#avatar_path' do
using RSpec::Parameterized::TableSyntax
where(:has_asset_host, :visibility_level, :only_path, :avatar_path) do
true | Project::PRIVATE | true | [gitlab_host, relative_url_root, subject.avatar.url]
true | Project::PRIVATE | false | [gitlab_host, relative_url_root, subject.avatar.url]
true | Project::INTERNAL | true | [gitlab_host, relative_url_root, subject.avatar.url]
true | Project::INTERNAL | false | [gitlab_host, relative_url_root, subject.avatar.url]
true | Project::PUBLIC | true | [subject.avatar.url]
true | Project::PUBLIC | false | [asset_host, subject.avatar.url]
false | Project::PRIVATE | true | [relative_url_root, subject.avatar.url]
false | Project::PRIVATE | false | [gitlab_host, relative_url_root, subject.avatar.url]
false | Project::INTERNAL | true | [relative_url_root, subject.avatar.url]
false | Project::INTERNAL | false | [gitlab_host, relative_url_root, subject.avatar.url]
false | Project::PUBLIC | true | [relative_url_root, subject.avatar.url]
false | Project::PUBLIC | false | [gitlab_host, relative_url_root, subject.avatar.url]
where(:has_asset_host, :visibility_level, :only_path, :avatar_path_prefix) do
true | Project::PRIVATE | true | [gitlab_host, relative_url_root]
true | Project::PRIVATE | false | [gitlab_host, relative_url_root]
true | Project::INTERNAL | true | [gitlab_host, relative_url_root]
true | Project::INTERNAL | false | [gitlab_host, relative_url_root]
true | Project::PUBLIC | true | []
true | Project::PUBLIC | false | [asset_host]
false | Project::PRIVATE | true | [relative_url_root]
false | Project::PRIVATE | false | [gitlab_host, relative_url_root]
false | Project::INTERNAL | true | [relative_url_root]
false | Project::INTERNAL | false | [gitlab_host, relative_url_root]
false | Project::PUBLIC | true | [relative_url_root]
false | Project::PUBLIC | false | [gitlab_host, relative_url_root]
end
with_them do
before do
allow(ActionController::Base).to receive(:asset_host).and_return(has_asset_host ? asset_host : nil)
subject.visibility_level = visibility_level
allow(ActionController::Base).to receive(:asset_host) { has_asset_host && asset_host }
project.visibility_level = visibility_level
end
let(:avatar_path) { (avatar_path_prefix + [project.avatar.url]).join }
it 'returns the expected avatar path' do
expect(subject.avatar_path(only_path: only_path)).to eq(avatar_path.join)
expect(project.avatar_path(only_path: only_path)).to eq(avatar_path)
end
end
end
......
......@@ -488,7 +488,7 @@ describe Member do
member.accept_invite!(user)
end
it "refreshes user's authorized projects", :truncate do
it "refreshes user's authorized projects", :delete do
project = member.source
expect(user.authorized_projects).not_to include(project)
......@@ -523,7 +523,7 @@ describe Member do
end
end
describe "destroying a record", :truncate do
describe "destroying a record", :delete do
it "refreshes user's authorized projects" do
project = create(:project, :private)
user = create(:user)
......
......@@ -30,7 +30,7 @@ describe ProjectGroupLink do
end
end
describe "destroying a record", :truncate do
describe "destroying a record", :delete do
it "refreshes group users' authorized projects" do
project = create(:project, :private)
group = create(:group)
......
......@@ -1569,7 +1569,7 @@ describe User do
it { is_expected.to eq([private_group]) }
end
describe '#authorized_projects', :truncate do
describe '#authorized_projects', :delete do
context 'with a minimum access level' do
it 'includes projects for which the user is an owner' do
user = create(:user)
......
require 'database_cleaner/active_record/deletion'
module FakeInformationSchema
# Work around a bug in DatabaseCleaner when using the deletion strategy:
# https://github.com/DatabaseCleaner/database_cleaner/issues/347
#
# On MySQL, if the information schema is said to exist, we use an inaccurate
# row count leading to some tables not being cleaned when they should
def information_schema_exists?(_connection)
false
end
end
DatabaseCleaner::ActiveRecord::Deletion.prepend(FakeInformationSchema)
RSpec.configure do |config|
# Ensure all sequences are reset at the start of the suite run
config.before(:suite) do
DatabaseCleaner.clean_with(:truncation)
end
config.append_after(:context) do
DatabaseCleaner.clean_with(:truncation, cache_tables: false)
DatabaseCleaner.clean_with(:deletion, cache_tables: false)
end
config.before(:each) do
......@@ -12,15 +28,15 @@ RSpec.configure do |config|
end
config.before(:each, :js) do
DatabaseCleaner.strategy = :truncation
DatabaseCleaner.strategy = :deletion
end
config.before(:each, :truncate) do
DatabaseCleaner.strategy = :truncation
config.before(:each, :delete) do
DatabaseCleaner.strategy = :deletion
end
config.before(:each, :migration) do
DatabaseCleaner.strategy = :truncation, { cache_tables: false }
DatabaseCleaner.strategy = :deletion, { cache_tables: false }
end
config.before(:each) do
......
......@@ -143,15 +143,17 @@ shared_examples 'discussion comments' do |resource_name|
end
if resource_name == 'merge request'
let(:note_id) { find("#{comments_selector} .note", match: :first)['data-note-id'] }
it 'shows resolved discussion when toggled' do
click_button "Resolve discussion"
expect(page).to have_selector('.note-row-1', visible: true)
expect(page).to have_selector(".note-row-#{note_id}", visible: true)
refresh
click_button "Toggle discussion"
expect(page).to have_selector('.note-row-1', visible: true)
expect(page).to have_selector(".note-row-#{note_id}", visible: true)
end
end
end
......
......@@ -8,7 +8,7 @@ describe JobArtifactUploader do
describe '#store_dir' do
subject { uploader.store_dir }
let(:path) { "#{job_artifact.created_at.utc.strftime('%Y_%m_%d')}/#{job_artifact.project_id}/#{job_artifact.id}" }
let(:path) { "#{job_artifact.created_at.utc.strftime('%Y_%m_%d')}/#{job_artifact.job_id}/#{job_artifact.id}" }
context 'when using local storage' do
it { is_expected.to start_with(local_path) }
......@@ -45,7 +45,7 @@ describe JobArtifactUploader do
it { is_expected.to start_with(local_path) }
it { is_expected.to include("/#{job_artifact.created_at.utc.strftime('%Y_%m_%d')}/") }
it { is_expected.to include("/#{job_artifact.project_id}/") }
it { is_expected.to include("/#{job_artifact.job_id}/#{job_artifact.id}/") }
it { is_expected.to end_with("ci_build_artifacts.zip") }
end
end
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