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.
@@ -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( manager: {checkpoint_frequency: 20_000, state_file: 'arb.tree'} )
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( manager: {heartbeat_frequency: 0} )
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 ) do |addr|
54
- expect( addr ).to eq( sockaddr_for(node) )
55
- raise errors.shift
56
- end.at_least( :once )
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 ) do |addr|
80
- expect( addr ).to eq( sockaddr_for(node) )
81
- raise errors.shift
82
- end.at_least( :once )
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 )
@@ -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 unrelated identifiers"
808
- it "can be declared for related identifiers"
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 all of a group of identifiers"
812
- it "can be declared for any of a group of identifiers"
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
- event = Arborist::Event.create( 'node_delta', host_node, status: ['up', 'down'] )
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([ subscription.id, event ])
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
- subscription = described_class.new( &published_events.method(:push) )
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.pre20160829140603
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-08-29 00:00:00.000000000 Z
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.4.8
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