Commit 10a0d747 authored by Alex Kalderimis's avatar Alex Kalderimis Committed by Nick Thomas

Reuse issue between specs

This involves resetting the repo to blank manually between examples, but
saves about 30% of the spec runtime
parent 35c3c09a
...@@ -101,7 +101,7 @@ module DesignManagement ...@@ -101,7 +101,7 @@ module DesignManagement
scope :current, -> { visible_at_version(nil) } scope :current, -> { visible_at_version(nil) }
def self.relative_positioning_query_base(design) def self.relative_positioning_query_base(design)
on_issue(design.issue_id) default_scoped.on_issue(design.issue_id)
end end
def self.relative_positioning_parent_column def self.relative_positioning_parent_column
......
...@@ -5,9 +5,9 @@ RSpec.describe DesignManagement::SaveDesignsService do ...@@ -5,9 +5,9 @@ RSpec.describe DesignManagement::SaveDesignsService do
include DesignManagementTestHelpers include DesignManagementTestHelpers
include ConcurrentHelpers include ConcurrentHelpers
let_it_be(:developer) { create(:user) } let_it_be_with_reload(:issue) { create(:issue) }
let_it_be(:developer) { create(:user, developer_projects: [issue.project]) }
let(:project) { issue.project } let(:project) { issue.project }
let(:issue) { create(:issue) }
let(:user) { developer } let(:user) { developer }
let(:files) { [rails_sample] } let(:files) { [rails_sample] }
let(:design_repository) { ::Gitlab::GlRepository::DESIGN.repository_resolver.call(project) } let(:design_repository) { ::Gitlab::GlRepository::DESIGN.repository_resolver.call(project) }
...@@ -19,8 +19,20 @@ RSpec.describe DesignManagement::SaveDesignsService do ...@@ -19,8 +19,20 @@ RSpec.describe DesignManagement::SaveDesignsService do
fixture_file_upload("spec/fixtures/#{filename}") fixture_file_upload("spec/fixtures/#{filename}")
end end
def commit_count
design_repository.expire_statistics_caches
design_repository.expire_root_ref_cache
design_repository.commit_count
end
before do before do
project.add_developer(developer) if issue.design_collection.repository.exists?
issue.design_collection.repository.expire_all_method_caches
issue.design_collection.repository.raw.delete_all_refs_except([Gitlab::Git::BLANK_SHA])
end
allow(::DesignManagement::NewVersionWorker)
.to receive(:perform_async).with(Integer).and_return(nil)
end end
def run_service(files_to_upload = nil) def run_service(files_to_upload = nil)
...@@ -83,24 +95,20 @@ RSpec.describe DesignManagement::SaveDesignsService do ...@@ -83,24 +95,20 @@ RSpec.describe DesignManagement::SaveDesignsService do
design_repository.exists? design_repository.exists?
end end
it 'creates a design repository when it did not exist' do it 'is ensured when the service runs' do
expect { run_service }.to change { repository_exists }.from(false).to(true) run_service
expect(repository_exists).to be true
end end
end end
it 'updates the creation count' do it 'creates a commit, an event in the activity stream and updates the creation count' do
counter = Gitlab::UsageDataCounters::DesignsCounter counter = Gitlab::UsageDataCounters::DesignsCounter
expect { run_service }.to change { counter.read(:create) }.by(1)
end
it 'creates an event in the activity stream' do
expect { run_service } expect { run_service }
.to change { Event.count }.by(1) .to change { Event.count }.by(1)
.and change { Event.for_design.created_action.count }.by(1) .and change { Event.for_design.created_action.count }.by(1)
end .and change { counter.read(:create) }.by(1)
it 'creates a commit in the repository' do
run_service
expect(design_repository.commit).to have_attributes( expect(design_repository.commit).to have_attributes(
author: user, author: user,
...@@ -109,36 +117,27 @@ RSpec.describe DesignManagement::SaveDesignsService do ...@@ -109,36 +117,27 @@ RSpec.describe DesignManagement::SaveDesignsService do
end end
it 'can run the same command in parallel' do it 'can run the same command in parallel' do
blocks = Array.new(10).map do parellism = 4
unique_files = %w(rails_sample.jpg dk.png)
.map { |name| RenameableUpload.unique_file(name) }
-> { run_service(unique_files) } blocks = Array.new(parellism).map do
end unique_files = [RenameableUpload.unique_file('rails_sample.jpg')]
expect { run_parallel(blocks) }.to change(DesignManagement::Version, :count).by(10) -> { run_service(unique_files) }
end end
it 'causes diff_refs not to be nil' do expect { run_parallel(blocks) }.to change(DesignManagement::Version, :count).by(parellism)
expect(response).to include(
designs: all(have_attributes(diff_refs: be_present))
)
end end
it 'creates a design & a version for the filename if it did not exist' do describe 'the response' do
expect(issue.designs.size).to eq(0) it 'includes designs with the expected properties' do
updated_designs = response[:designs] updated_designs = response[:designs]
expect(updated_designs).to all(have_attributes(diff_refs: be_present))
expect(updated_designs.size).to eq(1) expect(updated_designs.size).to eq(1)
expect(updated_designs.first.versions.size).to eq(1) expect(updated_designs.first.versions.size).to eq(1)
end
it 'saves the user as the author' do
updated_designs = response[:designs]
expect(updated_designs.first.versions.first.author).to eq(user) expect(updated_designs.first.versions.first.author).to eq(user)
end end
end
describe 'saving the file to LFS' do describe 'saving the file to LFS' do
before do before do
...@@ -147,14 +146,10 @@ RSpec.describe DesignManagement::SaveDesignsService do ...@@ -147,14 +146,10 @@ RSpec.describe DesignManagement::SaveDesignsService do
end end
end end
it 'saves the design to LFS' do it 'saves the design to LFS and saves the repository_type of the LfsObjectsProject as design' do
expect { run_service }.to change { LfsObject.count }.by(1) expect { run_service }
end .to change { LfsObject.count }.by(1)
.and change { project.lfs_objects_projects.count }.from(0).to(1)
it 'saves the repository_type of the LfsObjectsProject as design' do
expect do
run_service
end.to change { project.lfs_objects_projects.count }.from(0).to(1)
expect(project.lfs_objects_projects.first.repository_type).to eq('design') expect(project.lfs_objects_projects.first.repository_type).to eq('design')
end end
...@@ -202,12 +197,10 @@ RSpec.describe DesignManagement::SaveDesignsService do ...@@ -202,12 +197,10 @@ RSpec.describe DesignManagement::SaveDesignsService do
run_service run_service
end end
it 'does not create a new version' do it 'does not create a new version, and returns the design in `skipped_designs`' do
expect { run_service }.not_to change { issue.design_versions.count } response = nil
end
it 'returns the design in `skipped_designs` instead of `designs`' do expect { response = run_service }.not_to change { issue.design_versions.count }
response = run_service
expect(response[:designs]).to be_empty expect(response[:designs]).to be_empty
expect(response[:skipped_designs].size).to eq(1) expect(response[:skipped_designs].size).to eq(1)
...@@ -223,35 +216,20 @@ RSpec.describe DesignManagement::SaveDesignsService do ...@@ -223,35 +216,20 @@ RSpec.describe DesignManagement::SaveDesignsService do
touch_files([files.first]) touch_files([files.first])
end end
it 'counts one creation and one update' do it 'has the correct side-effects' do
counter = Gitlab::UsageDataCounters::DesignsCounter counter = Gitlab::UsageDataCounters::DesignsCounter
expect { run_service }
.to change { counter.read(:create) }.by(1)
.and change { counter.read(:update) }.by(1)
end
it 'creates the correct activity stream events' do expect(::DesignManagement::NewVersionWorker)
.to receive(:perform_async).once.with(Integer).and_return(nil)
expect { run_service } expect { run_service }
.to change { Event.count }.by(2) .to change { Event.count }.by(2)
.and change { Event.for_design.count }.by(2) .and change { Event.for_design.count }.by(2)
.and change { Event.created_action.count }.by(1) .and change { Event.created_action.count }.by(1)
.and change { Event.updated_action.count }.by(1) .and change { Event.updated_action.count }.by(1)
end .and change { counter.read(:create) }.by(1)
.and change { counter.read(:update) }.by(1)
it 'creates a single commit' do .and change { commit_count }.by(1)
commit_count = -> do
design_repository.expire_all_method_caches
design_repository.commit_count
end
expect { run_service }.to change { commit_count.call }.by(1)
end
it 'enqueues just one new version worker' do
expect(::DesignManagement::NewVersionWorker)
.to receive(:perform_async).once.with(Integer)
run_service
end end
end end
...@@ -262,45 +240,28 @@ RSpec.describe DesignManagement::SaveDesignsService do ...@@ -262,45 +240,28 @@ RSpec.describe DesignManagement::SaveDesignsService do
expect(response).to include(designs: have_attributes(size: 2), status: :success) expect(response).to include(designs: have_attributes(size: 2), status: :success)
end end
it 'creates 2 designs with a single version' do it 'has the correct side-effects', :request_store do
expect { run_service }.to change { issue.designs.count }.from(0).to(2)
expect(DesignManagement::Version.for_designs(issue.designs).size).to eq(1)
end
it 'increments the creation count by 2' do
counter = Gitlab::UsageDataCounters::DesignsCounter counter = Gitlab::UsageDataCounters::DesignsCounter
expect { run_service }.to change { counter.read(:create) }.by 2
end
it 'enqueues a new version worker' do
expect(::DesignManagement::NewVersionWorker)
.to receive(:perform_async).once.with(Integer)
run_service
end
it 'creates a single commit' do
commit_count = -> do
design_repository.expire_all_method_caches
design_repository.commit_count
end
expect { run_service }.to change { commit_count.call }.by(1)
end
it 'only does 5 gitaly calls', :request_store, :sidekiq_might_not_need_inline do
allow(::DesignManagement::NewVersionWorker).to receive(:perform_async).with(Integer)
service = described_class.new(project, user, issue: issue, files: files) service = described_class.new(project, user, issue: issue, files: files)
# Some unrelated calls that are usually cached or happen only once # Some unrelated calls that are usually cached or happen only once
service.__send__(:repository).create_if_not_exists # We expect:
service.__send__(:repository).has_visible_content? # - An exists?
# - a check for existing blobs
# - default branch
# - an after_commit callback on LfsObjectsProject
design_repository.create_if_not_exists
design_repository.has_visible_content?
request_count = -> { Gitlab::GitalyClient.get_request_count } expect(::DesignManagement::NewVersionWorker)
.to receive(:perform_async).once.with(Integer).and_return(nil)
# An exists?, a check for existing blobs, default branch, an after_commit expect { service.execute }
# callback on LfsObjectsProject .to change { issue.designs.count }.from(0).to(2)
expect { service.execute }.to change(&request_count).by(4) .and change { DesignManagement::Version.count }.by(1)
.and change { counter.read(:create) }.by(2)
.and change { Gitlab::GitalyClient.get_request_count }.by(3)
.and change { commit_count }.by(1)
end end
context 'when uploading too many files' do context 'when uploading too many files' do
...@@ -313,7 +274,7 @@ RSpec.describe DesignManagement::SaveDesignsService do ...@@ -313,7 +274,7 @@ RSpec.describe DesignManagement::SaveDesignsService do
end end
context 'when the user is not allowed to upload designs' do context 'when the user is not allowed to upload designs' do
let(:user) { create(:user) } let(:user) { build_stubbed(:user) }
it_behaves_like 'a service error' it_behaves_like 'a service error'
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