win32-service 0.5.2-mswin32
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.
- data/CHANGES +174 -0
- data/MANIFEST +16 -0
- data/README +46 -0
- data/doc/daemon.txt +160 -0
- data/doc/service.txt +382 -0
- data/lib/win32/service.c +2131 -0
- data/lib/win32/service.h +416 -0
- data/lib/win32/service.so +0 -0
- data/test/tc_daemon.rb +59 -0
- data/test/tc_service.rb +406 -0
- metadata +59 -0
data/lib/win32/service.h
ADDED
@@ -0,0 +1,416 @@
|
|
1
|
+
#define WIN32_SERVICE_VERSION "0.5.2"
|
2
|
+
|
3
|
+
#define MAX_KEY_SIZE 24
|
4
|
+
#define MAX_SERVICES 1000
|
5
|
+
#define MAX_BUF_SIZE 4096
|
6
|
+
|
7
|
+
struct servicestruct{
|
8
|
+
SC_HANDLE hSCManager;
|
9
|
+
};
|
10
|
+
|
11
|
+
typedef struct servicestruct SvcStruct;
|
12
|
+
|
13
|
+
static void service_free(SvcStruct *p){
|
14
|
+
CloseServiceHandle(p->hSCManager);
|
15
|
+
p->hSCManager = NULL;
|
16
|
+
free(p);
|
17
|
+
}
|
18
|
+
|
19
|
+
// A list of valid keys (attributes) for the Service class. Note that the
|
20
|
+
// 'dependencies' attribute is defined manually for type checking purposes
|
21
|
+
// so it is not included in this array.
|
22
|
+
char *keys[] = {
|
23
|
+
"machine_name",
|
24
|
+
"desired_access",
|
25
|
+
"service_name",
|
26
|
+
"display_name",
|
27
|
+
"service_type",
|
28
|
+
"start_type",
|
29
|
+
"error_control",
|
30
|
+
"tag_id",
|
31
|
+
"binary_path_name",
|
32
|
+
"load_order_group",
|
33
|
+
"start_name",
|
34
|
+
"password",
|
35
|
+
"service_description"
|
36
|
+
};
|
37
|
+
|
38
|
+
// Return an error code as a string
|
39
|
+
LPTSTR ErrorDescription(DWORD p_dwError)
|
40
|
+
{
|
41
|
+
HLOCAL hLocal = NULL;
|
42
|
+
static TCHAR ErrStr[1024];
|
43
|
+
int len;
|
44
|
+
|
45
|
+
if (!(len=FormatMessage(
|
46
|
+
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
47
|
+
FORMAT_MESSAGE_FROM_SYSTEM |
|
48
|
+
FORMAT_MESSAGE_IGNORE_INSERTS,
|
49
|
+
NULL,
|
50
|
+
p_dwError,
|
51
|
+
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
52
|
+
(LPTSTR)&hLocal,
|
53
|
+
0,
|
54
|
+
NULL)))
|
55
|
+
{
|
56
|
+
rb_raise(rb_eStandardError, "unable to format error message");
|
57
|
+
}
|
58
|
+
memset(ErrStr, 0, sizeof(ErrStr));
|
59
|
+
strncpy(ErrStr, (LPTSTR)hLocal, len-2); // remove \r\n
|
60
|
+
LocalFree(hLocal);
|
61
|
+
return ErrStr;
|
62
|
+
}
|
63
|
+
|
64
|
+
static VALUE rb_get_dependencies(LPTSTR lpDependencies){
|
65
|
+
VALUE v_dependencies = rb_ary_new();
|
66
|
+
|
67
|
+
if(lpDependencies){
|
68
|
+
TCHAR* pszDepend = 0;
|
69
|
+
int i = 0;
|
70
|
+
|
71
|
+
pszDepend = &lpDependencies[i];
|
72
|
+
|
73
|
+
while(*pszDepend != 0){
|
74
|
+
rb_ary_push(v_dependencies, rb_str_new2(pszDepend));
|
75
|
+
i += _tcslen(lpDependencies) + 1;
|
76
|
+
pszDepend = &lpDependencies[i];
|
77
|
+
}
|
78
|
+
}
|
79
|
+
|
80
|
+
if(RARRAY(v_dependencies)->len == 0)
|
81
|
+
v_dependencies = Qnil;
|
82
|
+
|
83
|
+
return v_dependencies;
|
84
|
+
}
|
85
|
+
|
86
|
+
static VALUE rb_get_error_control(DWORD dwErrorControl){
|
87
|
+
VALUE v_error_control;
|
88
|
+
switch(dwErrorControl){
|
89
|
+
case SERVICE_ERROR_CRITICAL:
|
90
|
+
v_error_control = rb_str_new2("critical");
|
91
|
+
break;
|
92
|
+
case SERVICE_ERROR_IGNORE:
|
93
|
+
v_error_control = rb_str_new2("ignore");
|
94
|
+
break;
|
95
|
+
case SERVICE_ERROR_NORMAL:
|
96
|
+
v_error_control = rb_str_new2("normal");
|
97
|
+
break;
|
98
|
+
case SERVICE_ERROR_SEVERE:
|
99
|
+
v_error_control = rb_str_new2("severe");
|
100
|
+
break;
|
101
|
+
default:
|
102
|
+
v_error_control = Qnil;
|
103
|
+
|
104
|
+
}
|
105
|
+
|
106
|
+
return v_error_control;
|
107
|
+
}
|
108
|
+
|
109
|
+
static VALUE rb_get_start_type(DWORD dwStartType){
|
110
|
+
VALUE v_start_type;
|
111
|
+
switch(dwStartType){
|
112
|
+
case SERVICE_AUTO_START:
|
113
|
+
v_start_type = rb_str_new2("auto start");
|
114
|
+
break;
|
115
|
+
case SERVICE_BOOT_START:
|
116
|
+
v_start_type = rb_str_new2("boot start");
|
117
|
+
break;
|
118
|
+
case SERVICE_DEMAND_START:
|
119
|
+
v_start_type = rb_str_new2("demand start");
|
120
|
+
break;
|
121
|
+
case SERVICE_DISABLED:
|
122
|
+
v_start_type = rb_str_new2("disabled");
|
123
|
+
break;
|
124
|
+
case SERVICE_SYSTEM_START:
|
125
|
+
v_start_type = rb_str_new2("system start");
|
126
|
+
break;
|
127
|
+
default:
|
128
|
+
v_start_type = Qnil;
|
129
|
+
}
|
130
|
+
|
131
|
+
return v_start_type;
|
132
|
+
}
|
133
|
+
|
134
|
+
/* Helper function to retrieve the service type. Note that some of these
|
135
|
+
* values were not documented from the MSDN web site, but are listed in the
|
136
|
+
* winnt.h header file.
|
137
|
+
*/
|
138
|
+
static VALUE rb_get_service_type(DWORD dwServiceType){
|
139
|
+
VALUE rbServiceType;
|
140
|
+
switch(dwServiceType){
|
141
|
+
case SERVICE_FILE_SYSTEM_DRIVER:
|
142
|
+
rbServiceType = rb_str_new2("filesystem driver");
|
143
|
+
break;
|
144
|
+
case SERVICE_KERNEL_DRIVER:
|
145
|
+
rbServiceType = rb_str_new2("kernel driver");
|
146
|
+
break;
|
147
|
+
case SERVICE_WIN32_OWN_PROCESS:
|
148
|
+
rbServiceType = rb_str_new2("own process");
|
149
|
+
break;
|
150
|
+
case SERVICE_WIN32_SHARE_PROCESS:
|
151
|
+
rbServiceType = rb_str_new2("share process");
|
152
|
+
break;
|
153
|
+
/* There is some debate whether this is supposed to be 'RECOGNIZED' */
|
154
|
+
case SERVICE_RECOGNIZER_DRIVER:
|
155
|
+
rbServiceType = rb_str_new2("recognizer driver");
|
156
|
+
break;
|
157
|
+
case SERVICE_DRIVER:
|
158
|
+
rbServiceType = rb_str_new2("driver");
|
159
|
+
break;
|
160
|
+
case SERVICE_WIN32:
|
161
|
+
rbServiceType = rb_str_new2("win32");
|
162
|
+
break;
|
163
|
+
case SERVICE_TYPE_ALL:
|
164
|
+
rbServiceType = rb_str_new2("all");
|
165
|
+
break;
|
166
|
+
case (SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS):
|
167
|
+
rbServiceType = rb_str_new2("own process, interactive");
|
168
|
+
break;
|
169
|
+
case (SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_SHARE_PROCESS):
|
170
|
+
rbServiceType = rb_str_new2("share process, interactive");
|
171
|
+
break;
|
172
|
+
default:
|
173
|
+
rbServiceType = Qnil;
|
174
|
+
}
|
175
|
+
|
176
|
+
return rbServiceType;
|
177
|
+
}
|
178
|
+
|
179
|
+
static VALUE rb_get_current_state(DWORD dwCurrentState){
|
180
|
+
VALUE rbCurrentState;
|
181
|
+
switch(dwCurrentState){
|
182
|
+
case SERVICE_CONTINUE_PENDING:
|
183
|
+
rbCurrentState = rb_str_new2("continue pending");
|
184
|
+
break;
|
185
|
+
case SERVICE_PAUSE_PENDING:
|
186
|
+
rbCurrentState = rb_str_new2("pause pending");
|
187
|
+
break;
|
188
|
+
case SERVICE_PAUSED:
|
189
|
+
rbCurrentState = rb_str_new2("paused");
|
190
|
+
break;
|
191
|
+
case SERVICE_RUNNING:
|
192
|
+
rbCurrentState = rb_str_new2("running");
|
193
|
+
break;
|
194
|
+
case SERVICE_START_PENDING:
|
195
|
+
rbCurrentState = rb_str_new2("start pending");
|
196
|
+
break;
|
197
|
+
case SERVICE_STOP_PENDING:
|
198
|
+
rbCurrentState = rb_str_new2("stop pending");
|
199
|
+
break;
|
200
|
+
case SERVICE_STOPPED:
|
201
|
+
rbCurrentState = rb_str_new2("stopped");
|
202
|
+
break;
|
203
|
+
default:
|
204
|
+
rbCurrentState = Qnil;
|
205
|
+
}
|
206
|
+
|
207
|
+
return rbCurrentState;
|
208
|
+
}
|
209
|
+
|
210
|
+
static VALUE rb_get_controls_accepted(DWORD dwControlsAccepted){
|
211
|
+
VALUE rbControlsAccepted = rb_ary_new();
|
212
|
+
if(dwControlsAccepted & SERVICE_ACCEPT_NETBINDCHANGE){
|
213
|
+
rb_ary_push(rbControlsAccepted,rb_str_new2("netbind change"));
|
214
|
+
}
|
215
|
+
|
216
|
+
if(dwControlsAccepted & SERVICE_ACCEPT_PARAMCHANGE){
|
217
|
+
rb_ary_push(rbControlsAccepted,rb_str_new2("param change"));
|
218
|
+
}
|
219
|
+
|
220
|
+
if(dwControlsAccepted & SERVICE_PAUSE_CONTINUE){
|
221
|
+
rb_ary_push(rbControlsAccepted,rb_str_new2("pause continue"));
|
222
|
+
}
|
223
|
+
|
224
|
+
if(dwControlsAccepted & SERVICE_ACCEPT_SHUTDOWN){
|
225
|
+
rb_ary_push(rbControlsAccepted,rb_str_new2("shutdown"));
|
226
|
+
}
|
227
|
+
|
228
|
+
if(dwControlsAccepted & SERVICE_ACCEPT_STOP){
|
229
|
+
rb_ary_push(rbControlsAccepted,rb_str_new2("stop"));
|
230
|
+
}
|
231
|
+
|
232
|
+
if(RARRAY(rbControlsAccepted)->len == 0){
|
233
|
+
rbControlsAccepted = Qnil;
|
234
|
+
}
|
235
|
+
|
236
|
+
return rbControlsAccepted;
|
237
|
+
}
|
238
|
+
|
239
|
+
static void set_service_constants(VALUE klass)
|
240
|
+
{
|
241
|
+
// Desired Access Flags
|
242
|
+
rb_define_const(klass, "MANAGER_ALL_ACCESS",
|
243
|
+
INT2NUM(SC_MANAGER_ALL_ACCESS));
|
244
|
+
|
245
|
+
rb_define_const(klass, "MANAGER_CREATE_SERVICE",
|
246
|
+
INT2NUM(SC_MANAGER_CREATE_SERVICE));
|
247
|
+
|
248
|
+
rb_define_const(klass, "MANAGER_CONNECT",
|
249
|
+
INT2NUM(SC_MANAGER_CONNECT));
|
250
|
+
|
251
|
+
rb_define_const(klass, "MANAGER_ENUMERATE_SERVICE",
|
252
|
+
INT2NUM(SC_MANAGER_ENUMERATE_SERVICE));
|
253
|
+
|
254
|
+
rb_define_const(klass, "MANAGER_LOCK",
|
255
|
+
INT2NUM(SC_MANAGER_LOCK));
|
256
|
+
|
257
|
+
#ifdef SC_MANAGER_BOOT_CONFIG
|
258
|
+
rb_define_const(klass, "MANAGER_BOOT_CONFIG",
|
259
|
+
INT2NUM(SC_MANAGER_BOOT_CONFIG));
|
260
|
+
#endif
|
261
|
+
|
262
|
+
rb_define_const(klass, "MANAGER_QUERY_LOCK_STATUS",
|
263
|
+
INT2NUM(SC_MANAGER_QUERY_LOCK_STATUS));
|
264
|
+
|
265
|
+
/* Service specific access flags */
|
266
|
+
rb_define_const(klass, "ALL_ACCESS", INT2NUM(SERVICE_ALL_ACCESS));
|
267
|
+
rb_define_const(klass, "CHANGE_CONFIG", INT2NUM(SERVICE_CHANGE_CONFIG));
|
268
|
+
|
269
|
+
rb_define_const(klass, "ENUMERATE_DEPENDENTS",
|
270
|
+
INT2NUM(SERVICE_ENUMERATE_DEPENDENTS));
|
271
|
+
|
272
|
+
rb_define_const(klass, "INTERROGATE", INT2NUM(SERVICE_INTERROGATE));
|
273
|
+
rb_define_const(klass, "PAUSE_CONTINUE", INT2NUM(SERVICE_PAUSE_CONTINUE));
|
274
|
+
rb_define_const(klass, "QUERY_CONFIG", INT2NUM(SERVICE_QUERY_CONFIG));
|
275
|
+
rb_define_const(klass, "QUERY_STATUS", INT2NUM(SERVICE_QUERY_STATUS));
|
276
|
+
rb_define_const(klass, "STOP", INT2NUM(SERVICE_STOP));
|
277
|
+
rb_define_const(klass, "START", INT2NUM(SERVICE_START));
|
278
|
+
|
279
|
+
rb_define_const(klass, "USER_DEFINED_CONTROL",
|
280
|
+
INT2NUM(SERVICE_USER_DEFINED_CONTROL));
|
281
|
+
|
282
|
+
// Service Type
|
283
|
+
rb_define_const(klass, "FILE_SYSTEM_DRIVER",
|
284
|
+
INT2NUM(SERVICE_FILE_SYSTEM_DRIVER));
|
285
|
+
|
286
|
+
rb_define_const(klass, "KERNEL_DRIVER",
|
287
|
+
INT2NUM(SERVICE_KERNEL_DRIVER));
|
288
|
+
|
289
|
+
rb_define_const(klass, "WIN32_OWN_PROCESS",
|
290
|
+
INT2NUM(SERVICE_WIN32_OWN_PROCESS));
|
291
|
+
|
292
|
+
rb_define_const(klass, "WIN32_SHARE_PROCESS",
|
293
|
+
INT2NUM(SERVICE_WIN32_SHARE_PROCESS));
|
294
|
+
|
295
|
+
rb_define_const(klass, "INTERACTIVE_PROCESS",
|
296
|
+
INT2NUM(SERVICE_INTERACTIVE_PROCESS));
|
297
|
+
|
298
|
+
// Start Type
|
299
|
+
rb_define_const(klass, "AUTO_START",
|
300
|
+
INT2NUM(SERVICE_AUTO_START));
|
301
|
+
|
302
|
+
rb_define_const(klass, "BOOT_START",
|
303
|
+
INT2NUM(SERVICE_BOOT_START));
|
304
|
+
|
305
|
+
rb_define_const(klass, "DEMAND_START",
|
306
|
+
INT2NUM(SERVICE_DEMAND_START));
|
307
|
+
|
308
|
+
rb_define_const(klass, "DISABLED",
|
309
|
+
INT2NUM(SERVICE_DISABLED));
|
310
|
+
|
311
|
+
rb_define_const(klass, "SYSTEM_START",
|
312
|
+
INT2NUM(SERVICE_SYSTEM_START));
|
313
|
+
|
314
|
+
// Error Control
|
315
|
+
rb_define_const(klass, "ERROR_IGNORE",
|
316
|
+
INT2NUM(SERVICE_ERROR_IGNORE));
|
317
|
+
|
318
|
+
rb_define_const(klass, "ERROR_NORMAL",
|
319
|
+
INT2NUM(SERVICE_ERROR_NORMAL));
|
320
|
+
|
321
|
+
rb_define_const(klass, "ERROR_SEVERE",
|
322
|
+
INT2NUM(SERVICE_ERROR_SEVERE));
|
323
|
+
|
324
|
+
rb_define_const(klass, "ERROR_CRITICAL",
|
325
|
+
INT2NUM(SERVICE_ERROR_CRITICAL));
|
326
|
+
|
327
|
+
// Service Status
|
328
|
+
rb_define_const(klass, "CONTINUE_PENDING",
|
329
|
+
INT2NUM(SERVICE_CONTINUE_PENDING));
|
330
|
+
|
331
|
+
rb_define_const(klass, "PAUSE_PENDING",
|
332
|
+
INT2NUM(SERVICE_PAUSE_PENDING));
|
333
|
+
|
334
|
+
rb_define_const(klass, "PAUSED",
|
335
|
+
INT2NUM(SERVICE_PAUSED));
|
336
|
+
|
337
|
+
rb_define_const(klass, "RUNNING",
|
338
|
+
INT2NUM(SERVICE_RUNNING));
|
339
|
+
|
340
|
+
rb_define_const(klass, "START_PENDING",
|
341
|
+
INT2NUM(SERVICE_START_PENDING));
|
342
|
+
|
343
|
+
rb_define_const(klass, "STOP_PENDING",
|
344
|
+
INT2NUM(SERVICE_STOP_PENDING));
|
345
|
+
|
346
|
+
rb_define_const(klass, "STOPPED",
|
347
|
+
INT2NUM(SERVICE_STOPPED));
|
348
|
+
|
349
|
+
// Service Control Signals
|
350
|
+
rb_define_const(klass, "CONTROL_STOP",
|
351
|
+
INT2NUM(SERVICE_CONTROL_STOP));
|
352
|
+
|
353
|
+
rb_define_const(klass, "CONTROL_PAUSE",
|
354
|
+
INT2NUM(SERVICE_CONTROL_PAUSE));
|
355
|
+
|
356
|
+
rb_define_const(klass, "CONTROL_CONTINUE",
|
357
|
+
INT2NUM(SERVICE_CONTROL_CONTINUE));
|
358
|
+
|
359
|
+
rb_define_const(klass, "CONTROL_INTERROGATE",
|
360
|
+
INT2NUM(SERVICE_CONTROL_INTERROGATE));
|
361
|
+
|
362
|
+
rb_define_const(klass, "CONTROL_SHUTDOWN",
|
363
|
+
INT2NUM(SERVICE_CONTROL_SHUTDOWN));
|
364
|
+
|
365
|
+
#ifdef SERVICE_CONTROL_PARAMCHANGE
|
366
|
+
rb_define_const(klass, "CONTROL_PARAMCHANGE",
|
367
|
+
INT2NUM(SERVICE_CONTROL_PARAMCHANGE));
|
368
|
+
#endif
|
369
|
+
|
370
|
+
#ifdef SERVICE_CONTROL_NETBINDADD
|
371
|
+
rb_define_const(klass, "CONTROL_NETBINDADD",
|
372
|
+
INT2NUM(SERVICE_CONTROL_NETBINDADD));
|
373
|
+
#endif
|
374
|
+
|
375
|
+
#ifdef SERVICE_CONTROL_NETBINDREMOVE
|
376
|
+
rb_define_const(klass, "CONTROL_NETBINDREMOVE",
|
377
|
+
INT2NUM(SERVICE_CONTROL_NETBINDREMOVE));
|
378
|
+
#endif
|
379
|
+
|
380
|
+
#ifdef SERVICE_CONTROL_NETBINDENABLE
|
381
|
+
rb_define_const(klass, "CONTROL_NETBINDENABLE",
|
382
|
+
INT2NUM(SERVICE_CONTROL_NETBINDENABLE));
|
383
|
+
#endif
|
384
|
+
|
385
|
+
#ifdef SERVICE_CONTROL_NETBINDDISABLE
|
386
|
+
rb_define_const(klass, "CONTROL_NETBINDDISABLE",
|
387
|
+
INT2NUM(SERVICE_CONTROL_NETBINDDISABLE));
|
388
|
+
#endif
|
389
|
+
}
|
390
|
+
|
391
|
+
// The Daemon class only needs a subset of the Service constants
|
392
|
+
void set_daemon_constants(VALUE klass){
|
393
|
+
rb_define_const(klass, "CONTINUE_PENDING",
|
394
|
+
INT2NUM(SERVICE_CONTINUE_PENDING));
|
395
|
+
|
396
|
+
rb_define_const(klass, "PAUSE_PENDING",
|
397
|
+
INT2NUM(SERVICE_PAUSE_PENDING));
|
398
|
+
|
399
|
+
rb_define_const(klass, "PAUSED",
|
400
|
+
INT2NUM(SERVICE_PAUSED));
|
401
|
+
|
402
|
+
rb_define_const(klass, "RUNNING",
|
403
|
+
INT2NUM(SERVICE_RUNNING));
|
404
|
+
|
405
|
+
rb_define_const(klass, "START_PENDING",
|
406
|
+
INT2NUM(SERVICE_START_PENDING));
|
407
|
+
|
408
|
+
rb_define_const(klass, "STOP_PENDING",
|
409
|
+
INT2NUM(SERVICE_STOP_PENDING));
|
410
|
+
|
411
|
+
rb_define_const(klass, "STOPPED",
|
412
|
+
INT2NUM(SERVICE_STOPPED));
|
413
|
+
|
414
|
+
rb_define_const(klass, "IDLE", INT2NUM(0));
|
415
|
+
}
|
416
|
+
|
Binary file
|
data/test/tc_daemon.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
#########################################################################
|
2
|
+
# tc_daemon.rb
|
3
|
+
#
|
4
|
+
# Test suite for the Daemon class
|
5
|
+
#########################################################################
|
6
|
+
if File.basename(Dir.pwd) == "test"
|
7
|
+
require "ftools"
|
8
|
+
Dir.chdir ".."
|
9
|
+
Dir.mkdir("win32") unless File.exists?("win32")
|
10
|
+
File.copy("service.so","win32")
|
11
|
+
$LOAD_PATH.unshift Dir.pwd
|
12
|
+
end
|
13
|
+
|
14
|
+
require "win32/service"
|
15
|
+
require "test/unit"
|
16
|
+
include Win32
|
17
|
+
|
18
|
+
class TC_Daemon < Test::Unit::TestCase
|
19
|
+
def setup
|
20
|
+
@d = Daemon.new
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_version
|
24
|
+
assert_equal("0.5.2", Daemon::VERSION)
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_constructor
|
28
|
+
assert_respond_to(Daemon, :new)
|
29
|
+
assert_nothing_raised{ Daemon.new }
|
30
|
+
assert_raises(ArgumentError){ Daemon.new(1) } # No arguments by default
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_mainloop
|
34
|
+
assert_respond_to(@d, :mainloop)
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_state
|
38
|
+
assert_respond_to(@d, :state)
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_running
|
42
|
+
assert_respond_to(@d, :running?)
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_constants
|
46
|
+
assert_not_nil(Daemon::CONTINUE_PENDING)
|
47
|
+
assert_not_nil(Daemon::PAUSE_PENDING)
|
48
|
+
assert_not_nil(Daemon::PAUSED)
|
49
|
+
assert_not_nil(Daemon::RUNNING)
|
50
|
+
assert_not_nil(Daemon::START_PENDING)
|
51
|
+
assert_not_nil(Daemon::STOP_PENDING)
|
52
|
+
assert_not_nil(Daemon::STOPPED)
|
53
|
+
assert_not_nil(Daemon::IDLE)
|
54
|
+
end
|
55
|
+
|
56
|
+
def teardown
|
57
|
+
@d = nil
|
58
|
+
end
|
59
|
+
end
|