ruby-changes:34398
From: ko1 <ko1@a...>
Date: Fri, 20 Jun 2014 17:22:21 +0900 (JST)
Subject: [ruby-changes:34398] ko1:r46479 (trunk): * test/lib/tracepointchecker.rb: add to check TracePoint healthiness.
ko1 2014-06-20 17:22:09 +0900 (Fri, 20 Jun 2014) New Revision: 46479 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=46479 Log: * test/lib/tracepointchecker.rb: add to check TracePoint healthiness. * test/runner.rb: use it. Added files: trunk/test/lib/tracepointchecker.rb Modified files: trunk/ChangeLog trunk/test/runner.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 46478) +++ ChangeLog (revision 46479) @@ -1,3 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Fri Jun 20 17:15:43 2014 Koichi Sasada <ko1@a...> + + * test/lib/tracepointchecker.rb: add to check TracePoint healthiness. + + * test/runner.rb: use it. + Fri Jun 20 07:26:44 2014 Koichi Sasada <ko1@a...> * test/ruby/test_settracefunc.rb: rewrite tests with Index: test/runner.rb =================================================================== --- test/runner.rb (revision 46478) +++ test/runner.rb (revision 46479) @@ -16,27 +16,16 @@ end https://github.com/ruby/ruby/blob/trunk/test/runner.rb#L16 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 Index: test/lib/tracepointchecker.rb =================================================================== --- test/lib/tracepointchecker.rb (revision 0) +++ test/lib/tracepointchecker.rb (revision 46479) @@ -0,0 +1,118 @@ https://github.com/ruby/ruby/blob/trunk/test/lib/tracepointchecker.rb#L1 +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 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/