trepanning 0.0.4

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.
Files changed (219) hide show
  1. data/ChangeLog +4422 -0
  2. data/LICENSE +23 -0
  3. data/NEWS +12 -0
  4. data/README.textile +56 -0
  5. data/Rakefile +171 -0
  6. data/app/Makefile +7 -0
  7. data/app/breakpoint.rb +157 -0
  8. data/app/brkptmgr.rb +149 -0
  9. data/app/condition.rb +22 -0
  10. data/app/core.rb +203 -0
  11. data/app/default.rb +54 -0
  12. data/app/disassemble.rb +61 -0
  13. data/app/display.rb +148 -0
  14. data/app/file.rb +135 -0
  15. data/app/frame.rb +275 -0
  16. data/app/irb.rb +112 -0
  17. data/app/mock.rb +22 -0
  18. data/app/options.rb +122 -0
  19. data/app/run.rb +95 -0
  20. data/app/thread.rb +24 -0
  21. data/app/util.rb +32 -0
  22. data/bin/trepan +63 -0
  23. data/data/custom_require.rb +44 -0
  24. data/data/irbrc +55 -0
  25. data/data/prelude.rb +38 -0
  26. data/interface/base_intf.rb +95 -0
  27. data/interface/script.rb +103 -0
  28. data/interface/user.rb +90 -0
  29. data/io/base_io.rb +92 -0
  30. data/io/input.rb +111 -0
  31. data/io/string_array.rb +155 -0
  32. data/lib/Makefile +7 -0
  33. data/lib/trepanning.rb +277 -0
  34. data/processor/breakpoint.rb +108 -0
  35. data/processor/command/alias.rb +55 -0
  36. data/processor/command/backtrace.rb +95 -0
  37. data/processor/command/base/cmd.rb +97 -0
  38. data/processor/command/base/subcmd.rb +207 -0
  39. data/processor/command/base/submgr.rb +178 -0
  40. data/processor/command/base/subsubcmd.rb +102 -0
  41. data/processor/command/base/subsubmgr.rb +182 -0
  42. data/processor/command/break.rb +85 -0
  43. data/processor/command/condition.rb +64 -0
  44. data/processor/command/continue.rb +61 -0
  45. data/processor/command/debug.rb +85 -0
  46. data/processor/command/delete.rb +54 -0
  47. data/processor/command/directory.rb +43 -0
  48. data/processor/command/disable.rb +65 -0
  49. data/processor/command/disassemble.rb +103 -0
  50. data/processor/command/display.rb +81 -0
  51. data/processor/command/down.rb +56 -0
  52. data/processor/command/enable.rb +43 -0
  53. data/processor/command/exit.rb +54 -0
  54. data/processor/command/finish.rb +81 -0
  55. data/processor/command/frame.rb +117 -0
  56. data/processor/command/help.rb +146 -0
  57. data/processor/command/info.rb +28 -0
  58. data/processor/command/info_subcmd/args.rb +56 -0
  59. data/processor/command/info_subcmd/breakpoints.rb +162 -0
  60. data/processor/command/info_subcmd/file.rb +162 -0
  61. data/processor/command/info_subcmd/frame.rb +39 -0
  62. data/processor/command/info_subcmd/iseq.rb +83 -0
  63. data/processor/command/info_subcmd/locals.rb +88 -0
  64. data/processor/command/info_subcmd/program.rb +54 -0
  65. data/processor/command/info_subcmd/registers.rb +72 -0
  66. data/processor/command/info_subcmd/registers_subcmd/dfp.rb +38 -0
  67. data/processor/command/info_subcmd/registers_subcmd/helper.rb +40 -0
  68. data/processor/command/info_subcmd/registers_subcmd/lfp.rb +54 -0
  69. data/processor/command/info_subcmd/registers_subcmd/pc.rb +44 -0
  70. data/processor/command/info_subcmd/registers_subcmd/sp.rb +75 -0
  71. data/processor/command/info_subcmd/return.rb +40 -0
  72. data/processor/command/info_subcmd/thread.rb +106 -0
  73. data/processor/command/irb.rb +106 -0
  74. data/processor/command/kill.rb +58 -0
  75. data/processor/command/list.rb +327 -0
  76. data/processor/command/macro.rb +65 -0
  77. data/processor/command/next.rb +89 -0
  78. data/processor/command/nocache.rb +33 -0
  79. data/processor/command/print.rb +37 -0
  80. data/processor/command/ps.rb +40 -0
  81. data/processor/command/quit.rb +62 -0
  82. data/processor/command/raise.rb +47 -0
  83. data/processor/command/reload.rb +28 -0
  84. data/processor/command/reload_subcmd/command.rb +34 -0
  85. data/processor/command/restart.rb +57 -0
  86. data/processor/command/save.rb +60 -0
  87. data/processor/command/set.rb +47 -0
  88. data/processor/command/set_subcmd/auto.rb +27 -0
  89. data/processor/command/set_subcmd/auto_subcmd/eval.rb +67 -0
  90. data/processor/command/set_subcmd/auto_subcmd/irb.rb +49 -0
  91. data/processor/command/set_subcmd/auto_subcmd/list.rb +51 -0
  92. data/processor/command/set_subcmd/basename.rb +39 -0
  93. data/processor/command/set_subcmd/debug.rb +27 -0
  94. data/processor/command/set_subcmd/debug_subcmd/dbgr.rb +49 -0
  95. data/processor/command/set_subcmd/debug_subcmd/except.rb +35 -0
  96. data/processor/command/set_subcmd/debug_subcmd/macro.rb +35 -0
  97. data/processor/command/set_subcmd/debug_subcmd/skip.rb +35 -0
  98. data/processor/command/set_subcmd/debug_subcmd/stack.rb +45 -0
  99. data/processor/command/set_subcmd/different.rb +67 -0
  100. data/processor/command/set_subcmd/events.rb +71 -0
  101. data/processor/command/set_subcmd/max.rb +35 -0
  102. data/processor/command/set_subcmd/max_subcmd/list.rb +50 -0
  103. data/processor/command/set_subcmd/max_subcmd/stack.rb +60 -0
  104. data/processor/command/set_subcmd/max_subcmd/string.rb +53 -0
  105. data/processor/command/set_subcmd/max_subcmd/width.rb +50 -0
  106. data/processor/command/set_subcmd/return.rb +66 -0
  107. data/processor/command/set_subcmd/sp.rb +62 -0
  108. data/processor/command/set_subcmd/substitute.rb +25 -0
  109. data/processor/command/set_subcmd/substitute_subcmd/eval.rb +98 -0
  110. data/processor/command/set_subcmd/substitute_subcmd/path.rb +55 -0
  111. data/processor/command/set_subcmd/substitute_subcmd/string.rb +72 -0
  112. data/processor/command/set_subcmd/timer.rb +68 -0
  113. data/processor/command/set_subcmd/trace.rb +43 -0
  114. data/processor/command/set_subcmd/trace_subcmd/buffer.rb +56 -0
  115. data/processor/command/set_subcmd/trace_subcmd/print.rb +54 -0
  116. data/processor/command/set_subcmd/trace_subcmd/var.rb +61 -0
  117. data/processor/command/show.rb +27 -0
  118. data/processor/command/show_subcmd/alias.rb +50 -0
  119. data/processor/command/show_subcmd/args.rb +50 -0
  120. data/processor/command/show_subcmd/auto.rb +27 -0
  121. data/processor/command/show_subcmd/auto_subcmd/eval.rb +38 -0
  122. data/processor/command/show_subcmd/auto_subcmd/irb.rb +34 -0
  123. data/processor/command/show_subcmd/auto_subcmd/list.rb +36 -0
  124. data/processor/command/show_subcmd/basename.rb +28 -0
  125. data/processor/command/show_subcmd/debug.rb +27 -0
  126. data/processor/command/show_subcmd/debug_subcmd/dbgr.rb +31 -0
  127. data/processor/command/show_subcmd/debug_subcmd/except.rb +33 -0
  128. data/processor/command/show_subcmd/debug_subcmd/macro.rb +32 -0
  129. data/processor/command/show_subcmd/debug_subcmd/skip.rb +33 -0
  130. data/processor/command/show_subcmd/debug_subcmd/stack.rb +32 -0
  131. data/processor/command/show_subcmd/different.rb +37 -0
  132. data/processor/command/show_subcmd/events.rb +40 -0
  133. data/processor/command/show_subcmd/macro.rb +45 -0
  134. data/processor/command/show_subcmd/max.rb +31 -0
  135. data/processor/command/show_subcmd/max_subcmd/list.rb +39 -0
  136. data/processor/command/show_subcmd/max_subcmd/stack.rb +35 -0
  137. data/processor/command/show_subcmd/max_subcmd/string.rb +41 -0
  138. data/processor/command/show_subcmd/max_subcmd/width.rb +36 -0
  139. data/processor/command/show_subcmd/trace.rb +29 -0
  140. data/processor/command/show_subcmd/trace_subcmd/buffer.rb +84 -0
  141. data/processor/command/show_subcmd/trace_subcmd/print.rb +38 -0
  142. data/processor/command/source.rb +74 -0
  143. data/processor/command/step.rb +139 -0
  144. data/processor/command/stepi.rb +63 -0
  145. data/processor/command/unalias.rb +44 -0
  146. data/processor/command/undisplay.rb +63 -0
  147. data/processor/command/up.rb +92 -0
  148. data/processor/default.rb +45 -0
  149. data/processor/display.rb +17 -0
  150. data/processor/eval.rb +88 -0
  151. data/processor/eventbuf.rb +131 -0
  152. data/processor/frame.rb +230 -0
  153. data/processor/help.rb +72 -0
  154. data/processor/hook.rb +128 -0
  155. data/processor/load_cmds.rb +102 -0
  156. data/processor/location.rb +126 -0
  157. data/processor/main.rb +364 -0
  158. data/processor/mock.rb +100 -0
  159. data/processor/msg.rb +26 -0
  160. data/processor/running.rb +170 -0
  161. data/processor/subcmd.rb +159 -0
  162. data/processor/validate.rb +395 -0
  163. data/test/example/fname with blank.rb +1 -0
  164. data/test/example/gcd-xx.rb +18 -0
  165. data/test/example/gcd.rb +19 -0
  166. data/test/example/gcd1.rb +24 -0
  167. data/test/example/null.rb +1 -0
  168. data/test/example/thread1.rb +3 -0
  169. data/test/functional/fn_helper.rb +119 -0
  170. data/test/functional/test-break.rb +87 -0
  171. data/test/functional/test-condition.rb +59 -0
  172. data/test/functional/test-debugger-call-bug.rb +31 -0
  173. data/test/functional/test-delete.rb +71 -0
  174. data/test/functional/test-finish.rb +44 -0
  175. data/test/functional/test-immediate-step-bug.rb +35 -0
  176. data/test/functional/test-next.rb +77 -0
  177. data/test/functional/test-raise.rb +73 -0
  178. data/test/functional/test-return.rb +100 -0
  179. data/test/functional/test-step.rb +274 -0
  180. data/test/functional/test-stepbug.rb +40 -0
  181. data/test/functional/test-trace-var.rb +40 -0
  182. data/test/functional/tmp/b1.rb +5 -0
  183. data/test/functional/tmp/s1.rb +9 -0
  184. data/test/functional/tmp/t2.rb +6 -0
  185. data/test/integration/file-diff.rb +88 -0
  186. data/test/integration/helper.rb +52 -0
  187. data/test/integration/test-fname-with-blank.rb +11 -0
  188. data/test/integration/test-quit.rb +11 -0
  189. data/test/integration/try-test-enable.rb +11 -0
  190. data/test/unit/cmd-helper.rb +44 -0
  191. data/test/unit/test-app-brkpt.rb +30 -0
  192. data/test/unit/test-app-brkptmgr.rb +56 -0
  193. data/test/unit/test-app-disassemble.rb +60 -0
  194. data/test/unit/test-app-file.rb +46 -0
  195. data/test/unit/test-app-frame.rb +49 -0
  196. data/test/unit/test-app-options.rb +60 -0
  197. data/test/unit/test-app-run.rb +19 -0
  198. data/test/unit/test-app-thread.rb +25 -0
  199. data/test/unit/test-app-util.rb +17 -0
  200. data/test/unit/test-base-subcmd.rb +59 -0
  201. data/test/unit/test-bin-trepan.rb +48 -0
  202. data/test/unit/test-cmd-alias.rb +50 -0
  203. data/test/unit/test-cmd-break.rb +80 -0
  204. data/test/unit/test-cmd-endisable.rb +59 -0
  205. data/test/unit/test-cmd-help.rb +100 -0
  206. data/test/unit/test-cmd-kill.rb +47 -0
  207. data/test/unit/test-cmd-quit.rb +26 -0
  208. data/test/unit/test-cmd-step.rb +45 -0
  209. data/test/unit/test-intf-user.rb +45 -0
  210. data/test/unit/test-io-input.rb +26 -0
  211. data/test/unit/test-proc-eval.rb +26 -0
  212. data/test/unit/test-proc-frame.rb +77 -0
  213. data/test/unit/test-proc-help.rb +15 -0
  214. data/test/unit/test-proc-hook.rb +29 -0
  215. data/test/unit/test-proc-load_cmds.rb +40 -0
  216. data/test/unit/test-proc-main.rb +99 -0
  217. data/test/unit/test-proc-validate.rb +90 -0
  218. data/test/unit/test-subcmd-help.rb +48 -0
  219. metadata +358 -0
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env ruby
2
+ require 'test/unit'
3
+ require_relative '../../app/disassemble'
4
+
5
+ # Test Trepan::CmdProcessor
6
+ class TestAppDisassemble < Test::Unit::TestCase
7
+
8
+ include Trepan::Disassemble
9
+
10
+ def setup
11
+ @dis_string='
12
+ local table (size: 6, argc: 1 [opts: 0, rest: -1, post: 0, block: -1] s1)
13
+ [ 6] relative_feature<Arg>[ 5] c [ 4] e [ 3] file [ 2] absolute_feature
14
+ 0000 trace 8 ( 26)
15
+ 0002 trace 1 ( 27)
16
+ 0004 putnil
17
+ '
18
+ end
19
+
20
+ def test_mark_dissassembly
21
+ # Check marking pc offset.
22
+ [[-1, -1], [1, -1], [2, 4], [10, -1]].each do |pc_offset, pos|
23
+ ary = mark_disassembly(@dis_string, true, pc_offset)
24
+ selected = ary.select{|line| line =~ /\d{4} / && line !~ /^ /}
25
+ if pos == -1
26
+ assert_equal([], selected,
27
+ 'All lines should not be marked')
28
+ else
29
+ assert_equal(1, selected.size,
30
+ "Should have found exectly one PC mark at #{pos}" +
31
+ "\n%s" % ary.join("\n"))
32
+ assert_equal(0, ary[pos] =~ /^ --> /,
33
+ "Should have marked PC at position #{pos}" +
34
+ "\n%s" % ary.join("\n"))
35
+ end
36
+ end
37
+
38
+ # Check marking breakpoints.
39
+
40
+ [[2, []], [2, [2]], [10, [0, 4]]].each do |pc_offset, brkpts|
41
+ ary = mark_disassembly(@dis_string, true, pc_offset, brkpts)
42
+ selected = ary.select{|line| line =~ /\d{4} / && line !~ /^ /}
43
+ assert_equal(brkpts.size, selected.size,
44
+ "Should have found #{brkpts.size} lines " +
45
+ "at #{brkpts.join(',')}" +
46
+ ("\n%s" % ary.join("\n")))
47
+ end
48
+ end
49
+
50
+ def test_disassemble_split
51
+ expect = {
52
+ 0=>
53
+ "0000 trace 8 ( 26)",
54
+ 2=>
55
+ "0002 trace 1 ( 27)",
56
+ 4=>"0004 putnil "
57
+ }
58
+ assert_equal(expect, disassemble_split(@dis_string))
59
+ end
60
+ end
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env ruby
2
+ require 'test/unit'
3
+ require_relative '../../app/file'
4
+
5
+ if defined?(SCRIPT_ISEQS__) && SCRIPT_ISEQS__.is_a?(Hash)
6
+ SCRIPT_ISEQS__.clear
7
+ else
8
+ SCRIPT_ISEQS__ = {}
9
+ end
10
+ if defined?(ISEQS__) && ISEQS__.is_a?(Hash)
11
+ ISEQS__.clear
12
+ else
13
+ ISEQS__ = {}
14
+ end
15
+
16
+ # To have something to work with.
17
+ load 'tmpdir.rb'
18
+
19
+ class TestAppFile < Test::Unit::TestCase
20
+ include Trepanning
21
+
22
+ def test_file_match_pat
23
+ assert_equal('(?:^|[/])abc\.rb$', file_match_pat('abc.rb'))
24
+ assert_equal('^/a/abc\.rb$', file_match_pat('/a/abc.rb'))
25
+ end
26
+
27
+ def test_find_iseqs
28
+ iseqs = find_iseqs(ISEQS__, "tmpdir")
29
+ assert_equal(false, iseqs.empty?)
30
+ iseqs = find_iseqs(ISEQS__, "tmpdir@#{__FILE__}")
31
+ assert_equal(true, iseqs.empty?)
32
+ iseqs = find_iseqs(ISEQS__, "tmpdir@tmpdir.rb")
33
+ assert_equal(false, iseqs.empty?)
34
+ end
35
+
36
+ def test_find_scripts
37
+ [['tmpdir.rb', true], ['/tmpdir.rb', false],
38
+ ['sometmpdir.rb', false]].each do
39
+ |filename, expected|
40
+ found = find_scripts(filename)
41
+ assert_equal(expected, !found.empty?,
42
+ "Should %shave found %s; got %s" %
43
+ [expected ? '' : 'not ', filename, found.inspect])
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env ruby
2
+ require 'test/unit'
3
+ require_relative '../../app/frame'
4
+ require 'thread_frame'
5
+
6
+ class TestAppFrame < Test::Unit::TestCase
7
+
8
+ include Trepan::Frame
9
+
10
+ def test_app_frame
11
+ frame = RubyVM::ThreadFrame.current
12
+ base_count = frame.stack_size
13
+ s = format_stack_entry(frame)
14
+ pat = /^METHOD .*#test_app_frame\(\) in file .*test-app-frame.rb at line \d+/
15
+ assert(s =~ pat, "got #{s}, expected pat #{pat}")
16
+ 1.times do
17
+ assert_equal(base_count+2, RubyVM::ThreadFrame.current.stack_size)
18
+ s = format_stack_entry(frame)
19
+ assert(s =~ pat, "got #{s}, expected pat #{pat}")
20
+ end
21
+
22
+ def inner_test(count)
23
+ frame = RubyVM::ThreadFrame.current
24
+ assert_equal(count, frame.stack_size)
25
+
26
+ s = format_stack_entry(frame)
27
+ pat = /^METHOD .*#inner_test\(count\) in file .*test-app-frame.rb at line \d+/
28
+ assert(s =~ pat, "got: #{s.inspect},\nexpected: pat #{pat}")
29
+
30
+ s = format_stack_entry(frame, :basename => true)
31
+ pat = /^METHOD .*#inner_test\(count\) in file test-app-frame.rb at line \d+/
32
+ assert(s =~ pat, "got: #{s.inspect},\nexpected: pat #{pat}")
33
+
34
+ s = format_stack_entry(frame, :basename => true, :show_pc => true)
35
+ pat = /^METHOD .*#inner_test\(count\) in file test-app-frame.rb at line \d+, pc: \d+/
36
+ assert(s =~ pat, "got: #{s.inspect},\nexpected: pat #{pat}")
37
+ end
38
+ inner_test(base_count+1)
39
+ end
40
+
41
+ def test_return
42
+ assert_equal(1, offset_for_return('return'))
43
+ assert_equal(2, offset_for_return('c-return'))
44
+ assert_raises RuntimeError do
45
+ offset_for_return('c-call')
46
+ end
47
+ end
48
+
49
+ end
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env ruby
2
+ require 'test/unit'
3
+ require 'stringio'
4
+ require 'tempfile'
5
+ require_relative '../../app/options'
6
+
7
+ # To have something to work with.
8
+ load 'tmpdir.rb'
9
+
10
+ class TestAppStringIO < Test::Unit::TestCase
11
+ include Trepanning
12
+
13
+ def setup
14
+ @options = DEFAULT_CMDLINE_SETTINGS.clone
15
+ @stderr = StringIO.new
16
+ @stdout = StringIO.new
17
+ @options = copy_default_options
18
+ @opts = setup_options(@options, @stdout, @stderr)
19
+ end
20
+
21
+ def test_cd
22
+ rest = @opts.parse(['--cd', Dir.tmpdir])
23
+ assert_equal(Dir.tmpdir, @options[:chdir])
24
+ assert_equal('', @stderr.string)
25
+ assert_equal('', @stdout.string)
26
+
27
+ setup
28
+ tf = Tempfile.new("delete-me")
29
+ orig_cd = @options[:chdir]
30
+ rest = @opts.parse(['--cd', tf.path])
31
+ assert_equal(orig_cd, @options[:chdir])
32
+ assert_not_equal('', @stderr.string)
33
+ assert_equal('', @stdout.string)
34
+ # FIXME: add test where directory isn't executable.
35
+ end
36
+
37
+ def test_binary_opts
38
+ %w(nx).each do |name|
39
+ setup
40
+ o = ["--#{name}"]
41
+ rest = @opts.parse o
42
+ assert_equal('', @stderr.string)
43
+ assert_equal(true, @options[name.to_sym])
44
+ end
45
+ end
46
+
47
+ def test_help_and_version_opts
48
+ %w(help version).each do |name|
49
+ setup
50
+ o = ["--#{name}"]
51
+ rest = @opts.parse o
52
+ assert_not_equal('', @stdout.string)
53
+ assert_equal('', @stderr.string)
54
+ assert_equal(true, @options[name.to_sym])
55
+ other_sym = 'help' == name ? :version : :help
56
+ assert_equal(false, @options.member?(other_sym))
57
+ end
58
+ end
59
+
60
+ end
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+ require 'test/unit'
3
+ require_relative '../../app/run'
4
+
5
+ class TestAppRun < Test::Unit::TestCase
6
+ include Trepanning
7
+ def test_basic
8
+ assert_equal(true, File.executable?(whence_file('irb')))
9
+ ng = whence_file('probably-does-not-exist')
10
+ assert_equal(true, File.executable?(ng) || ng == 'probably-does-not-exist')
11
+ rp = ruby_path
12
+ assert_equal(true, File.executable?(rp))
13
+ tup = explicit_restart_argv(ARGV)
14
+ assert_equal(rp, tup[0])
15
+ assert_equal(true, File.readable?(tup[1]))
16
+ assert_equal(ARGV.size + 2, tup.size)
17
+ end
18
+
19
+ end
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env ruby
2
+ require 'test/unit'
3
+ require_relative '../../app/thread'
4
+
5
+ class TestAppThread < Test::Unit::TestCase
6
+ include Trepan::ThreadHelper
7
+
8
+ def test_basic
9
+ Object::Thread.new do
10
+ th_main = Thread.main
11
+ th_current = Thread.current
12
+ [[ 0, th_main],
13
+ [ 1, th_current],
14
+ [-1, th_current],
15
+ [-2, th_main],
16
+ [2, nil], [-3, nil],
17
+ [Thread.main.object_id, th_main],
18
+ [Thread.current.object_id, th_current]].each do
19
+ |th_num, expected_th|
20
+ assert_equal(expected_th, get_thread(th_num),
21
+ "get_thread(#{th_num}) should be expected")
22
+ end
23
+ end.join
24
+ end
25
+ end
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ require 'test/unit'
3
+ require_relative '../../app/util'
4
+
5
+ class TestAppUtil < Test::Unit::TestCase
6
+ include Trepan::Util
7
+ def test_safe_repr
8
+ string = 'The time has come to talk of many things.'
9
+ assert_equal(string, safe_repr(string, 50))
10
+ assert_equal('The time has come...', safe_repr(string, 17))
11
+ assert_equal('The time has come', safe_repr(string, 17, ''))
12
+ assert_equal('"The time has co"...', safe_repr(string.inspect, 17))
13
+ string = "'The time has come to talk of many things.'"
14
+ assert_equal("'The time has co'...", safe_repr(string, 17))
15
+ end
16
+
17
+ end
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env ruby
2
+ require 'test/unit'
3
+ require_relative '../../app/core'
4
+ require_relative '../../processor/main'
5
+ require_relative '../../processor/command/exit'
6
+ require_relative '../../processor/command/base/subcmd'
7
+
8
+ # Mock debugger stub. FIXME: put in comment helper routine.
9
+ class Trepan
10
+ end
11
+
12
+ $errors = []
13
+ class TestBaseCommandHelp < Test::Unit::TestCase
14
+
15
+ def setup
16
+ $errors = []
17
+ $msgs = []
18
+ @dbg = Trepan.new
19
+ @core = Trepan::Core.new(@dbg)
20
+ @cmdproc = @core.processor = Trepan::CmdProcessor.new(@core)
21
+ @cmds = @cmdproc.instance_variable_get('@commands')
22
+ @exit_cmd = @cmds['exit']
23
+ @exit_subcmd = Trepan::Subcommand.new(@exit_cmd)
24
+ def @exit_subcmd.msg(message)
25
+ $msgs << message
26
+ end
27
+ def @exit_subcmd.errmsg(message)
28
+ $errors << message
29
+ end
30
+ end
31
+
32
+ def test_base_subcommand
33
+ assert @exit_subcmd
34
+ assert_raises RuntimeError do
35
+ @exit_subcmd.run
36
+ end
37
+ assert_equal([], $errors)
38
+ @exit_subcmd.run_set_int('', 'testing 1 2 3')
39
+ assert_equal(1, $errors.size)
40
+ assert_equal(Fixnum, @exit_subcmd.settings[:maxwidth].class)
41
+ @cmds.each do |cmd_name, cmd_obj|
42
+ next unless cmd_obj.is_a?(Trepan::SubcommandMgr)
43
+ cmd_obj.subcmds.subcmds.each do |subcmd_name, subcmd_obj|
44
+ %w(HELP NAME PREFIX).each do |attr|
45
+ assert_equal(true, subcmd_obj.class.constants.member?(attr.to_sym),
46
+ "Constant #{attr} should be defined in \"#{cmd_obj.name} #{subcmd_obj.name}\"")
47
+ end
48
+ end
49
+
50
+ end
51
+ end
52
+
53
+ def test_show_on_off
54
+ assert_equal('on', @exit_subcmd.show_onoff(true))
55
+ assert_equal('off', @exit_subcmd.show_onoff(false))
56
+ assert_equal('unset', @exit_subcmd.show_onoff(nil))
57
+ assert_equal('??', @exit_subcmd.show_onoff(5))
58
+ end
59
+ end
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env ruby
2
+ require 'test/unit'
3
+ require 'rbconfig'
4
+ load File.join(File.dirname(__FILE__), %w(.. .. bin trepan))
5
+
6
+ # Test bin/trepan Module methods
7
+ class TestBinTrepan < Test::Unit::TestCase
8
+
9
+ include Trepanning
10
+
11
+ def test_ruby_path
12
+ rb_path = ruby_path
13
+ assert_equal(true, File.executable?(rb_path),
14
+ "#{rb_path} should be an executable Ruby interpreter")
15
+
16
+ # Let us test that we get *exactly* the same configuration as we
17
+ # have in this. I'm a ball buster.
18
+ cmd = "#{rb_path} -rrbconfig -e 'puts Marshal.dump(RbConfig::CONFIG)'"
19
+ rb_config = Marshal.load(`#{cmd}`)
20
+ assert_equal(RbConfig::CONFIG, rb_config,
21
+ "#{rb_path} config doesn't match got:
22
+ #{rb_config.pretty_inspect}
23
+ expected:
24
+ #{RbConfig::CONFIG.pretty_inspect}
25
+ ")
26
+ end
27
+
28
+ def test_whence_file
29
+ abs_path_me = File.expand_path(__FILE__)
30
+ assert_equal(abs_path_me, whence_file(abs_path_me),
31
+ "whence_file should have just returned #{abs_path_me}")
32
+
33
+ basename_me = File.basename(__FILE__)
34
+ dirname_me = File.dirname(__FILE__)
35
+
36
+ # Add my directory onto the beginning of PATH
37
+ path_dirs = ENV['PATH'].split(File::PATH_SEPARATOR)
38
+ path_dirs.unshift(dirname_me)
39
+ ENV['PATH'] = path_dirs.join(File::PATH_SEPARATOR)
40
+
41
+ assert_equal(File.join(dirname_me, basename_me),
42
+ whence_file(basename_me),
43
+ "whence_file should have found me")
44
+ # Restore old path
45
+ path_dirs.shift
46
+ ENV['PATH'] = path_dirs.join(File::PATH_SEPARATOR)
47
+ end
48
+ end
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env ruby
2
+ require 'test/unit'
3
+ require_relative 'cmd-helper'
4
+ require_relative '../../processor/command/alias'
5
+ require_relative '../../processor/command/unalias'
6
+
7
+ # Test commands alias and unalias
8
+ class TestCommandAliasUnalias < Test::Unit::TestCase
9
+
10
+ include UnitHelper
11
+ def setup
12
+ common_setup
13
+ @name = File.basename(__FILE__, '.rb').split(/-/)[2]
14
+ end
15
+
16
+ def check_alias(should_not_have, cmd_name, *args)
17
+ @cmdproc.instance_variable_set('@msgs', [])
18
+ @cmdproc.instance_variable_set('@errmsgs', [])
19
+ arg_str = args.join(' ')
20
+ my_cmd = @cmds[cmd_name]
21
+ my_cmd.run([cmd_name] + args)
22
+ shoulda = should_not_have ? ['no ', ''] : ['', 'no ']
23
+ msgs = @cmdproc.instance_variable_get('@msgs')
24
+ errmsgs = @cmdproc.instance_variable_get('@errmsgs')
25
+ assert_equal(should_not_have, msgs.empty?,
26
+ "Expecting %s%s for #{arg_str}.\n Got #{msgs}" %
27
+ [shoulda[0], cmd_name])
28
+ assert_equal(!should_not_have, errmsgs.empty?,
29
+ "Expecting %serror for #{arg_str}.\n Got #{errmsgs}" %
30
+ shoulda[1])
31
+ end
32
+
33
+ def alias_defined?(alias_name)
34
+ @cmdproc.aliases.member?(alias_name)
35
+ end
36
+
37
+ def test_alias_command
38
+
39
+ assert_equal(false, @cmdproc.aliases.empty?,
40
+ 'There should be some aliases defined')
41
+
42
+ assert_equal(false, alias_defined?('ki'))
43
+ check_alias(false, 'alias', 'ki', 'kill')
44
+ assert_equal(true, alias_defined?('ki'))
45
+ check_alias(false, 'unalias', 'ki')
46
+ assert_equal(false, alias_defined?('ki'))
47
+
48
+ end
49
+
50
+ end
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env ruby
2
+ require 'test/unit'
3
+ require 'thread_frame'
4
+ require_relative 'cmd-helper'
5
+
6
+ class TestCommandBreak < Test::Unit::TestCase
7
+
8
+ include UnitHelper
9
+ def setup
10
+ common_setup
11
+ @name = File.basename(__FILE__, '.rb').split(/-/)[2]
12
+ @my_cmd = @cmds[@name]
13
+ end
14
+
15
+ def test_basic
16
+ tf = RubyVM::ThreadFrame.current
17
+ @cmdproc.frame_setup(tf)
18
+ [
19
+ [@name, __LINE__.to_s],
20
+ ].each_with_index do |args, i|
21
+ @my_cmd.run(args)
22
+ assert_equal(true, @cmdproc.errmsgs.empty?, @cmdproc.errmsgs)
23
+ assert_equal(0,
24
+ @cmdproc.msgs[0] =~ /^Breakpoint \d+ set at line \d+ in file #{__FILE__},\n\tVM offset \d+ of instruction sequence \"test_basic\"\.$/,
25
+ @cmdproc.msgs[0])
26
+ reset_cmdproc_vars
27
+ end
28
+ pc_offset = tf.pc_offset
29
+ [[@name],
30
+ [@name, "O#{pc_offset}"],
31
+ ].each_with_index do |args, i|
32
+ @my_cmd.run(args)
33
+ assert_equal(true, @cmdproc.errmsgs.empty?, @cmdproc.errmsgs)
34
+ assert_equal(0,
35
+ @cmdproc.msgs[0] =~ /^Breakpoint \d+ set at VM offset \d+ of instruction sequence \"test_basic\",\n\tline \d+ in file .+\.$/,
36
+ @cmdproc.msgs[0])
37
+ reset_cmdproc_vars
38
+ end
39
+
40
+ def foo
41
+ 5
42
+ end
43
+ [[@name, 'foo', (__LINE__-3).to_s]].each_with_index do |args, i|
44
+ @my_cmd.run(args)
45
+ assert_equal(true, @cmdproc.errmsgs.empty?,
46
+ @cmdproc.errmsgs)
47
+ assert_equal(0,
48
+ @cmdproc.msgs[0] =~ /^Breakpoint \d+ set at line \d+ in file #{__FILE__},\n\tVM offset \d+ of instruction sequence \"foo\"\.$/,
49
+ @cmdproc.msgs[0])
50
+ reset_cmdproc_vars
51
+ end
52
+ [[@name, 'foo']].each_with_index do |args, i|
53
+ @my_cmd.run(args)
54
+ assert_equal(true, @cmdproc.errmsgs.empty?,
55
+ @cmdproc.errmsgs)
56
+ assert_equal(0,
57
+ @cmdproc.msgs[0] =~ /Breakpoint \d+ set at line \d+ in file #{__FILE__},\n\tVM offset \d+/,
58
+ @cmdproc.msgs[0])
59
+ reset_cmdproc_vars
60
+ end
61
+ end
62
+
63
+ # Test setting a breakpoint at a line that can only be found using
64
+ # the parent instruction sequence, i.e. the line is not in the
65
+ # current instruction sequence.
66
+ def test_parent_breakpoint
67
+ xx = 5 # This is the line we set the breakpoint for.
68
+ 1.times do
69
+ tf = RubyVM::ThreadFrame.current
70
+ @cmdproc.frame_setup(tf)
71
+ @my_cmd.run([@name, (__LINE__-4).to_s])
72
+ assert_equal(true, @cmdproc.errmsgs.empty?, @cmdproc.errmsgs)
73
+ assert_equal(0,
74
+ @cmdproc.msgs[0] =~ /^Breakpoint \d+ set at line \d+ in file .+\n\tVM offset \d+ of instruction sequence \"test_parent_breakpoint\"\.$/,
75
+ @cmdproc.msgs[0])
76
+ reset_cmdproc_vars
77
+ end
78
+ end
79
+
80
+ end
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env ruby
2
+ require 'test/unit'
3
+ require_relative 'cmd-helper'
4
+ require_relative '../../app/breakpoint'
5
+
6
+ class TestCommandEnableDisable < Test::Unit::TestCase
7
+
8
+ include UnitHelper
9
+ def setup
10
+ Trepanning::Breakpoint::reset
11
+ common_setup
12
+ @break_cmd = @cmds['break']
13
+ @disable_cmd = @cmds['disable']
14
+ @enable_cmd = @cmds['enable']
15
+ end
16
+
17
+ def test_basic
18
+
19
+ # Some simple errors in running enable/disable commands
20
+ [[@enable_cmd, ['enable', '1'], 0, 1],
21
+ [@disable_cmd, ['disable', '1'], 0, 1]].each do
22
+ |cmd, args, nmsgs, nerrs|
23
+ # No breakpoint number given
24
+ cmd.run(args[0..0])
25
+ assert_equal(nmsgs, @cmdproc.msgs.size,
26
+ "#{args} - msgs: #{@cmdproc.msgs.inspect}")
27
+ assert_equal(nerrs, @cmdproc.errmsgs.size,
28
+ "#{args} - errmsgs: #{@cmdproc.errmsgs.inspect}")
29
+ reset_cmdproc_vars
30
+
31
+ # Non-existent breakpoint
32
+ cmd.run(args)
33
+ assert_equal(true, @cmdproc.msgs.empty?)
34
+ assert_equal(1, @cmdproc.errmsgs.size)
35
+ reset_cmdproc_vars
36
+ end
37
+
38
+ require 'thread_frame'
39
+ tf = RubyVM::ThreadFrame.current
40
+ @cmdproc.frame_setup(tf)
41
+ pc_offset = tf.pc_offset
42
+ @break_cmd.run(['break'])
43
+ assert_equal(true, @cmdproc.errmsgs.empty?)
44
+ assert_equal(1, @cmdproc.msgs.size)
45
+ reset_cmdproc_vars
46
+
47
+ @disable_cmd.run(['disable', '1'])
48
+ assert_equal(0,
49
+ @cmdproc.msgs[0] =~ /^Breakpoint 1 disabled./,
50
+ @cmdproc.msgs)
51
+ reset_cmdproc_vars
52
+
53
+ @enable_cmd.run(['enable', '1'])
54
+ assert_equal(0,
55
+ @cmdproc.msgs[0] =~ /^Breakpoint 1 enabled./,
56
+ @cmdproc.msgs)
57
+ end
58
+
59
+ end
@@ -0,0 +1,100 @@
1
+ #!/usr/bin/env ruby
2
+ require 'test/unit'
3
+ require_relative 'cmd-helper'
4
+ require_relative '../../processor/command/help'
5
+
6
+ class TestCommandHelp < Test::Unit::TestCase
7
+
8
+ include UnitHelper
9
+ def setup
10
+ common_setup
11
+ @name = File.basename(__FILE__, '.rb').split(/-/)[2]
12
+ @my_cmd = @cmds[@name]
13
+ end
14
+
15
+ def check_help(should_not_have, *args)
16
+ @cmdproc.instance_variable_set('@msgs', [])
17
+ @cmdproc.instance_variable_set('@errmsgs', [])
18
+ arg_str = args.join(' ')
19
+ @my_cmd.run([@name] + args)
20
+ shoulda = should_not_have ? ['no ', ''] : ['', 'no ']
21
+ msgs = @cmdproc.instance_variable_get('@msgs')
22
+ errmsgs = @cmdproc.instance_variable_get('@errmsgs')
23
+ assert_equal(should_not_have, msgs.empty?,
24
+ "Expecting %shelp for #{arg_str}.\n Got #{msgs}" %
25
+ shoulda[0])
26
+ assert_equal(!should_not_have, errmsgs.empty?,
27
+ "Expecting %serror for #{arg_str}.\n Got #{errmsgs}" %
28
+ shoulda[1])
29
+ end
30
+
31
+ def test_help_command
32
+
33
+ # Test we can run 'help *cmd* for each command
34
+ @cmds.keys.each do |cmd_name|
35
+ check_help(false, cmd_name)
36
+ end
37
+
38
+ # Test we can run 'help *alias* for each alias
39
+ @cmdproc.aliases.keys.each do |alias_name|
40
+ check_help(false, alias_name)
41
+ end
42
+
43
+ # double-check specific commands and aliases
44
+ %w(step n help).each do |cmd_pat|
45
+ check_help(false, cmd_pat)
46
+ end
47
+
48
+ # Test patterns
49
+ %w(* s.* ste).each do |cmd_pat|
50
+ check_help(false, cmd_pat)
51
+ end
52
+
53
+ # Test categories
54
+ %w(running stack).each do |cmd_pat|
55
+ check_help(false, cmd_pat)
56
+ end
57
+
58
+ # Test sub help and subhelp patterns
59
+ [%w(info file), %w(show *)].each do |args|
60
+ check_help(false, args)
61
+ end
62
+
63
+ # Test invalid commands
64
+ %w(bogus abcd.*).each do |cmd_pat|
65
+ check_help(true, cmd_pat)
66
+ end
67
+
68
+ # invalid help subcommands
69
+ [%w(info fdafds), %w(fedafdsa *)].each do |args|
70
+ check_help(true, *args)
71
+ end
72
+
73
+ # screwball error
74
+ check_help(true, '["info",')
75
+
76
+ end
77
+
78
+ # FIXME: Do better than this.
79
+ def check_subcmd_help(cmd_name, subcmd, *args)
80
+ def subcmd.msg(mess)
81
+ @msgs << mess
82
+ end
83
+ subcmd.instance_variable_set('@msgs', [])
84
+ subcmd.instance_variable_set('@errmsgs', [])
85
+ subcmd.help(cmd_name)
86
+ assert subcmd.instance_variable_get('@msgs')
87
+ # subcmd.help
88
+ end
89
+
90
+ def test_help_subcommand
91
+ # Get list of commands with subcmds
92
+ cmd_names = @cmds.values.map do |c|
93
+ c.instance_variable_defined?(:@subcmds) ? c.name : nil
94
+ end.compact
95
+ cmd_names.each do |cmd_name|
96
+ check_subcmd_help(cmd_name, @cmds[cmd_name].subcmds)
97
+ end
98
+ end
99
+
100
+ end