PageRenderTime 30ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/test/ruby/test_settracefunc.rb

https://gitlab.com/klauer/ruby
Ruby | 373 lines | 354 code | 19 blank | 0 comment | 1 complexity | 3f4f8043ef80e5de3eb7ff9df0ccfccf MD5 | raw file
  1. require 'test/unit'
  2. class TestSetTraceFunc < Test::Unit::TestCase
  3. def setup
  4. @original_compile_option = RubyVM::InstructionSequence.compile_option
  5. RubyVM::InstructionSequence.compile_option = {
  6. :trace_instruction => true,
  7. :specialized_instruction => false
  8. }
  9. end
  10. def teardown
  11. set_trace_func(nil)
  12. RubyVM::InstructionSequence.compile_option = @original_compile_option
  13. end
  14. def test_c_call
  15. events = []
  16. eval <<-EOF.gsub(/^.*?: /, "")
  17. 1: set_trace_func(Proc.new { |event, file, lineno, mid, binding, klass|
  18. 2: events << [event, lineno, mid, klass]
  19. 3: })
  20. 4: x = 1 + 1
  21. 5: set_trace_func(nil)
  22. EOF
  23. assert_equal(["c-return", 3, :set_trace_func, Kernel],
  24. events.shift)
  25. assert_equal(["line", 4, __method__, self.class],
  26. events.shift)
  27. assert_equal(["c-call", 4, :+, Fixnum],
  28. events.shift)
  29. assert_equal(["c-return", 4, :+, Fixnum],
  30. events.shift)
  31. assert_equal(["line", 5, __method__, self.class],
  32. events.shift)
  33. assert_equal(["c-call", 5, :set_trace_func, Kernel],
  34. events.shift)
  35. assert_equal([], events)
  36. end
  37. def test_call
  38. events = []
  39. eval <<-EOF.gsub(/^.*?: /, "")
  40. 1: set_trace_func(Proc.new { |event, file, lineno, mid, binding, klass|
  41. 2: events << [event, lineno, mid, klass]
  42. 3: })
  43. 4: def add(x, y)
  44. 5: x + y
  45. 6: end
  46. 7: x = add(1, 1)
  47. 8: set_trace_func(nil)
  48. EOF
  49. assert_equal(["c-return", 3, :set_trace_func, Kernel],
  50. events.shift)
  51. assert_equal(["line", 4, __method__, self.class],
  52. events.shift)
  53. assert_equal(["c-call", 4, :method_added, self.class],
  54. events.shift)
  55. assert_equal(["c-return", 4, :method_added, self.class],
  56. events.shift)
  57. assert_equal(["line", 7, __method__, self.class],
  58. events.shift)
  59. assert_equal(["call", 4, :add, self.class],
  60. events.shift)
  61. assert_equal(["line", 5, :add, self.class],
  62. events.shift)
  63. assert_equal(["c-call", 5, :+, Fixnum],
  64. events.shift)
  65. assert_equal(["c-return", 5, :+, Fixnum],
  66. events.shift)
  67. assert_equal(["return", 6, :add, self.class],
  68. events.shift)
  69. assert_equal(["line", 8, __method__, self.class],
  70. events.shift)
  71. assert_equal(["c-call", 8, :set_trace_func, Kernel],
  72. events.shift)
  73. assert_equal([], events)
  74. end
  75. def test_class
  76. events = []
  77. eval <<-EOF.gsub(/^.*?: /, "")
  78. 1: set_trace_func(Proc.new { |event, file, lineno, mid, binding, klass|
  79. 2: events << [event, lineno, mid, klass]
  80. 3: })
  81. 4: class Foo
  82. 5: def bar
  83. 6: end
  84. 7: end
  85. 8: x = Foo.new.bar
  86. 9: set_trace_func(nil)
  87. EOF
  88. assert_equal(["c-return", 3, :set_trace_func, Kernel],
  89. events.shift)
  90. assert_equal(["line", 4, __method__, self.class],
  91. events.shift)
  92. assert_equal(["c-call", 4, :inherited, Class],
  93. events.shift)
  94. assert_equal(["c-return", 4, :inherited, Class],
  95. events.shift)
  96. assert_equal(["class", 4, nil, nil],
  97. events.shift)
  98. assert_equal(["line", 5, nil, nil],
  99. events.shift)
  100. assert_equal(["c-call", 5, :method_added, Module],
  101. events.shift)
  102. assert_equal(["c-return", 5, :method_added, Module],
  103. events.shift)
  104. assert_equal(["end", 7, nil, nil],
  105. events.shift)
  106. assert_equal(["line", 8, __method__, self.class],
  107. events.shift)
  108. assert_equal(["c-call", 8, :new, Class],
  109. events.shift)
  110. assert_equal(["c-call", 8, :initialize, BasicObject],
  111. events.shift)
  112. assert_equal(["c-return", 8, :initialize, BasicObject],
  113. events.shift)
  114. assert_equal(["c-return", 8, :new, Class],
  115. events.shift)
  116. assert_equal(["call", 5, :bar, Foo],
  117. events.shift)
  118. assert_equal(["return", 6, :bar, Foo],
  119. events.shift)
  120. assert_equal(["line", 9, __method__, self.class],
  121. events.shift)
  122. assert_equal(["c-call", 9, :set_trace_func, Kernel],
  123. events.shift)
  124. assert_equal([], events)
  125. end
  126. def test_return # [ruby-dev:38701]
  127. events = []
  128. eval <<-EOF.gsub(/^.*?: /, "")
  129. 1: set_trace_func(Proc.new { |event, file, lineno, mid, binding, klass|
  130. 2: events << [event, lineno, mid, klass]
  131. 3: })
  132. 4: def foo(a)
  133. 5: return if a
  134. 6: return
  135. 7: end
  136. 8: foo(true)
  137. 9: foo(false)
  138. 10: set_trace_func(nil)
  139. EOF
  140. assert_equal(["c-return", 3, :set_trace_func, Kernel],
  141. events.shift)
  142. assert_equal(["line", 4, __method__, self.class],
  143. events.shift)
  144. assert_equal(["c-call", 4, :method_added, self.class],
  145. events.shift)
  146. assert_equal(["c-return", 4, :method_added, self.class],
  147. events.shift)
  148. assert_equal(["line", 8, __method__, self.class],
  149. events.shift)
  150. assert_equal(["call", 4, :foo, self.class],
  151. events.shift)
  152. assert_equal(["line", 5, :foo, self.class],
  153. events.shift)
  154. assert_equal(["return", 5, :foo, self.class],
  155. events.shift)
  156. assert_equal(["line", 9, :test_return, self.class],
  157. events.shift)
  158. assert_equal(["call", 4, :foo, self.class],
  159. events.shift)
  160. assert_equal(["line", 5, :foo, self.class],
  161. events.shift)
  162. assert_equal(["return", 7, :foo, self.class],
  163. events.shift)
  164. assert_equal(["line", 10, :test_return, self.class],
  165. events.shift)
  166. assert_equal(["c-call", 10, :set_trace_func, Kernel],
  167. events.shift)
  168. assert_equal([], events)
  169. end
  170. def test_return2 # [ruby-core:24463]
  171. events = []
  172. eval <<-EOF.gsub(/^.*?: /, "")
  173. 1: set_trace_func(Proc.new { |event, file, lineno, mid, binding, klass|
  174. 2: events << [event, lineno, mid, klass]
  175. 3: })
  176. 4: def foo
  177. 5: a = 5
  178. 6: return a
  179. 7: end
  180. 8: foo
  181. 9: set_trace_func(nil)
  182. EOF
  183. assert_equal(["c-return", 3, :set_trace_func, Kernel],
  184. events.shift)
  185. assert_equal(["line", 4, __method__, self.class],
  186. events.shift)
  187. assert_equal(["c-call", 4, :method_added, self.class],
  188. events.shift)
  189. assert_equal(["c-return", 4, :method_added, self.class],
  190. events.shift)
  191. assert_equal(["line", 8, __method__, self.class],
  192. events.shift)
  193. assert_equal(["call", 4, :foo, self.class],
  194. events.shift)
  195. assert_equal(["line", 5, :foo, self.class],
  196. events.shift)
  197. assert_equal(["line", 6, :foo, self.class],
  198. events.shift)
  199. assert_equal(["return", 7, :foo, self.class],
  200. events.shift)
  201. assert_equal(["line", 9, :test_return2, self.class],
  202. events.shift)
  203. assert_equal(["c-call", 9, :set_trace_func, Kernel],
  204. events.shift)
  205. assert_equal([], events)
  206. end
  207. def test_raise
  208. events = []
  209. eval <<-EOF.gsub(/^.*?: /, "")
  210. 1: set_trace_func(Proc.new { |event, file, lineno, mid, binding, klass|
  211. 2: events << [event, lineno, mid, klass]
  212. 3: })
  213. 4: begin
  214. 5: raise TypeError, "error"
  215. 6: rescue TypeError
  216. 7: end
  217. 8: set_trace_func(nil)
  218. EOF
  219. assert_equal(["c-return", 3, :set_trace_func, Kernel],
  220. events.shift)
  221. assert_equal(["line", 4, __method__, self.class],
  222. events.shift)
  223. assert_equal(["line", 5, __method__, self.class],
  224. events.shift)
  225. assert_equal(["c-call", 5, :raise, Kernel],
  226. events.shift)
  227. assert_equal(["c-call", 5, :exception, Exception],
  228. events.shift)
  229. assert_equal(["c-call", 5, :initialize, Exception],
  230. events.shift)
  231. assert_equal(["c-return", 5, :initialize, Exception],
  232. events.shift)
  233. assert_equal(["c-return", 5, :exception, Exception],
  234. events.shift)
  235. assert_equal(["c-call", 5, :backtrace, Exception],
  236. events.shift)
  237. assert_equal(["c-return", 5, :backtrace, Exception],
  238. events.shift)
  239. assert_equal(["c-call", 5, :set_backtrace, Exception],
  240. events.shift)
  241. assert_equal(["c-return", 5, :set_backtrace, Exception],
  242. events.shift)
  243. assert_equal(["raise", 5, :test_raise, TestSetTraceFunc],
  244. events.shift)
  245. assert_equal(["c-return", 5, :raise, Kernel],
  246. events.shift)
  247. assert_equal(["c-call", 6, :===, Module],
  248. events.shift)
  249. assert_equal(["c-return", 6, :===, Module],
  250. events.shift)
  251. assert_equal(["line", 8, __method__, self.class],
  252. events.shift)
  253. assert_equal(["c-call", 8, :set_trace_func, Kernel],
  254. events.shift)
  255. assert_equal([], events)
  256. end
  257. def test_break # [ruby-core:27606] [Bug #2610]
  258. events = []
  259. eval <<-EOF.gsub(/^.*?: /, "")
  260. 1: set_trace_func(Proc.new { |event, file, lineno, mid, binding, klass|
  261. 2: events << [event, lineno, mid, klass]
  262. 3: })
  263. 4: [1,2,3].any? {|n| n}
  264. 8: set_trace_func(nil)
  265. EOF
  266. [["c-return", 3, :set_trace_func, Kernel],
  267. ["line", 4, __method__, self.class],
  268. ["c-call", 4, :any?, Enumerable],
  269. ["c-call", 4, :each, Array],
  270. ["line", 4, __method__, self.class],
  271. ["c-return", 4, :each, Array],
  272. ["c-return", 4, :any?, Enumerable],
  273. ["line", 5, __method__, self.class],
  274. ["c-call", 5, :set_trace_func, Kernel]].each{|e|
  275. assert_equal(e, events.shift)
  276. }
  277. end
  278. def test_invalid_proc
  279. assert_raise(TypeError) { set_trace_func(1) }
  280. end
  281. def test_raise_in_trace
  282. set_trace_func proc {raise rescue nil}
  283. assert_equal(42, (raise rescue 42), '[ruby-core:24118]')
  284. end
  285. def test_thread_trace
  286. events = {:set => [], :add => []}
  287. prc = Proc.new { |event, file, lineno, mid, binding, klass|
  288. events[:set] << [event, lineno, mid, klass, :set]
  289. }
  290. prc2 = Proc.new { |event, file, lineno, mid, binding, klass|
  291. events[:add] << [event, lineno, mid, klass, :add]
  292. }
  293. th = Thread.new do
  294. th = Thread.current
  295. eval <<-EOF.gsub(/^.*?: /, "")
  296. 1: th.set_trace_func(prc)
  297. 2: th.add_trace_func(prc2)
  298. 3: class ThreadTraceInnerClass
  299. 4: def foo
  300. 5: x = 1 + 1
  301. 6: end
  302. 7: end
  303. 8: ThreadTraceInnerClass.new.foo
  304. 9: th.set_trace_func(nil)
  305. EOF
  306. end
  307. th.join
  308. [["c-return", 1, :set_trace_func, Thread, :set],
  309. ["line", 2, __method__, self.class, :set],
  310. ["c-call", 2, :add_trace_func, Thread, :set]].each do |e|
  311. assert_equal(e, events[:set].shift)
  312. end
  313. [["c-return", 2, :add_trace_func, Thread],
  314. ["line", 3, __method__, self.class],
  315. ["c-call", 3, :inherited, Class],
  316. ["c-return", 3, :inherited, Class],
  317. ["class", 3, nil, nil],
  318. ["line", 4, nil, nil],
  319. ["c-call", 4, :method_added, Module],
  320. ["c-return", 4, :method_added, Module],
  321. ["end", 7, nil, nil],
  322. ["line", 8, __method__, self.class],
  323. ["c-call", 8, :new, Class],
  324. ["c-call", 8, :initialize, BasicObject],
  325. ["c-return", 8, :initialize, BasicObject],
  326. ["c-return", 8, :new, Class],
  327. ["call", 4, :foo, ThreadTraceInnerClass],
  328. ["line", 5, :foo, ThreadTraceInnerClass],
  329. ["c-call", 5, :+, Fixnum],
  330. ["c-return", 5, :+, Fixnum],
  331. ["return", 6, :foo, ThreadTraceInnerClass],
  332. ["line", 9, __method__, self.class],
  333. ["c-call", 9, :set_trace_func, Thread]].each do |e|
  334. [:set, :add].each do |type|
  335. assert_equal(e + [type], events[type].shift)
  336. end
  337. end
  338. assert_equal([], events[:set])
  339. assert_equal([], events[:add])
  340. end
  341. def test_remove_in_trace
  342. bug3921 = '[ruby-dev:42350]'
  343. ok = false
  344. func = lambda{|e, f, l, i, b, k|
  345. set_trace_func(nil)
  346. ok = eval("self", b)
  347. }
  348. set_trace_func(func)
  349. assert_equal(self, ok, bug3921)
  350. end
  351. class << self
  352. define_method(:method_added, Module.method(:method_added))
  353. end
  354. end