rubywbem 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,442 @@
1
+ #
2
+ # Copyright 2006, Red Hat, Inc
3
+ # Scott Seago <sseago@redhat.com>
4
+ #
5
+ # derived from pywbem, written by Tim Potter <tpot@hp.com>, Martin Pool <mbp@hp.com>
6
+ #
7
+ # This program is free software; you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation; either version 2 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # You should have received a copy of the GNU General Public License
13
+ # along with this program; if not, write to the Free Software
14
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15
+ #
16
+
17
+ require "getoptlong"
18
+ require "fileutils"
19
+
20
+ COMFYCHAIRDOC = <<END
21
+ comfychair: a Ruby-based instrument of software torture.
22
+ (based on the Python version)
23
+
24
+ This is a test framework designed for testing programs written in
25
+ Ruby, or (through a fork/exec interface) any other language.
26
+
27
+ For more information, see the file README.comfychair.
28
+
29
+ To run a test suite based on ComfyChair, just run it as a program.
30
+ END
31
+
32
+
33
+ module Comfychair
34
+
35
+ class TestCase
36
+ #"""A base class for tests. This class defines required functions which
37
+ #can optionally be overridden by subclasses. It also provides some
38
+ #utility functions for"""
39
+
40
+
41
+ attr_reader :test_log, :_cleanups, :basedir, :rundir, :tmpdir
42
+ attr_writer :test_log, :_cleanups, :basedir, :rundir, :tmpdir
43
+ def initialize
44
+ @test_log = ""
45
+ @background_pids = []
46
+ @_cleanups = []
47
+ _enter_rundir()
48
+ _save_environment()
49
+ add_cleanup(:teardown)
50
+ end
51
+
52
+ # --------------------------------------------------
53
+ # Save and restore directory
54
+ def _enter_rundir
55
+ @basedir = Dir.getwd
56
+ self.add_cleanup(:_restore_directory)
57
+ @rundir = File.join(self.basedir,
58
+ 'testtmp',
59
+ self.class.name)
60
+ @tmpdir = File.join(@rundir, 'tmp')
61
+ system("rm -fr %s" % @rundir)
62
+ FileUtils.mkdir_p(@tmpdir)
63
+ system("mkdir -p %s" % @rundir)
64
+ Dir.chdir(@rundir)
65
+ end
66
+
67
+ def _restore_directory
68
+ Dir.chdir(@basedir)
69
+ end
70
+
71
+ # --------------------------------------------------
72
+ # Save and restore environment
73
+ def _save_environment
74
+ @_saved_environ = ENV.to_hash
75
+ #ENV.each do |key, val|
76
+ # @_saved_environ[key] = val
77
+ #end
78
+ add_cleanup(:_restore_environment)
79
+ end
80
+
81
+ def _restore_environment
82
+ ENV.clear()
83
+ ENV.update(@_saved_environ)
84
+ end
85
+
86
+ def setup
87
+ #"""Set up test fixture."""
88
+ end
89
+
90
+ def teardown
91
+ #"""Tear down test fixture."""
92
+ end
93
+
94
+ def runtest
95
+ #"""Run the test."""
96
+ end
97
+
98
+ def add_cleanup(methodname, obj = self)
99
+ #"""Queue a cleanup to be run when the test is complete."""
100
+ @_cleanups << obj.method(methodname)
101
+ end
102
+
103
+ def fail(reason = "")
104
+ #"""Say the test failed."""
105
+ raise AssertionError, reason
106
+ end
107
+
108
+ #############################################################
109
+ # Requisition methods
110
+
111
+ def require( predicate, message)
112
+ #"""Check a predicate for running this test.
113
+
114
+ #If the predicate value is not true, the test is skipped with a message explaining
115
+ #why."""
116
+ raise NotRunError, message unless predicate
117
+ end
118
+
119
+ def require_root
120
+ #"""Skip this test unless run by root."""
121
+ self.require(Process.uid == 0, "must be root to run this test")
122
+ end
123
+
124
+ #############################################################
125
+ # Assertion methods
126
+
127
+ def assert_(expr, reason = "")
128
+ raise AssertionError, reason unless expr
129
+ end
130
+
131
+ def assert_equal(a, b)
132
+ raise AssertionError, "assertEquals failed: %s, %s" % [a, b] unless (a == b)
133
+ end
134
+
135
+ def assert_notequal(a, b)
136
+ raise AssertionError, "assertNotEqual failed: %s, %s" % [a, b] if (a == b)
137
+ end
138
+
139
+ def assert_re_match(pattern, s)
140
+ #"""Assert that a string *contains* a particular pattern
141
+
142
+ #Inputs:
143
+ #pattern string: regular expression
144
+ #s string: to be searched
145
+
146
+ #Raises:
147
+ #AssertionError if not matched
148
+ #"""
149
+ unless Regexp.new(pattern).match(s)
150
+ raise AssertionError, "string does not contain regexp\n string: %s\n re: %s" % [s, pattern]
151
+ end
152
+ end
153
+
154
+ def assert_no_file(filename)
155
+ if File.exists?(filename)
156
+ raise AssertionError, "file exists but should not: %s" % filename
157
+ end
158
+ end
159
+
160
+ #############################################################
161
+ # Methods for running programs
162
+
163
+ def runcmd_background(cmd)
164
+ self.test_log = self.test_log + "Run in background:\n#{cmd}\n"
165
+ pid = fork()
166
+ if pid.nil?
167
+ # child
168
+ begin
169
+ exec("/bin/sh", "-c", cmd)
170
+ ensure
171
+ exit!(127)
172
+ end
173
+ end
174
+ self.test_log = self.test_log + "pid: %d\n" % pid
175
+ return pid
176
+ end
177
+
178
+ def runcmd(cmd, expectedResult = 0)
179
+ #"""Run a command, fail if the command returns an unexpected exit
180
+ #code. Return the output produced."""
181
+ rc, output, stderr = self.runcmd_unchecked(cmd)
182
+ unless rc == expectedResult
183
+ raise AssertionError, "command returned %d; expected %s: \"%s\"\nstdout:\n%s\nstderr:\n%s""" % [rc, expectedResult, cmd, output, stderr]
184
+ end
185
+ return output, stderr
186
+ end
187
+
188
+ def run_captured(cmd)
189
+ #"""Run a command, capturing stdout and stderr.
190
+ #
191
+ #Based in part on popen2.py
192
+ #
193
+ #Returns (waitstatus, stdout, stderr)."""
194
+ pid = fork()
195
+ if pid.nil?
196
+ # child
197
+ begin
198
+ pid = Process.pid
199
+ openmode = FILE::O_WRONLY|FILE::O_CREAT|FILE::O_TRUNC
200
+
201
+ outfd = File.open('%d.out' % pid, openmode, 0666)
202
+ $stdout.reopen(outfd)
203
+
204
+ errfd = File.open('%d.err' % pid, openmode, 0666)
205
+ $stderr.reopen(errfd)
206
+
207
+ if cmd.is_a?(String)
208
+ cmd = ['/bin/sh', '-c', cmd]
209
+ end
210
+ exec(*cmd)
211
+ ensure
212
+ exit!(127)
213
+ end
214
+ else
215
+ # parent
216
+ exited_pid, waitstatus = Process.waitpid2(pid, 0)
217
+ stdout = File.open('%d.out' % pid)
218
+ stderr = File.open('%d.err' % pid)
219
+ return waitstatus, stdout, stderr
220
+
221
+ end
222
+ end
223
+
224
+ def runcmd_unchecked(cmd, skip_on_noexec = 0)
225
+ #"""Invoke a command; return (exitcode, stdout, stderr)"""
226
+ waitstatus, stdout, stderr = self.run_captured(cmd)
227
+ if waitstatus.signaled?
228
+ raise AssertionError, "%s terminated with signal %d" % [cmd, os.waitstatus.termsig]
229
+ end
230
+ rc = waitstatus.exitstatus
231
+ self.test_log = self.test_log + "Run command: %s\nWait status: %#x (exit code %d, signal %d)\nstdout:\n%s\nstderr:\n%s" % [cmd, waitstatus, waitstatus, waitstatus.termsig, stdout, stderr]
232
+ if skip_on_noexec and rc == 127
233
+ # Either we could not execute the command or the command
234
+ # returned exit code 127. According to system(3) we can't
235
+ # tell the difference.
236
+ raise NotRunError, "could not execute %s" % cmd
237
+ end
238
+ return rc, stdout, stderr
239
+ end
240
+
241
+ def explain_failure(exc_info = nil)
242
+ print "test_log:\n"
243
+ print test_log, "\n"
244
+ end
245
+
246
+ def log(msg)
247
+ #"""Log a message to the test log. This message is displayed if
248
+ #the test fails, or when the runtests function is invoked with
249
+ #the verbose option."""
250
+ self.test_log = self.test_log + msg + "\n" unless msg.nil?
251
+ end
252
+ end
253
+
254
+ class AssertionError < Exception; end
255
+ class NotRunError < Exception
256
+ #"""Raised if a test must be skipped because of missing resources"""
257
+ attr :value
258
+ def initialize(value = nil)
259
+ @value = value
260
+ end
261
+ end
262
+
263
+ def Comfychair._report_error(testcase, ex, debugger)
264
+ #"""Ask the test case to explain failure, and optionally run a debugger
265
+
266
+ #Input:
267
+ #testcase TestCase instance
268
+ #debugger if true, a debugger function to be applied to the traceback
269
+ #"""
270
+ print "-----------------------------------------------------------------\n"
271
+ unless ex.nil?
272
+ print ex, "\n"
273
+ ex.backtrace.each do |line|
274
+ print line, "\n"
275
+ end
276
+ testcase.explain_failure()
277
+ print "-----------------------------------------------------------------\n"
278
+ end
279
+ if debugger
280
+ #tb = ex[2]
281
+ #debugger(tb)
282
+ end
283
+ end
284
+
285
+ def Comfychair.runtests(test_list, verbose = false, debugger = nil, quiet = false)
286
+ # """Run a series of tests.
287
+
288
+ # Inputs:
289
+ # test_list sequence of TestCase classes
290
+ # verbose print more information as testing proceeds
291
+ # debugger debugger object to be applied to errors
292
+
293
+ # Returns:
294
+ # unix return code: 0 for success, 1 for failures, 2 for test failure
295
+ # """
296
+ ret = 0
297
+ test_list.each do |test_class|
298
+ print "%-30s" % Comfychair._test_name(test_class)
299
+ # flush now so that long running tests are easier to follow
300
+ STDOUT.flush
301
+
302
+ obj = nil
303
+ begin
304
+ begin # run test and show result
305
+ obj = test_class.new
306
+ obj.setup()
307
+ obj.runtest()
308
+ print "OK\n"
309
+ # rescue KeyboardInterrupt => ex
310
+ # print "INTERRUPT\n"
311
+ # Comfychair._report_error(obj, ex, debugger) unless quiet
312
+ # ret = 2
313
+ # break
314
+ rescue NotRunError => msg
315
+ print "NOTRUN, %s\n" % msg.value
316
+ rescue Exception => ex
317
+ print "FAIL\n"
318
+ Comfychair._report_error(obj, ex, debugger) unless quiet
319
+ ret = 1
320
+ end
321
+ ensure
322
+ while obj and !obj._cleanups.empty?
323
+ begin
324
+ obj._cleanups.pop().call
325
+ # rescue KeyboardInterrupt => ex
326
+ # print "interrupted during teardown\n"
327
+ # Comfychair._report_error(obj, ex, debugger)
328
+ # ret = 2
329
+ # break
330
+ rescue => ex
331
+ print "error during teardown\n"
332
+ Comfychair._report_error(obj, ex, debugger) unless quiet
333
+ ret = 1
334
+ end
335
+ end
336
+ end
337
+ # Display log file if we're verbose
338
+ obj.explain_failure() if ret == 0 and verbose
339
+ end
340
+ return ret
341
+ end
342
+
343
+ def Comfychair._test_name(test_class)
344
+ #"""Return a human-readable name for a test class.
345
+ #"""
346
+ begin
347
+ return test_class.name
348
+ rescue
349
+ return test_class
350
+ end
351
+ end
352
+
353
+ def Comfychair.print_help()
354
+ #"""Help for people running tests"""
355
+ msg = <<END
356
+ : software test suite based on ComfyChair
357
+
358
+ usage:
359
+ To run all tests, just run this program. To run particular tests,
360
+ list them on the command line.
361
+
362
+ options:
363
+ --help show usage message
364
+ --list list available tests
365
+ --verbose, -v show more information while running tests
366
+ END
367
+ # --post-mortem, -p enter Python debugger on error
368
+ print $0, msg
369
+ end
370
+
371
+ def Comfychair.print_list(test_list)
372
+ #"""Show list of available tests"""
373
+ test_list.each do |test_class|
374
+ print " %s\n" % Comfychair._test_name(test_class)
375
+ end
376
+ end
377
+
378
+ def Comfychair.main(tests, extra_tests=[])
379
+ # """Main entry point for test suites based on ComfyChair.
380
+
381
+ # inputs:
382
+ # tests Sequence of TestCase subclasses to be run by default.
383
+ # extra_tests Sequence of TestCase subclasses that are available but
384
+ # not run by default.
385
+
386
+ # Test suites should contain this boilerplate:
387
+
388
+ # if __FILE__ == $0
389
+ # Comfychair.main(tests)
390
+
391
+ # This function handles standard options such as --help and --list, and
392
+ # by default runs all tests in the suggested order.
393
+
394
+ # Calls sys.exit() on completion.
395
+ #"""
396
+ opt_verbose = false
397
+ opt_quiet = false
398
+ debugger = nil
399
+
400
+ opts = GetoptLong.new(
401
+ [ '--help', GetoptLong::NO_ARGUMENT ],
402
+ [ '--list', GetoptLong::NO_ARGUMENT ],
403
+ [ '--verbose', '-v', GetoptLong::NO_ARGUMENT ],
404
+ [ '--post-mortem', '-p', GetoptLong::NO_ARGUMENT ],
405
+ [ '--quiet', '-q', GetoptLong::NO_ARGUMENT ])
406
+
407
+ opts.each do |opt, opt_arg|
408
+ case opt
409
+ when '--help'
410
+ Comfychair.print_help()
411
+ return
412
+ when '--list'
413
+ Comfychair.print_list(tests + extra_tests)
414
+ return
415
+ when '--verbose'
416
+ opt_verbose = true
417
+ when '--post-mortem'
418
+ # anything similar for ruby?
419
+ #import pdb
420
+ #debugger = pdb.post_mortem
421
+ raise ArgumentError, "--post-mortem not supported for Ruby"
422
+ when '--quiet'
423
+ opt_quiet = true unless opt_verbose
424
+ end
425
+ end
426
+ unless ARGV.empty?
427
+ all_tests = tests + extra_tests
428
+ by_name = {}
429
+ all_tests.each { |t| by_name[Comfychair._test_name(t)] = t}
430
+ which_tests = []
431
+ ARGV.each { |name| which_tests << by_name[name]}
432
+ else
433
+ which_tests = tests
434
+ end
435
+
436
+ exit(Comfychair.runtests(which_tests, opt_verbose, debugger, opt_quiet))
437
+ end
438
+ end
439
+
440
+ if __FILE__ == $0
441
+ print COMFYCHAIRDOC, "\n"
442
+ end
@@ -0,0 +1,56 @@
1
+ #!/bin/sh
2
+
3
+ # Parse command line
4
+
5
+ usage() {
6
+ echo "Usage: runtests.sh [-p RUBY] [-- ARGS]"
7
+ echo ""
8
+ echo "Where RUBY is the ruby binary to use (default 'ruby')"
9
+ echo "and ARGS are passed as command line parameters to the test"
10
+ echo "scripts. (The '--' must separate runtest parameters from"
11
+ echo "test script parameters)."
12
+ }
13
+
14
+ RUBY="ruby"
15
+
16
+ while getopts "p:" options; do
17
+ case $options in
18
+ p) RUBY=$OPTARG
19
+ ;;
20
+ ?) usage
21
+ exit 1
22
+ ;;
23
+ esac
24
+ done
25
+
26
+ shift `expr $OPTIND - 1`
27
+
28
+ if [ "$1" = "all" ]; then
29
+ RUBY="ruby"
30
+ fi
31
+
32
+ # Run tests
33
+
34
+ failed=0
35
+
36
+ for test in test_*.rb; do
37
+ for ruby in $RUBY; do
38
+ echo ====================
39
+ echo $ruby $test
40
+ echo ====================
41
+ $ruby $test "$@"
42
+ if [ $? != 0 ]; then
43
+ failed=1
44
+ break
45
+ fi
46
+ done
47
+ done
48
+
49
+ # Display a message and set exit code appropriately
50
+
51
+ if [ $failed = 1 ]; then
52
+ echo TESTS FAILED
53
+ exit $failed
54
+ fi
55
+
56
+ echo TESTS PASSED