2015-10-11 17:41:23 +08:00
require " rails_helper "
2015-02-05 13:08:52 +08:00
require_dependency " middleware/request_tracker "
describe Middleware :: RequestTracker do
2017-07-28 09:20:09 +08:00
def env ( opts = { } )
2015-02-05 13:08:52 +08:00
{
" HTTP_HOST " = > " http://test.com " ,
" REQUEST_URI " = > " /path?bla=1 " ,
" REQUEST_METHOD " = > " GET " ,
" rack.input " = > " "
} . merge ( opts )
end
context " log_request " do
2015-02-26 08:40:57 +08:00
before do
2015-02-05 13:08:52 +08:00
freeze_time Time . now
ApplicationRequest . clear_cache!
2015-02-26 08:40:57 +08:00
end
def log_tracked_view ( val )
data = Middleware :: RequestTracker . get_data ( env (
" HTTP_DISCOURSE_TRACK_VIEW " = > val
2017-10-18 09:10:12 +08:00
) , [ " 200 " , { " Content-Type " = > 'text/html' } ] , 0 . 2 )
2015-02-26 08:40:57 +08:00
Middleware :: RequestTracker . log_request ( data )
end
it " can exclude/include based on custom header " do
log_tracked_view ( " true " )
log_tracked_view ( " 1 " )
log_tracked_view ( " false " )
log_tracked_view ( " 0 " )
ApplicationRequest . write_cache!
2015-04-25 23:18:35 +08:00
expect ( ApplicationRequest . page_view_anon . first . count ) . to eq ( 2 )
2015-02-26 08:40:57 +08:00
end
it " can log requests correctly " do
2015-02-05 13:08:52 +08:00
2015-02-10 14:03:33 +08:00
data = Middleware :: RequestTracker . get_data ( env (
2015-02-06 11:39:04 +08:00
" HTTP_USER_AGENT " = > " AdsBot-Google (+http://www.google.com/adsbot.html) "
2017-10-18 09:10:12 +08:00
) , [ " 200 " , { " Content-Type " = > 'text/html' } ] , 0 . 1 )
2015-02-10 14:03:33 +08:00
Middleware :: RequestTracker . log_request ( data )
data = Middleware :: RequestTracker . get_data ( env (
2015-02-06 11:39:04 +08:00
" HTTP_DISCOURSE_TRACK_VIEW " = > " 1 "
2017-10-18 09:10:12 +08:00
) , [ " 200 " , { } ] , 0 . 1 )
2015-02-10 14:03:33 +08:00
Middleware :: RequestTracker . log_request ( data )
2015-02-05 13:08:52 +08:00
2015-07-04 05:02:57 +08:00
data = Middleware :: RequestTracker . get_data ( env (
" HTTP_USER_AGENT " = > " Mozilla/5.0 (iPhone; CPU iPhone OS 8_1 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12B410 Safari/600.1.4 "
2017-10-18 09:10:12 +08:00
) , [ " 200 " , { " Content-Type " = > 'text/html' } ] , 0 . 1 )
2015-07-04 05:02:57 +08:00
Middleware :: RequestTracker . log_request ( data )
2015-02-05 13:08:52 +08:00
ApplicationRequest . write_cache!
2015-07-04 05:02:57 +08:00
expect ( ApplicationRequest . http_total . first . count ) . to eq ( 3 )
expect ( ApplicationRequest . http_2xx . first . count ) . to eq ( 3 )
2015-02-05 13:08:52 +08:00
2015-07-04 05:02:57 +08:00
expect ( ApplicationRequest . page_view_anon . first . count ) . to eq ( 2 )
2015-04-25 23:18:35 +08:00
expect ( ApplicationRequest . page_view_crawler . first . count ) . to eq ( 1 )
2015-07-04 05:02:57 +08:00
expect ( ApplicationRequest . page_view_anon_mobile . first . count ) . to eq ( 1 )
2015-02-05 13:08:52 +08:00
end
2017-10-18 09:10:12 +08:00
end
2017-12-11 14:21:00 +08:00
context " rate limiting " do
class TestLogger
attr_accessor :warnings
def initialize
@warnings = 0
end
def warn ( * args )
@warnings += 1
end
end
before do
RateLimiter . enable
RateLimiter . clear_all_global!
@old_logger = Rails . logger
Rails . logger = TestLogger . new
end
after do
RateLimiter . disable
Rails . logger = @old_logger
end
let :middleware do
app = lambda do | env |
[ 200 , { } , [ " OK " ] ]
end
Middleware :: RequestTracker . new ( app )
end
it " does nothing by default " do
global_setting :max_requests_per_ip_per_10_seconds , 1
status , _ = middleware . call ( env )
status , _ = middleware . call ( env )
expect ( status ) . to eq ( 200 )
end
it " does warn if rate limiter is enabled " do
global_setting :max_requests_per_ip_per_10_seconds , 1
global_setting :max_requests_per_ip_mode , 'warn'
status , _ = middleware . call ( env )
status , _ = middleware . call ( env )
expect ( Rails . logger . warnings ) . to eq ( 1 )
expect ( status ) . to eq ( 200 )
end
it " does block if rate limiter is enabled " do
global_setting :max_requests_per_ip_per_10_seconds , 1
global_setting :max_requests_per_ip_mode , 'block'
env1 = env ( " REMOTE_ADDR " = > " 1.1.1.1 " )
env2 = env ( " REMOTE_ADDR " = > " 1.1.1.2 " )
status , _ = middleware . call ( env1 )
status , _ = middleware . call ( env1 )
expect ( status ) . to eq ( 429 )
status , _ = middleware . call ( env2 )
expect ( status ) . to eq ( 200 )
end
end
2017-10-18 09:10:12 +08:00
context " callbacks " do
def app ( result , sql_calls : 0 , redis_calls : 0 )
lambda do | env |
sql_calls . times do
User . where ( id : - 100 ) . first
end
redis_calls . times do
$redis . get ( " x " )
end
result
end
end
let :logger do
- > ( env , data ) do
@env = env
@data = data
end
end
before do
Middleware :: RequestTracker . register_detailed_request_logger ( logger )
end
after do
Middleware :: RequestTracker . register_detailed_request_logger ( logger )
end
it " can correctly log detailed data " do
tracker = Middleware :: RequestTracker . new ( app ( [ 200 , { } , [ ] ] , sql_calls : 2 , redis_calls : 2 ) )
tracker . call ( env )
timing = @data [ :timing ]
expect ( timing [ :total_duration ] ) . to be > 0
expect ( timing [ :sql ] [ :duration ] ) . to be > 0
expect ( timing [ :sql ] [ :calls ] ) . to eq 2
expect ( timing [ :redis ] [ :duration ] ) . to be > 0
expect ( timing [ :redis ] [ :calls ] ) . to eq 2
end
2015-02-05 13:08:52 +08:00
end
end