diff --git a/lib/api/jobs.rb b/lib/api/jobs.rb index a116ab3c9bdb73771ba0be8afff5d9b8aa4c8282..9c205514b3ab374828f409e128a0883f22a831f2 100644 --- a/lib/api/jobs.rb +++ b/lib/api/jobs.rb @@ -38,6 +38,7 @@ module API builds = user_project.builds.order('id DESC') builds = filter_builds(builds, params[:scope]) + builds = builds.preload(:user, :job_artifacts_archive, :runner, pipeline: :project) present paginate(builds), with: Entities::Job end diff --git a/lib/api/v3/builds.rb b/lib/api/v3/builds.rb index fa0bef396029afee4e96f428081f3efc1ce32c6f..ac76fece931cedfd7ba263b15814e6f3fa832796 100644 --- a/lib/api/v3/builds.rb +++ b/lib/api/v3/builds.rb @@ -36,6 +36,7 @@ module API builds = user_project.builds.order('id DESC') builds = filter_builds(builds, params[:scope]) + builds = builds.preload(:user, :job_artifacts_archive, :runner, pipeline: :project) present paginate(builds), with: ::API::V3::Entities::Build end diff --git a/spec/requests/api/jobs_spec.rb b/spec/requests/api/jobs_spec.rb index 805496e4a5457fd875b0cf4e022b12f3569d07f9..e211c347266158f45b8a2a9165a08fae737550e6 100644 --- a/spec/requests/api/jobs_spec.rb +++ b/spec/requests/api/jobs_spec.rb @@ -25,8 +25,10 @@ describe API::Jobs do describe 'GET /projects/:id/jobs' do let(:query) { Hash.new } - before do - get api("/projects/#{project.id}/jobs", api_user), query + before do |example| + unless example.metadata[:skip_before_request] + get api("/projects/#{project.id}/jobs", api_user), query + end end context 'authorized user' do @@ -51,6 +53,23 @@ describe API::Jobs do expect(json_job['pipeline']['status']).to eq job.pipeline.status end + it 'avoids N+1 queries', skip_before_request: true do + first_build = create(:ci_build, :artifacts, pipeline: pipeline) + first_build.runner = create(:ci_runner) + first_build.user = create(:user) + first_build.save + + control_count = ActiveRecord::QueryRecorder.new { go }.count + + second_pipeline = create(:ci_empty_pipeline, project: project, sha: project.commit.id, ref: project.default_branch) + second_build = create(:ci_build, :artifacts, pipeline: second_pipeline) + second_build.runner = create(:ci_runner) + second_build.user = create(:user) + second_build.save + + expect { go }.not_to exceed_query_limit(control_count) + end + context 'filter project with one scope element' do let(:query) { { 'scope' => 'pending' } } @@ -83,6 +102,10 @@ describe API::Jobs do expect(response).to have_gitlab_http_status(401) end end + + def go + get api("/projects/#{project.id}/jobs", api_user), query + end end describe 'GET /projects/:id/pipelines/:pipeline_id/jobs' do diff --git a/spec/requests/api/v3/builds_spec.rb b/spec/requests/api/v3/builds_spec.rb index a73bb456b5228ecdcf2485b72acb17439a043fce..cdbc5692e19b6e00cb4822464fa0093ddbe34873 100644 --- a/spec/requests/api/v3/builds_spec.rb +++ b/spec/requests/api/v3/builds_spec.rb @@ -13,10 +13,12 @@ describe API::V3::Builds do describe 'GET /projects/:id/builds ' do let(:query) { '' } - before do + before do |example| create(:ci_build, :skipped, pipeline: pipeline) - get v3_api("/projects/#{project.id}/builds?#{query}", api_user) + unless example.metadata[:skip_before_request] + get v3_api("/projects/#{project.id}/builds?#{query}", api_user) + end end context 'authorized user' do @@ -40,6 +42,23 @@ describe API::V3::Builds do expect(json_build['pipeline']['status']).to eq build.pipeline.status end + it 'avoids N+1 queries', skip_before_request: true do + first_build = create(:ci_build, :artifacts, pipeline: pipeline) + first_build.runner = create(:ci_runner) + first_build.user = create(:user) + first_build.save + + control_count = ActiveRecord::QueryRecorder.new { go }.count + + second_pipeline = create(:ci_empty_pipeline, project: project, sha: project.commit.id, ref: project.default_branch) + second_build = create(:ci_build, :artifacts, pipeline: second_pipeline) + second_build.runner = create(:ci_runner) + second_build.user = create(:user) + second_build.save + + expect { go }.not_to exceed_query_limit(control_count) + end + context 'filter project with one scope element' do let(:query) { 'scope=pending' } @@ -84,6 +103,10 @@ describe API::V3::Builds do expect(response).to have_gitlab_http_status(401) end end + + def go + get v3_api("/projects/#{project.id}/builds?#{query}", api_user) + end end describe 'GET /projects/:id/repository/commits/:sha/builds' do