arborist 0.0.1.pre20160106113421

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.
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
+