execute_locked_block_spec.rb 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. require 'rails_helper'
  3. RSpec.describe Service::ExecuteLockedBlock, :aggregate_failures do
  4. describe '#execute' do
  5. subject(:object) { described_class.new(resource, ttl) }
  6. let(:resource) { 'resource' }
  7. let(:ttl) { 1 }
  8. let(:block) { proc { true } }
  9. it 'return block result' do
  10. allow_any_instance_of(Redlock::Client).to receive(:lock).with(resource, ttl, &block).and_return(true)
  11. expect(object.execute(&block)).to be(true)
  12. end
  13. context 'when resource is already locked' do
  14. it 'returns nil' do
  15. allow_any_instance_of(Redlock::Client).to receive(:lock).with(resource, ttl, &block).and_return(nil)
  16. expect(object.execute(&block)).to be_nil
  17. end
  18. end
  19. end
  20. describe '.lock' do
  21. let(:resource) { 'resource' }
  22. let(:ttl) { 1 }
  23. let(:lock_info) do
  24. {
  25. resource: resource,
  26. value: SecureRandom.uuid,
  27. }
  28. end
  29. it 'returns the lock info' do
  30. allow_any_instance_of(Redlock::Client).to receive(:lock).with(resource, ttl).and_return(lock_info)
  31. expect(described_class.lock(resource, ttl)).to be(lock_info)
  32. end
  33. context 'when resource is already locked' do
  34. it 'returns nil' do
  35. allow_any_instance_of(Redlock::Client).to receive(:lock).with(resource, ttl).and_return(nil)
  36. expect(described_class.lock(resource, ttl)).to be_nil
  37. end
  38. end
  39. end
  40. describe '.unlock' do
  41. let(:resource) { 'resource' }
  42. let(:lock_info) do
  43. {
  44. resource: resource,
  45. value: SecureRandom.uuid,
  46. }
  47. end
  48. it 'returns true' do
  49. allow_any_instance_of(Redlock::Client).to receive(:unlock).with(lock_info).and_return(1)
  50. expect(described_class.unlock(lock_info)).to be(1)
  51. end
  52. context 'when resource can not be unlocked' do
  53. it 'returns false' do
  54. allow_any_instance_of(Redlock::Client).to receive(:unlock).with(lock_info).and_return(0)
  55. expect(described_class.unlock(lock_info)).to be(0)
  56. end
  57. end
  58. end
  59. describe '.locked?' do
  60. let(:resource) { 'resource' }
  61. let(:lock_info) do
  62. {
  63. resource: resource,
  64. value: SecureRandom.uuid,
  65. }
  66. end
  67. context 'when resource is locked' do
  68. it 'returns true' do
  69. allow_any_instance_of(Redlock::Client).to receive(:locked?).with(resource).and_return(true)
  70. expect(described_class.locked?(resource)).to be(true)
  71. end
  72. end
  73. context 'when resource is not locked' do
  74. it 'returns false' do
  75. allow_any_instance_of(Redlock::Client).to receive(:locked?).with(resource).and_return(false)
  76. expect(described_class.locked?(resource)).to be(false)
  77. end
  78. end
  79. end
  80. describe '.locked!' do
  81. let(:resource) { 'resource' }
  82. let(:lock_info) do
  83. {
  84. resource: resource,
  85. value: SecureRandom.uuid,
  86. }
  87. end
  88. context 'when resource is locked' do
  89. it 'raises an error' do
  90. allow_any_instance_of(Redlock::Client).to receive(:locked?).with(resource).and_return(true)
  91. expect { described_class.locked!(resource) }.to raise_error(Service::ExecuteLockedBlock::ExecuteLockedBlockError)
  92. end
  93. end
  94. context 'when resource is not locked' do
  95. it 'returns false' do
  96. allow_any_instance_of(Redlock::Client).to receive(:locked?).with(resource).and_return(false)
  97. expect(described_class.locked!(resource)).to be_nil
  98. end
  99. end
  100. end
  101. describe '.extend' do
  102. let(:lock_info) do
  103. {
  104. resource: 'resource',
  105. value: SecureRandom.uuid,
  106. validity: 1,
  107. }
  108. end
  109. it 'returns true' do
  110. allow_any_instance_of(Redlock::Client).to receive(:lock).with(nil, nil, extend: lock_info).and_return(1)
  111. expect(described_class.extend(lock_info)).to be(1)
  112. end
  113. context 'when resource can not be extended' do
  114. it 'returns false' do
  115. allow_any_instance_of(Redlock::Client).to receive(:lock).with(nil, nil, extend: lock_info).and_return(0)
  116. expect(described_class.extend(lock_info)).to be(0)
  117. end
  118. end
  119. end
  120. end