stickshift 0.1
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.
- data/.gemtest +0 -0
- data/History.txt +3 -0
- data/LICENSE.txt +21 -0
- data/Manifest.txt +11 -0
- data/README.markdown +75 -0
- data/Rakefile +38 -0
- data/examples/example.rake +12 -0
- data/examples/stickshift_rails.rb +34 -0
- data/lib/stickshift.rb +142 -0
- data/lib/stickshift/version.rb +3 -0
- data/stickshift.gemspec +36 -0
- data/test/test_stickshift.rb +158 -0
- metadata +91 -0
data/.gemtest
ADDED
File without changes
|
data/History.txt
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# (c) Copyright 2008 Nick Sieger <nicksieger@gmail.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person
|
4
|
+
# obtaining a copy of this software and associated documentation files
|
5
|
+
# (the "Software"), to deal in the Software without restriction,
|
6
|
+
# including without limitation the rights to use, copy, modify, merge,
|
7
|
+
# publish, distribute, sublicense, and/or sell copies of the Software,
|
8
|
+
# and to permit persons to whom the Software is furnished to do so,
|
9
|
+
# subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be
|
12
|
+
# included in all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
18
|
+
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
19
|
+
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
# SOFTWARE.
|
data/Manifest.txt
ADDED
data/README.markdown
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
Stickshift is a simple, manual-instrumenting call-tree profiler in as
|
2
|
+
few lines of code as possible.
|
3
|
+
|
4
|
+
## Background
|
5
|
+
|
6
|
+
The idea is to be as minimally intrusive as possible, but also to be
|
7
|
+
stupid simple and manual. You tell stickshift to only instrument the
|
8
|
+
methods you want, and it measures time spent in that method, as well
|
9
|
+
as any time spent in any instrumented methods invoked by the method.
|
10
|
+
After leaving the top-most method, a call tree with timings is dumped
|
11
|
+
to $stdout.
|
12
|
+
|
13
|
+
Note: You aren't allowed to instrument methods on the String class, or any
|
14
|
+
object's #inspect method, because it can generate a recursive loop! For
|
15
|
+
#fine-grained profiling on any arbitrary class, use profiler or ruby-prof
|
16
|
+
instead. You're also not allowed to instrument an instrumented method.
|
17
|
+
|
18
|
+
## Example
|
19
|
+
|
20
|
+
Consider the following Rakefile:
|
21
|
+
|
22
|
+
task :sleep => :snooze do
|
23
|
+
sleep 1
|
24
|
+
end
|
25
|
+
task :snooze do
|
26
|
+
sleep 2
|
27
|
+
end
|
28
|
+
task :default => :sleep
|
29
|
+
|
30
|
+
require 'stickshift'
|
31
|
+
::Rake::Application.instrument :top_level
|
32
|
+
::Rake::Application.instrument :[], :with_args => 0
|
33
|
+
::Rake::Task.instrument :invoke, :execute, :inspect_self => true
|
34
|
+
|
35
|
+
Running 'rake' will produce the following output. Method self time is
|
36
|
+
shown along the left, while method total time is at the end of each
|
37
|
+
line.
|
38
|
+
|
39
|
+
0ms > Rake::Application#top_level < 3001ms
|
40
|
+
0ms > Rake::Application#[]("default") < 0ms
|
41
|
+
0ms > Rake::Task#invoke{<Rake::Task default => [sleep]>} < 3001ms
|
42
|
+
0ms > Rake::Application#[]("sleep") < 0ms
|
43
|
+
0ms > Rake::Application#[]("snooze") < 0ms
|
44
|
+
2000ms > Rake::Task#execute{<Rake::Task snooze => []>} < 2000ms
|
45
|
+
1000ms > Rake::Task#execute{<Rake::Task sleep => [snooze]>} < 1000ms
|
46
|
+
0ms > Rake::Task#execute{<Rake::Task default => [sleep]>} < 0ms
|
47
|
+
|
48
|
+
## Instrumentation
|
49
|
+
|
50
|
+
Stickshift adds a method named #instrument to the Module class that
|
51
|
+
instruments methods in the receiver module or class.
|
52
|
+
|
53
|
+
It accepts one or more method names, and an optional trailing hash of
|
54
|
+
options:
|
55
|
+
|
56
|
+
* `:label => "label"` gives the instrumented method a custom label
|
57
|
+
instead of the default "Class#method" label.
|
58
|
+
* `:with_args => 0` causes the first argument to the method to be
|
59
|
+
included in the label. Ranges can also be used.
|
60
|
+
* `:inspect_self => true` causes the inspected object to be printed in
|
61
|
+
the label.
|
62
|
+
* `:top_level => true` causes Stickshift to only be activated after
|
63
|
+
passing through this method. If any other non-top-level instrumented
|
64
|
+
method is called outside of a top-level method, it will not be timed
|
65
|
+
or reported.
|
66
|
+
|
67
|
+
`#uninstrument` and `#uninstrument_all` methods are also available if
|
68
|
+
you wish to disable instrumentation.
|
69
|
+
|
70
|
+
## Capture/Settings
|
71
|
+
|
72
|
+
* `Stickshift.enabled` (default `true`) controls whether Stickshift is
|
73
|
+
on or not.
|
74
|
+
* `Stickshift.output` (default `$stdout`) controls where output is
|
75
|
+
written. The object must respond to `#puts(*lines)`.
|
data/Rakefile
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'rake/testtask'
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'hoe'
|
5
|
+
Hoe.plugin :rubyforge
|
6
|
+
hoe = Hoe.spec("stickshift") do |p|
|
7
|
+
require File.dirname(__FILE__) + '/lib/stickshift/version'
|
8
|
+
p.version = Stickshift::VERSION
|
9
|
+
p.rubyforge_name = "caldersphere"
|
10
|
+
p.url = "http://caldersphere.rubyforge.org/stickshift"
|
11
|
+
p.readme_file = "README.markdown"
|
12
|
+
p.author = "Nick Sieger"
|
13
|
+
p.email = "nick@nicksieger.com"
|
14
|
+
p.summary = "Stickshift is a pedal-to-the-metal manual profiler."
|
15
|
+
p.description = "Stickshift is a simple, manual-instrumenting call-tree profiler in as few lines of code as possible."
|
16
|
+
end
|
17
|
+
|
18
|
+
task :gemspec do
|
19
|
+
File.open("#{hoe.name}.gemspec", "w") {|f| f << hoe.spec.to_ruby }
|
20
|
+
end
|
21
|
+
task :package => :gemspec
|
22
|
+
rescue LoadError
|
23
|
+
puts "You need hoe installed to be able to package this gem"
|
24
|
+
end
|
25
|
+
|
26
|
+
# Hoe has its own test, but I want Rake::TestTask
|
27
|
+
Rake::Task['test'].send :instance_variable_set, "@actions", []
|
28
|
+
Rake::TestTask.new
|
29
|
+
|
30
|
+
task :default => :test
|
31
|
+
|
32
|
+
desc "Run the instrumented rake example"
|
33
|
+
task :example do
|
34
|
+
puts "# Here is the example Rakefile"
|
35
|
+
puts *(File.readlines("examples/example.rake"))
|
36
|
+
puts "# Running it"
|
37
|
+
ruby "-Ilib -S rake -f examples/example.rake"
|
38
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
task :sleep => :snooze do
|
2
|
+
sleep 1
|
3
|
+
end
|
4
|
+
task :snooze do
|
5
|
+
sleep 2
|
6
|
+
end
|
7
|
+
task :default => :sleep
|
8
|
+
|
9
|
+
require 'stickshift'
|
10
|
+
::Rake::Application.instrument :top_level
|
11
|
+
::Rake::Application.instrument :[], :with_args => 0
|
12
|
+
::Rake::Task.instrument :invoke, :execute, :inspect_self => true
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# Instrument some of the main methods hit during a Rails request dispatch.
|
2
|
+
# Put stickshift.rb in the 'lib' directory of your rails app and this file
|
3
|
+
# in the config/initializers directory.
|
4
|
+
|
5
|
+
require 'stickshift'
|
6
|
+
require 'dispatcher'
|
7
|
+
require 'action_controller'
|
8
|
+
|
9
|
+
class << Dispatcher; instrument :dispatch, :label => "Rails Dispatcher", :top_level => true; end
|
10
|
+
class << ActionController::Base; instrument :process; end
|
11
|
+
ActionController::Base.instrument :default_render, :respond_to
|
12
|
+
ActionController::Base.instance_methods.select {|m| m =~ /^(process|perform_action)/ }.each do |m|
|
13
|
+
ActionController::Base.instrument m
|
14
|
+
end
|
15
|
+
ActionController::Base.private_instance_methods.select {|m| m =~ /^(process|perform_action)/ }.each do |m|
|
16
|
+
ActionController::Base.instrument m
|
17
|
+
end
|
18
|
+
ObjectSpace.each_object(Class) do |klazz|
|
19
|
+
klazz.instrument :run, :call, :inspect_self => true if klazz < ActionController::Filters::ClassMethods::Filter
|
20
|
+
end
|
21
|
+
ActionController::Base.instance_methods.select {|m| m =~ /^render/ }.each do |m|
|
22
|
+
ActionController::Base.instrument m, :with_args => 0
|
23
|
+
end
|
24
|
+
ActionController::Routing::RouteSet.instrument :recognize
|
25
|
+
ActionView::Base.instrument :render
|
26
|
+
|
27
|
+
class << ActiveRecord::Base; instrument :find; end
|
28
|
+
ActiveRecord::Base.instrument :save
|
29
|
+
ActiveRecord::ConnectionAdapters.constants.each do |c|
|
30
|
+
adapter_class = ActiveRecord::ConnectionAdapters.const_get(c)
|
31
|
+
if adapter_class < ActiveRecord::ConnectionAdapters::AbstractAdapter
|
32
|
+
adapter_class.instrument :execute, :with_args => 0
|
33
|
+
end
|
34
|
+
end
|
data/lib/stickshift.rb
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
module Stickshift
|
2
|
+
class << self; attr_accessor :enabled, :top_level_trigger, :output; end
|
3
|
+
@enabled = true
|
4
|
+
@output = $stdout
|
5
|
+
|
6
|
+
class Timer
|
7
|
+
def self.current; Thread.current['__stickshift']; end
|
8
|
+
def self.current=(timer); Thread.current['__stickshift'] = timer; end
|
9
|
+
attr_reader :depth
|
10
|
+
|
11
|
+
def initialize(obj, meth, options, *args)
|
12
|
+
@depth, @options, @args = 1, options, args
|
13
|
+
@label = if @options[:label]
|
14
|
+
@options[:label]
|
15
|
+
else
|
16
|
+
klass = Class === obj ? "#{obj.name}." : "#{obj.class.name}#"
|
17
|
+
"#{klass}#{meth}"
|
18
|
+
end
|
19
|
+
@label << "{#{obj.inspect}}" if @options[:inspect_self]
|
20
|
+
@label << "(#{@args[@options[:with_args]].inspect})" if @options[:with_args]
|
21
|
+
if @parent = Timer.current
|
22
|
+
@parent.add(self)
|
23
|
+
@depth = @parent.depth + 1
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def enabled?
|
28
|
+
Stickshift.enabled && (Timer.current || Stickshift.top_level_trigger.nil? || @options[:top_level])
|
29
|
+
end
|
30
|
+
|
31
|
+
def invoke(&block)
|
32
|
+
return block.call unless enabled?
|
33
|
+
begin
|
34
|
+
Timer.current = self
|
35
|
+
result = nil
|
36
|
+
@elapsed = realtime do
|
37
|
+
result = block.call
|
38
|
+
end
|
39
|
+
result
|
40
|
+
ensure
|
41
|
+
Timer.current = @parent
|
42
|
+
report unless @parent
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def realtime
|
47
|
+
start = Time.now
|
48
|
+
yield
|
49
|
+
Time.now - start
|
50
|
+
end
|
51
|
+
|
52
|
+
def add(child)
|
53
|
+
children << child
|
54
|
+
end
|
55
|
+
|
56
|
+
def children
|
57
|
+
@children ||= []
|
58
|
+
end
|
59
|
+
|
60
|
+
def elapsed
|
61
|
+
@elapsed ||= 0
|
62
|
+
end
|
63
|
+
|
64
|
+
def report
|
65
|
+
Stickshift.output.puts "#{self_format % self_time}ms >#{' ' * @depth}#{@label} < #{total_time}ms"
|
66
|
+
children.each {|c| c.report}
|
67
|
+
end
|
68
|
+
|
69
|
+
def ms(t)
|
70
|
+
(t * 1000)
|
71
|
+
end
|
72
|
+
|
73
|
+
def self_format
|
74
|
+
@self_format ||= if @parent
|
75
|
+
@parent.self_format
|
76
|
+
else
|
77
|
+
width = ("%0.2f" % total_time).length
|
78
|
+
"%#{width}.2f"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def self_time
|
83
|
+
@self_time ||= ms(elapsed - children.inject(0) {|sum,el| sum += el.elapsed})
|
84
|
+
end
|
85
|
+
|
86
|
+
def total_time
|
87
|
+
ms(elapsed)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
class Module
|
93
|
+
def instrument(*meths)
|
94
|
+
options = Hash === meths.last ? meths.pop : {}
|
95
|
+
Stickshift.top_level_trigger = true if options[:top_level]
|
96
|
+
@__stickshift ||= {}
|
97
|
+
meths.each do |meth|
|
98
|
+
unless instrumented?(meth)
|
99
|
+
mangled = __stickshift_mangle(meth)
|
100
|
+
meth_opts = options.merge(:original => meth)
|
101
|
+
@__stickshift[mangled] = meth_opts
|
102
|
+
define_method("#{mangled}__instrumented") { meth_opts }
|
103
|
+
alias_method "#{mangled}__orig_instrument", meth
|
104
|
+
alias_method "#{mangled}__without_instrument", meth
|
105
|
+
module_eval(<<-METH, __FILE__, __LINE__)
|
106
|
+
def #{meth}(*args, &block)
|
107
|
+
Stickshift::Timer.new(self, "#{meth}", #{mangled}__instrumented, *args).invoke do
|
108
|
+
#{mangled}__without_instrument(*args, &block)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
METH
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
RESTRICTED_CLASSES = [String]
|
117
|
+
RESTRICTED_METHODS = %w(inspect __send__ __id__)
|
118
|
+
|
119
|
+
def instrumented?(meth)
|
120
|
+
RESTRICTED_CLASSES.include?(self) ||
|
121
|
+
RESTRICTED_METHODS.include?(meth.to_s) ||
|
122
|
+
meth =~ /__instrumented$/ ||
|
123
|
+
instance_methods.include?("#{__stickshift_mangle(meth)}__instrumented")
|
124
|
+
end
|
125
|
+
|
126
|
+
def uninstrument(*meths)
|
127
|
+
meths.each do |meth|
|
128
|
+
if instrumented?(meth)
|
129
|
+
remove_method "#{__stickshift_mangle(meth)}__instrumented"
|
130
|
+
alias_method meth, "#{__stickshift_mangle(meth)}__orig_instrument"
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def uninstrument_all
|
136
|
+
uninstrument(*(instance_methods.select {|m| m =~ /__instrumented$/}.map {|mi| @__stickshift[mi[0...-14]][:original]}))
|
137
|
+
end
|
138
|
+
|
139
|
+
def __stickshift_mangle(meth)
|
140
|
+
(s = meth.to_s) =~ /^[a-zA-Z_][a-zA-Z0-9_]*$/ ? s : "_#{s.unpack("H*")[0]}"
|
141
|
+
end
|
142
|
+
end
|
data/stickshift.gemspec
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{stickshift}
|
5
|
+
s.version = "0.1"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Nick Sieger"]
|
9
|
+
s.date = %q{2011-04-25}
|
10
|
+
s.description = %q{Stickshift is a simple, manual-instrumenting call-tree profiler in as few lines of code as possible.}
|
11
|
+
s.email = %q{nick@nicksieger.com}
|
12
|
+
s.extra_rdoc_files = ["History.txt", "LICENSE.txt", "Manifest.txt"]
|
13
|
+
s.files = ["examples/example.rake", "examples/stickshift_rails.rb", "History.txt", "lib/stickshift/version.rb", "lib/stickshift.rb", "LICENSE.txt", "Manifest.txt", "Rakefile", "README.markdown", "stickshift.gemspec", "test/test_stickshift.rb", ".gemtest"]
|
14
|
+
s.homepage = %q{http://caldersphere.rubyforge.org/stickshift}
|
15
|
+
s.rdoc_options = ["--main", "README.markdown"]
|
16
|
+
s.require_paths = ["lib"]
|
17
|
+
s.rubyforge_project = %q{caldersphere}
|
18
|
+
s.rubygems_version = %q{1.5.1}
|
19
|
+
s.summary = %q{Stickshift is a pedal-to-the-metal manual profiler.}
|
20
|
+
s.test_files = ["test/test_stickshift.rb"]
|
21
|
+
|
22
|
+
if s.respond_to? :specification_version then
|
23
|
+
s.specification_version = 3
|
24
|
+
|
25
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
26
|
+
s.add_development_dependency(%q<rubyforge>, [">= 2.0.4"])
|
27
|
+
s.add_development_dependency(%q<hoe>, [">= 2.9.4"])
|
28
|
+
else
|
29
|
+
s.add_dependency(%q<rubyforge>, [">= 2.0.4"])
|
30
|
+
s.add_dependency(%q<hoe>, [">= 2.9.4"])
|
31
|
+
end
|
32
|
+
else
|
33
|
+
s.add_dependency(%q<rubyforge>, [">= 2.0.4"])
|
34
|
+
s.add_dependency(%q<hoe>, [">= 2.9.4"])
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,158 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'stringio'
|
3
|
+
require 'stickshift'
|
4
|
+
|
5
|
+
class Foo
|
6
|
+
def slow_method
|
7
|
+
sleep 0.1
|
8
|
+
end
|
9
|
+
def hello
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class Bar
|
14
|
+
def slow_method
|
15
|
+
call_foo
|
16
|
+
end
|
17
|
+
|
18
|
+
def call_foo
|
19
|
+
Foo.new.slow_method
|
20
|
+
end
|
21
|
+
|
22
|
+
def several_times
|
23
|
+
10.times do
|
24
|
+
slow_method
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def call(*args)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
module TestHelper
|
33
|
+
def instrumented_name(meth)
|
34
|
+
Module.__stickshift_mangle(meth) + '__instrumented'
|
35
|
+
end
|
36
|
+
module_function :instrumented_name
|
37
|
+
end
|
38
|
+
|
39
|
+
class StickshiftTest < Test::Unit::TestCase
|
40
|
+
include TestHelper
|
41
|
+
|
42
|
+
def capture
|
43
|
+
Stickshift.output = @stdout = StringIO.new
|
44
|
+
@out = nil
|
45
|
+
end
|
46
|
+
|
47
|
+
def teardown
|
48
|
+
Foo.uninstrument_all
|
49
|
+
Bar.uninstrument_all
|
50
|
+
Array.uninstrument_all
|
51
|
+
String.uninstrument_all
|
52
|
+
puts @out if @out
|
53
|
+
Stickshift.top_level_trigger = nil
|
54
|
+
Stickshift.output = $stdout
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_formatting
|
58
|
+
Bar.instrument :slow_method, :several_times
|
59
|
+
Foo.instrument :slow_method
|
60
|
+
Bar.new.several_times
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_output_profile
|
64
|
+
Bar.instrument :slow_method
|
65
|
+
Foo.instrument :slow_method
|
66
|
+
capture
|
67
|
+
Bar.new.slow_method
|
68
|
+
out = @stdout.string
|
69
|
+
assert out =~ /Bar#slow_method/
|
70
|
+
assert out =~ /Foo#slow_method/
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_custom_label
|
74
|
+
capture
|
75
|
+
Foo.instrument :hello, :label => "Hello World!"
|
76
|
+
Foo.new.hello
|
77
|
+
assert @stdout.string =~ /Hello World!/
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_instrument_uninstrument
|
81
|
+
capture
|
82
|
+
Foo.new.hello
|
83
|
+
assert @stdout.string.empty?
|
84
|
+
Foo.instrument :hello
|
85
|
+
Foo.new.hello
|
86
|
+
assert @stdout.string =~ /Foo#hello/
|
87
|
+
@stdout.string = ''
|
88
|
+
Foo.uninstrument :hello
|
89
|
+
Foo.new.hello
|
90
|
+
assert @stdout.string.empty?
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_instrument_with_first_arg
|
94
|
+
capture
|
95
|
+
Bar.instrument :call, :with_args => 0
|
96
|
+
Bar.new.call("abc")
|
97
|
+
Bar.new.call("def")
|
98
|
+
assert @stdout.string =~ /call.*"abc"/
|
99
|
+
assert @stdout.string =~ /call.*"def"/
|
100
|
+
end
|
101
|
+
|
102
|
+
def test_instrument_operator_method
|
103
|
+
capture
|
104
|
+
Array.instrument :<<
|
105
|
+
[] << 1
|
106
|
+
assert @stdout.string =~ /<</
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_instrument_label_self_inspect
|
110
|
+
capture
|
111
|
+
Array.instrument :length, :inspect_self => true
|
112
|
+
%w(a b c).length
|
113
|
+
assert @stdout.string =~ /"a", "b", "c"/
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_output_only_when_triggered_by_top_level_method
|
117
|
+
capture
|
118
|
+
Foo.instrument :slow_method
|
119
|
+
Bar.instrument :slow_method
|
120
|
+
Bar.new.slow_method
|
121
|
+
|
122
|
+
assert !@stdout.string.empty?
|
123
|
+
expected = @stdout.string
|
124
|
+
@stdout.reopen(StringIO.new)
|
125
|
+
assert @stdout.string.empty?
|
126
|
+
|
127
|
+
Bar.uninstrument :slow_method
|
128
|
+
Bar.instrument :slow_method, :top_level => true
|
129
|
+
assert Stickshift.top_level_trigger
|
130
|
+
|
131
|
+
Foo.new.slow_method
|
132
|
+
assert @stdout.string.empty?
|
133
|
+
|
134
|
+
Bar.new.slow_method
|
135
|
+
assert @stdout.string =~ /Bar#slow_method.*Foo#slow_method/m
|
136
|
+
end
|
137
|
+
|
138
|
+
def test_cannot_instrument_instrumented_methods
|
139
|
+
Foo.instrument :slow_method
|
140
|
+
assert Foo.instrumented?(:slow_method)
|
141
|
+
instrumented = instrumented_name(:slow_method)
|
142
|
+
assert Foo.instance_methods.include?(instrumented)
|
143
|
+
Foo.instrument instrumented
|
144
|
+
assert !Foo.instance_methods.include?(instrumented_name(instrumented))
|
145
|
+
end
|
146
|
+
|
147
|
+
def test_cannot_instrument_restricted_methods
|
148
|
+
[:inspect, :__send__, :__id__].each do |m|
|
149
|
+
Foo.instrument m
|
150
|
+
assert !Foo.instance_methods.include?(instrumented_name(m))
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def test_cannot_instrument_string_or_benchmark_methods
|
155
|
+
String.instrument :to_s
|
156
|
+
assert !String.instance_methods.include?(instrumented_name(:to_s))
|
157
|
+
end
|
158
|
+
end
|
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: stickshift
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: "0.1"
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Nick Sieger
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-04-25 00:00:00 -05:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: rubyforge
|
18
|
+
prerelease: false
|
19
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - ">="
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 2.0.4
|
25
|
+
type: :development
|
26
|
+
version_requirements: *id001
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: hoe
|
29
|
+
prerelease: false
|
30
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
31
|
+
none: false
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: 2.9.4
|
36
|
+
type: :development
|
37
|
+
version_requirements: *id002
|
38
|
+
description: Stickshift is a simple, manual-instrumenting call-tree profiler in as few lines of code as possible.
|
39
|
+
email: nick@nicksieger.com
|
40
|
+
executables: []
|
41
|
+
|
42
|
+
extensions: []
|
43
|
+
|
44
|
+
extra_rdoc_files:
|
45
|
+
- History.txt
|
46
|
+
- LICENSE.txt
|
47
|
+
- Manifest.txt
|
48
|
+
files:
|
49
|
+
- examples/example.rake
|
50
|
+
- examples/stickshift_rails.rb
|
51
|
+
- History.txt
|
52
|
+
- lib/stickshift/version.rb
|
53
|
+
- lib/stickshift.rb
|
54
|
+
- LICENSE.txt
|
55
|
+
- Manifest.txt
|
56
|
+
- Rakefile
|
57
|
+
- README.markdown
|
58
|
+
- stickshift.gemspec
|
59
|
+
- test/test_stickshift.rb
|
60
|
+
- .gemtest
|
61
|
+
has_rdoc: true
|
62
|
+
homepage: http://caldersphere.rubyforge.org/stickshift
|
63
|
+
licenses: []
|
64
|
+
|
65
|
+
post_install_message:
|
66
|
+
rdoc_options:
|
67
|
+
- --main
|
68
|
+
- README.markdown
|
69
|
+
require_paths:
|
70
|
+
- lib
|
71
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: "0"
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
|
+
none: false
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: "0"
|
83
|
+
requirements: []
|
84
|
+
|
85
|
+
rubyforge_project: caldersphere
|
86
|
+
rubygems_version: 1.5.1
|
87
|
+
signing_key:
|
88
|
+
specification_version: 3
|
89
|
+
summary: Stickshift is a pedal-to-the-metal manual profiler.
|
90
|
+
test_files:
|
91
|
+
- test/test_stickshift.rb
|