arborist 0.0.1.pre20160829140603 → 0.0.1.pre20161005112841

Sign up to get free protection for your applications and to get access to all the features.
@@ -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