Commit 1855eb3a authored by Aleksei Lipniagov's avatar Aleksei Lipniagov

Merge branch 'mc_rocha-capture-failed-dast-schedule-335662' into 'master'

Capture failed dast schedules

See merge request gitlab-org/gitlab!72024
parents 51a7822d faaab85e
...@@ -55,12 +55,12 @@ class Dast::ProfileSchedule < ApplicationRecord ...@@ -55,12 +55,12 @@ class Dast::ProfileSchedule < ApplicationRecord
Ability.allowed?(owner, :create_on_demand_dast_scan, project) Ability.allowed?(owner, :create_on_demand_dast_scan, project)
end end
private
def deactivate! def deactivate!
update!(active: false) update!(active: false)
end end
private
def cron_timezone def cron_timezone
Time.zone.name Time.zone.name
end end
......
...@@ -18,13 +18,10 @@ module AppSec ...@@ -18,13 +18,10 @@ module AppSec
dast_runnable_schedules.find_in_batches do |schedules| dast_runnable_schedules.find_in_batches do |schedules|
schedules.each do |schedule| schedules.each do |schedule|
with_context(project: schedule.project, user: schedule.owner) do if schedule.owner_valid?
schedule.schedule_next_run! execute_schedule(schedule)
else
response = service(schedule).execute schedule.deactivate!
if response.error?
logger.info(structured_payload(message: response.message))
end
end end
end end
end end
...@@ -46,6 +43,17 @@ module AppSec ...@@ -46,6 +43,17 @@ module AppSec
} }
) )
end end
def execute_schedule(schedule)
with_context(project: schedule.project, user: schedule.owner) do
schedule.schedule_next_run!
response = service(schedule).execute
if response.error?
logger.info(structured_payload(message: response.message))
end
end
end
end end
end end
end end
...@@ -5,7 +5,9 @@ RSpec.describe AppSec::Dast::ProfileScheduleWorker do ...@@ -5,7 +5,9 @@ RSpec.describe AppSec::Dast::ProfileScheduleWorker do
include ExclusiveLeaseHelpers include ExclusiveLeaseHelpers
let_it_be(:plan_limits) { create(:plan_limits, :default_plan) } let_it_be(:plan_limits) { create(:plan_limits, :default_plan) }
let_it_be(:schedule) { create(:dast_profile_schedule) } let_it_be(:owner) { create(:user) }
let_it_be(:project) { create(:project) }
let_it_be(:schedule) { create(:dast_profile_schedule, owner: owner, project: project) }
let(:worker) { described_class.new } let(:worker) { described_class.new }
let(:logger) { worker.send(:logger) } let(:logger) { worker.send(:logger) }
...@@ -13,6 +15,8 @@ RSpec.describe AppSec::Dast::ProfileScheduleWorker do ...@@ -13,6 +15,8 @@ RSpec.describe AppSec::Dast::ProfileScheduleWorker do
let(:service_result) { ServiceResponse.success } let(:service_result) { ServiceResponse.success }
before do before do
project.add_developer(owner)
allow(::AppSec::Dast::Scans::CreateService) allow(::AppSec::Dast::Scans::CreateService)
.to receive(:new) .to receive(:new)
.and_return(service) .and_return(service)
...@@ -33,6 +37,10 @@ RSpec.describe AppSec::Dast::ProfileScheduleWorker do ...@@ -33,6 +37,10 @@ RSpec.describe AppSec::Dast::ProfileScheduleWorker do
subject subject
end end
end end
context 'when feature is licensed' do
before do
stub_licensed_features(security_on_demand_scans: true)
end
context 'when multiple schedules exists' do context 'when multiple schedules exists' do
before do before do
...@@ -41,7 +49,7 @@ RSpec.describe AppSec::Dast::ProfileScheduleWorker do ...@@ -41,7 +49,7 @@ RSpec.describe AppSec::Dast::ProfileScheduleWorker do
def record_preloaded_queries def record_preloaded_queries
recorder = ActiveRecord::QueryRecorder.new { subject } recorder = ActiveRecord::QueryRecorder.new { subject }
recorder.data.values.flat_map {|v| v[:occurrences]}.select do |query| recorder.data.values.flat_map { |v| v[:occurrences] }.select do |query|
['FROM "projects"', 'FROM "users"', 'FROM "dast_profile"', 'FROM "dast_profile_schedule"'].any? do |s| ['FROM "projects"', 'FROM "users"', 'FROM "dast_profile"', 'FROM "dast_profile_schedule"'].any? do |s|
query.include?(s) query.include?(s)
end end
...@@ -56,6 +64,31 @@ RSpec.describe AppSec::Dast::ProfileScheduleWorker do ...@@ -56,6 +64,31 @@ RSpec.describe AppSec::Dast::ProfileScheduleWorker do
expect(actual_count).to eq(expected_count) expect(actual_count).to eq(expected_count)
end end
context 'when all of the schedule owners are invalid' do
before do
travel_to(30.minutes.ago) { create_list(:dast_profile_schedule, 5, owner: nil, active: true) }
end
it 'sets active to false' do
expect { subject }.to change { Dast::ProfileSchedule.where(active: false).count }.to(5)
end
end
context 'when some of the schedule owners are invalid' do
before do
travel_to(30.minutes.ago) do
create_list(:dast_profile_schedule, 2, owner: nil, active: true)
create_list(:dast_profile_schedule, 3, owner: owner, active: true, project: project)
end
end
it 'sets active to false' do
expect(service).to receive(:execute)
subject
expect(Dast::ProfileSchedule.where(active: false).count).to eq(2)
end
end
end end
context 'when schedule exists' do context 'when schedule exists' do
...@@ -72,6 +105,17 @@ RSpec.describe AppSec::Dast::ProfileScheduleWorker do ...@@ -72,6 +105,17 @@ RSpec.describe AppSec::Dast::ProfileScheduleWorker do
subject subject
end end
context 'when the schedule owner is invalid' do
before do
schedule.update_column(:user_id, nil)
schedule.update_column(:active, true)
end
it 'sets active to false' do
expect { subject }.to change { schedule.reload.active }.to(false)
end
end
end end
context 'when service returns an error' do context 'when service returns an error' do
...@@ -117,4 +161,5 @@ RSpec.describe AppSec::Dast::ProfileScheduleWorker do ...@@ -117,4 +161,5 @@ RSpec.describe AppSec::Dast::ProfileScheduleWorker do
end end
end end
end end
end
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