diff options
author | Stan Hu <stanhu@gmail.com> | 2019-04-12 12:29:47 -0700 |
---|---|---|
committer | Stan Hu <stanhu@gmail.com> | 2019-04-15 08:10:10 -0700 |
commit | 16259796539f19f7b04ad078a28aa38c5b50912f (patch) | |
tree | d3596f714417223feb8b788a8f037ce2406e4531 /spec | |
parent | 0a99e0220d9371423039f05f700af3675b26624f (diff) | |
download | gitlab-ce-sh-fix-pipeline-delete-caching.tar.gz |
Properly expire all pipeline caches when pipeline is deletedsh-fix-pipeline-delete-caching
When deleting a pipeline, only some of the cache structures were being
expired, but not the full pipeline list. We have to synchronously
schedule a pipeline cache expiration because the pipeline will be
deleted if the Sidekiq expiration job picks it up. To do this, properly
extract all the logic buried in the Sidekiq worker into a service, and
then call the service.
Closes https://gitlab.com/gitlab-org/gitlab-ce/issues/60469
Diffstat (limited to 'spec')
-rw-r--r-- | spec/services/ci/expire_pipeline_cache_service_spec.rb | 61 | ||||
-rw-r--r-- | spec/workers/expire_pipeline_cache_worker_spec.rb | 29 |
2 files changed, 64 insertions, 26 deletions
diff --git a/spec/services/ci/expire_pipeline_cache_service_spec.rb b/spec/services/ci/expire_pipeline_cache_service_spec.rb new file mode 100644 index 00000000000..ff2d286465a --- /dev/null +++ b/spec/services/ci/expire_pipeline_cache_service_spec.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Ci::ExpirePipelineCacheService do + set(:user) { create(:user) } + set(:project) { create(:project) } + set(:pipeline) { create(:ci_pipeline, project: project) } + subject { described_class.new } + + describe '#execute' do + it 'invalidates Etag caching for project pipelines path' do + pipelines_path = "/#{project.full_path}/pipelines.json" + new_mr_pipelines_path = "/#{project.full_path}/merge_requests/new.json" + pipeline_path = "/#{project.full_path}/pipelines/#{pipeline.id}.json" + + expect_any_instance_of(Gitlab::EtagCaching::Store).to receive(:touch).with(pipelines_path) + expect_any_instance_of(Gitlab::EtagCaching::Store).to receive(:touch).with(new_mr_pipelines_path) + expect_any_instance_of(Gitlab::EtagCaching::Store).to receive(:touch).with(pipeline_path) + + subject.execute(pipeline) + end + + it 'invalidates Etag caching for merge request pipelines if pipeline runs on any commit of that source branch' do + pipeline = create(:ci_empty_pipeline, status: 'created', project: project, ref: 'master') + merge_request = create(:merge_request, source_project: project, source_branch: pipeline.ref) + merge_request_pipelines_path = "/#{project.full_path}/merge_requests/#{merge_request.iid}/pipelines.json" + + allow_any_instance_of(Gitlab::EtagCaching::Store).to receive(:touch) + expect_any_instance_of(Gitlab::EtagCaching::Store).to receive(:touch).with(merge_request_pipelines_path) + + subject.execute(pipeline) + end + + it 'updates the cached status for a project' do + expect(Gitlab::Cache::Ci::ProjectPipelineStatus).to receive(:update_for_pipeline) + .with(pipeline) + + subject.execute(pipeline) + end + + context 'destroyed pipeline' do + let(:project_with_repo) { create(:project, :repository) } + let!(:pipeline_with_commit) { create(:ci_pipeline, :success, project: project_with_repo, sha: project_with_repo.commit.id) } + + it 'clears the cache', :use_clean_rails_memory_store_caching do + create(:commit_status, :success, pipeline: pipeline_with_commit, ref: pipeline_with_commit.ref) + + # Sanity check + expect(project_with_repo.pipeline_status.has_status?).to be_truthy + + subject.execute(pipeline_with_commit, delete: true) + + pipeline_with_commit.destroy! + + # Need to use find to avoid memoization + expect(Project.find(project_with_repo.id).pipeline_status.has_status?).to be_falsey + end + end + end +end diff --git a/spec/workers/expire_pipeline_cache_worker_spec.rb b/spec/workers/expire_pipeline_cache_worker_spec.rb index c98b69ef76c..5652f5e8685 100644 --- a/spec/workers/expire_pipeline_cache_worker_spec.rb +++ b/spec/workers/expire_pipeline_cache_worker_spec.rb @@ -9,40 +9,17 @@ describe ExpirePipelineCacheWorker do subject { described_class.new } describe '#perform' do - it 'invalidates Etag caching for project pipelines path' do - pipelines_path = "/#{project.full_path}/pipelines.json" - new_mr_pipelines_path = "/#{project.full_path}/merge_requests/new.json" - pipeline_path = "/#{project.full_path}/pipelines/#{pipeline.id}.json" - - expect_any_instance_of(Gitlab::EtagCaching::Store).to receive(:touch).with(pipelines_path) - expect_any_instance_of(Gitlab::EtagCaching::Store).to receive(:touch).with(new_mr_pipelines_path) - expect_any_instance_of(Gitlab::EtagCaching::Store).to receive(:touch).with(pipeline_path) - - subject.perform(pipeline.id) - end - - it 'invalidates Etag caching for merge request pipelines if pipeline runs on any commit of that source branch' do - pipeline = create(:ci_empty_pipeline, status: 'created', project: project, ref: 'master') - merge_request = create(:merge_request, source_project: project, source_branch: pipeline.ref) - merge_request_pipelines_path = "/#{project.full_path}/merge_requests/#{merge_request.iid}/pipelines.json" - - allow_any_instance_of(Gitlab::EtagCaching::Store).to receive(:touch) - expect_any_instance_of(Gitlab::EtagCaching::Store).to receive(:touch).with(merge_request_pipelines_path) + it 'executes the service' do + expect_any_instance_of(Ci::ExpirePipelineCacheService).to receive(:execute).with(pipeline).and_call_original subject.perform(pipeline.id) end it "doesn't do anything if the pipeline not exist" do + expect_any_instance_of(Ci::ExpirePipelineCacheService).not_to receive(:execute) expect_any_instance_of(Gitlab::EtagCaching::Store).not_to receive(:touch) subject.perform(617748) end - - it 'updates the cached status for a project' do - expect(Gitlab::Cache::Ci::ProjectPipelineStatus).to receive(:update_for_pipeline) - .with(pipeline) - - subject.perform(pipeline.id) - end end end |