newrelic_rpm 6.8.0.360 → 9.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +14 -1
- data/.rubocop.yml +1845 -0
- data/.rubocop_todo.yml +61 -0
- data/.simplecov +16 -0
- data/.snyk +11 -0
- data/.yardopts +1 -0
- data/Brewfile +13 -0
- data/CHANGELOG.md +4029 -2514
- data/CONTRIBUTING.md +132 -19
- data/DOCKER.md +167 -0
- data/Dockerfile +10 -0
- data/Gemfile +5 -2
- data/Guardfile +21 -8
- data/LICENSE +202 -38
- data/README.md +86 -87
- data/Rakefile +32 -32
- data/THIRD_PARTY_NOTICES.md +28 -0
- data/Thorfile +5 -0
- data/bin/newrelic +4 -2
- data/bin/newrelic_cmd +2 -0
- data/bin/nrdebug +86 -63
- data/config.dot +5 -5
- data/docker-compose.yml +107 -0
- data/init.rb +5 -7
- data/install.rb +3 -3
- data/lefthook.yml +9 -0
- data/lib/new_relic/agent/adaptive_sampler.rb +14 -10
- data/lib/new_relic/agent/agent.rb +114 -942
- data/lib/new_relic/agent/agent_helpers/connect.rb +222 -0
- data/lib/new_relic/agent/agent_helpers/harvest.rb +153 -0
- data/lib/new_relic/agent/agent_helpers/shutdown.rb +72 -0
- data/lib/new_relic/agent/agent_helpers/special_startup.rb +74 -0
- data/lib/new_relic/agent/agent_helpers/start_worker_thread.rb +175 -0
- data/lib/new_relic/agent/agent_helpers/startup.rb +202 -0
- data/lib/new_relic/agent/agent_helpers/transmit.rb +76 -0
- data/lib/new_relic/agent/agent_logger.rb +28 -24
- data/lib/new_relic/agent/attribute_filter.rb +66 -49
- data/lib/new_relic/agent/attribute_processing.rb +10 -10
- data/lib/new_relic/agent/attributes.rb +9 -8
- data/lib/new_relic/agent/audit_logger.rb +22 -7
- data/lib/new_relic/agent/autostart.rb +22 -21
- data/lib/new_relic/agent/chained_call.rb +2 -2
- data/lib/new_relic/agent/commands/agent_command.rb +5 -5
- data/lib/new_relic/agent/commands/agent_command_router.rb +16 -14
- data/lib/new_relic/agent/commands/thread_profiler_session.rb +17 -15
- data/lib/new_relic/agent/configuration/default_source.rb +1444 -1167
- data/lib/new_relic/agent/configuration/dotted_hash.rb +7 -6
- data/lib/new_relic/agent/configuration/environment_source.rb +14 -12
- data/lib/new_relic/agent/configuration/event_harvest_config.rb +41 -18
- data/lib/new_relic/agent/configuration/high_security_source.rb +12 -13
- data/lib/new_relic/agent/configuration/manager.rb +96 -70
- data/lib/new_relic/agent/configuration/manual_source.rb +2 -2
- data/lib/new_relic/agent/configuration/mask_defaults.rb +4 -4
- data/lib/new_relic/agent/configuration/security_policy_source.rb +93 -96
- data/lib/new_relic/agent/configuration/server_source.rb +44 -42
- data/lib/new_relic/agent/configuration/yaml_source.rb +36 -12
- data/lib/new_relic/agent/configuration.rb +2 -2
- data/lib/new_relic/agent/connect/request_builder.rb +19 -19
- data/lib/new_relic/agent/connect/response_handler.rb +6 -9
- data/lib/new_relic/agent/custom_event_aggregator.rb +16 -16
- data/lib/new_relic/agent/database/explain_plan_helpers.rb +6 -7
- data/lib/new_relic/agent/database/obfuscation_helpers.rb +18 -17
- data/lib/new_relic/agent/database/obfuscator.rb +5 -5
- data/lib/new_relic/agent/database/postgres_explain_obfuscator.rb +4 -4
- data/lib/new_relic/agent/database.rb +47 -56
- data/lib/new_relic/agent/database_adapter.rb +35 -0
- data/lib/new_relic/agent/datastores/metric_helper.rb +22 -23
- data/lib/new_relic/agent/datastores/mongo/event_formatter.rb +8 -7
- data/lib/new_relic/agent/datastores/mongo/metric_translator.rb +18 -22
- data/lib/new_relic/agent/datastores/mongo.rb +7 -12
- data/lib/new_relic/agent/datastores/nosql_obfuscator.rb +41 -0
- data/lib/new_relic/agent/datastores/redis.rb +10 -16
- data/lib/new_relic/agent/datastores.rb +14 -16
- data/lib/new_relic/agent/deprecator.rb +2 -2
- data/lib/new_relic/agent/{cross_app_payload.rb → distributed_tracing/cross_app_payload.rb} +13 -12
- data/lib/new_relic/agent/{cross_app_tracing.rb → distributed_tracing/cross_app_tracing.rb} +90 -70
- data/lib/new_relic/agent/distributed_tracing/distributed_trace_attributes.rb +84 -0
- data/lib/new_relic/agent/distributed_tracing/distributed_trace_metrics.rb +75 -0
- data/lib/new_relic/agent/distributed_tracing/distributed_trace_payload.rb +163 -0
- data/lib/new_relic/agent/distributed_tracing/distributed_trace_transport_type.rb +38 -0
- data/lib/new_relic/agent/distributed_tracing/trace_context.rb +245 -0
- data/lib/new_relic/agent/distributed_tracing/trace_context_payload.rb +127 -0
- data/lib/new_relic/agent/distributed_tracing.rb +113 -32
- data/lib/new_relic/agent/encoding_normalizer.rb +5 -3
- data/lib/new_relic/agent/error_collector.rb +129 -65
- data/lib/new_relic/agent/error_event_aggregator.rb +9 -8
- data/lib/new_relic/agent/error_filter.rb +174 -0
- data/lib/new_relic/agent/error_trace_aggregator.rb +10 -8
- data/lib/new_relic/agent/event_aggregator.rb +23 -22
- data/lib/new_relic/agent/event_buffer.rb +8 -9
- data/lib/new_relic/agent/event_listener.rb +2 -3
- data/lib/new_relic/agent/event_loop.rb +28 -26
- data/lib/new_relic/agent/external.rb +19 -52
- data/lib/new_relic/agent/guid_generator.rb +14 -12
- data/lib/new_relic/agent/harvester.rb +6 -9
- data/lib/new_relic/agent/heap.rb +9 -10
- data/lib/new_relic/agent/hostname.rb +22 -9
- data/lib/new_relic/agent/http_clients/abstract.rb +69 -0
- data/lib/new_relic/agent/http_clients/curb_wrappers.rb +30 -26
- data/lib/new_relic/agent/http_clients/excon_wrappers.rb +37 -21
- data/lib/new_relic/agent/http_clients/http_rb_wrappers.rb +22 -23
- data/lib/new_relic/agent/http_clients/httpclient_wrappers.rb +18 -17
- data/lib/new_relic/agent/http_clients/net_http_wrappers.rb +28 -8
- data/lib/new_relic/agent/http_clients/typhoeus_wrappers.rb +17 -17
- data/lib/new_relic/agent/http_clients/uri_util.rb +13 -14
- data/lib/new_relic/agent/instrumentation/action_cable_subscriber.rb +10 -25
- data/lib/new_relic/agent/instrumentation/action_controller_other_subscriber.rb +42 -0
- data/lib/new_relic/agent/instrumentation/action_controller_subscriber.rb +46 -34
- data/lib/new_relic/agent/instrumentation/action_dispatch.rb +31 -0
- data/lib/new_relic/agent/instrumentation/action_dispatch_subscriber.rb +64 -0
- data/lib/new_relic/agent/instrumentation/action_mailbox.rb +30 -0
- data/lib/new_relic/agent/instrumentation/action_mailbox_subscriber.rb +33 -0
- data/lib/new_relic/agent/instrumentation/action_mailer.rb +30 -0
- data/lib/new_relic/agent/instrumentation/action_mailer_subscriber.rb +85 -0
- data/lib/new_relic/agent/instrumentation/action_view_subscriber.rb +28 -21
- data/lib/new_relic/agent/instrumentation/active_job.rb +34 -14
- data/lib/new_relic/agent/instrumentation/active_job_subscriber.rb +41 -0
- data/lib/new_relic/agent/instrumentation/active_merchant.rb +21 -7
- data/lib/new_relic/agent/instrumentation/active_record.rb +97 -47
- data/lib/new_relic/agent/instrumentation/active_record_helper.rb +97 -73
- data/lib/new_relic/agent/instrumentation/active_record_notifications.rb +53 -66
- data/lib/new_relic/agent/instrumentation/active_record_prepend.rb +36 -12
- data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +37 -24
- data/lib/new_relic/agent/instrumentation/active_storage.rb +8 -4
- data/lib/new_relic/agent/instrumentation/active_storage_subscriber.rb +9 -30
- data/lib/new_relic/agent/instrumentation/active_support.rb +27 -0
- data/lib/new_relic/agent/instrumentation/active_support_logger/chain.rb +23 -0
- data/lib/new_relic/agent/instrumentation/active_support_logger/instrumentation.rb +20 -0
- data/lib/new_relic/agent/instrumentation/active_support_logger/prepend.rb +12 -0
- data/lib/new_relic/agent/instrumentation/active_support_logger.rb +24 -0
- data/lib/new_relic/agent/instrumentation/active_support_subscriber.rb +41 -0
- data/lib/new_relic/agent/instrumentation/bunny/chain.rb +45 -0
- data/lib/new_relic/agent/instrumentation/bunny/instrumentation.rb +150 -0
- data/lib/new_relic/agent/instrumentation/bunny/prepend.rb +35 -0
- data/lib/new_relic/agent/instrumentation/bunny.rb +14 -138
- data/lib/new_relic/agent/instrumentation/concurrent_ruby/chain.rb +36 -0
- data/lib/new_relic/agent/instrumentation/concurrent_ruby/instrumentation.rb +21 -0
- data/lib/new_relic/agent/instrumentation/concurrent_ruby/prepend.rb +27 -0
- data/lib/new_relic/agent/instrumentation/concurrent_ruby.rb +31 -0
- data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +75 -63
- data/lib/new_relic/agent/instrumentation/curb/chain.rb +91 -0
- data/lib/new_relic/agent/instrumentation/curb/instrumentation.rb +221 -0
- data/lib/new_relic/agent/instrumentation/curb/prepend.rb +61 -0
- data/lib/new_relic/agent/instrumentation/curb.rb +16 -201
- data/lib/new_relic/agent/instrumentation/custom_events.rb +12 -0
- data/lib/new_relic/agent/instrumentation/custom_events_subscriber.rb +38 -0
- data/lib/new_relic/agent/instrumentation/delayed_job/chain.rb +36 -0
- data/lib/new_relic/agent/instrumentation/delayed_job/instrumentation.rb +48 -0
- data/lib/new_relic/agent/instrumentation/delayed_job/prepend.rb +33 -0
- data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +31 -52
- data/lib/new_relic/agent/instrumentation/elasticsearch/chain.rb +29 -0
- data/lib/new_relic/agent/instrumentation/elasticsearch/instrumentation.rb +67 -0
- data/lib/new_relic/agent/instrumentation/elasticsearch/prepend.rb +13 -0
- data/lib/new_relic/agent/instrumentation/elasticsearch.rb +31 -0
- data/lib/new_relic/agent/instrumentation/excon/middleware.rb +10 -8
- data/lib/new_relic/agent/instrumentation/excon.rb +29 -31
- data/lib/new_relic/agent/instrumentation/fiber/chain.rb +20 -0
- data/lib/new_relic/agent/instrumentation/fiber/instrumentation.rb +24 -0
- data/lib/new_relic/agent/instrumentation/fiber/prepend.rb +18 -0
- data/lib/new_relic/agent/instrumentation/fiber.rb +25 -0
- data/lib/new_relic/agent/instrumentation/grape/chain.rb +24 -0
- data/lib/new_relic/agent/instrumentation/grape/instrumentation.rb +100 -0
- data/lib/new_relic/agent/instrumentation/grape/prepend.rb +17 -0
- data/lib/new_relic/agent/instrumentation/grape.rb +17 -123
- data/lib/new_relic/agent/instrumentation/grpc/client/chain.rb +97 -0
- data/lib/new_relic/agent/instrumentation/grpc/client/instrumentation.rb +90 -0
- data/lib/new_relic/agent/instrumentation/grpc/client/prepend.rb +111 -0
- data/lib/new_relic/agent/instrumentation/grpc/client/request_wrapper.rb +30 -0
- data/lib/new_relic/agent/instrumentation/grpc/helper.rb +32 -0
- data/lib/new_relic/agent/instrumentation/grpc/server/chain.rb +69 -0
- data/lib/new_relic/agent/instrumentation/grpc/server/instrumentation.rb +134 -0
- data/lib/new_relic/agent/instrumentation/grpc/server/rpc_desc_prepend.rb +35 -0
- data/lib/new_relic/agent/instrumentation/grpc/server/rpc_server_prepend.rb +26 -0
- data/lib/new_relic/agent/instrumentation/grpc_client.rb +23 -0
- data/lib/new_relic/agent/instrumentation/grpc_server.rb +25 -0
- data/lib/new_relic/agent/instrumentation/httpclient/chain.rb +24 -0
- data/lib/new_relic/agent/instrumentation/httpclient/instrumentation.rb +37 -0
- data/lib/new_relic/agent/instrumentation/httpclient/prepend.rb +15 -0
- data/lib/new_relic/agent/instrumentation/httpclient.rb +12 -32
- data/lib/new_relic/agent/instrumentation/httprb/chain.rb +22 -0
- data/lib/new_relic/agent/instrumentation/httprb/instrumentation.rb +30 -0
- data/lib/new_relic/agent/instrumentation/httprb/prepend.rb +15 -0
- data/lib/new_relic/agent/instrumentation/httprb.rb +29 -0
- data/lib/new_relic/agent/instrumentation/ignore_actions.rb +6 -7
- data/lib/new_relic/agent/instrumentation/logger/chain.rb +21 -0
- data/lib/new_relic/agent/instrumentation/logger/instrumentation.rb +66 -0
- data/lib/new_relic/agent/instrumentation/logger/prepend.rb +13 -0
- data/lib/new_relic/agent/instrumentation/logger.rb +26 -0
- data/lib/new_relic/agent/instrumentation/memcache/chain.rb +15 -0
- data/lib/new_relic/agent/instrumentation/memcache/dalli.rb +60 -125
- data/lib/new_relic/agent/instrumentation/memcache/helper.rb +59 -0
- data/lib/new_relic/agent/instrumentation/memcache/instrumentation.rb +90 -0
- data/lib/new_relic/agent/instrumentation/memcache/prepend.rb +103 -0
- data/lib/new_relic/agent/instrumentation/memcache.rb +57 -71
- data/lib/new_relic/agent/instrumentation/middleware_proxy.rb +16 -15
- data/lib/new_relic/agent/instrumentation/middleware_tracing.rb +11 -11
- data/lib/new_relic/agent/instrumentation/mongo.rb +7 -132
- data/lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb +53 -17
- data/lib/new_relic/agent/instrumentation/net_http/chain.rb +24 -0
- data/lib/new_relic/agent/instrumentation/net_http/instrumentation.rb +40 -0
- data/lib/new_relic/agent/instrumentation/net_http/prepend.rb +21 -0
- data/lib/new_relic/agent/instrumentation/net_http.rb +44 -0
- data/lib/new_relic/agent/instrumentation/notifications_subscriber.rb +75 -9
- data/lib/new_relic/agent/instrumentation/padrino/chain.rb +38 -0
- data/lib/new_relic/agent/instrumentation/padrino/instrumentation.rb +28 -0
- data/lib/new_relic/agent/instrumentation/padrino/prepend.rb +20 -0
- data/lib/new_relic/agent/instrumentation/padrino.rb +22 -58
- data/lib/new_relic/agent/instrumentation/passenger_instrumentation.rb +7 -7
- data/lib/new_relic/agent/instrumentation/queue_time.rb +9 -10
- data/lib/new_relic/agent/instrumentation/rack/chain.rb +66 -0
- data/lib/new_relic/agent/instrumentation/rack/helpers.rb +33 -0
- data/lib/new_relic/agent/instrumentation/rack/instrumentation.rb +75 -0
- data/lib/new_relic/agent/instrumentation/rack/prepend.rb +43 -0
- data/lib/new_relic/agent/instrumentation/rack.rb +33 -141
- data/lib/new_relic/agent/instrumentation/rails3/action_controller.rb +22 -57
- data/lib/new_relic/agent/instrumentation/rails_middleware.rb +5 -5
- data/lib/new_relic/agent/instrumentation/rails_notifications/action_cable.rb +10 -9
- data/lib/new_relic/agent/instrumentation/rails_notifications/action_controller.rb +18 -6
- data/lib/new_relic/agent/instrumentation/rails_notifications/action_view.rb +9 -6
- data/lib/new_relic/agent/instrumentation/rails_notifications/custom_events.rb +30 -0
- data/lib/new_relic/agent/instrumentation/rake/chain.rb +20 -0
- data/lib/new_relic/agent/instrumentation/rake/instrumentation.rb +142 -0
- data/lib/new_relic/agent/instrumentation/rake/prepend.rb +14 -0
- data/lib/new_relic/agent/instrumentation/rake.rb +18 -158
- data/lib/new_relic/agent/instrumentation/redis/chain.rb +45 -0
- data/lib/new_relic/agent/instrumentation/redis/constants.rb +17 -0
- data/lib/new_relic/agent/instrumentation/redis/instrumentation.rb +94 -0
- data/lib/new_relic/agent/instrumentation/redis/middleware.rb +16 -0
- data/lib/new_relic/agent/instrumentation/redis/prepend.rb +29 -0
- data/lib/new_relic/agent/instrumentation/redis.rb +20 -103
- data/lib/new_relic/agent/instrumentation/resque/chain.rb +21 -0
- data/lib/new_relic/agent/instrumentation/resque/helper.rb +19 -0
- data/lib/new_relic/agent/instrumentation/resque/instrumentation.rb +34 -0
- data/lib/new_relic/agent/instrumentation/resque/prepend.rb +15 -0
- data/lib/new_relic/agent/instrumentation/resque.rb +33 -41
- data/lib/new_relic/agent/instrumentation/sequel.rb +17 -20
- data/lib/new_relic/agent/instrumentation/sequel_helper.rb +13 -13
- data/lib/new_relic/agent/instrumentation/sidekiq/client.rb +20 -0
- data/lib/new_relic/agent/instrumentation/sidekiq/extensions/delayed_class.rb +30 -0
- data/lib/new_relic/agent/instrumentation/sidekiq/server.rb +37 -0
- data/lib/new_relic/agent/instrumentation/sidekiq.rb +30 -46
- data/lib/new_relic/agent/instrumentation/sinatra/chain.rb +55 -0
- data/lib/new_relic/agent/instrumentation/sinatra/ignorer.rb +31 -37
- data/lib/new_relic/agent/instrumentation/sinatra/instrumentation.rb +126 -0
- data/lib/new_relic/agent/instrumentation/sinatra/prepend.rb +33 -0
- data/lib/new_relic/agent/instrumentation/sinatra/transaction_namer.rb +4 -4
- data/lib/new_relic/agent/instrumentation/sinatra.rb +35 -165
- data/lib/new_relic/agent/instrumentation/thread/chain.rb +24 -0
- data/lib/new_relic/agent/instrumentation/thread/instrumentation.rb +28 -0
- data/lib/new_relic/agent/instrumentation/thread/prepend.rb +22 -0
- data/lib/new_relic/agent/instrumentation/thread.rb +20 -0
- data/lib/new_relic/agent/instrumentation/tilt/chain.rb +24 -0
- data/lib/new_relic/agent/instrumentation/tilt/instrumentation.rb +42 -0
- data/lib/new_relic/agent/instrumentation/tilt/prepend.rb +13 -0
- data/lib/new_relic/agent/instrumentation/tilt.rb +25 -0
- data/lib/new_relic/agent/instrumentation/typhoeus/chain.rb +22 -0
- data/lib/new_relic/agent/instrumentation/typhoeus/instrumentation.rb +80 -0
- data/lib/new_relic/agent/instrumentation/typhoeus/prepend.rb +14 -0
- data/lib/new_relic/agent/instrumentation/typhoeus.rb +14 -76
- data/lib/new_relic/agent/instrumentation.rb +2 -2
- data/lib/new_relic/agent/internal_agent_error.rb +3 -3
- data/lib/new_relic/agent/javascript_instrumentor.rb +59 -48
- data/lib/new_relic/agent/linking_metadata.rb +44 -0
- data/lib/new_relic/agent/local_log_decorator.rb +37 -0
- data/lib/new_relic/agent/log_event_aggregator.rb +235 -0
- data/lib/new_relic/agent/log_once.rb +2 -2
- data/lib/new_relic/agent/log_priority.rb +20 -0
- data/lib/new_relic/agent/logging.rb +104 -51
- data/lib/new_relic/agent/memory_logger.rb +3 -3
- data/lib/new_relic/agent/messaging.rb +74 -156
- data/lib/new_relic/agent/method_tracer.rb +157 -150
- data/lib/new_relic/agent/method_tracer_helpers.rb +89 -12
- data/lib/new_relic/agent/monitors/cross_app_monitor.rb +117 -0
- data/lib/new_relic/agent/monitors/distributed_tracing_monitor.rb +28 -0
- data/lib/new_relic/agent/{inbound_request_monitor.rb → monitors/inbound_request_monitor.rb} +3 -4
- data/lib/new_relic/agent/{synthetics_monitor.rb → monitors/synthetics_monitor.rb} +8 -13
- data/lib/new_relic/agent/monitors.rb +26 -0
- data/lib/new_relic/agent/new_relic_service/encoders.rb +8 -8
- data/lib/new_relic/agent/new_relic_service/json_marshaller.rb +7 -7
- data/lib/new_relic/agent/new_relic_service/marshaller.rb +3 -3
- data/lib/new_relic/agent/new_relic_service/security_policy_settings.rb +5 -5
- data/lib/new_relic/agent/new_relic_service.rb +266 -193
- data/lib/new_relic/agent/noticeable_error.rb +19 -0
- data/lib/new_relic/agent/null_logger.rb +8 -4
- data/lib/new_relic/agent/obfuscator.rb +9 -11
- data/lib/new_relic/agent/parameter_filtering.rb +30 -16
- data/lib/new_relic/agent/payload_metric_mapping.rb +10 -11
- data/lib/new_relic/agent/pipe_channel_manager.rb +34 -23
- data/lib/new_relic/agent/pipe_service.rb +14 -9
- data/lib/new_relic/agent/prepend_supportability.rb +3 -3
- data/lib/new_relic/agent/priority_sampled_buffer.rb +16 -16
- data/lib/new_relic/agent/rules_engine/replacement_rule.rb +12 -12
- data/lib/new_relic/agent/rules_engine/segment_terms_rule.rb +13 -14
- data/lib/new_relic/agent/rules_engine.rb +6 -5
- data/lib/new_relic/agent/sampler.rb +6 -6
- data/lib/new_relic/agent/sampler_collection.rb +5 -6
- data/lib/new_relic/agent/samplers/cpu_sampler.rb +9 -8
- data/lib/new_relic/agent/samplers/delayed_job_sampler.rb +21 -18
- data/lib/new_relic/agent/samplers/memory_sampler.rb +33 -22
- data/lib/new_relic/agent/samplers/object_sampler.rb +3 -3
- data/lib/new_relic/agent/samplers/vm_sampler.rb +22 -20
- data/lib/new_relic/agent/span_event_aggregator.rb +16 -16
- data/lib/new_relic/agent/span_event_primitive.rb +106 -68
- data/lib/new_relic/agent/sql_sampler.rb +23 -23
- data/lib/new_relic/agent/stats.rb +80 -43
- data/lib/new_relic/agent/stats_engine/gc_profiler.rb +11 -13
- data/lib/new_relic/agent/stats_engine/stats_hash.rb +13 -14
- data/lib/new_relic/agent/stats_engine.rb +9 -9
- data/lib/new_relic/agent/synthetics_event_aggregator.rb +9 -10
- data/lib/new_relic/agent/system_info.rb +97 -68
- data/lib/new_relic/agent/threading/agent_thread.rb +19 -15
- data/lib/new_relic/agent/threading/backtrace_node.rb +13 -14
- data/lib/new_relic/agent/threading/backtrace_service.rb +18 -22
- data/lib/new_relic/agent/threading/thread_profile.rb +25 -25
- data/lib/new_relic/agent/timestamp_sampled_buffer.rb +3 -3
- data/lib/new_relic/agent/tracer.rb +127 -107
- data/lib/new_relic/agent/transaction/abstract_segment.rb +145 -49
- data/lib/new_relic/agent/transaction/datastore_segment.rb +23 -19
- data/lib/new_relic/agent/transaction/distributed_tracer.rb +185 -0
- data/lib/new_relic/agent/transaction/distributed_tracing.rb +76 -86
- data/lib/new_relic/agent/transaction/external_request_segment.rb +67 -77
- data/lib/new_relic/agent/transaction/message_broker_segment.rb +34 -46
- data/lib/new_relic/agent/transaction/request_attributes.rb +40 -40
- data/lib/new_relic/agent/transaction/segment.rb +41 -11
- data/lib/new_relic/agent/transaction/slowest_sample_buffer.rb +2 -4
- data/lib/new_relic/agent/transaction/synthetics_sample_buffer.rb +3 -3
- data/lib/new_relic/agent/transaction/trace.rb +19 -17
- data/lib/new_relic/agent/transaction/trace_builder.rb +11 -11
- data/lib/new_relic/agent/transaction/trace_context.rb +102 -93
- data/lib/new_relic/agent/transaction/trace_node.rb +31 -32
- data/lib/new_relic/agent/transaction/tracing.rb +22 -13
- data/lib/new_relic/agent/transaction/transaction_sample_buffer.rb +7 -7
- data/lib/new_relic/agent/transaction.rb +239 -198
- data/lib/new_relic/agent/transaction_error_primitive.rb +32 -28
- data/lib/new_relic/agent/transaction_event_aggregator.rb +17 -17
- data/lib/new_relic/agent/transaction_event_primitive.rb +43 -47
- data/lib/new_relic/agent/transaction_event_recorder.rb +17 -16
- data/lib/new_relic/agent/transaction_metrics.rb +11 -10
- data/lib/new_relic/agent/transaction_sampler.rb +8 -9
- data/lib/new_relic/agent/transaction_time_aggregator.rb +33 -28
- data/lib/new_relic/agent/utilization/aws.rb +35 -5
- data/lib/new_relic/agent/utilization/azure.rb +7 -7
- data/lib/new_relic/agent/utilization/gcp.rb +11 -11
- data/lib/new_relic/agent/utilization/pcf.rb +7 -6
- data/lib/new_relic/agent/utilization/vendor.rb +45 -30
- data/lib/new_relic/agent/utilization_data.rb +8 -6
- data/lib/new_relic/agent/vm/jruby_vm.rb +2 -2
- data/lib/new_relic/agent/vm/monotonic_gc_profiler.rb +4 -4
- data/lib/new_relic/agent/vm/mri_vm.rb +54 -26
- data/lib/new_relic/agent/vm/snapshot.rb +6 -6
- data/lib/new_relic/agent/vm.rb +2 -2
- data/lib/new_relic/agent/worker_loop.rb +11 -13
- data/lib/new_relic/agent.rb +159 -109
- data/lib/new_relic/cli/command.rb +22 -24
- data/lib/new_relic/cli/commands/deployments.rb +101 -51
- data/lib/new_relic/cli/commands/install.rb +33 -35
- data/lib/new_relic/coerce.rb +19 -15
- data/lib/new_relic/collection_helper.rb +51 -49
- data/lib/new_relic/constants.rb +38 -0
- data/lib/new_relic/control/class_methods.rb +6 -6
- data/lib/new_relic/control/frameworks/external.rb +3 -3
- data/lib/new_relic/control/frameworks/rails.rb +50 -32
- data/lib/new_relic/control/frameworks/rails3.rb +4 -5
- data/lib/new_relic/control/frameworks/rails4.rb +2 -2
- data/lib/new_relic/control/frameworks/rails_notifications.rb +2 -2
- data/lib/new_relic/control/frameworks/ruby.rb +4 -4
- data/lib/new_relic/control/frameworks/sinatra.rb +8 -2
- data/lib/new_relic/control/frameworks.rb +2 -2
- data/lib/new_relic/control/instance_methods.rb +28 -46
- data/lib/new_relic/control/instrumentation.rb +26 -12
- data/lib/new_relic/control/private_instance_methods.rb +48 -0
- data/lib/new_relic/control/server_methods.rb +4 -5
- data/lib/new_relic/control.rb +2 -3
- data/lib/new_relic/delayed_job_injection.rb +2 -2
- data/lib/new_relic/dependency_detection.rb +138 -31
- data/lib/new_relic/environment_report.rb +42 -36
- data/lib/new_relic/helper.rb +50 -8
- data/lib/new_relic/language_support.rb +31 -7
- data/lib/new_relic/latest_changes.rb +11 -10
- data/lib/new_relic/local_environment.rb +23 -27
- data/lib/new_relic/metric_data.rb +32 -27
- data/lib/new_relic/metric_spec.rb +9 -7
- data/lib/new_relic/noticed_error.rb +58 -47
- data/lib/new_relic/rack/agent_hooks.rb +2 -2
- data/lib/new_relic/rack/agent_middleware.rb +6 -4
- data/lib/new_relic/rack/browser_monitoring.rb +136 -117
- data/lib/new_relic/rack.rb +2 -2
- data/lib/new_relic/recipes/capistrano3.rb +5 -63
- data/lib/new_relic/recipes/capistrano_legacy.rb +25 -28
- data/lib/new_relic/recipes/helpers/send_deployment.rb +70 -0
- data/lib/new_relic/recipes.rb +2 -2
- data/lib/new_relic/supportability_helper.rb +23 -7
- data/lib/new_relic/traced_thread.rb +39 -0
- data/lib/new_relic/version.rb +7 -18
- data/lib/newrelic_rpm.rb +21 -34
- data/lib/sequel/extensions/{newrelic_instrumentation.rb → new_relic_instrumentation.rb} +18 -21
- data/lib/sequel/plugins/{newrelic_instrumentation.rb → new_relic_instrumentation.rb} +10 -16
- data/lib/tasks/all.rb +4 -4
- data/lib/tasks/config.rake +24 -119
- data/lib/tasks/coverage_report.rake +28 -0
- data/lib/tasks/helpers/config.html.erb +21 -0
- data/lib/tasks/helpers/format.rb +123 -0
- data/lib/tasks/helpers/matches.rb +12 -0
- data/lib/tasks/helpers/prompt.rb +24 -0
- data/lib/tasks/helpers/removers.rb +33 -0
- data/lib/tasks/install.rake +8 -4
- data/lib/tasks/instrumentation_generator/README.md +63 -0
- data/lib/tasks/instrumentation_generator/TODO.md +33 -0
- data/lib/tasks/instrumentation_generator/instrumentation.thor +121 -0
- data/lib/tasks/instrumentation_generator/templates/Envfile.tt +9 -0
- data/lib/tasks/instrumentation_generator/templates/chain.tt +22 -0
- data/lib/tasks/instrumentation_generator/templates/chain_method.tt +8 -0
- data/lib/tasks/instrumentation_generator/templates/dependency_detection.tt +29 -0
- data/lib/tasks/instrumentation_generator/templates/instrumentation.tt +13 -0
- data/lib/tasks/instrumentation_generator/templates/instrumentation_method.tt +3 -0
- data/lib/tasks/instrumentation_generator/templates/newrelic.yml.tt +19 -0
- data/lib/tasks/instrumentation_generator/templates/prepend.tt +13 -0
- data/lib/tasks/instrumentation_generator/templates/prepend_method.tt +3 -0
- data/lib/tasks/instrumentation_generator/templates/test.tt +15 -0
- data/lib/tasks/multiverse.rake +4 -0
- data/lib/tasks/multiverse.rb +23 -9
- data/lib/tasks/newrelic.rb +3 -2
- data/lib/tasks/tests.rake +17 -17
- data/newrelic.yml +672 -3
- data/newrelic_rpm.gemspec +46 -39
- data/recipes/newrelic.rb +3 -3
- data/test/agent_helper.rb +340 -110
- metadata +272 -97
- data/.travis.yml +0 -210
- data/bin/mongrel_rpm +0 -33
- data/cert/cacert.pem +0 -1177
- data/lib/new_relic/agent/cross_app_monitor.rb +0 -110
- data/lib/new_relic/agent/datastores/mongo/obfuscator.rb +0 -44
- data/lib/new_relic/agent/datastores/mongo/statement_formatter.rb +0 -53
- data/lib/new_relic/agent/distributed_trace_intrinsics.rb +0 -90
- data/lib/new_relic/agent/distributed_trace_metrics.rb +0 -74
- data/lib/new_relic/agent/distributed_trace_monitor.rb +0 -30
- data/lib/new_relic/agent/distributed_trace_payload.rb +0 -175
- data/lib/new_relic/agent/distributed_trace_transport_type.rb +0 -43
- data/lib/new_relic/agent/http_clients/abstract_request.rb +0 -31
- data/lib/new_relic/agent/instrumentation/acts_as_solr.rb +0 -74
- data/lib/new_relic/agent/instrumentation/authlogic.rb +0 -25
- data/lib/new_relic/agent/instrumentation/data_mapper.rb +0 -202
- data/lib/new_relic/agent/instrumentation/excon/connection.rb +0 -46
- data/lib/new_relic/agent/instrumentation/http.rb +0 -46
- data/lib/new_relic/agent/instrumentation/merb/controller.rb +0 -44
- data/lib/new_relic/agent/instrumentation/merb/errors.rb +0 -33
- data/lib/new_relic/agent/instrumentation/net.rb +0 -50
- data/lib/new_relic/agent/instrumentation/rails/action_controller.rb +0 -125
- data/lib/new_relic/agent/instrumentation/rails/action_web_service.rb +0 -46
- data/lib/new_relic/agent/instrumentation/rainbows_instrumentation.rb +0 -26
- data/lib/new_relic/agent/instrumentation/sunspot.rb +0 -33
- data/lib/new_relic/agent/range_extensions.rb +0 -47
- data/lib/new_relic/agent/supported_versions.rb +0 -275
- data/lib/new_relic/agent/trace_context.rb +0 -244
- data/lib/new_relic/agent/trace_context_payload.rb +0 -134
- data/lib/new_relic/agent/trace_context_request_monitor.rb +0 -42
- data/lib/new_relic/build.rb +0 -2
- data/lib/new_relic/control/frameworks/merb.rb +0 -29
- data/lib/new_relic/metrics.rb +0 -13
- data/lib/tasks/config.html.erb +0 -32
- data/true +0 -0
- /data/lib/tasks/{config.text.erb → helpers/config.text.erb} +0 -0
data/test/agent_helper.rb
CHANGED
@@ -1,26 +1,36 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
# This file is distributed under New Relic's license terms.
|
3
|
-
# See https://github.com/newrelic/
|
2
|
+
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
|
3
|
+
# frozen_string_literal: true
|
4
4
|
|
5
5
|
# These helpers should not have any gem dependencies except on newrelic_rpm
|
6
6
|
# itself, and should be usable from within any multiverse suite.
|
7
7
|
|
8
8
|
require 'json'
|
9
|
+
require 'net/http'
|
10
|
+
begin
|
11
|
+
require 'net/http/status'
|
12
|
+
rescue LoadError
|
13
|
+
# NOP -- Net::HTTP::STATUS_CODES was introduced in Ruby 2.5
|
14
|
+
end
|
9
15
|
|
10
16
|
class ArrayLogDevice
|
11
|
-
def initialize(
|
17
|
+
def initialize(array = [])
|
12
18
|
@array = array
|
13
19
|
end
|
14
20
|
attr_reader :array
|
15
21
|
|
16
|
-
def write(
|
22
|
+
def write(message)
|
17
23
|
@array << message
|
18
24
|
end
|
19
25
|
|
20
26
|
def close; end
|
21
27
|
end
|
22
28
|
|
23
|
-
def
|
29
|
+
def fake_guid(length = 16)
|
30
|
+
NewRelic::Agent::GuidGenerator.generate_guid(length)
|
31
|
+
end
|
32
|
+
|
33
|
+
def assert_between(floor, ceiling, value, message = "expected #{floor} <= #{value} <= #{ceiling}")
|
24
34
|
assert((floor <= value && value <= ceiling), message)
|
25
35
|
end
|
26
36
|
|
@@ -38,8 +48,8 @@ end
|
|
38
48
|
|
39
49
|
def assert_has_traced_error(error_class)
|
40
50
|
errors = harvest_error_traces!
|
41
|
-
|
42
|
-
|
51
|
+
|
52
|
+
refute_nil errors.find { |e| e.exception_class_name == error_class.name }, \
|
43
53
|
"Didn't find error of class #{error_class}"
|
44
54
|
end
|
45
55
|
|
@@ -55,6 +65,14 @@ def last_transaction_event
|
|
55
65
|
harvest_transaction_events!.last.last
|
56
66
|
end
|
57
67
|
|
68
|
+
def harvest_span_events!
|
69
|
+
NewRelic::Agent.instance.span_event_aggregator.harvest!
|
70
|
+
end
|
71
|
+
|
72
|
+
def last_span_event
|
73
|
+
harvest_span_events!.last.last
|
74
|
+
end
|
75
|
+
|
58
76
|
def harvest_error_events!
|
59
77
|
NewRelic::Agent.instance.error_collector.error_event_aggregator.harvest!
|
60
78
|
end
|
@@ -63,29 +81,25 @@ def last_error_event
|
|
63
81
|
harvest_error_events!.last.last
|
64
82
|
end
|
65
83
|
|
66
|
-
unless defined?
|
67
|
-
def
|
68
|
-
assert yield, *msgs
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
unless defined?( assert_includes )
|
73
|
-
def assert_includes( collection, member, msg=nil )
|
84
|
+
unless defined? assert_includes
|
85
|
+
def assert_includes(collection, member, msg = nil)
|
74
86
|
msg = "Expected #{collection.inspect} to include #{member.inspect}"
|
75
|
-
|
87
|
+
|
88
|
+
assert_includes collection, member, msg
|
76
89
|
end
|
77
90
|
end
|
78
91
|
|
79
|
-
unless defined?
|
80
|
-
def assert_not_includes(
|
92
|
+
unless defined? assert_not_includes
|
93
|
+
def assert_not_includes(collection, member, msg = nil)
|
81
94
|
msg = "Expected #{collection.inspect} not to include #{member.inspect}"
|
82
|
-
|
95
|
+
|
96
|
+
refute_includes collection, member, msg
|
83
97
|
end
|
84
98
|
end
|
85
99
|
|
86
|
-
unless defined?
|
87
|
-
def assert_empty(collection, msg=nil)
|
88
|
-
|
100
|
+
unless defined? assert_empty
|
101
|
+
def assert_empty(collection, msg = nil)
|
102
|
+
assert_empty collection, msg
|
89
103
|
end
|
90
104
|
end
|
91
105
|
|
@@ -94,6 +108,13 @@ def assert_equal_unordered(left, right)
|
|
94
108
|
left.each { |element| assert_includes(right, element) }
|
95
109
|
end
|
96
110
|
|
111
|
+
def assert_log_contains(log, message)
|
112
|
+
lines = log.array
|
113
|
+
|
114
|
+
assert (lines.any? { |line| line.match(message) }),
|
115
|
+
"Could not find message. Log contained: #{lines.join("\n")}"
|
116
|
+
end
|
117
|
+
|
97
118
|
def assert_audit_log_contains(audit_log_contents, needle)
|
98
119
|
# Original request bodies dumped to the log have symbol keys, but once
|
99
120
|
# they go through a dump/load, they're strings again, so we strip
|
@@ -101,7 +122,8 @@ def assert_audit_log_contains(audit_log_contents, needle)
|
|
101
122
|
regex = /[:"]/
|
102
123
|
needle = needle.gsub(regex, '')
|
103
124
|
haystack = audit_log_contents.gsub(regex, '')
|
104
|
-
|
125
|
+
|
126
|
+
assert_includes(haystack, needle, "Expected log to contain '#{needle}'")
|
105
127
|
end
|
106
128
|
|
107
129
|
# Because we don't generate a strictly machine-readable representation of
|
@@ -115,30 +137,33 @@ end
|
|
115
137
|
def assert_audit_log_contains_object(audit_log_contents, o, format = :json)
|
116
138
|
case o
|
117
139
|
when Hash
|
118
|
-
o.each do |k,v|
|
140
|
+
o.each do |k, v|
|
119
141
|
assert_audit_log_contains_object(audit_log_contents, v, format)
|
120
142
|
assert_audit_log_contains_object(audit_log_contents, k, format)
|
121
143
|
end
|
122
144
|
when Array
|
145
|
+
|
123
146
|
o.each do |el|
|
124
147
|
assert_audit_log_contains_object(audit_log_contents, el, format)
|
125
148
|
end
|
126
149
|
when NilClass
|
127
|
-
|
150
|
+
|
151
|
+
assert_audit_log_contains(audit_log_contents, format == :json ? 'null' : 'nil')
|
128
152
|
else
|
129
153
|
assert_audit_log_contains(audit_log_contents, o.inspect)
|
130
154
|
end
|
131
155
|
end
|
132
156
|
|
133
157
|
def compare_metrics(expected, actual)
|
134
|
-
actual.delete_if {|a| a.include?('GC/Transaction/') }
|
158
|
+
actual.delete_if { |a| a.include?('GC/Transaction/') }
|
159
|
+
|
135
160
|
assert_equal(expected.to_a.sort, actual.to_a.sort, "extra: #{(actual - expected).to_a.inspect}; missing: #{(expected - actual).to_a.inspect}")
|
136
161
|
end
|
137
162
|
|
138
163
|
def metric_spec_from_specish(specish)
|
139
164
|
spec = case specish
|
140
165
|
when String then NewRelic::MetricSpec.new(specish)
|
141
|
-
when Array
|
166
|
+
when Array then NewRelic::MetricSpec.new(*specish)
|
142
167
|
end
|
143
168
|
spec
|
144
169
|
end
|
@@ -148,17 +173,17 @@ def _normalize_metric_expectations(expectations)
|
|
148
173
|
when Array
|
149
174
|
hash = {}
|
150
175
|
# Just assert that the metric is present, nothing about the attributes
|
151
|
-
expectations.each { |k| hash[k] = {
|
176
|
+
expectations.each { |k| hash[k] = {} }
|
152
177
|
hash
|
153
178
|
when String
|
154
|
-
{
|
179
|
+
{expectations => {}}
|
155
180
|
else
|
156
181
|
expectations
|
157
182
|
end
|
158
183
|
end
|
159
184
|
|
160
185
|
def dump_stats(stats)
|
161
|
-
str =
|
186
|
+
str = +" Call count: #{stats.call_count}\n"
|
162
187
|
str << " Total call time: #{stats.total_call_time}\n"
|
163
188
|
str << " Total exclusive time: #{stats.total_exclusive_time}\n"
|
164
189
|
str << " Min call time: #{stats.min_call_time}\n"
|
@@ -173,16 +198,31 @@ end
|
|
173
198
|
def assert_stats_has_values(stats, expected_spec, expected_attrs)
|
174
199
|
expected_attrs.each do |attr, expected_value|
|
175
200
|
actual_value = stats.send(attr)
|
201
|
+
|
202
|
+
msg = "Expected #{attr} for #{expected_spec} to be #{'~' unless attr == :call_count}#{expected_value}, " \
|
203
|
+
"got #{actual_value}.\nActual stats:\n#{dump_stats(stats)}"
|
204
|
+
|
176
205
|
if attr == :call_count
|
177
|
-
|
178
|
-
"Expected #{attr} for #{expected_spec} to be #{expected_value}, got #{actual_value}.\nActual stats:\n#{dump_stats(stats)}")
|
206
|
+
assert_stats_has_values_with_call_count(expected_value, actual_value, msg)
|
179
207
|
else
|
180
|
-
assert_in_delta(expected_value, actual_value, 0.0001,
|
181
|
-
"Expected #{attr} for #{expected_spec} to be ~#{expected_value}, got #{actual_value}.\nActual stats:\n#{dump_stats(stats)}")
|
208
|
+
assert_in_delta(expected_value, actual_value, 0.0001, msg)
|
182
209
|
end
|
183
210
|
end
|
184
211
|
end
|
185
212
|
|
213
|
+
def assert_stats_has_values_with_call_count(expected_value, actual_value, msg)
|
214
|
+
# >, <, >=, <= comparisons
|
215
|
+
if expected_value.to_s =~ /([<>]=?)\s*(\d+)/
|
216
|
+
operator = Regexp.last_match(1).to_sym
|
217
|
+
count = Regexp.last_match(2).to_i
|
218
|
+
|
219
|
+
assert_operator(actual_value, operator, count, msg)
|
220
|
+
# == comparison
|
221
|
+
else
|
222
|
+
assert_equal(expected_value, actual_value, msg)
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
186
226
|
def assert_metrics_recorded(expected)
|
187
227
|
expected = _normalize_metric_expectations(expected)
|
188
228
|
expected.each do |specish, expected_attrs|
|
@@ -199,6 +239,7 @@ def assert_metrics_recorded(expected)
|
|
199
239
|
|
200
240
|
assert(actual_stats, msg)
|
201
241
|
end
|
242
|
+
|
202
243
|
assert_stats_has_values(actual_stats, expected_spec, expected_attrs)
|
203
244
|
end
|
204
245
|
end
|
@@ -214,8 +255,9 @@ end
|
|
214
255
|
# the :ignore_filter option. This will allow you to specify a Regex that
|
215
256
|
# allowlists broad swathes of metric territory (e.g. 'Supportability/').
|
216
257
|
#
|
217
|
-
def assert_metrics_recorded_exclusive(expected, options={})
|
258
|
+
def assert_metrics_recorded_exclusive(expected, options = {})
|
218
259
|
expected = _normalize_metric_expectations(expected)
|
260
|
+
|
219
261
|
assert_metrics_recorded(expected)
|
220
262
|
|
221
263
|
recorded_metrics = NewRelic::Agent.instance.stats_engine.to_h.keys
|
@@ -227,14 +269,23 @@ def assert_metrics_recorded_exclusive(expected, options={})
|
|
227
269
|
recorded_metrics.reject! { |m| m.name.match(options[:ignore_filter]) }
|
228
270
|
end
|
229
271
|
|
230
|
-
expected_metrics
|
272
|
+
expected_metrics = expected.keys.map { |s| metric_spec_from_specish(s) }
|
231
273
|
|
232
274
|
unexpected_metrics = recorded_metrics - expected_metrics
|
233
|
-
unexpected_metrics.reject! { |m| m.name
|
275
|
+
unexpected_metrics.reject! { |m| m.name.include?('GC/Transaction') }
|
234
276
|
|
235
277
|
assert_equal(0, unexpected_metrics.size, "Found unexpected metrics: #{format_metric_spec_list(unexpected_metrics)}")
|
236
278
|
end
|
237
279
|
|
280
|
+
def assert_newrelic_metadata_present(metadata)
|
281
|
+
assert metadata.key?('newrelic')
|
282
|
+
refute_nil metadata['newrelic']
|
283
|
+
end
|
284
|
+
|
285
|
+
def assert_distributed_tracing_payload_created_for_transaction(transaction)
|
286
|
+
assert transaction.distributed_tracer.instance_variable_get(:@distributed_trace_payload_created)
|
287
|
+
end
|
288
|
+
|
238
289
|
# The clear_metrics! method prevents metrics from "leaking" between tests by resetting
|
239
290
|
# the @stats_hash instance variable in the current instance of NewRelic::Agent::StatsEngine.
|
240
291
|
|
@@ -261,7 +312,8 @@ def assert_metrics_not_recorded(not_expected)
|
|
261
312
|
found_but_not_expected << spec
|
262
313
|
end
|
263
314
|
end
|
264
|
-
|
315
|
+
|
316
|
+
assert_empty(found_but_not_expected, "Found unexpected metrics: #{format_metric_spec_list(found_but_not_expected)}")
|
265
317
|
end
|
266
318
|
|
267
319
|
alias :refute_metrics_recorded :assert_metrics_not_recorded
|
@@ -269,13 +321,12 @@ alias :refute_metrics_recorded :assert_metrics_not_recorded
|
|
269
321
|
def assert_no_metrics_match(regex)
|
270
322
|
matching_metrics = []
|
271
323
|
NewRelic::Agent.instance.stats_engine.to_h.keys.map(&:to_s).each do |metric|
|
272
|
-
matching_metrics << metric if metric.match
|
324
|
+
matching_metrics << metric if metric.match(regex)
|
273
325
|
end
|
274
326
|
|
275
|
-
|
276
|
-
[],
|
327
|
+
assert_empty(
|
277
328
|
matching_metrics,
|
278
|
-
"Found unexpected metrics:\n" +
|
329
|
+
"Found unexpected metrics:\n" + matching_metrics.map { |m| " '#{m}'" }.join("\n") + "\n\n"
|
279
330
|
)
|
280
331
|
end
|
281
332
|
|
@@ -290,21 +341,23 @@ end
|
|
290
341
|
|
291
342
|
def assert_truthy(expected, msg = nil)
|
292
343
|
msg ||= "Expected #{expected.inspect} to be truthy"
|
293
|
-
|
344
|
+
|
345
|
+
refute !expected, msg
|
294
346
|
end
|
295
347
|
|
296
348
|
def assert_falsy(expected, msg = nil)
|
297
349
|
msg ||= "Expected #{expected.inspect} to be falsy"
|
298
|
-
|
350
|
+
|
351
|
+
refute expected, msg
|
299
352
|
end
|
300
353
|
|
301
|
-
unless defined?
|
354
|
+
unless defined? assert_false
|
302
355
|
def assert_false(expected)
|
303
|
-
|
356
|
+
refute expected
|
304
357
|
end
|
305
358
|
end
|
306
359
|
|
307
|
-
unless defined?
|
360
|
+
unless defined? refute
|
308
361
|
alias refute assert_false
|
309
362
|
end
|
310
363
|
|
@@ -327,30 +380,67 @@ end
|
|
327
380
|
# in_transaction('foobar', :category => :controller) { ... }
|
328
381
|
#
|
329
382
|
def in_transaction(*args, &blk)
|
330
|
-
opts
|
331
|
-
category = (opts
|
383
|
+
opts = args.last&.is_a?(Hash) ? args.pop : {}
|
384
|
+
category = (opts&.delete(:category)) || :other
|
332
385
|
|
333
386
|
# At least one test passes `:transaction_name => nil`, so handle it gently
|
334
|
-
name = opts.key?(:transaction_name) ? opts.delete(:transaction_name) :
|
335
|
-
args.first || 'dummy'
|
387
|
+
name = opts.key?(:transaction_name) ? opts.delete(:transaction_name) : args.first || 'dummy'
|
336
388
|
|
337
389
|
state = NewRelic::Agent::Tracer.state
|
338
390
|
txn = nil
|
339
391
|
|
340
392
|
NewRelic::Agent::Tracer.in_transaction(name: name, category: category, options: opts) do
|
341
393
|
txn = state.current_transaction
|
342
|
-
yield
|
394
|
+
yield(state.current_transaction)
|
343
395
|
end
|
344
396
|
|
345
397
|
txn
|
346
398
|
end
|
347
399
|
|
400
|
+
# Temporarily disables default transformer so tests with invalid inputs can be tried
|
401
|
+
def with_disabled_defaults_transformer(key)
|
402
|
+
begin
|
403
|
+
transformer = NewRelic::Agent::Configuration::DEFAULTS[key][:transform]
|
404
|
+
NewRelic::Agent::Configuration::DEFAULTS[key][:transform] = nil
|
405
|
+
yield
|
406
|
+
ensure
|
407
|
+
NewRelic::Agent::Configuration::DEFAULTS[key][:transform] = transformer
|
408
|
+
end
|
409
|
+
end
|
410
|
+
|
348
411
|
# Convenience wrapper to stand up a transaction and provide a segment within
|
349
|
-
# that transaction to work with. The same
|
412
|
+
# that transaction to work with. The same arguments as provided to in_transaction
|
350
413
|
# may be supplied.
|
351
|
-
def with_segment
|
352
|
-
|
353
|
-
|
414
|
+
def with_segment(*args, &blk)
|
415
|
+
segment = nil
|
416
|
+
txn = in_transaction(*args) do |t|
|
417
|
+
segment = t.current_segment
|
418
|
+
yield(segment, t)
|
419
|
+
end
|
420
|
+
[segment, txn]
|
421
|
+
end
|
422
|
+
|
423
|
+
# building error attributes on segments are deferred until it's time
|
424
|
+
# to publish/harvest them as spans, so for testing, we'll explicitly
|
425
|
+
# build 'em as appropriate so we can test 'em
|
426
|
+
def build_deferred_error_attributes(segment)
|
427
|
+
return unless segment.noticed_error
|
428
|
+
return if segment.noticed_error_attributes.frozen?
|
429
|
+
|
430
|
+
segment.noticed_error.build_error_attributes
|
431
|
+
end
|
432
|
+
|
433
|
+
def capture_segment_with_error
|
434
|
+
begin
|
435
|
+
segment_with_error = nil
|
436
|
+
with_segment do |segment|
|
437
|
+
segment_with_error = segment
|
438
|
+
raise 'oops!'
|
439
|
+
end
|
440
|
+
rescue Exception => exception
|
441
|
+
assert segment_with_error, 'expected to have a segment_with_error'
|
442
|
+
build_deferred_error_attributes(segment_with_error)
|
443
|
+
return segment_with_error, exception
|
354
444
|
end
|
355
445
|
end
|
356
446
|
|
@@ -360,15 +450,15 @@ end
|
|
360
450
|
|
361
451
|
# Convenience wrapper around in_transaction that sets the category so that it
|
362
452
|
# looks like we are in a web transaction
|
363
|
-
def in_web_transaction(name='dummy')
|
453
|
+
def in_web_transaction(name = 'dummy')
|
364
454
|
in_transaction(name, :category => :controller, :request => stub(:path => '/')) do |txn|
|
365
|
-
yield
|
455
|
+
yield(txn)
|
366
456
|
end
|
367
457
|
end
|
368
458
|
|
369
|
-
def in_background_transaction(name='silly')
|
459
|
+
def in_background_transaction(name = 'silly')
|
370
460
|
in_transaction(name, :category => :task) do |txn|
|
371
|
-
yield
|
461
|
+
yield(txn)
|
372
462
|
end
|
373
463
|
end
|
374
464
|
|
@@ -380,13 +470,14 @@ end
|
|
380
470
|
|
381
471
|
def last_transaction_trace
|
382
472
|
return unless last_sample = NewRelic::Agent.agent.transaction_sampler.last_sample
|
473
|
+
|
383
474
|
NewRelic::Agent::Transaction::TraceBuilder.build_trace(last_sample)
|
384
475
|
end
|
385
476
|
|
386
477
|
def last_transaction_trace_request_params
|
387
478
|
agent_attributes = attributes_for(last_transaction_trace, :agent)
|
388
479
|
agent_attributes.inject({}) do |memo, (key, value)|
|
389
|
-
memo[key] = value if key.to_s.start_with?(
|
480
|
+
memo[key] = value if key.to_s.start_with?('request.parameters.')
|
390
481
|
memo
|
391
482
|
end
|
392
483
|
end
|
@@ -401,7 +492,7 @@ def last_sql_trace
|
|
401
492
|
NewRelic::Agent.agent.sql_sampler.sql_traces.values.last
|
402
493
|
end
|
403
494
|
|
404
|
-
def find_last_transaction_node(transaction_sample=nil)
|
495
|
+
def find_last_transaction_node(transaction_sample = nil)
|
405
496
|
if transaction_sample
|
406
497
|
root_node = transaction_sample.root_node
|
407
498
|
else
|
@@ -409,7 +500,7 @@ def find_last_transaction_node(transaction_sample=nil)
|
|
409
500
|
end
|
410
501
|
|
411
502
|
last_node = nil
|
412
|
-
root_node.each_node {|s| last_node = s }
|
503
|
+
root_node.each_node { |s| last_node = s }
|
413
504
|
|
414
505
|
return last_node
|
415
506
|
end
|
@@ -426,7 +517,7 @@ end
|
|
426
517
|
|
427
518
|
def find_node_with_name_matching(transaction_sample, regex)
|
428
519
|
transaction_sample.root_node.each_node do |node|
|
429
|
-
if node.metric_name.match
|
520
|
+
if node.metric_name.match(regex)
|
430
521
|
return node
|
431
522
|
end
|
432
523
|
end
|
@@ -440,7 +531,7 @@ def find_all_nodes_with_name_matching(transaction_sample, regexes)
|
|
440
531
|
|
441
532
|
transaction_sample.root_node.each_node do |node|
|
442
533
|
regexes.each do |regex|
|
443
|
-
if node.metric_name.match
|
534
|
+
if node.metric_name.match(regex)
|
444
535
|
matching_nodes << node
|
445
536
|
end
|
446
537
|
end
|
@@ -449,7 +540,7 @@ def find_all_nodes_with_name_matching(transaction_sample, regexes)
|
|
449
540
|
matching_nodes
|
450
541
|
end
|
451
542
|
|
452
|
-
def with_config(config_hash, at_start=true)
|
543
|
+
def with_config(config_hash, at_start = true)
|
453
544
|
config = NewRelic::Agent::Configuration::DottedHash.new(config_hash, true)
|
454
545
|
NewRelic::Agent.config.add_config_for_testing(config, at_start)
|
455
546
|
NewRelic::Agent.instance.refresh_attribute_filter
|
@@ -461,8 +552,8 @@ def with_config(config_hash, at_start=true)
|
|
461
552
|
end
|
462
553
|
end
|
463
554
|
|
464
|
-
def with_server_source
|
465
|
-
with_config
|
555
|
+
def with_server_source(config_hash, at_start = true)
|
556
|
+
with_config(config_hash, at_start) do
|
466
557
|
NewRelic::Agent.config.notify_server_source_added
|
467
558
|
yield
|
468
559
|
end
|
@@ -500,7 +591,7 @@ unless Time.respond_to?(:__original_now)
|
|
500
591
|
end
|
501
592
|
end
|
502
593
|
|
503
|
-
def nr_freeze_time(now=Time.now)
|
594
|
+
def nr_freeze_time(now = Time.now)
|
504
595
|
Time.__frozen_now = now
|
505
596
|
end
|
506
597
|
|
@@ -512,7 +603,32 @@ def advance_time(seconds)
|
|
512
603
|
Time.__frozen_now = Time.now + seconds
|
513
604
|
end
|
514
605
|
|
515
|
-
|
606
|
+
unless Process.respond_to?(:__original_clock_gettime)
|
607
|
+
Process.instance_eval do
|
608
|
+
class << self
|
609
|
+
attr_accessor :__frozen_clock_gettime
|
610
|
+
alias_method :__original_clock_gettime, :clock_gettime
|
611
|
+
|
612
|
+
def clock_gettime(clock_id, unit = :float_second)
|
613
|
+
__frozen_clock_gettime || __original_clock_gettime(clock_id, unit)
|
614
|
+
end
|
615
|
+
end
|
616
|
+
end
|
617
|
+
end
|
618
|
+
|
619
|
+
def advance_process_time(seconds, clock_id = Process::CLOCK_REALTIME)
|
620
|
+
Process.__frozen_clock_gettime = Process.clock_gettime(clock_id) + seconds
|
621
|
+
end
|
622
|
+
|
623
|
+
def nr_freeze_process_time(now = Process.clock_gettime(Process::CLOCK_REALTIME))
|
624
|
+
Process.__frozen_clock_gettime = now
|
625
|
+
end
|
626
|
+
|
627
|
+
def nr_unfreeze_process_time
|
628
|
+
Process.__frozen_clock_gettime = nil
|
629
|
+
end
|
630
|
+
|
631
|
+
def with_constant_defined(constant_symbol, implementation = Module.new)
|
516
632
|
const_path = constant_path(constant_symbol.to_s)
|
517
633
|
|
518
634
|
if const_path
|
@@ -532,7 +648,7 @@ def with_constant_defined(constant_symbol, implementation=Module.new)
|
|
532
648
|
end
|
533
649
|
end
|
534
650
|
|
535
|
-
def constant_path(name, opts={})
|
651
|
+
def constant_path(name, opts = {})
|
536
652
|
allow_partial = opts[:allow_partial]
|
537
653
|
path = [Object]
|
538
654
|
parts = name.gsub(/^::/, '').split('::')
|
@@ -540,6 +656,7 @@ def constant_path(name, opts={})
|
|
540
656
|
if !path.last.constants.include?(part.to_sym)
|
541
657
|
return allow_partial ? path : nil
|
542
658
|
end
|
659
|
+
|
543
660
|
path << path.last.const_get(part)
|
544
661
|
end
|
545
662
|
path
|
@@ -555,7 +672,8 @@ def undefine_constant(constant_symbol)
|
|
555
672
|
const_str = constant_symbol.to_s
|
556
673
|
parent = get_parent(const_str)
|
557
674
|
const_name = const_str.gsub(/.*::/, '')
|
558
|
-
return yield unless parent
|
675
|
+
return yield unless parent&.constants&.include?(const_name.to_sym)
|
676
|
+
|
559
677
|
removed_constant = parent.send(:remove_const, const_name)
|
560
678
|
yield
|
561
679
|
ensure
|
@@ -566,7 +684,7 @@ def with_debug_logging
|
|
566
684
|
orig_logger = NewRelic::Agent.logger
|
567
685
|
$stderr.puts '', '---', ''
|
568
686
|
NewRelic::Agent.logger =
|
569
|
-
NewRelic::Agent::AgentLogger.new('', Logger.new($stderr)
|
687
|
+
NewRelic::Agent::AgentLogger.new('', Logger.new($stderr))
|
570
688
|
|
571
689
|
with_config(:log_level => 'debug') do
|
572
690
|
yield
|
@@ -576,17 +694,17 @@ ensure
|
|
576
694
|
end
|
577
695
|
|
578
696
|
def create_agent_command(args = {})
|
579
|
-
NewRelic::Agent::Commands::AgentCommand.new([-1, {
|
697
|
+
NewRelic::Agent::Commands::AgentCommand.new([-1, {'name' => 'command_name', 'arguments' => args}])
|
580
698
|
end
|
581
699
|
|
582
|
-
def wait_for_backtrace_service_poll(opts={})
|
700
|
+
def wait_for_backtrace_service_poll(opts = {})
|
583
701
|
defaults = {
|
584
702
|
:timeout => 10.0,
|
585
|
-
:service => NewRelic::Agent.agent.agent_command_router.backtrace_service,
|
703
|
+
:service => NewRelic::Agent.agent.instance_variable_get(:@agent_command_router).backtrace_service,
|
586
704
|
:iterations => 1
|
587
705
|
}
|
588
706
|
opts = defaults.merge(opts)
|
589
|
-
deadline =
|
707
|
+
deadline = Process.clock_gettime(Process::CLOCK_REALTIME) + opts[:timeout]
|
590
708
|
|
591
709
|
service = opts[:service]
|
592
710
|
worker_loop = service.worker_loop
|
@@ -594,25 +712,25 @@ def wait_for_backtrace_service_poll(opts={})
|
|
594
712
|
|
595
713
|
until worker_loop.iterations > opts[:iterations]
|
596
714
|
sleep(0.01)
|
597
|
-
if
|
715
|
+
if Process.clock_gettime(Process::CLOCK_REALTIME) > deadline
|
598
716
|
raise "Timed out waiting #{opts[:timeout]} s for backtrace service poll\n" +
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
717
|
+
"Worker loop ran for #{opts[:service].worker_loop.iterations} iterations\n\n" +
|
718
|
+
Thread.list.map { |t|
|
719
|
+
"#{t.to_s}: newrelic_label: #{t[:newrelic_label].inspect}\n\n" +
|
720
|
+
(t.backtrace || []).join("\n\t")
|
721
|
+
}.join("\n\n")
|
604
722
|
end
|
605
723
|
end
|
606
724
|
end
|
607
725
|
|
608
|
-
def with_array_logger(level
|
726
|
+
def with_array_logger(level = :info)
|
609
727
|
orig_logger = NewRelic::Agent.logger
|
610
|
-
config = {
|
728
|
+
config = {:log_level => level}
|
611
729
|
logdev = ArrayLogDevice.new
|
612
730
|
override_logger = Logger.new(logdev)
|
613
731
|
|
614
732
|
with_config(config) do
|
615
|
-
NewRelic::Agent.logger = NewRelic::Agent::AgentLogger.new(
|
733
|
+
NewRelic::Agent.logger = NewRelic::Agent::AgentLogger.new('', override_logger)
|
616
734
|
yield
|
617
735
|
end
|
618
736
|
|
@@ -627,7 +745,7 @@ end
|
|
627
745
|
# a core bug in the JVM implementation of Ruby. Root cause was not
|
628
746
|
# discovered, but it was found that a combination of retrying and using
|
629
747
|
# mutex lock around the update operation was the only consistently working
|
630
|
-
# solution as the error continued to surface without the mutex and
|
748
|
+
# solution as the error continued to surface without the mutex and
|
631
749
|
# retry alone wasn't enough, either.
|
632
750
|
#
|
633
751
|
# JRUBY: oraclejdk8 + jruby-9.2.6.0
|
@@ -640,9 +758,9 @@ class EnvUpdater
|
|
640
758
|
@mutex = Mutex.new
|
641
759
|
end
|
642
760
|
|
643
|
-
# Will attempt the given block up to MAX_RETRIES before
|
761
|
+
# Will attempt the given block up to MAX_RETRIES before
|
644
762
|
# surfacing the exception down the chain.
|
645
|
-
def with_retry
|
763
|
+
def with_retry(retry_limit = MAX_RETRIES)
|
646
764
|
retries ||= 0
|
647
765
|
sleep(retries)
|
648
766
|
yield
|
@@ -651,19 +769,19 @@ class EnvUpdater
|
|
651
769
|
end
|
652
770
|
|
653
771
|
# Locks and updates the ENV
|
654
|
-
def safe_update
|
772
|
+
def safe_update(env)
|
655
773
|
with_retry do
|
656
774
|
@mutex.synchronize do
|
657
|
-
env.each{ |key, val| ENV[key] = val.to_s }
|
775
|
+
env.each { |key, val| ENV[key] = val.to_s }
|
658
776
|
end
|
659
777
|
end
|
660
778
|
end
|
661
779
|
|
662
780
|
# Locks and restores the ENV
|
663
|
-
def safe_restore
|
781
|
+
def safe_restore(old_env)
|
664
782
|
with_retry do
|
665
783
|
@mutex.synchronize do
|
666
|
-
old_env.each{ |key, val| val ? ENV[key] = val : ENV.delete(key) }
|
784
|
+
old_env.each { |key, val| val ? ENV[key] = val : ENV.delete(key) }
|
667
785
|
end
|
668
786
|
end
|
669
787
|
end
|
@@ -673,32 +791,32 @@ class EnvUpdater
|
|
673
791
|
@@instance ||= EnvUpdater.new
|
674
792
|
end
|
675
793
|
|
676
|
-
def self.safe_update
|
677
|
-
instance.safe_update
|
794
|
+
def self.safe_update(env)
|
795
|
+
instance.safe_update(env)
|
678
796
|
end
|
679
797
|
|
680
|
-
def self.safe_restore
|
681
|
-
instance.safe_restore
|
798
|
+
def self.safe_restore(old_env)
|
799
|
+
instance.safe_restore(old_env)
|
682
800
|
end
|
683
801
|
|
684
802
|
# Effectively saves current ENV settings for given env's key/values,
|
685
803
|
# runs given block, then restores ENV to original state before returning.
|
686
|
-
def self.inject
|
804
|
+
def self.inject(env, &block)
|
687
805
|
old_env = {}
|
688
|
-
env.each{ |key, val| old_env[key] = ENV[key] }
|
806
|
+
env.each { |key, val| old_env[key] = ENV[key] }
|
689
807
|
begin
|
690
808
|
safe_update(env)
|
691
809
|
yield
|
692
810
|
ensure
|
693
811
|
safe_restore(old_env)
|
694
812
|
end
|
695
|
-
end
|
813
|
+
end
|
696
814
|
|
697
815
|
# must call instance here to ensure only one @mutex for all threads.
|
698
816
|
instance
|
699
817
|
end
|
700
818
|
|
701
|
-
# Changes ENV settings to given and runs given block and restores ENV
|
819
|
+
# Changes ENV settings to given and runs given block and restores ENV
|
702
820
|
# to original values before returning.
|
703
821
|
def with_environment(env, &block)
|
704
822
|
EnvUpdater.inject(env) { yield }
|
@@ -727,7 +845,7 @@ ensure
|
|
727
845
|
end
|
728
846
|
|
729
847
|
def json_dump_and_encode(object)
|
730
|
-
Base64.encode64(
|
848
|
+
Base64.encode64(JSON.dump(object))
|
731
849
|
end
|
732
850
|
|
733
851
|
def get_last_analytics_event
|
@@ -753,15 +871,15 @@ def load_cross_agent_test(name)
|
|
753
871
|
test_file_path = File.join(cross_agent_tests_dir, "#{name}.json")
|
754
872
|
data = File.read(test_file_path)
|
755
873
|
data.gsub!('callCount', 'call_count')
|
756
|
-
data =
|
757
|
-
data.each { |testcase| testcase['testname'].
|
874
|
+
data = JSON.load(data)
|
875
|
+
data.each { |testcase| testcase['testname'].tr!(' ', '_') if String === testcase['testname'] }
|
758
876
|
data
|
759
877
|
end
|
760
878
|
|
761
879
|
def each_cross_agent_test(options)
|
762
|
-
options = {:dir => nil, :pattern =>
|
763
|
-
path = File.join
|
764
|
-
Dir.glob(path).each { |file| yield
|
880
|
+
options = {:dir => nil, :pattern => '*'}.update(options)
|
881
|
+
path = File.join([cross_agent_tests_dir, options[:dir], options[:pattern]].compact)
|
882
|
+
Dir.glob(path).each { |file| yield(file) }
|
765
883
|
end
|
766
884
|
|
767
885
|
def assert_event_attributes(event, test_name, expected_attributes, non_expected_attributes)
|
@@ -774,7 +892,7 @@ def assert_event_attributes(event, test_name, expected_attributes, non_expected_
|
|
774
892
|
incorrect_attributes << name unless actual_value == expected_value
|
775
893
|
end
|
776
894
|
|
777
|
-
msg = "Found missing or incorrect attribute values in #{test_name}:\n"
|
895
|
+
msg = +"Found missing or incorrect attribute values in #{test_name}:\n"
|
778
896
|
|
779
897
|
incorrect_attributes.each do |name|
|
780
898
|
msg << " #{name}: expected = #{expected_attributes[name].inspect}, actual = #{event_attrs[name].inspect}\n"
|
@@ -785,13 +903,125 @@ def assert_event_attributes(event, test_name, expected_attributes, non_expected_
|
|
785
903
|
event_attrs.each do |name, actual_value|
|
786
904
|
msg << " #{name}: #{actual_value.inspect}\n"
|
787
905
|
end
|
788
|
-
|
906
|
+
|
907
|
+
assert_empty(incorrect_attributes, msg)
|
789
908
|
|
790
909
|
non_expected_attributes.each do |name|
|
791
|
-
|
910
|
+
refute event_attrs[name], "Found value '#{event_attrs[name]}' for attribute '#{name}', but expected nothing in #{test_name}"
|
792
911
|
end
|
793
912
|
end
|
794
913
|
|
795
914
|
def attributes_for(sample, type)
|
796
915
|
sample.attributes.instance_variable_get("@#{type}_attributes")
|
797
916
|
end
|
917
|
+
|
918
|
+
def uncache_trusted_account_key
|
919
|
+
NewRelic::Agent::Transaction::TraceContext::AccountHelpers.instance_variable_set(:@trace_state_entry_key, nil)
|
920
|
+
end
|
921
|
+
|
922
|
+
def reset_buffers_and_caches
|
923
|
+
NewRelic::Agent.drop_buffered_data
|
924
|
+
uncache_trusted_account_key
|
925
|
+
end
|
926
|
+
|
927
|
+
def message_for_status_code(code)
|
928
|
+
# Net::HTTP::STATUS_CODES was introduced in Ruby 2.5
|
929
|
+
if defined?(Net::HTTP::STATUS_CODES)
|
930
|
+
return Net::HTTP::STATUS_CODES[code]
|
931
|
+
end
|
932
|
+
|
933
|
+
case code
|
934
|
+
when 200 then 'OK'
|
935
|
+
when 404 then 'Not Found'
|
936
|
+
when 403 then 'Forbidden'
|
937
|
+
else 'Unknown'
|
938
|
+
end
|
939
|
+
end
|
940
|
+
|
941
|
+
# wraps the given headers in a Net::HTTPResponse which has accompanying
|
942
|
+
# http status code associated with it.
|
943
|
+
# a "status_code" may be passed in the headers to alter the HTTP Status Code
|
944
|
+
# that is wrapped in the response.
|
945
|
+
def mock_http_response(headers, wrap_it = true)
|
946
|
+
status_code = (headers.delete('status_code') || 200).to_i
|
947
|
+
net_http_resp = Net::HTTPResponse.new(1.0, status_code, message_for_status_code(status_code))
|
948
|
+
headers.each do |key, value|
|
949
|
+
net_http_resp.add_field(key.to_s, value)
|
950
|
+
end
|
951
|
+
return net_http_resp unless wrap_it
|
952
|
+
|
953
|
+
NewRelic::Agent::HTTPClients::NetHTTPResponse.new(net_http_resp)
|
954
|
+
end
|
955
|
+
|
956
|
+
# +expected+ can be a string or regular expression
|
957
|
+
def assert_match_or_equal(expected, value)
|
958
|
+
if expected.is_a?(Regexp)
|
959
|
+
assert_match expected, value
|
960
|
+
else
|
961
|
+
assert_equal expected, value
|
962
|
+
end
|
963
|
+
end
|
964
|
+
|
965
|
+
# selects the last segment with a noticed_error and checks
|
966
|
+
# the expectations against it.
|
967
|
+
def assert_segment_noticed_error(txn, segment_name, error_classes, error_message)
|
968
|
+
error_segment = txn.segments.reverse.detect { |s| s.noticed_error }
|
969
|
+
|
970
|
+
assert error_segment, 'Expected at least one segment with a noticed_error'
|
971
|
+
|
972
|
+
assert_match_or_equal segment_name, error_segment.name
|
973
|
+
|
974
|
+
noticed_error = error_segment.noticed_error
|
975
|
+
|
976
|
+
assert_match_or_equal error_classes, noticed_error.exception_class_name
|
977
|
+
assert_match_or_equal error_message, noticed_error.message
|
978
|
+
end
|
979
|
+
|
980
|
+
def assert_transaction_noticed_error(txn, error_classes)
|
981
|
+
refute_empty txn.exceptions, 'Expected transaction to notice the error'
|
982
|
+
assert_match_or_equal error_classes, txn.exceptions.keys.first.class.name
|
983
|
+
end
|
984
|
+
|
985
|
+
def refute_transaction_noticed_error(txn, error_class)
|
986
|
+
error_segment = txn.segments.reverse.detect { |s| s.noticed_error }
|
987
|
+
|
988
|
+
assert error_segment, 'Expected at least one segment with a noticed_error'
|
989
|
+
assert_empty txn.exceptions, 'Expected transaction to NOT notice any segment errors'
|
990
|
+
end
|
991
|
+
|
992
|
+
def refute_raises(*exp)
|
993
|
+
msg = "#{exp.pop}.\n" if String === exp.last
|
994
|
+
|
995
|
+
begin
|
996
|
+
yield
|
997
|
+
rescue MiniTest::Skip => e
|
998
|
+
puts "SKIP REPORTS: #{e.inspect}"
|
999
|
+
return e if exp.include?(MiniTest::Skip)
|
1000
|
+
|
1001
|
+
raise e
|
1002
|
+
rescue Exception => e
|
1003
|
+
puts "EXCEPTION RAISED: #{e.inspect}\n#{e.backtrace}"
|
1004
|
+
exp = exp.first if exp.size == 1
|
1005
|
+
|
1006
|
+
flunk(msg || "unexpected exception raised: #{e}")
|
1007
|
+
end
|
1008
|
+
end
|
1009
|
+
|
1010
|
+
def assert_implements(instance, method, *args)
|
1011
|
+
fail_message = "expected #{instance.class}##{method} method to be implemented"
|
1012
|
+
refute_raises NotImplementedError, fail_message do
|
1013
|
+
instance.send(method, *args)
|
1014
|
+
end
|
1015
|
+
end
|
1016
|
+
|
1017
|
+
def defer_testing_to_min_supported_rails(test_file, min_rails_version, supports_jruby = true)
|
1018
|
+
if defined?(Rails) &&
|
1019
|
+
defined?(Rails::VERSION::STRING) &&
|
1020
|
+
(Rails::VERSION::STRING.to_f >= min_rails_version) &&
|
1021
|
+
(supports_jruby || !NewRelic::LanguageSupport.jruby?)
|
1022
|
+
|
1023
|
+
yield
|
1024
|
+
else
|
1025
|
+
puts "Skipping tests in #{File.basename(test_file)} because Rails >= #{min_rails_version} is unavailable" if ENV['VERBOSE_TEST_OUTPUT']
|
1026
|
+
end
|
1027
|
+
end
|