thin_service 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,18 @@
1
+ '#--
2
+ '# Copyright (c) 2006-2007 Luis Lavena, Multimedia systems
3
+ '#
4
+ '# This source code is released under the MIT License.
5
+ '# See MIT-LICENSE file for details
6
+ '#++
7
+
8
+ #include once "testly.bi"
9
+
10
+ '# the code in this module runs after all
11
+ '# the other modules have "registered" their suites.
12
+
13
+ '# evaluate the result from run_tests() to
14
+ '# return a error to the OS or not.
15
+ if (run_tests() = false) then
16
+ end 1
17
+ end if
18
+
@@ -0,0 +1,92 @@
1
+ '#--
2
+ '# Copyright (c) 2006-2007 Luis Lavena, Multimedia systems
3
+ '#
4
+ '# This source code is released under the MIT License.
5
+ '# See MIT-LICENSE file for details
6
+ '#++
7
+
8
+ '# this program mock a common process that will:
9
+ '# output some text to stdout
10
+ '# output some error messages to stderr
11
+ '# will wait until Ctrl-C is hit (only if commandline contains "wait")
12
+ '# or drop an error if commandline contains "error"
13
+
14
+ #include once "crt.bi"
15
+ #include once "windows.bi"
16
+
17
+ dim shared as any ptr control_signal, control_mutex
18
+ dim shared flagged as byte
19
+ dim shared result as integer
20
+
21
+ function slow_console_handler(byval dwCtrlType as DWORD) as BOOL
22
+ dim result as BOOL
23
+
24
+ if (dwCtrlType = CTRL_C_EVENT) then
25
+ fprintf(stdout, !"out: CTRL-C received\r\n")
26
+ mutexlock(control_mutex)
27
+ result = 1
28
+ flagged = 1
29
+ condsignal(control_signal)
30
+ mutexunlock(control_mutex)
31
+ elseif (dwCtrlType = CTRL_BREAK_EVENT) then
32
+ fprintf(stdout, !"out: CTRL-BREAK received\r\n")
33
+ mutexlock(control_mutex)
34
+ result = 1
35
+ flagged = 2
36
+ condsignal(control_signal)
37
+ mutexunlock(control_mutex)
38
+ end if
39
+
40
+ return result
41
+ end function
42
+
43
+ sub wait_for(byval flag_level as integer)
44
+ flagged = 0
45
+ '# set handler
46
+ if (SetConsoleCtrlHandler(@slow_console_handler, 1) = 0) then
47
+ fprintf(stderr, !"err: cannot set console handler\r\n")
48
+ end if
49
+ fprintf(stdout, !"out: waiting for keyboard signal\r\n")
50
+ mutexlock(control_mutex)
51
+ do until (flagged = flag_level)
52
+ condwait(control_signal, control_mutex)
53
+ loop
54
+ mutexunlock(control_mutex)
55
+ fprintf(stdout, !"out: got keyboard signal\r\n")
56
+ if (SetConsoleCtrlHandler(@slow_console_handler, 0) = 0) then
57
+ fprintf(stderr, !"err: cannot unset console handler\r\n")
58
+ end if
59
+ end sub
60
+
61
+ function main() as integer
62
+ fprintf(stdout, !"out: message\r\n")
63
+ fprintf(stderr, !"err: error\r\n")
64
+
65
+ select case lcase(command(1))
66
+ case "wait":
67
+ sleep
68
+ return 0
69
+
70
+ case "error":
71
+ '# terminate with error code
72
+ return 1
73
+
74
+ case "slow1":
75
+ wait_for(1)
76
+ return 10
77
+
78
+ case "slow2":
79
+ wait_for(2)
80
+ return 20
81
+ end select
82
+ end function
83
+
84
+ control_signal = condcreate()
85
+ control_mutex = mutexcreate()
86
+
87
+ result = main()
88
+
89
+ conddestroy(control_signal)
90
+ mutexdestroy(control_mutex)
91
+
92
+ end result
@@ -0,0 +1,402 @@
1
+ '#--
2
+ '# Copyright (c) 2006-2007 Luis Lavena, Multimedia systems
3
+ '#
4
+ '# This source code is released under the MIT License.
5
+ '# See MIT-LICENSE file for details
6
+ '#++
7
+
8
+ #include once "console_process.bi"
9
+ #include once "file.bi"
10
+ #include once "testly.bi"
11
+ #include once "test_helpers.bi"
12
+
13
+ namespace Suite_Test_Console_Process
14
+ '# test helpers
15
+ declare function process_cleanup() as boolean
16
+
17
+ dim shared child as ConsoleProcess ptr
18
+
19
+ sub before_all()
20
+ kill("out.log")
21
+ kill("err.log")
22
+ kill("both.log")
23
+ kill("both_slow.log")
24
+ kill("both_forced.log")
25
+ end sub
26
+
27
+ sub after_each()
28
+ process_cleanup()
29
+ end sub
30
+
31
+ sub test_process_create()
32
+ child = new ConsoleProcess()
33
+ assert_not_equal(0, child)
34
+ assert_equal("", child->filename)
35
+ assert_equal("", child->arguments)
36
+ assert_false(child->running)
37
+ delete child
38
+ end sub
39
+
40
+ sub test_process_create_args()
41
+ child = new ConsoleProcess("mock_process.exe", "some params")
42
+ assert_equal("mock_process.exe", child->filename)
43
+ assert_equal("some params", child->arguments)
44
+ delete child
45
+ end sub
46
+
47
+ sub test_properly_quoted_filename()
48
+ child = new ConsoleProcess("C:\path with spaces\my_executable.exe", "some params")
49
+ assert_not_equal(0, instr(child->filename, !"\""))
50
+ delete child
51
+ end sub
52
+
53
+ sub test_failed_unexistant_process()
54
+ child = new ConsoleProcess("no_valid_file.exe", "some params")
55
+ assert_false(child->start())
56
+ assert_equal(0, child->pid)
57
+ assert_false(child->running)
58
+ delete child
59
+ end sub
60
+
61
+ sub test_process_spawn_exit_code()
62
+ child = new ConsoleProcess("mock_process.exe", "error")
63
+
64
+ '# start() should return true since it started, no matter if was terminated
65
+ '# improperly
66
+ assert_true(child->start())
67
+ sleep 500
68
+
69
+ '# should not be running, but pid should be != than 0
70
+ assert_not_equal(0, child->pid)
71
+
72
+ '# we need to wait a bit prior asking for state
73
+ '# the process could be still running
74
+ assert_false(child->running)
75
+
76
+ '# get exit code, should be 1
77
+ assert_equal(1, child->exit_code)
78
+
79
+ delete child
80
+ end sub
81
+
82
+ sub test_redirected_output()
83
+ assert_false(fileexists("out.log"))
84
+ assert_false(fileexists("err.log"))
85
+
86
+ '# redirected output is used with logging files.
87
+ child = new ConsoleProcess("mock_process.exe")
88
+
89
+ '# redirect stdout
90
+ assert_true(child->redirect(ProcessStdOut, "out.log"))
91
+ assert_string_equal("out.log", child->redirected_stdout)
92
+
93
+ '# redirect stderr
94
+ assert_true(child->redirect(ProcessStdErr, "err.log"))
95
+ assert_string_equal("err.log", child->redirected_stderr)
96
+
97
+ '# start() will be true since process terminated nicely
98
+ assert_true(child->start())
99
+ sleep 500
100
+
101
+ '# running should be false
102
+ assert_false(child->running)
103
+
104
+ '# exit_code should be 0
105
+ assert_equal(0, child->exit_code)
106
+
107
+ delete child
108
+
109
+ '# now out.log and err.log must exist and content must be valid.
110
+ assert_true(fileexists("out.log"))
111
+ assert_string_equal("out: message", content_of_file("out.log"))
112
+
113
+ assert_true(fileexists("err.log"))
114
+ assert_string_equal("err: error", content_of_file("err.log"))
115
+
116
+ assert_equal(0, kill("out.log"))
117
+ assert_equal(0, kill("err.log"))
118
+ end sub
119
+
120
+ sub test_redirected_merged_output()
121
+ dim content as string
122
+
123
+ '# redirected output is used with logging files.
124
+ child = new ConsoleProcess("mock_process.exe")
125
+
126
+ '# redirect both stdout and stderr
127
+ child->redirect(ProcessStdBoth, "both.log")
128
+ assert_equal("both.log", child->redirected_stdout)
129
+ assert_equal("both.log", child->redirected_stderr)
130
+
131
+ '# start() will be true since process terminated nicely
132
+ assert_true(child->start())
133
+ sleep 500
134
+
135
+ '# running should be false
136
+ assert_false(child->running)
137
+
138
+ '# exit_code should be 0
139
+ assert_equal(0, child->exit_code)
140
+
141
+ delete child
142
+
143
+ '# file must exists
144
+ assert_true(fileexists("both.log"))
145
+
146
+ '# contents must match
147
+ content = content_of_file("both.log")
148
+
149
+ assert_not_equal(0, instr(content, "out: message"))
150
+ assert_not_equal(0, instr(content, "err: error"))
151
+
152
+ assert_equal(0, kill("both.log"))
153
+ end sub
154
+
155
+ sub test_redirected_output_append()
156
+ dim content as string
157
+
158
+ child = new ConsoleProcess("mock_process.exe")
159
+
160
+ '# redirect both stdout and stderr
161
+ child->redirect(ProcessStdBoth, "both.log")
162
+
163
+ '# start() will be true since process terminated nicely
164
+ assert_true(child->start())
165
+ sleep 500
166
+
167
+ content = content_of_file("both.log")
168
+
169
+ '# start() again
170
+ assert_true(child->start())
171
+ sleep 500
172
+
173
+ delete child
174
+
175
+ assert_not_equal(len(content), len(content_of_file("both.log")))
176
+
177
+ assert_equal(0, kill("both.log"))
178
+ end sub
179
+
180
+ sub test_process_terminate()
181
+ dim content as string
182
+
183
+ '# redirected output is used with logging files.
184
+ child = new ConsoleProcess("mock_process.exe", "wait")
185
+ child->redirect(ProcessStdBoth, "both.log")
186
+
187
+ '# start
188
+ assert_true(child->start())
189
+ sleep 500
190
+
191
+ '# validate if running
192
+ assert_true(child->running)
193
+
194
+ '# validate PID
195
+ assert_not_equal(0, child->pid)
196
+
197
+ '# now terminates it
198
+ assert_true(child->terminate())
199
+ sleep 500
200
+
201
+ assert_equal(9, child->exit_code)
202
+
203
+ '# it should be done
204
+ assert_false(child->running)
205
+
206
+ delete child
207
+
208
+ '# validate output
209
+ '# file must exists
210
+ assert_true(fileexists("both.log"))
211
+
212
+ '# contents must match
213
+ content = content_of_file("both.log")
214
+
215
+ assert_not_equal(0, instr(content, "out: message"))
216
+ assert_not_equal(0, instr(content, "err: error"))
217
+ assert_not_equal(0, instr(content, "interrupted"))
218
+
219
+ assert_equal(0, kill("both.log"))
220
+ end sub
221
+
222
+ sub test_process_terminate_slow1()
223
+ dim content as string
224
+
225
+ '# redirected output is used with logging files.
226
+ child = new ConsoleProcess("mock_process.exe", "slow1")
227
+ child->redirect(ProcessStdBoth, "both_slow1.log")
228
+
229
+ '# start
230
+ assert_true(child->start())
231
+ sleep 500
232
+
233
+ '# validate if running
234
+ assert_true(child->running)
235
+
236
+ '# validate PID
237
+ assert_not_equal(0, child->pid)
238
+
239
+ '# now terminates it
240
+ assert_true(child->terminate())
241
+ sleep 500
242
+
243
+ assert_equal(10, child->exit_code)
244
+
245
+ '# it should be done
246
+ assert_false(child->running)
247
+
248
+ delete child
249
+
250
+ '# validate output
251
+ '# file must exists
252
+ assert_true(fileexists("both_slow1.log"))
253
+
254
+ '# contents must match
255
+ content = content_of_file("both_slow1.log")
256
+
257
+ assert_equal(0, instr(content, "interrupted"))
258
+ assert_not_equal(0, instr(content, "out: CTRL-C received"))
259
+ assert_equal(0, instr(content, "out: CTRL-BREAK received"))
260
+
261
+ assert_equal(0, kill("both_slow1.log"))
262
+ end sub
263
+
264
+ sub test_process_terminate_slow2()
265
+ dim content as string
266
+
267
+ '# redirected output is used with logging files.
268
+ child = new ConsoleProcess("mock_process.exe", "slow2")
269
+ child->redirect(ProcessStdBoth, "both_slow2.log")
270
+
271
+ '# start
272
+ assert_true(child->start())
273
+ sleep 500
274
+
275
+ '# validate if running
276
+ assert_true(child->running)
277
+
278
+ '# validate PID
279
+ assert_not_equal(0, child->pid)
280
+
281
+ '# now terminates it
282
+ assert_true(child->terminate())
283
+ sleep 500
284
+
285
+ assert_equal(20, child->exit_code)
286
+
287
+ '# it should be done
288
+ assert_false(child->running)
289
+
290
+ delete child
291
+
292
+ '# validate output
293
+ '# file must exists
294
+ assert_true(fileexists("both_slow2.log"))
295
+
296
+ '# contents must match
297
+ content = content_of_file("both_slow2.log")
298
+
299
+ assert_equal(0, instr(content, "interrupted"))
300
+ assert_not_equal(0, instr(content, "out: CTRL-C received"))
301
+ assert_not_equal(0, instr(content, "out: CTRL-BREAK received"))
302
+
303
+ '# cleanup
304
+ assert_equal(0, kill("both_slow2.log"))
305
+ end sub
306
+
307
+ sub test_process_terminate_forced()
308
+ dim content as string
309
+
310
+ '# redirected output is used with logging files.
311
+ child = new ConsoleProcess("mock_process.exe", "wait")
312
+ child->redirect(ProcessStdBoth, "both_forced.log")
313
+
314
+ '# start
315
+ assert_true(child->start())
316
+ sleep 500
317
+
318
+ '# validate if running
319
+ assert_true(child->running)
320
+
321
+ '# validate PID
322
+ assert_not_equal(0, child->pid)
323
+
324
+ '# now terminates it
325
+ assert_true(child->terminate(true))
326
+ sleep 500
327
+
328
+ '# it should be done
329
+ assert_false(child->running)
330
+
331
+ '# look for termination code
332
+ assert_equal(0, child->exit_code)
333
+
334
+ delete child
335
+
336
+ '# validate output
337
+ '# file must exists
338
+ assert_true(fileexists("both_forced.log"))
339
+
340
+ '# contents must match
341
+ content = content_of_file("both_forced.log")
342
+
343
+ assert_equal(0, instr(content, "out: message"))
344
+ assert_equal(0, instr(content, "err: error"))
345
+ assert_equal(0, instr(content, "interrupted"))
346
+
347
+ assert_equal(0, kill("both_forced.log"))
348
+ end sub
349
+
350
+ sub test_reuse_object_instance()
351
+ dim first_pid as uinteger
352
+
353
+ child = new ConsoleProcess("mock_process.exe")
354
+
355
+ '# start
356
+ assert_true(child->start())
357
+ sleep 500
358
+
359
+ '# validate not running
360
+ assert_false(child->running)
361
+
362
+ '# validate PID
363
+ assert_not_equal(0, child->pid)
364
+
365
+ '# saves PID
366
+ first_pid = child->pid
367
+
368
+ '# start it again
369
+ assert_true(child->start())
370
+ sleep 500
371
+
372
+ '# it should have stopped by now
373
+ assert_false(child->running)
374
+ assert_not_equal(0, child->pid)
375
+ assert_not_equal(first_pid, child->pid)
376
+
377
+ delete child
378
+ end sub
379
+
380
+ private sub register() constructor
381
+ add_suite(Suite_Test_Console_Process)
382
+ add_test(test_process_create)
383
+ add_test(test_process_create_args)
384
+ add_test(test_properly_quoted_filename)
385
+ add_test(test_failed_unexistant_process)
386
+ add_test(test_process_spawn_exit_code)
387
+ add_test(test_redirected_output)
388
+ add_test(test_redirected_merged_output)
389
+ add_test(test_redirected_output_append)
390
+ add_test(test_process_terminate)
391
+ add_test(test_process_terminate_slow1)
392
+ add_test(test_process_terminate_slow2)
393
+ add_test(test_process_terminate_forced)
394
+ add_test(test_reuse_object_instance)
395
+ end sub
396
+
397
+ '# test helpers below this point
398
+ private function process_cleanup() as boolean
399
+ shell "taskkill /f /im mock_process.exe 1>NUL 2>&1"
400
+ return true
401
+ end function
402
+ end namespace