diff options
author | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-06-20 08:22:09 +0000 |
---|---|---|
committer | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-06-20 08:22:09 +0000 |
commit | 2aa6f9c2b7149e37d8610154cfd5ead3c0fdd994 (patch) | |
tree | f7b789c5b61a250397071f1de731c55bd759ffb7 | |
parent | 7d9b37cc53b259ccbd9e8e5d4b9b068b7b1d5e2c (diff) | |
download | ruby-2aa6f9c2b7149e37d8610154cfd5ead3c0fdd994.tar.gz |
* test/lib/tracepointchecker.rb: add to check TracePoint healthiness.
* test/runner.rb: use it.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@46479 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | test/lib/tracepointchecker.rb | 118 | ||||
-rw-r--r-- | test/runner.rb | 15 |
3 files changed, 126 insertions, 13 deletions
@@ -1,3 +1,9 @@ +Fri Jun 20 17:15:43 2014 Koichi Sasada <ko1@atdot.net> + + * test/lib/tracepointchecker.rb: add to check TracePoint healthiness. + + * test/runner.rb: use it. + Fri Jun 20 07:26:44 2014 Koichi Sasada <ko1@atdot.net> * test/ruby/test_settracefunc.rb: rewrite tests with diff --git a/test/lib/tracepointchecker.rb b/test/lib/tracepointchecker.rb new file mode 100644 index 0000000000..f90611b536 --- /dev/null +++ b/test/lib/tracepointchecker.rb @@ -0,0 +1,118 @@ +module TracePointChecker + STATE = { + count: 0, + running: false, + } + + module ZombieTraceHunter + def before_setup + @tracepoint_captured_stat = TracePoint.stat.map{|k, (activated, deleted)| [k, activated]} + + super + end + + def after_teardown + super + + # detect zombie traces. + assert_equal( + @tracepoint_captured_stat, + TracePoint.stat.map{|k, (activated, deleted)| [k, activated]}, + "The number of active trace events was changed" + ) + # puts "TracePoint - deleted: #{deleted}" if deleted > 0 + + TracePointChecker.check if STATE[:running] + end + end + + MAIN_THREAD = Thread.current + TRACES = [] + + def self.prefix event + case event + when :call, :return + :n + when :c_call, :c_return + :c + when :b_call, :b_return + :b + end + end + + def self.clear_call_stack + Thread.current[:call_stack] = [] + end + + def self.call_stack + stack = Thread.current[:call_stack] + stack = clear_call_stack unless stack + stack + end + + def self.verbose_out label, method + puts label => call_stack, :count => STATE[:count], :method => method + end + + def self.method_label tp + "#{prefix(tp.event)}##{tp.method_id}" + end + + def self.start verbose: false, stop_at_failure: false + call_events = %i(a_call) + return_events = %i(a_return) + clear_call_stack + + STATE[:running] = true + + TRACES << TracePoint.new(*call_events){|tp| + next if Thread.current != MAIN_THREAD + + method = method_label(tp) + call_stack.push method + STATE[:count] += 1 + + verbose_out :psuh, method if verbose + } + + TRACES << TracePoint.new(*return_events){|tp| + next if Thread.current != MAIN_THREAD + STATE[:count] += 1 + + method = "#{prefix(tp.event)}##{tp.method_id}" + verbose_out :pop1, method if verbose + + stored_method = call_stack.pop + next if stored_method.nil? + + verbose_out :pop2, method if verbose + + if stored_method != method + stop if stop_at_failure + RubyVM::SDR() if defined? RubyVM::SDR() + call_stack.clear + raise "#{stored_method} is expected, but #{method} (count: #{STATE[:count]})" + end + } + + TRACES.each{|trace| trace.enable} + end + + def self.stop + STATE[:running] = true + TRACES.each{|trace| trace.disable} + TRACES.clear + end + + def self.check + TRACES.each{|trace| + raise "trace #{trace} should not be deactivated" unless trace.enabled? + } + end +end + +class ::Test::Unit::TestCase + include TracePointChecker::ZombieTraceHunter +end + +# TracePointChecker.start verbose: false diff --git a/test/runner.rb b/test/runner.rb index 3a8eb78add..aa249a53d5 100644 --- a/test/runner.rb +++ b/test/runner.rb @@ -16,27 +16,16 @@ end ENV["GEM_SKIP"] = ENV["GEM_HOME"] = ENV["GEM_PATH"] = "".freeze require_relative 'profile_test_all' if ENV.has_key?('RUBY_TEST_ALL_PROFILE') +require_relative 'lib/tracepointchecker' module Test::Unit module ZombieHunter - - def before_setup - @tracepoint_captured_stat = TracePoint.stat.map{|k, (activated, deleted)| [k, activated]} - end - def after_teardown super assert_empty(Process.waitall) - - # detect zombie traces. - assert_equal( - @tracepoint_captured_stat, - TracePoint.stat.map{|k, (activated, deleted)| [k, activated]}, - "The number of active trace events was changed" - ) - # puts "TracePoint - deleted: #{deleted}" if deleted > 0 end end + class TestCase include ZombieHunter end |