rrd-grapher 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +9 -0
- data/.rvmrc +1 -0
- data/Gemfile +11 -0
- data/Guardfile +123 -0
- data/README.md +91 -0
- data/Rakefile +42 -0
- data/example_app/Gemfile +9 -0
- data/example_app/Guardfile +18 -0
- data/example_app/app.rb +38 -0
- data/example_app/assets/javascripts/available_rrds.coffee +13 -0
- data/example_app/assets/javascripts/collectd.coffee +48 -0
- data/example_app/config.ru +9 -0
- data/example_app/public/.gitignore +1 -0
- data/example_app/public/chosen/chosen-sprite.png +0 -0
- data/example_app/public/chosen/chosen.css +340 -0
- data/example_app/public/chosen/chosen.jquery.js +786 -0
- data/example_app/public/chosen/chosen.jquery.min.js +10 -0
- data/example_app/public/javascripts/available_rrds.js +16 -0
- data/example_app/public/javascripts/collectd.js +64 -0
- data/example_app/public/javascripts/jquery.timeago.js +148 -0
- data/example_app/public/stylesheets/Aristo/images/bg_fallback.png +0 -0
- data/example_app/public/stylesheets/Aristo/images/icon_sprite.png +0 -0
- data/example_app/public/stylesheets/Aristo/images/progress_bar.gif +0 -0
- data/example_app/public/stylesheets/Aristo/images/slider_handles.png +0 -0
- data/example_app/public/stylesheets/Aristo/images/ui-icons_222222_256x240.png +0 -0
- data/example_app/public/stylesheets/Aristo/images/ui-icons_454545_256x240.png +0 -0
- data/example_app/public/stylesheets/Aristo/theme.css +738 -0
- data/example_app/views/available_rrds.haml +26 -0
- data/example_app/views/collectd.haml +30 -0
- data/example_app/views/layout.haml +19 -0
- data/example_app/views/stylesheets/available_rrds.scss +7 -0
- data/example_notifier/Gemfile +2 -0
- data/example_notifier/notifier.rb +25 -0
- data/lib/rrd-grapher/assets/javascripts/app-dev.js +20 -0
- data/lib/rrd-grapher/assets/javascripts/app.js +20 -0
- data/lib/rrd-grapher/assets/javascripts/classes/format.coffee +35 -0
- data/lib/rrd-grapher/assets/javascripts/classes/graph.coffee +306 -0
- data/lib/rrd-grapher/assets/javascripts/classes/graph_definition.coffee +216 -0
- data/lib/rrd-grapher/assets/javascripts/classes/serie.coffee +13 -0
- data/lib/rrd-grapher/assets/javascripts/classes/size.coffee +5 -0
- data/lib/rrd-grapher/assets/javascripts/classes/static_line.coffee +44 -0
- data/lib/rrd-grapher/assets/javascripts/classes/time.coffee +17 -0
- data/lib/rrd-grapher/notifier/alarm_manager.rb +190 -0
- data/lib/rrd-grapher/notifier/alarm_trigger.rb +187 -0
- data/lib/rrd-grapher/notifier/alarms.rb +79 -0
- data/lib/rrd-grapher/notifier/collectdrb.rb +86 -0
- data/lib/rrd-grapher/notifier/data_struct.rb +46 -0
- data/lib/rrd-grapher/notifier/default_user_handler.rb +36 -0
- data/lib/rrd-grapher/notifier/parsers/bindata_parser.rb +144 -0
- data/lib/rrd-grapher/notifier/parsers/ruby_parser.rb +134 -0
- data/lib/rrd-grapher/notifier/structures.rb +80 -0
- data/lib/rrd-grapher/notifier.rb +87 -0
- data/lib/rrd-grapher/public/favicon.ico +0 -0
- data/lib/rrd-grapher/public/javascripts/app-dev.js +13709 -0
- data/lib/rrd-grapher/public/javascripts/app.js +4057 -0
- data/lib/rrd-grapher/public/javascripts/backbone/backbone.js +1155 -0
- data/lib/rrd-grapher/public/javascripts/backbone/backbone.min.js +32 -0
- data/lib/rrd-grapher/public/javascripts/backbone/underscore.js +841 -0
- data/lib/rrd-grapher/public/javascripts/backbone/underscore.min.js +27 -0
- data/lib/rrd-grapher/public/javascripts/classes/format.js +42 -0
- data/lib/rrd-grapher/public/javascripts/classes/graph.js +360 -0
- data/lib/rrd-grapher/public/javascripts/classes/graph_definition.js +298 -0
- data/lib/rrd-grapher/public/javascripts/classes/serie.js +32 -0
- data/lib/rrd-grapher/public/javascripts/classes/size.js +7 -0
- data/lib/rrd-grapher/public/javascripts/classes/static_line.js +48 -0
- data/lib/rrd-grapher/public/javascripts/classes/time.js +17 -0
- data/lib/rrd-grapher/public/javascripts/flot/.gitignore +4 -0
- data/lib/rrd-grapher/public/javascripts/flot/excanvas.min.js +1 -0
- data/lib/rrd-grapher/public/javascripts/flot/jquery.colorhelpers.min.js +1 -0
- data/lib/rrd-grapher/public/javascripts/flot/jquery.flot.crosshair.min.js +1 -0
- data/lib/rrd-grapher/public/javascripts/flot/jquery.flot.fillbetween.min.js +1 -0
- data/lib/rrd-grapher/public/javascripts/flot/jquery.flot.image.min.js +1 -0
- data/lib/rrd-grapher/public/javascripts/flot/jquery.flot.js +2604 -0
- data/lib/rrd-grapher/public/javascripts/flot/jquery.flot.navigate.min.js +1 -0
- data/lib/rrd-grapher/public/javascripts/flot/jquery.flot.pie.min.js +1 -0
- data/lib/rrd-grapher/public/javascripts/flot/jquery.flot.resize.min.js +1 -0
- data/lib/rrd-grapher/public/javascripts/flot/jquery.flot.selection.js +345 -0
- data/lib/rrd-grapher/public/javascripts/flot/jquery.flot.selection.min.js +1 -0
- data/lib/rrd-grapher/public/javascripts/flot/jquery.flot.stack.min.js +1 -0
- data/lib/rrd-grapher/public/javascripts/flot/jquery.flot.symbol.min.js +1 -0
- data/lib/rrd-grapher/public/javascripts/flot/jquery.flot.threshold.min.js +1 -0
- data/lib/rrd-grapher/public/javascripts/jquery/jquery-1.6.2.js +8981 -0
- data/lib/rrd-grapher/public/javascripts/jquery/jquery-1.6.2.min.js +18 -0
- data/lib/rrd-grapher/public/javascripts/jquery/jquery-ui-1.8.11.min.js +783 -0
- data/lib/rrd-grapher/public/javascripts/jquery/jquery.showtime.js +63 -0
- data/lib/rrd-grapher/public/javascripts/jquery/jquery.tpl.min.js +10 -0
- data/lib/rrd-grapher/resources.rb +14 -0
- data/lib/rrd-grapher/rrd.rb +238 -0
- data/lib/rrd-grapher/rrd_server.rb +78 -0
- data/lib/rrd-grapher/version.rb +4 -0
- data/lib/rrd-grapher/views/stylesheets/app.scss +111 -0
- data/lib/rrd-grapher.rb +12 -0
- data/rrd-grapher.gemspec +47 -0
- data/spec/common.rb +70 -0
- data/spec/data/myrouter.rrd +0 -0
- data/spec/data/subdata.rrd +0 -0
- data/spec/data/test.rrd +0 -0
- data/spec/factories.rb +23 -0
- data/spec/javascripts/helpers/jasmine-jquery-1.3.0.js +283 -0
- data/spec/javascripts/source/format_spec.coffee +18 -0
- data/spec/javascripts/source/graph_def_spec.coffee +27 -0
- data/spec/javascripts/source/graph_spec.coffee +63 -0
- data/spec/javascripts/source/serie_spec.coffee +28 -0
- data/spec/javascripts/source/static_line_spec.coffee +13 -0
- data/spec/javascripts/source/time_spec.coffee +26 -0
- data/spec/javascripts/support/jasmine.yml +78 -0
- data/spec/javascripts/support/jasmine_config.rb +23 -0
- data/spec/javascripts/support/jasmine_runner.rb +32 -0
- data/spec/unit/alarm_manager_spec.rb +252 -0
- data/spec/unit/alarm_trigger_spec.rb +26 -0
- data/spec/unit/data_struct_spec.rb +55 -0
- data/spec/unit/notifier_spec.rb +45 -0
- data/spec/unit/parsers/bindata_parser_spec.rb +184 -0
- data/spec/unit/parsers/ruby_parser_spec.rb +184 -0
- data/spec/unit/rrd_spec.rb +50 -0
- data/spec/unit/structures_spec.rb +28 -0
- data/tests/4series.rrd +0 -0
- data/tests/analyze_rrd.rb +62 -0
- data/tests/exact.rrd +0 -0
- data/tests/exact2.rrd +0 -0
- data/tests/filler.rb +46 -0
- metadata +414 -0
@@ -0,0 +1,252 @@
|
|
1
|
+
|
2
|
+
require 'eventmachine'
|
3
|
+
|
4
|
+
require File.expand_path('../../common', __FILE__)
|
5
|
+
require File.expand_path('../../../lib/rrd-grapher/notifier/alarm_manager', __FILE__)
|
6
|
+
|
7
|
+
|
8
|
+
describe 'AlarmManager' do
|
9
|
+
before do
|
10
|
+
@manager = RRDNotifier::AlarmManager.new
|
11
|
+
end
|
12
|
+
|
13
|
+
should 'create the manager' do
|
14
|
+
@manager.should.not == nil
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'with a user notification handler' do
|
18
|
+
before do
|
19
|
+
@handler_class = Class.new do
|
20
|
+
def dispatch_notification(notification); end
|
21
|
+
def alarm_started(alarm); end
|
22
|
+
def alarm_stopped(alarm); end
|
23
|
+
end
|
24
|
+
|
25
|
+
@handler = @handler_class.new
|
26
|
+
|
27
|
+
@manager = RRDNotifier::AlarmManager.new(:notification_handler => @handler)
|
28
|
+
end
|
29
|
+
|
30
|
+
should 'dispatch notification as is' do
|
31
|
+
notif = Factory(:notification)
|
32
|
+
@handler.expects(:dispatch_notification).with(notif)
|
33
|
+
@manager.packet_received(notif)
|
34
|
+
end
|
35
|
+
|
36
|
+
should 'notify the user handler when an alarm is raised' do
|
37
|
+
packet = Factory(:data_point)
|
38
|
+
alarm = RRDNotifier::AlarmTooLow.new(packet, 10)
|
39
|
+
|
40
|
+
@handler.expects(:alarm_started).with(alarm)
|
41
|
+
@manager.raise_alarm(packet.measure_id, alarm)
|
42
|
+
end
|
43
|
+
|
44
|
+
should 'notify the user handler when an alarm is stopped' do
|
45
|
+
p = Factory(:data_point)
|
46
|
+
alarm = RRDNotifier::AlarmTooLow.new(p, 10)
|
47
|
+
|
48
|
+
@handler.expects(:alarm_stopped).with(alarm)
|
49
|
+
@manager.stop_specific_alarm(p.measure_id, alarm)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe 'a trigger on low value' do
|
54
|
+
before do
|
55
|
+
@manager.register_alarm('*', "memory/*", "memory/active", :min => 10)
|
56
|
+
end
|
57
|
+
|
58
|
+
should 'raise an alarm for a value below the threshold' do
|
59
|
+
p = Factory(:data_point, :plugin => "memory", :type => "memory", :type_instance => "active", :values => [8])
|
60
|
+
|
61
|
+
@manager.expects(:raise_alarm).with(p.measure_id, kind_of(RRDNotifier::AlarmTooLow) )
|
62
|
+
|
63
|
+
@manager.packet_received(p)
|
64
|
+
end
|
65
|
+
|
66
|
+
should 'not raise an alarm for a value above the threshold' do
|
67
|
+
p = Factory(:data_point, :plugin => "memory", :type => "memory", :type_instance => "active", :values => [81])
|
68
|
+
|
69
|
+
@manager.expects(:raise_alarm).never
|
70
|
+
|
71
|
+
@manager.packet_received(p)
|
72
|
+
end
|
73
|
+
|
74
|
+
should 'not reraise another alarm if the value stays below the threshold' do
|
75
|
+
p_alarm = Factory(:data_point, :plugin => "memory", :type => "memory", :type_instance => "active", :values => [8])
|
76
|
+
p_alarm2 = Factory(:data_point, :plugin => "memory", :type => "memory", :type_instance => "active", :values => [5])
|
77
|
+
|
78
|
+
@manager.expects(:active_alarms_for).with(p_alarm.measure_id).returns( [RRDNotifier::AlarmTooLow.new(p_alarm, 10)] )
|
79
|
+
@manager.expects(:raise_alarm).never
|
80
|
+
|
81
|
+
@manager.packet_received(p_alarm2)
|
82
|
+
end
|
83
|
+
|
84
|
+
should 'stop the alarm when the value comes back above the threshold' do
|
85
|
+
p_alarm = Factory(:data_point, :plugin => "memory", :type => "memory", :type_instance => "active", :values => [8])
|
86
|
+
p_normal = Factory(:data_point, :plugin => "memory", :type => "memory", :type_instance => "active", :values => [81])
|
87
|
+
|
88
|
+
@manager.expects(:active_alarms_for).with(p_alarm.measure_id).returns( [RRDNotifier::AlarmTooLow.new(p_alarm, 10)] )
|
89
|
+
|
90
|
+
@manager.expects(:raise_alarm).never
|
91
|
+
@manager.expects(:stop_specific_alarm).with( p_normal.measure_id, kind_of(RRDNotifier::AlarmTooLow) )
|
92
|
+
|
93
|
+
@manager.packet_received(p_normal)
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
describe 'a trigger on high value' do
|
99
|
+
before do
|
100
|
+
@manager.register_alarm('*', "memory/*", "memory/active", :max => 10)
|
101
|
+
end
|
102
|
+
|
103
|
+
should 'raise an alarm for a value above the threshold' do
|
104
|
+
p = Factory(:data_point, :plugin => "memory", :type => "memory", :type_instance => "active", :values => [81])
|
105
|
+
|
106
|
+
@manager.expects(:raise_alarm).with(p.measure_id, kind_of(RRDNotifier::AlarmTooHigh) )
|
107
|
+
|
108
|
+
@manager.packet_received(p)
|
109
|
+
end
|
110
|
+
|
111
|
+
should 'not raise an alarm for a value below the threshold' do
|
112
|
+
p = Factory(:data_point, :plugin => "memory", :type => "memory", :type_instance => "active", :values => [8])
|
113
|
+
|
114
|
+
@manager.expects(:raise_alarm).never
|
115
|
+
|
116
|
+
@manager.packet_received(p)
|
117
|
+
end
|
118
|
+
|
119
|
+
should 'not reraise another alarm if the value stays above the threshold' do
|
120
|
+
p_alarm = Factory(:data_point, :plugin => "memory", :type => "memory", :type_instance => "active", :values => [81])
|
121
|
+
p_alarm2 = Factory(:data_point, :plugin => "memory", :type => "memory", :type_instance => "active", :values => [81])
|
122
|
+
|
123
|
+
@manager.expects(:active_alarms_for).with(p_alarm.measure_id).returns( [RRDNotifier::AlarmTooLow.new(p_alarm, 10)] )
|
124
|
+
@manager.expects(:raise_alarm).never
|
125
|
+
|
126
|
+
@manager.packet_received(p_alarm2)
|
127
|
+
end
|
128
|
+
|
129
|
+
should 'stop the alarm when the value comes back below the threshold' do
|
130
|
+
p_alarm = Factory(:data_point, :plugin => "memory", :type => "memory", :type_instance => "active", :values => [81])
|
131
|
+
p_normal = Factory(:data_point, :plugin => "memory", :type => "memory", :type_instance => "active", :values => [8])
|
132
|
+
|
133
|
+
@manager.expects(:active_alarms_for).with(p_alarm.measure_id).returns( [RRDNotifier::AlarmTooHigh.new(p_alarm, 10)] )
|
134
|
+
|
135
|
+
@manager.expects(:raise_alarm).never
|
136
|
+
@manager.expects(:stop_specific_alarm).with( p_normal.measure_id, kind_of(RRDNotifier::AlarmTooHigh) )
|
137
|
+
|
138
|
+
@manager.packet_received(p_normal)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
describe 'a trigger on clock drift' do
|
143
|
+
before do
|
144
|
+
@manager.stubs(:send_gauge)
|
145
|
+
@manager.register_alarm('*', "memory/*", "memory/active",
|
146
|
+
:monitor_drift => 30 # allow 30s of drift
|
147
|
+
)
|
148
|
+
end
|
149
|
+
|
150
|
+
should 'raise an alarm if time difference is higher than threshold' do
|
151
|
+
p = Factory(:data_point, :time => Time.now - 60, :plugin => "memory", :type => "memory", :type_instance => "active", :values => [8])
|
152
|
+
@manager.expects(:raise_alarm).with(p.measure_id, kind_of(RRDNotifier::AlarmClockDrift) )
|
153
|
+
|
154
|
+
@manager.packet_received(p)
|
155
|
+
|
156
|
+
p = Factory(:data_point, :time => Time.now + 60, :plugin => "memory", :type => "memory", :type_instance => "active", :values => [8])
|
157
|
+
@manager.expects(:raise_alarm).with(p.measure_id, kind_of(RRDNotifier::AlarmClockDrift) )
|
158
|
+
|
159
|
+
@manager.packet_received(p)
|
160
|
+
end
|
161
|
+
|
162
|
+
should 'not raise an alarm if time difference is below the threshold' do
|
163
|
+
p = Factory(:data_point, :time => Time.now - 20, :plugin => "memory", :type => "memory", :type_instance => "active", :values => [8])
|
164
|
+
@manager.expects(:raise_alarm).never
|
165
|
+
|
166
|
+
@manager.packet_received(p)
|
167
|
+
|
168
|
+
p = Factory(:data_point, :time => Time.now + 20, :plugin => "memory", :type => "memory", :type_instance => "active", :values => [8])
|
169
|
+
@manager.expects(:raise_alarm).never
|
170
|
+
|
171
|
+
@manager.packet_received(p)
|
172
|
+
end
|
173
|
+
|
174
|
+
should 'not reraise another alarm if time difference stays above the threshold' do
|
175
|
+
p_alarm = Factory(:data_point, :time => Time.now - 60, :plugin => "memory", :type => "memory", :type_instance => "active", :values => [81])
|
176
|
+
p_alarm2 = Factory(:data_point, :time => Time.now - 50, :plugin => "memory", :type => "memory", :type_instance => "active", :values => [81])
|
177
|
+
|
178
|
+
@manager.expects(:active_alarms_for).with(p_alarm.measure_id).returns( [RRDNotifier::AlarmClockDrift.new(p_alarm, 30)] )
|
179
|
+
@manager.expects(:raise_alarm).never
|
180
|
+
|
181
|
+
@manager.packet_received(p_alarm2)
|
182
|
+
end
|
183
|
+
|
184
|
+
should 'stop the alarm if time difference moves below the threshold' do
|
185
|
+
p_alarm = Factory(:data_point, :time => Time.now - 60, :plugin => "memory", :type => "memory", :type_instance => "active", :values => [81])
|
186
|
+
p_normal = Factory(:data_point, :time => Time.now - 10, :plugin => "memory", :type => "memory", :type_instance => "active", :values => [81])
|
187
|
+
|
188
|
+
@manager.expects(:active_alarms_for).with(p_alarm.measure_id).returns( [RRDNotifier::AlarmClockDrift.new(p_alarm, 30)] )
|
189
|
+
|
190
|
+
@manager.expects(:raise_alarm).never
|
191
|
+
@manager.expects(:stop_specific_alarm).with( p_normal.measure_id, kind_of(RRDNotifier::AlarmClockDrift) )
|
192
|
+
|
193
|
+
@manager.packet_received(p_normal)
|
194
|
+
end
|
195
|
+
|
196
|
+
end
|
197
|
+
|
198
|
+
describe 'a trigger on presence' do
|
199
|
+
before do
|
200
|
+
@interval = 0.5 # seconds
|
201
|
+
@manager.register_alarm('*', "memory/*", "memory/active",
|
202
|
+
:monitor_presence => @interval
|
203
|
+
)
|
204
|
+
end
|
205
|
+
|
206
|
+
should 'raise an alarm if value is missing for more than the threshold' do
|
207
|
+
p = Factory(:data_point, :plugin => "memory", :type => "memory", :type_instance => "active", :values => [8])
|
208
|
+
|
209
|
+
# force the timer to be called
|
210
|
+
EM::expects(:add_timer).with(@interval).yields()
|
211
|
+
|
212
|
+
@manager.expects(:raise_alarm).with(p.measure_id, kind_of(RRDNotifier::AlarmMissingData) )
|
213
|
+
@manager.packet_received(p)
|
214
|
+
end
|
215
|
+
|
216
|
+
should 'not raise an alarm is value missing for less than the threshold' do
|
217
|
+
p = Factory(:data_point, :plugin => "memory", :type => "memory", :type_instance => "active", :values => [8])
|
218
|
+
|
219
|
+
# catch the timer creation but do not execute its callback
|
220
|
+
EM::expects(:add_timer).with(@interval)
|
221
|
+
|
222
|
+
@manager.expects(:raise_alarm).never
|
223
|
+
@manager.packet_received(p)
|
224
|
+
end
|
225
|
+
|
226
|
+
should 'stop the alarm when a value is received' do
|
227
|
+
p_alarm = Factory(:data_point, :plugin => "memory", :type => "memory", :type_instance => "active", :values => [8])
|
228
|
+
p_normal = Factory(:data_point, :plugin => "memory", :type => "memory", :type_instance => "active", :values => [8])
|
229
|
+
|
230
|
+
alarm_time = Time.now - 60
|
231
|
+
@manager.stubs(:last_update_for).with(p_alarm.measure_id).returns(alarm_time)
|
232
|
+
|
233
|
+
|
234
|
+
# catch the timer creation and execute the calback to raise an alarm
|
235
|
+
timer_id = stub()
|
236
|
+
EM::expects(:add_timer).with(@interval).yields.returns(timer_id).once
|
237
|
+
@manager.expects(:raise_alarm).with(p_alarm.measure_id, kind_of(RRDNotifier::AlarmMissingData) )
|
238
|
+
@manager.packet_received(p_alarm)
|
239
|
+
|
240
|
+
|
241
|
+
EM::expects(:cancel_timer).with(timer_id)
|
242
|
+
EM::expects(:add_timer).with(@interval)
|
243
|
+
@manager.expects(:active_alarms_for).with(p_alarm.measure_id).returns( [RRDNotifier::AlarmMissingData.new(p_alarm, @interval, alarm_time)] )
|
244
|
+
@manager.expects(:stop_specific_alarm).with( p_normal.measure_id, kind_of(RRDNotifier::AlarmMissingData) )
|
245
|
+
@manager.expects(:raise_alarm).never
|
246
|
+
|
247
|
+
@manager.packet_received(p_normal)
|
248
|
+
end
|
249
|
+
|
250
|
+
end
|
251
|
+
|
252
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require File.expand_path('../../common', __FILE__)
|
2
|
+
require File.expand_path('../../../lib/rrd-grapher/notifier/alarm_trigger', __FILE__)
|
3
|
+
|
4
|
+
describe 'AlarmTrigger' do
|
5
|
+
it 'can can parse initialize parameters' do
|
6
|
+
RRDNotifier::AlarmTrigger.load_param("*").should == nil
|
7
|
+
RRDNotifier::AlarmTrigger.load_param("memory").should == "memory"
|
8
|
+
RRDNotifier::AlarmTrigger.load_param("memory/*").should == ["memory", nil]
|
9
|
+
RRDNotifier::AlarmTrigger.load_param("*/*").should == [nil, nil]
|
10
|
+
RRDNotifier::AlarmTrigger.load_param("*/memory").should == [nil, "memory"]
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'can handle packets with multiple counters' do
|
14
|
+
manager = stub('manager', :active_alarm? => nil)
|
15
|
+
trigger = RRDNotifier::AlarmTrigger.new(manager, "*", "*/*", "*/*", :max => 10, :index => 1)
|
16
|
+
|
17
|
+
# we are not testing matching code, bypass
|
18
|
+
trigger.expects(:match?).returns(true)
|
19
|
+
p = Factory(:data_point, :values => [1, 45, 5])
|
20
|
+
|
21
|
+
manager.expects(:raise_alarm).with(p.measure_id, kind_of(RRDNotifier::Alarm))
|
22
|
+
trigger.check_alarms(p)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require File.expand_path('../../common', __FILE__)
|
2
|
+
require File.expand_path('../../../lib/rrd-grapher/notifier/data_struct', __FILE__)
|
3
|
+
|
4
|
+
describe 'DataStruct' do
|
5
|
+
before do
|
6
|
+
@s1 = Class.new(DataStruct) do
|
7
|
+
properties :one, :two
|
8
|
+
end
|
9
|
+
|
10
|
+
@s2 = Class.new(DataStruct) do
|
11
|
+
properties :name, :host
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
should 'have disctinct attributes set for each child class' do
|
16
|
+
@s1.attributes.should == [:one, :two]
|
17
|
+
@s2.attributes.should == [:name, :host]
|
18
|
+
end
|
19
|
+
|
20
|
+
it "can merge data from multiple Hash sources" do
|
21
|
+
obj = @s1.new(:one => 12)
|
22
|
+
obj.merge_data_from(:two => 34, :one => nil)
|
23
|
+
|
24
|
+
obj.one.should == 12
|
25
|
+
obj.two.should == 34
|
26
|
+
end
|
27
|
+
|
28
|
+
it "can merge data from multiple Object sources" do
|
29
|
+
dummy_class = Struct.new(:one, :two)
|
30
|
+
|
31
|
+
d1 = dummy_class.new(23)
|
32
|
+
d2 = dummy_class.new(nil, 56)
|
33
|
+
|
34
|
+
obj = @s1.new(d1)
|
35
|
+
obj.merge_data_from(d2)
|
36
|
+
|
37
|
+
obj.one.should == 23
|
38
|
+
obj.two.should == 56
|
39
|
+
end
|
40
|
+
|
41
|
+
it "can merge data selectively from multiple Object sources" do
|
42
|
+
dummy_class = Struct.new(:one, :two)
|
43
|
+
|
44
|
+
d1 = dummy_class.new(23)
|
45
|
+
d2 = dummy_class.new(67, 56)
|
46
|
+
|
47
|
+
obj = @s1.new(d1)
|
48
|
+
obj.merge_data_from(d2, [:two])
|
49
|
+
|
50
|
+
obj.one.should == 23
|
51
|
+
obj.two.should == 56
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require File.expand_path('../../common', __FILE__)
|
2
|
+
require File.expand_path('../../../lib/rrd-grapher/notifier', __FILE__)
|
3
|
+
|
4
|
+
# require 'eventmachine'
|
5
|
+
|
6
|
+
describe 'Notifier::Server' do
|
7
|
+
should 'bind an udp socket on start' do
|
8
|
+
EM::expects(:open_datagram_socket).with('local', 7777, RRDNotifier::Server, kind_of(RRDNotifier::AlarmManager), nil, nil)
|
9
|
+
RRDNotifier::Server.start(:host => 'local', :port => 7777)
|
10
|
+
end
|
11
|
+
|
12
|
+
should 'raise an error on unknown constructor option' do
|
13
|
+
err = proc{
|
14
|
+
RRDNotifier::Server.start(:i_am_invalid => "yes really !")
|
15
|
+
}.should.raise()
|
16
|
+
err.message.should.include?("Unknown arguments")
|
17
|
+
end
|
18
|
+
|
19
|
+
describe 'an existing notifier' do
|
20
|
+
before do
|
21
|
+
@alarm_manager = stub('alarm_manager')
|
22
|
+
|
23
|
+
EM::stubs(:open_datagram_socket)
|
24
|
+
@notifier = RRDNotifier::Server.new(nil, @alarm_manager)
|
25
|
+
end
|
26
|
+
|
27
|
+
should "delegate register_alarm to the alarm manager" do
|
28
|
+
@alarm_manager.expects(:register_alarm).with(12, "a useless message")
|
29
|
+
@notifier.register_alarm(12, "a useless message")
|
30
|
+
end
|
31
|
+
|
32
|
+
should 'dispatch parsed packets when data is received' do
|
33
|
+
data = ""
|
34
|
+
packets = [ Factory(:data_point), Factory(:data_point), Factory(:notification) ]
|
35
|
+
|
36
|
+
@alarm_manager.expects(:packet_received).with(packets[0])
|
37
|
+
@alarm_manager.expects(:packet_received).with(packets[1])
|
38
|
+
@alarm_manager.expects(:packet_received).with(packets[2])
|
39
|
+
|
40
|
+
RRDNotifier::RubyParser::expects(:parse).with(data).returns(packets)
|
41
|
+
@notifier.receive_data(data)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,184 @@
|
|
1
|
+
require File.expand_path('../../../common', __FILE__)
|
2
|
+
require File.expand_path('../../../../lib/rrd-grapher/notifier/parsers/bindata_parser', __FILE__)
|
3
|
+
|
4
|
+
# as helper to build packets
|
5
|
+
require File.expand_path('../../../helpers/collectdrb', __FILE__)
|
6
|
+
|
7
|
+
describe 'Collectd Bindata parser' do
|
8
|
+
describe 'Simple packets' do
|
9
|
+
before do
|
10
|
+
@parser = RRDNotifier::BindataParser::Part.new
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'can parse numbers' do
|
14
|
+
data = @parser.read( Collectd::number(1, 122) )
|
15
|
+
data.get_value.should == 122
|
16
|
+
|
17
|
+
data = @parser.read( Collectd::number(1, -2500) )
|
18
|
+
data.get_value.should == -2500
|
19
|
+
|
20
|
+
data = @parser.read( Collectd::number(1, 356798) )
|
21
|
+
data.get_value.should == 356798
|
22
|
+
end
|
23
|
+
|
24
|
+
should 'parse strings' do
|
25
|
+
data = @parser.read( Collectd::string(0, "hostname1") )
|
26
|
+
data.get_value.should == 'hostname1'
|
27
|
+
|
28
|
+
data = @parser.read( Collectd::string(0, "string with spaces") )
|
29
|
+
data.get_value.should == 'string with spaces'
|
30
|
+
|
31
|
+
data = @parser.read( Collectd::string(0, "a really long string with many words in it") )
|
32
|
+
data.get_value.should == 'a really long string with many words in it'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe 'One notification in buffer' do
|
37
|
+
before do
|
38
|
+
@now = Time.new.to_i
|
39
|
+
|
40
|
+
@pkt = ""
|
41
|
+
@pkt << Collectd.number(1, @now)
|
42
|
+
@pkt << Collectd.string(0, 'hostname')
|
43
|
+
|
44
|
+
@pkt << Collectd.string(2, 'plugin')
|
45
|
+
@pkt << Collectd.string(3, 'plugin_inst')
|
46
|
+
@pkt << Collectd.string(4, 'type')
|
47
|
+
@pkt << Collectd.string(5, 'type_inst')
|
48
|
+
@pkt << Collectd.number(257, 2) # severity
|
49
|
+
@pkt << Collectd.string(256, 'a message')
|
50
|
+
end
|
51
|
+
|
52
|
+
should 'parse the notification' do
|
53
|
+
data = RRDNotifier::BindataParser.parse(@pkt)
|
54
|
+
|
55
|
+
data.size.should == 1
|
56
|
+
|
57
|
+
data[0].class.should == RRDNotifier::Packet
|
58
|
+
data[0].host.should == 'hostname'
|
59
|
+
data[0].time.should == @now
|
60
|
+
data[0].plugin.should == 'plugin'
|
61
|
+
data[0].plugin_instance.should == 'plugin_inst'
|
62
|
+
data[0].type.should == 'type'
|
63
|
+
data[0].type_instance.should == 'type_inst'
|
64
|
+
data[0].message.should == 'a message'
|
65
|
+
data[0].severity.should == 2
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe 'One packet in buffer' do
|
71
|
+
before do
|
72
|
+
@now = Time.new.to_i
|
73
|
+
@interval = 10
|
74
|
+
@pkt = ""
|
75
|
+
@pkt << Collectd.number(1, @now)
|
76
|
+
@pkt << Collectd.string(0, 'hostname')
|
77
|
+
@pkt << Collectd.number(7, @interval)
|
78
|
+
|
79
|
+
@pkt << Collectd.string(2, 'plugin')
|
80
|
+
@pkt << Collectd.string(3, 'plugin_inst')
|
81
|
+
@pkt << Collectd.string(4, 'type')
|
82
|
+
@pkt << Collectd.string(5, 'type_inst')
|
83
|
+
|
84
|
+
@pkt << Collectd.values([[:counter, 1034], [:gauge, 3.45]])
|
85
|
+
end
|
86
|
+
|
87
|
+
should 'parse it' do
|
88
|
+
data = nil
|
89
|
+
# BinData::trace_reading do
|
90
|
+
data = RRDNotifier::BindataParser.parse(@pkt)
|
91
|
+
# end
|
92
|
+
|
93
|
+
data.size.should == 1
|
94
|
+
|
95
|
+
data[0].class.should == RRDNotifier::Packet
|
96
|
+
data[0].host.should == 'hostname'
|
97
|
+
data[0].time.should == @now
|
98
|
+
data[0].interval.should == @interval
|
99
|
+
data[0].plugin.should == 'plugin'
|
100
|
+
data[0].plugin_instance.should == 'plugin_inst'
|
101
|
+
data[0].type.should == 'type'
|
102
|
+
data[0].type_instance.should == 'type_inst'
|
103
|
+
|
104
|
+
data[0].values.size.should == 2
|
105
|
+
data[0].values[0].should == 1034
|
106
|
+
data[0].values[1].should == 3.45
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe "Multiple packets in buffer" do
|
111
|
+
before do
|
112
|
+
@now = Time.new.to_i
|
113
|
+
@interval = 10
|
114
|
+
|
115
|
+
@pkt = Collectd.string(0, 'hostname')
|
116
|
+
@pkt << Collectd.number(1, @now)
|
117
|
+
@pkt << Collectd.number(7, @interval)
|
118
|
+
|
119
|
+
@pkt << Collectd.string(2, 'plugin')
|
120
|
+
@pkt << Collectd.string(3, 'plugin_inst')
|
121
|
+
@pkt << Collectd.string(4, 'type')
|
122
|
+
@pkt << Collectd.string(5, 'type_inst')
|
123
|
+
|
124
|
+
@pkt << Collectd.values([[:counter, 1034], [:gauge, 3.45]])
|
125
|
+
|
126
|
+
@pkt << Collectd.string(2, 'plugin2')
|
127
|
+
@pkt << Collectd.string(3, 'plugin2_inst')
|
128
|
+
@pkt << Collectd.string(4, 'type2')
|
129
|
+
@pkt << Collectd.string(5, 'type2_inst')
|
130
|
+
|
131
|
+
@pkt << Collectd.values([[:counter, 42]])
|
132
|
+
|
133
|
+
|
134
|
+
@pkt << Collectd.string(5, 'type21_inst')
|
135
|
+
@pkt << Collectd.values([[:gauge, 3.1415927]])
|
136
|
+
end
|
137
|
+
|
138
|
+
should 'parse it' do
|
139
|
+
data = nil
|
140
|
+
# BinData::trace_reading do
|
141
|
+
data = RRDNotifier::BindataParser.parse(@pkt)
|
142
|
+
# end
|
143
|
+
|
144
|
+
data.size.should == 3
|
145
|
+
|
146
|
+
data[0].class.should == RRDNotifier::Packet
|
147
|
+
|
148
|
+
# data.packets.size.should == 8
|
149
|
+
|
150
|
+
data[0].host.should == 'hostname'
|
151
|
+
data[0].time.should == @now
|
152
|
+
data[0].interval.should == @interval
|
153
|
+
data[0].plugin.should == 'plugin'
|
154
|
+
data[0].plugin_instance.should == 'plugin_inst'
|
155
|
+
data[0].type.should == 'type'
|
156
|
+
data[0].type_instance.should == 'type_inst'
|
157
|
+
data[0].values.size.should == 2
|
158
|
+
data[0].values[0].should == 1034
|
159
|
+
data[0].values[1].should == 3.45
|
160
|
+
|
161
|
+
data[1].host.should == 'hostname'
|
162
|
+
data[1].time.should == @now
|
163
|
+
data[1].interval.should == @interval
|
164
|
+
data[1].plugin.should == 'plugin2'
|
165
|
+
data[1].plugin_instance.should == 'plugin2_inst'
|
166
|
+
data[1].type.should == 'type2'
|
167
|
+
data[1].type_instance.should == 'type2_inst'
|
168
|
+
data[1].values.size.should == 1
|
169
|
+
data[1].values[0].should == 42
|
170
|
+
|
171
|
+
data[2].host.should == 'hostname'
|
172
|
+
data[2].time.should == @now
|
173
|
+
data[2].interval.should == @interval
|
174
|
+
data[2].plugin.should == 'plugin2'
|
175
|
+
data[2].plugin_instance.should == 'plugin2_inst'
|
176
|
+
data[2].type.should == 'type2'
|
177
|
+
data[2].type_instance.should == 'type21_inst'
|
178
|
+
data[2].values.size.should == 1
|
179
|
+
data[2].values[0].should == 3.1415927
|
180
|
+
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
end
|