active_metric 2.5.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|