diff --git a/lib/travis/api/app/endpoint/builds.rb b/lib/travis/api/app/endpoint/builds.rb index e04dc25f..477731ed 100644 --- a/lib/travis/api/app/endpoint/builds.rb +++ b/lib/travis/api/app/endpoint/builds.rb @@ -2,6 +2,7 @@ require 'travis/api/app' require 'travis/api/workers/build_cancellation' require 'travis/api/workers/build_restart' require 'travis/api/enqueue/services/restart_model' +require 'travis/api/enqueue/services/cancel_model' class Travis::Api::App class Endpoint @@ -21,7 +22,12 @@ class Travis::Api::App post '/:id/cancel' do Metriks.meter("api.request.cancel_build").mark - service = self.service(:cancel_build, params.merge(source: 'api')) + if Travis::Features.owner_active?(:enqueue_to_hub, current_user) + service = Travis::Enqueue::Services::CancelModel.new(current_user, { build_id: params[:id], source: 'api' }) + else + service = self.service(:cancel_build, params.merge(source: 'api')) + end + if !service.authorized? json = { error: { message: "You don't have access to cancel build(#{params[:id]})" @@ -40,7 +46,12 @@ class Travis::Api::App status 422 respond_with json else - Travis::Sidekiq::BuildCancellation.perform_async(id: params[:id], user_id: current_user.id, source: 'api') + if service.respond_to?(:enqueue_to_hub) + payload = { build_id: params[:id], source: 'api'} + service.enqueue_to_hub(payload) + else + Travis::Sidekiq::BuildCancellation.perform_async(id: params[:id], user_id: current_user.id, source: 'api') + end Metriks.meter("api.request.cancel_build.success").mark status 204 diff --git a/lib/travis/api/enqueue/services/cancel_model.rb b/lib/travis/api/enqueue/services/cancel_model.rb index 47c5f006..d8868a50 100644 --- a/lib/travis/api/enqueue/services/cancel_model.rb +++ b/lib/travis/api/enqueue/services/cancel_model.rb @@ -13,11 +13,6 @@ module Travis target end - def run - cancel - end - instrument :run - def messages messages = [] messages << { :notice => "The #{type} was successfully cancelled." } if can_cancel? @@ -26,7 +21,7 @@ module Travis messages end - def cancel(payload) + def enqueue_to_hub(payload) # target may have been retrieved with a :join query, so we need to reset the readonly status if can_cancel? target.send(:instance_variable_set, :@readonly, false) @@ -41,11 +36,9 @@ module Travis end def push_matrix(payload) - target.matrix.each do |job| push(payload, job) end - end def push(payload, job) diff --git a/spec/integration/v2/builds_spec.rb b/spec/integration/v2/builds_spec.rb index c4e78d44..f3fb77a1 100644 --- a/spec/integration/v2/builds_spec.rb +++ b/spec/integration/v2/builds_spec.rb @@ -63,6 +63,16 @@ describe 'Builds' do response = post "/builds/#{build.id}/cancel", {}, headers response.status.should == 403 end + + context 'and enqueues cancel event for the Hub' do + before { Travis::Features.activate_owner(:enqueue_to_hub, repo.owner) } + + it 'responds with 403' do + response = post "/builds/#{build.id}/cancel", {}, headers + response.status.should == 403 + end + + end end context 'when build is not cancelable' do @@ -72,23 +82,55 @@ describe 'Builds' do response = post "/builds/#{build.id}/cancel", {}, headers response.status.should == 422 end + + context 'and enqueues cancel event for the Hub' do + before { Travis::Features.activate_owner(:enqueue_to_hub, repo.owner) } + + it 'responds with 422' do + response = post "/builds/#{build.id}/cancel", {}, headers + response.status.should == 422 + end + end end context 'when build can be canceled' do before do - Travis::Sidekiq::BuildCancellation.stubs(:perform_async) build.matrix.each { |j| j.update_attribute(:state, 'created') } build.update_attribute(:state, 'created') end - it 'cancels the build' do - Travis::Sidekiq::BuildCancellation.expects(:perform_async).with( id: build.id.to_s, user_id: user.id, source: 'api') - post "/builds/#{build.id}/cancel", {}, headers + context 'from the Core' do + before { Travis::Sidekiq::BuildCancellation.stubs(:perform_async) } + + it 'cancels the build' do + Travis::Sidekiq::BuildCancellation.expects(:perform_async).with( id: build.id.to_s, user_id: user.id, source: 'api') + post "/builds/#{build.id}/cancel", {}, headers + end + + it 'responds with 204' do + response = post "/builds/#{build.id}/cancel", {}, headers + response.status.should == 204 + end end - it 'responds with 204' do - response = post "/builds/#{build.id}/cancel", {}, headers - response.status.should == 204 + context 'and enqueues cancel event for the Hub' do + before { Travis::Features.activate_owner(:enqueue_to_hub, repo.owner) } + + before do + build.matrix.each { |j| j.update_attribute(:state, 'created') } + build.update_attribute(:state, 'created') + end + + it 'cancels the build' do + ::Sidekiq::Client.expects(:push).times(4) + post "/builds/#{build.id}/cancel", {}, headers + end + + it 'responds with 204' do + ::Sidekiq::Client.expects(:push).times(4) + response = post "/builds/#{build.id}/cancel", {}, headers + response.status.should == 204 + end end end end