arborist 0.0.1.pre20161005182540 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -19,9 +19,9 @@ describe Arborist::MonitorRunner do
19
19
 
20
20
  let( :monitor_class ) { Class.new(Arborist::Monitor) }
21
21
 
22
- let( :mon1 ) { monitor_class.new("testing monitor1") }
23
- let( :mon2 ) { monitor_class.new("testing monitor2") { splay 10 } }
24
- let( :mon3 ) { monitor_class.new("testing monitor3") }
22
+ let( :mon1 ) { monitor_class.new("testing monitor1", :testing) }
23
+ let( :mon2 ) { monitor_class.new("testing monitor2", :testing) { splay 10 } }
24
+ let( :mon3 ) { monitor_class.new("testing monitor3", :testing) }
25
25
  let( :monitors ) {[ mon1, mon2, mon3 ]}
26
26
 
27
27
 
@@ -146,6 +146,35 @@ describe Arborist::MonitorRunner do
146
146
 
147
147
  end
148
148
 
149
+
150
+ it "manages the communication between the monitor and the manager" do
151
+ monitor = Arborist::Monitor.new do
152
+ description 'test monitor'
153
+ key :test
154
+ every 20
155
+ match type: 'host'
156
+ use :addresses
157
+ exec 'fping', '-e', '-t', '150'
158
+ end
159
+ nodes = { 'test1' => {}, 'test2' => {} }
160
+ monitor_results = { 'test1' => {ping: {rtt: 1}}, 'test2' => {ping: {rtt: 8}} }
161
+
162
+ expect( handler ).to receive( :fetch ).
163
+ with( {type: 'host'}, false, [:addresses], {} ).
164
+ and_yield( nodes )
165
+
166
+ expect( monitor ).to receive( :run ).with( nodes ).
167
+ and_return( monitor_results )
168
+
169
+ expect( handler ).to receive( :update ).
170
+ with({
171
+ "test1"=>{:ping=>{:rtt=>1}, "_monitor_key"=>:test},
172
+ "test2"=>{:ping=>{:rtt=>8}, "_monitor_key"=>:test}
173
+ })
174
+
175
+ handler.run_monitor( monitor )
176
+ end
177
+
149
178
  end
150
179
 
151
180
  end
@@ -32,10 +32,11 @@ describe Arborist::Monitor do
32
32
  }}
33
33
 
34
34
 
35
- it "can be created with just a description" do
36
- mon = described_class.new( "the description" )
35
+ it "can be created with just a description and key" do
36
+ mon = described_class.new( "the description", :key )
37
37
  expect( mon ).to be_a( described_class )
38
38
  expect( mon.description ).to eq( "the description" )
39
+ expect( mon.key ).to eq( :key )
39
40
  expect( mon.include_down? ).to be_falsey
40
41
  expect( mon.interval ).to eq( Arborist::Monitor::DEFAULT_INTERVAL )
41
42
  expect( mon.splay ).to eq( 0 )
@@ -45,9 +46,75 @@ describe Arborist::Monitor do
45
46
  end
46
47
 
47
48
 
49
+ it "can be created with just a description and key set in the block" do
50
+ mon = described_class.new do
51
+ description "the description"
52
+ key :key
53
+ end
54
+
55
+ expect( mon ).to be_a( described_class )
56
+ expect( mon.description ).to eq( "the description" )
57
+ expect( mon.key ).to eq( :key )
58
+ expect( mon.include_down? ).to be_falsey
59
+ expect( mon.interval ).to eq( Arborist::Monitor::DEFAULT_INTERVAL )
60
+ expect( mon.splay ).to eq( 0 )
61
+ expect( mon.positive_criteria ).to be_empty
62
+ expect( mon.negative_criteria ).to be_empty
63
+ expect( mon.node_properties ).to be_empty
64
+ end
65
+
66
+
67
+ it "can be created with description set in the constructor and key in the block" do
68
+ mon = described_class.new( "the description" ) do
69
+ key :key
70
+ end
71
+
72
+ expect( mon ).to be_a( described_class )
73
+ expect( mon.description ).to eq( "the description" )
74
+ expect( mon.key ).to eq( :key )
75
+ expect( mon.include_down? ).to be_falsey
76
+ expect( mon.interval ).to eq( Arborist::Monitor::DEFAULT_INTERVAL )
77
+ expect( mon.splay ).to eq( 0 )
78
+ expect( mon.positive_criteria ).to be_empty
79
+ expect( mon.negative_criteria ).to be_empty
80
+ expect( mon.node_properties ).to be_empty
81
+ end
82
+
83
+
84
+ it "can be created with a DSL function" do
85
+ mon = Arborist::Monitor( "the description", :the_key )
86
+
87
+ expect( mon ).to be_a( described_class )
88
+ expect( mon.description ).to eq( "the description" )
89
+ expect( mon.key ).to eq( :the_key )
90
+ expect( mon.include_down? ).to be_falsey
91
+ expect( mon.interval ).to eq( Arborist::Monitor::DEFAULT_INTERVAL )
92
+ expect( mon.splay ).to eq( 0 )
93
+ expect( mon.positive_criteria ).to be_empty
94
+ expect( mon.negative_criteria ).to be_empty
95
+ expect( mon.node_properties ).to be_empty
96
+ end
97
+
98
+
99
+ it "raises a ConfigError if constructed without a description" do
100
+ expect {
101
+ described_class.new do
102
+ key :key
103
+ end
104
+ }.to raise_error( Arborist::ConfigError, /no description/i )
105
+ end
106
+
107
+
108
+ it "raises a ConfigError if constructed without a key" do
109
+ expect {
110
+ described_class.new( "the description" )
111
+ }.to raise_error( Arborist::ConfigError, /no key/i )
112
+ end
113
+
114
+
48
115
  it "yields itself to the provided block for the DSL" do
49
116
  block_self = nil
50
- mon = described_class.new( "testing monitor" ) do
117
+ mon = described_class.new( "testing monitor", :testing ) do
51
118
  block_self = self
52
119
  end
53
120
 
@@ -56,7 +123,7 @@ describe Arborist::Monitor do
56
123
 
57
124
 
58
125
  it "can specify an interval" do
59
- mon = described_class.new( "testing monitor" ) do
126
+ mon = described_class.new( "testing monitor", :testing ) do
60
127
  every 30
61
128
  end
62
129
 
@@ -65,7 +132,7 @@ describe Arborist::Monitor do
65
132
 
66
133
 
67
134
  it "can specify a splay" do
68
- mon = described_class.new( "testing monitor" ) do
135
+ mon = described_class.new( "testing monitor", :testing ) do
69
136
  splay 15
70
137
  end
71
138
 
@@ -74,7 +141,7 @@ describe Arborist::Monitor do
74
141
 
75
142
 
76
143
  it "can specify criteria for matching nodes to monitor" do
77
- mon = described_class.new( "testing monitor" ) do
144
+ mon = described_class.new( "testing monitor", :testing ) do
78
145
  match type: 'host'
79
146
  end
80
147
 
@@ -83,7 +150,7 @@ describe Arborist::Monitor do
83
150
 
84
151
 
85
152
  it "can specify criteria for matching nodes not to monitor" do
86
- mon = described_class.new( "testing monitor" ) do
153
+ mon = described_class.new( "testing monitor", :testing ) do
87
154
  exclude tag: 'laptop'
88
155
  end
89
156
 
@@ -91,8 +158,17 @@ describe Arborist::Monitor do
91
158
  end
92
159
 
93
160
 
161
+ it "automatically includes 'down' nodes if the matcher specifies an unreachable state" do
162
+ mon = described_class.new( "testing monitor", :testing ) do
163
+ match status: 'down'
164
+ end
165
+
166
+ expect( mon.include_down? ).to be_truthy
167
+ end
168
+
169
+
94
170
  it "can specify that it will include hosts marked as 'down'" do
95
- mon = described_class.new( "testing monitor" ) do
171
+ mon = described_class.new( "testing monitor", :testing ) do
96
172
  include_down true
97
173
  end
98
174
 
@@ -101,7 +177,7 @@ describe Arborist::Monitor do
101
177
 
102
178
 
103
179
  it "can specify one or more properties to include in the input to the monitor" do
104
- mon = described_class.new( "testing monitor" ) do
180
+ mon = described_class.new( "testing monitor", :testing ) do
105
181
  use :address, :tags
106
182
  end
107
183
 
@@ -110,7 +186,7 @@ describe Arborist::Monitor do
110
186
 
111
187
 
112
188
  it "can specify a command to exec to do the monitor's work" do
113
- mon = described_class.new( "the description" ) do
189
+ mon = described_class.new( "the description", :testing ) do
114
190
  exec 'cat'
115
191
  end
116
192
 
@@ -123,7 +199,7 @@ describe Arborist::Monitor do
123
199
  it "can specify a block to call to do the monitor's work" do
124
200
  block_was_run = false
125
201
 
126
- mon = described_class.new( "the description" )
202
+ mon = described_class.new( "the description", :testing )
127
203
  mon.exec do |nodes|
128
204
  block_was_run = true
129
205
  end
@@ -145,7 +221,7 @@ describe Arborist::Monitor do
145
221
  end
146
222
 
147
223
 
148
- mon = described_class.new( "the description" )
224
+ mon = described_class.new( "the description", :testing )
149
225
  mon.exec( mod )
150
226
 
151
227
  mon.run( testing_nodes )
@@ -155,7 +231,7 @@ describe Arborist::Monitor do
155
231
 
156
232
 
157
233
  it "can provide a function for building arguments for its command" do
158
- mon = described_class.new( "the description" ) do
234
+ mon = described_class.new( "the description", :testing ) do
159
235
 
160
236
  exec 'the_command'
161
237
 
@@ -182,7 +258,7 @@ describe Arborist::Monitor do
182
258
 
183
259
 
184
260
  it "handles system call errors while running the monitor command" do
185
- mon = described_class.new( "the description" ) do
261
+ mon = described_class.new( "the description", :testing ) do
186
262
 
187
263
  exec 'the_command'
188
264
 
@@ -205,7 +281,7 @@ describe Arborist::Monitor do
205
281
 
206
282
 
207
283
  it "can provide a function for providing input to its command" do
208
- mon = described_class.new( "the description" ) do
284
+ mon = described_class.new( "the description", :testing ) do
209
285
 
210
286
  exec 'cat'
211
287
 
@@ -224,7 +300,7 @@ describe Arborist::Monitor do
224
300
 
225
301
 
226
302
  it "can provide a function for parsing its command's output" do
227
- mon = described_class.new( "the description" ) do
303
+ mon = described_class.new( "the description", :testing ) do
228
304
 
229
305
  exec 'cat'
230
306
 
@@ -259,7 +335,7 @@ describe Arborist::Monitor do
259
335
 
260
336
  end
261
337
 
262
- mon = described_class.new( "the description" ) do
338
+ mon = described_class.new( "the description", :testing ) do
263
339
  exec 'cat'
264
340
  exec_callbacks( the_module )
265
341
  end
@@ -156,7 +156,6 @@ describe Arborist::Node do
156
156
  expect( node ).to_not have_children
157
157
  end
158
158
 
159
-
160
159
  describe "status" do
161
160
 
162
161
  it "starts out in `unknown` status" do
@@ -177,7 +176,7 @@ describe Arborist::Node do
177
176
 
178
177
  it "transitions from `down` to `acked` status if it's updated with an `ack` property" do
179
178
  node.status = 'down'
180
- node.error = 'Something is wrong | he falls | betraying the trust | "\
179
+ node.errors = 'Something is wrong | he falls | betraying the trust | "\
181
180
  "there is a disaster in his life.'
182
181
  node.update( ack: {message: "Leitmotiv", sender: 'ged'} )
183
182
  expect( node ).to be_acked
@@ -185,8 +184,8 @@ describe Arborist::Node do
185
184
 
186
185
  it "transitions from `acked` to `up` status if its error is cleared" do
187
186
  node.status = 'down'
188
- node.error = 'Something is wrong | he falls | betraying the trust | "\
189
- "there is a disaster in his life.'
187
+ node.errors = { '_' => 'Something is wrong | he falls | betraying the trust | "\
188
+ "there is a disaster in his life.' }
190
189
  node.update( ack: {message: "Leitmotiv", sender: 'ged'} )
191
190
  node.update( error: nil )
192
191
 
@@ -195,7 +194,7 @@ describe Arborist::Node do
195
194
 
196
195
  it "stays `up` if its error is cleared and stays cleared" do
197
196
  node.status = 'down'
198
- node.error = 'stay up damn you!'
197
+ node.errors = { '_' => 'stay up damn you!' }
199
198
  node.update( ack: {message: "Leitmotiv", sender: 'ged'} )
200
199
  node.update( error: nil )
201
200
  node.update( error: nil )
@@ -245,6 +244,40 @@ describe Arborist::Node do
245
244
  expect( node.ack ).to be_nil
246
245
  end
247
246
 
247
+ it "knows if it's status deems it 'reachable'" do
248
+ node.update( error: nil )
249
+ expect( node ).to be_reachable
250
+ expect( node ).to_not be_unreachable
251
+ end
252
+
253
+ it "knows if it's status deems it 'unreachable'" do
254
+ node.update( error: 'ded' )
255
+ expect( node ).to be_unreachable
256
+ expect( node ).to_not be_reachable
257
+ end
258
+
259
+ it "groups errors from separate monitor by their key" do
260
+ expect( node ).to be_unknown
261
+
262
+ node.update( _monitor_key: 'MonitorTron2000', error: 'ded' )
263
+ node.update( _monitor_key: 'MonitorTron5000', error: 'moar ded' )
264
+ expect( node ).to be_down
265
+
266
+ expect( node.errors.length ).to eq( 2 )
267
+ node.update( _monitor_key: 'MonitorTron5000' )
268
+
269
+ expect( node ).to be_down
270
+ expect( node.errors.length ).to eq( 1 )
271
+
272
+ node.update( _monitor_key: 'MonitorTron2000' )
273
+ expect( node ).to be_up
274
+ end
275
+
276
+ it "sets a default monitor key" do
277
+ node.update( error: 'ded' )
278
+ expect( node ).to be_down
279
+ expect( node.errors ).to eq({ '_' => 'ded' })
280
+ end
248
281
  end
249
282
 
250
283
 
@@ -380,7 +413,7 @@ describe Arborist::Node do
380
413
 
381
414
  old_node.status = 'down'
382
415
  old_node.status_changed = Time.now - 400
383
- old_node.error = "Host unreachable"
416
+ old_node.errors = "Host unreachable"
384
417
  old_node.update(
385
418
  ack: {
386
419
  'time' => Time.now - 200,
@@ -400,7 +433,7 @@ describe Arborist::Node do
400
433
 
401
434
  expect( node.status ).to eq( old_node.status )
402
435
  expect( node.status_changed ).to eq( old_node.status_changed )
403
- expect( node.error ).to eq( old_node.error )
436
+ expect( node.errors ).to eq( old_node.errors )
404
437
  expect( node.ack ).to eq( old_node.ack )
405
438
  expect( node.properties ).to include( old_node.properties )
406
439
  expect( node.last_contacted ).to eq( old_node.last_contacted )
@@ -455,7 +488,7 @@ describe Arborist::Node do
455
488
  expect( result ).to include(
456
489
  :identifier,
457
490
  :parent, :description, :tags, :properties, :ack, :status,
458
- :last_contacted, :status_changed, :error, :quieted_reasons,
491
+ :last_contacted, :status_changed, :errors, :quieted_reasons,
459
492
  :dependencies
460
493
  )
461
494
  expect( result[:identifier] ).to eq( 'foo' )
@@ -467,7 +500,8 @@ describe Arborist::Node do
467
500
  expect( result[:ack] ).to be_nil
468
501
  expect( result[:last_contacted] ).to eq( node.last_contacted.iso8601 )
469
502
  expect( result[:status_changed] ).to eq( node.status_changed.iso8601 )
470
- expect( result[:error] ).to be_nil
503
+ expect( result[:errors] ).to be_a( Hash )
504
+ expect( result[:errors] ).to be_empty
471
505
  expect( result[:dependencies] ).to be_a( Hash )
472
506
  expect( result[:quieted_reasons] ).to be_a( Hash )
473
507
  end
@@ -690,6 +724,12 @@ describe Arborist::Node do
690
724
  end
691
725
 
692
726
 
727
+ it "can be matched with its parent" do
728
+ expect( node ).to match_criteria( parent: 'bar' )
729
+ expect( node ).to_not match_criteria( parent: 'hooowat' )
730
+ end
731
+
732
+
693
733
  it "can be matched with a single tag" do
694
734
  expect( node ).to match_criteria( tag: 'hunky' )
695
735
  expect( node ).to_not match_criteria( tag: 'plucky' )
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: arborist
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.pre20161005182540
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Granger
@@ -36,7 +36,7 @@ cert_chain:
36
36
  w8aNA5re5+Rt/Vvjxj5AcEnZnZiz5x959NaddQocX32Z1unHw44pzRNUur1GInfW
37
37
  p4vpx2kUSFSAGjtCbDGTNV2AH8w9OU4xEmNz8c5lyoA=
38
38
  -----END CERTIFICATE-----
39
- date: 2016-10-06 00:00:00.000000000 Z
39
+ date: 2017-01-02 00:00:00.000000000 Z
40
40
  dependencies:
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: schedulability
@@ -58,28 +58,28 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '0.11'
61
+ version: '0.12'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '0.11'
68
+ version: '0.12'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: configurability
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '2.2'
75
+ version: '3.0'
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '2.2'
82
+ version: '3.0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: pluggability
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -207,61 +207,61 @@ dependencies:
207
207
  - !ruby/object:Gem::Version
208
208
  version: '0.2'
209
209
  - !ruby/object:Gem::Dependency
210
- name: rdoc
210
+ name: rspec
211
211
  requirement: !ruby/object:Gem::Requirement
212
212
  requirements:
213
213
  - - "~>"
214
214
  - !ruby/object:Gem::Version
215
- version: '4.0'
215
+ version: '3.2'
216
216
  type: :development
217
217
  prerelease: false
218
218
  version_requirements: !ruby/object:Gem::Requirement
219
219
  requirements:
220
220
  - - "~>"
221
221
  - !ruby/object:Gem::Version
222
- version: '4.0'
222
+ version: '3.2'
223
223
  - !ruby/object:Gem::Dependency
224
- name: rspec
224
+ name: simplecov
225
225
  requirement: !ruby/object:Gem::Requirement
226
226
  requirements:
227
227
  - - "~>"
228
228
  - !ruby/object:Gem::Version
229
- version: '3.2'
229
+ version: '0.9'
230
230
  type: :development
231
231
  prerelease: false
232
232
  version_requirements: !ruby/object:Gem::Requirement
233
233
  requirements:
234
234
  - - "~>"
235
235
  - !ruby/object:Gem::Version
236
- version: '3.2'
236
+ version: '0.9'
237
237
  - !ruby/object:Gem::Dependency
238
- name: simplecov
238
+ name: timecop
239
239
  requirement: !ruby/object:Gem::Requirement
240
240
  requirements:
241
241
  - - "~>"
242
242
  - !ruby/object:Gem::Version
243
- version: '0.9'
243
+ version: '0.7'
244
244
  type: :development
245
245
  prerelease: false
246
246
  version_requirements: !ruby/object:Gem::Requirement
247
247
  requirements:
248
248
  - - "~>"
249
249
  - !ruby/object:Gem::Version
250
- version: '0.9'
250
+ version: '0.7'
251
251
  - !ruby/object:Gem::Dependency
252
- name: timecop
252
+ name: rdoc
253
253
  requirement: !ruby/object:Gem::Requirement
254
254
  requirements:
255
255
  - - "~>"
256
256
  - !ruby/object:Gem::Version
257
- version: '0.7'
257
+ version: '4.0'
258
258
  type: :development
259
259
  prerelease: false
260
260
  version_requirements: !ruby/object:Gem::Requirement
261
261
  requirements:
262
262
  - - "~>"
263
263
  - !ruby/object:Gem::Version
264
- version: '0.7'
264
+ version: '4.0'
265
265
  - !ruby/object:Gem::Dependency
266
266
  name: hoe
267
267
  requirement: !ruby/object:Gem::Requirement
@@ -408,12 +408,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
408
408
  version: 2.3.1
409
409
  required_rubygems_version: !ruby/object:Gem::Requirement
410
410
  requirements:
411
- - - ">"
411
+ - - ">="
412
412
  - !ruby/object:Gem::Version
413
- version: 1.3.1
413
+ version: '0'
414
414
  requirements: []
415
415
  rubyforge_project:
416
- rubygems_version: 2.5.1
416
+ rubygems_version: 2.6.8
417
417
  signing_key:
418
418
  specification_version: 4
419
419
  summary: Arborist is a monitoring toolkit that follows the UNIX philosophy of small