diff options
author | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-08-22 05:12:31 +0000 |
---|---|---|
committer | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-08-22 05:12:31 +0000 |
commit | d28e07d57bc15a4baf08f8f4fb64d27cf927aac7 (patch) | |
tree | bfbf87a7fce23415d5560c611a6943ef61dc30ed /test/ruby/test_settracefunc.rb | |
parent | 22a173df3f462244103a02261c276eeee8926863 (diff) | |
download | ruby-d28e07d57bc15a4baf08f8f4fb64d27cf927aac7.tar.gz |
* vm_trace.c: support TracePoint. [ruby-trunk - Feature #6895]
* test/ruby/test_settracefunc.rb: add tests for above.
* proc.c (rb_binding_new_with_cfp): add an internal function.
* vm.c (rb_vm_control_frame_id_and_class): add an internal function.
* vm_trace.c: add rb_add_event_hook2() and rb_thread_add_event_hook2().
Give us the good name for them!
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36773 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'test/ruby/test_settracefunc.rb')
-rw-r--r-- | test/ruby/test_settracefunc.rb | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/test/ruby/test_settracefunc.rb b/test/ruby/test_settracefunc.rb index 463923aa26..d24bcccd4d 100644 --- a/test/ruby/test_settracefunc.rb +++ b/test/ruby/test_settracefunc.rb @@ -397,4 +397,222 @@ class TestSetTraceFunc < Test::Unit::TestCase class << self define_method(:method_added, Module.method(:method_added)) end + + def test_tracepoint + events = [] + trace = nil + xyzzy = nil + local_var = :outer + eval <<-EOF.gsub(/^.*?: /, ""), nil, 'xyzzy' + 1: trace = TracePoint.trace(){|tp| + 2: events << [tp.event, tp.line, tp.file, tp.klass, tp.id, tp.self, tp.binding.eval("local_var")] + 3: } + 4: 1.times{|;local_var| local_var = :inner + 5: tap{} + 6: } + 7: class XYZZY + 8: local_var = :XYZZY_outer + 9: def foo + 10: local_var = :XYZZY_foo + 11: bar + 12: end + 13: def bar + 14: local_var = :XYZZY_bar + 15: tap{} + 16: end + 17: end + 18: xyzzy = XYZZY.new + 19: xyzzy.foo + 20: trace.untrace + EOF + + events.each{|ev| + STDERR.puts [ev[0], ev[1]].inspect + STDERR.puts ev.inspect + } + + [ + # + [:c_return, 1, "xyzzy", self.class, :trace, TracePoint, :outer], + [:line, 4, 'xyzzy', self.class, :test_tracepoint, self, :outer], + [:c_call, 4, 'xyzzy', Integer, :times, 1, :outer], + [:line, 4, 'xyzzy', self.class, :test_tracepoint, self, nil], + [:line, 5, 'xyzzy', self.class, :test_tracepoint, self, :inner], + [:c_call, 5, 'xyzzy', Kernel, :tap, self, :inner], + [:line, 7, 'xyzzy', self.class, :test_tracepoint, self, :outer], + [:c_call, 7, "xyzzy", Class, :new, TestSetTraceFunc::XYZZY, :outer], + [:c_call, 7, "xyzzy", BasicObject, :initialize, xyzzy, :outer], + [:line, 8, 'xyzzy', self.class, :test_tracepoint, self, :outer], + [:c_call, 9, 'xyzzy', TracePoint, :untrace, trace,:outer], + ].each{|e| + assert_equal e, events.shift + } + assert_equal [], events + end + + + def trace_by_tracepoint *trace_events + events = [] + trace = nil + xyzzy = nil + local_var = :outer + method = :trace_by_tracepoint + + eval <<-EOF.gsub(/^.*?: /, ""), nil, 'xyzzy' + 1: trace = TracePoint.trace(*trace_events){|tp| + 2: events << [tp.event, tp.line, tp.file, tp.klass, tp.id, tp.self, tp.binding.eval("local_var")] + 3: } + 4: 1.times{|;local_var| local_var = :inner + 5: tap{} + 6: } + 7: class XYZZY + 8: local_var = :XYZZY_outer + 9: def foo + 10: local_var = :XYZZY_foo + 11: bar + 12: end + 13: def bar + 14: local_var = :XYZZY_bar + 15: tap{} + 16: end + 17: end + 18: xyzzy = XYZZY.new + 19: xyzzy.foo + 20: trace.untrace + EOF + self.class.class_eval{remove_const(:XYZZY)} + + answer_events = [ + # + [:c_return, 1, "xyzzy", TracePoint, :trace, TracePoint, :outer], + [:line, 4, 'xyzzy', self.class, method, self, :outer], + [:c_call, 4, 'xyzzy', Integer, :times, 1, :outer], + [:line, 4, 'xyzzy', self.class, method, self, nil], + [:line, 5, 'xyzzy', self.class, method, self, :inner], + [:c_call, 5, 'xyzzy', Kernel, :tap, self, :inner], + [:c_return, 5, "xyzzy", Kernel, :tap, self, :inner], + [:c_return, 4, "xyzzy", Integer, :times, 1, :outer], + [:line, 7, 'xyzzy', self.class, method, self, :outer], + [:c_call, 7, "xyzzy", Class, :inherited, Object, :outer], + [:c_return, 7, "xyzzy", Class, :inherited, Object, :outer], + [:class, 7, "xyzzy", nil, nil, xyzzy.class, nil], + [:line, 8, "xyzzy", nil, nil, xyzzy.class, nil], + [:line, 9, "xyzzy", nil, nil, xyzzy.class, :XYZZY_outer], + [:c_call, 9, "xyzzy", Module, :method_added, xyzzy.class, :XYZZY_outer], + [:c_return, 9, "xyzzy", Module, :method_added, xyzzy.class, :XYZZY_outer], + [:line, 13, "xyzzy", nil, nil, xyzzy.class, :XYZZY_outer], + [:c_call, 13, "xyzzy", Module, :method_added, xyzzy.class, :XYZZY_outer], + [:c_return,13, "xyzzy", Module, :method_added, xyzzy.class, :XYZZY_outer], + [:end, 17, "xyzzy", nil, nil, xyzzy.class, :XYZZY_outer], + [:line, 18, "xyzzy", TestSetTraceFunc, method, self, :outer], + [:c_call, 18, "xyzzy", Class, :new, xyzzy.class, :outer], + [:c_call, 18, "xyzzy", BasicObject, :initialize, xyzzy, :outer], + [:c_return,18, "xyzzy", BasicObject, :initialize, xyzzy, :outer], + [:c_return,18, "xyzzy", Class, :new, xyzzy.class, :outer], + [:line, 19, "xyzzy", TestSetTraceFunc, method, self, :outer], + [:call, 9, "xyzzy", xyzzy.class, :foo, xyzzy, nil], + [:line, 10, "xyzzy", xyzzy.class, :foo, xyzzy, nil], + [:line, 11, "xyzzy", xyzzy.class, :foo, xyzzy, :XYZZY_foo], + [:call, 13, "xyzzy", xyzzy.class, :bar, xyzzy, nil], + [:line, 14, "xyzzy", xyzzy.class, :bar, xyzzy, nil], + [:line, 15, "xyzzy", xyzzy.class, :bar, xyzzy, :XYZZY_bar], + [:c_call, 15, "xyzzy", Kernel, :tap, xyzzy, :XYZZY_bar], + [:c_return,15, "xyzzy", Kernel, :tap, xyzzy, :XYZZY_bar], + [:return, 16, "xyzzy", xyzzy.class, :bar, xyzzy, :XYZZY_bar], + [:return, 12, "xyzzy", xyzzy.class, :foo, xyzzy, :XYZZY_foo], + [:line, 20, "xyzzy", TestSetTraceFunc, method, self, :outer], + [:c_call, 20, "xyzzy", TracePoint, :untrace, trace, :outer], + ] + + return events, answer_events + end + + def trace_by_set_trace_func + events = [] + trace = nil + xyzzy = nil + local_var = :outer + eval <<-EOF.gsub(/^.*?: /, ""), nil, 'xyzzy' + 1: set_trace_func(lambda{|event, file, line, id, binding, klass| + 2: events << [event, line, file, klass, id, binding.eval('self'), binding.eval("local_var")] + 3: }) + 4: 1.times{|;local_var| local_var = :inner + 5: tap{} + 6: } + 7: class XYZZY + 8: local_var = :XYZZY_outer + 9: def foo + 10: local_var = :XYZZY_foo + 11: bar + 12: end + 13: def bar + 14: local_var = :XYZZY_bar + 15: tap{} + 16: end + 17: end + 18: xyzzy = XYZZY.new + 19: xyzzy.foo + 20: set_trace_func(nil) + EOF + self.class.class_eval{remove_const(:XYZZY)} + return events + end + + def test_tracepoint + events1, answer_events = *trace_by_tracepoint() + answer_events.zip(events1){|answer, event| + assert_equal answer, event + } + + events2 = trace_by_set_trace_func + events1.zip(events2){|ev1, ev2| + ev2[0] = ev2[0].sub('-', '_').to_sym + assert_equal ev1[0..2], ev2[0..2], ev1.inspect + + # event, line, file, klass, id, binding.eval('self'), binding.eval("local_var") + assert_equal ev1[3].nil?, ev2[3].nil? # klass + assert_equal ev1[4].nil?, ev2[4].nil? # id + assert_equal ev1[6], ev2[6] # local_var + } + + [:line, :class, :end, :call, :return, :c_call, :c_return, :raise].each{|event| + events1, answer_events = *trace_by_tracepoint(event) + answer_events.find_all{|e| e[0] == event}.zip(events1){|answer_line, event_line| + assert_equal answer_line, event_line + } + } + end + + def test_tracepoint_object_id + tps = [] + trace = TracePoint.trace(){|tp| + tps << tp + } + tap{} + tap{} + tap{} + trace.untrace + + # passed tp is unique, `trace' object which is genereted by TracePoint.trace + tps.each{|tp| + assert_equal trace, tp + } + end + + def test_tracepoint_access_from_outside + tp_store = nil + trace = TracePoint.trace(){|tp| + tp_store = tp + } + tap{} + trace.untrace + + assert_raise(RuntimeError){tp_store.line} + assert_raise(RuntimeError){tp_store.event} + assert_raise(RuntimeError){tp_store.file} + assert_raise(RuntimeError){tp_store.id} + assert_raise(RuntimeError){tp_store.klass} + assert_raise(RuntimeError){tp_store.binding} + assert_raise(RuntimeError){tp_store.self} + end end |