hitimes 0.4.1-x86-mswin32-60 → 1.0.0-x86-mswin32-60
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/HISTORY +10 -0
- data/README +74 -14
- data/ext/hitimes_interval.c +6 -3
- data/ext/hitimes_stats.c +31 -8
- data/gemspec.rb +4 -2
- data/lib/hitimes.rb +5 -1
- data/lib/hitimes/metric.rb +74 -0
- data/lib/hitimes/stats.rb +26 -1
- data/lib/hitimes/timed_metric.rb +181 -0
- data/lib/hitimes/timed_value_metric.rb +240 -0
- data/lib/hitimes/value_metric.rb +69 -0
- data/lib/hitimes/version.rb +23 -8
- data/lib/hitimes_ext.so +0 -0
- data/spec/metric_spec.rb +30 -0
- data/spec/stats_spec.rb +30 -2
- data/spec/timed_metric_spec.rb +155 -0
- data/spec/timed_value_metric_spec.rb +172 -0
- data/spec/value_metric_spec.rb +110 -0
- data/spec/version_spec.rb +6 -0
- data/tasks/config.rb +1 -1
- metadata +27 -8
- data/lib/hitimes/timer.rb +0 -223
- data/spec/timer_spec.rb +0 -105
@@ -0,0 +1,155 @@
|
|
1
|
+
require File.expand_path( File.join( File.dirname( __FILE__ ), "spec_helper.rb" ) )
|
2
|
+
|
3
|
+
require 'hitimes/timed_metric'
|
4
|
+
|
5
|
+
describe Hitimes::TimedMetric do
|
6
|
+
before( :each ) do
|
7
|
+
@tm = Hitimes::TimedMetric.new( 'test-timed-metric' )
|
8
|
+
end
|
9
|
+
|
10
|
+
it "knows if it is running or not" do
|
11
|
+
@tm.should_not be_running
|
12
|
+
@tm.start
|
13
|
+
@tm.should be_running
|
14
|
+
@tm.stop
|
15
|
+
@tm.should_not be_running
|
16
|
+
end
|
17
|
+
|
18
|
+
it "#split returns the last duration and the timer is still running" do
|
19
|
+
@tm.start
|
20
|
+
d = @tm.split
|
21
|
+
@tm.should be_running
|
22
|
+
d.should > 0
|
23
|
+
@tm.count.should == 1
|
24
|
+
@tm.duration.should == d
|
25
|
+
end
|
26
|
+
|
27
|
+
it "#stop returns false if called more than once in a row" do
|
28
|
+
@tm.start
|
29
|
+
@tm.stop.should > 0
|
30
|
+
@tm.stop.should == false
|
31
|
+
end
|
32
|
+
|
33
|
+
it "does not count a currently running interval as an interval in calculations" do
|
34
|
+
@tm.start
|
35
|
+
@tm.count.should == 0
|
36
|
+
@tm.split
|
37
|
+
@tm.count.should == 1
|
38
|
+
end
|
39
|
+
|
40
|
+
it "#split called on a stopped timer does nothing" do
|
41
|
+
@tm.start
|
42
|
+
@tm.stop
|
43
|
+
@tm.split.should == false
|
44
|
+
end
|
45
|
+
|
46
|
+
it "calculates the mean of the durations" do
|
47
|
+
2.times { @tm.start ; sleep 0.05 ; @tm.stop }
|
48
|
+
@tm.mean.should be_close( 0.05, 0.01 )
|
49
|
+
end
|
50
|
+
|
51
|
+
it "calculates the rate of the counts " do
|
52
|
+
5.times { @tm.start ; sleep 0.05 ; @tm.stop }
|
53
|
+
@tm.rate.should be_close( 20.00, 0.1 )
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
it "calculates the stddev of the durations" do
|
58
|
+
3.times { |x| @tm.start ; sleep (0.05 * x) ; @tm.stop }
|
59
|
+
@tm.stddev.should be_close( 0.05, 0.001)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "returns 0.0 for stddev if there is no data" do
|
63
|
+
@tm.stddev.should == 0.0
|
64
|
+
end
|
65
|
+
|
66
|
+
it "keeps track of the min value" do
|
67
|
+
2.times { @tm.start ; sleep 0.05 ; @tm.stop }
|
68
|
+
@tm.min.should be_close( 0.05, 0.001 )
|
69
|
+
end
|
70
|
+
|
71
|
+
it "keeps track of the max value" do
|
72
|
+
2.times { @tm.start ; sleep 0.05 ; @tm.stop }
|
73
|
+
@tm.max.should be_close( 0.05, 0.001 )
|
74
|
+
end
|
75
|
+
|
76
|
+
it "keeps track of the sum value" do
|
77
|
+
2.times { @tm.start ; sleep 0.05 ; @tm.stop }
|
78
|
+
@tm.sum.should be_close( 0.10, 0.001 )
|
79
|
+
end
|
80
|
+
|
81
|
+
it "keeps track of the sum of squars value" do
|
82
|
+
3.times { @tm.start ; sleep 0.05 ; @tm.stop }
|
83
|
+
@tm.sumsq.should be_close( 0.0075, 0.0001 )
|
84
|
+
end
|
85
|
+
|
86
|
+
it "keeps track of the minimum start time of all the intervals" do
|
87
|
+
f1 = Time.now.gmtime.to_f * 1000000
|
88
|
+
5.times { @tm.start ; sleep 0.05 ; @tm.stop }
|
89
|
+
f2 = Time.now.gmtime.to_f * 1000000
|
90
|
+
@tm.sampling_start_time.should > f1
|
91
|
+
@tm.sampling_start_time.should < f2
|
92
|
+
# distance from now to start time should be greater than the distance from
|
93
|
+
# the start to the min start_time
|
94
|
+
(f2 - @tm.sampling_start_time).should > ( @tm.sampling_start_time - f1 )
|
95
|
+
end
|
96
|
+
|
97
|
+
it "keeps track of the last stop time of all the intervals" do
|
98
|
+
f1 = Time.now.gmtime.to_f * 1000000
|
99
|
+
5.times { @tm.start ; sleep 0.05 ; @tm.stop }
|
100
|
+
f2 = Time.now.gmtime.to_f * 1000000
|
101
|
+
@tm.sampling_stop_time.should > f1
|
102
|
+
@tm.sampling_stop_time.should < f2
|
103
|
+
# distance from now to max stop time time should be less than the distance
|
104
|
+
# from the start to the max stop time
|
105
|
+
(f2 - @tm.sampling_stop_time).should < ( @tm.sampling_stop_time - f1 )
|
106
|
+
end
|
107
|
+
|
108
|
+
it "can create an already running timer" do
|
109
|
+
t = Hitimes::TimedMetric.now( 'already-running' )
|
110
|
+
t.should be_running
|
111
|
+
end
|
112
|
+
|
113
|
+
it "can measure a block of code from an instance" do
|
114
|
+
t = Hitimes::TimedMetric.new( 'measure a block' )
|
115
|
+
3.times { t.measure { sleep 0.05 } }
|
116
|
+
t.duration.should be_close( 0.15, 0.001 )
|
117
|
+
t.count.should == 3
|
118
|
+
end
|
119
|
+
|
120
|
+
it "returns the value of the block when measuring" do
|
121
|
+
t = Hitimes::TimedMetric.new( 'measure a block' )
|
122
|
+
x = t.measure { sleep 0.05; 42 }
|
123
|
+
t.duration.should be_close( 0.05, 0.001 )
|
124
|
+
x.should == 42
|
125
|
+
end
|
126
|
+
|
127
|
+
describe "#to_hash" do
|
128
|
+
|
129
|
+
it "has name value" do
|
130
|
+
h = @tm.to_hash
|
131
|
+
h['name'].should == "test-timed-metric"
|
132
|
+
end
|
133
|
+
|
134
|
+
it "has an empty has for additional_data" do
|
135
|
+
h = @tm.to_hash
|
136
|
+
h['additional_data'].should == Hash.new
|
137
|
+
h['additional_data'].size.should == 0
|
138
|
+
end
|
139
|
+
|
140
|
+
it "has the right sum" do
|
141
|
+
10.times { |x| @tm.measure { sleep 0.01*x } }
|
142
|
+
h = @tm.to_hash
|
143
|
+
h['sum'].should be_close( 0.45, 0.002 )
|
144
|
+
end
|
145
|
+
|
146
|
+
fields = ::Hitimes::Stats::STATS.dup + %w[ name additional_data sampling_start_time sampling_stop_time ]
|
147
|
+
fields.each do |f|
|
148
|
+
it "should have a value for #{f}" do
|
149
|
+
@tm.measure { sleep 0.001 }
|
150
|
+
h = @tm.to_hash
|
151
|
+
h[f].should_not be_nil
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
@@ -0,0 +1,172 @@
|
|
1
|
+
require File.expand_path( File.join( File.dirname( __FILE__ ), "spec_helper.rb" ) )
|
2
|
+
|
3
|
+
require 'hitimes/timed_value_metric'
|
4
|
+
|
5
|
+
describe Hitimes::TimedValueMetric do
|
6
|
+
before( :each ) do
|
7
|
+
@tm = Hitimes::TimedValueMetric.new( 'test-timed-value-metric' )
|
8
|
+
end
|
9
|
+
|
10
|
+
it "knows if it is running or not" do
|
11
|
+
@tm.should_not be_running
|
12
|
+
@tm.start
|
13
|
+
@tm.should be_running
|
14
|
+
@tm.stop( 1 )
|
15
|
+
@tm.should_not be_running
|
16
|
+
end
|
17
|
+
|
18
|
+
it "#split returns the last duration and the timer is still running" do
|
19
|
+
@tm.start
|
20
|
+
d = @tm.split( 1 )
|
21
|
+
@tm.should be_running
|
22
|
+
d.should > 0
|
23
|
+
@tm.value_stats.count.should == 1
|
24
|
+
@tm.timed_stats.count.should == 1
|
25
|
+
@tm.duration.should == d
|
26
|
+
end
|
27
|
+
|
28
|
+
it "#stop returns false if called more than once in a row" do
|
29
|
+
@tm.start
|
30
|
+
@tm.stop( 1 ).should > 0
|
31
|
+
@tm.stop( 1 ).should == false
|
32
|
+
end
|
33
|
+
|
34
|
+
it "does not count a currently running interval as an interval in calculations" do
|
35
|
+
@tm.start
|
36
|
+
@tm.value_stats.count.should == 0
|
37
|
+
@tm.timed_stats.count.should == 0
|
38
|
+
@tm.split( 1 )
|
39
|
+
@tm.value_stats.count.should == 1
|
40
|
+
@tm.timed_stats.count.should == 1
|
41
|
+
end
|
42
|
+
|
43
|
+
it "#split called on a stopped timer does nothing" do
|
44
|
+
@tm.start
|
45
|
+
@tm.stop( 1 )
|
46
|
+
@tm.split( 1 ).should == false
|
47
|
+
end
|
48
|
+
|
49
|
+
it "calculates the mean of the durations" do
|
50
|
+
3.times { |x| @tm.start ; sleep 0.05 ; @tm.stop(x) }
|
51
|
+
@tm.timed_stats.mean.should be_close( 0.05, 0.01 )
|
52
|
+
@tm.value_stats.mean.should == 1.00
|
53
|
+
end
|
54
|
+
|
55
|
+
it "calculates the rate of the counts " do
|
56
|
+
5.times { |x| @tm.start ; sleep 0.05 ; @tm.stop( x ) }
|
57
|
+
@tm.rate.should be_close( 40.0, 0.2)
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
it "calculates the stddev of the durations" do
|
62
|
+
3.times { |x| @tm.start ; sleep (0.05 * x) ; @tm.stop(x) }
|
63
|
+
@tm.timed_stats.stddev.should be_close( 0.05, 0.001)
|
64
|
+
@tm.value_stats.stddev.should == 1.0
|
65
|
+
end
|
66
|
+
|
67
|
+
it "returns 0.0 for stddev if there is no data" do
|
68
|
+
@tm.timed_stats.stddev.should == 0.0
|
69
|
+
@tm.value_stats.stddev.should == 0.0
|
70
|
+
end
|
71
|
+
|
72
|
+
it "keeps track of the min value" do
|
73
|
+
3.times { |x| @tm.start ; sleep 0.05 ; @tm.stop( x ) }
|
74
|
+
@tm.timed_stats.min.should be_close( 0.05, 0.001 )
|
75
|
+
@tm.value_stats.min.should == 0
|
76
|
+
end
|
77
|
+
|
78
|
+
it "keeps track of the max value" do
|
79
|
+
3.times { |x| @tm.start ; sleep 0.05 ; @tm.stop( x ) }
|
80
|
+
@tm.timed_stats.max.should be_close( 0.05, 0.001)
|
81
|
+
@tm.value_stats.max.should == 2
|
82
|
+
end
|
83
|
+
|
84
|
+
it "keeps track of the sum value" do
|
85
|
+
3.times { |x| @tm.start ; sleep 0.05 ; @tm.stop( x ) }
|
86
|
+
@tm.timed_stats.sum.should be_close( 0.15, 0.01 )
|
87
|
+
@tm.value_stats.sum.should == 3
|
88
|
+
end
|
89
|
+
|
90
|
+
it "keeps track of the sum of squares value" do
|
91
|
+
3.times { |x| @tm.start ; sleep 0.05 ; @tm.stop( x ) }
|
92
|
+
@tm.timed_stats.sumsq.should be_close( 0.0075, 0.0001 )
|
93
|
+
@tm.value_stats.sumsq.should == 5
|
94
|
+
end
|
95
|
+
|
96
|
+
it "keeps track of the minimum start time of all the intervals" do
|
97
|
+
f1 = Time.now.gmtime.to_f * 1000000
|
98
|
+
5.times { @tm.start ; sleep 0.05 ; @tm.stop( 1 ) }
|
99
|
+
f2 = Time.now.gmtime.to_f * 1000000
|
100
|
+
@tm.sampling_start_time.should > f1
|
101
|
+
@tm.sampling_start_time.should < f2
|
102
|
+
# distance from now to start time should be greater than the distance from
|
103
|
+
# the start to the min start_time
|
104
|
+
(f2 - @tm.sampling_start_time).should > ( @tm.sampling_start_time - f1 )
|
105
|
+
end
|
106
|
+
|
107
|
+
it "keeps track of the last stop time of all the intervals" do
|
108
|
+
f1 = Time.now.gmtime.to_f * 1000000
|
109
|
+
5.times { @tm.start ; sleep 0.05 ; @tm.stop( 1 ) }
|
110
|
+
f2 = Time.now.gmtime.to_f * 1000000
|
111
|
+
@tm.sampling_stop_time.should > f1
|
112
|
+
@tm.sampling_stop_time.should < f2
|
113
|
+
# distance from now to max stop time time should be less than the distance
|
114
|
+
# from the start to the max stop time
|
115
|
+
(f2 - @tm.sampling_stop_time).should < ( @tm.sampling_stop_time - f1 )
|
116
|
+
end
|
117
|
+
|
118
|
+
it "can create an already running timer" do
|
119
|
+
t = Hitimes::TimedValueMetric.now( 'already-running' )
|
120
|
+
t.should be_running
|
121
|
+
end
|
122
|
+
|
123
|
+
it "can measure a block of code from an instance" do
|
124
|
+
t = Hitimes::TimedValueMetric.new( 'measure a block' )
|
125
|
+
3.times { t.measure( 1 ) { sleep 0.05 } }
|
126
|
+
t.duration.should be_close( 0.15, 0.001 )
|
127
|
+
t.timed_stats.count.should == 3
|
128
|
+
t.value_stats.count.should == 3
|
129
|
+
end
|
130
|
+
|
131
|
+
it "returns the value of the block when measuring" do
|
132
|
+
t = Hitimes::TimedValueMetric.new( 'measure a block' )
|
133
|
+
x = t.measure( 42 ) { sleep 0.05; 42 }
|
134
|
+
t.duration.should be_close( 0.05, 0.001 )
|
135
|
+
x.should == 42
|
136
|
+
end
|
137
|
+
|
138
|
+
describe "#to_hash" do
|
139
|
+
|
140
|
+
it "has name value" do
|
141
|
+
h = @tm.to_hash
|
142
|
+
h['name'].should == "test-timed-value-metric"
|
143
|
+
end
|
144
|
+
|
145
|
+
it "has an empty has for additional_data" do
|
146
|
+
h = @tm.to_hash
|
147
|
+
h['additional_data'].should == Hash.new
|
148
|
+
h['additional_data'].size.should == 0
|
149
|
+
end
|
150
|
+
|
151
|
+
it "has a rate" do
|
152
|
+
5.times { |x| @tm.start ; sleep 0.05 ; @tm.stop( x ) }
|
153
|
+
h = @tm.to_hash
|
154
|
+
h['rate'].should be_close( 40.0, 0.2 )
|
155
|
+
end
|
156
|
+
|
157
|
+
it "has a unit_count" do
|
158
|
+
5.times { |x| @tm.start ; sleep 0.05 ; @tm.stop( x ) }
|
159
|
+
h = @tm.to_hash
|
160
|
+
h['unit_count'].should == 10
|
161
|
+
end
|
162
|
+
|
163
|
+
fields = %w[ name additional_data sampling_start_time sampling_stop_time value_stats timed_stats rate unit_count ]
|
164
|
+
fields.each do |f|
|
165
|
+
it "should have a value for #{f}" do
|
166
|
+
3.times { |x| @tm.measure(x) { sleep 0.001 } }
|
167
|
+
h = @tm.to_hash
|
168
|
+
h[f].should_not be_nil
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require File.expand_path( File.join( File.dirname( __FILE__ ), "spec_helper.rb" ) )
|
2
|
+
|
3
|
+
require 'hitimes/value_metric'
|
4
|
+
|
5
|
+
describe Hitimes::ValueMetric do
|
6
|
+
before( :each ) do
|
7
|
+
@metric = Hitimes::ValueMetric.new( "testing" )
|
8
|
+
10.times { |x| @metric.measure( x ) }
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'has a name' do
|
12
|
+
@metric.name.should == "testing"
|
13
|
+
end
|
14
|
+
|
15
|
+
it "has associated data from initialization" do
|
16
|
+
m = Hitimes::ValueMetric.new( "more-data", 'foo' => 'bar', 'this' => 'that' )
|
17
|
+
m.additional_data['foo'].should == 'bar'
|
18
|
+
m.additional_data['this'].should == 'that'
|
19
|
+
|
20
|
+
m = Hitimes::ValueMetric.new( "more-data", { 'foo' => 'bar', 'this' => 'that' } )
|
21
|
+
m.additional_data['foo'].should == 'bar'
|
22
|
+
m.additional_data['this'].should == 'that'
|
23
|
+
end
|
24
|
+
|
25
|
+
it "calculates the mean of the measurements" do
|
26
|
+
@metric.mean.should == 4.5
|
27
|
+
end
|
28
|
+
|
29
|
+
it "calculates the stddev of the measurements" do
|
30
|
+
@metric.stddev.should > 0.0
|
31
|
+
end
|
32
|
+
|
33
|
+
it "returns 0.0 for stddev if there is no data" do
|
34
|
+
m = Hitimes::ValueMetric.new('0-data')
|
35
|
+
m.stddev.should == 0.0
|
36
|
+
end
|
37
|
+
|
38
|
+
it "keeps track of the sum of data" do
|
39
|
+
@metric.sum.should == 45.0
|
40
|
+
end
|
41
|
+
|
42
|
+
it "keeps track of the sum of squars of data" do
|
43
|
+
@metric.sumsq.should == 285.0
|
44
|
+
end
|
45
|
+
|
46
|
+
it "retuns 0.0 for mean if there is no data" do
|
47
|
+
Hitimes::ValueMetric.new('0-data').mean.should == 0.0
|
48
|
+
end
|
49
|
+
|
50
|
+
it "keeps track of the min value" do
|
51
|
+
@metric.min.should == 0
|
52
|
+
end
|
53
|
+
|
54
|
+
it "keeps track of the max value" do
|
55
|
+
@metric.max.should == 9
|
56
|
+
end
|
57
|
+
|
58
|
+
it "keeps track of the first start time of all the measurements" do
|
59
|
+
m = Hitimes::ValueMetric.new( "first-start-time" )
|
60
|
+
f1 = Time.now.gmtime.to_f * 1_000_000
|
61
|
+
10.times{ |x| m.measure( x ) }
|
62
|
+
f2 = Time.now.gmtime.to_f * 1_000_000
|
63
|
+
m.sampling_start_time.should > f1
|
64
|
+
m.sampling_stop_time.should < f2
|
65
|
+
# distance from now to start time should be greater than the distance from
|
66
|
+
# the start to the min start_time
|
67
|
+
(f2 - m.sampling_start_time).should > ( m.sampling_start_time - f1 )
|
68
|
+
end
|
69
|
+
|
70
|
+
it "keeps track of the last stop time of all the intervals" do
|
71
|
+
m = Hitimes::ValueMetric.new( "last-stop-time" )
|
72
|
+
f1 = Time.now.gmtime.to_f * 1_000_000
|
73
|
+
10.times {|x| m.measure( x ) }
|
74
|
+
f2 = Time.now.gmtime.to_f * 1_000_000
|
75
|
+
m.sampling_stop_time.should > f1
|
76
|
+
m.sampling_stop_time.should < f2
|
77
|
+
# distance from now to max stop time time should be less than the distance
|
78
|
+
# from the start to the max stop time
|
79
|
+
(f2 - m.sampling_stop_time).should < ( m.sampling_stop_time - f1 )
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "#to_hash" do
|
83
|
+
|
84
|
+
it "has name value" do
|
85
|
+
h = @metric.to_hash
|
86
|
+
h['name'].should == "testing"
|
87
|
+
end
|
88
|
+
|
89
|
+
it "has an empty has for additional_data" do
|
90
|
+
h = @metric.to_hash
|
91
|
+
h['additional_data'].should == Hash.new
|
92
|
+
h['additional_data'].size.should == 0
|
93
|
+
end
|
94
|
+
|
95
|
+
it "has the right sum" do
|
96
|
+
h = @metric.to_hash
|
97
|
+
h['sum'].should == 45
|
98
|
+
end
|
99
|
+
|
100
|
+
fields = ::Hitimes::Stats::STATS.dup + %w[ name additional_data sampling_start_time sampling_stop_time ]
|
101
|
+
fields = fields - [ 'rate' ]
|
102
|
+
fields.each do |f|
|
103
|
+
it "should have a value for #{f}" do
|
104
|
+
h = @metric.to_hash
|
105
|
+
h[f].should_not be_nil
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
data/spec/version_spec.rb
CHANGED
@@ -21,6 +21,12 @@ describe "Hitimes::Version" do
|
|
21
21
|
Hitimes::Version.to_s.should match(/\d+\.\d+\.\d+/)
|
22
22
|
end
|
23
23
|
|
24
|
+
it "should have a hash representation" do
|
25
|
+
[ :major, :minor, :build ].each do |k|
|
26
|
+
Hitimes::Version.to_hash[k].should_not be_nil
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
24
30
|
it "should be accessable as a constant" do
|
25
31
|
Hitimes::VERSION.should match(/\d+\.\d+\.\d+/)
|
26
32
|
end
|