puppet 6.0.0 → 6.0.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of puppet might be problematic. Click here for more details.

Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +4 -4
  3. data/lib/puppet/application/apply.rb +99 -59
  4. data/lib/puppet/application/cert.rb +2 -112
  5. data/lib/puppet/configurer.rb +2 -3
  6. data/lib/puppet/defaults.rb +14 -1
  7. data/lib/puppet/etc.rb +20 -0
  8. data/lib/puppet/module/task.rb +29 -38
  9. data/lib/puppet/parser/catalog_compiler.rb +24 -0
  10. data/lib/puppet/parser/compiler.rb +3 -1
  11. data/lib/puppet/pops/evaluator/deferred_resolver.rb +3 -0
  12. data/lib/puppet/pops/evaluator/runtime3_converter.rb +2 -2
  13. data/lib/puppet/pops/loader/ruby_legacy_function_instantiator.rb +18 -10
  14. data/lib/puppet/pops/loader/task_instantiator.rb +13 -70
  15. data/lib/puppet/pops/parser/heredoc_support.rb +1 -2
  16. data/lib/puppet/pops/parser/lexer2.rb +1 -1
  17. data/lib/puppet/pops/pcore.rb +10 -33
  18. data/lib/puppet/pops/serialization.rb +1 -0
  19. data/lib/puppet/pops/serialization/to_data_converter.rb +9 -1
  20. data/lib/puppet/provider/exec.rb +57 -57
  21. data/lib/puppet/provider/group/aix.rb +1 -15
  22. data/lib/puppet/provider/group/pw.rb +4 -8
  23. data/lib/puppet/provider/group/windows_adsi.rb +7 -4
  24. data/lib/puppet/provider/nameservice.rb +1 -25
  25. data/lib/puppet/provider/nameservice/directoryservice.rb +5 -3
  26. data/lib/puppet/provider/package/portage.rb +2 -2
  27. data/lib/puppet/provider/service/launchd.rb +19 -3
  28. data/lib/puppet/provider/user/aix.rb +48 -2
  29. data/lib/puppet/type/group.rb +62 -18
  30. data/lib/puppet/type/schedule.rb +7 -0
  31. data/lib/puppet/util/execution.rb +14 -1
  32. data/lib/puppet/util/posix.rb +15 -0
  33. data/lib/puppet/util/storage.rb +12 -0
  34. data/lib/puppet/util/windows/adsi.rb +60 -1
  35. data/lib/puppet/util/windows/process.rb +16 -1
  36. data/lib/puppet/util/windows/service.rb +68 -26
  37. data/lib/puppet/version.rb +1 -1
  38. data/lib/puppet_pal.rb +36 -3
  39. data/locales/ja/puppet.po +598 -861
  40. data/locales/puppet.pot +197 -160
  41. data/man/man5/puppet.conf.5 +12 -1
  42. data/man/man8/puppet.8 +1 -1
  43. data/spec/integration/application/apply_spec.rb +4 -1
  44. data/spec/integration/util/windows/adsi_spec.rb +2 -1
  45. data/spec/unit/application/apply_spec.rb +14 -0
  46. data/spec/unit/configurer_spec.rb +11 -0
  47. data/spec/unit/etc_spec.rb +25 -0
  48. data/spec/unit/indirector/catalog/json_spec.rb +9 -3
  49. data/spec/unit/pops/evaluator/runtime3_converter_spec.rb +22 -4
  50. data/spec/unit/pops/loaders/loader_spec.rb +3 -10
  51. data/spec/unit/pops/loaders/loaders_spec.rb +30 -0
  52. data/spec/unit/pops/loaders/module_loaders_spec.rb +7 -7
  53. data/spec/unit/pops/parser/parse_heredoc_spec.rb +16 -0
  54. data/spec/unit/pops/serialization/to_from_hr_spec.rb +9 -0
  55. data/spec/unit/pops/types/task_spec.rb +42 -116
  56. data/spec/unit/provider/group/aix_spec.rb +0 -19
  57. data/spec/unit/provider/group/pw_spec.rb +0 -6
  58. data/spec/unit/provider/group/windows_adsi_spec.rb +34 -35
  59. data/spec/unit/provider/nameservice/directoryservice_spec.rb +2 -2
  60. data/spec/unit/provider/service/launchd_spec.rb +19 -0
  61. data/spec/unit/provider/user/aix_spec.rb +43 -2
  62. data/spec/unit/provider/user/windows_adsi_spec.rb +1 -4
  63. data/spec/unit/puppet_pal_2pec.rb +6 -6
  64. data/spec/unit/puppet_pal_catalog_spec.rb +58 -0
  65. data/spec/unit/task_spec.rb +50 -5
  66. data/spec/unit/type/group_spec.rb +111 -13
  67. data/spec/unit/util/execution_spec.rb +59 -0
  68. data/spec/unit/util/posix_spec.rb +28 -0
  69. data/spec/unit/util/storage_spec.rb +107 -0
  70. data/spec/unit/util/windows/adsi_spec.rb +100 -5
  71. data/spec/unit/util/windows/service_spec.rb +100 -43
  72. metadata +2 -2
@@ -264,6 +264,101 @@ describe Puppet::Util::Windows::ADSI, :if => Puppet::Util::Platform.windows? do
264
264
  end
265
265
  end
266
266
  end
267
+
268
+ describe 'userflags' do
269
+ # Avoid having to type out the constant everytime we want to
270
+ # retrieve a userflag's value.
271
+ def ads_userflags(flag)
272
+ Puppet::Util::Windows::ADSI::User::ADS_USERFLAGS[flag]
273
+ end
274
+
275
+ before(:each) do
276
+ userflags = [
277
+ :ADS_UF_SCRIPT,
278
+ :ADS_UF_ACCOUNTDISABLE,
279
+ :ADS_UF_HOMEDIR_REQUIRED,
280
+ :ADS_UF_LOCKOUT
281
+ ].inject(0) do |flags, flag|
282
+ flags | ads_userflags(flag)
283
+ end
284
+
285
+ user.stubs(:[]).with('UserFlags').returns(userflags)
286
+ end
287
+
288
+ describe '#userflag_set?' do
289
+ it 'returns true if the specified userflag is set' do
290
+ expect(user.userflag_set?(:ADS_UF_SCRIPT)).to be true
291
+ end
292
+
293
+ it 'returns false if the specified userflag is not set' do
294
+ expect(user.userflag_set?(:ADS_UF_PASSWD_NOTREQD)).to be false
295
+ end
296
+
297
+ it 'returns false if the specified userflag is an unrecognized userflag' do
298
+ expect(user.userflag_set?(:ADS_UF_UNRECOGNIZED_FLAG)).to be false
299
+ end
300
+ end
301
+
302
+ shared_examples 'set/unset common tests' do |method|
303
+ it 'raises an ArgumentError for any unrecognized userflags' do
304
+ unrecognized_flags = [
305
+ :ADS_UF_UNRECOGNIZED_FLAG_ONE,
306
+ :ADS_UF_UNRECOGNIZED_FLAG_TWO
307
+ ]
308
+ input_flags = unrecognized_flags + [
309
+ :ADS_UF_PASSWORD_EXPIRED,
310
+ :ADS_UF_DONT_EXPIRE_PASSWD
311
+ ]
312
+
313
+ expect { user.send(method, *input_flags) }.to raise_error(
314
+ ArgumentError, /#{unrecognized_flags.join(', ')}/
315
+ )
316
+ end
317
+
318
+ it 'noops if no userflags are passed-in' do
319
+ user.expects(:[]=).never
320
+ user.expects(:commit).never
321
+
322
+ user.send(method)
323
+ end
324
+ end
325
+
326
+ describe '#set_userflags' do
327
+ include_examples 'set/unset common tests', :set_userflags
328
+
329
+ it 'should add the passed-in flags to the current set of userflags' do
330
+ input_flags = [
331
+ :ADS_UF_PASSWORD_EXPIRED,
332
+ :ADS_UF_DONT_EXPIRE_PASSWD
333
+ ]
334
+
335
+ userflags = user['UserFlags']
336
+ expected_userflags = userflags | ads_userflags(input_flags[0]) | ads_userflags(input_flags[1])
337
+
338
+ user.expects(:[]=).with('UserFlags', expected_userflags)
339
+
340
+ user.set_userflags(*input_flags)
341
+ end
342
+ end
343
+
344
+ describe '#unset_userflags' do
345
+ include_examples 'set/unset common tests', :unset_userflags
346
+
347
+ it 'should remove the passed-in flags from the current set of userflags' do
348
+ input_flags = [
349
+ :ADS_UF_SCRIPT,
350
+ :ADS_UF_ACCOUNTDISABLE
351
+ ]
352
+
353
+ # ADS_UF_HOMEDIR_REQUIRED and ADS_UF_LOCKOUT should be the only flags set.
354
+ expected_userflags = 0 | ads_userflags(:ADS_UF_HOMEDIR_REQUIRED) | ads_userflags(:ADS_UF_LOCKOUT)
355
+
356
+ user.expects(:[]=).with('UserFlags', expected_userflags)
357
+
358
+ user.unset_userflags(*input_flags)
359
+ end
360
+ end
361
+ end
267
362
  end
268
363
  end
269
364
 
@@ -338,7 +433,7 @@ describe Puppet::Util::Windows::ADSI, :if => Puppet::Util::Platform.windows? do
338
433
  adsi_group.expects(:Remove).with('WinNT://DOMAIN/user1,user')
339
434
  adsi_group.expects(:Add).with('WinNT://DOMAIN2/user3,user')
340
435
 
341
- group.set_members(['user2', 'DOMAIN2\user3'])
436
+ group.set_members('user2,DOMAIN2\user3')
342
437
  end
343
438
 
344
439
  it "should add the desired_members to an existing group when not inclusive" do
@@ -365,7 +460,7 @@ describe Puppet::Util::Windows::ADSI, :if => Puppet::Util::Platform.windows? do
365
460
 
366
461
  adsi_group.expects(:Add).with('WinNT://DOMAIN2/user3,user')
367
462
 
368
- group.set_members(['user2', 'DOMAIN2\user3'],false)
463
+ group.set_members('user2,DOMAIN2\user3',false)
369
464
  end
370
465
 
371
466
  it "should return immediately when desired_members is nil" do
@@ -397,7 +492,7 @@ describe Puppet::Util::Windows::ADSI, :if => Puppet::Util::Platform.windows? do
397
492
  adsi_group.expects(:Remove).with('WinNT://DOMAIN/user1,user')
398
493
  adsi_group.expects(:Remove).with('WinNT://testcomputername/user2,user')
399
494
 
400
- group.set_members([])
495
+ group.set_members('')
401
496
  end
402
497
 
403
498
  it "should do nothing when desired_members is empty and not inclusive" do
@@ -416,13 +511,13 @@ describe Puppet::Util::Windows::ADSI, :if => Puppet::Util::Platform.windows? do
416
511
  adsi_group.expects(:Remove).never
417
512
  adsi_group.expects(:Add).never
418
513
 
419
- group.set_members([],false)
514
+ group.set_members('',false)
420
515
  end
421
516
 
422
517
  it "should raise an error when a username does not resolve to a SID" do
423
518
  expect {
424
519
  adsi_group.expects(:Members).returns []
425
- group.set_members(['foobar'])
520
+ group.set_members('foobar')
426
521
  }.to raise_error(Puppet::Error, /Could not resolve name: foobar/)
427
522
  end
428
523
  end
@@ -52,6 +52,7 @@ describe "Puppet::Util::Windows::Service", :if => Puppet.features.microsoft_wind
52
52
  pointer.stubs(:read_dword)
53
53
  pointer.stubs(:write_dword)
54
54
  pointer.stubs(:size)
55
+ subject.stubs(:sleep)
55
56
  end
56
57
 
57
58
  describe "#start" do
@@ -76,12 +77,13 @@ describe "Puppet::Util::Windows::Service", :if => Puppet.features.microsoft_wind
76
77
  end
77
78
 
78
79
  it "Starts the service once the service reports SERVICE_RUNNING" do
80
+ expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_RUNNING})
79
81
  expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_RUNNING})
80
82
  subject.start(mock_service_name)
81
83
  end
82
84
 
83
- it "Raises an error if after calling StartServiceW the service is not in RUNNING or START_PENDING" do
84
- expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_PAUSED})
85
+ it "Raises an error if after calling StartServiceW the service never transitions to RUNNING or START_PENDING" do
86
+ expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_PAUSED}).times(31)
85
87
  expect{ subject.start(mock_service_name) }.to raise_error(Puppet::Error)
86
88
  end
87
89
 
@@ -93,26 +95,32 @@ describe "Puppet::Util::Windows::Service", :if => Puppet.features.microsoft_wind
93
95
 
94
96
  context "when the service hasn't stopped yet:" do
95
97
  it "waits, then queries again until SERVICE_STOPPED" do
98
+ expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOP_PENDING, :dwWaitHint => 30000, :dwCheckPoint => 1})
96
99
  expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOP_PENDING, :dwWaitHint => 30000, :dwCheckPoint => 1})
97
100
  expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOP_PENDING, :dwWaitHint => 30000, :dwCheckPoint => 50})
98
101
  expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOPPED})
99
102
  expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_RUNNING})
103
+ expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_RUNNING})
100
104
  subject.expects(:sleep).with(3).twice
101
105
  subject.start(mock_service_name)
102
106
  end
103
107
 
104
108
  it "waits for at least 1 second if wait hint/10 is < 1 second" do
109
+ expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOP_PENDING, :dwWaitHint => 30000, :dwCheckPoint => 1})
105
110
  expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOP_PENDING, :dwWaitHint => 0, :dwCheckPoint => 1})
106
111
  expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOPPED})
107
112
  expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_RUNNING})
113
+ expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_RUNNING})
108
114
  subject.expects(:sleep).with(1)
109
115
  subject.start(mock_service_name)
110
116
  end
111
117
 
112
118
  it "waits for at most 10 seconds if wait hint/10 is > 10 seconds" do
119
+ expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOP_PENDING, :dwWaitHint => 30000, :dwCheckPoint => 1})
113
120
  expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOP_PENDING, :dwWaitHint => 1000000, :dwCheckPoint => 1})
114
121
  expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOPPED})
115
122
  expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_RUNNING})
123
+ expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_RUNNING})
116
124
  subject.expects(:sleep).with(10)
117
125
  subject.start(mock_service_name)
118
126
  end
@@ -123,20 +131,8 @@ describe "Puppet::Util::Windows::Service", :if => Puppet.features.microsoft_wind
123
131
  expect{subject.start(mock_service_name)}.to raise_error(Puppet::Error)
124
132
  end
125
133
 
126
- it "raises a puppet error if the services configured dwWaitHint is 0, 30 seconds have passed and dwCheckPoint hasn't increased" do
127
- # the number of times here is a little strange: there are 31 and 32 status queries sleeps because:
128
- expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOP_PENDING, :dwWaitHint => 0, :dwCheckPoint => 0}).times(31)
129
- subject.expects(:sleep).times(30).with(1)
130
- expect{subject.start(mock_service_name)}.to raise_error(Puppet::Error)
131
- end
132
-
133
- it "raises a puppet error if the services configured dwWaitHint has passed and dwCheckPoint hasn't increased" do
134
- expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOP_PENDING, :dwWaitHint => 40000, :dwCheckPoint => 0}).times(11)
135
- subject.expects(:sleep).times(10).with(4)
136
- expect{subject.start(mock_service_name)}.to raise_error(Puppet::Error)
137
- end
138
-
139
134
  it "Does not raise an error if the service makes progress" do
135
+ expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOP_PENDING, :dwWaitHint => 0, :dwCheckPoint => 0})
140
136
  expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOP_PENDING, :dwWaitHint => 0, :dwCheckPoint => 0})
141
137
  expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOP_PENDING, :dwWaitHint => 0, :dwCheckPoint => 2})
142
138
  expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOP_PENDING, :dwWaitHint => 0, :dwCheckPoint => 30})
@@ -144,46 +140,84 @@ describe "Puppet::Util::Windows::Service", :if => Puppet.features.microsoft_wind
144
140
  expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOP_PENDING, :dwWaitHint => 0, :dwCheckPoint => 98})
145
141
  expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOPPED})
146
142
  expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_RUNNING})
147
- subject.expects(:sleep).times(5).with(1)
143
+ expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_RUNNING})
148
144
  expect{subject.start(mock_service_name)}.to_not raise_error
149
145
  end
150
146
  end
151
147
 
148
+ context "when the service ends up still in STOPPED:" do
149
+ it "waits, then queries again until RUNNING" do
150
+ # these will be before the call to controlService
151
+ expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOPPED})
152
+ # everything from here on will be _after_ the call to ControlService
153
+ expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOPPED})
154
+ expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_START_PENDING, :dwWaitHint => 30000, :dwCheckPoint => 1})
155
+ expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_START_PENDING, :dwWaitHint => 30000, :dwCheckPoint => 50})
156
+ expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_RUNNING})
157
+ subject.start(mock_service_name)
158
+ end
159
+
160
+ it "raises a puppet error if the services never exits the RUNNING state" do
161
+ # these will be before the call to controlService
162
+ expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOPPED})
163
+ # the number of times here is a little strange: there are 31 status queries sleeps because there will be a 31st query
164
+ # that is the final query where the command has reached the wait hint and it's time to error
165
+ expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOPPED}).times(31)
166
+ subject.expects(:sleep).times(30).with(1)
167
+ expect{subject.start(mock_service_name)}.to raise_error(Puppet::Error)
168
+ end
169
+ end
170
+
152
171
  context "when the service ends up in START_PENDING:" do
153
- it "waits, then queries again until SERVICE_RUNNING" do
172
+ before(:each) do
173
+ # these will be before the call to StartService
154
174
  expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOPPED})
175
+ end
176
+
177
+ it "waits, then queries again until SERVICE_RUNNING" do
155
178
  expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_START_PENDING, :dwWaitHint => 30000, :dwCheckPoint => 1})
156
179
  expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_START_PENDING, :dwWaitHint => 30000, :dwCheckPoint => 50})
157
180
  expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_RUNNING})
158
- subject.expects(:sleep).with(3).twice
159
181
  subject.start(mock_service_name)
160
182
  end
161
183
 
162
184
  it "waits for at least 1 second if wait hint/10 is < 1 second" do
163
- expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOPPED})
164
- expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_START_PENDING, :dwWaitHint => 0, :dwCheckPoint => 1})
185
+ # the first call is executed in wait_for_state, which we aren't testing here
186
+ expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_START_PENDING})
187
+ expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_START_PENDING, :dwWaitHint => 0, :dwCheckPoint => 2})
165
188
  expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_RUNNING})
166
189
  subject.expects(:sleep).with(1)
167
190
  subject.start(mock_service_name)
168
191
  end
169
192
 
170
193
  it "waits for at most 10 seconds if wait hint/10 is > 10 seconds" do
171
- expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOPPED})
194
+ # the first call is executed in wait_for_state, which we aren't testing here
195
+ expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_START_PENDING})
172
196
  expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_START_PENDING, :dwWaitHint => 1000000, :dwCheckPoint => 1})
173
197
  expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_RUNNING})
174
198
  subject.expects(:sleep).with(10)
175
199
  subject.start(mock_service_name)
176
200
  end
177
201
 
202
+ it "raises a puppet error if the services configured dwWaitHint is 0, 30 seconds have passed and dwCheckPoint hasn't increased" do
203
+ # the first call is executed in wait_for_state, which we aren't testing here
204
+ expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_START_PENDING})
205
+ expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_START_PENDING, :dwWaitHint => 0, :dwCheckPoint => 0}).times(31)
206
+ subject.expects(:sleep).times(30).with(1)
207
+ expect{subject.start(mock_service_name)}.to raise_error(Puppet::Error)
208
+ end
209
+
178
210
  it "raises a puppet error if the service's configured dwWaitHint has passed and dwCheckPoint hasn't increased" do
179
- expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOPPED})
211
+ # the first call is executed in wait_for_state, which we aren't testing here
212
+ expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_START_PENDING})
180
213
  expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_START_PENDING, :dwWaitHint => 40000, :dwCheckPoint => 0}).times(11)
181
214
  subject.expects(:sleep).times(10).with(4)
182
215
  expect{subject.start(mock_service_name)}.to raise_error(Puppet::Error)
183
216
  end
184
217
 
185
218
  it "Does not raise an error if the service makes progress" do
186
- expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOPPED})
219
+ # the first call is executed in wait_for_state, which we aren't testing here
220
+ expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_START_PENDING})
187
221
  expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_START_PENDING, :dwWaitHint => 0, :dwCheckPoint => 0})
188
222
  expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_START_PENDING, :dwWaitHint => 0, :dwCheckPoint => 2})
189
223
  expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_START_PENDING, :dwWaitHint => 0, :dwCheckPoint => 30})
@@ -213,48 +247,71 @@ describe "Puppet::Util::Windows::Service", :if => Puppet.features.microsoft_wind
213
247
 
214
248
  context "when the service can be opened and is in the running state:" do
215
249
  before do
250
+ # this will be before the call to controlService
216
251
  expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_RUNNING})
217
252
  end
218
-
219
- it "Sends the SERVICE_CONTROL_STOP to the service once the service reports SERVICE_RUNNING" do
220
- expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOPPED})
221
- subject.stop(mock_service_name)
222
- end
223
-
224
- it "Raises an error if after calling ControlService the service is not in STOPPED or STOP_PENDING" do
225
- expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_PAUSED})
226
- expect{ subject.stop(mock_service_name) }.to raise_error(Puppet::Error)
227
- end
228
-
229
253
  it "raises a puppet error if ControlService returns false" do
230
254
  subject.expects(:ControlService).returns(FFI::WIN32_FALSE)
231
255
  expect{ subject.stop(mock_service_name) }.to raise_error(Puppet::Error)
232
256
  end
233
257
  end
234
258
 
235
- # No need to retest much of the wait functionality here, since
259
+ # No need to retest the wait hint functionality itself here, since
236
260
  # both stop and start use the wait_for_pending_transition helper
237
261
  # which is tested in the start unit tests.
238
- context "when the service hasn't started yet:" do
239
- it "waits, then queries again until SERVICE_STOPPED" do
240
- expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_START_PENDING, :dwWaitHint => 30000, :dwCheckPoint => 1})
241
- expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_START_PENDING, :dwWaitHint => 30000, :dwCheckPoint => 50})
242
- expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_RUNNING})
262
+ context "when the service is already in stop pending or stopped" do
263
+ it "waits for the service to stop and then exits immediately" do
264
+ expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOP_PENDING, :dwWaitHint => 30000, :dwCheckPoint => 1})
265
+ expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOP_PENDING, :dwWaitHint => 30000, :dwCheckPoint => 5})
243
266
  expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOPPED})
244
- subject.expects(:sleep).with(3).twice
245
267
  subject.stop(mock_service_name)
246
268
  end
247
269
  end
248
270
 
249
271
  context "when the service ends up in STOP_PENDING:" do
250
- it "waits, then queries again until SERVICE_RUNNING" do
272
+ before(:each) do
273
+ # this will be before the call to controlService
251
274
  expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_RUNNING})
275
+ end
276
+
277
+ it "waits, then queries again until SERVICE_STOPPED" do
278
+ # the first call is to wait_for_state, which we don't test here
279
+ expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOP_PENDING})
280
+ # everything from here on will be _after_ the call to ControlService
252
281
  expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOP_PENDING, :dwWaitHint => 30000, :dwCheckPoint => 1})
253
282
  expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOP_PENDING, :dwWaitHint => 30000, :dwCheckPoint => 50})
254
283
  expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOPPED})
255
- subject.expects(:sleep).with(3).twice
256
284
  subject.stop(mock_service_name)
257
285
  end
286
+
287
+ it "raises a puppet error if the services never exits the STOP_PENDING state" do
288
+ # the first call is to wait_for_state, which we don't test here
289
+ expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOP_PENDING})
290
+ expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOP_PENDING, :dwWaitHint => 0, :dwCheckPoint => 0}).times(31)
291
+ expect{subject.stop(mock_service_name)}.to raise_error(Puppet::Error)
292
+ end
293
+ end
294
+
295
+ context "when the service ends up still in RUNNING:" do
296
+ before(:each) do
297
+ # this will be before the call to controlService
298
+ expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_RUNNING})
299
+ end
300
+ it "waits, then queries again until SERVICE_STOPPED" do
301
+ # the first call is to wait_for_state, which we don't test here
302
+ expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_RUNNING, :dwWaitHint => 0, :dwCheckPoint => 0}).times(10)
303
+ expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOP_PENDING, :dwWaitHint => 30000, :dwCheckPoint => 1})
304
+ expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOP_PENDING, :dwWaitHint => 30000, :dwCheckPoint => 50})
305
+ expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_STOPPED})
306
+ subject.stop(mock_service_name)
307
+ end
308
+
309
+ it "raises a puppet error if the services never exits the RUNNING state" do
310
+ # the first call is to wait_for_state, which we don't test here
311
+ expect_successful_status_query_and_return({:dwCurrentState => subject::SERVICE_RUNNING, :dwWaitHint => 0, :dwCheckPoint => 0}).times(31)
312
+ subject.expects(:sleep).times(30).with(1)
313
+ expect{subject.stop(mock_service_name)}.to raise_error(Puppet::Error)
314
+ end
258
315
  end
259
316
  end
260
317
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puppet
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.0.0
4
+ version: 6.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Puppet Labs
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-09-18 00:00:00.000000000 Z
11
+ date: 2018-10-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: facter