arborist 0.0.1.pre20160106113421

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +7 -0
  2. data/.document +4 -0
  3. data/.simplecov +9 -0
  4. data/ChangeLog +417 -0
  5. data/Events.md +20 -0
  6. data/History.md +4 -0
  7. data/LICENSE +29 -0
  8. data/Manifest.txt +72 -0
  9. data/Monitors.md +141 -0
  10. data/Nodes.md +0 -0
  11. data/Observers.md +72 -0
  12. data/Protocol.md +214 -0
  13. data/README.md +75 -0
  14. data/Rakefile +81 -0
  15. data/TODO.md +24 -0
  16. data/bin/amanagerd +10 -0
  17. data/bin/amonitord +12 -0
  18. data/bin/aobserverd +12 -0
  19. data/lib/arborist.rb +182 -0
  20. data/lib/arborist/client.rb +191 -0
  21. data/lib/arborist/event.rb +61 -0
  22. data/lib/arborist/event/node_acked.rb +18 -0
  23. data/lib/arborist/event/node_delta.rb +20 -0
  24. data/lib/arborist/event/node_matching.rb +34 -0
  25. data/lib/arborist/event/node_update.rb +19 -0
  26. data/lib/arborist/event/sys_reloaded.rb +15 -0
  27. data/lib/arborist/exceptions.rb +21 -0
  28. data/lib/arborist/manager.rb +508 -0
  29. data/lib/arborist/manager/event_publisher.rb +97 -0
  30. data/lib/arborist/manager/tree_api.rb +207 -0
  31. data/lib/arborist/mixins.rb +363 -0
  32. data/lib/arborist/monitor.rb +377 -0
  33. data/lib/arborist/monitor/socket.rb +163 -0
  34. data/lib/arborist/monitor_runner.rb +217 -0
  35. data/lib/arborist/node.rb +700 -0
  36. data/lib/arborist/node/host.rb +87 -0
  37. data/lib/arborist/node/root.rb +60 -0
  38. data/lib/arborist/node/service.rb +112 -0
  39. data/lib/arborist/observer.rb +176 -0
  40. data/lib/arborist/observer/action.rb +125 -0
  41. data/lib/arborist/observer/summarize.rb +105 -0
  42. data/lib/arborist/observer_runner.rb +181 -0
  43. data/lib/arborist/subscription.rb +82 -0
  44. data/spec/arborist/client_spec.rb +282 -0
  45. data/spec/arborist/event/node_update_spec.rb +71 -0
  46. data/spec/arborist/event_spec.rb +64 -0
  47. data/spec/arborist/manager/event_publisher_spec.rb +66 -0
  48. data/spec/arborist/manager/tree_api_spec.rb +458 -0
  49. data/spec/arborist/manager_spec.rb +442 -0
  50. data/spec/arborist/mixins_spec.rb +195 -0
  51. data/spec/arborist/monitor/socket_spec.rb +195 -0
  52. data/spec/arborist/monitor_runner_spec.rb +152 -0
  53. data/spec/arborist/monitor_spec.rb +251 -0
  54. data/spec/arborist/node/host_spec.rb +104 -0
  55. data/spec/arborist/node/root_spec.rb +29 -0
  56. data/spec/arborist/node/service_spec.rb +98 -0
  57. data/spec/arborist/node_spec.rb +552 -0
  58. data/spec/arborist/observer/action_spec.rb +205 -0
  59. data/spec/arborist/observer/summarize_spec.rb +294 -0
  60. data/spec/arborist/observer_spec.rb +146 -0
  61. data/spec/arborist/subscription_spec.rb +71 -0
  62. data/spec/arborist_spec.rb +146 -0
  63. data/spec/data/monitors/pings.rb +80 -0
  64. data/spec/data/monitors/port_checks.rb +27 -0
  65. data/spec/data/monitors/system_resources.rb +30 -0
  66. data/spec/data/monitors/web_services.rb +17 -0
  67. data/spec/data/nodes/duir.rb +20 -0
  68. data/spec/data/nodes/localhost.rb +15 -0
  69. data/spec/data/nodes/sidonie.rb +29 -0
  70. data/spec/data/nodes/yevaud.rb +26 -0
  71. data/spec/data/observers/auditor.rb +23 -0
  72. data/spec/data/observers/webservices.rb +18 -0
  73. data/spec/spec_helper.rb +117 -0
  74. metadata +368 -0
@@ -0,0 +1,205 @@
1
+ #!/usr/bin/env rspec -cfd
2
+
3
+ require_relative '../../spec_helper'
4
+
5
+ require 'timecop'
6
+ require 'arborist/observer/action'
7
+
8
+
9
+ using Arborist::TimeRefinements
10
+
11
+
12
+ describe Arborist::Observer::Action do
13
+
14
+ let( :event ) {{ stuff: :woo }}
15
+
16
+
17
+ it "can be created with just a block" do
18
+ result = described_class.new {}
19
+ expect( result ).to be_a( described_class )
20
+ expect( result.block ).to respond_to( :call )
21
+ end
22
+
23
+
24
+ it "is supplied the event history if the block has a second argument" do
25
+ history_arg = nil
26
+ action = described_class.new( after: 2 ) do |event, history|
27
+ history_arg = history
28
+ end
29
+
30
+ action.handle_event( event )
31
+ action.handle_event( event )
32
+
33
+ expect( history_arg ).to be_a( Hash )
34
+ end
35
+
36
+
37
+ it "clears the event history when the block is called" do
38
+ action = described_class.new( after: 2 ) {}
39
+ 2.times { action.handle_event(event) }
40
+
41
+ expect( action.event_history ).to be_empty
42
+ end
43
+
44
+
45
+ it "requires a block" do
46
+ expect { described_class.new }.to raise_exception( ArgumentError, /requires a block/i )
47
+ end
48
+
49
+
50
+ context "without any other criteria" do
51
+
52
+ before( :each ) do
53
+ @call_count = 0
54
+ @last_call_arguments = nil
55
+ end
56
+
57
+ let( :action ) do
58
+ described_class.new do |args|
59
+ @call_count += 1
60
+ @last_call_arguments = args
61
+ end
62
+ end
63
+
64
+
65
+ it "calls its block immediately when handling an event" do
66
+ expect { action.handle_event(event) }.to change { @call_count }.by( 1 ).and(
67
+ change { @last_call_arguments }.to( event )
68
+ )
69
+ end
70
+
71
+
72
+ end
73
+
74
+
75
+ # within: 0, after: 1, during: nil
76
+
77
+
78
+ context "with a time threshold" do
79
+
80
+ before( :each ) do
81
+ @call_count = 0
82
+ @last_call_arguments = nil
83
+ end
84
+
85
+ let( :action ) do
86
+ described_class.new( within: 1.minute ) do |args|
87
+ @call_count += 1
88
+ @last_call_arguments = args
89
+ end
90
+ end
91
+
92
+
93
+ it "calls its block if two events arrive within the specified time" do
94
+ Timecop.freeze do
95
+ expect { action.handle_event(event) }.to_not change { @call_count }
96
+ Timecop.travel( 5.seconds ) do
97
+ expect { action.handle_event(event) }.to change { @call_count }.by( 1 )
98
+ end
99
+ end
100
+ end
101
+
102
+
103
+ it "calls its block if three events arrive, and the last two are within the specified time" do
104
+ Timecop.freeze do
105
+ expect { action.handle_event(event) }.to_not change { @call_count }
106
+ Timecop.travel( 65.seconds ) do
107
+ expect { action.handle_event(event) }.to_not change { @call_count }
108
+ Timecop.travel( 5.seconds ) do
109
+ expect { action.handle_event(event) }.to change { @call_count }.by( 1 )
110
+ end
111
+ end
112
+ end
113
+ end
114
+
115
+
116
+ it "doesn't call its block if two events arrive with more than the specified time between them" do
117
+ Timecop.freeze do
118
+ expect { action.handle_event(event) }.to_not change { @call_count }
119
+ Timecop.travel( 65.seconds ) do
120
+ expect { action.handle_event(event) }.to_not change { @call_count }
121
+ end
122
+ end
123
+ end
124
+
125
+
126
+ context "and a count threshold" do
127
+
128
+ let( :action ) do
129
+ described_class.new( within: 1.minute, after: 3 ) do |args|
130
+ @call_count += 1
131
+ @last_call_arguments = args
132
+ end
133
+ end
134
+
135
+ it "calls its block if the threshold number of events arrive within the specified time" do
136
+ Timecop.freeze do
137
+ expect { action.handle_event(event) }.to_not change { @call_count }
138
+ Timecop.travel( 5.seconds ) do
139
+ expect { action.handle_event(event) }.to_not change { @call_count }
140
+ Timecop.travel( 5.seconds ) do
141
+ expect { action.handle_event(event) }.to change { @call_count }.by( 1 )
142
+ end
143
+ end
144
+ end
145
+ end
146
+
147
+
148
+ it "doesn't call the block if the threshold number of events arrive with more than " +
149
+ "the specified time between them" do
150
+ Timecop.freeze do
151
+ expect { action.handle_event(event) }.to_not change { @call_count }
152
+ Timecop.travel( 5.seconds ) do
153
+ expect { action.handle_event(event) }.to_not change { @call_count }
154
+ Timecop.travel( 65.seconds ) do
155
+ expect { action.handle_event(event) }.to_not change { @call_count }
156
+ end
157
+ end
158
+ end
159
+ end
160
+
161
+ end
162
+
163
+ end
164
+
165
+
166
+ context "with a count threshold" do
167
+ before( :each ) do
168
+ @call_count = 0
169
+ @last_call_arguments = nil
170
+ end
171
+
172
+ let( :action ) do
173
+ described_class.new( after: 2 ) do |args|
174
+ @call_count += 1
175
+ @last_call_arguments = args
176
+ end
177
+ end
178
+
179
+
180
+ it "calls the block if more events than count threshold have arrived" do
181
+ expect { action.handle_event(event) }.to_not change { @call_count }
182
+ expect { action.handle_event(event) }.to change { @call_count }.by( 1 )
183
+ end
184
+
185
+ end
186
+
187
+
188
+ context "with a schedule" do
189
+
190
+
191
+ context "with a time threshold" do
192
+
193
+ context "and a count threshold"
194
+
195
+ end
196
+
197
+
198
+ context "and a count threshold"
199
+
200
+ end
201
+
202
+
203
+ end
204
+
205
+
@@ -0,0 +1,294 @@
1
+ #!/usr/bin/env rspec -cfd
2
+
3
+ require_relative '../../spec_helper'
4
+
5
+ require 'timecop'
6
+ require 'arborist/observer/summarize'
7
+
8
+
9
+ using Arborist::TimeRefinements
10
+
11
+
12
+ describe Arborist::Observer::Summarize do
13
+
14
+ before( :all ) do
15
+ @actual_zone = ENV['TZ']
16
+ ENV['TZ'] = 'GMT'
17
+ end
18
+
19
+ after( :all ) do
20
+ ENV['TZ'] = @actual_zone
21
+ end
22
+
23
+
24
+ let( :event ) {{ stuff: :woo }}
25
+
26
+
27
+ it "can be created with just a block and a count" do
28
+ result = described_class.new( every: 1.minute ) {}
29
+ expect( result ).to be_a( described_class )
30
+ expect( result.block ).to respond_to( :call )
31
+ expect( result.time_threshold ).to eq( 1.minute )
32
+ end
33
+
34
+
35
+ it "errors if created with just a block" do
36
+ expect {
37
+ described_class.new {}
38
+ }.to raise_error( ArgumentError, /requires a value/i )
39
+ end
40
+
41
+
42
+ it "is supplied the event history if the block has a second argument" do
43
+ history_arg = nil
44
+ summarize = described_class.new( count: 2 ) do |history|
45
+ history_arg = history
46
+ end
47
+
48
+ summarize.handle_event( event )
49
+ summarize.handle_event( event )
50
+
51
+ expect( history_arg ).to be_a( Hash )
52
+ end
53
+
54
+
55
+ it "clears the event history when the block is called" do
56
+ summarize = described_class.new( count: 2 ) {}
57
+ 2.times { summarize.handle_event(event) }
58
+
59
+ expect( summarize.event_history ).to be_empty
60
+ end
61
+
62
+
63
+ it "requires a block" do
64
+ expect {
65
+ described_class.new( count: 2 )
66
+ }.to raise_exception( ArgumentError, /requires a block/i )
67
+ end
68
+
69
+
70
+
71
+ # every: 0, count: 1, during: nil
72
+
73
+
74
+ context "with a time threshold" do
75
+
76
+ before( :each ) do
77
+ @call_count = 0
78
+ @last_call_arguments = nil
79
+ end
80
+
81
+ let( :summarize ) do
82
+ described_class.new( every: 1.minute ) do |args|
83
+ @call_count += 1
84
+ @last_call_arguments = args
85
+ end
86
+ end
87
+
88
+
89
+ it "calls its block if any events have arrived within the specified time" do
90
+ Timecop.freeze do
91
+ expect { summarize.handle_event(event) }.to_not change { @call_count }
92
+ Timecop.travel( 5.seconds ) do
93
+ expect { summarize.handle_event(event) }.to_not change { @call_count }
94
+ Timecop.travel( 55.seconds ) do
95
+ expect { summarize.on_timer }.to change { @call_count }.by( 1 )
96
+ end
97
+ end
98
+ end
99
+ end
100
+
101
+
102
+ it "doesn't call its block if no events arrive with the specified time" do
103
+ expect { summarize.on_timer }.to_not change { @call_count }
104
+ end
105
+
106
+
107
+ context "and a count threshold" do
108
+
109
+ let( :summarize ) do
110
+ described_class.new( every: 1.minute, count: 3 ) do |args|
111
+ @call_count += 1
112
+ @last_call_arguments = args
113
+ end
114
+ end
115
+
116
+ it "calls its block if the threshold number of events arrive before the specified time threshold" do
117
+ Timecop.freeze do
118
+ expect { summarize.handle_event(event) }.to_not change { @call_count }
119
+ Timecop.travel( 5.seconds ) do
120
+ expect { summarize.handle_event(event) }.to_not change { @call_count }
121
+ Timecop.travel( 5.seconds ) do
122
+ expect { summarize.handle_event(event) }.to change { @call_count }.by( 1 )
123
+ end
124
+ end
125
+ end
126
+ end
127
+
128
+
129
+ it "calls the block if the time threshold is met before the count threshold" do
130
+ Timecop.freeze do
131
+ expect { summarize.handle_event(event) }.to_not change { @call_count }
132
+ Timecop.travel( 5.seconds ) do
133
+ expect { summarize.handle_event(event) }.to_not change { @call_count }
134
+ Timecop.travel( 55.seconds ) do
135
+ expect { summarize.on_timer }.to change { @call_count }
136
+ end
137
+ end
138
+ end
139
+ end
140
+
141
+ end
142
+
143
+ end
144
+
145
+
146
+ context "with a count threshold" do
147
+ before( :each ) do
148
+ @call_count = 0
149
+ @last_call_arguments = nil
150
+ end
151
+
152
+ let( :summarize ) do
153
+ described_class.new( count: 2 ) do |args|
154
+ @call_count += 1
155
+ @last_call_arguments = args
156
+ end
157
+ end
158
+
159
+
160
+ it "calls the block if more events than count threshold have arrived" do
161
+ expect { summarize.handle_event(event) }.to_not change { @call_count }
162
+ expect { summarize.handle_event(event) }.to change { @call_count }.by( 1 )
163
+ end
164
+
165
+ end
166
+
167
+
168
+ context "with a schedule" do
169
+
170
+ before( :each ) do
171
+ @call_count = 0
172
+ @last_call_arguments = nil
173
+ end
174
+
175
+ let( :summarize ) do
176
+ # Count or every threshold is mandatory with a summary, so just use 1
177
+ described_class.new( count: 1, during: 'hr {9am-5pm} wd {Mon-Fri}' ) do |args|
178
+ @call_count += 1
179
+ @last_call_arguments = args
180
+ end
181
+ end
182
+
183
+
184
+ it "calls its block if any events arrive within the specified schedule" do
185
+ Timecop.freeze( '2015-11-11T08:00:00-00:00' ) do
186
+ expect { summarize.handle_event(event) }.to_not change { @call_count }
187
+ Timecop.travel( 2.hours ) do
188
+ expect { summarize.handle_event(event) }.to change { @call_count }.by( 1 )
189
+ Timecop.travel( 9.hours ) do
190
+ expect { summarize.on_timer }.to_not change { @call_count }
191
+ end
192
+ end
193
+ end
194
+ end
195
+
196
+
197
+ it "doesn't call its block if no events arrive with the specified time" do
198
+ expect { summarize.on_timer }.to_not change { @call_count }
199
+ end
200
+
201
+
202
+ context "and a count threshold" do
203
+
204
+ let( :summarize ) do
205
+ # Count or every threshold is mandatory with a summary, so just use 1
206
+ described_class.new( count: 3, during: 'hr {9am-5pm} wd {Mon-Fri}' ) do |args|
207
+ @call_count += 1
208
+ @last_call_arguments = args
209
+ end
210
+ end
211
+
212
+
213
+ it "calls its block if any events arrive within the specified schedule" do
214
+ Timecop.freeze( '2015-11-11T08:00:00-00:00' ) do
215
+ expect { summarize.handle_event(event) }.to_not change { @call_count }
216
+
217
+ Timecop.travel( 2.hours )
218
+ expect { summarize.handle_event(event) }.to_not change { @call_count }
219
+
220
+ Timecop.travel( 2.hours )
221
+ expect { summarize.handle_event(event) }.to_not change { @call_count }
222
+
223
+ Timecop.travel( 2.hours )
224
+ expect { summarize.handle_event(event) }.to change { @call_count }.by( 1 )
225
+
226
+ Timecop.travel( 6.hours )
227
+ expect { summarize.on_timer }.to_not change { @call_count }
228
+ end
229
+ end
230
+
231
+ end
232
+
233
+
234
+ context "and a time threshold" do
235
+
236
+ let( :summarize ) do
237
+ described_class.new( every: 5.minutes, during: 'hr {9am-5pm} wd {Mon-Fri}' ) do |args|
238
+ @call_count += 1
239
+ @last_call_arguments = args
240
+ end
241
+ end
242
+
243
+
244
+ it "calls its block on the timer if any events arrived within the specified schedule" do
245
+ Timecop.freeze( '2015-11-11T09:00:00-00:00' ) do
246
+ expect { summarize.handle_event(event) }.to_not change { @call_count }
247
+ Timecop.travel( 1.minute )
248
+ expect { summarize.handle_event(event) }.to_not change { @call_count }
249
+ Timecop.travel( 4.minutes )
250
+ expect { summarize.on_timer }.to change { @call_count }.by( 1 )
251
+ end
252
+ end
253
+
254
+
255
+
256
+ context "and a count threshold" do
257
+
258
+ let( :summarize ) do
259
+ described_class.new( every: 5.minutes, count: 2, during: 'hr {9am-5pm}' ) do |args|
260
+ @call_count += 1
261
+ @last_call_arguments = args
262
+ end
263
+ end
264
+
265
+
266
+ it "calls its block on the timer if any events arrived within the specified schedule" do
267
+ Timecop.freeze( '2015-11-11T09:00:00-00:00' ) do
268
+ expect { summarize.handle_event(event) }.to_not change { @call_count }
269
+ Timecop.travel( 5.minutes )
270
+ expect { summarize.on_timer }.to change { @call_count }.by( 1 )
271
+ end
272
+ end
273
+
274
+
275
+ it "calls its block on the event if it arrives within the specified schedule and " +
276
+ "exceeds the count threshold" do
277
+ Timecop.freeze( '2015-11-11T09:00:00-00:00' ) do
278
+ expect { summarize.handle_event(event) }.to_not change { @call_count }
279
+ Timecop.travel( 1.minute )
280
+ expect { summarize.handle_event(event) }.to change { @call_count }.by( 1 )
281
+ end
282
+ end
283
+
284
+ end
285
+
286
+ end
287
+
288
+
289
+ end
290
+
291
+
292
+ end
293
+
294
+