Commit e317e8fa authored by Ash McKenzie's avatar Ash McKenzie

Merge branch '13426-design-collection-copy-state' into 'master'

Add copy states to DesignCollection

See merge request gitlab-org/gitlab!42291
parents d43c1db0 5083eeec
......@@ -6,8 +6,34 @@ module DesignManagement
delegate :designs, :project, to: :issue
state_machine :copy_state, initial: :ready, namespace: :copy do
after_transition any => any, do: :update_stored_copy_state!
event :start do
transition ready: :in_progress
end
event :end do
transition in_progress: :ready
end
event :error do
transition in_progress: :error
end
event :reset do
transition any => :ready
end
end
def initialize(issue)
super() # Necessary to initialize state_machine
@issue = issue
if stored_copy_state = get_stored_copy_state
@copy_state = stored_copy_state
end
end
def ==(other)
......@@ -30,5 +56,39 @@ module DesignManagement
def designs_by_filename(filenames)
designs.current.where(filename: filenames)
end
private
def update_stored_copy_state!
# As "ready" is the initial copy state we can clear the cached value
# rather than persist it.
if copy_ready?
unset_store_copy_state!
else
set_stored_copy_state!
end
end
def copy_state_cache_key
"DesignCollection/copy_state/issue=#{issue.id}"
end
def get_stored_copy_state
Gitlab::Redis::SharedState.with do |redis|
redis.get(copy_state_cache_key)
end
end
def set_stored_copy_state!
Gitlab::Redis::SharedState.with do |redis|
redis.set(copy_state_cache_key, copy_state)
end
end
def unset_store_copy_state!
Gitlab::Redis::SharedState.with do |redis|
redis.del(copy_state_cache_key)
end
end
end
end
......@@ -3,8 +3,9 @@ require 'spec_helper'
RSpec.describe DesignManagement::DesignCollection do
include DesignManagementTestHelpers
using RSpec::Parameterized::TableSyntax
let_it_be(:issue, reload: true) { create(:issue) }
let_it_be(:issue, refind: true) { create(:issue) }
subject(:collection) { described_class.new(issue) }
......@@ -45,6 +46,61 @@ RSpec.describe DesignManagement::DesignCollection do
end
end
describe "#copy_state", :clean_gitlab_redis_shared_state do
it "defaults to ready" do
expect(collection).to be_copy_ready
end
it "persists its state changes between initializations" do
collection.start_copy!
expect(described_class.new(issue)).to be_copy_in_progress
end
where(:state, :can_start, :can_end, :can_error, :can_reset) do
"ready" | true | false | true | true
"in_progress" | false | true | true | true
"error" | false | false | false | true
end
with_them do
it "maintains state machine transition rules", :aggregate_failures do
collection.copy_state = state
expect(collection.can_start_copy?).to eq(can_start)
expect(collection.can_end_copy?).to eq(can_end)
end
end
describe "clearing the redis cached state when state changes back to ready" do
def redis_copy_state
Gitlab::Redis::SharedState.with do |redis|
redis.get(collection.send(:copy_state_cache_key))
end
end
def fire_state_events(*events)
events.each do |event|
collection.fire_copy_state_event(event)
end
end
it "clears the cached state on end_copy!", :aggregate_failures do
fire_state_events(:start)
expect { collection.end_copy! }.to change { redis_copy_state }.from("in_progress").to(nil)
expect(collection).to be_copy_ready
end
it "clears the cached state on reset_copy!", :aggregate_failures do
fire_state_events(:start, :error)
expect { collection.reset_copy! }.to change { redis_copy_state }.from("error").to(nil)
expect(collection).to be_copy_ready
end
end
end
describe "#versions" do
it "includes versions for all designs" do
version_1 = create(:design_version)
......
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