win32-service 0.8.10 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,6 @@
1
+ module Win32
2
+ class Service
3
+ VERSION = "1.0.1"
4
+ MAJOR, MINOR, TINY = VERSION.split(".")
5
+ end
6
+ end
@@ -1,58 +1,58 @@
1
- #########################################################################
2
- # test_win32_daemon.rb
3
- #
4
- # Test suite for the Win32::Daemon class. You should run this test via
5
- # the 'rake test' or 'rake test_daemon' tasks.
6
- #
7
- # These tests are rather limited, since the acid test is to install
8
- # your daemon as a service and see how it behaves.
9
- #########################################################################
10
- require 'test-unit'
11
- require 'win32/daemon'
12
- include Win32
13
-
14
- class TC_Daemon < Test::Unit::TestCase
15
- def setup
16
- @daemon = Daemon.new
17
- end
18
-
19
- test "version number is set properly" do
20
- assert_equal('0.8.10', Daemon::VERSION)
21
- end
22
-
23
- test "constructor basic functionality" do
24
- assert_respond_to(Daemon, :new)
25
- assert_nothing_raised{ Daemon.new }
26
- end
27
-
28
- test "constructor does not accept any arguments" do
29
- assert_raises(ArgumentError){ Daemon.new(1) }
30
- end
31
-
32
- test "mainloop basic functionality" do
33
- assert_respond_to(@daemon, :mainloop)
34
- end
35
-
36
- test "state basic functionality" do
37
- assert_respond_to(@daemon, :state)
38
- end
39
-
40
- test "is_running basic functionality" do
41
- assert_respond_to(@daemon, :running?)
42
- end
43
-
44
- test "expected constants are defined" do
45
- assert_not_nil(Daemon::CONTINUE_PENDING)
46
- assert_not_nil(Daemon::PAUSE_PENDING)
47
- assert_not_nil(Daemon::PAUSED)
48
- assert_not_nil(Daemon::RUNNING)
49
- assert_not_nil(Daemon::START_PENDING)
50
- assert_not_nil(Daemon::STOP_PENDING)
51
- assert_not_nil(Daemon::STOPPED)
52
- assert_not_nil(Daemon::IDLE)
53
- end
54
-
55
- def teardown
56
- @daemon = nil
57
- end
58
- end
1
+ #########################################################################
2
+ # test_win32_daemon.rb
3
+ #
4
+ # Test suite for the Win32::Daemon class. You should run this test via
5
+ # the 'rake test' or 'rake test_daemon' tasks.
6
+ #
7
+ # These tests are rather limited, since the acid test is to install
8
+ # your daemon as a service and see how it behaves.
9
+ #########################################################################
10
+ require 'test-unit'
11
+ require 'win32/daemon'
12
+ include Win32
13
+
14
+ class TC_Daemon < Test::Unit::TestCase
15
+ def setup
16
+ @daemon = Daemon.new
17
+ end
18
+
19
+ test "version number is set properly" do
20
+ assert_equal('0.8.10', Daemon::VERSION)
21
+ end
22
+
23
+ test "constructor basic functionality" do
24
+ assert_respond_to(Daemon, :new)
25
+ assert_nothing_raised{ Daemon.new }
26
+ end
27
+
28
+ test "constructor does not accept any arguments" do
29
+ assert_raises(ArgumentError){ Daemon.new(1) }
30
+ end
31
+
32
+ test "mainloop basic functionality" do
33
+ assert_respond_to(@daemon, :mainloop)
34
+ end
35
+
36
+ test "state basic functionality" do
37
+ assert_respond_to(@daemon, :state)
38
+ end
39
+
40
+ test "is_running basic functionality" do
41
+ assert_respond_to(@daemon, :running?)
42
+ end
43
+
44
+ test "expected constants are defined" do
45
+ assert_not_nil(Daemon::CONTINUE_PENDING)
46
+ assert_not_nil(Daemon::PAUSE_PENDING)
47
+ assert_not_nil(Daemon::PAUSED)
48
+ assert_not_nil(Daemon::RUNNING)
49
+ assert_not_nil(Daemon::START_PENDING)
50
+ assert_not_nil(Daemon::STOP_PENDING)
51
+ assert_not_nil(Daemon::STOPPED)
52
+ assert_not_nil(Daemon::IDLE)
53
+ end
54
+
55
+ def teardown
56
+ @daemon = nil
57
+ end
58
+ end
@@ -1,468 +1,468 @@
1
- ##########################################################################
2
- # test_win32_service.rb
3
- #
4
- # Tests for the Win32::Service class. Some tests are skipped unless
5
- # run with admin privileges either because they are somewhat invasive,
6
- # or because they take too long.
7
- ##########################################################################
8
- require 'test-unit'
9
- require 'win32/security'
10
- require 'win32/service'
11
- require 'socket'
12
-
13
- class TC_Win32_Service < Test::Unit::TestCase
14
- def self.startup
15
- @@host = Socket.gethostname
16
- @@service_name = 'stisvc'
17
- @@elevated = Win32::Security.elevated_security?
18
- end
19
-
20
- def setup
21
- @display_name = 'Windows Image Acquisition (WIA)'
22
- @service_name = 'stisvc'
23
- @service_stat = nil
24
- @services = []
25
- @elevated = Win32::Security.elevated_security?
26
-
27
- @singleton_methods = Win32::Service.methods.map{ |m| m.to_s }
28
- @instance_methods = Win32::Service.instance_methods.map{ |m| m.to_s }
29
- end
30
-
31
- def omit_unless_elevated
32
- omit_unless(@elevated, "Skipped unless run with admin privileges")
33
- end
34
-
35
- def start_service(service)
36
- status = Win32::Service.status(@service_name).current_state
37
-
38
- if @elevated
39
- if status == 'paused'
40
- Win32::Service.resume(service)
41
- else
42
- unless ['running', 'start pending'].include?(status)
43
- Win32::Service.start(service)
44
- end
45
- end
46
- wait_for_status('running')
47
- end
48
- end
49
-
50
- def stop_service(service)
51
- status = Win32::Service.status(@service_name).current_state
52
- if @elevated
53
- unless ['stopped', 'stop pending'].include?(status)
54
- Win32::Service.stop(service)
55
- end
56
- wait_for_status('stopped')
57
- end
58
- end
59
-
60
- # Helper method that waits for a status to change its state since state
61
- # changes aren't usually instantaneous.
62
- def wait_for_status(status)
63
- sleep 0.1 while Win32::Service.status(@service_name).current_state != status
64
- end
65
-
66
- test "version number is expected value" do
67
- assert_equal('0.8.10', Win32::Service::VERSION)
68
- end
69
-
70
- test "services basic functionality" do
71
- assert_respond_to(Win32::Service, :services)
72
- end
73
-
74
- test "services with no arguments works as expected" do
75
- assert_nothing_raised{ Win32::Service.services }
76
- end
77
-
78
- test "services with explicit host works as expected" do
79
- assert_nothing_raised{ Win32::Service.services(@@host) }
80
- end
81
-
82
- test "services with explicit host and group works as expected" do
83
- assert_nothing_raised{ Win32::Service.services(@@host, 'network') }
84
- end
85
-
86
- test "services method returns an array without a block" do
87
- assert_nothing_raised{ @services = Win32::Service.services }
88
- assert_kind_of(Array, @services)
89
- assert_kind_of(Struct::ServiceInfo, @services[0])
90
- end
91
-
92
- test "services method yields service objects when a block is provided" do
93
- assert_nothing_raised{ Win32::Service.services{ |s| @services << s } }
94
- assert_kind_of(Array, @services)
95
- assert_kind_of(Struct::ServiceInfo, @services[0])
96
- end
97
-
98
- test "the host argument must be a string or an error is raised" do
99
- assert_raise(TypeError){ Win32::Service.services(1) }
100
- end
101
-
102
- test "the group argument must be a string or an error is raised" do
103
- assert_raise(TypeError){ Win32::Service.services(nil, 1) }
104
- end
105
-
106
- test "the services method only accepts 2 arguments" do
107
- assert_raise(ArgumentError){ Win32::Service.services(nil, 'network', 1) }
108
- end
109
-
110
- test "a valid hostname must be provided or an error is raised" do
111
- omit_unless_elevated
112
- assert_raise(SystemCallError){ Win32::Service.services('bogus') }
113
- end
114
-
115
- test "delete method basic functionality" do
116
- assert_respond_to(Win32::Service, :delete)
117
- end
118
-
119
- test "a service name must be provided to the delete method" do
120
- assert_raise(ArgumentError){ Win32::Service.delete }
121
- end
122
-
123
- test "delete method raises an error if a bogus service name is provided" do
124
- omit_unless_elevated
125
- assert_raise(SystemCallError){ Win32::Service.delete('bogus') }
126
- end
127
-
128
- test "delete method raises an error if a bogus host name is provided" do
129
- omit_unless_elevated
130
- assert_raise(SystemCallError){ Win32::Service.delete('bogus', 'bogus') }
131
- end
132
-
133
- test "delete method only accepts up to two arguments" do
134
- assert_raise(ArgumentError){ Win32::Service.delete('x', 'y', 'z') }
135
- end
136
-
137
- test "pause basic functionality" do
138
- assert_respond_to(Win32::Service, :pause)
139
- end
140
-
141
- test "resume basic functionality" do
142
- assert_respond_to(Win32::Service, :resume)
143
- end
144
-
145
- test "pause and resume work as expected" do
146
- omit_unless_elevated
147
- start_service(@service_name)
148
-
149
- assert_nothing_raised{ Win32::Service.pause(@service_name) }
150
- wait_for_status('paused')
151
-
152
- assert_nothing_raised{ Win32::Service.resume(@service_name) }
153
- wait_for_status('running')
154
- end
155
-
156
- test "pausing an already paused service is harmless" do
157
- omit_unless_elevated
158
- start_service(@service_name)
159
-
160
- assert_nothing_raised{ Win32::Service.pause(@service_name) }
161
- wait_for_status('paused')
162
- assert_nothing_raised{ Win32::Service.pause(@service_name) }
163
- end
164
-
165
- test "pause requires a service name as an argument" do
166
- assert_raise(ArgumentError){ Win32::Service.pause }
167
- end
168
-
169
- test "pausing an unrecognized service name raises an error" do
170
- assert_raise(SystemCallError){ Win32::Service.pause('bogus') }
171
- end
172
-
173
- test "pausing a service on an unrecognized host raises an error" do
174
- omit_unless_elevated
175
- assert_raise(SystemCallError){ Win32::Service.pause('W32Time', 'bogus') }
176
- end
177
-
178
- test "pause method accepts a maximum of two arguments" do
179
- assert_raise(ArgumentError){ Win32::Service.pause('x', 'y', 'z') }
180
- end
181
-
182
- test "resume method requires a service name" do
183
- assert_raise(ArgumentError){ Win32::Service.resume }
184
- end
185
-
186
- test "resume method with an unrecognized service name raises an error" do
187
- assert_raise(SystemCallError){ Win32::Service.resume('bogus') }
188
- end
189
-
190
- test "resume method with an unrecognized host name raises an error" do
191
- omit_unless_elevated
192
- assert_raise(SystemCallError){ Win32::Service.resume('W32Time', 'bogus') }
193
- end
194
-
195
- test "resume method accepts a maximum of two arguments" do
196
- assert_raise(ArgumentError){ Win32::Service.resume('W32Time', @@host, true) }
197
- end
198
-
199
- test "stop method basic functionality" do
200
- assert_respond_to(Win32::Service, :stop)
201
- end
202
-
203
- test "start method basic functionality" do
204
- assert_respond_to(Win32::Service, :start)
205
- end
206
-
207
- test "stop and start methods work as expected" do
208
- omit_unless_elevated
209
- start_service(@service_name)
210
-
211
- assert_nothing_raised{ Win32::Service.stop(@service_name) }
212
- wait_for_status('stopped')
213
-
214
- assert_nothing_raised{ Win32::Service.start(@service_name) }
215
- wait_for_status('running')
216
- end
217
-
218
- test "attempting to stop a stopped service raises an error" do
219
- omit_unless_elevated
220
- start_service(@service_name)
221
-
222
- assert_nothing_raised{ Win32::Service.stop(@service_name) }
223
- wait_for_status('stopped')
224
- assert_raise(SystemCallError){ Win32::Service.stop(@service_name) }
225
-
226
- assert_nothing_raised{ Win32::Service.start(@service_name) }
227
- end
228
-
229
- test "stop method requires a service name" do
230
- assert_raise(ArgumentError){ Win32::Service.stop }
231
- end
232
-
233
- test "stop method raises an error if the service name is unrecognized" do
234
- assert_raise(SystemCallError){ Win32::Service.stop('bogus') }
235
- end
236
-
237
- test "stop method raises an error if the host is unrecognized" do
238
- omit_unless_elevated
239
- assert_raise(SystemCallError){ Win32::Service.stop('W32Time', 'bogus') }
240
- end
241
-
242
- test "stop metho accepts a maximum of two arguments" do
243
- assert_raise(ArgumentError){ Win32::Service.stop('W32Time', @@host, true) }
244
- end
245
-
246
- test "start method requires a service name" do
247
- assert_raise(ArgumentError){ Win32::Service.start }
248
- end
249
-
250
- test "attempting to start a running service raises an error" do
251
- omit_unless_elevated
252
- start_service(@service_name)
253
- assert_raise(SystemCallError){ Win32::Service.start(@service_name) }
254
- end
255
-
256
- test "attempting to start an unrecognized service raises an error" do
257
- assert_raise(SystemCallError){ Win32::Service.start('bogus') }
258
- end
259
-
260
- test "attempting to start a service on an unknown host raises an error" do
261
- omit_unless_elevated
262
- assert_raise(SystemCallError){ Win32::Service.start('bogus', 'bogus') }
263
- end
264
-
265
- test "stop requires at least one argument" do
266
- assert_raise(ArgumentError){ Win32::Service.stop }
267
- end
268
-
269
- test "stop raises an error with an unrecognized service name" do
270
- assert_raise(SystemCallError){ Win32::Service.stop('bogus') }
271
- end
272
-
273
- test "stop raises an error with an unrecognized host" do
274
- omit_unless_elevated
275
- assert_raise(SystemCallError){ Win32::Service.stop('W32Time', 'bogus') }
276
- end
277
-
278
- test "stop accepts a maximum of 2 arguments" do
279
- assert_raise(ArgumentError){ Win32::Service.stop('a', 'b', 'c') }
280
- end
281
-
282
- test "status basic functionality" do
283
- assert_respond_to(Win32::Service, :status)
284
- assert_nothing_raised{ Win32::Service.status(@service_name) }
285
- assert_kind_of(Struct::ServiceStatus, Win32::Service.status(@service_name))
286
- end
287
-
288
- test "get_service_name basic functionality" do
289
- assert_respond_to(Win32::Service, :get_service_name)
290
- assert_nothing_raised{ Win32::Service.get_service_name(@display_name) }
291
- assert_kind_of(String, Win32::Service.get_service_name(@display_name))
292
- end
293
-
294
- test "get_service_name returns expected results" do
295
- assert_equal(@service_name, Win32::Service.get_service_name(@display_name))
296
- end
297
-
298
- test "getservicename is an alias for get_service_name" do
299
- assert_respond_to(Win32::Service, :getservicename)
300
- assert_alias_method(Win32::Service, :getservicename, :get_service_name)
301
- end
302
-
303
- test "get_service_name requires at least one argument" do
304
- assert_raise(ArgumentError){ Win32::Service.get_service_name }
305
- end
306
-
307
- test "get_service_name raises an error if a bogus service name is provided" do
308
- assert_raise(SystemCallError){ Win32::Service.get_service_name('bogus') }
309
- end
310
-
311
- test "get_service_name raises an error if a bogus host is provided" do
312
- omit_unless_elevated
313
- assert_raise(SystemCallError){ Win32::Service.get_service_name('foo', 'bogus') }
314
- end
315
-
316
- test "get_service_name accepts a maximum of two arguments" do
317
- assert_raise(ArgumentError){ Win32::Service.get_service_name('x', 'y', 'z') }
318
- end
319
-
320
- test "get_display_name basic functionality" do
321
- assert_respond_to(Win32::Service, :get_display_name)
322
- assert_nothing_raised{ Win32::Service.get_display_name(@service_name) }
323
- assert_kind_of(String, Win32::Service.get_display_name(@service_name))
324
- end
325
-
326
- test "get_display_name returns expected results" do
327
- assert_equal(@display_name, Win32::Service.get_display_name(@service_name))
328
- end
329
-
330
- test "getdisplayname is an alias for get_display_name" do
331
- assert_respond_to(Win32::Service, :getdisplayname)
332
- assert_alias_method(Win32::Service, :getdisplayname, :get_display_name)
333
- end
334
-
335
- test "get_display_name requires at least one argument" do
336
- assert_raise(ArgumentError){ Win32::Service.get_display_name }
337
- end
338
-
339
- test "get_display_name raises an error if the service does not exist" do
340
- assert_raise(SystemCallError){ Win32::Service.get_display_name('bogus') }
341
- end
342
-
343
- test "get_display_name raises an error if a bad host name is provided" do
344
- omit_unless_elevated
345
- assert_raise(SystemCallError){ Win32::Service.get_display_name('W32Time', 'bogus') }
346
- end
347
-
348
- test "get_display_name takes a maximum of two arguments" do
349
- assert_raise(ArgumentError){ Win32::Service.get_display_name('x', 'y', 'z') }
350
- end
351
-
352
- test "exists method basic functionality" do
353
- assert_respond_to(Win32::Service, :exists?)
354
- assert_boolean(Win32::Service.exists?('W32Time'))
355
- assert_nothing_raised{ Win32::Service.exists?('W32Time') }
356
- end
357
-
358
- test "exists method returns expected results" do
359
- assert_true(Win32::Service.exists?('W32Time'))
360
- assert_false(Win32::Service.exists?('foobar'))
361
- end
362
-
363
- test "exists method requires at least one argument or an error is raised" do
364
- assert_raises(ArgumentError){ Win32::Service.exists? }
365
- end
366
-
367
- test "exists method raises an error if a bogus host is passed" do
368
- omit_unless_elevated
369
- assert_raises(SystemCallError){ Win32::Service.exists?('foo', 'bogus') }
370
- end
371
-
372
- test "exists method only accepts up to two arguments" do
373
- assert_raises(ArgumentError){
374
- Win32::Service.exists?('foo', 'bar', 'baz')
375
- }
376
- end
377
-
378
- test "scm security constants are defined" do
379
- assert_not_nil(Win32::Service::MANAGER_ALL_ACCESS)
380
- assert_not_nil(Win32::Service::MANAGER_CREATE_SERVICE)
381
- assert_not_nil(Win32::Service::MANAGER_CONNECT)
382
- assert_not_nil(Win32::Service::MANAGER_ENUMERATE_SERVICE)
383
- assert_not_nil(Win32::Service::MANAGER_LOCK)
384
- assert_not_nil(Win32::Service::MANAGER_QUERY_LOCK_STATUS)
385
- end
386
-
387
- test "service specific constants are defined" do
388
- assert_not_nil(Win32::Service::ALL_ACCESS)
389
- assert_not_nil(Win32::Service::CHANGE_CONFIG)
390
- assert_not_nil(Win32::Service::ENUMERATE_DEPENDENTS)
391
- assert_not_nil(Win32::Service::INTERROGATE)
392
- assert_not_nil(Win32::Service::PAUSE_CONTINUE)
393
- assert_not_nil(Win32::Service::QUERY_CONFIG)
394
- assert_not_nil(Win32::Service::QUERY_STATUS)
395
- assert_not_nil(Win32::Service::STOP)
396
- assert_not_nil(Win32::Service::START)
397
- assert_not_nil(Win32::Service::USER_DEFINED_CONTROL)
398
- end
399
-
400
- test "service type constants are defined" do
401
- assert_not_nil(Win32::Service::FILE_SYSTEM_DRIVER)
402
- assert_not_nil(Win32::Service::KERNEL_DRIVER)
403
- assert_not_nil(Win32::Service::WIN32_OWN_PROCESS)
404
- assert_not_nil(Win32::Service::WIN32_SHARE_PROCESS)
405
- assert_not_nil(Win32::Service::INTERACTIVE_PROCESS)
406
- end
407
-
408
- test "service start option constants are defined" do
409
- assert_not_nil(Win32::Service::AUTO_START)
410
- assert_not_nil(Win32::Service::BOOT_START)
411
- assert_not_nil(Win32::Service::DEMAND_START)
412
- assert_not_nil(Win32::Service::DISABLED)
413
- assert_not_nil(Win32::Service::SYSTEM_START)
414
- end
415
-
416
- test "service error control constants are defined" do
417
- assert_not_nil(Win32::Service::ERROR_IGNORE)
418
- assert_not_nil(Win32::Service::ERROR_NORMAL)
419
- assert_not_nil(Win32::Service::ERROR_SEVERE)
420
- assert_not_nil(Win32::Service::ERROR_CRITICAL)
421
- end
422
-
423
- test "service state constants are defined" do
424
- assert_not_nil(Win32::Service::CONTINUE_PENDING)
425
- assert_not_nil(Win32::Service::PAUSE_PENDING)
426
- assert_not_nil(Win32::Service::PAUSED)
427
- assert_not_nil(Win32::Service::RUNNING)
428
- assert_not_nil(Win32::Service::START_PENDING)
429
- assert_not_nil(Win32::Service::STOP_PENDING)
430
- assert_not_nil(Win32::Service::STOPPED)
431
- end
432
-
433
- test "internal ffi functions are not public as singleton methods" do
434
- assert_false(@singleton_methods.include?('CloseHandle'))
435
- assert_false(@singleton_methods.include?('ControlService'))
436
- assert_false(@singleton_methods.include?('DeleteService'))
437
- end
438
-
439
- test "internal ffi functions are not public as instance methods" do
440
- assert_false(@instance_methods.include?('CloseHandle'))
441
- assert_false(@instance_methods.include?('ControlService'))
442
- assert_false(@instance_methods.include?('DeleteService'))
443
- end
444
-
445
- def teardown
446
- @display_name = nil
447
- @service_name = nil
448
- @service_stat = nil
449
- @services = nil
450
- end
451
-
452
- def self.shutdown
453
- @@host = nil
454
- status = Win32::Service.status(@@service_name).current_state
455
-
456
- if @elevated
457
- if status == 'paused'
458
- Win32::Service.resume(@@service_name)
459
- end
460
-
461
- unless ['running', 'start pending'].include?(status)
462
- Win32::Service.start(@@service_name)
463
- end
464
- end
465
-
466
- @@elevated = nil
467
- end
468
- end
1
+ ##########################################################################
2
+ # test_win32_service.rb
3
+ #
4
+ # Tests for the Win32::Service class. Some tests are skipped unless
5
+ # run with admin privileges either because they are somewhat invasive,
6
+ # or because they take too long.
7
+ ##########################################################################
8
+ require 'test-unit'
9
+ require 'win32/security'
10
+ require 'win32/service'
11
+ require 'socket'
12
+
13
+ class TC_Win32_Service < Test::Unit::TestCase
14
+ def self.startup
15
+ @@host = Socket.gethostname
16
+ @@service_name = 'stisvc'
17
+ @@elevated = Win32::Security.elevated_security?
18
+ end
19
+
20
+ def setup
21
+ @display_name = 'Windows Image Acquisition (WIA)'
22
+ @service_name = 'stisvc'
23
+ @service_stat = nil
24
+ @services = []
25
+ @elevated = Win32::Security.elevated_security?
26
+
27
+ @singleton_methods = Win32::Service.methods.map{ |m| m.to_s }
28
+ @instance_methods = Win32::Service.instance_methods.map{ |m| m.to_s }
29
+ end
30
+
31
+ def omit_unless_elevated
32
+ omit_unless(@elevated, "Skipped unless run with admin privileges")
33
+ end
34
+
35
+ def start_service(service)
36
+ status = Win32::Service.status(@service_name).current_state
37
+
38
+ if @elevated
39
+ if status == 'paused'
40
+ Win32::Service.resume(service)
41
+ else
42
+ unless ['running', 'start pending'].include?(status)
43
+ Win32::Service.start(service)
44
+ end
45
+ end
46
+ wait_for_status('running')
47
+ end
48
+ end
49
+
50
+ def stop_service(service)
51
+ status = Win32::Service.status(@service_name).current_state
52
+ if @elevated
53
+ unless ['stopped', 'stop pending'].include?(status)
54
+ Win32::Service.stop(service)
55
+ end
56
+ wait_for_status('stopped')
57
+ end
58
+ end
59
+
60
+ # Helper method that waits for a status to change its state since state
61
+ # changes aren't usually instantaneous.
62
+ def wait_for_status(status)
63
+ sleep 0.1 while Win32::Service.status(@service_name).current_state != status
64
+ end
65
+
66
+ test "version number is expected value" do
67
+ assert_equal('0.8.10', Win32::Service::VERSION)
68
+ end
69
+
70
+ test "services basic functionality" do
71
+ assert_respond_to(Win32::Service, :services)
72
+ end
73
+
74
+ test "services with no arguments works as expected" do
75
+ assert_nothing_raised{ Win32::Service.services }
76
+ end
77
+
78
+ test "services with explicit host works as expected" do
79
+ assert_nothing_raised{ Win32::Service.services(@@host) }
80
+ end
81
+
82
+ test "services with explicit host and group works as expected" do
83
+ assert_nothing_raised{ Win32::Service.services(@@host, 'network') }
84
+ end
85
+
86
+ test "services method returns an array without a block" do
87
+ assert_nothing_raised{ @services = Win32::Service.services }
88
+ assert_kind_of(Array, @services)
89
+ assert_kind_of(Struct::ServiceInfo, @services[0])
90
+ end
91
+
92
+ test "services method yields service objects when a block is provided" do
93
+ assert_nothing_raised{ Win32::Service.services{ |s| @services << s } }
94
+ assert_kind_of(Array, @services)
95
+ assert_kind_of(Struct::ServiceInfo, @services[0])
96
+ end
97
+
98
+ test "the host argument must be a string or an error is raised" do
99
+ assert_raise(TypeError){ Win32::Service.services(1) }
100
+ end
101
+
102
+ test "the group argument must be a string or an error is raised" do
103
+ assert_raise(TypeError){ Win32::Service.services(nil, 1) }
104
+ end
105
+
106
+ test "the services method only accepts 2 arguments" do
107
+ assert_raise(ArgumentError){ Win32::Service.services(nil, 'network', 1) }
108
+ end
109
+
110
+ test "a valid hostname must be provided or an error is raised" do
111
+ omit_unless_elevated
112
+ assert_raise(SystemCallError){ Win32::Service.services('bogus') }
113
+ end
114
+
115
+ test "delete method basic functionality" do
116
+ assert_respond_to(Win32::Service, :delete)
117
+ end
118
+
119
+ test "a service name must be provided to the delete method" do
120
+ assert_raise(ArgumentError){ Win32::Service.delete }
121
+ end
122
+
123
+ test "delete method raises an error if a bogus service name is provided" do
124
+ omit_unless_elevated
125
+ assert_raise(SystemCallError){ Win32::Service.delete('bogus') }
126
+ end
127
+
128
+ test "delete method raises an error if a bogus host name is provided" do
129
+ omit_unless_elevated
130
+ assert_raise(SystemCallError){ Win32::Service.delete('bogus', 'bogus') }
131
+ end
132
+
133
+ test "delete method only accepts up to two arguments" do
134
+ assert_raise(ArgumentError){ Win32::Service.delete('x', 'y', 'z') }
135
+ end
136
+
137
+ test "pause basic functionality" do
138
+ assert_respond_to(Win32::Service, :pause)
139
+ end
140
+
141
+ test "resume basic functionality" do
142
+ assert_respond_to(Win32::Service, :resume)
143
+ end
144
+
145
+ test "pause and resume work as expected" do
146
+ omit_unless_elevated
147
+ start_service(@service_name)
148
+
149
+ assert_nothing_raised{ Win32::Service.pause(@service_name) }
150
+ wait_for_status('paused')
151
+
152
+ assert_nothing_raised{ Win32::Service.resume(@service_name) }
153
+ wait_for_status('running')
154
+ end
155
+
156
+ test "pausing an already paused service is harmless" do
157
+ omit_unless_elevated
158
+ start_service(@service_name)
159
+
160
+ assert_nothing_raised{ Win32::Service.pause(@service_name) }
161
+ wait_for_status('paused')
162
+ assert_nothing_raised{ Win32::Service.pause(@service_name) }
163
+ end
164
+
165
+ test "pause requires a service name as an argument" do
166
+ assert_raise(ArgumentError){ Win32::Service.pause }
167
+ end
168
+
169
+ test "pausing an unrecognized service name raises an error" do
170
+ assert_raise(SystemCallError){ Win32::Service.pause('bogus') }
171
+ end
172
+
173
+ test "pausing a service on an unrecognized host raises an error" do
174
+ omit_unless_elevated
175
+ assert_raise(SystemCallError){ Win32::Service.pause('W32Time', 'bogus') }
176
+ end
177
+
178
+ test "pause method accepts a maximum of two arguments" do
179
+ assert_raise(ArgumentError){ Win32::Service.pause('x', 'y', 'z') }
180
+ end
181
+
182
+ test "resume method requires a service name" do
183
+ assert_raise(ArgumentError){ Win32::Service.resume }
184
+ end
185
+
186
+ test "resume method with an unrecognized service name raises an error" do
187
+ assert_raise(SystemCallError){ Win32::Service.resume('bogus') }
188
+ end
189
+
190
+ test "resume method with an unrecognized host name raises an error" do
191
+ omit_unless_elevated
192
+ assert_raise(SystemCallError){ Win32::Service.resume('W32Time', 'bogus') }
193
+ end
194
+
195
+ test "resume method accepts a maximum of two arguments" do
196
+ assert_raise(ArgumentError){ Win32::Service.resume('W32Time', @@host, true) }
197
+ end
198
+
199
+ test "stop method basic functionality" do
200
+ assert_respond_to(Win32::Service, :stop)
201
+ end
202
+
203
+ test "start method basic functionality" do
204
+ assert_respond_to(Win32::Service, :start)
205
+ end
206
+
207
+ test "stop and start methods work as expected" do
208
+ omit_unless_elevated
209
+ start_service(@service_name)
210
+
211
+ assert_nothing_raised{ Win32::Service.stop(@service_name) }
212
+ wait_for_status('stopped')
213
+
214
+ assert_nothing_raised{ Win32::Service.start(@service_name) }
215
+ wait_for_status('running')
216
+ end
217
+
218
+ test "attempting to stop a stopped service raises an error" do
219
+ omit_unless_elevated
220
+ start_service(@service_name)
221
+
222
+ assert_nothing_raised{ Win32::Service.stop(@service_name) }
223
+ wait_for_status('stopped')
224
+ assert_raise(SystemCallError){ Win32::Service.stop(@service_name) }
225
+
226
+ assert_nothing_raised{ Win32::Service.start(@service_name) }
227
+ end
228
+
229
+ test "stop method requires a service name" do
230
+ assert_raise(ArgumentError){ Win32::Service.stop }
231
+ end
232
+
233
+ test "stop method raises an error if the service name is unrecognized" do
234
+ assert_raise(SystemCallError){ Win32::Service.stop('bogus') }
235
+ end
236
+
237
+ test "stop method raises an error if the host is unrecognized" do
238
+ omit_unless_elevated
239
+ assert_raise(SystemCallError){ Win32::Service.stop('W32Time', 'bogus') }
240
+ end
241
+
242
+ test "stop metho accepts a maximum of two arguments" do
243
+ assert_raise(ArgumentError){ Win32::Service.stop('W32Time', @@host, true) }
244
+ end
245
+
246
+ test "start method requires a service name" do
247
+ assert_raise(ArgumentError){ Win32::Service.start }
248
+ end
249
+
250
+ test "attempting to start a running service raises an error" do
251
+ omit_unless_elevated
252
+ start_service(@service_name)
253
+ assert_raise(SystemCallError){ Win32::Service.start(@service_name) }
254
+ end
255
+
256
+ test "attempting to start an unrecognized service raises an error" do
257
+ assert_raise(SystemCallError){ Win32::Service.start('bogus') }
258
+ end
259
+
260
+ test "attempting to start a service on an unknown host raises an error" do
261
+ omit_unless_elevated
262
+ assert_raise(SystemCallError){ Win32::Service.start('bogus', 'bogus') }
263
+ end
264
+
265
+ test "stop requires at least one argument" do
266
+ assert_raise(ArgumentError){ Win32::Service.stop }
267
+ end
268
+
269
+ test "stop raises an error with an unrecognized service name" do
270
+ assert_raise(SystemCallError){ Win32::Service.stop('bogus') }
271
+ end
272
+
273
+ test "stop raises an error with an unrecognized host" do
274
+ omit_unless_elevated
275
+ assert_raise(SystemCallError){ Win32::Service.stop('W32Time', 'bogus') }
276
+ end
277
+
278
+ test "stop accepts a maximum of 2 arguments" do
279
+ assert_raise(ArgumentError){ Win32::Service.stop('a', 'b', 'c') }
280
+ end
281
+
282
+ test "status basic functionality" do
283
+ assert_respond_to(Win32::Service, :status)
284
+ assert_nothing_raised{ Win32::Service.status(@service_name) }
285
+ assert_kind_of(Struct::ServiceStatus, Win32::Service.status(@service_name))
286
+ end
287
+
288
+ test "get_service_name basic functionality" do
289
+ assert_respond_to(Win32::Service, :get_service_name)
290
+ assert_nothing_raised{ Win32::Service.get_service_name(@display_name) }
291
+ assert_kind_of(String, Win32::Service.get_service_name(@display_name))
292
+ end
293
+
294
+ test "get_service_name returns expected results" do
295
+ assert_equal(@service_name, Win32::Service.get_service_name(@display_name))
296
+ end
297
+
298
+ test "getservicename is an alias for get_service_name" do
299
+ assert_respond_to(Win32::Service, :getservicename)
300
+ assert_alias_method(Win32::Service, :getservicename, :get_service_name)
301
+ end
302
+
303
+ test "get_service_name requires at least one argument" do
304
+ assert_raise(ArgumentError){ Win32::Service.get_service_name }
305
+ end
306
+
307
+ test "get_service_name raises an error if a bogus service name is provided" do
308
+ assert_raise(SystemCallError){ Win32::Service.get_service_name('bogus') }
309
+ end
310
+
311
+ test "get_service_name raises an error if a bogus host is provided" do
312
+ omit_unless_elevated
313
+ assert_raise(SystemCallError){ Win32::Service.get_service_name('foo', 'bogus') }
314
+ end
315
+
316
+ test "get_service_name accepts a maximum of two arguments" do
317
+ assert_raise(ArgumentError){ Win32::Service.get_service_name('x', 'y', 'z') }
318
+ end
319
+
320
+ test "get_display_name basic functionality" do
321
+ assert_respond_to(Win32::Service, :get_display_name)
322
+ assert_nothing_raised{ Win32::Service.get_display_name(@service_name) }
323
+ assert_kind_of(String, Win32::Service.get_display_name(@service_name))
324
+ end
325
+
326
+ test "get_display_name returns expected results" do
327
+ assert_equal(@display_name, Win32::Service.get_display_name(@service_name))
328
+ end
329
+
330
+ test "getdisplayname is an alias for get_display_name" do
331
+ assert_respond_to(Win32::Service, :getdisplayname)
332
+ assert_alias_method(Win32::Service, :getdisplayname, :get_display_name)
333
+ end
334
+
335
+ test "get_display_name requires at least one argument" do
336
+ assert_raise(ArgumentError){ Win32::Service.get_display_name }
337
+ end
338
+
339
+ test "get_display_name raises an error if the service does not exist" do
340
+ assert_raise(SystemCallError){ Win32::Service.get_display_name('bogus') }
341
+ end
342
+
343
+ test "get_display_name raises an error if a bad host name is provided" do
344
+ omit_unless_elevated
345
+ assert_raise(SystemCallError){ Win32::Service.get_display_name('W32Time', 'bogus') }
346
+ end
347
+
348
+ test "get_display_name takes a maximum of two arguments" do
349
+ assert_raise(ArgumentError){ Win32::Service.get_display_name('x', 'y', 'z') }
350
+ end
351
+
352
+ test "exists method basic functionality" do
353
+ assert_respond_to(Win32::Service, :exists?)
354
+ assert_boolean(Win32::Service.exists?('W32Time'))
355
+ assert_nothing_raised{ Win32::Service.exists?('W32Time') }
356
+ end
357
+
358
+ test "exists method returns expected results" do
359
+ assert_true(Win32::Service.exists?('W32Time'))
360
+ assert_false(Win32::Service.exists?('foobar'))
361
+ end
362
+
363
+ test "exists method requires at least one argument or an error is raised" do
364
+ assert_raises(ArgumentError){ Win32::Service.exists? }
365
+ end
366
+
367
+ test "exists method raises an error if a bogus host is passed" do
368
+ omit_unless_elevated
369
+ assert_raises(SystemCallError){ Win32::Service.exists?('foo', 'bogus') }
370
+ end
371
+
372
+ test "exists method only accepts up to two arguments" do
373
+ assert_raises(ArgumentError){
374
+ Win32::Service.exists?('foo', 'bar', 'baz')
375
+ }
376
+ end
377
+
378
+ test "scm security constants are defined" do
379
+ assert_not_nil(Win32::Service::MANAGER_ALL_ACCESS)
380
+ assert_not_nil(Win32::Service::MANAGER_CREATE_SERVICE)
381
+ assert_not_nil(Win32::Service::MANAGER_CONNECT)
382
+ assert_not_nil(Win32::Service::MANAGER_ENUMERATE_SERVICE)
383
+ assert_not_nil(Win32::Service::MANAGER_LOCK)
384
+ assert_not_nil(Win32::Service::MANAGER_QUERY_LOCK_STATUS)
385
+ end
386
+
387
+ test "service specific constants are defined" do
388
+ assert_not_nil(Win32::Service::ALL_ACCESS)
389
+ assert_not_nil(Win32::Service::CHANGE_CONFIG)
390
+ assert_not_nil(Win32::Service::ENUMERATE_DEPENDENTS)
391
+ assert_not_nil(Win32::Service::INTERROGATE)
392
+ assert_not_nil(Win32::Service::PAUSE_CONTINUE)
393
+ assert_not_nil(Win32::Service::QUERY_CONFIG)
394
+ assert_not_nil(Win32::Service::QUERY_STATUS)
395
+ assert_not_nil(Win32::Service::STOP)
396
+ assert_not_nil(Win32::Service::START)
397
+ assert_not_nil(Win32::Service::USER_DEFINED_CONTROL)
398
+ end
399
+
400
+ test "service type constants are defined" do
401
+ assert_not_nil(Win32::Service::FILE_SYSTEM_DRIVER)
402
+ assert_not_nil(Win32::Service::KERNEL_DRIVER)
403
+ assert_not_nil(Win32::Service::WIN32_OWN_PROCESS)
404
+ assert_not_nil(Win32::Service::WIN32_SHARE_PROCESS)
405
+ assert_not_nil(Win32::Service::INTERACTIVE_PROCESS)
406
+ end
407
+
408
+ test "service start option constants are defined" do
409
+ assert_not_nil(Win32::Service::AUTO_START)
410
+ assert_not_nil(Win32::Service::BOOT_START)
411
+ assert_not_nil(Win32::Service::DEMAND_START)
412
+ assert_not_nil(Win32::Service::DISABLED)
413
+ assert_not_nil(Win32::Service::SYSTEM_START)
414
+ end
415
+
416
+ test "service error control constants are defined" do
417
+ assert_not_nil(Win32::Service::ERROR_IGNORE)
418
+ assert_not_nil(Win32::Service::ERROR_NORMAL)
419
+ assert_not_nil(Win32::Service::ERROR_SEVERE)
420
+ assert_not_nil(Win32::Service::ERROR_CRITICAL)
421
+ end
422
+
423
+ test "service state constants are defined" do
424
+ assert_not_nil(Win32::Service::CONTINUE_PENDING)
425
+ assert_not_nil(Win32::Service::PAUSE_PENDING)
426
+ assert_not_nil(Win32::Service::PAUSED)
427
+ assert_not_nil(Win32::Service::RUNNING)
428
+ assert_not_nil(Win32::Service::START_PENDING)
429
+ assert_not_nil(Win32::Service::STOP_PENDING)
430
+ assert_not_nil(Win32::Service::STOPPED)
431
+ end
432
+
433
+ test "internal ffi functions are not public as singleton methods" do
434
+ assert_false(@singleton_methods.include?('CloseHandle'))
435
+ assert_false(@singleton_methods.include?('ControlService'))
436
+ assert_false(@singleton_methods.include?('DeleteService'))
437
+ end
438
+
439
+ test "internal ffi functions are not public as instance methods" do
440
+ assert_false(@instance_methods.include?('CloseHandle'))
441
+ assert_false(@instance_methods.include?('ControlService'))
442
+ assert_false(@instance_methods.include?('DeleteService'))
443
+ end
444
+
445
+ def teardown
446
+ @display_name = nil
447
+ @service_name = nil
448
+ @service_stat = nil
449
+ @services = nil
450
+ end
451
+
452
+ def self.shutdown
453
+ @@host = nil
454
+ status = Win32::Service.status(@@service_name).current_state
455
+
456
+ if @elevated
457
+ if status == 'paused'
458
+ Win32::Service.resume(@@service_name)
459
+ end
460
+
461
+ unless ['running', 'start pending'].include?(status)
462
+ Win32::Service.start(@@service_name)
463
+ end
464
+ end
465
+
466
+ @@elevated = nil
467
+ end
468
+ end