active_metric 2.5.2
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/MIT-LICENSE +20 -0
- data/README.rdoc +5 -0
- data/Rakefile +37 -0
- data/lib/active_metric.rb +38 -0
- data/lib/active_metric/axis.rb +11 -0
- data/lib/active_metric/behavior/calculates_derivative.rb +18 -0
- data/lib/active_metric/behavior/graph_calculation.rb +78 -0
- data/lib/active_metric/calculators/reservoir.rb +81 -0
- data/lib/active_metric/calculators/standard_deviator.rb +39 -0
- data/lib/active_metric/config/initializers/inflections.rb +4 -0
- data/lib/active_metric/graph_view_model.rb +60 -0
- data/lib/active_metric/measurement.rb +13 -0
- data/lib/active_metric/point_series_data.rb +17 -0
- data/lib/active_metric/report.rb +57 -0
- data/lib/active_metric/report_view_model.rb +106 -0
- data/lib/active_metric/sample.rb +148 -0
- data/lib/active_metric/series_data.rb +26 -0
- data/lib/active_metric/stat.rb +72 -0
- data/lib/active_metric/stat_definition.rb +20 -0
- data/lib/active_metric/statistics/defaults.rb +157 -0
- data/lib/active_metric/statistics/standard_deviation.rb +43 -0
- data/lib/active_metric/subject.rb +117 -0
- data/lib/active_metric/version.rb +3 -0
- data/test/active_metric_test.rb +30 -0
- data/test/axis_test.rb +22 -0
- data/test/behavior_tests/calculates_derivative_test.rb +35 -0
- data/test/behavior_tests/graph_calculation_test.rb +68 -0
- data/test/config/mongoid.yml +13 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/test.log +18597 -0
- data/test/graph_view_model_test.rb +92 -0
- data/test/integration_test.rb +149 -0
- data/test/measurement_test.rb +45 -0
- data/test/mongoid_test.rb +24 -0
- data/test/point_series_data_test.rb +27 -0
- data/test/report_test.rb +73 -0
- data/test/report_view_model_test.rb +94 -0
- data/test/reservoir_test.rb +67 -0
- data/test/sample_test.rb +142 -0
- data/test/series_data_test.rb +20 -0
- data/test/standard_deviator_test.rb +45 -0
- data/test/stat_test.rb +222 -0
- data/test/subject_test.rb +22 -0
- data/test/test_helper.rb +76 -0
- metadata +123 -0
@@ -0,0 +1,67 @@
|
|
1
|
+
require_relative "test_helper"
|
2
|
+
|
3
|
+
module ActiveMetric
|
4
|
+
class ReservoirTest < ActiveSupport::TestCase
|
5
|
+
|
6
|
+
class Measurement
|
7
|
+
attr_accessor :value
|
8
|
+
end
|
9
|
+
|
10
|
+
setup do
|
11
|
+
@reservoir = Reservoir.new(10)
|
12
|
+
end
|
13
|
+
|
14
|
+
test "can initialize reservoir with type and size" do
|
15
|
+
assert_equal @reservoir.size, 10
|
16
|
+
end
|
17
|
+
|
18
|
+
test "can fill reservoir" do
|
19
|
+
@reservoir.fill create_measurement(1)
|
20
|
+
end
|
21
|
+
|
22
|
+
test "can fill reservoir and calculate percentile" do
|
23
|
+
(1..10).reverse_each do |value|
|
24
|
+
@reservoir.fill create_measurement(value)
|
25
|
+
end
|
26
|
+
assert_equal 9, @reservoir.calculate_percentile(0.8, :value)
|
27
|
+
assert_equal 10, @reservoir.calculate_percentile(0.98, :value)
|
28
|
+
end
|
29
|
+
|
30
|
+
test "calculates based on moving window" do
|
31
|
+
(1..20).reverse_each do |value|
|
32
|
+
@reservoir.fill create_measurement(value)
|
33
|
+
end
|
34
|
+
|
35
|
+
assert_equal 9, @reservoir.calculate_percentile(0.8, :value)
|
36
|
+
assert_equal 10, @reservoir.calculate_percentile(0.98, :value)
|
37
|
+
end
|
38
|
+
|
39
|
+
test "can calculate standard deviation for window" do
|
40
|
+
reverse_fill(1..20)
|
41
|
+
assert_close_to 2.87, @reservoir.calculate_standard_deviation(:value)
|
42
|
+
reverse_fill(95..100)
|
43
|
+
assert_close_to 46.56, @reservoir.calculate_standard_deviation(:value)
|
44
|
+
reverse_fill(90..95)
|
45
|
+
assert_close_to 2.47, @reservoir.calculate_standard_deviation(:value)
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def reverse_fill(range)
|
51
|
+
range.reverse_each do |value|
|
52
|
+
@reservoir.fill create_measurement(value)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def shuffle(array)
|
57
|
+
array.size.downto(1) { |n| array.push array.delete_at(rand(n)) }
|
58
|
+
end
|
59
|
+
|
60
|
+
def create_measurement(value)
|
61
|
+
measurement = Measurement.new
|
62
|
+
measurement.value = value
|
63
|
+
measurement
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
data/test/sample_test.rb
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
require_relative "test_helper"
|
2
|
+
|
3
|
+
module ActiveMetric
|
4
|
+
class SampleTest < ActiveSupport::TestCase
|
5
|
+
|
6
|
+
test "should have the correct stats by name" do
|
7
|
+
subject = TestSubject.new
|
8
|
+
sample = TestSample.new(:samplable => subject)
|
9
|
+
assert_equal 12, sample.stats.size
|
10
|
+
assert_kind_of Min, sample.min_value
|
11
|
+
assert_kind_of Mean, sample.mean_value
|
12
|
+
assert_kind_of Max, sample.max_value
|
13
|
+
assert_kind_of Eightieth, sample.eightieth_value
|
14
|
+
assert_kind_of NinetyEighth, sample.ninety_eighth_value
|
15
|
+
assert_kind_of StandardDeviation, sample.standard_deviation_value
|
16
|
+
assert_kind_of Delta, sample.delta_value
|
17
|
+
assert_kind_of Bucket, sample.bucket_value
|
18
|
+
assert_kind_of Speed, sample.speed_value
|
19
|
+
assert_kind_of PercentFalse, sample.percent_false_value
|
20
|
+
assert_kind_of TestCount, sample.test_count
|
21
|
+
assert_kind_of TestResponseCodes, sample.test_response_codes
|
22
|
+
end
|
23
|
+
|
24
|
+
test "samples spawned from samples contain seed measurement" do
|
25
|
+
subject = TestSubject.new
|
26
|
+
|
27
|
+
num_measurements = 5
|
28
|
+
|
29
|
+
sample = TestSample.new(:interval => 6, :samplable => subject)
|
30
|
+
|
31
|
+
num_measurements.times do |time|
|
32
|
+
sample.calculate TestMeasurement.new :value => 1, :timestamp => time
|
33
|
+
end
|
34
|
+
|
35
|
+
new_sample = sample.new_sample
|
36
|
+
|
37
|
+
assert_not_equal sample, new_sample
|
38
|
+
assert_equal 4, new_sample.seed_measurement.timestamp
|
39
|
+
assert_equal sample.latest_measurement, new_sample.seed_measurement
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
test "should have correct timestamp" do
|
44
|
+
measurements = [TestMeasurement.new(:value => 10, :timestamp => 1),
|
45
|
+
TestMeasurement.new(:value => 12, :timestamp => 2),
|
46
|
+
TestMeasurement.new(:value => 11, :timestamp => 9)]
|
47
|
+
|
48
|
+
subject = TestSubject.create
|
49
|
+
sample = TestSample.new(:samplable => subject)
|
50
|
+
measurements.each do |measurement|
|
51
|
+
sample.calculate(measurement)
|
52
|
+
end
|
53
|
+
assert_equal (4), sample.timestamp
|
54
|
+
end
|
55
|
+
|
56
|
+
test "should call calculate on all stats" do
|
57
|
+
subject = TestSubject.create
|
58
|
+
sample = TestSample.new(:samplable => subject)
|
59
|
+
5.times do |value|
|
60
|
+
measurement = TestMeasurement.new :value => value, :timestamp => 1
|
61
|
+
sample.stats.each do |stat|
|
62
|
+
stat.expects(:calculate).with(measurement)
|
63
|
+
end
|
64
|
+
sample.calculate measurement
|
65
|
+
end
|
66
|
+
|
67
|
+
sample.stats.each do |stat|
|
68
|
+
stat.expects(:complete)
|
69
|
+
end
|
70
|
+
sample.complete
|
71
|
+
end
|
72
|
+
|
73
|
+
test "should return raw stat if sample does not have that stat" do
|
74
|
+
sample = TestSample.new
|
75
|
+
stat = sample.this_stat_does_not_exist
|
76
|
+
assert_equal 0, stat.value
|
77
|
+
end
|
78
|
+
|
79
|
+
test "should return stat if sample has it" do
|
80
|
+
sample = TestSample.new
|
81
|
+
stat = sample.min_value
|
82
|
+
assert stat.kind_of? Min
|
83
|
+
end
|
84
|
+
|
85
|
+
test "is summary" do
|
86
|
+
subject = TestSubject.create
|
87
|
+
summary = subject.summary
|
88
|
+
assert summary.is_summary?
|
89
|
+
end
|
90
|
+
|
91
|
+
test "summary only should set start time after first measurement" do
|
92
|
+
subject = TestSubject.create
|
93
|
+
summary = subject.summary
|
94
|
+
assert_nil summary.start_time
|
95
|
+
|
96
|
+
|
97
|
+
summary.calculate(TestMeasurement.new :value => 1, :timestamp => 1)
|
98
|
+
assert_equal 1, summary.start_time
|
99
|
+
end
|
100
|
+
|
101
|
+
test "duration from previous sample defaults to current sample duration if no previous sample" do
|
102
|
+
nil_seed_measurement = nil
|
103
|
+
sample = TestSample.new({},nil_seed_measurement)
|
104
|
+
sample.expects(:duration_in_seconds)
|
105
|
+
sample.duration_from_previous_sample_in_seconds
|
106
|
+
end
|
107
|
+
|
108
|
+
test "duration from previous sample returns correct duration" do
|
109
|
+
seed_measurement = mock
|
110
|
+
|
111
|
+
seed_measurement.expects(:timestamp).returns(100)
|
112
|
+
|
113
|
+
sample = TestSample.new({},{}, seed_measurement)
|
114
|
+
sample.expects(:end_time).returns(200)
|
115
|
+
|
116
|
+
assert_equal 100, sample.duration_from_previous_sample_in_seconds
|
117
|
+
end
|
118
|
+
|
119
|
+
test "passing in just a hash to create sets seed measurement to nil" do
|
120
|
+
subject = TestSubject.new
|
121
|
+
|
122
|
+
sample = TestSample.create( {:samplable => subject, :foo => "bar"} )
|
123
|
+
assert_nil sample.seed_measurement
|
124
|
+
|
125
|
+
end
|
126
|
+
|
127
|
+
test "stat definitions have proper axis" do
|
128
|
+
@stat_definitions = TestSample.stats_defined
|
129
|
+
assert_contains_axis(:min_value,0)
|
130
|
+
assert_contains_axis(:mean_value,0)
|
131
|
+
assert_contains_axis(:max_value,0)
|
132
|
+
assert_contains_axis(:standard_deviation_value,1)
|
133
|
+
assert_contains_axis(:test_count,1)
|
134
|
+
assert_contains_axis(:test_response_codes, -1)
|
135
|
+
end
|
136
|
+
|
137
|
+
def assert_contains_axis(stat,axis)
|
138
|
+
assert_equal axis, @stat_definitions.select {|sd| sd.access_name == stat}.first.options[:axis]
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative "test_helper"
|
2
|
+
|
3
|
+
module ActiveMetric
|
4
|
+
class SeriesDataTest < ActiveSupport::TestCase
|
5
|
+
|
6
|
+
test "can instantiate from stat definition" do
|
7
|
+
access_name = "name_of_stat"
|
8
|
+
options = {axis: 2, visible: false}
|
9
|
+
stat_definition = StatDefinition.new(:property,Min,access_name,options)
|
10
|
+
series = SeriesData.from_stat_definition(stat_definition)
|
11
|
+
|
12
|
+
assert_equal access_name, series.label
|
13
|
+
assert_equal 2, series.y_axis
|
14
|
+
assert_equal 0, series.x_axis
|
15
|
+
assert_equal false, series.visible
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require_relative "test_helper"
|
2
|
+
module ActiveMetric
|
3
|
+
class StandardDeviatorTest < ActiveSupport::TestCase
|
4
|
+
|
5
|
+
test "can calculate standard deviation" do
|
6
|
+
sd = StandardDeviator.new(:value)
|
7
|
+
test_stat(sd, 100.times)
|
8
|
+
assert_close_to 28.87, sd.standard_deviation
|
9
|
+
end
|
10
|
+
|
11
|
+
test "memoize standard deviation with a single measurement" do
|
12
|
+
sd = StandardDeviator.new(:value)
|
13
|
+
sd.expects(:calculate_standard_deviation).returns(5)
|
14
|
+
test_stat(sd, 1.times)
|
15
|
+
assert_equal 5, sd.standard_deviation
|
16
|
+
assert_equal 5, sd.standard_deviation
|
17
|
+
end
|
18
|
+
|
19
|
+
test "un-memoizes standard deviation with new measurement" do
|
20
|
+
sd = StandardDeviator.new(:value)
|
21
|
+
sd.expects(:calculate_standard_deviation).twice.returns(5,2)
|
22
|
+
test_stat(sd, 1.times)
|
23
|
+
assert_equal 5, sd.standard_deviation
|
24
|
+
assert_equal 5, sd.standard_deviation
|
25
|
+
test_stat(sd, 1.times)
|
26
|
+
assert_equal 2, sd.standard_deviation
|
27
|
+
end
|
28
|
+
|
29
|
+
test "can calculate standard deviation with no calculations " do
|
30
|
+
sd = StandardDeviator.new(:value)
|
31
|
+
assert_equal 0, sd.standard_deviation
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def test_stat(stat, values)
|
37
|
+
values.each do |value|
|
38
|
+
stat.calculate TestMeasurement.new(:value => value)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
data/test/stat_test.rb
ADDED
@@ -0,0 +1,222 @@
|
|
1
|
+
require_relative 'test_helper'
|
2
|
+
|
3
|
+
module ActiveMetric
|
4
|
+
class StatTest < ActiveSupport::TestCase
|
5
|
+
|
6
|
+
setup do
|
7
|
+
@subject = TestSubject.create
|
8
|
+
@sample = TestSample.create({:samplable => @subject})
|
9
|
+
@stat = TestStat.new :property, :calculable => @sample
|
10
|
+
end
|
11
|
+
|
12
|
+
test "create a new stat" do
|
13
|
+
assert @stat
|
14
|
+
end
|
15
|
+
|
16
|
+
test "stat is a mongoid document" do
|
17
|
+
assert @stat.kind_of?(Mongoid::Document)
|
18
|
+
end
|
19
|
+
|
20
|
+
test "calculate raises an error if not implemented" do
|
21
|
+
assert_raise CannotInstantiateBaseStat do
|
22
|
+
@stat.calculate(mock)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
test "has a dynamically defined name" do
|
27
|
+
assert_equal :test_stat_property, @stat.access_name
|
28
|
+
end
|
29
|
+
|
30
|
+
test "sets name for custom stat" do
|
31
|
+
proc = Proc.new { |m| self.value = m.value }
|
32
|
+
stat = Stat.create_custom_stat(:property, Integer, {}, proc).new(:property)
|
33
|
+
assert_equal :property, stat.access_name
|
34
|
+
end
|
35
|
+
|
36
|
+
test "custom stat uses block to calculate" do
|
37
|
+
proc = Proc.new { |m| self.value = m.value }
|
38
|
+
stat = Stat.create_custom_stat(:property, Integer, {}, proc).new(:property)
|
39
|
+
measurement = mock(:value => 10)
|
40
|
+
stat.calculate(measurement)
|
41
|
+
assert_equal 10, stat.value
|
42
|
+
end
|
43
|
+
|
44
|
+
test "can calculate min" do
|
45
|
+
stat = Min.new(:value, :calculable => @sample)
|
46
|
+
test_stat(stat, 10.times)
|
47
|
+
assert_equal 0, stat.value
|
48
|
+
end
|
49
|
+
|
50
|
+
test "can calculate max" do
|
51
|
+
stat = Max.new(:value, :calculable => @sample)
|
52
|
+
test_stat(stat, 10.times)
|
53
|
+
assert_equal 9, stat.value
|
54
|
+
end
|
55
|
+
|
56
|
+
test "can calculate mean" do
|
57
|
+
stat = Mean.new(:value, :calculable => @sample)
|
58
|
+
test_stat(stat, 10.times)
|
59
|
+
assert_equal 4.5, stat.value
|
60
|
+
end
|
61
|
+
|
62
|
+
test "can calculate derivative without seed_measurement" do
|
63
|
+
stat = Derivative.new(:value, :calculable => @sample)
|
64
|
+
@sample.stubs(:seed_measurement).returns(nil)
|
65
|
+
|
66
|
+
@sample.expects(:duration_from_previous_sample_in_seconds).times(2).returns(0, 1)
|
67
|
+
test_stat(stat, [1, 2])
|
68
|
+
slope_of_one = 1.0
|
69
|
+
|
70
|
+
assert_equal slope_of_one, stat.value
|
71
|
+
end
|
72
|
+
|
73
|
+
test "can calculate derivative with seed_measurement " do
|
74
|
+
stat = Derivative.new(:value, :calculable => @sample)
|
75
|
+
|
76
|
+
@sample.stubs(:seed_measurement).returns(test_seed_measurement)
|
77
|
+
@sample.expects(:duration_from_previous_sample_in_seconds).times(2).returns(1, 2)
|
78
|
+
test_stat(stat, [2, 3])
|
79
|
+
|
80
|
+
slope_of_one = 1.0
|
81
|
+
|
82
|
+
assert_equal slope_of_one, stat.value
|
83
|
+
end
|
84
|
+
|
85
|
+
test "can calculate last derivative without seed_measurement" do
|
86
|
+
stat = LastDerivative.new(:value, :calculable => @sample)
|
87
|
+
@sample.stubs(:seed_measurement).returns(nil)
|
88
|
+
|
89
|
+
test_stat(stat, [1])
|
90
|
+
no_derivative = 0
|
91
|
+
|
92
|
+
assert_equal no_derivative, stat.value
|
93
|
+
end
|
94
|
+
|
95
|
+
test "can calculate last derivative with seed measurement" do
|
96
|
+
stat = LastDerivative.new(:value, :calculable => @sample)
|
97
|
+
|
98
|
+
@sample.stubs(:seed_measurement).returns(test_seed_measurement)
|
99
|
+
test_stat(stat, [2, 4], [2, 3])
|
100
|
+
|
101
|
+
slope_of_two = 2.0
|
102
|
+
|
103
|
+
assert_equal slope_of_two, stat.value
|
104
|
+
end
|
105
|
+
|
106
|
+
test "can calculate speed" do
|
107
|
+
stat = Speed.new(:value, :calculable => @sample)
|
108
|
+
|
109
|
+
@sample.stubs(:seed_measurement).returns(test_seed_measurement)
|
110
|
+
@sample.expects(:duration_from_previous_sample_in_seconds).times(4).returns(1, 2, 3, 4)
|
111
|
+
|
112
|
+
test_stat(stat, [2, 3, 4, 5])
|
113
|
+
|
114
|
+
speed_of_one_per_second = 1.0
|
115
|
+
assert_equal speed_of_one_per_second, stat.value
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
test "can calculate delta without seed measurement" do
|
120
|
+
stat = Delta.new(:value, :calculable => @sample)
|
121
|
+
@sample.stubs(:seed_measurement).returns(nil)
|
122
|
+
|
123
|
+
test_stat(stat, [1, 5, 10])
|
124
|
+
assert_equal 9, stat.value
|
125
|
+
end
|
126
|
+
|
127
|
+
test "can calculate delta with seed measurement" do
|
128
|
+
stat = Delta.new(:value, :calculable => @sample)
|
129
|
+
@sample.stubs(:seed_measurement).returns(test_seed_measurement)
|
130
|
+
|
131
|
+
test_stat(stat, [5, 10])
|
132
|
+
assert_equal 9, stat.value
|
133
|
+
end
|
134
|
+
|
135
|
+
test "can calculate sum" do
|
136
|
+
stat = Sum.new(:value, :calculable => @sample)
|
137
|
+
test_stat(stat, 10.times)
|
138
|
+
assert_equal 45, stat.value
|
139
|
+
end
|
140
|
+
|
141
|
+
test "can calculate last" do
|
142
|
+
stat = Last.new(:value, :calculable => @sample)
|
143
|
+
test_stat(stat, 10.times)
|
144
|
+
assert_equal 9, stat.value
|
145
|
+
end
|
146
|
+
|
147
|
+
test "can calculate count" do
|
148
|
+
stat = Count.new(:value, :calculable => @sample)
|
149
|
+
test_stat(stat, 10.times)
|
150
|
+
assert_equal 10, stat.value
|
151
|
+
end
|
152
|
+
|
153
|
+
test "can calculate true count" do
|
154
|
+
stat = TrueCount.new(:value, :calculabe => @sample)
|
155
|
+
values = [true, true, false]
|
156
|
+
test_stat(stat, values)
|
157
|
+
assert_equal 2, stat.value
|
158
|
+
end
|
159
|
+
|
160
|
+
test "can calculate false count" do
|
161
|
+
stat = FalseCount.new(:value, :calculabe => @sample)
|
162
|
+
values = [true, true, false]
|
163
|
+
test_stat(stat, values)
|
164
|
+
assert_equal 1, stat.value
|
165
|
+
end
|
166
|
+
|
167
|
+
test "can bucket values" do
|
168
|
+
stat = Bucket.new(:value, :calculabe => @sample)
|
169
|
+
values = [200, 404, 500, 502, 200, 500, 504.2]
|
170
|
+
test_stat(stat, values)
|
171
|
+
expected_bucket = {
|
172
|
+
"200" => 2,
|
173
|
+
"404" => 1,
|
174
|
+
"500" => 2,
|
175
|
+
"502" => 1,
|
176
|
+
"504_2" => 1
|
177
|
+
}
|
178
|
+
assert_equal expected_bucket, stat.value
|
179
|
+
end
|
180
|
+
|
181
|
+
test "can calculate false percentage" do
|
182
|
+
stat = PercentFalse.new(:value, :calculabe => @sample)
|
183
|
+
values = [true, true, false, true]
|
184
|
+
test_stat(stat, values)
|
185
|
+
assert_equal 25, stat.value
|
186
|
+
end
|
187
|
+
|
188
|
+
|
189
|
+
#this test is here for the user, not for automated tests
|
190
|
+
#test "random distributions are good too" do
|
191
|
+
# stat = StandardDeviation.new(:value, :calculable => @sample)
|
192
|
+
# 100.times do
|
193
|
+
# stat.calculate TestMeasurement.create(:value => rand(100))
|
194
|
+
# end
|
195
|
+
# stat.complete
|
196
|
+
# assert_close_to 28.87, stat.value
|
197
|
+
#end
|
198
|
+
|
199
|
+
test "has subject" do
|
200
|
+
subject = TestSubject.create
|
201
|
+
sample = TestSample.create(:samplable => subject)
|
202
|
+
assert_equal subject, sample.stats.first.subject
|
203
|
+
end
|
204
|
+
|
205
|
+
private
|
206
|
+
|
207
|
+
def test_stat(stat, values, timestamps = values.to_a)
|
208
|
+
values.each_with_index do |value, index|
|
209
|
+
stat.calculate TestMeasurement.new(:value => value, :timestamp => timestamps[index])
|
210
|
+
end
|
211
|
+
stat.complete
|
212
|
+
end
|
213
|
+
|
214
|
+
def test_seed_measurement
|
215
|
+
seed_measurement = mock()
|
216
|
+
seed_measurement.stubs(:value).returns(1)
|
217
|
+
seed_measurement.stubs(:timestamp).returns(1)
|
218
|
+
seed_measurement
|
219
|
+
end
|
220
|
+
|
221
|
+
end
|
222
|
+
end
|