[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]