spec/arborist/node_spec.rb in arborist-0.3.0 vs spec/arborist/node_spec.rb in arborist-0.4.0

- old
+ new

@@ -25,10 +25,20 @@ let( :identifier ) { 'the_identifier' } let( :identifier2 ) { 'the_other_identifier' } + ### Suppress $VERBOSE warnings for the duration of a block + def with_warnings_suppressed + oldwarn = $VERBOSE + $VERBOSE = nil + yield + ensure + $VERBOSE = oldwarn + end + + shared_examples_for "a reachable node" do it "is still 'reachable'" do expect( node ).to be_reachable expect( node ).to_not be_unreachable @@ -112,15 +122,16 @@ subnode_class.parent_type( concrete_class ) expect( subnode_class.parent_types ).to include( concrete_class ) end - it "can be constructed via a factory method on instances of their parent type" do - subnode_class = Class.new( described_class ) do - def self::name; "TestSubNode"; end - def self::plugin_name; "testsub"; end + subnode_class = with_warnings_suppressed do + Class.new( described_class ) do + def self::name; "TestSubNode"; end + def self::plugin_name; "testsub"; end + end end described_class.derivatives['testsub'] = subnode_class subnode_class.parent_type( concrete_class ) parent = concrete_class.new( 'branch' ) @@ -131,22 +142,24 @@ expect( node.parent ).to eq( 'branch' ) end it "can pre-process the factory method arguments" do - subnode_class = Class.new( described_class ) do - def self::name; "TestSubNode"; end - def self::plugin_name; "testsub"; end - def args( new_args=nil ) - @args = new_args if new_args - return @args + subnode_class = with_warnings_suppressed do + Class.new( described_class ) do + def self::name; "TestSubNode"; end + def self::plugin_name; "testsub"; end + def args( new_args=nil ) + @args = new_args if new_args + return @args + end + def modify( attributes ) + attributes = stringify_keys( attributes ) + super + self.args( attributes['args'] ) + end end - def modify( attributes ) - attributes = stringify_keys( attributes ) - super - self.args( attributes['args'] ) - end end described_class.derivatives['testsub'] = subnode_class subnode_class.parent_type( concrete_class ) do |arg1, id, *args| [ id, {args: [arg1] + args} ] @@ -251,10 +264,40 @@ expect( node ).to be_up expect( node.status_last_changed ).to eq( time ) end + it "stores a history of its status" do + node.status_history_size( 3 ) + + node.update( {} ) + node.update( {} ) + node.update( { warning: 'whoopsie' } ) + node.update( {} ) + + expect( node.status_history ).to eq( ['up', 'warn', 'up'] ) + end + + + it "knows if its status is transitioning frequently" do + node.status_history_size( 10 ) + node.flap_threshold( 3 ) + + 7.times{ node.update( {} ) } + node.update( { error: 'boooM!' } ) + node.update( { warning: 'whoopsie' } ) + node.update( {} ) + + expect( node ).to be_flapping + + node.flap_threshold( 4 ) + node.update( {} ) + + expect( node ).to_not be_flapping + end + + it "groups errors from separate monitors by their key" do expect( node ).to be_unknown node.update( {error: 'ded'}, 'MonitorTron2000' ) node.update( {error: 'moar ded'}, 'MonitorTron5000' ) @@ -372,10 +415,21 @@ expect { node.handle_event( down_event ) }.to change { node.status }.from( 'up' ).to( 'quieted' ) end + + it "records its transition to quieted in its status history" do + node.status_history_size( 3 ) + down_event = Arborist::Event.create( :node_down, parent_node ) + + expect( node.status ).to eq( 'up' ) + node.handle_event( down_event ) + expect( node.status ).to eq( 'quieted' ) + + expect( node.status_history ).to eq( ['quieted'] ) + end end describe "in `down` status" do @@ -793,16 +847,20 @@ 'ttl' => 0.23 } ) old_node.last_contacted = Time.now - 28 old_node.dependencies.mark_down( 'svchost-postgres' ) + old_node.status_history << 'up' + old_node.flapping = true node.restore( old_node ) expect( node.status ).to eq( old_node.status ) expect( node.status_changed ).to eq( old_node.status_changed ) expect( node.status_last_changed ).to eq( old_node.status_last_changed ) + expect( node.status_history ).to eq( old_node.status_history ) + expect( node.flapping? ).to eq( old_node.flapping? ) expect( node.errors ).to eq( old_node.errors ) expect( node.ack ).to eq( old_node.ack ) expect( node.properties ).to include( old_node.properties ) expect( node.last_contacted ).to eq( old_node.last_contacted ) expect( node.dependencies ).to eql( old_node.dependencies ) @@ -871,10 +929,12 @@ expect( result[:status_last_changed] ).to eq( node.status_last_changed.iso8601 ) expect( result[:errors] ).to be_a( Hash ) expect( result[:errors] ).to be_empty expect( result[:dependencies] ).to be_a( Hash ) expect( result[:quieted_reasons] ).to be_a( Hash ) + expect( result[:status_history] ).to eq( node.status_history ) + expect( result[:flapping] ).to eq( node.flapping? ) expect( result[:children] ).to be_empty end @@ -1145,10 +1205,10 @@ describe "matching" do let( :concrete_class ) do - cls = Class.new( described_class ) do + Class.new( described_class ) do def self::name; "TestNode"; end end end