Project

General

Profile

Bug #12614 » small_test_newrelic_rpm.patch

wanabe (_ wanabe), 08/14/2016 06:01 AM

View differences:

newrelic_rpm.gemspec
s.add_development_dependency 'yard'
s.add_development_dependency 'rails', '~> 3.2.13'
s.add_development_dependency 'pry', '~> 0.9.12'
s.add_development_dependency 'pry-stack_explorer'
s.add_development_dependency 'pry-byebug'
s.add_development_dependency 'hometown', '~> 0.2.5'
# Only let Guard run on newer Rubies
test/multiverse/suites/rails/action_cable_test.rb
# encoding: utf-8
# This file is distributed under New Relic's license terms.
# See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
begin
require 'action_cable'
rescue LoadError
end
if defined?(ActionCable::Channel)
require 'stringio'
require 'logger'
require 'json'
class ActionCableTest < Minitest::Test
include MultiverseHelpers
class TestConnection
attr_reader :transmissions, :identifiers, :logger
def initialize
@transmissions = []
@identifiers = []
@logger = Logger.new StringIO.new
end
def transmit data
@transmissions << data
end
def last_transmission
JSON.parse @transmissions.last
end
end
class TestChannel < ActionCable::Channel::Base
def test_action data
transmit data['content']
end
def boom data
raise StandardError.new("Boom!")
end
end
setup_and_teardown_agent do
@connection = TestConnection.new
@channel = TestChannel.new @connection, "{id: 1}"
end
def test_creates_trace
@channel.perform_action({ 'action' => :test_action, 'content' => 'hello' })
last_sample = NewRelic::Agent.instance.transaction_sampler.last_sample
assert_equal('Controller/ActionCable/ActionCableTest::TestChannel/test_action', last_sample.transaction_name)
end
def test_creates_web_transaction
@channel.perform_action({ 'action'=> :test_action, 'content' => 'hello' })
expected_metrics = {
'HttpDispatcher' => { :call_count => 1 },
'Controller/ActionCable/ActionCableTest::TestChannel/test_action' => { :call_count => 1}
}
assert_metrics_recorded expected_metrics
end
def test_action_with_error_is_noticed_by_agent
@channel.perform_action({ 'action'=> :boom }) rescue nil
error_trace = last_traced_error
assert_equal "StandardError", error_trace.exception_class_name
assert_equal "Boom!", error_trace.message
assert_equal "Controller/ActionCable/ActionCableTest::TestChannel/boom", error_trace.path
end
end
end
test/multiverse/suites/rails/action_controller_live_rum_test.rb
# encoding: utf-8
# This file is distributed under New Relic's license terms.
# See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
require './app'
if defined?(ActionController::Live)
class UndeadController < ApplicationController
RESPONSE_BODY = "<html><head></head><body>Brains!</body></html>"
def brains
render :inline => RESPONSE_BODY
end
end
class LiveController < UndeadController
include ActionController::Live
end
class ActionControllerLiveRumTest < RailsMultiverseTest
include MultiverseHelpers
JS_LOADER = "JS LOADER IN DA HOUSE"
setup_and_teardown_agent(:js_agent_loader => JS_LOADER, :beacon => "beacon", :browser_key => "key")
def test_rum_instrumentation_when_not_streaming
get '/undead/brains'
assert_includes(response.body, JS_LOADER)
end
def test_excludes_rum_instrumentation_when_streaming_with_action_controller_live
get '/live/brains'
assert_equal(LiveController::RESPONSE_BODY, response.body)
end
end
end
test/multiverse/suites/rails/activejob_test.rb
# encoding: utf-8
# This file is distributed under New Relic's license terms.
# See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
require File.expand_path(File.join(__FILE__, '..', 'app'))
require 'logger'
require 'stringio'
# ActiveJob is in Rails 4.2+, so make sure we're on an allowed version before
# we try to load. Previously just tried to require it, but that had load issues
# on Rubinius.
if Rails::VERSION::STRING >= "4.2.0"
require 'active_job'
ActiveJob::Base.queue_adapter = :inline
class MyJob < ActiveJob::Base
def perform
# Nothing needed!
end
end
class MyJobWithAlternateQueue < ActiveJob::Base
queue_as :my_jobs
def perform
end
end
class MyJobWithParams < ActiveJob::Base
def self.last_params
@@last_params
end
def perform(first, last)
@@last_params = [first, last]
end
end
class MyFailure < ActiveJob::Base
def perform
raise ArgumentError.new("No it isn't!")
end
end
class ActiveJobTest < Minitest::Test
include MultiverseHelpers
setup_and_teardown_agent do
@log = StringIO.new
ActiveJob::Base.logger = ::Logger.new(@log)
end
def after_teardown
unless passed?
puts "\nEmitting log from failure: #{self.name}"
@log.rewind
puts @log.read
end
end
ENQUEUE_PREFIX = "MessageBroker/ActiveJob::Inline/Queue/Produce/Named"
PERFORM_PREFIX = "MessageBroker/ActiveJob::Inline/Queue/Consume/Named"
PERFORM_TRANSACTION_NAME = 'OtherTransaction/ActiveJob::Inline/MyJob/execute'
PERFORM_TRANSACTION_ROLLUP = 'OtherTransaction/ActiveJob::Inline/all'
def test_record_enqueue_metrics
in_web_transaction do
MyJob.perform_later
end
assert_metrics_recorded("#{ENQUEUE_PREFIX}/default")
end
def test_record_enqueue_metrics_with_alternate_queue
in_web_transaction do
MyJobWithAlternateQueue.perform_later
end
assert_metrics_recorded("#{ENQUEUE_PREFIX}/my_jobs")
end
def test_record_perform_metrics_in_web
in_web_transaction do
MyJob.perform_later
end
assert_metrics_recorded("#{PERFORM_PREFIX}/default")
end
def test_record_perform_metrics_with_alternate_queue_in_web
in_web_transaction do
MyJobWithAlternateQueue.perform_later
end
assert_metrics_recorded("#{PERFORM_PREFIX}/my_jobs")
end
def test_doesnt_record_perform_metrics_from_background
in_background_transaction do
MyJob.perform_later
end
assert_metrics_not_recorded("#{PERFORM_PREFIX}/default")
end
def test_starts_transaction_if_there_isnt_one
MyJob.perform_later
assert_metrics_recorded([PERFORM_TRANSACTION_ROLLUP,
PERFORM_TRANSACTION_NAME])
end
def test_nests_other_transaction_if_already_running
in_background_transaction do
MyJob.perform_later
end
assert_metrics_recorded([PERFORM_TRANSACTION_ROLLUP,
PERFORM_TRANSACTION_NAME])
end
# If running tasks inline, either in a dev environment or from
# misconfiguration we shouldn't accidentally rename our web transaction
def test_doesnt_nest_transactions_if_in_web
in_web_transaction do
MyJob.perform_later
end
assert_metrics_not_recorded([PERFORM_TRANSACTION_ROLLUP,
PERFORM_TRANSACTION_NAME])
end
def test_doesnt_interfere_with_params_on_job
MyJobWithParams.perform_later("1", "2")
assert_equal(["1", "2"], MyJobWithParams.last_params)
end
def test_captures_errors
# Because we're processing inline, we get the error raised here
assert_raises ArgumentError do
MyFailure.perform_later
end
assert_metrics_recorded(["Errors/all"])
end
end
end
test/multiverse/suites/rails/bad_instrumentation_test.rb
# encoding: utf-8
# This file is distributed under New Relic's license terms.
# See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
require './app'
class BadInstrumentationController < ApplicationController
# This action is intended to simulate a chunk of instrumentation that pushes
# a traced method frame, but then never pops it. Such a situation will break
# instrumentation of that request, but should not actually cause the request
# to fail.
# https://newrelic.atlassian.net/browse/RUBY-1158
def failwhale
state = NewRelic::Agent::TransactionState.tl_get
stack = state.traced_method_stack
stack.push_frame(state, 'failwhale')
render :text => 'everything went great'
end
end
class BadInstrumentationTest < RailsMultiverseTest
include MultiverseHelpers
setup_and_teardown_agent
def test_unbalanced_tt_stack_should_not_cause_request_to_fail
rsp = get '/bad_instrumentation/failwhale'
assert_equal(200, rsp.to_i)
end
end
test/multiverse/suites/rails/error_tracing_test.rb
# encoding: utf-8
# This file is distributed under New Relic's license terms.
# See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
require 'action_controller/railtie'
require 'active_model'
require 'rails/test_help'
# https://newrelic.atlassian.net/browse/RUBY-747
require './app'
require 'fake_collector'
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'helpers', 'exceptions'))
class ErrorController < ApplicationController
include NewRelic::TestHelpers::Exceptions
newrelic_ignore :only => :ignored_action
def controller_error
raise 'this is an uncaught controller error'
end
def exception_error
raise Exception.new('wobble')
end
def view_error
render :inline => "<% raise 'this is an uncaught view error' %>"
end
def model_error
Foo.new.raise_error
end
def ignored_action
raise 'this error should not be noticed'
end
def ignored_error
raise NewRelic::TestHelpers::Exceptions::IgnoredError.new('this error should not be noticed')
end
def server_ignored_error
raise NewRelic::TestHelpers::Exceptions::ServerIgnoredError.new('this is a server ignored error')
end
def frozen_error
e = RuntimeError.new("frozen errors make a refreshing treat on a hot summer day")
e.freeze
raise e
end
def string_noticed_error
NewRelic::Agent.notice_error("trilobites died out millions of years ago")
render :text => 'trilobites'
end
def noticed_error
NewRelic::Agent.notice_error(RuntimeError.new('this error should be noticed'))
render :text => "Shoulda noticed an error"
end
def deprecated_noticed_error
newrelic_notice_error(RuntimeError.new('this error should be noticed'))
render :text => "Shoulda noticed an error"
end
def middleware_error
render :text => 'everything went great'
end
def error_with_custom_params
NewRelic::Agent.add_custom_attributes(:texture => 'chunky')
raise 'bad things'
end
if Rails::VERSION::MAJOR == 2
filter_parameter_logging(:secret)
end
end
class ErrorsWithoutSSCTest < RailsMultiverseTest
extend Multiverse::Color
include MultiverseHelpers
setup_and_teardown_agent do |collector|
setup_collector_mocks
@error_collector = agent.error_collector
end
# Let base class override this without moving where we start the agent
def setup_collector_mocks
$collector.stub('connect', {"agent_run_id" => 666 }, 200)
end
def last_error
errors.last
end
if Rails::VERSION::MAJOR >= 3
def test_error_collector_should_be_enabled
assert NewRelic::Agent.config[:agent_enabled]
assert NewRelic::Agent.config[:'error_collector.enabled']
assert @error_collector.enabled?
end
def test_should_capture_routing_error
get '/bad_route'
assert_error_reported_once('this is an uncaught routing error', nil, nil)
end
def test_should_capture_errors_raised_in_middleware_before_call
get '/error/middleware_error/before'
assert_error_reported_once('middleware error', nil, nil)
end
def test_should_capture_errors_raised_in_middleware_after_call
get '/error/middleware_error/after'
assert_error_reported_once('middleware error', nil, nil)
end
def test_should_capture_request_uri_and_params
get '/error/controller_error?eat=static'
assert_equal('/error/controller_error', attributes_for_single_error_posted("request_uri"))
expected_params = {
'request.parameters.eat' => 'static',
'httpResponseCode' => '500'
}
attributes = agent_attributes_for_single_error_posted
expected_params.each do |key, value|
assert_equal value, attributes[key]
end
end
end
def test_should_capture_error_raised_in_view
get '/error/view_error'
assert_error_reported_once('this is an uncaught view error',
'Controller/error/view_error')
end
def test_should_capture_error_raised_in_controller
get '/error/controller_error'
assert_error_reported_once('this is an uncaught controller error',
'Controller/error/controller_error')
end
def test_should_capture_error_raised_in_model
get '/error/model_error'
assert_error_reported_once('this is an uncaught model error',
'Controller/error/model_error')
end
if Rails::VERSION::MAJOR < 5
def test_should_capture_deprecated_noticed_error_in_controller
get '/error/deprecated_noticed_error'
assert_error_reported_once('this error should be noticed',
'Controller/error/deprecated_noticed_error')
end
end
def test_should_capture_noticed_error_in_controller
get '/error/noticed_error'
assert_error_reported_once('this error should be noticed',
'Controller/error/noticed_error')
end
def test_should_capture_frozen_errors
get '/error/frozen_error'
assert_error_reported_once("frozen errors make a refreshing treat on a hot summer day",
"Controller/error/frozen_error")
end
def test_should_capture_string_noticed_errors
get '/error/string_noticed_error'
assert_error_reported_once("trilobites died out millions of years ago",
"Controller/error/string_noticed_error")
end
# Important choice of controllor_error, since this goes through both the
# transaction and the rack error collector, so risks multiple counting!
def test_should_capture_multiple_errors
40.times do
get '/error/controller_error'
if !defined?(MyApp)
class MyApp < Rails::Application
initialize!
routes.draw do
get '/:controller(/:action(/:id))'
end
assert_errors_reported('this is an uncaught controller error',
NewRelic::Agent::ErrorCollector::MAX_ERROR_QUEUE_LENGTH,
40, nil, 40)
end
def test_should_capture_manually_noticed_error
NewRelic::Agent.notice_error(RuntimeError.new('this is a noticed error'))
assert_error_reported_once('this is a noticed error', nil, nil)
end
def test_should_apply_parameter_filtering
get '/error/controller_error?secret=shouldnotbecaptured&other=whatever'
attributes = agent_attributes_for_single_error_posted
assert_equal('[FILTERED]', attributes['request.parameters.secret'])
assert_equal('whatever', attributes['request.parameters.other'])
end
def test_should_apply_parameter_filtering_for_non_standard_errors
get '/error/exception_error?secret=shouldnotbecaptured&other=whatever'
attributes = agent_attributes_for_single_error_posted
assert_equal('[FILTERED]', attributes['request.parameters.secret'])
assert_equal('whatever', attributes['request.parameters.other'])
end
def test_should_not_notice_errors_from_ignored_action
get '/error/ignored_action'
assert(errors.empty?,
'Noticed an error that should have been ignored')
end
def test_should_not_notice_ignored_error_classes
get '/error/ignored_error'
assert(errors.empty?,
'Noticed an error that should have been ignored')
end
class ApplicationController < ActionController::Base; end
end
def test_should_not_fail_apdex_for_ignored_error_class_noticed
get '/error/ignored_error'
assert_metrics_recorded({
'Apdex' => { :apdex_f => 0 },
'Apdex/error/ignored_error' => { :apdex_f => 0 }
})
class ErrorController < ApplicationController
def controller_error
raise
end
end
def test_should_not_notice_filtered_errors
filter = Proc.new do |error|
!error.kind_of?(RuntimeError)
end
with_ignore_error_filter(filter) do
class ErrorsWithoutSSCTest < ActionDispatch::IntegrationTest
def test_1
100.times do
get '/error/controller_error'
end
assert(errors.empty?,
'Noticed an error that should have been ignored')
end
def test_should_notice_server_ignored_error_if_no_server_side_config
get '/error/server_ignored_error'
assert_error_reported_once('this is a server ignored error')
end
def test_captured_errors_should_include_custom_params
with_config(:'error_collector.attributes.enabled' => true) do
get '/error/error_with_custom_params'
assert_error_reported_once('bad things')
attributes = user_attributes_for_single_error_posted
assert_equal({'texture' => 'chunky'}, attributes)
end
end
def test_captured_errors_should_include_custom_params_with_legacy_setting
with_config(:'error_collector.capture_attributes' => true) do
get '/error/error_with_custom_params'
assert_error_reported_once('bad things')
attributes = user_attributes_for_single_error_posted
assert_equal({'texture' => 'chunky'}, attributes)
end
end
def test_captured_errors_should_not_include_custom_params_if_config_says_no
with_config(:'error_collector.attributes.enabled' => false) do
get '/error/error_with_custom_params'
assert_error_reported_once('bad things')
attributes = user_attributes_for_single_error_posted
assert_empty attributes
end
end
def test_captured_errors_should_not_include_custom_params_if_legacy_setting_says_no
with_config(:'error_collector.capture_attributes' => false) do
get '/error/error_with_custom_params'
assert_error_reported_once('bad things')
attributes = user_attributes_for_single_error_posted
assert_empty attributes
end
end
protected
def errors
@error_collector.error_trace_aggregator.instance_variable_get :@errors
end
def errors_with_message(message)
errors.select{|error| error.message == message}
end
def assert_errors_reported(message, queued_count, total_count=queued_count, txn_name=nil, apdex_f=1)
expected = { :call_count => total_count }
assert_metrics_recorded("Errors/all" => expected)
assert_metrics_recorded("Errors/#{txn_name}" => expected) if txn_name
unless apdex_f.nil?
assert_metrics_recorded("Apdex" => { :apdex_f => apdex_f })
end
assert_equal(queued_count,
errors_with_message(message).size,
"Wrong number of errors with message #{message.inspect} found")
end
def assert_error_reported_once(message, txn_name=nil, apdex_f=1)
assert_errors_reported(message, 1, 1, txn_name, apdex_f)
end
alias test_2 test_1
end
class ErrorsWithSSCTest < ErrorsWithoutSSCTest
def setup_collector_mocks
$collector.stub('connect', {
"agent_run_id" => 1,
"agent_config" => {
"error_collector.ignore_errors" => 'NewRelic::TestHelpers::Exceptions::IgnoredError,NewRelic::TestHelpers::Exceptions::ServerIgnoredError',
"error_collector.enabled" => true,
},
"collect_errors" => true
}, 200)
end
def test_should_notice_server_ignored_error_if_no_server_side_config
# Overrides test in base class, since doesn't apply
end
def test_should_ignore_server_ignored_errors
get '/error/server_ignored_error'
assert(errors.empty?,
'Noticed an error that should have been ignored' + errors.join(', '))
end
end
GC.disable
GC.enable
test/multiverse/suites/rails/gc_instrumentation_test.rb
# encoding: utf-8
# This file is distributed under New Relic's license terms.
# See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
require './app'
# These tests only return consistent results for REE or MRI >= 1.9.2
if NewRelic::LanguageSupport.ree? ||
(RUBY_VERSION >= '1.9.2' &&
!NewRelic::LanguageSupport.jruby? &&
!NewRelic::LanguageSupport.rubinius?)
class GcController < ApplicationController
def gc_action
begin
NewRelic::Agent::StatsEngine::GCProfiler.init
initial_gc_count = current_gc_count
Timeout.timeout(5) do
until current_gc_count > initial_gc_count
long_string = "01234567" * 100_000
long_string = nil
another_long_string = "01234567" * 100_000
another_long_string = nil
end
end
rescue Timeout::Error
puts "Timed out waiting for GC..."
end
render :text => 'ha'
end
def current_gc_count
if NewRelic::LanguageSupport.ree?
::GC.collections
elsif RUBY_VERSION >= '1.9.2'
::GC.count
end
end
end
class GCRailsInstrumentationTest < ActionController::TestCase
tests GcController
include MultiverseHelpers
setup_and_teardown_agent do
NewRelic::Agent.drop_buffered_data
NewRelic::Agent::StatsEngine::GCProfiler.reset
enable_gc_stats
@controller = GcController.new
end
def test_records_accurate_time_for_gc_activity
start = Time.now
get :gc_action
elapsed = Time.now.to_f - start.to_f
assert_in_range(elapsed, get_call_time('GC/Transaction/allWeb'))
assert_in_range(elapsed, get_call_time('GC/Transaction/allWeb', 'Controller/gc/gc_action'))
end
def test_records_transaction_param_for_gc_activity
start = Time.now.to_f
get :gc_action
elapsed = Time.now.to_f - start
trace = NewRelic::Agent.instance.transaction_sampler.last_sample
assert_in_range(elapsed, attributes_for(trace, :intrinsic)[:gc_time])
end
def assert_in_range(duration, gc_time)
assert gc_time > 0.0, "GC Time wasn't recorded!"
assert gc_time < duration, "GC Time #{gc_time} can't be more than elapsed #{duration}!"
end
def get_call_time(name, scope=nil)
NewRelic::Agent.agent.stats_engine.
get_stats(name, true, false, scope).
total_call_time
end
def enable_gc_stats
if NewRelic::LanguageSupport.ree?
GC.enable_stats
elsif RUBY_VERSION >= '1.9.2'
GC::Profiler.enable
end
end
end
end
test/multiverse/suites/rails/ignore_test.rb
# encoding: utf-8
# This file is distributed under New Relic's license terms.
# See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
# https://newrelic.atlassian.net/browse/RUBY-927
require './app'
class IgnoredController < ApplicationController
newrelic_ignore :only => :action_to_ignore
newrelic_ignore_apdex :only => :action_to_ignore_apdex
def action_to_ignore
render :text => "Ignore this"
end
def action_to_ignore_apdex
render :text => "This too"
end
end
class ParentController < ApplicationController
newrelic_ignore_apdex
def foo(*args); end
add_transaction_tracer :foo
end
class ChildController < ParentController
def bar(*args); end
add_transaction_tracer :bar
end
class IgnoredActionsTest < RailsMultiverseTest
include MultiverseHelpers
setup_and_teardown_agent(:cross_process_id => "boo",
:encoding_key => "\0",
:trusted_account_ids => [1])
def after_setup
# Make sure we've got a blank slate for doing easier metric comparisons
NewRelic::Agent.instance.drop_buffered_data
end
def test_metric__ignore
get '/ignored/action_to_ignore'
assert_metrics_recorded_exclusive([])
end
def test_metric__ignore_apdex
get '/ignored/action_to_ignore_apdex'
assert_metrics_recorded(["Controller/ignored/action_to_ignore_apdex"])
assert_metrics_not_recorded(["Apdex"])
end
def test_ignored_transaction_traces_dont_leak
get '/ignored/action_to_ignore'
get '/request_stats/stats_action'
trace = NewRelic::Agent.instance.transaction_sampler.last_sample
assert_equal 1, trace.root_node.called_nodes.count
end
def test_should_not_write_cat_response_headers_for_ignored_transactions
get '/ignored/action_to_ignore', nil, {'X-NewRelic-ID' => Base64.encode64('1#234')}
assert_nil @response.headers["X-NewRelic-App-Data"]
end
def test_apdex_ignored_if_ignored_in_parent_class
get '/child/foo'
get '/child/bar'
assert_metrics_not_recorded("Apdex")
end
end
test/multiverse/suites/rails/middleware_instrumentation_test.rb
# encoding: utf-8
# This file is distributed under New Relic's license terms.
# See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
# https://newrelic.atlassian.net/browse/RUBY-927
require './app'
if Rails::VERSION::MAJOR.to_i >= 3
class MiddlewareInstrumentationTest < RailsMultiverseTest
def test_rails_middleware_records_metrics
get('/')
assert_metrics_recorded(
['Middleware/all', 'Middleware/Rack/Rails::Rack::Logger/call']
)
end
def test_rails_routeset_is_instrumented
get('/')
assert_metrics_recorded(
'Middleware/Rack/ActionDispatch::Routing::RouteSet/call'
)
end
if Rails::VERSION::MAJOR >= 4
def test_rails_middlewares_constructed_by_name
get('/')
assert response.headers['NamedMiddleware'], "NamedMiddleware should have been called, but wasn't"
assert_metrics_recorded('Middleware/Rack/NamedMiddleware/call')
end
def test_rails_middlewares_passed_as_instances
get('/')
assert response.headers['InstanceMiddleware'], "InstanceMiddleware should have been called, but wasn't"
assert_metrics_recorded('Middleware/Rack/InstanceMiddleware/call')
end
end
end
end
test/multiverse/suites/rails/parameter_capture_test.rb
# encoding: utf-8
# This file is distributed under New Relic's license terms.
# See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
require './app'
class ParameterCaptureController < ApplicationController
def transaction
render :text => 'hi!'
end
def create
raise 'problem' if params[:raise]
render :text => 'created'
end
def sql
NewRelic::Agent.agent.sql_sampler.notice_sql(
'SELECT * FROM table',
'ActiveRecord/foos/find',
{},
100.0
)
end
def error
raise 'wut'
end
# For Rails 3+, this is configured globally in the config block for the app
if Rails::VERSION::MAJOR == 2
filter_parameter_logging(:secret)
end
end
class ParameterCaptureTest < RailsMultiverseTest
include MultiverseHelpers
setup_and_teardown_agent
def test_no_params_captured_on_errors_when_disabled
with_config(:capture_params => false) do
get '/parameter_capture/error?other=1234&secret=4567'
refute_contains_request_params(agent_attributes_for_single_error_posted)
end
end
def test_no_params_captured_on_tts_when_disabled
with_config(:capture_params => false) do
get '/parameter_capture/transaction?other=1234&secret=4567'
end
assert_equal({}, last_transaction_trace_request_params)
end
def test_uri_on_traced_errors_never_contains_query_string_without_capture_params
with_config(:capture_params => false) do
get '/parameter_capture/error?other=1234&secret=4567'
assert_equal('/parameter_capture/error', attributes_for_single_error_posted("request_uri"))
end
end
def test_uri_on_traced_errors_never_contains_query_string_with_capture_params
with_config(:capture_params => true) do
get '/parameter_capture/error?other=1234&secret=4567'
assert_equal('/parameter_capture/error', attributes_for_single_error_posted("request_uri"))
end
end
def test_referrer_on_traced_errors_never_contains_query_string_without_capture_params
with_config(:capture_params => false) do
get '/parameter_capture/error?other=1234&secret=4567', {}, { 'HTTP_REFERER' => '/foo/bar?other=123&secret=456' }
attributes = agent_attributes_for_single_error_posted
assert_equal('/foo/bar', attributes["request.headers.referer"])
end
end
def test_referrer_on_traced_errors_never_contains_query_string_even_with_capture_params
with_config(:capture_params => true) do
get '/parameter_capture/error?other=1234&secret=4567', {}, { 'HTTP_REFERER' => '/foo/bar?other=123&secret=456' }
attributes = agent_attributes_for_single_error_posted
assert_equal('/foo/bar', attributes["request.headers.referer"])
end
end
def test_controller_and_action_excluded_from_error_parameters
with_config(:capture_params => true) do
get '/parameter_capture/error'
run_harvest
refute_error_has_agent_attribute('request.parameters.controller')
refute_error_has_agent_attribute('request.parameters.action')
end
end
def test_controller_and_action_excluded_from_transaction_trace_parameters
with_config(:capture_params => true, :'transaction_tracer.transaction_threshold' => -10) do
get '/parameter_capture/transaction'
run_harvest
refute_transaction_trace_has_agent_attribute('request.parameters.controller')
refute_transaction_trace_has_agent_attribute('request.parameters.action')
end
end
def test_uri_on_tts_never_contains_query_string
with_config(:capture_params => false) do
get '/parameter_capture/transaction?other=1234&secret=4567'
end
assert_equal('/parameter_capture/transaction', last_transaction_trace.uri)
with_config(:capture_params => true) do
get '/parameter_capture/transaction?other=1234&secret=4567'
end
assert_equal('/parameter_capture/transaction', last_transaction_trace.uri)
end
def test_filters_parameters_on_traced_errors
with_config(:capture_params => true) do
get '/parameter_capture/error?other=1234&secret=4567'
captured_params = agent_attributes_for_single_error_posted
assert_equal('[FILTERED]', captured_params['request.parameters.secret'])
assert_equal('1234', captured_params['request.parameters.other'])
end
end
def test_filters_parameters_on_transaction_traces
with_config(:capture_params => true) do
get '/parameter_capture/transaction?other=1234&secret=4567'
end
captured_params = last_transaction_trace_request_params
assert_equal('[FILTERED]', captured_params['request.parameters.secret'])
assert_equal('1234', captured_params['request.parameters.other'])
end
def test_no_traced_error_params_captured_when_bails_before_rails
with_config(:capture_params => false) do
get '/middleware_error/before?other=1234&secret=4567'
refute_contains_request_params(agent_attributes_for_single_error_posted)
end
end
def test_no_transaction_trace_params_captured_when_bails_before_rails
with_config(:capture_params => false) do
get '/middleware_error/before?other=1234&secret=4567'
end
assert_equal({}, last_transaction_trace_request_params)
end
def test_no_params_captured_on_error_when_bails_before_rails_even_when_enabled
with_config(:capture_params => true) do
get '/middleware_error/before?other=1234&secret=4567'
refute_contains_request_params(agent_attributes_for_single_error_posted)
end
end
def test_no_params_captured_on_tt_when_bails_before_rails_even_when_enabled
with_config(:capture_params => true) do
get '/middleware_error/before?other=1234&secret=4567'
end
assert_equal({}, last_transaction_trace_request_params)
end
def test_uri_on_tt_should_not_contain_query_string_with_capture_params_off
with_config(:capture_params => false) do
get '/parameter_capture/transaction?param1=value1&param2=value2'
end
assert_equal('/parameter_capture/transaction', last_transaction_trace.uri)
end
def test_uri_on_tt_should_not_contain_query_string_with_capture_params_on
with_config(:capture_params => true) do
get '/parameter_capture/transaction?param1=value1&param2=value2'
end
assert_equal('/parameter_capture/transaction', last_transaction_trace.uri)
end
def test_uri_on_traced_error_should_not_contain_query_string_with_capture_params_off
with_config(:capture_params => false) do
get '/parameter_capture/error?param1=value1&param2=value2'
assert_equal('/parameter_capture/error', attributes_for_single_error_posted("request_uri"))
end
end
def test_uri_on_traced_error_should_not_contain_query_string_with_capture_params_on
with_config(:capture_params => true) do
get '/parameter_capture/error?param1=value1&param2=value2'
assert_equal('/parameter_capture/error', attributes_for_single_error_posted("request_uri"))
end
end
def test_uri_on_sql_trace_should_not_contain_query_string_with_capture_params_off
with_config(:capture_params => false) do
get '/parameter_capture/sql?param1=value1&param2=value2'
end
assert_equal('/parameter_capture/sql', last_sql_trace.url)
end
def test_uri_on_sql_trace_should_not_contain_query_string_with_capture_params_on
with_config(:capture_params => true) do
get '/parameter_capture/sql?param1=value1&param2=value2'
end
assert_equal('/parameter_capture/sql', last_sql_trace.url)
end
def test_parameters_attached_to_transaction_events_if_enabled
with_config(:'attributes.include' => 'request.parameters.*',
:'attributes.exclude' => ['request.*', 'response.*']) do
get '/parameter_capture/transaction?param1=value1&param2=value2'
end
actual = agent_attributes_for_single_event_posted_without_ignored_attributes
expected = {"request.parameters.param1" => "value1",
"request.parameters.param2" => "value2"
}
assert_equal expected, actual
end
def test_request_and_response_attributes_recorded_as_agent_attributes
get '/parameter_capture/transaction'
expected = {
"response.headers.contentType" => "#{response.content_type}; charset=#{response.charset}",
"request.headers.contentLength" => request.content_length.to_i,
"request.headers.contentType" => request.content_type,
"request.headers.host" => request.host,
"request.headers.accept" => request.accept
}
# ActionController::IntegrationTest sets this header whereas ActionDispatch::IntegrationTest
# does not. Since we test using both we need to conditionally expect content_length to be set.
unless defined?(ActionDispatch::IntegrationTest)
expected["response.headers.contentLength"] = response.content_length
end
actual = agent_attributes_for_single_event_posted_without_ignored_attributes
# request method may be a symbol or string based on Rails versions
request_method = actual.delete("request.method")
assert_equal request_method, request.request_method.to_s.upcase
assert_equal(expected, actual)
end
if Rails::VERSION::MAJOR > 2
def test_params_tts_should_be_filtered_when_serviced_by_rack_app
params = {"secret" => "shhhhhhh", "name" => "name"}
with_config(:capture_params => true) do
post '/filtering_test/', params
end
expected = {
"request.parameters.secret" => "[FILTERED]",
"request.parameters.name" => "name"
}
assert_equal expected, last_transaction_trace_request_params
end
def test_params_on_errors_should_be_filtered_when_serviced_by_rack_app
params = {"secret" => "shhhhhhh", "name" => "name"}
with_config(:capture_params => true) do
post '/filtering_test?raise=1', params
expected = {
"request.parameters.secret" => "[FILTERED]",
"request.parameters.name" => "name",
"request.parameters.raise" => "1"
}
attributes = agent_attributes_for_single_error_posted
expected.each do |key, value|
assert_equal value, attributes[key]
end
end
end
def test_parameter_filtering_should_not_mutate_argument
input = { "foo" => "bar", "secret" => "baz" }
env = { "action_dispatch.parameter_filter" => ["secret"] }
filtered = NewRelic::Agent::ParameterFiltering.apply_filters(env, input)
assert_equal({ "foo" => "bar", "secret" => "[FILTERED]" }, filtered)
assert_equal({ "foo" => "bar", "secret" => "baz" }, input)
end
end
if Rails::VERSION::MAJOR > 2 && defined?(Sinatra)
def test_params_tts_should_be_filtered_when_serviced_by_sinatra_app
with_config(:capture_params => true) do
get '/sinatra_app/', "secret" => "shhhhhhh", "name" => "name"
end
expected = {
"request.parameters.secret" => "[FILTERED]",
"request.parameters.name" => "name"
}
assert_equal expected, last_transaction_trace_request_params
end
def test_params_on_errors_should_be_filtered_when_serviced_by_sinatra_app
with_config(:capture_params => true) do
get '/sinatra_app?raise=1', "secret" => "shhhhhhh", "name" => "name"
attributes = agent_attributes_for_single_error_posted
assert_equal "[FILTERED]", attributes["request.parameters.secret"]
assert_equal "name", attributes["request.parameters.name"]
assert_equal "1", attributes["request.parameters.raise"]
end
end
def test_file_upload_params_are_replaced_with_placeholder
with_config(:capture_params => true, :'transaction_tracer.transaction_threshold' => -10) do
post '/parameter_capture', :file => Rack::Test::UploadedFile.new(__FILE__, 'text/plain')
run_harvest
result = single_transaction_trace_posted
assert_equal "#<ActionDispatch::Http::UploadedFile>", result.agent_attributes["request.parameters.file"]
end
end
end
end
test/multiverse/suites/rails/queue_time_test.rb
# encoding: utf-8
# This file is distributed under New Relic's license terms.
# See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
# https://newrelic.atlassian.net/browse/RUBY-927
require './app'
class QueueController < ApplicationController
def queued
respond_to do |format|
format.html { render :text => "<html><head></head><body>Queued</body></html>" }
end
end
def nested
nested_transaction
render :text => 'whatever'
end
def nested_transaction; end
add_transaction_tracer :nested_transaction
end
class QueueTimeTest < RailsMultiverseTest
REQUEST_START_HEADER = 'HTTP_X_REQUEST_START'
include MultiverseHelpers
setup_and_teardown_agent(:beacon => "beacon", :browser_key => "key", :js_agent_loader => "loader")
def test_should_track_queue_time_metric
t0 = freeze_time
t1 = advance_time(2)
get_path('/queue/queued', t0)
assert_metrics_recorded(
'WebFrontend/QueueTime' => {
:call_count => 1,
:total_call_time => (t1 - t0)
}
)
end
def test_should_see_queue_time_in_rum
t0 = freeze_time
t1 = advance_time(2)
get_path('/queue/queued', t0)
queue_time = extract_queue_time_from_response
assert_equal((t1 - t0) * 1000, queue_time)
end
def test_should_not_track_queue_time_for_nested_transactions
t0 = freeze_time
t1 = advance_time(2)
get_path('/queue/nested', t0)
assert_metrics_recorded(
'WebFrontend/QueueTime' => {
:call_count => 1,
:total_call_time => (t1 - t0)
}
)
end
def get_path(path, queue_start_time)
value = "t=#{(queue_start_time.to_f * 1_000_000).to_i}"
get(path, nil, REQUEST_START_HEADER => value)
end
def extract_queue_time_from_response
get_last_response_body =~ /\"queueTime\":(\d+.*)/
refute_nil $1, "Should have found queue time in #{@response.body.inspect}"
$1.to_i
end
def get_last_response_body
if Rails::VERSION::MAJOR >= 3
@response.body
else
# In Rails 2 integration tests, @response.body is always the response from
# the controller itself, not the middleware stack. Since we want the
# response from the middleware stack, we grab it off of the integration
# session.
@integration_session.body
end
end
end
test/multiverse/suites/rails/request_statistics_test.rb
# encoding: utf-8
# This file is distributed under New Relic's license terms.
# See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
# https://newrelic.atlassian.net/browse/RUBY-1096
require './app'
class RequestStatsController < ApplicationController
def stats_action
sleep 0.01
render :text => 'some stuff'
end
def cross_app_action
NewRelic::Agent::TransactionState.tl_get.is_cross_app_caller = true
render :text => 'some stuff'
end
def stats_action_with_custom_params
::NewRelic::Agent.add_custom_attributes('color' => 'blue', 1 => :bar, 'bad' => {})
render :text => 'some stuff'
end
end
class RequestStatsTest < RailsMultiverseTest
extend Multiverse::Color
include MultiverseHelpers
setup_and_teardown_agent
#
# Tests
#
def test_doesnt_send_when_disabled
with_config( :'analytics_events.enabled' => false ) do
5.times { get '/request_stats/stats_action' }
NewRelic::Agent.agent.send(:harvest_and_send_analytic_event_data)
assert_equal 0, $collector.calls_for('analytic_event_data').length
end
end
def test_request_times_should_be_reported_if_enabled
with_config( :'analytics_events.enabled' => true ) do
5.times { get '/request_stats/stats_action' }
NewRelic::Agent.agent.send(:harvest_and_send_analytic_event_data)
post = $collector.calls_for('analytic_event_data').first
refute_nil( post )
assert_kind_of Array, post.events
assert_kind_of Array, post.events.first
assert_equal 3, post.events.first.length
post.events.first.each do |event_chunk|
assert_kind_of Hash, event_chunk
end
sample = post.events.first.first
assert_equal 'Controller/request_stats/stats_action', sample['name']
assert_encoding 'utf-8', sample['name']
assert_equal 'Transaction', sample['type']
assert_kind_of Float, sample['duration']
assert_kind_of Float, sample['timestamp']
assert_nil sample['nr.guid']
assert_nil sample['nr.referringTransactionGuid']
end
end
def test_request_should_include_guid_if_cross_app
with_config( :'analytics_events.enabled' => true ) do
5.times { get '/request_stats/cross_app_action' }
NewRelic::Agent.agent.send(:harvest_and_send_analytic_event_data)
post = $collector.calls_for('analytic_event_data').first
refute_nil( post )
assert_kind_of Array, post.events
assert_kind_of Array, post.events.first
sample = post.events.first.first
assert_kind_of Hash, sample
assert_kind_of String, sample['nr.guid']
end
end
def test_request_should_include_referring_guid_if_needed
with_config(:'analytics_events.enabled' => true,
:'cross_process_id' => 'boo',
:'encoding_key' => "\0",
:'trusted_account_ids' => [1]) do
rack_env = {
'HTTP_X_NEWRELIC_ID' => Base64.encode64('1#234'),
'HTTP_X_NEWRELIC_TRANSACTION' => Base64.encode64('["8badf00d",1]')
}
get '/request_stats/cross_app_action', {}, rack_env
NewRelic::Agent.agent.send(:harvest_and_send_analytic_event_data)
post = $collector.calls_for('analytic_event_data').first
refute_nil( post )
assert_kind_of Array, post.events
assert_kind_of Array, post.events.first
sample = post.events.first.first
assert_kind_of Hash, sample
assert_kind_of String, sample['nr.guid']
assert_equal('8badf00d', sample['nr.referringTransactionGuid'])
end
end
def test_custom_params_should_be_reported_with_events_and_coerced_to_safe_types
with_config( :'analytics_events.enabled' => true ) do
5.times { get '/request_stats/stats_action_with_custom_params' }
NewRelic::Agent.agent.send(:harvest_and_send_analytic_event_data)
post = $collector.calls_for('analytic_event_data').first
refute_nil( post )
assert_kind_of Array, post.events
assert_kind_of Array, post.events.first
... This diff was truncated because it exceeds the maximum size that can be displayed.
(3-3/3)