2017-07-09 13:41:28 -04:00
# frozen_string_literal: true
2011-06-06 14:17:44 -04:00
require " cases/helper "
2012-12-14 02:29:49 -05:00
require " models/binary "
2010-01-12 14:00:53 -05:00
require " models/developer "
2011-05-02 03:00:54 -04:00
require " models/post "
2010-06-24 07:23:43 -04:00
require " active_support/log_subscriber/test_helper "
2010-01-12 14:00:53 -05:00
2010-07-14 19:35:52 -04:00
class LogSubscriberTest < ActiveRecord :: TestCase
2010-06-24 07:23:43 -04:00
include ActiveSupport :: LogSubscriber :: TestHelper
2011-12-20 00:05:28 -05:00
include ActiveSupport :: Logger :: Severity
2015-07-17 16:23:59 -04:00
REGEXP_CLEAR = Regexp . escape ( ActiveRecord :: LogSubscriber :: CLEAR )
REGEXP_BOLD = Regexp . escape ( ActiveRecord :: LogSubscriber :: BOLD )
REGEXP_MAGENTA = Regexp . escape ( ActiveRecord :: LogSubscriber :: MAGENTA )
REGEXP_CYAN = Regexp . escape ( ActiveRecord :: LogSubscriber :: CYAN )
SQL_COLORINGS = {
SELECT : Regexp . escape ( ActiveRecord :: LogSubscriber :: BLUE ) ,
INSERT : Regexp . escape ( ActiveRecord :: LogSubscriber :: GREEN ) ,
UPDATE : Regexp . escape ( ActiveRecord :: LogSubscriber :: YELLOW ) ,
DELETE : Regexp . escape ( ActiveRecord :: LogSubscriber :: RED ) ,
LOCK : Regexp . escape ( ActiveRecord :: LogSubscriber :: WHITE ) ,
ROLLBACK : Regexp . escape ( ActiveRecord :: LogSubscriber :: RED ) ,
TRANSACTION : REGEXP_CYAN ,
OTHER : REGEXP_MAGENTA
}
2017-04-28 21:31:36 -04:00
Event = Struct . new ( :duration , :payload )
2010-01-12 14:00:53 -05:00
2013-01-07 22:28:23 -05:00
class TestDebugLogSubscriber < ActiveRecord :: LogSubscriber
attr_reader :debugs
def initialize
@debugs = [ ]
super
end
2016-10-18 18:59:21 -04:00
def debug ( progname = nil , & block )
@debugs << progname
super
2013-01-07 22:28:23 -05:00
end
end
2011-05-02 03:00:54 -04:00
fixtures :posts
2010-01-12 18:41:04 -05:00
def setup
2010-03-04 05:20:01 -05:00
@old_logger = ActiveRecord :: Base . logger
2011-12-08 04:06:15 -05:00
Developer . primary_key
2018-08-13 11:51:54 -04:00
ActiveRecord :: Base . connection . materialize_transactions
2010-01-12 14:00:53 -05:00
super
2010-06-24 07:23:43 -04:00
ActiveRecord :: LogSubscriber . attach_to ( :active_record )
2010-01-12 14:00:53 -05:00
end
def teardown
super
2010-06-24 07:23:43 -04:00
ActiveRecord :: LogSubscriber . log_subscribers . pop
2010-01-12 14:00:53 -05:00
ActiveRecord :: Base . logger = @old_logger
end
def set_logger ( logger )
2010-01-12 18:41:04 -05:00
ActiveRecord :: Base . logger = logger
2010-01-12 14:00:53 -05:00
end
2011-03-28 18:27:37 -04:00
def test_schema_statements_are_ignored
2013-01-07 22:28:23 -05:00
logger = TestDebugLogSubscriber . new
2011-03-28 18:27:37 -04:00
assert_equal 0 , logger . debugs . length
2017-05-16 21:56:41 -04:00
logger . sql ( Event . new ( 0 . 9 , sql : " hi mom! " ) )
2011-03-28 18:27:37 -04:00
assert_equal 1 , logger . debugs . length
2017-05-16 21:56:41 -04:00
logger . sql ( Event . new ( 0 . 9 , sql : " hi mom! " , name : " foo " ) )
2011-03-28 18:27:37 -04:00
assert_equal 2 , logger . debugs . length
2017-05-16 21:56:41 -04:00
logger . sql ( Event . new ( 0 . 9 , sql : " hi mom! " , name : " SCHEMA " ) )
2011-03-28 18:27:37 -04:00
assert_equal 2 , logger . debugs . length
end
2013-06-18 04:46:33 -04:00
def test_sql_statements_are_not_squeezed
logger = TestDebugLogSubscriber . new
2017-05-16 21:56:41 -04:00
logger . sql ( Event . new ( 0 . 9 , sql : " ruby rails " ) )
2013-06-18 04:46:33 -04:00
assert_match ( / ruby rails / , logger . debugs . first )
end
2010-01-12 14:00:53 -05:00
def test_basic_query_logging
2012-08-03 06:51:52 -04:00
Developer . all . load
2010-01-12 14:00:53 -05:00
wait
assert_equal 1 , @logger . logged ( :debug ) . size
2010-03-15 21:09:33 -04:00
assert_match ( / Developer Load / , @logger . logged ( :debug ) . last )
2010-02-15 10:57:45 -05:00
assert_match ( / SELECT .*?FROM .?developers.? /i , @logger . logged ( :debug ) . last )
2011-06-22 16:41:34 -04:00
end
2015-07-17 16:23:59 -04:00
def test_basic_query_logging_coloration
logger = TestDebugLogSubscriber . new
logger . colorize_logging = true
SQL_COLORINGS . each do | verb , color_regex |
2017-05-16 21:56:41 -04:00
logger . sql ( Event . new ( 0 . 9 , sql : verb . to_s ) )
2015-07-17 16:23:59 -04:00
assert_match ( / #{ REGEXP_BOLD } #{ color_regex } #{ verb } #{ REGEXP_CLEAR } /i , logger . debugs . last )
end
end
def test_basic_payload_name_logging_coloration_generic_sql
logger = TestDebugLogSubscriber . new
logger . colorize_logging = true
SQL_COLORINGS . each do | verb , _ |
2017-05-16 21:56:41 -04:00
logger . sql ( Event . new ( 0 . 9 , sql : verb . to_s ) )
assert_match ( / #{ REGEXP_BOLD } #{ REGEXP_MAGENTA } \ (0 \ .9ms \ ) #{ REGEXP_CLEAR } /i , logger . debugs . last )
2015-07-17 16:23:59 -04:00
2017-05-16 21:56:41 -04:00
logger . sql ( Event . new ( 0 . 9 , sql : verb . to_s , name : " SQL " ) )
assert_match ( / #{ REGEXP_BOLD } #{ REGEXP_MAGENTA } SQL \ (0 \ .9ms \ ) #{ REGEXP_CLEAR } /i , logger . debugs . last )
2015-07-17 16:23:59 -04:00
end
end
def test_basic_payload_name_logging_coloration_named_sql
logger = TestDebugLogSubscriber . new
logger . colorize_logging = true
SQL_COLORINGS . each do | verb , _ |
2017-05-16 21:56:41 -04:00
logger . sql ( Event . new ( 0 . 9 , sql : verb . to_s , name : " Model Load " ) )
assert_match ( / #{ REGEXP_BOLD } #{ REGEXP_CYAN } Model Load \ (0 \ .9ms \ ) #{ REGEXP_CLEAR } /i , logger . debugs . last )
2015-07-17 16:23:59 -04:00
2017-05-16 21:56:41 -04:00
logger . sql ( Event . new ( 0 . 9 , sql : verb . to_s , name : " Model Exists " ) )
assert_match ( / #{ REGEXP_BOLD } #{ REGEXP_CYAN } Model Exists \ (0 \ .9ms \ ) #{ REGEXP_CLEAR } /i , logger . debugs . last )
2015-07-17 16:23:59 -04:00
2017-05-16 21:56:41 -04:00
logger . sql ( Event . new ( 0 . 9 , sql : verb . to_s , name : " ANY SPECIFIC NAME " ) )
assert_match ( / #{ REGEXP_BOLD } #{ REGEXP_CYAN } ANY SPECIFIC NAME \ (0 \ .9ms \ ) #{ REGEXP_CLEAR } /i , logger . debugs . last )
2015-07-17 16:23:59 -04:00
end
end
def test_query_logging_coloration_with_nested_select
logger = TestDebugLogSubscriber . new
logger . colorize_logging = true
SQL_COLORINGS . slice ( :SELECT , :INSERT , :UPDATE , :DELETE ) . each do | verb , color_regex |
2017-05-16 21:56:41 -04:00
logger . sql ( Event . new ( 0 . 9 , sql : " #{ verb } WHERE ID IN SELECT " ) )
assert_match ( / #{ REGEXP_BOLD } #{ REGEXP_MAGENTA } \ (0 \ .9ms \ ) #{ REGEXP_CLEAR } #{ REGEXP_BOLD } #{ color_regex } #{ verb } WHERE ID IN SELECT #{ REGEXP_CLEAR } /i , logger . debugs . last )
2015-07-17 16:23:59 -04:00
end
end
def test_query_logging_coloration_with_multi_line_nested_select
logger = TestDebugLogSubscriber . new
logger . colorize_logging = true
SQL_COLORINGS . slice ( :SELECT , :INSERT , :UPDATE , :DELETE ) . each do | verb , color_regex |
sql = <<-EOS
#{verb}
WHERE ID IN (
SELECT ID FROM THINGS
)
EOS
2017-05-16 21:56:41 -04:00
logger . sql ( Event . new ( 0 . 9 , sql : sql ) )
assert_match ( / #{ REGEXP_BOLD } #{ REGEXP_MAGENTA } \ (0 \ .9ms \ ) #{ REGEXP_CLEAR } #{ REGEXP_BOLD } #{ color_regex } .* #{ verb } .* #{ REGEXP_CLEAR } /mi , logger . debugs . last )
2015-07-17 16:23:59 -04:00
end
end
def test_query_logging_coloration_with_lock
logger = TestDebugLogSubscriber . new
logger . colorize_logging = true
sql = <<-EOS
SELECT * FROM
( SELECT * FROM mytable FOR UPDATE ) ss
WHERE col1 = 5 ;
EOS
2017-05-16 21:56:41 -04:00
logger . sql ( Event . new ( 0 . 9 , sql : sql ) )
assert_match ( / #{ REGEXP_BOLD } #{ REGEXP_MAGENTA } \ (0 \ .9ms \ ) #{ REGEXP_CLEAR } #{ REGEXP_BOLD } #{ SQL_COLORINGS [ :LOCK ] } .*FOR UPDATE.* #{ REGEXP_CLEAR } /mi , logger . debugs . last )
2015-07-17 16:23:59 -04:00
sql = <<-EOS
LOCK TABLE films IN SHARE MODE ;
EOS
2017-05-16 21:56:41 -04:00
logger . sql ( Event . new ( 0 . 9 , sql : sql ) )
assert_match ( / #{ REGEXP_BOLD } #{ REGEXP_MAGENTA } \ (0 \ .9ms \ ) #{ REGEXP_CLEAR } #{ REGEXP_BOLD } #{ SQL_COLORINGS [ :LOCK ] } .*LOCK TABLE.* #{ REGEXP_CLEAR } /mi , logger . debugs . last )
2015-07-17 16:23:59 -04:00
end
2011-06-22 16:41:34 -04:00
def test_exists_query_logging
Developer . exists? 1
wait
assert_equal 1 , @logger . logged ( :debug ) . size
assert_match ( / Developer Exists / , @logger . logged ( :debug ) . last )
assert_match ( / SELECT .*?FROM .?developers.? /i , @logger . logged ( :debug ) . last )
2010-01-12 14:00:53 -05:00
end
2016-10-18 18:59:21 -04:00
def test_vebose_query_logs
ActiveRecord :: Base . verbose_query_logs = true
logger = TestDebugLogSubscriber . new
logger . sql ( Event . new ( 0 , sql : " hi mom! " ) )
2018-07-28 09:50:03 -04:00
assert_equal 2 , @logger . logged ( :debug ) . size
2016-10-18 18:59:21 -04:00
assert_match ( / ↳ / , @logger . logged ( :debug ) . last )
ensure
ActiveRecord :: Base . verbose_query_logs = false
end
2018-07-28 09:50:03 -04:00
def test_verbose_query_with_ignored_callstack
ActiveRecord :: Base . verbose_query_logs = true
2018-07-28 10:17:56 -04:00
2018-07-28 09:50:03 -04:00
logger = TestDebugLogSubscriber . new
2018-07-28 10:17:56 -04:00
def logger . extract_query_source_location ( * ) ; nil ; end
2018-07-28 09:50:03 -04:00
logger . sql ( Event . new ( 0 , sql : " hi mom! " ) )
assert_equal 1 , @logger . logged ( :debug ) . size
assert_no_match ( / ↳ / , @logger . logged ( :debug ) . last )
ensure
ActiveRecord :: Base . verbose_query_logs = false
end
2016-10-18 18:59:21 -04:00
def test_verbose_query_logs_disabled_by_default
logger = TestDebugLogSubscriber . new
logger . sql ( Event . new ( 0 , sql : " hi mom! " ) )
assert_no_match ( / ↳ / , @logger . logged ( :debug ) . last )
end
2010-01-12 14:00:53 -05:00
def test_cached_queries
ActiveRecord :: Base . cache do
2012-08-03 06:51:52 -04:00
Developer . all . load
Developer . all . load
2010-01-12 14:00:53 -05:00
end
wait
assert_equal 2 , @logger . logged ( :debug ) . size
2010-03-15 21:09:33 -04:00
assert_match ( / CACHE / , @logger . logged ( :debug ) . last )
2010-02-15 10:57:45 -05:00
assert_match ( / SELECT .*?FROM .?developers.? /i , @logger . logged ( :debug ) . last )
2010-01-12 14:00:53 -05:00
end
2010-07-19 16:28:51 -04:00
def test_basic_query_doesnt_log_when_level_is_not_debug
2010-07-20 16:00:12 -04:00
@logger . level = INFO
2012-08-03 06:51:52 -04:00
Developer . all . load
2010-07-19 16:28:51 -04:00
wait
assert_equal 0 , @logger . logged ( :debug ) . size
end
def test_cached_queries_doesnt_log_when_level_is_not_debug
2010-07-20 16:00:12 -04:00
@logger . level = INFO
2010-07-19 16:28:51 -04:00
ActiveRecord :: Base . cache do
2012-08-03 06:51:52 -04:00
Developer . all . load
Developer . all . load
2010-07-19 16:28:51 -04:00
end
wait
assert_equal 0 , @logger . logged ( :debug ) . size
end
2010-07-26 13:14:24 -04:00
def test_initializes_runtime
Thread . new { assert_equal 0 , ActiveRecord :: LogSubscriber . runtime } . join
end
2012-12-14 02:29:49 -05:00
2015-11-05 03:39:53 -05:00
if ActiveRecord :: Base . connection . prepared_statements
2013-11-08 10:57:51 -05:00
def test_binary_data_is_not_logged
2016-08-06 12:26:20 -04:00
Binary . create ( data : " some binary data " )
2013-11-08 10:57:51 -05:00
wait
assert_match ( / <16 bytes of binary data> / , @logger . logged ( :debug ) . join )
end
2016-05-10 15:42:07 -04:00
def test_binary_data_hash
Binary . create ( data : { a : 1 } )
wait
assert_match ( / <7 bytes of binary data> / , @logger . logged ( :debug ) . join )
end
2012-12-14 02:29:49 -05:00
end
2010-03-15 21:09:33 -04:00
end