arborist 0.0.1.pre20160829140603 → 0.0.1.pre20161005112841
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.
- checksums.yaml +5 -5
- checksums.yaml.gz.sig +1 -0
- data.tar.gz.sig +0 -0
- data/ChangeLog +99 -2
- data/Events.md +15 -0
- data/Protocol.md +3 -0
- data/Rakefile +4 -0
- data/TODO.md +2 -9
- data/lib/arborist/client.rb +46 -36
- data/lib/arborist/command/config.rb +1 -0
- data/lib/arborist/dependency.rb +3 -3
- data/lib/arborist/event.rb +3 -1
- data/lib/arborist/event/node.rb +5 -3
- data/lib/arborist/event/node_delta.rb +12 -5
- data/lib/arborist/manager.rb +8 -5
- data/lib/arborist/manager/tree_api.rb +11 -10
- data/lib/arborist/monitor.rb +2 -2
- data/lib/arborist/monitor/socket.rb +12 -8
- data/lib/arborist/node.rb +74 -17
- data/lib/arborist/observer.rb +2 -2
- data/lib/arborist/subscription.rb +22 -6
- data/spec/arborist/dependency_spec.rb +4 -3
- data/spec/arborist/event/node_delta_spec.rb +8 -0
- data/spec/arborist/event/node_spec.rb +0 -1
- data/spec/arborist/manager/tree_api_spec.rb +55 -16
- data/spec/arborist/manager_spec.rb +3 -3
- data/spec/arborist/monitor/socket_spec.rb +10 -26
- data/spec/arborist/node_spec.rb +23 -4
- data/spec/arborist/observer_spec.rb +33 -0
- data/spec/arborist/subscription_spec.rb +63 -11
- metadata +3 -3
- metadata.gz.sig +0 -0
@@ -164,7 +164,7 @@ describe Arborist::Manager do
|
|
164
164
|
|
165
165
|
|
166
166
|
it "checkpoints the state file periodically if an interval is configured" do
|
167
|
-
described_class.configure(
|
167
|
+
described_class.configure( checkpoint_frequency: 20_000, state_file: 'arb.tree' )
|
168
168
|
|
169
169
|
zloop = instance_double( ZMQ::Loop, register: nil, :verbose= => nil )
|
170
170
|
timer = instance_double( ZMQ::Timer, "checkpoint timer" )
|
@@ -203,12 +203,12 @@ describe Arborist::Manager do
|
|
203
203
|
|
204
204
|
it "errors if configured with a heartbeat of 0" do
|
205
205
|
expect {
|
206
|
-
described_class.configure(
|
206
|
+
described_class.configure( heartbeat_frequency: 0 )
|
207
207
|
}.to raise_error( Arborist::ConfigError, /positive non-zero/i )
|
208
208
|
end
|
209
209
|
|
210
210
|
|
211
|
-
it "is sent at the configured "
|
211
|
+
it "is sent at the configured interval"
|
212
212
|
|
213
213
|
end
|
214
214
|
|
@@ -48,12 +48,11 @@ describe Arborist::Monitor::Socket do
|
|
48
48
|
def make_successful_mock_socket( node )
|
49
49
|
address = Addrinfo.tcp( node.addresses.first.to_s, node.port )
|
50
50
|
socket = instance_double( Socket, "#{node.identifier} socket", remote_address: address )
|
51
|
-
errors = [ IO::EINPROGRESSWaitWritable, Errno::EISCONN ]
|
52
51
|
|
53
|
-
expect( socket ).to receive( :connect_nonblock )
|
54
|
-
|
55
|
-
|
56
|
-
|
52
|
+
expect( socket ).to receive( :connect_nonblock ).with( sockaddr_for(node) ).
|
53
|
+
and_raise( IO::EINPROGRESSWaitWritable )
|
54
|
+
allow( socket ).to receive( :getpeername ).
|
55
|
+
and_return( address.to_sockaddr )
|
57
56
|
|
58
57
|
return socket
|
59
58
|
end
|
@@ -74,12 +73,13 @@ describe Arborist::Monitor::Socket do
|
|
74
73
|
def make_wait_error_mock_socket( node, error_class, message )
|
75
74
|
address = Addrinfo.tcp( node.addresses.first.to_s, node.port )
|
76
75
|
socket = instance_double( Socket, "#{node.identifier} socket", remote_address: address )
|
77
|
-
errors = [ IO::EINPROGRESSWaitWritable, error_class.new(message) ]
|
78
76
|
|
79
|
-
expect( socket ).to receive( :connect_nonblock )
|
80
|
-
|
81
|
-
|
82
|
-
|
77
|
+
expect( socket ).to receive( :connect_nonblock ).with( sockaddr_for(node) ).
|
78
|
+
and_raise( IO::EINPROGRESSWaitWritable )
|
79
|
+
expect( socket ).to receive( :getpeername ).
|
80
|
+
and_raise( Errno::EINVAL.new("Invalid argument - getpeername(2)") )
|
81
|
+
expect( socket ).to receive( :read ).with( 1 ).
|
82
|
+
and_raise( Errno::ECONNREFUSED.new )
|
83
83
|
|
84
84
|
return socket
|
85
85
|
end
|
@@ -167,22 +167,6 @@ describe Arborist::Monitor::Socket do
|
|
167
167
|
end
|
168
168
|
|
169
169
|
|
170
|
-
it "updates nodes with an error on a 'getpeername' error" do
|
171
|
-
socket = make_wait_error_mock_socket( www_service_node, Errno::EINVAL, "getpeername(2)" )
|
172
|
-
allow( Socket ).to receive( :new ).and_return( socket )
|
173
|
-
allow( IO ).to receive( :select ).
|
174
|
-
with( nil, [socket], nil, kind_of(Numeric) ).
|
175
|
-
and_return( [nil, [socket], nil] )
|
176
|
-
allow( socket ).to receive( :close )
|
177
|
-
|
178
|
-
result = described_class.run( 'test-www' => www_service_node.fetch_values )
|
179
|
-
|
180
|
-
expect( result ).to be_a( Hash )
|
181
|
-
expect( result ).to include( 'test-www' )
|
182
|
-
expect( result['test-www'] ).to include( error: 'Invalid argument - getpeername(2)' )
|
183
|
-
end
|
184
|
-
|
185
|
-
|
186
170
|
it "can be instantiated to run with a different timeout" do
|
187
171
|
mon = described_class.new.with_timeout( 30 )
|
188
172
|
expect( mon.timeout ).to eq( 30 )
|
data/spec/arborist/node_spec.rb
CHANGED
@@ -205,6 +205,13 @@ describe Arborist::Node do
|
|
205
205
|
expect( node ).to be_disabled
|
206
206
|
end
|
207
207
|
|
208
|
+
it "transitions to `disabled` from `unknown` status if it's updated with an `ack` property" do
|
209
|
+
node.status = 'unknown'
|
210
|
+
node.update( ack: {message: "Maintenance", sender: 'mahlon'} )
|
211
|
+
|
212
|
+
expect( node ).to be_disabled
|
213
|
+
end
|
214
|
+
|
208
215
|
it "stays `disabled` if it gets an error" do
|
209
216
|
node.status = 'up'
|
210
217
|
node.update( ack: {message: "Maintenance", sender: 'mahlon'} )
|
@@ -804,12 +811,24 @@ describe Arborist::Node do
|
|
804
811
|
end
|
805
812
|
|
806
813
|
|
807
|
-
it "can be declared for
|
808
|
-
|
814
|
+
it "can be declared for all of a group of identifiers" do
|
815
|
+
node.depends_on( 'iscsi', 'memcached', 'ldap', on: 'dmz' )
|
816
|
+
expect( node ).to have_dependencies
|
817
|
+
expect( node.dependencies.behavior ).to eq( :all )
|
818
|
+
expect( node.dependencies.identifiers ).to include( 'dmz-iscsi', 'dmz-memcached', 'dmz-ldap' )
|
819
|
+
end
|
809
820
|
|
810
821
|
|
811
|
-
it "can be declared for
|
812
|
-
|
822
|
+
it "can be declared for any of a group of identifiers" do
|
823
|
+
node.depends_on( node.any_of('memcached', on: %w[blade1 blade2 blade3]) )
|
824
|
+
expect( node ).to have_dependencies
|
825
|
+
expect( node.dependencies.behavior ).to eq( :all )
|
826
|
+
expect( node.dependencies.subdeps.size ).to eq( 1 )
|
827
|
+
subdep = node.dependencies.subdeps.first
|
828
|
+
expect( subdep.behavior ).to eq( :any )
|
829
|
+
expect( subdep.identifiers ).
|
830
|
+
to include( 'blade1-memcached', 'blade2-memcached', 'blade3-memcached' )
|
831
|
+
end
|
813
832
|
|
814
833
|
|
815
834
|
it "cause the node to be quieted when the dependent node goes down" do
|
@@ -43,6 +43,39 @@ describe Arborist::Observer do
|
|
43
43
|
end
|
44
44
|
|
45
45
|
|
46
|
+
it "can specify criteria for events" do
|
47
|
+
observer = described_class.new( "testing observer" ) do
|
48
|
+
subscribe to: 'node.up', where: { type: 'host' }
|
49
|
+
end
|
50
|
+
|
51
|
+
expect( observer.subscriptions ).to be_an( Array )
|
52
|
+
expect( observer.subscriptions ).to include( a_hash_including(criteria: {type: 'host'}) )
|
53
|
+
expect( observer.subscriptions.length ).to eq( 1 )
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
it "can specify negative criteria for events" do
|
58
|
+
observer = described_class.new( "testing observer" ) do
|
59
|
+
subscribe to: 'node.up', exclude: { type: 'host' }
|
60
|
+
end
|
61
|
+
|
62
|
+
expect( observer.subscriptions ).to be_an( Array )
|
63
|
+
expect( observer.subscriptions ).to include( a_hash_including(exclude: {type: 'host'}) )
|
64
|
+
expect( observer.subscriptions.length ).to eq( 1 )
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
it "can specify a subscription node other than the root" do
|
69
|
+
observer = described_class.new( "testing observer" ) do
|
70
|
+
subscribe to: 'node.down', on: 'dmz-gateway'
|
71
|
+
end
|
72
|
+
|
73
|
+
expect( observer.subscriptions ).to be_an( Array )
|
74
|
+
expect( observer.subscriptions ).to include( a_hash_including(identifier: 'dmz-gateway') )
|
75
|
+
expect( observer.subscriptions.length ).to eq( 1 )
|
76
|
+
end
|
77
|
+
|
78
|
+
|
46
79
|
it "can specify an action to run when a subscribed event is received" do
|
47
80
|
observer = described_class.new( "testing observer" ) do
|
48
81
|
action do |event|
|
@@ -18,10 +18,6 @@ describe Arborist::Subscription do
|
|
18
18
|
let( :service_node ) do
|
19
19
|
host_node.service( 'ssh' )
|
20
20
|
end
|
21
|
-
let( :published_events ) {[]}
|
22
|
-
let( :subscription ) do
|
23
|
-
described_class.new( 'node.delta', type: 'host', &published_events.method(:push) )
|
24
|
-
end
|
25
21
|
|
26
22
|
|
27
23
|
it "raises an error if created without a callback block" do
|
@@ -32,34 +28,47 @@ describe Arborist::Subscription do
|
|
32
28
|
|
33
29
|
|
34
30
|
it "generates a unique ID when it's created" do
|
31
|
+
subscription = described_class.new( 'node.delta', type: 'host' ) do |*|
|
32
|
+
# no-op
|
33
|
+
end
|
35
34
|
expect( subscription.id ).to match( /^\S{16,}$/ )
|
36
35
|
end
|
37
36
|
|
38
37
|
|
39
38
|
it "publishes events which are of the desired type and have matching criteria" do
|
40
|
-
|
39
|
+
published_events = []
|
40
|
+
subscription = described_class.new( 'node.delta', type: 'host' ) do |_, event|
|
41
|
+
published_events << event
|
42
|
+
end
|
43
|
+
event = Arborist::Event.create( 'node_delta', host_node, 'status' => ['up', 'down'] )
|
41
44
|
|
42
45
|
subscription.on_events( event )
|
43
46
|
|
44
|
-
expect( published_events ).to eq([
|
47
|
+
expect( published_events ).to eq([ event ])
|
45
48
|
end
|
46
49
|
|
47
50
|
|
48
51
|
it "publishes events which are of any type if the specified type is `nil`" do
|
49
|
-
|
52
|
+
published_events = []
|
53
|
+
subscription = described_class.new( nil, type: 'host' ) do |_, event|
|
54
|
+
published_events << event
|
55
|
+
end
|
56
|
+
|
50
57
|
event1 = Arborist::Event.create( 'node_delta', host_node, status: ['up', 'down'] )
|
51
58
|
event2 = Arborist::Event.create( 'node_update', host_node )
|
52
59
|
|
53
60
|
subscription.on_events( event1, event2 )
|
54
61
|
|
55
|
-
expect( published_events ).to eq([
|
56
|
-
subscription.id, event1,
|
57
|
-
subscription.id, event2
|
58
|
-
])
|
62
|
+
expect( published_events ).to eq([ event1, event2 ])
|
59
63
|
end
|
60
64
|
|
61
65
|
|
62
66
|
it "doesn't publish events which are of the desired type but don't have matching criteria" do
|
67
|
+
published_events = []
|
68
|
+
subscription = described_class.new( 'node.delta', type: 'host' ) do |_, event|
|
69
|
+
published_events << event
|
70
|
+
end
|
71
|
+
|
63
72
|
event = Arborist::Event.create( 'node_delta', service_node, status: ['up', 'down'] )
|
64
73
|
|
65
74
|
subscription.on_events( event )
|
@@ -69,6 +78,11 @@ describe Arborist::Subscription do
|
|
69
78
|
|
70
79
|
|
71
80
|
it "doesn't publish events which have matching criteria but aren't of the desired type" do
|
81
|
+
published_events = []
|
82
|
+
subscription = described_class.new( 'node.delta', type: 'host' ) do |_, event|
|
83
|
+
published_events << event
|
84
|
+
end
|
85
|
+
|
72
86
|
event = Arborist::Event.create( 'node_update', host_node )
|
73
87
|
|
74
88
|
subscription.on_events( event )
|
@@ -76,5 +90,43 @@ describe Arborist::Subscription do
|
|
76
90
|
expect( published_events ).to be_empty
|
77
91
|
end
|
78
92
|
|
93
|
+
|
94
|
+
it "doesn't publish events which have matching negative criteria" do
|
95
|
+
published_events = []
|
96
|
+
subscription = described_class.new( 'node.update', type: 'host' ) do |_, event|
|
97
|
+
Loggability[ Arborist ].warn "Published event: %p" % [ event ]
|
98
|
+
published_events << event
|
99
|
+
end
|
100
|
+
subscription.exclude( 'status' => 'down' )
|
101
|
+
|
102
|
+
events = host_node.update( error: "Angry bees." )
|
103
|
+
subscription.on_events( events )
|
104
|
+
|
105
|
+
events = host_node.update( error: nil )
|
106
|
+
subscription.on_events( events )
|
107
|
+
|
108
|
+
expect( published_events ).to all( be_a Arborist::Event::NodeUpdate )
|
109
|
+
expect( published_events.length ).to eq( 1 )
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
it "doesn't publish delta events which have matching negative criteria" do
|
114
|
+
published_events = []
|
115
|
+
subscription = described_class.new( 'node.delta', type: 'host' ) do |_, event|
|
116
|
+
published_events << event
|
117
|
+
end
|
118
|
+
subscription.exclude( 'delta' => {'status' => ['unknown', 'down']} )
|
119
|
+
|
120
|
+
events = host_node.update( error: "Angry badgers." )
|
121
|
+
subscription.on_events( events )
|
122
|
+
|
123
|
+
events = host_node.update( error: nil )
|
124
|
+
subscription.on_events( events )
|
125
|
+
|
126
|
+
expect( published_events.length ).to eq( 1 )
|
127
|
+
expect( published_events.first ).to be_a( Arborist::Event::NodeDelta )
|
128
|
+
expect( published_events.first.payload['status'] ).to eq( ['down', 'up'] )
|
129
|
+
end
|
130
|
+
|
79
131
|
end
|
80
132
|
|
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.
|
4
|
+
version: 0.0.1.pre20161005112841
|
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-
|
39
|
+
date: 2016-10-05 00:00:00.000000000 Z
|
40
40
|
dependencies:
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: schedulability
|
@@ -413,7 +413,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
413
413
|
version: 1.3.1
|
414
414
|
requirements: []
|
415
415
|
rubyforge_project:
|
416
|
-
rubygems_version: 2.
|
416
|
+
rubygems_version: 2.5.1
|
417
417
|
signing_key:
|
418
418
|
specification_version: 4
|
419
419
|
summary: Arborist is a monitoring toolkit that follows the UNIX philosophy of small
|
metadata.gz.sig
ADDED
Binary file
|