foreman_dlm 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +619 -0
  3. data/README.md +84 -0
  4. data/Rakefile +47 -0
  5. data/app/controllers/api/v2/dlmlocks_controller.rb +157 -0
  6. data/app/controllers/concerns/foreman/controller/parameters/dlmlocks.rb +15 -0
  7. data/app/controllers/concerns/foreman_dlm/find_host_by_client_cert.rb +63 -0
  8. data/app/controllers/concerns/foreman_dlm/find_host_by_ip.rb +54 -0
  9. data/app/controllers/dlmlocks_controller.rb +13 -0
  10. data/app/helpers/foreman_dlm/dlmlock_helper.rb +15 -0
  11. data/app/models/concerns/foreman_dlm/host_extensions.rb +14 -0
  12. data/app/models/concerns/foreman_dlm/host_monitoring_extensions.rb +36 -0
  13. data/app/models/dlmlock/update.rb +5 -0
  14. data/app/models/dlmlock.rb +79 -0
  15. data/app/views/api/v2/dlmlocks/acquire.json.rabl +3 -0
  16. data/app/views/api/v2/dlmlocks/base.json.rabl +3 -0
  17. data/app/views/api/v2/dlmlocks/create.json.rabl +3 -0
  18. data/app/views/api/v2/dlmlocks/index.json.rabl +3 -0
  19. data/app/views/api/v2/dlmlocks/main.json.rabl +7 -0
  20. data/app/views/api/v2/dlmlocks/release.json.rabl +3 -0
  21. data/app/views/api/v2/dlmlocks/show.json.rabl +8 -0
  22. data/app/views/api/v2/dlmlocks/update.json.rabl +3 -0
  23. data/app/views/api/v2/errors/precondition_failed.json.rabl +5 -0
  24. data/app/views/dlmlocks/_details.html.erb +35 -0
  25. data/app/views/dlmlocks/_list.html.erb +45 -0
  26. data/app/views/dlmlocks/index.html.erb +2 -0
  27. data/app/views/dlmlocks/show.html.erb +7 -0
  28. data/app/views/dlmlocks/welcome.html.erb +14 -0
  29. data/config/routes.rb +25 -0
  30. data/db/migrate/20170824084100_add_dlmlock.foreman_dlm.rb +12 -0
  31. data/lib/foreman_dlm/engine.rb +76 -0
  32. data/lib/foreman_dlm/version.rb +3 -0
  33. data/lib/foreman_dlm.rb +4 -0
  34. data/lib/tasks/foreman_dlm_tasks.rake +37 -0
  35. data/locale/Makefile +60 -0
  36. data/locale/en/foreman_dlm.po +19 -0
  37. data/locale/foreman_dlm.pot +19 -0
  38. data/locale/gemspec.rb +2 -0
  39. data/test/controllers/api/v2/dlmlocks_controller_test.rb +367 -0
  40. data/test/controllers/dlmlocks_test.rb +24 -0
  41. data/test/controllers/find_host_by_client_cert_test.rb +91 -0
  42. data/test/factories/dlmlock.rb +6 -0
  43. data/test/models/dlmlock_test.rb +201 -0
  44. data/test/models/host_monitoring_test.rb +42 -0
  45. data/test/test_plugin_helper.rb +9 -0
  46. metadata +124 -0
@@ -0,0 +1,367 @@
1
+ require 'test_plugin_helper'
2
+
3
+ class Api::V2::DlmlocksControllerTest < ActionController::TestCase
4
+ let(:host1) { as_admin { FactoryBot.create(:host, :managed) } }
5
+ let(:host2) { as_admin { FactoryBot.create(:host, :managed) } }
6
+
7
+ context 'with user authentication' do
8
+ context '#index' do
9
+ test 'should show dlmlocks' do
10
+ dlmlock = FactoryBot.create(:dlmlock, :host => host1)
11
+ get :index
12
+ assert_response :success
13
+ body = ActiveSupport::JSON.decode(@response.body)
14
+ results = body['results']
15
+ assert results
16
+ entry = results.detect { |entry| entry['id'] == dlmlock.id }
17
+ assert entry
18
+ assert_equal dlmlock.name, entry['name']
19
+ assert_equal dlmlock.type, entry['type']
20
+ assert_equal dlmlock.enabled, entry['enabled']
21
+ assert_equal dlmlock.host_id, entry['host_id']
22
+ end
23
+ end
24
+
25
+ context '#create' do
26
+ test 'should create dlmlock' do
27
+ assert_difference('Dlmlock.unscoped.count') do
28
+ post :create, valid_attrs_with_root
29
+ end
30
+ assert_response :success
31
+ body = ActiveSupport::JSON.decode(@response.body)
32
+ dlmlock = Dlmlock.find(body['id'])
33
+ assert dlmlock
34
+ assert_equal valid_attrs['name'], dlmlock.name
35
+ assert_equal valid_attrs['type'], dlmlock.type
36
+ assert_equal true, dlmlock.enabled
37
+ assert_nil dlmlock.host
38
+ end
39
+ end
40
+
41
+ context '#show' do
42
+ test 'should show individual record with host' do
43
+ dlmlock = FactoryBot.create(:dlmlock, :host => host1)
44
+ get :show, { :id => dlmlock.to_param }
45
+ assert_response :success
46
+ body = ActiveSupport::JSON.decode(@response.body)
47
+ refute_empty body
48
+ assert_equal dlmlock.name, body['name']
49
+ assert_equal dlmlock.type, body['type']
50
+ assert_equal true, body['enabled']
51
+ assert_equal host1.id, body['host_id']
52
+ end
53
+
54
+ test 'should show individual record that is disabled' do
55
+ dlmlock = FactoryBot.create(:dlmlock, :enabled => false)
56
+ get :show, { :id => dlmlock.to_param }
57
+ assert_response :success
58
+ body = ActiveSupport::JSON.decode(@response.body)
59
+ refute_empty body
60
+ assert_equal dlmlock.name, body['name']
61
+ assert_equal dlmlock.type, body['type']
62
+ assert_equal false, body['enabled']
63
+ assert_nil body['host_id']
64
+ end
65
+
66
+ test 'should show individual record by name' do
67
+ dlmlock = FactoryBot.create(:dlmlock, :host => host1)
68
+ get :show, { :id => dlmlock.name }
69
+ assert_response :success
70
+ body = ActiveSupport::JSON.decode(@response.body)
71
+ refute_empty body
72
+ assert_equal dlmlock.id, body['id']
73
+ assert_equal dlmlock.name, body['name']
74
+ host = body['host']
75
+ assert host
76
+ assert_equal host1.name, host['name']
77
+ refute host.has_key?('self')
78
+ end
79
+
80
+ test 'should not find dlmlock with invalid id' do
81
+ get :show, { :id => 9999999 }
82
+ assert_response :not_found
83
+ end
84
+ end
85
+
86
+ context '#update' do
87
+ test 'should update dlmlock' do
88
+ dlmlock = FactoryBot.create(:dlmlock)
89
+ put :update, { :id => dlmlock.to_param, :dlmlock => valid_attrs.merge(:host_id => host1.id, :enabled => false) }
90
+ assert_response :success
91
+ dlmlock.reload
92
+ assert_equal valid_attrs['name'], dlmlock.name
93
+ assert_equal valid_attrs['type'], dlmlock.type
94
+ assert_equal false, dlmlock.enabled
95
+ assert_equal host1.id, dlmlock.host_id
96
+ end
97
+ end
98
+
99
+ context '#destroy' do
100
+ test 'should destroy dlmlock' do
101
+ dlmlock = FactoryBot.create(:dlmlock)
102
+ assert_difference('Dlmlock.unscoped.count', -1) do
103
+ delete :destroy, { :id => dlmlock.to_param }
104
+ end
105
+ assert_response :success
106
+ assert_equal 0, Dlmlock.where(:id => dlmlock.id).count
107
+ end
108
+ end
109
+
110
+ context '#acquire' do
111
+ test 'should deny access' do
112
+ dlmlock = FactoryBot.create(:dlmlock)
113
+ put :acquire, { :id => dlmlock.to_param }
114
+ assert_response :forbidden
115
+ assert_nil dlmlock.reload.host
116
+ end
117
+ end
118
+
119
+ context '#release' do
120
+ test 'should deny access' do
121
+ dlmlock = FactoryBot.create(:dlmlock, :host => host2)
122
+ delete :release, { :id => dlmlock.to_param }
123
+ assert_response :forbidden
124
+ assert_equal host2, dlmlock.reload.host
125
+ end
126
+ end
127
+ end
128
+
129
+ context 'with client cert' do
130
+ setup do
131
+ User.current = nil
132
+ reset_api_credentials
133
+
134
+ Setting[:ssl_client_dn_env] = 'SSL_CLIENT_S_DN'
135
+ Setting[:ssl_client_verify_env] = 'SSL_CLIENT_VERIFY'
136
+
137
+ @request.env['HTTPS'] = 'on'
138
+ @request.env['SSL_CLIENT_S_DN'] = "CN=#{host1.name},DN=example,DN=com"
139
+ @request.env['SSL_CLIENT_VERIFY'] = 'SUCCESS'
140
+ end
141
+
142
+ context '#index' do
143
+ test 'should deny access' do
144
+ dlmlock = as_admin { FactoryBot.create(:dlmlock) }
145
+ get :index, { :id => dlmlock.to_param }
146
+ assert_response :unauthorized
147
+ end
148
+ end
149
+
150
+ context '#create' do
151
+ test 'should deny access' do
152
+ dlmlock = as_admin { FactoryBot.create(:dlmlock) }
153
+ post :create, valid_attrs_with_root
154
+ assert_response :unauthorized
155
+ end
156
+ end
157
+
158
+ context '#update' do
159
+ test 'should deny access' do
160
+ dlmlock = as_admin { FactoryBot.create(:dlmlock) }
161
+ put :update, { :id => dlmlock.to_param, :dlmlock => valid_attrs }
162
+ assert_response :unauthorized
163
+ end
164
+ end
165
+
166
+ context '#destroy' do
167
+ test 'should deny access' do
168
+ dlmlock = as_admin { FactoryBot.create(:dlmlock) }
169
+ delete :destroy, { :id => dlmlock.to_param }
170
+ assert_response :unauthorized
171
+ assert_equal 1, as_admin { Dlmlock.where(:id => dlmlock.id).count }
172
+ end
173
+ end
174
+
175
+ context '#show' do
176
+ test 'should show individual free lock' do
177
+ dlmlock = as_admin { FactoryBot.create(:dlmlock) }
178
+ get :show, { :id => dlmlock.to_param }
179
+ assert_response :success
180
+ body = ActiveSupport::JSON.decode(@response.body)
181
+ refute_empty body
182
+ assert_equal dlmlock.name, body['name']
183
+ assert_equal dlmlock.type, body['type']
184
+ assert_equal true, body['enabled']
185
+ assert_nil body['host_id']
186
+ assert_nil body['host']
187
+ end
188
+
189
+ test 'should show individual acquired lock by me' do
190
+ dlmlock = as_admin { FactoryBot.create(:dlmlock, :host => host1) }
191
+ get :show, { :id => dlmlock.to_param }
192
+ assert_response :success
193
+ body = ActiveSupport::JSON.decode(@response.body)
194
+ refute_empty body
195
+ assert_equal dlmlock.name, body['name']
196
+ assert_equal dlmlock.type, body['type']
197
+ assert_equal true, body['enabled']
198
+ assert_equal host1.id, body['host_id']
199
+ host = body['host']
200
+ assert host
201
+ assert_equal host1.name, host['name']
202
+ assert_equal true, host['self']
203
+ end
204
+
205
+ test 'should show individual acquired lock by other' do
206
+ dlmlock = as_admin { FactoryBot.create(:dlmlock, :host => host2) }
207
+ get :show, { :id => dlmlock.to_param }
208
+ assert_response :success
209
+ body = ActiveSupport::JSON.decode(@response.body)
210
+ refute_empty body
211
+ assert_equal dlmlock.name, body['name']
212
+ assert_equal dlmlock.type, body['type']
213
+ assert_equal true, body['enabled']
214
+ assert_equal host2.id, body['host_id']
215
+ host = body['host']
216
+ assert host
217
+ assert_equal host2.name, host['name']
218
+ assert_equal false, host['self']
219
+ end
220
+ end
221
+
222
+ context '#acquire' do
223
+ test 'should acquire empty dlmlock' do
224
+ dlmlock = as_admin { FactoryBot.create(:dlmlock) }
225
+ put :acquire, { :id => dlmlock.to_param }
226
+ assert_response :success
227
+ assert_equal host1, as_admin { dlmlock.reload.host }
228
+ end
229
+
230
+ test 'should acquire own dlmlock' do
231
+ dlmlock = as_admin { FactoryBot.create(:dlmlock, :host => host1) }
232
+ put :acquire, { :id => dlmlock.to_param }
233
+ assert_response :success
234
+ assert_equal host1, as_admin { dlmlock.reload.host }
235
+ end
236
+
237
+ test 'should not acquire foreign dlmlock' do
238
+ dlmlock = as_admin { FactoryBot.create(:dlmlock, :host => host2) }
239
+ put :acquire, { :id => dlmlock.to_param }
240
+ assert_response :precondition_failed
241
+ assert_equal host2, as_admin { dlmlock.reload.host }
242
+ end
243
+
244
+ test 'should transparently create non-existing dlmlock' do
245
+ lockname = 'Test Lock'
246
+ assert_equal 0, as_admin { Dlmlock.where(:name => lockname).count }
247
+ put :acquire, { :id => lockname }
248
+ assert_response :success
249
+ dlmlock = as_admin { Dlmlock.find_by(:name => lockname) }
250
+ assert_equal lockname, dlmlock.name
251
+ assert_equal host1, dlmlock.host
252
+ end
253
+ end
254
+
255
+ context '#release' do
256
+ test 'should release empty dlmlock' do
257
+ dlmlock = as_admin { FactoryBot.create(:dlmlock) }
258
+ delete :release, { :id => dlmlock.to_param }
259
+ assert_response :success
260
+ assert_nil as_admin { dlmlock.reload.host }
261
+ end
262
+
263
+ test 'should release own dlmlock' do
264
+ dlmlock = as_admin { FactoryBot.create(:dlmlock, :host => host1) }
265
+ delete :release, { :id => dlmlock.to_param }
266
+ assert_response :success
267
+ assert_nil as_admin { dlmlock.reload.host }
268
+ end
269
+
270
+ test 'should not acquire foreign dlmlock' do
271
+ dlmlock = as_admin { FactoryBot.create(:dlmlock, :host => host2) }
272
+ delete :release, { :id => dlmlock.to_param }
273
+ assert_response :precondition_failed
274
+ assert_equal host2, as_admin { dlmlock.reload.host }
275
+ end
276
+
277
+ test 'should transparently create non-existing dlmlock' do
278
+ lockname = 'Test Lock'
279
+ assert_equal 0, as_admin { Dlmlock.where(:name => lockname).count }
280
+ delete :release, { :id => lockname }
281
+ assert_response :success
282
+ dlmlock = as_admin { Dlmlock.find_by(:name => lockname) }
283
+ assert_equal lockname, dlmlock.name
284
+ assert_nil dlmlock.host
285
+ end
286
+ end
287
+ end
288
+
289
+ context 'without any credentials' do
290
+ setup do
291
+ User.current = nil
292
+ reset_api_credentials
293
+ end
294
+
295
+ context '#index' do
296
+ test 'should deny access' do
297
+ dlmlock = as_admin { FactoryBot.create(:dlmlock) }
298
+ get :index, { :id => dlmlock.to_param }
299
+ assert_response :unauthorized
300
+ end
301
+ end
302
+
303
+ context '#show' do
304
+ test 'should deny access' do
305
+ dlmlock = as_admin { FactoryBot.create(:dlmlock) }
306
+ get :show, { :id => dlmlock.to_param }
307
+ assert_response :unauthorized
308
+ end
309
+ end
310
+
311
+ context '#create' do
312
+ test 'should deny access' do
313
+ dlmlock = as_admin { FactoryBot.create(:dlmlock) }
314
+ post :create, valid_attrs_with_root
315
+ assert_response :unauthorized
316
+ end
317
+ end
318
+
319
+ context '#update' do
320
+ test 'should deny access' do
321
+ dlmlock = as_admin { FactoryBot.create(:dlmlock) }
322
+ put :update, { :id => dlmlock.to_param, :dlmlock => valid_attrs }
323
+ assert_response :unauthorized
324
+ end
325
+ end
326
+
327
+ context '#destroy' do
328
+ test 'should deny access' do
329
+ dlmlock = as_admin { FactoryBot.create(:dlmlock) }
330
+ delete :destroy, { :id => dlmlock.to_param }
331
+ assert_response :unauthorized
332
+ assert_equal 1, as_admin { Dlmlock.where(:id => dlmlock.id).count }
333
+ end
334
+ end
335
+
336
+ context '#acquire' do
337
+ test 'should deny access' do
338
+ dlmlock = as_admin { FactoryBot.create(:dlmlock) }
339
+ put :acquire, { :id => dlmlock.to_param }
340
+ assert_response :unauthorized
341
+ assert_nil as_admin { dlmlock.reload.host }
342
+ end
343
+ end
344
+
345
+ context '#release' do
346
+ test 'should deny access' do
347
+ dlmlock = as_admin { FactoryBot.create(:dlmlock, :host => host2) }
348
+ delete :release, { :id => dlmlock.to_param }
349
+ assert_response :unauthorized
350
+ assert_equal host2, as_admin { dlmlock.reload.host }
351
+ end
352
+ end
353
+ end
354
+
355
+ private
356
+
357
+ def valid_attrs
358
+ {
359
+ 'name' => 'testlock',
360
+ 'type' => 'Dlmlock::Update'
361
+ }
362
+ end
363
+
364
+ def valid_attrs_with_root(extra_attrs = {})
365
+ { :dlmlock => valid_attrs.merge(extra_attrs) }
366
+ end
367
+ end
@@ -0,0 +1,24 @@
1
+ require 'test_plugin_helper'
2
+
3
+ class DlmlocksControllerTest < ActionController::TestCase
4
+ test '#index' do
5
+ FactoryBot.create(:dlmlock)
6
+ get :index, {}, set_session_user
7
+ assert_response :success
8
+ assert_not_nil assigns('dlmlocks')
9
+ assert_template 'index'
10
+ end
11
+
12
+ test '#index with no lock shows welcome page' do
13
+ get :index, {}, set_session_user
14
+ assert_response :success
15
+ assert_template 'welcome'
16
+ end
17
+
18
+ test '#show' do
19
+ dlmlock = FactoryBot.create(:dlmlock)
20
+ get :show, { :id => dlmlock.id }, set_session_user
21
+ assert_response :success
22
+ assert_template 'show'
23
+ end
24
+ end
@@ -0,0 +1,91 @@
1
+ require 'test_plugin_helper'
2
+
3
+ class FindHostByClientCertTest < ActionController::TestCase
4
+ tests "api/v2/dlmlocks"
5
+
6
+ def described_class
7
+ Api::V2::DlmlocksController
8
+ end
9
+
10
+ context 'with ssl settings' do
11
+ setup do
12
+ Setting[:ssl_client_dn_env] = 'SSL_CLIENT_S_DN'
13
+ Setting[:ssl_client_verify_env] = 'SSL_CLIENT_VERIFY'
14
+ end
15
+
16
+ let(:host) { as_admin { FactoryBot.create(:host, :managed) } }
17
+
18
+ context 'with api credentials' do
19
+ test 'certificate with dn permits access' do
20
+ @request.env['HTTPS'] = 'on'
21
+ @request.env['SSL_CLIENT_VERIFY'] = 'NONE'
22
+
23
+ get :index
24
+
25
+ assert @controller.send(:require_client_cert_or_login)
26
+ assert_nil @controller.detected_host
27
+ end
28
+
29
+ test 'certificate with dn permits access' do
30
+ @request.env['HTTPS'] = 'on'
31
+ @request.env['SSL_CLIENT_S_DN'] = "CN=#{host.name},DN=example,DN=com"
32
+ @request.env['SSL_CLIENT_VERIFY'] = 'SUCCESS'
33
+
34
+ get :index
35
+
36
+ assert @controller.send(:require_client_cert_or_login)
37
+ assert_equal host, @controller.detected_host
38
+ end
39
+ end
40
+
41
+ context 'without api credentials' do
42
+ setup do
43
+ User.current = nil
44
+ reset_api_credentials
45
+ end
46
+
47
+ test 'certificate with dn permits access' do
48
+ @request.env['HTTPS'] = 'on'
49
+ @request.env['SSL_CLIENT_S_DN'] = "CN=#{host.name},DN=example,DN=com"
50
+ @request.env['SSL_CLIENT_VERIFY'] = 'SUCCESS'
51
+
52
+ get :index
53
+
54
+ assert @controller.send(:require_client_cert_or_login)
55
+ assert_equal host, @controller.detected_host
56
+ end
57
+
58
+ test 'certificate with unknown dn denies access' do
59
+ @request.env['HTTPS'] = 'on'
60
+ @request.env['SSL_CLIENT_S_DN'] = "CN=doesnotexist.example.com,DN=example,DN=com"
61
+ @request.env['SSL_CLIENT_VERIFY'] = 'SUCCESS'
62
+
63
+ get :index
64
+
65
+ assert_equal false, @controller.send(:require_client_cert_or_login)
66
+ assert_nil @controller.detected_host
67
+ end
68
+
69
+ test 'invalid certificate denies access' do
70
+ @request.env['HTTPS'] = 'on'
71
+ @request.env['SSL_CLIENT_S_DN'] = "CN=#{host.name},DN=example,DN=com"
72
+ @request.env['SSL_CLIENT_VERIFY'] = 'GENEROUS'
73
+
74
+ get :index
75
+
76
+ assert_equal false, @controller.send(:require_client_cert_or_login)
77
+ assert_nil @controller.detected_host
78
+ end
79
+
80
+ test 'no certificate denies access' do
81
+ @request.env['HTTPS'] = 'on'
82
+ @request.env['SSL_CLIENT_VERIFY'] = 'NONE'
83
+
84
+ get :index
85
+
86
+ assert_equal false, @controller.send(:require_client_cert_or_login)
87
+ assert_nil @controller.detected_host
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,6 @@
1
+ FactoryBot.define do
2
+ factory :dlmlock do
3
+ sequence(:name) { |n| "Lock #{n}" }
4
+ type 'Dlmlock::Update'
5
+ end
6
+ end
@@ -0,0 +1,201 @@
1
+ require 'test_plugin_helper'
2
+
3
+ class DlmlockTest < ActiveSupport::TestCase
4
+ setup do
5
+ User.current = users(:admin)
6
+ end
7
+
8
+ subject { FactoryBot.create(:dlmlock) }
9
+ should validate_presence_of(:name)
10
+ should validate_uniqueness_of(:name)
11
+
12
+ let(:host1) { FactoryBot.create(:host, :managed) }
13
+ let(:host2) { FactoryBot.create(:host, :managed) }
14
+
15
+ class HostWithCallbacks < ::Host::Managed
16
+ attr_accessor :callbacks
17
+
18
+ def initialize(*attributes, &block)
19
+ super
20
+ @callbacks = []
21
+ end
22
+
23
+ after_lock :callback1
24
+ after_unlock :callback2
25
+
26
+ def callback1
27
+ Rails.logger.debug "callback1 executed for #{self} (#{self.class})"
28
+ callbacks << 'callback1'
29
+ end
30
+
31
+ def callback2
32
+ Rails.logger.debug "callback2 executed for #{self} (#{self.class})"
33
+ callbacks << 'callback2'
34
+ end
35
+ end
36
+
37
+ let(:host1_with_callbacks) { HostWithCallbacks.create(:name => 'test1.example.com') }
38
+ let(:host2_with_callbacks) { HostWithCallbacks.create(:name => 'test2.example.com') }
39
+
40
+ context 'a free and enabled DLM lock' do
41
+ let(:dlmlock) { FactoryBot.create(:dlmlock) }
42
+
43
+ test 'should be enabled and unlocked' do
44
+ assert_equal true, dlmlock.enabled?
45
+ assert_equal false, dlmlock.disabled?
46
+ assert_equal false, dlmlock.locked?
47
+ assert_equal false, dlmlock.taken?
48
+ end
49
+
50
+ test 'can be acquired' do
51
+ assert_nil dlmlock.host
52
+ assert dlmlock.acquire!(host1)
53
+ assert_equal host1, dlmlock.reload.host
54
+ end
55
+
56
+ test 'can be released' do
57
+ assert_nil dlmlock.host
58
+ assert dlmlock.release!(host1)
59
+ assert_nil dlmlock.reload.host
60
+ end
61
+
62
+ test 'records audit change on acquisition by owner' do
63
+ assert_difference "Audit.where(auditable_type: 'Dlmlock').count" do
64
+ assert dlmlock.acquire!(host1)
65
+ end
66
+ audit_record = dlmlock.audits.last
67
+ assert_equal 'update', audit_record.action
68
+ assert_equal({:host_id => host1.id}, audit_record.audited_changes)
69
+ end
70
+
71
+ test 'records no audit change on release' do
72
+ assert_no_difference "Audit.where(auditable_type: 'Dlmlock').count" do
73
+ assert dlmlock.release!(host1)
74
+ end
75
+ end
76
+
77
+ test 'triggers after_lock callback' do
78
+ host = HostWithCallbacks.new
79
+ host.name = 'test.example.com'
80
+ host.save
81
+ assert dlmlock.acquire!(host)
82
+ assert_equal ['callback1'], host.callbacks
83
+ end
84
+ end
85
+
86
+ context 'a free and disabled DLM lock' do
87
+ let(:dlmlock) { FactoryBot.create(:dlmlock, :enabled => false) }
88
+
89
+ test 'should be disabled and unlocked' do
90
+ assert_equal false, dlmlock.enabled?
91
+ assert_equal true, dlmlock.disabled?
92
+ assert_equal false, dlmlock.locked?
93
+ assert_equal false, dlmlock.taken?
94
+ end
95
+
96
+ test 'can not be acquired' do
97
+ assert_nil dlmlock.host
98
+ assert_equal false, dlmlock.acquire!(host1)
99
+ assert_nil dlmlock.reload.host
100
+ end
101
+
102
+ test 'can not be released' do
103
+ assert_nil dlmlock.host
104
+ assert_equal false, dlmlock.release!(host1)
105
+ assert_nil dlmlock.reload.host
106
+ end
107
+
108
+ test 'triggers no callbacks' do
109
+ host = HostWithCallbacks.new
110
+ host.name = 'test.example.com'
111
+ host.save
112
+ assert_equal false, dlmlock.release!(host)
113
+ assert_equal [], host.callbacks
114
+ end
115
+ end
116
+
117
+ context 'an acquired DLM lock' do
118
+ let(:dlmlock) { FactoryBot.create(:dlmlock, :host => host1) }
119
+
120
+ test 'should be enabled and locked' do
121
+ assert_equal true, dlmlock.enabled?
122
+ assert_equal false, dlmlock.disabled?
123
+ assert_equal true, dlmlock.locked?
124
+ assert_equal true, dlmlock.taken?
125
+ assert_equal true, dlmlock.locked_by?(host1)
126
+ assert_equal true, dlmlock.acquired_by?(host1)
127
+ end
128
+
129
+ test 'can be acquired by owner' do
130
+ assert_equal host1, dlmlock.host
131
+ assert dlmlock.acquire!(host1)
132
+ assert_equal host1, dlmlock.reload.host
133
+ end
134
+
135
+ test 'can not be acquired by other host' do
136
+ assert_equal host1, dlmlock.host
137
+ assert_equal false, dlmlock.acquire!(host2)
138
+ assert_equal host1, dlmlock.reload.host
139
+ end
140
+
141
+ test 'can be released by owner' do
142
+ assert_equal host1, dlmlock.host
143
+ assert dlmlock.release!(host1)
144
+ assert_nil dlmlock.reload.host
145
+ end
146
+
147
+ test 'can not be released by other host' do
148
+ assert_equal host1, dlmlock.host
149
+ assert_equal false, dlmlock.release!(host2)
150
+ assert_equal host1, dlmlock.reload.host
151
+ end
152
+
153
+ test 'records audit change on release by owner' do
154
+ assert_difference "Audit.where(auditable_type: 'Dlmlock').count" do
155
+ assert dlmlock.release!(host1)
156
+ end
157
+ audit_record = dlmlock.audits.last
158
+ assert_equal 'update', audit_record.action
159
+ assert_equal({:host_id => nil}, audit_record.audited_changes)
160
+ end
161
+
162
+ test 'records no audit change on acquisition by owner' do
163
+ assert_no_difference "Audit.where(auditable_type: 'Dlmlock').count" do
164
+ assert dlmlock.acquire!(host1)
165
+ end
166
+ end
167
+
168
+ test 'triggers after_unlock callback on release by owner' do
169
+ host = HostWithCallbacks.new
170
+ host.name = 'test.example.com'
171
+ host.save
172
+ dlmlock.host = host
173
+ dlmlock.save
174
+ assert dlmlock.release!(host)
175
+ assert_equal ['callback2'], host.callbacks
176
+ end
177
+
178
+ test 'triggers no callbacks on release attempt by other host' do
179
+ assert host1_with_callbacks
180
+ assert host2_with_callbacks
181
+ dlmlock.update(:host => host1_with_callbacks)
182
+ assert_equal false, dlmlock.release!(host2_with_callbacks)
183
+ assert_equal [], host1_with_callbacks.callbacks
184
+ assert_equal [], host2_with_callbacks.callbacks
185
+ end
186
+
187
+ test 'triggers no callbacks on acquiry attempt by owner' do
188
+ assert host1_with_callbacks
189
+ dlmlock.update(:host => host1_with_callbacks)
190
+ assert dlmlock.acquire!(host1_with_callbacks)
191
+ assert_equal [], host1_with_callbacks.callbacks
192
+ end
193
+ end
194
+
195
+ context 'scoped search' do
196
+ test 'can be searched by name' do
197
+ dlmlock = FactoryBot.create(:dlmlock)
198
+ assert_equal Dlmlock::Update.find(dlmlock.id), Dlmlock.search_for("name ~ #{dlmlock.name}").first
199
+ end
200
+ end
201
+ end