Commit 61013501 authored by Alex Kalderimis's avatar Alex Kalderimis

Merge branch 'refactor-stop-environments-service' into 'master'

Refactor stop environments service and fix a bug that it can't stop empty environments

See merge request gitlab-org/gitlab!67485
parents abd1c50f 868d3761
...@@ -32,7 +32,7 @@ module Environments ...@@ -32,7 +32,7 @@ module Environments
return false unless environments.exists? return false unless environments.exists?
Ci::StopEnvironmentsService.execute_in_batch(environments) Environments::StopService.execute_in_batch(environments)
end end
end end
end end
# frozen_string_literal: true # frozen_string_literal: true
module Ci module Environments
class StopEnvironmentsService < BaseService class StopService < BaseService
attr_reader :ref attr_reader :ref
def execute(branch_name) def execute(environment)
return unless can?(current_user, :stop_environment, environment)
environment.stop_with_action!(current_user)
end
def execute_for_branch(branch_name)
@ref = branch_name @ref = branch_name
return unless @ref.present? return unless @ref.present?
environments.each { |environment| stop(environment) } environments.each { |environment| execute(environment) }
end end
def execute_for_merge_request(merge_request) def execute_for_merge_request(merge_request)
merge_request.environments.each { |environment| stop(environment) } merge_request.environments.each { |environment| execute(environment) }
end end
## ##
...@@ -39,12 +45,5 @@ module Ci ...@@ -39,12 +45,5 @@ module Ci
.new(project, current_user, ref: @ref, recently_updated: true) .new(project, current_user, ref: @ref, recently_updated: true)
.execute .execute
end end
def stop(environment)
return unless environment.stop_action_available?
return unless can?(current_user, :stop_environment, environment)
environment.stop_with_action!(current_user)
end
end end
end end
...@@ -58,7 +58,7 @@ module Git ...@@ -58,7 +58,7 @@ module Git
def stop_environments def stop_environments
return unless removing_branch? return unless removing_branch?
Ci::StopEnvironmentsService.new(project, current_user).execute(branch_name) Environments::StopService.new(project, current_user).execute_for_branch(branch_name)
end end
def unlock_artifacts def unlock_artifacts
......
...@@ -61,7 +61,7 @@ module MergeRequests ...@@ -61,7 +61,7 @@ module MergeRequests
end end
def cleanup_environments(merge_request) def cleanup_environments(merge_request)
Ci::StopEnvironmentsService.new(merge_request.source_project, current_user) Environments::StopService.new(merge_request.source_project, current_user)
.execute_for_merge_request(merge_request) .execute_for_merge_request(merge_request)
end end
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe Ci::StopEnvironmentsService do RSpec.describe Environments::StopService do
include CreateEnvironmentsHelpers include CreateEnvironmentsHelpers
let(:project) { create(:project, :private, :repository) } let(:project) { create(:project, :private, :repository) }
...@@ -11,6 +11,59 @@ RSpec.describe Ci::StopEnvironmentsService do ...@@ -11,6 +11,59 @@ RSpec.describe Ci::StopEnvironmentsService do
let(:service) { described_class.new(project, user) } let(:service) { described_class.new(project, user) }
describe '#execute' do describe '#execute' do
subject { service.execute(environment) }
let_it_be(:project) { create(:project, :private, :repository) }
let_it_be(:developer) { create(:user).tap { |u| project.add_developer(u) } }
let_it_be(:reporter) { create(:user).tap { |u| project.add_reporter(u) } }
let(:user) { developer }
context 'with a deployment' do
let!(:environment) { review_job.persisted_environment }
let!(:pipeline) { create(:ci_pipeline, project: project) }
let!(:review_job) { create(:ci_build, :with_deployment, :start_review_app, pipeline: pipeline, project: project) }
let!(:stop_review_job) { create(:ci_build, :with_deployment, :stop_review_app, :manual, pipeline: pipeline, project: project) }
before do
review_job.success!
end
it 'stops the environment' do
expect { subject }.to change { environment.reload.state }.from('available').to('stopped')
end
it 'plays the stop action' do
expect { subject }.to change { stop_review_job.reload.status }.from('manual').to('pending')
end
context 'when an environment has already been stopped' do
let!(:environment) { create(:environment, :stopped, project: project) }
it 'does not play the stop action' do
expect { subject }.not_to change { stop_review_job.reload.status }
end
end
end
context 'without a deployment' do
let!(:environment) { create(:environment, project: project) }
it 'stops the environment' do
expect { subject }.to change { environment.reload.state }.from('available').to('stopped')
end
context 'when the actor is a reporter' do
let(:user) { reporter }
it 'does not stop the environment' do
expect { subject }.not_to change { environment.reload.state }
end
end
end
end
describe '#execute_for_branch' do
context 'when environment with review app exists' do context 'when environment with review app exists' do
before do before do
create(:environment, :with_review_app, project: project, create(:environment, :with_review_app, project: project,
...@@ -48,8 +101,9 @@ RSpec.describe Ci::StopEnvironmentsService do ...@@ -48,8 +101,9 @@ RSpec.describe Ci::StopEnvironmentsService do
context 'when environment is not stopped' do context 'when environment is not stopped' do
before do before do
allow_any_instance_of(Environment) allow_next_found_instance_of(Environment) do |environment|
.to receive(:state).and_return(:stopped) allow(environment).to receive(:state).and_return(:stopped)
end
end end
it 'does not stop environment' do it 'does not stop environment' do
...@@ -101,7 +155,7 @@ RSpec.describe Ci::StopEnvironmentsService do ...@@ -101,7 +155,7 @@ RSpec.describe Ci::StopEnvironmentsService do
context 'when environment does not exist' do context 'when environment does not exist' do
it 'does not raise error' do it 'does not raise error' do
expect { service.execute('master') } expect { service.execute_for_branch('master') }
.not_to raise_error .not_to raise_error
end end
end end
...@@ -238,16 +292,12 @@ RSpec.describe Ci::StopEnvironmentsService do ...@@ -238,16 +292,12 @@ RSpec.describe Ci::StopEnvironmentsService do
end end
def expect_environment_stopped_on(branch) def expect_environment_stopped_on(branch)
expect_any_instance_of(Environment) expect { service.execute_for_branch(branch) }
.to receive(:stop!) .to change { Environment.last.state }.from('available').to('stopped')
service.execute(branch)
end end
def expect_environment_not_stopped_on(branch) def expect_environment_not_stopped_on(branch)
expect_any_instance_of(Environment) expect { service.execute_for_branch(branch) }
.not_to receive(:stop!) .not_to change { Environment.last.state }
service.execute(branch)
end end
end end
...@@ -597,7 +597,7 @@ RSpec.describe Git::BranchPushService, services: true do ...@@ -597,7 +597,7 @@ RSpec.describe Git::BranchPushService, services: true do
let(:oldrev) { blankrev } let(:oldrev) { blankrev }
it 'does nothing' do it 'does nothing' do
expect(::Ci::StopEnvironmentsService).not_to receive(:new) expect(::Environments::StopService).not_to receive(:new)
execute_service(project, user, oldrev: oldrev, newrev: newrev, ref: ref) execute_service(project, user, oldrev: oldrev, newrev: newrev, ref: ref)
end end
...@@ -605,7 +605,7 @@ RSpec.describe Git::BranchPushService, services: true do ...@@ -605,7 +605,7 @@ RSpec.describe Git::BranchPushService, services: true do
context 'update branch' do context 'update branch' do
it 'does nothing' do it 'does nothing' do
expect(::Ci::StopEnvironmentsService).not_to receive(:new) expect(::Environments::StopService).not_to receive(:new)
execute_service(project, user, oldrev: oldrev, newrev: newrev, ref: ref) execute_service(project, user, oldrev: oldrev, newrev: newrev, ref: ref)
end end
...@@ -615,10 +615,10 @@ RSpec.describe Git::BranchPushService, services: true do ...@@ -615,10 +615,10 @@ RSpec.describe Git::BranchPushService, services: true do
let(:newrev) { blankrev } let(:newrev) { blankrev }
it 'stops environments' do it 'stops environments' do
expect_next_instance_of(::Ci::StopEnvironmentsService) do |stop_service| expect_next_instance_of(::Environments::StopService) do |stop_service|
expect(stop_service.project).to eq(project) expect(stop_service.project).to eq(project)
expect(stop_service.current_user).to eq(user) expect(stop_service.current_user).to eq(user)
expect(stop_service).to receive(:execute).with(branch) expect(stop_service).to receive(:execute_for_branch).with(branch)
end end
execute_service(project, user, oldrev: oldrev, newrev: newrev, ref: ref) execute_service(project, user, oldrev: oldrev, newrev: newrev, ref: ref)
......
...@@ -92,7 +92,7 @@ RSpec.describe MergeRequests::CloseService do ...@@ -92,7 +92,7 @@ RSpec.describe MergeRequests::CloseService do
end end
it 'clean up environments for the merge request' do it 'clean up environments for the merge request' do
expect_next_instance_of(Ci::StopEnvironmentsService) do |service| expect_next_instance_of(::Environments::StopService) do |service|
expect(service).to receive(:execute_for_merge_request).with(merge_request) expect(service).to receive(:execute_for_merge_request).with(merge_request)
end end
......
...@@ -75,7 +75,7 @@ RSpec.describe MergeRequests::PostMergeService do ...@@ -75,7 +75,7 @@ RSpec.describe MergeRequests::PostMergeService do
end end
it 'clean up environments for the merge request' do it 'clean up environments for the merge request' do
expect_next_instance_of(Ci::StopEnvironmentsService) do |stop_environment_service| expect_next_instance_of(::Environments::StopService) do |stop_environment_service|
expect(stop_environment_service).to receive(:execute_for_merge_request).with(merge_request) expect(stop_environment_service).to receive(:execute_for_merge_request).with(merge_request)
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