gitlab-org--gitlab-foss/spec/models/concerns/reactive_caching_spec.rb
Shinya Maeda 8fa361b2d9 Squashed commit of the following:
commit 610c02c305d9fb3c7d271883450a5fee8b0cf16f
Merge: f2088edb260 84f24dcef0
Author: Shinya Maeda <shinya@gitlab.com>
Date:   Tue Aug 7 23:01:38 2018 +0900

    Merge branch 'master-ce' into improve-junit-support-be

commit f2088edb26008e5791b7be86fc02fc470c881143
Merge: c67e1d32cac 339f47abec1
Author: Shinya Maeda <shinya@gitlab.com>
Date:   Tue Aug 7 21:52:10 2018 +0900

    Merge branch 'improve-junit-support-be' of gitlab.com:gitlab-org/gitlab-ce into improve-junit-support-be

commit c67e1d32cac731b895e2f49a24ce0e1726b8196c
Author: Shinya Maeda <shinya@gitlab.com>
Date:   Tue Aug 7 21:51:39 2018 +0900

    Remove debuggable fixtures

commit 339f47abec1d0ce815e6103a087902d71d8ff5be
Merge: 7a33a9be724 96b748fbcc0
Author: Filipa Lacerda <filipa@gitlab.com>
Date:   Tue Aug 7 11:10:18 2018 +0100

    Merge branch 'improve-junit-support-be' of https://gitlab.com/gitlab-org/gitlab-ce into improve-junit-support-be

    * 'improve-junit-support-be' of https://gitlab.com/gitlab-org/gitlab-ce:
      Add spec for latest
      Add spec for merge request
      Add spec for cache invalidation
      Add spec for pipeline
      Add spec
      Fix specs
      Support corrupted fixtures
      Add  cache key to error message

commit 7a33a9be724dbde79a24cec77658952ff2d2fa6c
Author: Filipa Lacerda <filipa@gitlab.com>
Date:   Tue Aug 7 11:09:56 2018 +0100

    Show resolved failures

commit 96b748fbcc00a98a13aeb78f5d97de9cf25035b6
Author: Shinya Maeda <shinya@gitlab.com>
Date:   Tue Aug 7 18:50:05 2018 +0900

    Add spec for latest

commit 0e8b024169b4b0ac272331117ac2fa821c4052f7
Author: Shinya Maeda <shinya@gitlab.com>
Date:   Tue Aug 7 18:24:38 2018 +0900

    Add spec for merge request

commit 8690a699bc98394ad4deebdc91e6690758c5965e
Author: Shinya Maeda <shinya@gitlab.com>
Date:   Tue Aug 7 18:18:55 2018 +0900

    Add spec for cache invalidation

commit 97678e1612826af409ca8a04b6c0dc830f7b66c6
Author: Shinya Maeda <shinya@gitlab.com>
Date:   Tue Aug 7 18:01:03 2018 +0900

    Add spec for pipeline

commit 96c2a698af049e4026c68e74b1f41a265464b2b2
Author: Shinya Maeda <shinya@gitlab.com>
Date:   Tue Aug 7 17:52:21 2018 +0900

    Add spec

commit 67bcbd25a3c13abb78ea43c0411f5aed417b87d0
Author: Shinya Maeda <shinya@gitlab.com>
Date:   Tue Aug 7 17:39:02 2018 +0900

    Fix specs

commit d7d49def2023f85c07d2718b83f35c8849f65f05
Author: Shinya Maeda <shinya@gitlab.com>
Date:   Tue Aug 7 13:11:07 2018 +0900

    Support corrupted fixtures

commit d58dbbc17a7d954db22082615f5331c148c1061b
Author: Shinya Maeda <shinya@gitlab.com>
Date:   Tue Aug 7 13:10:47 2018 +0900

    Add  cache key to error message

commit f6f976216dc36333b5e05e3f0acdfca689350483
Author: Shinya Maeda <shinya@gitlab.com>
Date:   Thu Aug 2 19:07:46 2018 +0900

    bring back debaggable fixtures

commit 48a7800e67a718145c0e88c324c0c1f9619e26a4
Merge: 2822b9e8a36 dd627072b3
Author: Shinya Maeda <shinya@gitlab.com>
Date:   Tue Aug 7 09:22:22 2018 +0900

    Merge branch 'master-ce' into improve-junit-support-be

commit 2822b9e8a369162d098a72a58803c8494b2343cd
Author: Shinya Maeda <shinya@gitlab.com>
Date:   Mon Aug 6 22:54:47 2018 +0900

    Move cache invalidation policy to outside of reactive cache

commit b35efb1764ae61bb31dacbf79dbc022dcee3a203
Author: Shinya Maeda <shinya@gitlab.com>
Date:   Mon Aug 6 22:34:10 2018 +0900

    ADd reactive cache an ability to invalite cache

commit feafee6f8a50f4a32866d8ae768e99766b0b7c73
Author: Shinya Maeda <shinya@gitlab.com>
Date:   Mon Aug 6 19:25:22 2018 +0900

    Pipeline has test reports if latest builds have any

commit f302dbb73abe03c6c431e7d52d526e28a1586fee
Author: Shinya Maeda <shinya@gitlab.com>
Date:   Mon Aug 6 19:18:56 2018 +0900

    Invalidate test reports cache if it's outdated

commit 83adaca01a1ee1cd64cac86b6fa3d10e2e4e2b98
Author: Shinya Maeda <shinya@gitlab.com>
Date:   Mon Aug 6 18:08:06 2018 +0900

    Revert cache invalidation in expire pipeline cache worker

commit ec3af5de4ca34e2e92ad6b97f29733d6c65062bc
Author: Shinya Maeda <shinya@gitlab.com>
Date:   Mon Aug 6 15:13:47 2018 +0900

    Fix feature spec

commit 0db48805a1ba68763be0504eb57218bde2380e4b
Author: Shinya Maeda <shinya@gitlab.com>
Date:   Mon Aug 6 14:07:46 2018 +0900

    Change lifetime of test reports cache to 10 minutes

commit 17f7e78bfe2188c349cda1ff90a3ea94d337461e
Author: Shinya Maeda <shinya@gitlab.com>
Date:   Mon Aug 6 14:07:19 2018 +0900

    Add changelog

commit 89c87585ab7f5333a8139c02b330dd2caf0be31a
Author: Shinya Maeda <shinya@gitlab.com>
Date:   Mon Aug 6 14:01:20 2018 +0900

    Add feature spec

commit 1120cfd7a9ab06105f2e763c375fab00922b7e0c
Author: Shinya Maeda <shinya@gitlab.com>
Date:   Mon Aug 6 12:55:47 2018 +0900

    Invalidate cache when pipeline status transits. Correct test reports from the latest builds
2018-08-07 23:03:48 +09:00

181 lines
4.4 KiB
Ruby

require 'spec_helper'
describe ReactiveCaching, :use_clean_rails_memory_store_caching do
include ExclusiveLeaseHelpers
include ReactiveCachingHelpers
class CacheTest
include ReactiveCaching
self.reactive_cache_key = ->(thing) { ["foo", thing.id] }
self.reactive_cache_lifetime = 5.minutes
self.reactive_cache_refresh_interval = 15.seconds
attr_reader :id
def initialize(id, &blk)
@id = id
@calculator = blk
end
def calculate_reactive_cache
@calculator.call
end
def result
with_reactive_cache do |data|
data / 2
end
end
end
let(:calculation) { -> { 2 + 2 } }
let(:cache_key) { "foo:666" }
let(:instance) { CacheTest.new(666, &calculation) }
describe '#with_reactive_cache' do
before do
stub_reactive_cache
end
subject(:go!) { instance.result }
context 'when cache is empty' do
it { is_expected.to be_nil }
it 'enqueues a background worker to bootstrap the cache' do
expect(ReactiveCachingWorker).to receive(:perform_async).with(CacheTest, 666)
go!
end
it 'updates the cache lifespan' do
expect(reactive_cache_alive?(instance)).to be_falsy
go!
expect(reactive_cache_alive?(instance)).to be_truthy
end
end
context 'when the cache is full' do
before do
stub_reactive_cache(instance, 4)
end
it { is_expected.to eq(2) }
it 'does not enqueue a background worker' do
expect(ReactiveCachingWorker).not_to receive(:perform_async)
go!
end
it 'updates the cache lifespan' do
expect(Rails.cache).to receive(:write).with(alive_reactive_cache_key(instance), true, expires_in: anything)
go!
end
context 'and expired' do
before do
invalidate_reactive_cache(instance)
end
it { is_expected.to be_nil }
end
context 'when cache was invalidated' do
it 'refreshes cache' do
expect(ReactiveCachingWorker).to receive(:perform_async).with(CacheTest, 666)
instance.with_reactive_cache { raise described_class::InvalidateReactiveCache }
end
end
end
end
describe '#clear_reactive_cache!' do
before do
stub_reactive_cache(instance, 4)
instance.clear_reactive_cache!
end
it { expect(instance.result).to be_nil }
it { expect(reactive_cache_alive?(instance)).to be_falsy }
end
describe '#exclusively_update_reactive_cache!' do
subject(:go!) { instance.exclusively_update_reactive_cache! }
context 'when the lease is free and lifetime is not exceeded' do
before do
stub_reactive_cache(instance, "preexisting")
end
it 'takes and releases the lease' do
expect_to_obtain_exclusive_lease(cache_key, 'uuid')
expect_to_cancel_exclusive_lease(cache_key, 'uuid')
go!
end
it 'caches the result of #calculate_reactive_cache' do
go!
expect(read_reactive_cache(instance)).to eq(calculation.call)
end
it "enqueues a repeat worker" do
expect_reactive_cache_update_queued(instance)
go!
end
it "calls a reactive_cache_updated only once if content did not change on subsequent update" do
expect(instance).to receive(:calculate_reactive_cache).twice
expect(instance).to receive(:reactive_cache_updated).once
2.times { instance.exclusively_update_reactive_cache! }
end
context 'and #calculate_reactive_cache raises an exception' do
before do
stub_reactive_cache(instance, "preexisting")
end
let(:calculation) { -> { raise "foo"} }
it 'leaves the cache untouched' do
expect { go! }.to raise_error("foo")
expect(read_reactive_cache(instance)).to eq("preexisting")
end
it 'enqueues a repeat worker' do
expect_reactive_cache_update_queued(instance)
expect { go! }.to raise_error("foo")
end
end
end
context 'when lifetime is exceeded' do
it 'skips the calculation' do
expect(instance).to receive(:calculate_reactive_cache).never
go!
end
end
context 'when the lease is already taken' do
it 'skips the calculation' do
stub_exclusive_lease_taken(cache_key)
expect(instance).to receive(:calculate_reactive_cache).never
go!
end
end
end
end