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.
@@ -44,237 +44,264 @@ describe Arborist::Client do
44
44
  let( :manager ) { @manager }
45
45
 
46
46
 
47
- it "can fetch the status of the manager it's connected to" do
48
- res = client.status
49
- expect( res ).to include( 'server_version', 'state', 'uptime', 'nodecount' )
50
- end
47
+ describe "high-level API" do
51
48
 
49
+ it "provides a convenience method for acknowledging" do
50
+ manager.nodes['sidonie'].update( error: "Clown apocalypse" )
52
51
 
53
- it "can list the nodes of the manager it's connected to" do
54
- res = client.list
55
- expect( res ).to be_an( Array )
56
- expect( res.length ).to eq( manager.nodes.length )
57
- end
52
+ res = client.acknowledge( :sidonie, "I'm on it.", "ged" )
58
53
 
54
+ expect( manager.nodes['sidonie'] ).to be_acked
55
+ end
59
56
 
60
- it "can list a subtree of the nodes of the manager it's connected to" do
61
- res = client.list( from: 'duir' )
62
- expect( res ).to be_an( Array )
63
- expect( res.length ).to be < manager.nodes.length
64
- end
65
57
 
58
+ it "provides a convenience method for clearing acknowledgments" do
59
+ manager.nodes['sidonie'].update( error: "Clown apocalypse" )
66
60
 
67
- it "can list a depth-limited subtree of the node of the managed it's connected to" do
68
- res = client.list( depth: 2 )
69
- expect( res ).to be_an( Array )
70
- expect( res.length ).to eq( 8 )
71
- end
61
+ res = client.acknowledge( :sidonie, "I'm on it.", "ged" )
62
+ res = client.clear_acknowledgement( :sidonie )
72
63
 
64
+ expect( manager.nodes['sidonie'] ).to_not be_acked
65
+ end
73
66
 
74
- it "can list a depth-limited subtree of the nodes of the manager it's connected to" do
75
- res = client.list( from: 'duir', depth: 1 )
76
- expect( res ).to be_an( Array )
77
- expect( res.length ).to eq( 5 )
78
67
  end
79
68
 
80
69
 
81
- it "can fetch all node properties for all 'up' nodes" do
82
- res = client.fetch
83
- expect( res ).to be_a( Hash )
84
- expect( res.length ).to be == manager.nodes.length
85
- expect( res.values ).to all( be_a(Hash) )
86
- end
70
+ describe "protocol-level API" do
87
71
 
72
+ it "can fetch the status of the manager it's connected to" do
73
+ res = client.status
74
+ expect( res ).to include( 'server_version', 'state', 'uptime', 'nodecount' )
75
+ end
88
76
 
89
- it "can fetch identifiers for all 'up' nodes" do
90
- res = client.fetch( {}, properties: nil )
91
- expect( res ).to be_a( Hash )
92
- expect( res.length ).to be == manager.nodes.length
93
- expect( res.values ).to all( be_empty )
94
- end
95
77
 
78
+ it "can list the nodes of the manager it's connected to" do
79
+ res = client.list
80
+ expect( res ).to be_an( Array )
81
+ expect( res.length ).to eq( manager.nodes.length )
82
+ end
96
83
 
97
- it "can fetch a subset of properties for all 'up' nodes" do
98
- res = client.fetch( {}, properties: [:addresses, :status] )
99
- expect( res ).to be_a( Hash )
100
- expect( res.length ).to be == manager.nodes.length
101
- expect( res.values ).to all( be_a(Hash) )
102
- expect( res.values.map(&:length) ).to all( be <= 2 )
103
- end
104
84
 
85
+ it "can list a subtree of the nodes of the manager it's connected to" do
86
+ res = client.list( from: 'duir' )
87
+ expect( res ).to be_an( Array )
88
+ expect( res.length ).to be < manager.nodes.length
89
+ end
105
90
 
106
- it "can fetch a subset of properties for all 'up' nodes matching specified criteria" do
107
- res = client.fetch( {type: 'host'}, properties: [:addresses, :status] )
108
- expect( res ).to be_a( Hash )
109
- expect( res.length ).to be == manager.nodes.values.count {|n| n.type == 'host' }
110
- expect( res.values ).to all( include('addresses', 'status') )
111
- end
112
91
 
92
+ it "can list a depth-limited subtree of the node of the managed it's connected to" do
93
+ res = client.list( depth: 2 )
94
+ expect( res ).to be_an( Array )
95
+ expect( res.length ).to eq( 8 )
96
+ end
113
97
 
114
- it "can fetch all node properties for 'up' nodes that don't match specified criteria" do
115
- res = client.fetch( {}, properties: [:addresses, :status], exclude: {tag: 'testing'} )
116
98
 
117
- testing_nodes = manager.nodes.values.select {|n| n.tags.include?('testing') }
99
+ it "can list a depth-limited subtree of the nodes of the manager it's connected to" do
100
+ res = client.list( from: 'duir', depth: 1 )
101
+ expect( res ).to be_an( Array )
102
+ expect( res.length ).to eq( 5 )
103
+ end
118
104
 
119
- expect( res ).to be_a( Hash )
120
- expect( res ).to_not be_empty()
121
- expect( res.length ).to eq( manager.nodes.length - testing_nodes.length )
122
- expect( res.values ).to all( be_a(Hash) )
123
- end
124
105
 
106
+ it "can fetch all node properties for all 'up' nodes" do
107
+ res = client.fetch
108
+ expect( res ).to be_a( Hash )
109
+ expect( res.length ).to be == manager.nodes.length
110
+ expect( res.values ).to all( be_a(Hash) )
111
+ end
125
112
 
126
- it "can fetch all properties for all nodes regardless of their status" do
127
- # Down a node
128
- manager.nodes['duir'].update( error: 'something happened' )
129
113
 
130
- res = client.fetch( {type: 'host'}, include_down: true )
114
+ it "can fetch identifiers for all 'up' nodes" do
115
+ res = client.fetch( {}, properties: nil )
116
+ expect( res ).to be_a( Hash )
117
+ expect( res.length ).to be == manager.nodes.length
118
+ expect( res.values ).to all( be_empty )
119
+ end
131
120
 
132
- expect( res ).to be_a( Hash )
133
- expect( res ).to include( 'duir' )
134
- expect( res['duir']['status'] ).to eq( 'down' )
135
- end
136
121
 
122
+ it "can fetch a subset of properties for all 'up' nodes" do
123
+ res = client.fetch( {}, properties: [:addresses, :status] )
124
+ expect( res ).to be_a( Hash )
125
+ expect( res.length ).to be == manager.nodes.length
126
+ expect( res.values ).to all( be_a(Hash) )
127
+ expect( res.values.map(&:length) ).to all( be <= 2 )
128
+ end
137
129
 
138
- it "can update the properties of managed nodes", :no_ci do
139
- res = client.update( duir: { ping: {rtt: 24} } )
140
130
 
141
- expect( res ).to be_truthy
142
- expect( manager.nodes['duir'].properties ).to include( 'ping' )
143
- expect( manager.nodes['duir'].properties['ping'] ).to include( 'rtt' )
144
- expect( manager.nodes['duir'].properties['ping']['rtt'] ).to eq( 24 )
145
- end
131
+ it "can fetch a subset of properties for all 'up' nodes matching specified criteria" do
132
+ res = client.fetch( {type: 'host'}, properties: [:addresses, :status] )
133
+ expect( res ).to be_a( Hash )
134
+ expect( res.length ).to be == manager.nodes.values.count {|n| n.type == 'host' }
135
+ expect( res.values ).to all( include('addresses', 'status') )
136
+ end
146
137
 
147
138
 
148
- it "can subscribe to all events" do
149
- sub_id = client.subscribe
150
- expect( sub_id ).to be_a( String )
151
- expect( sub_id ).to match( /^[\w\-]{16,}/ )
139
+ it "can fetch all node properties for 'up' nodes that don't match specified criteria" do
140
+ res = client.fetch( {}, properties: [:addresses, :status], exclude: {tag: 'testing'} )
152
141
 
153
- node = manager.subscriptions[ sub_id ]
154
- sub = manager.root.subscriptions[ sub_id ]
142
+ testing_nodes = manager.nodes.values.select {|n| n.tags.include?('testing') }
155
143
 
156
- expect( sub ).to be_a( Arborist::Subscription )
157
- expect( sub.criteria ).to be_empty
158
- expect( sub.event_type ).to be_nil
159
- end
144
+ expect( res ).to be_a( Hash )
145
+ expect( res ).to_not be_empty()
146
+ expect( res.length ).to eq( manager.nodes.length - testing_nodes.length )
147
+ expect( res.values ).to all( be_a(Hash) )
148
+ end
160
149
 
161
150
 
162
- it "can subscribe to a particular kind of event" do
163
- sub_id = client.subscribe( event_type: 'node.ack' )
164
- expect( sub_id ).to be_a( String )
165
- expect( sub_id ).to match( /^[\w\-]{16,}/ )
151
+ it "can fetch all properties for all nodes regardless of their status" do
152
+ # Down a node
153
+ manager.nodes['duir'].update( error: 'something happened' )
166
154
 
167
- node = manager.subscriptions[ sub_id ]
168
- sub = manager.root.subscriptions[ sub_id ]
155
+ res = client.fetch( {type: 'host'}, include_down: true )
169
156
 
170
- expect( sub ).to be_a( Arborist::Subscription )
171
- expect( sub.criteria ).to be_empty
172
- expect( sub.event_type ).to eq( 'node.ack' )
173
- end
157
+ expect( res ).to be_a( Hash )
158
+ expect( res ).to include( 'duir' )
159
+ expect( res['duir']['status'] ).to eq( 'down' )
160
+ end
174
161
 
175
162
 
176
- it "can subscribe to events for descendants of a particular node in the tree" do
177
- sub_id = client.subscribe( identifier: 'sidonie' )
178
- expect( sub_id ).to be_a( String )
179
- expect( sub_id ).to match( /^[\w\-]{16,}/ )
163
+ it "can update the properties of managed nodes", :no_ci do
164
+ res = client.update( duir: { ping: {rtt: 24} } )
180
165
 
181
- node = manager.subscriptions[ sub_id ]
182
- sub = node.subscriptions[ sub_id ]
166
+ expect( res ).to be_truthy
167
+ expect( manager.nodes['duir'].properties ).to include( 'ping' )
168
+ expect( manager.nodes['duir'].properties['ping'] ).to include( 'rtt' )
169
+ expect( manager.nodes['duir'].properties['ping']['rtt'] ).to eq( 24 )
170
+ end
183
171
 
184
- expect( node.identifier ).to eq( 'sidonie' )
185
- expect( sub ).to be_a( Arborist::Subscription )
186
- expect( sub.criteria ).to be_empty
187
- expect( sub.event_type ).to be_nil
188
- end
189
172
 
173
+ it "can subscribe to all events" do
174
+ sub_id = client.subscribe
175
+ expect( sub_id ).to be_a( String )
176
+ expect( sub_id ).to match( /^[\w\-]{16,}/ )
190
177
 
191
- it "can subscribe to events of a particular type for descendants of a particular node" do
192
- sub_id = client.subscribe( identifier: 'sidonie', event_type: 'node.delta' )
193
- expect( sub_id ).to be_a( String )
194
- expect( sub_id ).to match( /^[\w\-]{16,}/ )
178
+ node = manager.subscriptions[ sub_id ]
179
+ sub = manager.root.subscriptions[ sub_id ]
195
180
 
196
- node = manager.subscriptions[ sub_id ]
197
- sub = node.subscriptions[ sub_id ]
181
+ expect( sub ).to be_a( Arborist::Subscription )
182
+ expect( sub.criteria ).to be_empty
183
+ expect( sub.event_type ).to be_nil
184
+ end
198
185
 
199
- expect( node.identifier ).to eq( 'sidonie' )
200
- expect( sub ).to be_a( Arborist::Subscription )
201
- expect( sub.criteria ).to be_empty
202
- expect( sub.event_type ).to eq( 'node.delta' )
203
- end
204
186
 
187
+ it "can subscribe to a particular kind of event" do
188
+ sub_id = client.subscribe( event_type: 'node.ack' )
189
+ expect( sub_id ).to be_a( String )
190
+ expect( sub_id ).to match( /^[\w\-]{16,}/ )
205
191
 
206
- it "can subscribe to events matching one or more criteria" do
207
- sub_id = client.subscribe( criteria: {type: 'service'} )
208
- expect( sub_id ).to be_a( String )
209
- expect( sub_id ).to match( /^[\w\-]{16,}/ )
192
+ node = manager.subscriptions[ sub_id ]
193
+ sub = manager.root.subscriptions[ sub_id ]
210
194
 
211
- node = manager.subscriptions[ sub_id ]
212
- sub = node.subscriptions[ sub_id ]
195
+ expect( sub ).to be_a( Arborist::Subscription )
196
+ expect( sub.criteria ).to be_empty
197
+ expect( sub.event_type ).to eq( 'node.ack' )
198
+ end
213
199
 
214
- expect( node.identifier ).to eq( '_' )
215
- expect( sub ).to be_a( Arborist::Subscription )
216
- expect( sub.criteria ).to eq( 'type' => 'service' )
217
- expect( sub.event_type ).to eq( nil )
218
- end
219
200
 
201
+ it "can subscribe to events for descendants of a particular node in the tree" do
202
+ sub_id = client.subscribe( identifier: 'sidonie' )
203
+ expect( sub_id ).to be_a( String )
204
+ expect( sub_id ).to match( /^[\w\-]{16,}/ )
220
205
 
221
- it "can unsubscribe from events using a subscription ID" do
222
- sub_id = client.subscribe
223
- res = client.unsubscribe( sub_id )
224
- expect( res ).to be_truthy
225
- expect( manager.subscriptions ).to_not include( sub_id )
226
- end
206
+ node = manager.subscriptions[ sub_id ]
207
+ sub = node.subscriptions[ sub_id ]
227
208
 
209
+ expect( node.identifier ).to eq( 'sidonie' )
210
+ expect( sub ).to be_a( Arborist::Subscription )
211
+ expect( sub.criteria ).to be_empty
212
+ expect( sub.event_type ).to be_nil
213
+ end
228
214
 
229
- it "returns nil without error when unsubscribing to a non-existant subscription" do
230
- res = client.unsubscribe( 'a_subid' )
231
- expect( res ).to be_nil
232
- end
233
215
 
216
+ it "can subscribe to events of a particular type for descendants of a particular node" do
217
+ sub_id = client.subscribe( identifier: 'sidonie', event_type: 'node.delta' )
218
+ expect( sub_id ).to be_a( String )
219
+ expect( sub_id ).to match( /^[\w\-]{16,}/ )
234
220
 
235
- it "can prune nodes from the tree" do
236
- res = client.prune( 'sidonie-ssh' )
221
+ node = manager.subscriptions[ sub_id ]
222
+ sub = node.subscriptions[ sub_id ]
237
223
 
238
- expect( res ).to eq( true )
239
- expect( manager.nodes ).to_not include( 'sidonie-ssh' )
240
- end
224
+ expect( node.identifier ).to eq( 'sidonie' )
225
+ expect( sub ).to be_a( Arborist::Subscription )
226
+ expect( sub.criteria ).to be_empty
227
+ expect( sub.event_type ).to eq( 'node.delta' )
228
+ end
241
229
 
242
230
 
243
- it "returns nil without error when pruning a node that doesn't exist" do
244
- res = client.prune( 'carrigor' )
245
- expect( res ).to be_nil
246
- end
231
+ it "can subscribe to events matching one or more criteria" do
232
+ sub_id = client.subscribe( criteria: {type: 'service'} )
233
+ expect( sub_id ).to be_a( String )
234
+ expect( sub_id ).to match( /^[\w\-]{16,}/ )
247
235
 
236
+ node = manager.subscriptions[ sub_id ]
237
+ sub = node.subscriptions[ sub_id ]
248
238
 
249
- it "can graft new nodes onto the tree" do
250
- res = client.graft( 'breakfast-burrito', type: 'host' )
251
- expect( res ).to eq( 'breakfast-burrito' )
252
- expect( manager.nodes ).to include( 'breakfast-burrito' )
253
- expect( manager.nodes['breakfast-burrito'] ).to be_a( Arborist::Node::Host )
254
- expect( manager.nodes['breakfast-burrito'].parent ).to eq( '_' )
255
- end
239
+ expect( node.identifier ).to eq( '_' )
240
+ expect( sub ).to be_a( Arborist::Subscription )
241
+ expect( sub.criteria ).to eq( 'type' => 'service' )
242
+ expect( sub.event_type ).to eq( nil )
243
+ end
256
244
 
257
245
 
258
- it "can graft nodes with attributes onto the tree" do
259
- res = client.graft( 'breakfast-burrito',
260
- type: 'service',
261
- parent: 'duir',
262
- port: 9999,
263
- tags: ['yusss']
264
- )
265
- expect( res ).to eq( 'duir-breakfast-burrito' )
266
- expect( manager.nodes ).to include( 'duir-breakfast-burrito' )
267
- expect( manager.nodes['duir-breakfast-burrito'] ).to be_a( Arborist::Node::Service )
268
- expect( manager.nodes['duir-breakfast-burrito'].parent ).to eq( 'duir' )
269
- expect( manager.nodes['duir-breakfast-burrito'].port ).to eq( 9999 )
270
- expect( manager.nodes['duir-breakfast-burrito'].tags ).to include( 'yusss' )
271
- end
246
+ it "can unsubscribe from events using a subscription ID" do
247
+ sub_id = client.subscribe
248
+ res = client.unsubscribe( sub_id )
249
+ expect( res ).to be_truthy
250
+ expect( manager.subscriptions ).to_not include( sub_id )
251
+ end
252
+
253
+
254
+ it "returns nil without error when unsubscribing to a non-existant subscription" do
255
+ res = client.unsubscribe( 'a_subid' )
256
+ expect( res ).to be_nil
257
+ end
272
258
 
273
259
 
274
- it "can modify operational attributes of a node" do
275
- res = client.modify( "duir", tags: 'girlrobot' )
276
- expect( res ).to be_truthy
277
- expect( manager.nodes['duir'].tags ).to eq( ['girlrobot'] )
260
+ it "can prune nodes from the tree" do
261
+ res = client.prune( 'sidonie-ssh' )
262
+
263
+ expect( res ).to eq( true )
264
+ expect( manager.nodes ).to_not include( 'sidonie-ssh' )
265
+ end
266
+
267
+
268
+ it "returns nil without error when pruning a node that doesn't exist" do
269
+ res = client.prune( 'carrigor' )
270
+ expect( res ).to be_nil
271
+ end
272
+
273
+
274
+ it "can graft new nodes onto the tree" do
275
+ res = client.graft( 'breakfast-burrito', type: 'host' )
276
+ expect( res ).to eq( 'breakfast-burrito' )
277
+ expect( manager.nodes ).to include( 'breakfast-burrito' )
278
+ expect( manager.nodes['breakfast-burrito'] ).to be_a( Arborist::Node::Host )
279
+ expect( manager.nodes['breakfast-burrito'].parent ).to eq( '_' )
280
+ end
281
+
282
+
283
+ it "can graft nodes with attributes onto the tree" do
284
+ res = client.graft( 'breakfast-burrito',
285
+ type: 'service',
286
+ parent: 'duir',
287
+ port: 9999,
288
+ tags: ['yusss']
289
+ )
290
+ expect( res ).to eq( 'duir-breakfast-burrito' )
291
+ expect( manager.nodes ).to include( 'duir-breakfast-burrito' )
292
+ expect( manager.nodes['duir-breakfast-burrito'] ).to be_a( Arborist::Node::Service )
293
+ expect( manager.nodes['duir-breakfast-burrito'].parent ).to eq( 'duir' )
294
+ expect( manager.nodes['duir-breakfast-burrito'].port ).to eq( 9999 )
295
+ expect( manager.nodes['duir-breakfast-burrito'].tags ).to include( 'yusss' )
296
+ end
297
+
298
+
299
+ it "can modify operational attributes of a node" do
300
+ res = client.modify( "duir", tags: 'girlrobot' )
301
+ expect( res ).to be_truthy
302
+ expect( manager.nodes['duir'].tags ).to eq( ['girlrobot'] )
303
+ end
304
+
278
305
  end
279
306
 
280
307
  end
@@ -74,7 +74,7 @@ describe Arborist::Event::NodeDown do
74
74
  event = described_class.new( node )
75
75
 
76
76
  expect( event.payload ).to be_a( Hash )
77
- expect( event.payload ).to include( :status, :error, :properties, :type )
77
+ expect( event.payload ).to include( :status, :errors, :properties, :type )
78
78
  end
79
79
 
80
80
  end
@@ -133,7 +133,7 @@ describe Arborist::Manager do
133
133
  saved_router_node.instance_variable_set( :@status, 'up' )
134
134
  saved_host_node = Marshal.load( Marshal.dump(host_node) )
135
135
  saved_host_node.instance_variable_set( :@status, 'down' )
136
- saved_host_node.error = 'Stuff happened and it was not good.'
136
+ saved_host_node.errors = { '_' => 'Stuff happened and it was not good.' }
137
137
 
138
138
  expect( statefile ).to receive( :readable? ).and_return( true )
139
139
  expect( statefile ).to receive( :open ).with( 'r:binary' ).
@@ -145,7 +145,7 @@ describe Arborist::Manager do
145
145
 
146
146
  expect( manager.nodes['router'].status ).to eq( 'up' )
147
147
  expect( manager.nodes['host-a'].status ).to eq( 'down' )
148
- expect( manager.nodes['host-a'].error ).to eq( 'Stuff happened and it was not good.' )
148
+ expect( manager.nodes['host-a'].errors ).to eq({ '_' => 'Stuff happened and it was not good.' })
149
149
 
150
150
  end
151
151