ruby-prof 2.0.4 → 2.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -2
  3. data/lib/ruby-prof/printers/flame_graph_printer.rb +80 -78
  4. data/lib/ruby-prof/version.rb +1 -1
  5. metadata +4 -85
  6. data/Rakefile +0 -98
  7. data/docs/advanced-usage.md +0 -132
  8. data/docs/alternatives.md +0 -98
  9. data/docs/architecture.md +0 -304
  10. data/docs/best-practices.md +0 -27
  11. data/docs/getting-started.md +0 -130
  12. data/docs/history.md +0 -11
  13. data/docs/index.md +0 -45
  14. data/docs/profiling-rails.md +0 -64
  15. data/docs/public/examples/example.rb +0 -33
  16. data/docs/public/examples/generate_reports.rb +0 -92
  17. data/docs/public/examples/reports/call_info.txt +0 -27
  18. data/docs/public/examples/reports/call_stack.html +0 -835
  19. data/docs/public/examples/reports/callgrind.out +0 -150
  20. data/docs/public/examples/reports/flame_graph.html +0 -408
  21. data/docs/public/examples/reports/flat.txt +0 -45
  22. data/docs/public/examples/reports/graph.dot +0 -129
  23. data/docs/public/examples/reports/graph.html +0 -1319
  24. data/docs/public/examples/reports/graph.txt +0 -100
  25. data/docs/public/examples/reports/graphviz_viewer.html +0 -1
  26. data/docs/public/images/call_stack.png +0 -0
  27. data/docs/public/images/class_diagram.png +0 -0
  28. data/docs/public/images/dot_printer.png +0 -0
  29. data/docs/public/images/flame_graph.png +0 -0
  30. data/docs/public/images/flat.png +0 -0
  31. data/docs/public/images/graph.png +0 -0
  32. data/docs/public/images/graph_html.png +0 -0
  33. data/docs/public/images/ruby-prof-logo.svg +0 -1
  34. data/docs/reports.md +0 -151
  35. data/docs/stylesheets/extra.css +0 -80
  36. data/ruby-prof.gemspec +0 -66
  37. data/test/abstract_printer_test.rb +0 -25
  38. data/test/alias_test.rb +0 -203
  39. data/test/call_tree_builder.rb +0 -126
  40. data/test/call_tree_test.rb +0 -94
  41. data/test/call_tree_visitor_test.rb +0 -27
  42. data/test/call_trees_test.rb +0 -66
  43. data/test/duplicate_names_test.rb +0 -32
  44. data/test/dynamic_method_test.rb +0 -50
  45. data/test/enumerable_test.rb +0 -23
  46. data/test/exceptions_test.rb +0 -24
  47. data/test/exclude_methods_test.rb +0 -363
  48. data/test/exclude_threads_test.rb +0 -48
  49. data/test/fiber_test.rb +0 -195
  50. data/test/gc_test.rb +0 -104
  51. data/test/inverse_call_tree_test.rb +0 -174
  52. data/test/line_number_test.rb +0 -563
  53. data/test/marshal_test.rb +0 -144
  54. data/test/measure_allocations.rb +0 -26
  55. data/test/measure_allocations_test.rb +0 -1511
  56. data/test/measure_process_time_test.rb +0 -3286
  57. data/test/measure_times.rb +0 -56
  58. data/test/measure_wall_time_test.rb +0 -774
  59. data/test/measurement_test.rb +0 -82
  60. data/test/merge_test.rb +0 -146
  61. data/test/method_info_test.rb +0 -100
  62. data/test/multi_printer_test.rb +0 -52
  63. data/test/no_method_class_test.rb +0 -15
  64. data/test/pause_resume_test.rb +0 -171
  65. data/test/prime.rb +0 -54
  66. data/test/prime_script.rb +0 -6
  67. data/test/printer_call_stack_test.rb +0 -28
  68. data/test/printer_call_tree_test.rb +0 -30
  69. data/test/printer_flame_graph_test.rb +0 -82
  70. data/test/printer_flat_test.rb +0 -110
  71. data/test/printer_graph_html_test.rb +0 -62
  72. data/test/printer_graph_test.rb +0 -42
  73. data/test/printers_test.rb +0 -162
  74. data/test/printing_recursive_graph_test.rb +0 -81
  75. data/test/profile_test.rb +0 -101
  76. data/test/rack_test.rb +0 -103
  77. data/test/recursive_test.rb +0 -796
  78. data/test/scheduler.rb +0 -367
  79. data/test/singleton_test.rb +0 -39
  80. data/test/stack_printer_test.rb +0 -61
  81. data/test/start_stop_test.rb +0 -106
  82. data/test/test_helper.rb +0 -24
  83. data/test/thread_test.rb +0 -229
  84. data/test/unique_call_path_test.rb +0 -123
  85. data/test/yarv_test.rb +0 -56
@@ -1,126 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require File.expand_path('../test_helper', __FILE__)
4
- require 'base64'
5
-
6
- # Create a DummyClass with methods so we can create call trees in the test_merge method below
7
- class DummyClass
8
- %i[root a b aa ab ba bb].each do |method_name|
9
- define_method(method_name) do
10
- end
11
- end
12
- end
13
-
14
- def create_call_tree(method_name)
15
- method_info = RubyProf::MethodInfo.new(DummyClass, method_name)
16
- RubyProf::CallTree.new(method_info)
17
- end
18
-
19
- def build_call_tree(tree_hash)
20
- # tree_hash is a hash keyed on the parent method_name whose values are
21
- # child methods. Example:
22
- #
23
- # tree_hash = {root: [:a, :b],
24
- # a: [:aa, :ab],
25
- # b: [:bb]}
26
- #
27
- # Note this is a simplified structure for testing. It assumes methods
28
- # are only called from one call_tree.
29
-
30
- call_trees = Hash.new
31
- tree_hash.each do |method_name, children|
32
- parent = call_trees[method_name] ||= create_call_tree(method_name)
33
- children.each do |child_method_name|
34
- child = call_trees[child_method_name] ||= create_call_tree(child_method_name)
35
- parent.add_child(child)
36
- end
37
- end
38
-
39
- call_trees
40
- end
41
-
42
- def create_call_tree_1
43
- #
44
- # root
45
- # / \
46
- # a b
47
- # / \ \
48
- # aa ab bb
49
- #
50
-
51
- # ------ Call Trees 1 -------------
52
- tree_hash = {root: [:a, :b],
53
- a: [:aa, :ab],
54
- b: [:bb]}
55
-
56
- call_trees = build_call_tree(tree_hash)
57
-
58
- # Setup times
59
- call_trees[:aa].measurement.total_time = 1.5
60
- call_trees[:aa].measurement.self_time = 1.5
61
- call_trees[:ab].measurement.total_time = 2.2
62
- call_trees[:ab].measurement.self_time = 2.2
63
- call_trees[:a].measurement.total_time = 3.7
64
-
65
- call_trees[:aa].target.measurement.total_time = 1.5
66
- call_trees[:aa].target.measurement.self_time = 1.5
67
- call_trees[:ab].target.measurement.total_time = 2.2
68
- call_trees[:ab].target.measurement.self_time = 2.2
69
- call_trees[:a].target.measurement.total_time = 3.7
70
-
71
- call_trees[:bb].measurement.total_time = 4.3
72
- call_trees[:bb].measurement.self_time = 4.3
73
- call_trees[:b].measurement.total_time = 4.3
74
-
75
- call_trees[:bb].target.measurement.total_time = 4.3
76
- call_trees[:bb].target.measurement.self_time = 4.3
77
- call_trees[:b].target.measurement.total_time = 4.3
78
-
79
- call_trees[:root].measurement.total_time = 8.0
80
- call_trees[:root].target.measurement.total_time = 8.0
81
-
82
- call_trees[:root]
83
- end
84
-
85
- def create_call_tree_2
86
- #
87
- # root
88
- # / \
89
- # a b
90
- # \ / \
91
- # ab ba bb
92
-
93
- tree_hash = {root: [:a, :b],
94
- a: [:ab],
95
- b: [:ba, :bb]}
96
-
97
- call_trees = build_call_tree(tree_hash)
98
-
99
- # Setup times
100
- call_trees[:ab].measurement.total_time = 0.4
101
- call_trees[:ab].measurement.self_time = 0.4
102
- call_trees[:a].measurement.total_time = 0.4
103
-
104
- call_trees[:ab].target.measurement.total_time = 0.4
105
- call_trees[:ab].target.measurement.self_time = 0.4
106
- call_trees[:a].target.measurement.total_time = 0.4
107
-
108
- call_trees[:ba].measurement.total_time = 0.9
109
- call_trees[:ba].measurement.self_time = 0.7
110
- call_trees[:ba].measurement.wait_time = 0.2
111
- call_trees[:bb].measurement.total_time = 2.3
112
- call_trees[:bb].measurement.self_time = 2.3
113
- call_trees[:b].measurement.total_time = 3.2
114
-
115
- call_trees[:ba].target.measurement.total_time = 0.9
116
- call_trees[:ba].target.measurement.self_time = 0.7
117
- call_trees[:ba].target.measurement.wait_time = 0.2
118
- call_trees[:bb].target.measurement.total_time = 2.3
119
- call_trees[:bb].target.measurement.self_time = 2.3
120
- call_trees[:b].target.measurement.total_time = 3.2
121
-
122
- call_trees[:root].measurement.total_time = 3.6
123
- call_trees[:root].target.measurement.total_time = 3.6
124
-
125
- call_trees[:root]
126
- end
@@ -1,94 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require File.expand_path('../test_helper', __FILE__)
4
- require_relative './call_tree_builder'
5
- require 'base64'
6
-
7
- class CallTreeTest < Minitest::Test
8
- def test_initialize
9
- method_info = RubyProf::MethodInfo.new(Base64, :encode64)
10
- call_tree = RubyProf::CallTree.new(method_info)
11
- assert_equal(method_info, call_tree.target)
12
- end
13
-
14
- def test_measurement
15
- method_info = RubyProf::MethodInfo.new(Base64, :encode64)
16
- call_tree = RubyProf::CallTree.new(method_info)
17
-
18
- assert_equal(0, call_tree.total_time)
19
- assert_equal(0, call_tree.self_time)
20
- assert_equal(0, call_tree.wait_time)
21
- assert_equal(0, call_tree.children_time)
22
- assert_equal(0, call_tree.called)
23
- end
24
-
25
- def test_compare
26
- method_info_1 = RubyProf::MethodInfo.new(Base64, :encode64)
27
- call_tree_1 = RubyProf::CallTree.new(method_info_1)
28
- method_info_2 = RubyProf::MethodInfo.new(Base64, :encode64)
29
- call_tree_2 = RubyProf::CallTree.new(method_info_2)
30
- assert_equal(0, call_tree_1 <=> call_tree_2)
31
-
32
- method_info_1 = RubyProf::MethodInfo.new(Base64, :decode64)
33
- call_tree_1 = RubyProf::CallTree.new(method_info_1)
34
- call_tree_1.measurement.total_time = 1
35
- method_info_2 = RubyProf::MethodInfo.new(Base64, :encode64)
36
- call_tree_2 = RubyProf::CallTree.new(method_info_2)
37
- assert_equal(1, call_tree_1 <=> call_tree_2)
38
-
39
- method_info_1 = RubyProf::MethodInfo.new(Base64, :decode64)
40
- call_tree_1 = RubyProf::CallTree.new(method_info_1)
41
- method_info_2 = RubyProf::MethodInfo.new(Base64, :encode64)
42
- call_tree_2 = RubyProf::CallTree.new(method_info_2)
43
- call_tree_2.measurement.total_time = 1
44
- assert_equal(-1, call_tree_1 <=> call_tree_2)
45
- end
46
-
47
- def test_to_s
48
- method_info = RubyProf::MethodInfo.new(Base64, :encode64)
49
- call_tree = RubyProf::CallTree.new(method_info)
50
- assert_equal("<RubyProf::CallTree - Base64#encode64>", call_tree.to_s)
51
- end
52
-
53
- def test_add_child
54
- method_info_parent = RubyProf::MethodInfo.new(Base64, :encode64)
55
- call_tree_parent = RubyProf::CallTree.new(method_info_parent)
56
-
57
- method_info_child = RubyProf::MethodInfo.new(Array, :pack)
58
- call_tree_child = RubyProf::CallTree.new(method_info_child)
59
-
60
- assert_equal(0, call_tree_parent.children.size)
61
- assert_nil(call_tree_child.parent)
62
-
63
- result = call_tree_parent.add_child(call_tree_child)
64
- assert_equal(1, call_tree_parent.children.size)
65
- assert_equal(call_tree_child, call_tree_parent.children.first)
66
- assert_equal(call_tree_child, result)
67
- assert_equal(call_tree_parent, call_tree_child.parent)
68
- end
69
-
70
- def test_add_child_gc
71
- GC.stress = true
72
-
73
- begin
74
- method_info_parent = RubyProf::MethodInfo.new(Base64, :encode64)
75
- call_tree_parent = RubyProf::CallTree.new(method_info_parent)
76
-
77
- method_info_child = RubyProf::MethodInfo.new(Array, :pack)
78
- call_tree_child = RubyProf::CallTree.new(method_info_child)
79
- call_tree_parent.add_child(call_tree_child)
80
-
81
- # Free the child first
82
- call_tree_child = nil
83
- GC.start
84
-
85
- # Now free the parent and make sure it doesn't free the child a second time
86
- call_tree_parent = nil
87
- GC.start
88
-
89
- assert(true)
90
- ensure
91
- GC.stress = false
92
- end
93
- end
94
- end
@@ -1,27 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # encoding: UTF-8
3
-
4
- require File.expand_path('../test_helper', __FILE__)
5
- require_relative './measure_times'
6
-
7
- class CallTreeVisitorTest < TestCase
8
- def test_visit
9
- result = RubyProf::Profile.profile(measure_mode: RubyProf::WALL_TIME) do
10
- RubyProf::C1.sleep_wait
11
- end
12
-
13
- visitor = RubyProf::CallTreeVisitor.new(result.threads.first.call_tree)
14
-
15
- method_names = Array.new
16
-
17
- visitor.visit do |call_tree, event|
18
- method_names << call_tree.target.full_name if event == :enter
19
- end
20
-
21
- assert_equal(3, method_names.length)
22
- assert_equal("CallTreeVisitorTest#test_visit", method_names[0])
23
- assert_equal("<Class::RubyProf::C1>#sleep_wait", method_names[1])
24
- assert_equal("Kernel#sleep", method_names[2])
25
- end
26
- end
27
-
@@ -1,66 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # encoding: UTF-8
3
-
4
- require File.expand_path('../test_helper', __FILE__)
5
-
6
- # -- Tests ----
7
- class CallTreesTest < TestCase
8
- def some_method_1
9
- some_method_2
10
- end
11
-
12
- def some_method_2
13
- end
14
-
15
- def test_call_infos
16
- result = RubyProf::Profile.profile do
17
- some_method_1
18
- end
19
-
20
- thread = result.threads.first
21
- assert_equal(3, thread.methods.length)
22
-
23
- method = thread.methods[0]
24
- assert_equal('CallTreesTest#test_call_infos', method.full_name)
25
-
26
- call_trees = method.call_trees
27
- assert_empty(call_trees.callers)
28
- assert_equal(1, call_trees.callees.length)
29
- assert_kind_of(RubyProf::CallTree, call_trees.callees[0])
30
- assert_equal('CallTreesTest#some_method_1', call_trees.callees[0].target.full_name)
31
-
32
- method = thread.methods[1]
33
- assert_equal('CallTreesTest#some_method_1', method.full_name)
34
-
35
- call_trees = method.call_trees
36
- assert_equal(1, call_trees.callers.length)
37
- assert_kind_of(RubyProf::CallTree, call_trees.callers[0])
38
- assert_equal('CallTreesTest#test_call_infos', call_trees.callers[0].parent.target.full_name)
39
- assert_equal(1, call_trees.callees.length)
40
- assert_kind_of(RubyProf::CallTree, call_trees.callees[0])
41
- assert_equal('CallTreesTest#some_method_2', call_trees.callees[0].target.full_name)
42
-
43
- method = thread.methods[2]
44
- assert_equal('CallTreesTest#some_method_2', method.full_name)
45
-
46
- call_trees = method.call_trees
47
- assert_equal(1, call_trees.callers.length)
48
- assert_kind_of(RubyProf::CallTree, call_trees.callers[0])
49
- assert_equal('CallTreesTest#some_method_1', call_trees.callers[0].parent.target.full_name)
50
- assert_empty(call_trees.callees)
51
- end
52
-
53
- def test_gc
54
- result = RubyProf::Profile.profile do
55
- some_method_1
56
- end
57
-
58
- method = result.threads.first.methods[1]
59
-
60
- 100.times do |i|
61
- method.call_trees.callers
62
- GC.start
63
- end
64
- assert(true)
65
- end
66
- end
@@ -1,32 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # encoding: UTF-8
3
-
4
- require File.expand_path('../test_helper', __FILE__)
5
-
6
- class DuplicateNamesTest < TestCase
7
- def test_names
8
- result = RubyProf::Profile.profile do
9
- str = %{module Foo; class Bar; def foo; end end end}
10
-
11
- eval str
12
- Foo::Bar.new.foo
13
- DuplicateNamesTest.class_eval {remove_const :Foo}
14
-
15
- eval str
16
- Foo::Bar.new.foo
17
- DuplicateNamesTest.class_eval {remove_const :Foo}
18
-
19
- eval str
20
- Foo::Bar.new.foo
21
- end
22
-
23
- # There should be 3 foo methods
24
- methods = result.threads.first.methods.sort.reverse
25
-
26
- methods = methods.select do |method|
27
- method.full_name == 'DuplicateNamesTest::Foo::Bar#foo'
28
- end
29
-
30
- assert_equal(3, methods.length)
31
- end
32
- end
@@ -1,50 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # encoding: UTF-8
3
-
4
- require File.expand_path("../test_helper", __FILE__)
5
-
6
- class DynamicMethodTest < TestCase
7
-
8
- class FruitMedley
9
- define_method(:apple) do
10
- sleep(0.1)
11
- "I'm a peach"
12
- end
13
-
14
- define_method(:orange) do
15
- sleep(0.2)
16
- "I'm an orange"
17
- end
18
-
19
- [:banana, :peach].each_with_index do |fruit,i|
20
- define_method(fruit) do
21
- sleep(i == 0 ? 0.3 : 0.4)
22
- "I'm a #{fruit}"
23
- end
24
- end
25
- end
26
-
27
- def test_dynamic_method
28
- medley = FruitMedley.new
29
- result = RubyProf::Profile.profile(measure_mode: RubyProf::WALL_TIME) do
30
- medley.apple
31
- medley.orange
32
- medley.banana
33
- medley.peach
34
- end
35
-
36
- methods = result.threads.first.methods.sort.reverse
37
-
38
- expected_method_names = %w(
39
- DynamicMethodTest#test_dynamic_method
40
- Kernel#sleep
41
- DynamicMethodTest::FruitMedley#peach
42
- DynamicMethodTest::FruitMedley#banana
43
- DynamicMethodTest::FruitMedley#orange
44
- DynamicMethodTest::FruitMedley#apple
45
- Integer#==
46
- )
47
-
48
- assert_equal expected_method_names.join("\n"), methods.map(&:full_name).join("\n")
49
- end
50
- end
@@ -1,23 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # encoding: UTF-8
3
-
4
- require File.expand_path('../test_helper', __FILE__)
5
-
6
- # -- Test for bug
7
- # http://github.com/rdp/ruby-prof/issues#issue/12
8
-
9
- class EnumerableTest < TestCase
10
- def test_enumerable
11
- result = RubyProf::Profile.profile do
12
- 3.times { [1,2,3].any? {|n| n} }
13
- end
14
- methods = if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('3.3')
15
- %w(EnumerableTest#test_enumerable Integer#times Array#any?)
16
- elsif Gem::Version.new(RUBY_VERSION) < Gem::Version.new('3.4')
17
- %w(EnumerableTest#test_enumerable Integer#times Kernel#block_given? Integer#< Array#any? Integer#succ)
18
- else
19
- %w(EnumerableTest#test_enumerable Integer#times Integer#< Array#any? Integer#succ)
20
- end
21
- assert_equal(methods, result.threads.first.methods.map(&:full_name))
22
- end
23
- end
@@ -1,24 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # encoding: UTF-8
3
-
4
- require File.expand_path('../test_helper', __FILE__)
5
-
6
- class ExceptionsTest < TestCase
7
- def test_profile
8
- result = begin
9
- RubyProf::Profile.profile do
10
- raise(RuntimeError, 'Test error')
11
- end
12
- rescue
13
- end
14
- assert_kind_of(RubyProf::Profile, result)
15
- end
16
-
17
- def test_profile_allows_exceptions
18
- assert_raises(RuntimeError) do
19
- RubyProf::Profile.profile(allow_exceptions: true) do
20
- raise(RuntimeError, 'Test error')
21
- end
22
- end
23
- end
24
- end