diff options
Diffstat (limited to 'spec/requests/api/ci')
-rw-r--r-- | spec/requests/api/ci/job_artifacts_spec.rb | 12 | ||||
-rw-r--r-- | spec/requests/api/ci/jobs_spec.rb | 26 | ||||
-rw-r--r-- | spec/requests/api/ci/runner/jobs_request_post_spec.rb | 83 | ||||
-rw-r--r-- | spec/requests/api/ci/runners_spec.rb | 38 |
4 files changed, 98 insertions, 61 deletions
diff --git a/spec/requests/api/ci/job_artifacts_spec.rb b/spec/requests/api/ci/job_artifacts_spec.rb index 2fa1ffb4974..0fb11bf98d2 100644 --- a/spec/requests/api/ci/job_artifacts_spec.rb +++ b/spec/requests/api/ci/job_artifacts_spec.rb @@ -24,8 +24,7 @@ RSpec.describe API::Ci::JobArtifacts do let(:guest) { create(:project_member, :guest, project: project).user } let!(:job) do - create(:ci_build, :success, :tags, pipeline: pipeline, - artifacts_expire_at: 1.day.since) + create(:ci_build, :success, :tags, pipeline: pipeline, artifacts_expire_at: 1.day.since) end before do @@ -535,8 +534,7 @@ RSpec.describe API::Ci::JobArtifacts do context 'with regular branch' do before do pipeline.reload - pipeline.update!(ref: 'master', - sha: project.commit('master').sha) + pipeline.update!(ref: 'master', sha: project.commit('master').sha) get_for_ref('master') end @@ -579,8 +577,7 @@ RSpec.describe API::Ci::JobArtifacts do stub_artifacts_object_storage job.success - project.update!(visibility_level: visibility_level, - public_builds: public_builds) + project.update!(visibility_level: visibility_level, public_builds: public_builds) get_artifact_file(artifact) end @@ -676,8 +673,7 @@ RSpec.describe API::Ci::JobArtifacts do context 'with branch name containing slash' do before do pipeline.reload - pipeline.update!(ref: 'improve/awesome', - sha: project.commit('improve/awesome').sha) + pipeline.update!(ref: 'improve/awesome', sha: project.commit('improve/awesome').sha) end it 'returns a specific artifact file for a valid path', :sidekiq_might_not_need_inline do diff --git a/spec/requests/api/ci/jobs_spec.rb b/spec/requests/api/ci/jobs_spec.rb index 57828e50320..b8983e9632e 100644 --- a/spec/requests/api/ci/jobs_spec.rb +++ b/spec/requests/api/ci/jobs_spec.rb @@ -32,8 +32,7 @@ RSpec.describe API::Ci::Jobs do end let!(:job) do - create(:ci_build, :success, :tags, pipeline: pipeline, - artifacts_expire_at: 1.day.since) + create(:ci_build, :success, :tags, pipeline: pipeline, artifacts_expire_at: 1.day.since) end before do @@ -94,9 +93,13 @@ RSpec.describe API::Ci::Jobs do let(:params_with_token) { {} } end + def perform_request + get api('/job'), headers: headers_with_token, params: params_with_token + end + before do |example| unless example.metadata[:skip_before_request] - get api('/job'), headers: headers_with_token, params: params_with_token + perform_request end end @@ -125,6 +128,15 @@ RSpec.describe API::Ci::Jobs do expect(json_response['finished_at']).to be_nil end + it 'avoids N+1 queries', :skip_before_request do + control_count = ActiveRecord::QueryRecorder.new { perform_request }.count + + running_job = create(:ci_build, :running, project: project, user: user, pipeline: pipeline, artifacts_expire_at: 1.day.since) + running_job.save! + + expect { perform_request }.not_to exceed_query_limit(control_count) + end + it_behaves_like 'returns common pipeline data' do let(:jobx) { running_job } end @@ -237,6 +249,10 @@ RSpec.describe API::Ci::Jobs do it 'includes environment slug' do expect(json_response.dig('environment', 'slug')).to eq('production') end + + it 'includes environment tier' do + expect(json_response.dig('environment', 'tier')).to eq('production') + end end context 'when non-deployment environment action' do @@ -248,6 +264,10 @@ RSpec.describe API::Ci::Jobs do it 'includes environment slug' do expect(json_response.dig('environment', 'slug')).to eq('review') end + + it 'includes environment tier' do + expect(json_response.dig('environment', 'tier')).to eq('development') + end end context 'when passing the token as params' do diff --git a/spec/requests/api/ci/runner/jobs_request_post_spec.rb b/spec/requests/api/ci/runner/jobs_request_post_spec.rb index cd58251cfcc..b33b97f90d7 100644 --- a/spec/requests/api/ci/runner/jobs_request_post_spec.rb +++ b/spec/requests/api/ci/runner/jobs_request_post_spec.rb @@ -17,11 +17,12 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do end describe '/api/v4/jobs' do - let(:group) { create(:group, :nested) } + let_it_be(:group) { create(:group, :nested) } + let_it_be(:user) { create(:user) } + let(:project) { create(:project, namespace: group, shared_runners_enabled: false) } - let(:pipeline) { create(:ci_pipeline, project: project, ref: 'master') } let(:runner) { create(:ci_runner, :project, projects: [project]) } - let(:user) { create(:user) } + let(:pipeline) { create(:ci_pipeline, project: project, ref: 'master') } let(:job) do create(:ci_build, :pending, :queued, :artifacts, :extended_options, pipeline: pipeline, name: 'spinach', stage: 'test', stage_idx: 0) @@ -145,7 +146,7 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do let(:expected_job_info) do { 'id' => job.id, 'name' => job.name, - 'stage' => job.stage, + 'stage' => job.stage_name, 'project_id' => job.project.id, 'project_name' => job.project.name } end @@ -354,6 +355,9 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do end context 'when GIT_DEPTH is not specified and there is no default git depth for the project' do + let(:project) { create(:project, namespace: group, shared_runners_enabled: false) } + let(:runner) { create(:ci_runner, :project, projects: [project]) } + before do project.update!(ci_default_git_depth: nil) end @@ -411,7 +415,8 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do context 'when job is made for merge request' do let(:pipeline) { create(:ci_pipeline, source: :merge_request_event, project: project, ref: 'feature', merge_request: merge_request) } let!(:job) { create(:ci_build, :pending, :queued, pipeline: pipeline, name: 'spinach', ref: 'feature', stage: 'test', stage_idx: 0) } - let(:merge_request) { create(:merge_request) } + + let_it_be(:merge_request) { create(:merge_request) } it 'sets branch as ref_type' do request_job @@ -546,9 +551,12 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do let!(:job) { create(:ci_build, :pending, :queued, :tag, pipeline: pipeline, name: 'spinach', stage: 'test', stage_idx: 0) } let!(:job2) { create(:ci_build, :pending, :queued, :tag, pipeline: pipeline, name: 'rubocop', stage: 'test', stage_idx: 0) } let!(:test_job) do - create(:ci_build, :pending, :queued, pipeline: pipeline, name: 'deploy', - stage: 'deploy', stage_idx: 1, - options: { script: ['bash'], dependencies: [job2.name] }) + create(:ci_build, :pending, :queued, + pipeline: pipeline, + name: 'deploy', + stage: 'deploy', + stage_idx: 1, + options: { script: ['bash'], dependencies: [job2.name] }) end before do @@ -570,9 +578,12 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do let!(:job) { create(:ci_build, :pending, :queued, :tag, pipeline: pipeline, name: 'spinach', stage: 'test', stage_idx: 0) } let!(:job2) { create(:ci_build, :pending, :queued, :tag, pipeline: pipeline, name: 'rubocop', stage: 'test', stage_idx: 0) } let!(:empty_dependencies_job) do - create(:ci_build, :pending, :queued, pipeline: pipeline, name: 'empty_dependencies_job', - stage: 'deploy', stage_idx: 1, - options: { script: ['bash'], dependencies: [] }) + create(:ci_build, :pending, :queued, + pipeline: pipeline, + name: 'empty_dependencies_job', + stage: 'deploy', + stage_idx: 1, + options: { script: ['bash'], dependencies: [] }) end before do @@ -722,7 +733,9 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do describe 'timeout support' do context 'when project specifies job timeout' do - let(:project) { create(:project, shared_runners_enabled: false, build_timeout: 1234) } + let_it_be(:project) { create(:project, shared_runners_enabled: false, build_timeout: 1234) } + + let(:runner) { create(:ci_runner, :project, projects: [project]) } it 'contains info about timeout taken from project' do request_job @@ -827,22 +840,6 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do 'image' => { 'name' => 'ruby', 'pull_policy' => ['if-not-present'], 'entrypoint' => nil, 'ports' => [] } ) end - - context 'when the FF ci_docker_image_pull_policy is disabled' do - before do - stub_feature_flags(ci_docker_image_pull_policy: false) - end - - it 'returns the image without pull policy' do - request_job - - expect(response).to have_gitlab_http_status(:created) - expect(json_response).to include( - 'id' => job.id, - 'image' => { 'name' => 'ruby', 'entrypoint' => nil, 'ports' => [] } - ) - end - end end context 'when service has pull_policy' do @@ -867,31 +864,17 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do 'ports' => [], 'pull_policy' => ['if-not-present'], 'variables' => [] }] ) end - - context 'when the FF ci_docker_image_pull_policy is disabled' do - before do - stub_feature_flags(ci_docker_image_pull_policy: false) - end - - it 'returns the service without pull policy' do - request_job - - expect(response).to have_gitlab_http_status(:created) - expect(json_response).to include( - 'id' => job.id, - 'services' => [{ 'alias' => nil, 'command' => nil, 'entrypoint' => nil, 'name' => 'postgres:11.9', - 'ports' => [], 'variables' => [] }] - ) - end - end end describe 'a job with excluded artifacts' do context 'when excluded paths are defined' do let(:job) do - create(:ci_build, :pending, :queued, pipeline: pipeline, name: 'test', - stage: 'deploy', stage_idx: 1, - options: { artifacts: { paths: ['abc'], exclude: ['cde'] } }) + create(:ci_build, :pending, :queued, + pipeline: pipeline, + name: 'test', + stage: 'deploy', + stage_idx: 1, + options: { artifacts: { paths: ['abc'], exclude: ['cde'] } }) end context 'when a runner supports this feature' do @@ -950,8 +933,8 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do end context 'when the runner is of group type' do - let(:group) { create(:group) } - let(:runner) { create(:ci_runner, :group, groups: [group]) } + let_it_be(:group) { create(:group) } + let_it_be(:runner) { create(:ci_runner, :group, groups: [group]) } it_behaves_like 'storing arguments in the application context for the API' do let(:expected_params) { { root_namespace: group.full_path_components.first, client_id: "runner/#{runner.id}" } } diff --git a/spec/requests/api/ci/runners_spec.rb b/spec/requests/api/ci/runners_spec.rb index 31b85a0b1d6..fa1f713e757 100644 --- a/spec/requests/api/ci/runners_spec.rb +++ b/spec/requests/api/ci/runners_spec.rb @@ -889,6 +889,44 @@ RSpec.describe API::Ci::Runners do end end + it 'avoids N+1 DB queries' do + get api("/runners/#{shared_runner.id}/jobs", admin) + + control = ActiveRecord::QueryRecorder.new do + get api("/runners/#{shared_runner.id}/jobs", admin) + end + + create(:ci_build, :failed, runner: shared_runner, project: project) + + expect do + get api("/runners/#{shared_runner.id}/jobs", admin) + end.not_to exceed_query_limit(control.count) + end + + it 'batches loading of commits' do + shared_runner = create(:ci_runner, :instance, description: 'Shared runner') + + project_with_repo = create(:project, :repository) + + pipeline = create(:ci_pipeline, project: project_with_repo, sha: 'ddd0f15ae83993f5cb66a927a28673882e99100b') + create(:ci_build, :running, runner: shared_runner, project: project_with_repo, pipeline: pipeline) + + pipeline = create(:ci_pipeline, project: project_with_repo, sha: 'c1c67abbaf91f624347bb3ae96eabe3a1b742478') + create(:ci_build, :failed, runner: shared_runner, project: project_with_repo, pipeline: pipeline) + + pipeline = create(:ci_pipeline, project: project_with_repo, sha: '1a0b36b3cdad1d2ee32457c102a8c0b7056fa863') + create(:ci_build, :failed, runner: shared_runner, project: project_with_repo, pipeline: pipeline) + + expect_next_instance_of(Repository) do |repo| + expect(repo).to receive(:commits_by).with(oids: %w[ + 1a0b36b3cdad1d2ee32457c102a8c0b7056fa863 + c1c67abbaf91f624347bb3ae96eabe3a1b742478 + ]).once.and_call_original + end + + get api("/runners/#{shared_runner.id}/jobs", admin), params: { per_page: 2, order_by: 'id', sort: 'desc' } + end + context "when runner doesn't exist" do it 'returns 404' do get api('/runners/0/jobs', admin) |