aboutsummaryrefslogblamecommitdiffstats
path: root/activesupport/test/notifications_test.rb
blob: 9175c8f26e792d0082de571aa4a8b9d690c75f64 (plain) (tree)
1
2
3
4
5
6
7
8
9

                       
                                   
                                                




                    
                                                   

                                                                               

                                                      

     
                                                       

                                                            
 


                                        
                                     
     

                                              




                                                                                     






                                        




                                                      
 


                                                  

   
                                                  
           
                
                                    


                                                               


              
                                     
                                            

     

                                                                                              


           
                          


                                             
                                                                                     


           

              

                                            
                                                                        


                                            

                                                                                     
             

         

                

                                           
                                                                   

       

              

                                            
                                                                        
                                                  


                                              
                                                                                     


                           

              

                                            
                                                                        
     
 
                                             
                                                                                  



                                            
                                                                        

     



















                                                                

                                  




                                                                
                                                        









                                            


                                                                
 

                                                            
 
              


                                            
                                         

     

                                                    


                                                                

                      
                                                          



             








                                            

     
require 'abstract_unit'

# Allow LittleFanout to be cleaned.
class ActiveSupport::Notifications::LittleFanout
  def clear
    @listeners.clear
  end
end

class NotificationsEventTest < Test::Unit::TestCase
  def test_events_are_initialized_with_details
    event = event(:foo, Time.now, Time.now + 1, 1, random_id, :payload => :bar)
    assert_equal :foo, event.name
    assert_equal Hash[:payload => :bar], event.payload
  end

  def test_events_consumes_information_given_as_payload
    time = Time.now
    event = event(:foo, time, time + 0.01, 1, random_id, {})

    assert_equal Hash.new, event.payload
    assert_equal time, event.time
    assert_equal 1, event.result
    assert_equal 10.0, event.duration
  end

  def test_event_is_parent_based_on_time_frame
    time = Time.utc(2009, 01, 01, 0, 0, 1)

    parent    = event(:foo, Time.utc(2009), Time.utc(2009) + 100, nil, random_id, {})
    child     = event(:foo, time, time + 10, nil, random_id, {})
    not_child = event(:foo, time, time + 100, nil, random_id, {})

    assert parent.parent_of?(child)
    assert !child.parent_of?(parent)
    assert !parent.parent_of?(not_child)
    assert !not_child.parent_of?(parent)
  end

protected

  def random_id
    @random_id ||= ActiveSupport::SecureRandom.hex(10)
  end

  def event(*args)
    ActiveSupport::Notifications::Event.new(*args)
  end
end

class NotificationsMainTest < Test::Unit::TestCase
  def setup
    @events = []
    Thread.abort_on_exception = true
    ActiveSupport::Notifications.subscribe do |*args|
      @events << ActiveSupport::Notifications::Event.new(*args)
    end
  end

  def teardown
    Thread.abort_on_exception = false
    ActiveSupport::Notifications.queue.clear
  end

  def test_notifications_returns_action_result
    result = ActiveSupport::Notifications.instrument(:awesome, :payload => "notifications") do
      1 + 1
    end

    assert_equal 2, result
  end

  def test_events_are_published_to_a_listener
    ActiveSupport::Notifications.instrument(:awesome, :payload => "notifications") do
      1 + 1
    end

    sleep(0.1)

    assert_equal 1, @events.size
    assert_equal :awesome, @events.last.name
    assert_equal Hash[:payload => "notifications"], @events.last.payload
  end

  def test_nested_events_can_be_instrumented
    ActiveSupport::Notifications.instrument(:awesome, :payload => "notifications") do
      ActiveSupport::Notifications.instrument(:wot, :payload => "child") do
        1 + 1
      end

      sleep(0.1)

      assert_equal 1, @events.size
      assert_equal :wot, @events.first.name
      assert_equal Hash[:payload => "child"], @events.first.payload
    end

    sleep(0.1)

    assert_equal 2, @events.size
    assert_equal :awesome, @events.last.name
    assert_equal Hash[:payload => "notifications"], @events.last.payload
    assert_in_delta 100, @events.last.duration, 70
  end

  def test_event_is_pushed_even_if_block_fails
    ActiveSupport::Notifications.instrument(:awesome, :payload => "notifications") do
      raise "OMG"
    end rescue RuntimeError

    sleep(0.1)

    assert_equal 1, @events.size
    assert_equal :awesome, @events.last.name
    assert_equal Hash[:payload => "notifications"], @events.last.payload
  end

  def test_event_is_pushed_even_without_block
    ActiveSupport::Notifications.instrument(:awesome, :payload => "notifications")
    sleep(0.1)

    assert_equal 1, @events.size
    assert_equal :awesome, @events.last.name
    assert_equal Hash[:payload => "notifications"], @events.last.payload
  end

  def test_subscribed_in_a_transaction
    @another = []

    ActiveSupport::Notifications.subscribe("cache") do |*args|
      @another << ActiveSupport::Notifications::Event.new(*args)
    end

    ActiveSupport::Notifications.instrument(:cache){ 1 }
    ActiveSupport::Notifications.transaction do
      ActiveSupport::Notifications.instrument(:cache){ 1 }
    end
    ActiveSupport::Notifications.instrument(:cache){ 1 }

    sleep 0.1

    before, during, after = @another.map {|e| e.transaction_id }
    assert_equal before, after
    assert_not_equal before, during
  end

  def test_subscriber_with_pattern
    @another = []

    ActiveSupport::Notifications.subscribe("cache") do |*args|
      @another << ActiveSupport::Notifications::Event.new(*args)
    end

    ActiveSupport::Notifications.instrument(:cache){ 1 }

    sleep(0.1)

    assert_equal 1, @another.size
    assert_equal :cache, @another.first.name
    assert_equal 1, @another.first.result
  end

  def test_subscriber_with_pattern_as_regexp
    @another = []
    ActiveSupport::Notifications.subscribe(/cache/) do |*args|
      @another << ActiveSupport::Notifications::Event.new(*args)
    end

    ActiveSupport::Notifications.instrument(:something){ 0 }
    ActiveSupport::Notifications.instrument(:cache){ 1 }

    sleep(0.1)

    assert_equal 1, @another.size
    assert_equal :cache, @another.first.name
    assert_equal 1, @another.first.result
  end

  def test_with_several_consumers_and_several_events
    @another = []
    ActiveSupport::Notifications.subscribe do |*args|
      @another << ActiveSupport::Notifications::Event.new(*args)
    end

    1.upto(100) do |i|
      ActiveSupport::Notifications.instrument(:value){ i }
    end

    sleep 0.1

    assert_equal 100, @events.size
    assert_equal :value, @events.first.name
    assert_equal 1, @events.first.result
    assert_equal 100, @events.last.result

    assert_equal 100, @another.size
    assert_equal :value, @another.first.name
    assert_equal 1, @another.first.result
    assert_equal 100, @another.last.result
  end
end