fiveruns-dash-ruby 0.7.0

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.
@@ -0,0 +1,204 @@
1
+ require File.dirname(__FILE__) << "/test_helper"
2
+
3
+ class MetricTest < Test::Unit::TestCase
4
+
5
+ attr_reader :metric
6
+
7
+ def self.time_me(val=0)
8
+ if val == 0
9
+ time_me(1)
10
+ end
11
+ sleep 0.01
12
+ end
13
+
14
+ context "Metric" do
15
+
16
+ teardown do
17
+ # Hacked 'uninstrument' until it's built-in
18
+ ::Fiveruns::Dash::Instrument.handlers.each do |handler|
19
+ (class << MetricTest; self; end).class_eval <<-EOCE
20
+ remove_method :time_me_with_instrument_#{handler.hash}
21
+ alias_method :time_me, :time_me_without_instrument_#{handler.hash}
22
+ remove_method :time_me_without_instrument_#{handler.hash}
23
+ EOCE
24
+ end
25
+ ::Fiveruns::Dash::Instrument.handlers.clear
26
+ end
27
+
28
+ context "should parse arguments for name, description and help_text" do
29
+ setup do
30
+ @options = Hash.new
31
+ @options[:method] = time_method
32
+ @metric = TimeMetric.new(:name, "Description", "HelpText", :method => time_method)
33
+ end
34
+
35
+ should "interpret name" do
36
+ assert_equal "name", @metric.name
37
+ end
38
+
39
+ should "interpret description" do
40
+ assert_equal "Description", @metric.description
41
+ end
42
+
43
+ should "interpret help text" do
44
+ assert_equal "HelpText", @metric.help_text
45
+ end
46
+
47
+ should "interpret options" do
48
+ assert_equal @options, @metric.options
49
+ end
50
+ end
51
+
52
+ context "should parse arguments for name, description using defaults" do
53
+ setup do
54
+ @options = Hash.new
55
+ @options[:method] = time_method
56
+ @metric = TimeMetric.new(:name, :method => time_method)
57
+ end
58
+
59
+ should "interpret name" do
60
+ assert_equal "name", @metric.name
61
+ end
62
+
63
+ should "default description to titleized name" do
64
+ assert_equal "Name", @metric.description
65
+ end
66
+
67
+ should "default help text to nil" do
68
+ assert_nil @metric.help_text
69
+ end
70
+
71
+ should "interpret options" do
72
+ assert_equal @options, @metric.options
73
+ end
74
+ end
75
+
76
+ context "using reentrant time" do
77
+ setup do
78
+ @metric = TimeMetric.new(:time_mes, :method => time_method, :reentrant => true)
79
+ flexmock(@metric).should_receive(:info_id).and_return(1)
80
+ end
81
+ teardown do
82
+ # Hacked 'uninstrument' until it's built-in
83
+ ::Fiveruns::Dash::Instrument.handlers.each do |handler|
84
+ (class << MetricTest; self; end).class_eval <<-EOCE
85
+ remove_method :time_me_with_instrument_#{handler.hash}
86
+ alias_method :time_me, :time_me_without_instrument_#{handler.hash}
87
+ remove_method :time_me_without_instrument_#{handler.hash}
88
+ EOCE
89
+ end
90
+ ::Fiveruns::Dash::Instrument.handlers.clear
91
+ end
92
+ should "get correct number of invocations" do
93
+ invoke 4
94
+ assert_invocations_reported 4
95
+ invoke 1
96
+ assert_invocations_reported 1
97
+ end
98
+ end
99
+
100
+ context "using time" do
101
+ setup do
102
+ @metric = TimeMetric.new(:time_mes, :method => time_method)
103
+ flexmock(@metric).should_receive(:info_id).and_return(1)
104
+ end
105
+ teardown do
106
+ # Hacked 'uninstrument' until it's built-in
107
+ ::Fiveruns::Dash::Instrument.handlers.each do |handler|
108
+ (class << MetricTest; self; end).class_eval <<-EOCE
109
+ remove_method :time_me_with_instrument_#{handler.hash}
110
+ alias_method :time_me, :time_me_without_instrument_#{handler.hash}
111
+ remove_method :time_me_without_instrument_#{handler.hash}
112
+ EOCE
113
+ end
114
+ ::Fiveruns::Dash::Instrument.handlers.clear
115
+ end
116
+ should "raise exception without :on option" do
117
+ assert_raises ArgumentError do
118
+ TimeMetric.new(:time_mes, 'A Name')
119
+ end
120
+ end
121
+ should "get correct number of invocations" do
122
+ invoke 4
123
+ assert_invocations_reported 8
124
+ invoke 1
125
+ assert_invocations_reported 2
126
+ end
127
+ should "time invocations" do
128
+ last_total = 0
129
+ 4.times do |i|
130
+ invoke
131
+ assert_equal (i + 1)*2, current_invocations
132
+ reported_total = current_time_total
133
+ assert(reported_total > last_total)
134
+ last_total = reported_total
135
+ end
136
+ metric.data # clears
137
+ assert_equal 0, current_time_total
138
+ end
139
+ should "have correct info" do
140
+ assert_equal 'time_mes', metric.info[:name]
141
+ assert_equal 'Time Mes', metric.info[:description]
142
+ end
143
+ should "be able to set context finder" do
144
+ finder = lambda { |obj, *args| [:class, obj.name] }
145
+ @metric.find_context_with(&finder)
146
+ invoke 4
147
+ assert_equal 8, metric.data[:values].select { |m| m[:context] == [:class, 'MetricTest'] }.first[:invocations]
148
+ end
149
+ end
150
+
151
+ context "using incremented counter" do
152
+ setup do
153
+ @metric = CounterMetric.new(:time_mes_counter, :incremented_by => time_method)
154
+ flexmock(@metric).should_receive(:info_id).and_return(1)
155
+ end
156
+ should "default to 0 before being incremented, and after reset" do
157
+ assert_counted 0
158
+ invoke 4
159
+ assert_counted 8
160
+ assert_counted 0
161
+ end
162
+ should "get correct number after being incremented" do
163
+ invoke 4
164
+ assert_counted 8
165
+ end
166
+ end
167
+
168
+ end
169
+
170
+ #######
171
+ private
172
+ #######
173
+
174
+ def current_time_total
175
+ metric.instance_eval { @data[[]][:value] }
176
+ end
177
+
178
+ def current_invocations
179
+ metric.instance_eval { @data[[]][:invocations] }
180
+ end
181
+
182
+ def time_method
183
+ 'MetricTest.time_me'
184
+ end
185
+
186
+ def assert_counted(number)
187
+ counted = nil
188
+ assert_nothing_raised do
189
+ # We fetch to ensure values aren't just being returned due to hash defaults
190
+ counted = metric.data[:values].detect { |m| m[:context] == [] }[:value]
191
+ end
192
+ assert_kind_of Numeric, counted
193
+ assert_equal number, counted
194
+ end
195
+
196
+ def assert_invocations_reported(number = 1)
197
+ assert_equal number, metric.data[:values].detect { |m| m[:context] == [] }[:invocations]
198
+ end
199
+
200
+ def invoke(number = 1)
201
+ number.times { MetricTest.time_me }
202
+ end
203
+
204
+ end
@@ -0,0 +1,146 @@
1
+ require File.dirname(__FILE__) << "/test_helper"
2
+
3
+ class RecipeTest < Test::Unit::TestCase
4
+
5
+ attr_reader :config
6
+
7
+ context "Recipe" do
8
+
9
+ setup do
10
+ mock_streams!
11
+ Fiveruns::Dash.recipes.clear
12
+ @config = Fiveruns::Dash::Configuration.new
13
+ end
14
+
15
+ teardown do
16
+ restore_streams!
17
+ end
18
+
19
+ context "when registering" do
20
+ context "with valid metadata" do
21
+ setup do
22
+ assert_nothing_raised do
23
+ recipe do |metrics|
24
+ metrics.counter :foo do
25
+ 1
26
+ end
27
+ end
28
+ end
29
+ end
30
+ should "is added to available recipes" do
31
+ assert_equal 1, Fiveruns::Dash.recipes.size
32
+ assert_kind_of Array, Fiveruns::Dash.recipes[:test]
33
+ assert_kind_of Fiveruns::Dash::Recipe, Fiveruns::Dash.recipes[:test].first
34
+ end
35
+ end
36
+ context "without url" do
37
+ should "raise error" do
38
+ assert_raises Fiveruns::Dash::Recipe::ConfigurationError do
39
+ recipe(:test, {}) do |metrics|
40
+ metrics.counter :foo do
41
+ 1
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+ end
49
+
50
+ context "when adding" do
51
+ context "with single matching recipe" do
52
+ setup do
53
+ recipe :test, :url => 'http://test1.com' do |r|
54
+ r.counter(:test1) { }
55
+ end
56
+ config.add_recipe :test
57
+ end
58
+ should "description" do
59
+ assert_metrics(*%w(test1))
60
+ end
61
+ end
62
+ context "with multiple similiarly-named recipes" do
63
+ setup do
64
+ recipe :test, :url => 'http://test1.com' do |r|
65
+ r.counter(:test1) { }
66
+ end
67
+ recipe :test, :url => 'http://test2.com' do |r|
68
+ r.counter(:test2) { }
69
+ end
70
+ end
71
+ should "load all by default" do
72
+ config.add_recipe :test
73
+ assert_equal 2, config.metrics.size
74
+ assert_metrics(*%w(test1 test2))
75
+ end
76
+ should "allow specific recipe to be loaded" do
77
+ config.add_recipe :test, :url => 'http://test2.com'
78
+ assert_equal 1, config.metrics.size
79
+ assert_metrics(*%w(test2))
80
+ end
81
+ end
82
+ end
83
+
84
+ context "when added" do
85
+ setup do
86
+ @fired = false
87
+ recipe :test, :url => 'http://test.com' do |recipe|
88
+ recipe.added do
89
+ @fired = true
90
+ end
91
+ recipe.counter(:countme) { }
92
+ end
93
+ end
94
+ should "fire recipe hook" do
95
+ config.add_recipe :test
96
+ assert @fired
97
+ end
98
+ should "allow metrics with same name and different recipes" do
99
+ config.counter(:countme) { }
100
+ config.add_recipe :test
101
+ assert_metrics(*%w(countme countme))
102
+ end
103
+ context "modifying existing metrics" do
104
+ setup do
105
+ recipe :test3 do |r|
106
+ r.modify :name => :countme do |metric|
107
+ metric.find_context_with do |obj, *args|
108
+ [:modified, true]
109
+ end
110
+ end
111
+ end
112
+ end
113
+ should "only occur on addition" do
114
+ config.metrics.each do |metric|
115
+ if metric.name == 'countme'
116
+ assert_nil metric.instance_eval { @metric_finder }
117
+ end
118
+ end
119
+ end
120
+ should "change context finder" do
121
+ config.add_recipe :test3
122
+ config.metrics.each do |metric|
123
+ if metric.name == 'countme'
124
+ assert_kind_of Proc, metric.instance_eval { @metric_finder }
125
+ end
126
+ end
127
+ end
128
+ end
129
+
130
+ end
131
+
132
+ end
133
+
134
+ #######
135
+ private
136
+ #######
137
+
138
+ def assert_metrics(*names)
139
+ assert_equal names.sort, config.metrics.map(&:name).map(&:to_s).sort
140
+ end
141
+
142
+ def recipe(name = :test, options = {:url => 'http://test.com'}, &block)
143
+ Fiveruns::Dash.register_recipe(name, options, &block)
144
+ end
145
+
146
+ end
@@ -0,0 +1,60 @@
1
+ require File.dirname(__FILE__) << "/test_helper"
2
+
3
+ class Gizmo
4
+
5
+ def oops!
6
+ raise 'I made an oopsie!'
7
+ end
8
+
9
+ end
10
+
11
+ class ReliabilityTest < Test::Unit::TestCase
12
+
13
+ context "FiveRuns Dash" do
14
+
15
+ should 'not swallow user-created exceptions' do
16
+ dash do |metrics|
17
+ metrics.time(:oops, 'Time spent messing up', 'Ooops!',
18
+ :method => 'Gizmo#oops!')
19
+ end
20
+
21
+ assert_raises(RuntimeError) { Gizmo.new.oops! }
22
+ end
23
+
24
+ should 'report an exception if instrumentation cannot proceed' do
25
+ assert_raises(Fiveruns::Dash::Instrument::Error) do
26
+ dash do |metrics|
27
+ metrics.time(:wheee, 'Time spent having fun', 'Wheeee!',
28
+ :method => 'Gizmo.wheeeeeeee!')
29
+ metrics.time(:oops, 'Time spent messing up', 'Ooops!',
30
+ :method => 'Gizmo#oops!')
31
+ end
32
+ end
33
+ end
34
+
35
+ should 'not proceed with instrumentation if an error occurs' do
36
+ begin
37
+ dash do |metrics|
38
+ metrics.time(:wheee, 'Time spent having fun', 'Wheeee!',
39
+ :method => 'Gizmo.wheeeeeeee!')
40
+ metrics.time(:oops, 'Time spent messing up', 'Ooops!',
41
+ :method => 'Gizmo#oops!')
42
+ end
43
+ rescue Fiveruns::Dash::Instrument::Error
44
+ end
45
+ assert_equal 0, Fiveruns::Dash.configuration.metrics.length
46
+ end
47
+
48
+ should 'not modify Thread.abort_on_exception if the user has set it' do
49
+ assert !Thread.abort_on_exception
50
+ end
51
+
52
+ end
53
+
54
+ def dash(&block)
55
+ Fiveruns::Dash.configure({:app => ENV['DASH_APP']}, &block)
56
+ Fiveruns::Dash.session.reporter.interval = 10
57
+ Fiveruns::Dash.session.start
58
+ end
59
+
60
+ end
@@ -0,0 +1,46 @@
1
+ require File.dirname(__FILE__) << "/test_helper"
2
+
3
+ class ReporterTest < Test::Unit::TestCase
4
+
5
+ include Fiveruns::Dash
6
+
7
+ attr_reader :reporter
8
+
9
+ context "Reporter" do
10
+
11
+ setup do
12
+ mock!
13
+ end
14
+
15
+ context "instance" do
16
+ setup do
17
+ @reporter = Reporter.new(@session)
18
+ end
19
+ should "start normally" do
20
+ assert !@reporter.started?
21
+ assert !@reporter.background?
22
+ @reporter.start
23
+ assert_kind_of Time, @reporter.started_at
24
+ assert @reporter.started?
25
+ assert @reporter.background?
26
+ assert !@restarted
27
+ end
28
+ should "allow restart" do
29
+ @reporter.start
30
+ time = @reporter.started_at
31
+ assert_kind_of Time, time
32
+ assert !@restarted
33
+ @reporter.start
34
+ assert @restarted
35
+ assert_equal time.to_f, @reporter.started_at.to_f
36
+ end
37
+ end
38
+
39
+ end
40
+
41
+ #######
42
+ private
43
+ #######
44
+
45
+
46
+ end