From bac69b5b232317d9b4b3fddeacb2b6766fe9fe21 Mon Sep 17 00:00:00 2001 From: Marco Costa Date: Mon, 22 Jun 2020 12:11:03 -0400 Subject: [PATCH] Deprecate Contrib::Configuration::Settings#tracer= (#1079) --- ddtrace.gemspec | 2 + docs/GettingStarted.md | 33 -------- .../contrib/active_support/cache/redis.rb | 2 +- .../active_support/notifications/event.rb | 4 +- .../context_composite_executor_service.rb | 12 ++- lib/ddtrace/contrib/configuration/settings.rb | 18 +++++ lib/ddtrace/contrib/graphql/patcher.rb | 9 ++- .../contrib/rails/configuration/settings.rb | 12 --- lib/ddtrace/contrib/rails/framework.rb | 35 ++++----- lib/ddtrace/tracer.rb | 4 +- .../action_cable/instrumentation_spec.rb | 14 ++-- .../contrib/action_cable/patcher_spec.rb | 13 ++-- .../active_model_serializers/patcher_spec.rb | 9 +-- .../contrib/active_record/multi_db_spec.rb | 15 ++-- .../contrib/active_record/performance_spec.rb | 6 +- .../contrib/active_record/tracer_spec.rb | 9 +-- .../notifications/subscription_spec.rb | 1 - spec/ddtrace/contrib/analytics_examples.rb | 39 +++------- .../contrib/aws/instrumentation_spec.rb | 6 +- .../concurrent_ruby/integration_test_spec.rb | 35 +++++---- .../contrib/configuration/settings_spec.rb | 9 +++ .../contrib/dalli/instrumentation_spec.rb | 19 ++--- spec/ddtrace/contrib/dalli/patcher_spec.rb | 3 +- .../contrib/delayed_job/plugin_spec.rb | 8 +- .../contrib/elasticsearch/patcher_spec.rb | 16 ++-- .../contrib/elasticsearch/transport_spec.rb | 6 +- spec/ddtrace/contrib/ethon/easy_patch_spec.rb | 9 +-- .../contrib/ethon/integration_context.rb | 5 +- .../ddtrace/contrib/ethon/multi_patch_spec.rb | 16 ++-- spec/ddtrace/contrib/ethon/shared_examples.rb | 6 +- .../ethon/typhoeus_integration_spec.rb | 5 +- .../contrib/excon/instrumentation_spec.rb | 8 +- .../contrib/faraday/middleware_spec.rb | 6 +- spec/ddtrace/contrib/faraday/patcher_spec.rb | 3 +- spec/ddtrace/contrib/graphql/tracer_spec.rb | 1 - .../grpc/datadog_interceptor/client_spec.rb | 11 ++- .../grpc/datadog_interceptor/server_spec.rb | 5 +- .../contrib/grpc/integration_test_spec.rb | 12 +-- .../contrib/grpc/interception_context_spec.rb | 5 +- spec/ddtrace/contrib/grpc/patcher_spec.rb | 3 +- .../contrib/http/circuit_breaker_spec.rb | 5 +- spec/ddtrace/contrib/http/miniapp_spec.rb | 5 +- spec/ddtrace/contrib/http/patcher_spec.rb | 7 +- spec/ddtrace/contrib/http/request_spec.rb | 5 +- spec/ddtrace/contrib/mongodb/client_spec.rb | 22 ++---- spec/ddtrace/contrib/mysql2/patcher_spec.rb | 6 +- spec/ddtrace/contrib/presto/client_spec.rb | 23 +++--- spec/ddtrace/contrib/racecar/patcher_spec.rb | 11 +-- .../contrib/rack/configuration_spec.rb | 6 +- spec/ddtrace/contrib/rack/distributed_spec.rb | 6 +- .../contrib/rack/integration_test_spec.rb | 6 +- spec/ddtrace/contrib/rack/middleware_spec.rb | 3 +- .../contrib/rack/resource_name_spec.rb | 7 +- .../contrib/rails/action_controller_spec.rb | 19 ++--- spec/ddtrace/contrib/rails/analytics_spec.rb | 6 +- spec/ddtrace/contrib/rails/cache_spec.rb | 3 + spec/ddtrace/contrib/rails/database_spec.rb | 6 +- spec/ddtrace/contrib/rails/defaults_spec.rb | 4 +- spec/ddtrace/contrib/rails/middleware_spec.rb | 2 +- .../contrib/rails/rails_active_job_spec.rb | 2 - .../ddtrace/contrib/rails/redis_cache_spec.rb | 6 +- .../contrib/rails/support/application.rb | 9 +-- .../contrib/rake/instrumentation_spec.rb | 5 +- .../contrib/redis/instrumentation_spec.rb | 24 +++--- .../contrib/redis/integration_test_spec.rb | 15 ++-- spec/ddtrace/contrib/redis/miniapp_spec.rb | 18 ++--- spec/ddtrace/contrib/redis/redis_spec.rb | 35 +++------ .../contrib/resque/instrumentation_spec.rb | 8 +- .../contrib/rest_client/request_patch_spec.rb | 15 +--- .../contrib/sequel/configuration_spec.rb | 14 ++-- .../contrib/sequel/instrumentation_spec.rb | 7 +- spec/ddtrace/contrib/shoryuken/tracer_spec.rb | 6 +- .../contrib/sinatra/activerecord_spec.rb | 6 +- .../ddtrace/contrib/sinatra/multi_app_spec.rb | 6 +- spec/ddtrace/contrib/sinatra/tracer_spec.rb | 4 +- spec/ddtrace/contrib/support/spec_helper.rb | 14 ++++ .../ddtrace/contrib/support/tracer_helpers.rb | 73 ++++++++++++++++++ spec/ddtrace/integration_spec.rb | 4 +- spec/ddtrace/sync_writer_spec.rb | 16 +--- spec/ddtrace/writer_spec.rb | 16 +--- spec/support/tracer_helpers.rb | 8 +- test/contrib/grape/app.rb | 6 -- test/contrib/grape/rack_app.rb | 23 +++--- test/contrib/grape/rack_integration_test.rb | 3 - test/contrib/grape/request_test.rb | 19 ++++- test/contrib/rails/apps/rails3.rb | 21 +++-- test/contrib/rails/apps/rails4.rb | 8 +- test/contrib/rails/apps/rails5.rb | 8 +- test/contrib/rails/apps/rails6.rb | 9 ++- test/contrib/rails/controller_test.rb | 34 ++------- test/contrib/rails/errors_test.rb | 21 +---- test/contrib/rails/rack_middleware_test.rb | 23 +----- test/contrib/rails/test_helper.rb | 45 +++++++++++ test/contrib/rails/utils_test.rb | 21 +++-- test/contrib/sidekiq/client_tracer_test.rb | 9 +-- test/contrib/sidekiq/disabled_tracer_test.rb | 5 +- test/contrib/sidekiq/server_tracer_test.rb | 20 ++--- test/contrib/sidekiq/tracer_configure_test.rb | 5 +- test/contrib/sidekiq/tracer_test_base.rb | 13 +++- test/contrib/sucker_punch/patcher_test.rb | 35 ++++----- test/helper.rb | 76 +++++++++++++++++++ 101 files changed, 627 insertions(+), 674 deletions(-) create mode 100644 spec/ddtrace/contrib/support/tracer_helpers.rb diff --git a/ddtrace.gemspec b/ddtrace.gemspec index e961139373c..e2eb3ee9153 100644 --- a/ddtrace.gemspec +++ b/ddtrace.gemspec @@ -46,6 +46,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'rspec', '~> 3.0' spec.add_development_dependency 'rspec-collection_matchers', '~> 1.1' spec.add_development_dependency 'minitest', '= 5.10.1' + spec.add_development_dependency 'minitest-around', '0.5.0' + spec.add_development_dependency 'minitest-stub_any_instance', '1.0.2' spec.add_development_dependency 'appraisal', '~> 2.2' spec.add_development_dependency 'yard', '~> 0.9' spec.add_development_dependency 'webmock', '~> 2.0' diff --git a/docs/GettingStarted.md b/docs/GettingStarted.md index be3555e6155..5150c01e17f 100644 --- a/docs/GettingStarted.md +++ b/docs/GettingStarted.md @@ -381,7 +381,6 @@ Where `options` is an optional `Hash` that accepts the following parameters: | --- | ----------- | ------- | | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` | | `service_name` | Service name used for `action_cable` instrumentation | `'action_cable'` | -| `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually you don't need to set this. | `Datadog.tracer` | ### Action View @@ -402,7 +401,6 @@ Where `options` is an optional `Hash` that accepts the following parameters: | ---| --- | --- | | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` | | `service_name` | Service name used for rendering instrumentation. | `action_view` | -| `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually you don't need to set this. | `Datadog.tracer` | | `template_base_path` | Used when the template name is parsed. If you don't store your templates in the `views/` folder, you may need to change this value | `'views/'` | ### Active Model Serializers @@ -425,7 +423,6 @@ ActiveModelSerializers::SerializableResource.new(test_obj).serializable_hash | --- | ----------- | ------- | | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` | | `service_name` | Service name used for `active_model_serializers` instrumentation. | `'active_model_serializers'` | -| `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually you don't need to set this. | `Datadog.tracer` | ### Action Pack @@ -446,7 +443,6 @@ Where `options` is an optional `Hash` that accepts the following parameters: | ---| --- | --- | | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` | | `service_name` | Service name used for rendering instrumentation. | `action_pack` | -| `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually you don't need to set this. | `Datadog.tracer` | ### Active Record @@ -476,7 +472,6 @@ Where `options` is an optional `Hash` that accepts the following parameters: | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to the global setting, `false` for off. | `false` | | `orm_service_name` | Service name used for the Ruby ORM portion of `active_record` instrumentation. Overrides service name for ORM spans if explicitly set, which otherwise inherit their service from their parent. | `'active_record'` | | `service_name` | Service name used for database portion of `active_record` instrumentation. | Name of database adapter (e.g. `'mysql2'`) | -| `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually, you don't need to set this. | `Datadog.tracer` | **Configuring trace settings per database** @@ -538,7 +533,6 @@ Where `options` is an optional `Hash` that accepts the following parameters: | ---| --- | --- | | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` | | `cache_service` | Service name used for caching with `active_support` instrumentation. | `active_support-cache` | -| `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually you don't need to set this. | `Datadog.tracer` | ### AWS @@ -562,7 +556,6 @@ Where `options` is an optional `Hash` that accepts the following parameters: | --- | ----------- | ------- | | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` | | `service_name` | Service name used for `aws` instrumentation | `'aws'` | -| `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually you don't need to set this. | `Datadog.tracer` | ### Concurrent Ruby @@ -589,7 +582,6 @@ Where `options` is an optional `Hash` that accepts the following parameters: | Key | Description | Default | | --- | ----------- | ------- | | `service_name` | Service name used for `concurrent-ruby` instrumentation | `'concurrent-ruby'` | -| `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually you don't need to set this. | `Datadog.tracer` | ### Dalli @@ -615,7 +607,6 @@ Where `options` is an optional `Hash` that accepts the following parameters: | --- | ----------- | ------- | | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` | | `service_name` | Service name used for `dalli` instrumentation | `'memcached'` | -| `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually you don't need to set this. | `Datadog.tracer` | ### DelayedJob @@ -637,7 +628,6 @@ Where `options` is an optional `Hash` that accepts the following parameters: | --- | ----------- | ------- | | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` | | `service_name` | Service name used for `DelayedJob` instrumentation | `'delayed_job'` | -| `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually you don't need to set this. | `Datadog.tracer` | ### Elasticsearch @@ -663,7 +653,6 @@ Where `options` is an optional `Hash` that accepts the following parameters: | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` | | `quantize` | Hash containing options for quantization. May include `:show` with an Array of keys to not quantize (or `:all` to skip quantization), or `:exclude` with Array of keys to exclude entirely. | `{}` | | `service_name` | Service name used for `elasticsearch` instrumentation | `'elasticsearch'` | -| `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually you don't need to set this. | `Datadog.tracer` | ### Ethon @@ -691,7 +680,6 @@ Where `options` is an optional `Hash` that accepts the following parameters: | `distributed_tracing` | Enables [distributed tracing](#distributed-tracing) | `true` | | `service_name` | Service name for `ethon` instrumentation. | `'ethon'` | | `split_by_domain` | Uses the request domain as the service name when set to `true`. | `false` | -| `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually you don't need to set this. | `Datadog.tracer` | ### Excon @@ -725,7 +713,6 @@ Where `options` is an optional `Hash` that accepts the following parameters: | `error_handler` | A `Proc` that accepts a `response` parameter. If it evaluates to a *truthy* value, the trace span is marked as an error. By default only sets 5XX responses as errors. | `nil` | | `service_name` | Service name for Excon instrumentation. When provided to middleware for a specific connection, it applies only to that connection object. | `'excon'` | | `split_by_domain` | Uses the request domain as the service name when set to `true`. | `false` | -| `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually you don't need to set this. | `Datadog.tracer` | **Configuring connections to use different settings** @@ -789,7 +776,6 @@ Where `options` is an optional `Hash` that accepts the following parameters: | `error_handler` | A `Proc` that accepts a `response` parameter. If it evaluates to a *truthy* value, the trace span is marked as an error. By default only sets 5XX responses as errors. | `nil` | | `service_name` | Service name for Faraday instrumentation. When provided to middleware for a specific connection, it applies only to that connection object. | `'faraday'` | | `split_by_domain` | Uses the request domain as the service name when set to `true`. | `false` | -| `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually, you don't need to set this. | `Datadog.tracer` | ### Grape @@ -822,7 +808,6 @@ Where `options` is an optional `Hash` that accepts the following parameters: | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `nil` | | `enabled` | Defines whether Grape should be traced. Useful for temporarily disabling tracing. `true` or `false` | `true` | | `service_name` | Service name used for `grape` instrumentation | `'grape'` | -| `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually you don't need to set this. | `Datadog.tracer` | ### GraphQL @@ -847,7 +832,6 @@ The `use :graphql` method accepts the following parameters. Additional options c | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `nil` | | `service_name` | Service name used for `graphql` instrumentation | `'ruby-graphql'` | | `schemas` | Required. Array of `GraphQL::Schema` objects which to trace. Tracing will be added to all the schemas listed, using the options provided to this configuration. If you do not provide any, then tracing will not be activated. | `[]` | -| `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually you don't need to set this. | `Datadog.tracer` | **Manually configuring GraphQL schemas** @@ -926,7 +910,6 @@ Where `options` is an optional `Hash` that accepts the following parameters: | --- | ----------- | ------- | | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` | | `service_name` | Service name used for `grpc` instrumentation | `'grpc'` | -| `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually you don't need to set this. | `Datadog.tracer` | **Configuring clients to use different settings** @@ -974,7 +957,6 @@ Where `options` is an optional `Hash` that accepts the following parameters: | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` | | `quantize` | Hash containing options for quantization. May include `:show` with an Array of keys to not quantize (or `:all` to skip quantization), or `:exclude` with Array of keys to exclude entirely. | `{ show: [:collection, :database, :operation] }` | | `service_name` | Service name used for `mongo` instrumentation | `'mongodb'` | -| `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually you don't need to set this. | `Datadog.tracer` | ### MySQL2 @@ -998,7 +980,6 @@ Where `options` is an optional `Hash` that accepts the following parameters: | --- | ----------- | ------- | | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` | | `service_name` | Service name used for `mysql2` instrumentation | `'mysql2'` | -| `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually you don't need to set this. | `Datadog.tracer` | ### Net/HTTP @@ -1034,7 +1015,6 @@ Where `options` is an optional `Hash` that accepts the following parameters: | `distributed_tracing` | Enables [distributed tracing](#distributed-tracing) | `true` | | `service_name` | Service name used for `http` instrumentation | `'net/http'` | | `split_by_domain` | Uses the request domain as the service name when set to `true`. | `false` | -| `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually you don't need to set this. | `Datadog.tracer` | If you wish to configure each connection object individually, you may use the `Datadog.configure` as it follows: @@ -1074,7 +1054,6 @@ Where `options` is an optional `Hash` that accepts the following parameters: | --- | ----------- | ------- | | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` | | `service_name` | Service name used for `presto` instrumentation | `'presto'` | -| `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually you don't need to set this. | `Datadog.tracer` | ### Racecar @@ -1096,7 +1075,6 @@ Where `options` is an optional `Hash` that accepts the following parameters: | --- | ----------- | ------- | | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` | | `service_name` | Service name used for `racecar` instrumentation | `'racecar'` | -| `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually you don't need to set this. | `Datadog.tracer` | ### Rack @@ -1137,7 +1115,6 @@ Where `options` is an optional `Hash` that accepts the following parameters: | `quantize.fragment` | Defines behavior for URL fragments. Removes fragments by default. May be `:show` to show URL fragments. Option must be nested inside the `quantize` option. | `nil` | | `request_queuing` | Track HTTP request time spent in the queue of the frontend server. See [HTTP request queuing](#http-request-queuing) for setup details. Set to `true` to enable. | `false` | | `service_name` | Service name used for `rack` instrumentation | `'rack'` | -| `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually you don't need to set this. | `Datadog.tracer` | | `web_service_name` | Service name for frontend server request queuing spans. (e.g. `'nginx'`) | `'web-server'` | @@ -1200,7 +1177,6 @@ Where `options` is an optional `Hash` that accepts the following parameters: | `middleware_names` | Enables any short-circuited middleware requests to display the middleware name as a resource for the trace. | `false` | | `service_name` | Service name used when tracing application requests (on the `rack` level) | `''` (inferred from your Rails application namespace) | | `template_base_path` | Used when the template name is parsed. If you don't store your templates in the `views/` folder, you may need to change this value | `'views/'` | -| `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually, you don't need to set this. | `Datadog.tracer` | **Supported versions** @@ -1243,7 +1219,6 @@ Where `options` is an optional `Hash` that accepts the following parameters: | `enabled` | Defines whether Rake tasks should be traced. Useful for temporarily disabling tracing. `true` or `false` | `true` | | `quantize` | Hash containing options for quantization of task arguments. See below for more details and examples. | `{}` | | `service_name` | Service name used for `rake` instrumentation | `'rake'` | -| `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually, you don't need to set this. | `Datadog.tracer` | **Configuring task quantization behavior** @@ -1302,7 +1277,6 @@ Where `options` is an optional `Hash` that accepts the following parameters: | --- | ----------- | ------- | | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` | | `service_name` | Service name used for `redis` instrumentation | `'redis'` | -| `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually you don't need to set this. | `Datadog.tracer` | You can also set *per-instance* configuration as it follows: @@ -1379,7 +1353,6 @@ Where `options` is an optional `Hash` that accepts the following parameters: | --- | ----------- | ------- | | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to the global setting, `false` for off. | `false` | | `service_name` | Service name used for `resque` instrumentation | `'resque'` | -| `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually, you don't need to set this. | `Datadog.tracer` | | `workers` | An array including all worker classes you want to trace (e.g. `[MyJob]`) | `[]` | ### Rest Client @@ -1402,7 +1375,6 @@ Where `options` is an optional `Hash` that accepts the following parameters: | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` | | `distributed_tracing` | Enables [distributed tracing](#distributed-tracing) | `true` | | `service_name` | Service name for `rest_client` instrumentation. | `'rest_client'` | -| `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually you don't need to set this. | `Datadog.tracer` | ### Sequel @@ -1436,7 +1408,6 @@ Where `options` is an optional `Hash` that accepts the following parameters: | --- | ----------- | ------- | | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` | | `service_name` | Service name for `sequel` instrumentation | Name of database adapter (e.g. `'mysql2'`) | -| `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually you don't need to set this. | `Datadog.tracer` | Only Ruby 2.0+ is supported. @@ -1473,7 +1444,6 @@ Where `options` is an optional `Hash` that accepts the following parameters: | --- | ----------- | ------- | | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` | | `service_name` | Service name used for `shoryuken` instrumentation | `'shoryuken'` | -| `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually you don't need to set this. | `Datadog.tracer` | ### Sidekiq @@ -1497,7 +1467,6 @@ Where `options` is an optional `Hash` that accepts the following parameters: | `client_service_name` | Service name used for client-side `sidekiq` instrumentation | `'sidekiq-client'` | | `service_name` | Service name used for server-side `sidekiq` instrumentation | `'sidekiq'` | | `tag_args` | Enable tagging of job arguments. `true` for on, `false` for off. | `false` | -| `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually you don't need to set this. | `Datadog.tracer` | ### Sinatra @@ -1562,7 +1531,6 @@ Ensure you register `Datadog::Contrib::Sinatra::Tracer` as a middleware before y | `headers` | Hash of HTTP request or response headers to add as tags to the `sinatra.request`. Accepts `request` and `response` keys with Array values e.g. `['Last-Modified']`. Adds `http.request.headers.*` and `http.response.headers.*` tags respectively. | `{ response: ['Content-Type', 'X-Request-ID'] }` | | `resource_script_names` | Prepend resource names with script name | `false` | | `service_name` | Service name used for `sinatra` instrumentation | `'sinatra'` | -| `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually you don't need to set this. | `Datadog.tracer` | ### Sucker Punch @@ -1585,7 +1553,6 @@ Where `options` is an optional `Hash` that accepts the following parameters: | --- | ----------- | ------- | | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` | | `service_name` | Service name used for `sucker_punch` instrumentation | `'sucker_punch'` | -| `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually you don't need to set this. | `Datadog.tracer` | ## Advanced configuration diff --git a/lib/ddtrace/contrib/active_support/cache/redis.rb b/lib/ddtrace/contrib/active_support/cache/redis.rb index 1e31dc77da8..406dced1d30 100644 --- a/lib/ddtrace/contrib/active_support/cache/redis.rb +++ b/lib/ddtrace/contrib/active_support/cache/redis.rb @@ -14,7 +14,7 @@ module Patcher # We need to do a per-method monkey patching as some of them might # be redefined, and some of them not. The latest version of redis-activesupport # redefines write but leaves untouched read and delete: - # https://github.com/redis-store/redis-activesupport/blob/master/lib/active_support/cache/redis_store.rb + # https://github.com/redis-store/redis-activesupport/blob/v4.1.5/lib/active_support/cache/redis_store.rb # # For Rails >= 5.2 w/o redis-activesupport... # ActiveSupport includes a Redis cache store internally, and does not require these overrides. diff --git a/lib/ddtrace/contrib/active_support/notifications/event.rb b/lib/ddtrace/contrib/active_support/notifications/event.rb index bfcda011ae8..c66fd3358d6 100644 --- a/lib/ddtrace/contrib/active_support/notifications/event.rb +++ b/lib/ddtrace/contrib/active_support/notifications/event.rb @@ -18,6 +18,8 @@ def self.included(base) # Redefines some class behaviors for a Subscriber to make # it a bit simpler for an Event. module ClassMethods + DEFAULT_TRACER = -> { Datadog.tracer } + def subscribe! super end @@ -52,7 +54,7 @@ def span_options end def tracer - Datadog.tracer + DEFAULT_TRACER end end end diff --git a/lib/ddtrace/contrib/concurrent_ruby/context_composite_executor_service.rb b/lib/ddtrace/contrib/concurrent_ruby/context_composite_executor_service.rb index 9f2eb15f26a..d1494b67d34 100644 --- a/lib/ddtrace/contrib/concurrent_ruby/context_composite_executor_service.rb +++ b/lib/ddtrace/contrib/concurrent_ruby/context_composite_executor_service.rb @@ -16,11 +16,17 @@ def initialize(composited_executor) # post method runs the task within composited executor - in a different thread def post(*args, &task) - context = datadog_configuration.tracer.provider.context + parent_context = datadog_configuration.tracer.provider.context @composited_executor.post(*args) do - datadog_configuration.tracer.provider.context = context - yield + begin + original_context = datadog_configuration.tracer.provider.context + datadog_configuration.tracer.provider.context = parent_context + yield + ensure + # Restore context in case the current thread gets reused + datadog_configuration.tracer.provider.context = original_context + end end end diff --git a/lib/ddtrace/contrib/configuration/settings.rb b/lib/ddtrace/contrib/configuration/settings.rb index 456679b1e3f..6c6a4c07c6a 100644 --- a/lib/ddtrace/contrib/configuration/settings.rb +++ b/lib/ddtrace/contrib/configuration/settings.rb @@ -12,6 +12,9 @@ class Settings option :service_name option :tracer do |o| o.delegate_to { Datadog.tracer } + o.on_set do |_value| + log_deprecation_warning(:tracer) + end end def configure(options = {}) @@ -29,6 +32,21 @@ def [](name) def []=(name, value) respond_to?("#{name}=") ? send("#{name}=", value) : set_option(name, value) end + + DEPRECATION_WARNING = %( + Explicitly providing a tracer instance is DEPRECATED. + It's recommended to not provide an explicit tracer instance + and let Datadog::Contrib::Configuration::Settings resolve + the correct tracer internally. + ).freeze + + include Datadog::Patcher # DEV includes #do_once here. We should move that logic to a generic component. + + def log_deprecation_warning(method_name) + do_once(method_name) do + Datadog.logger.warn("#{method_name}:#{DEPRECATION_WARNING}:#{caller.join("\n")}") + end + end end end end diff --git a/lib/ddtrace/contrib/graphql/patcher.rb b/lib/ddtrace/contrib/graphql/patcher.rb index ffb2da4a8c4..c18f3732123 100644 --- a/lib/ddtrace/contrib/graphql/patcher.rb +++ b/lib/ddtrace/contrib/graphql/patcher.rb @@ -22,7 +22,6 @@ def patch end def patch_schema!(schema) - tracer = get_option(:tracer) service_name = get_option(:service_name) analytics_enabled = Contrib::Analytics.enabled?(get_option(:analytics_enabled)) analytics_sample_rate = get_option(:analytics_sample_rate) @@ -30,7 +29,9 @@ def patch_schema!(schema) if schema.respond_to?(:use) schema.use( ::GraphQL::Tracing::DataDogTracing, - tracer: tracer, + # By default, Tracing::DataDogTracing indirectly delegates the tracer instance + # to +Datadog.tracer+. If we provide a tracer argument here it will be eagerly cached, + # and Tracing::DataDogTracing will send traces to a stale tracer instance. service: service_name, analytics_enabled: analytics_enabled, analytics_sample_rate: analytics_sample_rate @@ -39,7 +40,9 @@ def patch_schema!(schema) schema.define do use( ::GraphQL::Tracing::DataDogTracing, - tracer: tracer, + # By default, Tracing::DataDogTracing indirectly delegates the tracer instance + # to +Datadog.tracer+. If we provide a tracer argument here it will be eagerly cached, + # and Tracing::DataDogTracing will send traces to a stale tracer instance. service: service_name, analytics_enabled: analytics_enabled, analytics_sample_rate: analytics_sample_rate diff --git a/lib/ddtrace/contrib/rails/configuration/settings.rb b/lib/ddtrace/contrib/rails/configuration/settings.rb index 1c1ae8af21a..6c382c41ab0 100644 --- a/lib/ddtrace/contrib/rails/configuration/settings.rb +++ b/lib/ddtrace/contrib/rails/configuration/settings.rb @@ -76,18 +76,6 @@ def initialize(options = {}) Datadog.configuration[:action_view][:template_base_path] = value end end - - option :tracer do |o| - o.delegate_to { Datadog.tracer } - o.on_set do |value| - Datadog.configuration[:action_cable][:tracer] = value - Datadog.configuration[:active_record][:tracer] = value - Datadog.configuration[:active_support][:tracer] = value - Datadog.configuration[:action_pack][:tracer] = value - Datadog.configuration[:action_view][:tracer] = value - Datadog.configuration[:rack][:tracer] = value - end - end end end end diff --git a/lib/ddtrace/contrib/rails/framework.rb b/lib/ddtrace/contrib/rails/framework.rb index 097f2b7e66a..793795f323b 100644 --- a/lib/ddtrace/contrib/rails/framework.rb +++ b/lib/ddtrace/contrib/rails/framework.rb @@ -19,10 +19,12 @@ module Rails # - handle configuration entries which are specific to Datadog tracing # - instrument parts of the framework when needed module Framework - # configure Datadog settings + # After the Rails application finishes initializing, we configure the Rails + # integration and all its sub-components with the application information + # available. + # We do this after the initialization because not all the information we + # require is available before then. def self.setup - rails_config = config_with_defaults - # NOTE: #configure has the side effect of rebuilding trace components. # During a typical Rails application lifecycle, we will see trace # components initialized twice because of this. This is necessary @@ -31,6 +33,8 @@ def self.setup # used to reconfigure tracer components with Rails-sourced defaults. # This is a trade-off we take to get nice defaults. Datadog.configure do |datadog_config| + rails_config = config_with_defaults(datadog_config) + # By default, default service would be guessed from the script # being executed, but here we know better, get it from Rails config. # Don't set this if service has been explicitly provided by the user. @@ -43,17 +47,12 @@ def self.setup activate_action_view!(datadog_config, rails_config) activate_active_record!(datadog_config, rails_config) end - - # Update the tracer if its not the default tracer. - if rails_config[:tracer] != Datadog.configuration.tracer - rails_config[:tracer].default_service = rails_config[:service_name] - end end - def self.config_with_defaults + def self.config_with_defaults(datadog_config) # We set defaults here instead of in the patcher because we need to wait # for the Rails application to be fully initialized. - Datadog.configuration[:rails].tap do |config| + datadog_config[:rails].tap do |config| config[:service_name] ||= (Datadog.configuration.service || Utils.app_name) config[:database_service] ||= "#{config[:service_name]}-#{Contrib::ActiveRecord::Utils.adapter_name}" config[:controller_service] ||= config[:service_name] @@ -64,7 +63,6 @@ def self.config_with_defaults def self.activate_rack!(datadog_config, rails_config) datadog_config.use( :rack, - tracer: rails_config[:tracer], application: ::Rails.application, service_name: rails_config[:service_name], middleware_names: rails_config[:middleware_names], @@ -77,8 +75,7 @@ def self.activate_active_support!(datadog_config, rails_config) datadog_config.use( :active_support, - cache_service: rails_config[:cache_service], - tracer: rails_config[:tracer] + cache_service: rails_config[:cache_service] ) end @@ -87,8 +84,7 @@ def self.activate_action_cable!(datadog_config, rails_config) datadog_config.use( :action_cable, - service_name: "#{rails_config[:service_name]}-#{Contrib::ActionCable::Ext::SERVICE_NAME}", - tracer: rails_config[:tracer] + service_name: "#{rails_config[:service_name]}-#{Contrib::ActionCable::Ext::SERVICE_NAME}" ) end @@ -101,8 +97,7 @@ def self.activate_action_pack!(datadog_config, rails_config) datadog_config.use( :action_pack, - service_name: rails_config[:service_name], - tracer: rails_config[:tracer] + service_name: rails_config[:service_name] ) end @@ -111,8 +106,7 @@ def self.activate_action_view!(datadog_config, rails_config) datadog_config.use( :action_view, - service_name: rails_config[:service_name], - tracer: rails_config[:tracer] + service_name: rails_config[:service_name] ) end @@ -121,8 +115,7 @@ def self.activate_active_record!(datadog_config, rails_config) datadog_config.use( :active_record, - service_name: rails_config[:database_service], - tracer: rails_config[:tracer] + service_name: rails_config[:database_service] ) end end diff --git a/lib/ddtrace/tracer.rb b/lib/ddtrace/tracer.rb index ac930ee52d4..338c009921b 100644 --- a/lib/ddtrace/tracer.rb +++ b/lib/ddtrace/tracer.rb @@ -314,7 +314,7 @@ def record(context) def record_context(context) trace = @context_flush.consume!(context) - write(trace) if trace && !trace.empty? + write(trace) if @enabled && trace && !trace.empty? end # Return the current active span or +nil+. @@ -335,7 +335,7 @@ def active_correlation # Send the trace to the writer to enqueue the spans list in the agent # sending queue. def write(trace) - return if @writer.nil? || !@enabled + return if @writer.nil? if Datadog.configuration.diagnostics.debug Datadog.logger.debug("Writing #{trace.length} spans (enabled: #{@enabled})") diff --git a/spec/ddtrace/contrib/action_cable/instrumentation_spec.rb b/spec/ddtrace/contrib/action_cable/instrumentation_spec.rb index 2fdfe635eee..32583e13305 100644 --- a/spec/ddtrace/contrib/action_cable/instrumentation_spec.rb +++ b/spec/ddtrace/contrib/action_cable/instrumentation_spec.rb @@ -16,10 +16,7 @@ include Rack::Test::Methods include_context 'Rails test application' - let(:tracer) { get_test_tracer } - let(:spans) { tracer.writer.spans(:keep) } - - let(:options) { { tracer: tracer } } + let(:options) { {} } before do Datadog.configure do |c| @@ -46,8 +43,13 @@ subject! { get '/cable' } it 'overrides parent Rack resource' do - expect(span.name).to eq('rack.request') - expect(span.resource).to eq('ActionCable::Connection::Base#on_open') + action_cable, rack = spans + + expect(action_cable.name).to eq('action_cable.on_open') + expect(action_cable.resource).to eq('ActionCable::Connection::Base#on_open') + + expect(rack.name).to eq('rack.request') + expect(rack.resource).to eq('ActionCable::Connection::Base#on_open') end end end diff --git a/spec/ddtrace/contrib/action_cable/patcher_spec.rb b/spec/ddtrace/contrib/action_cable/patcher_spec.rb index 6c4716b8c01..7e1214923e0 100644 --- a/spec/ddtrace/contrib/action_cable/patcher_spec.rb +++ b/spec/ddtrace/contrib/action_cable/patcher_spec.rb @@ -15,8 +15,7 @@ RSpec.describe 'ActionCable patcher' do before { skip('ActionCable not supported') unless Datadog::Contrib::ActionCable::Integration.compatible? } - let(:tracer) { get_test_tracer } - let(:configuration_options) { { tracer: tracer } } + let(:configuration_options) { {} } before do Datadog.configure do |c| @@ -31,11 +30,9 @@ Datadog.registry[:action_cable].reset_configuration! end - let(:all_spans) { tracer.writer.spans(:keep) } - let(:span) do - expect(all_spans).to have(1).item - all_spans.find { |s| s.service == 'action_cable' } + expect(spans).to have(1).item + spans.find { |s| s.service == 'action_cable' } end context 'with server' do @@ -135,12 +132,12 @@ def foo(data) end) end - let(:span) { all_spans.last } # Skip 'perform_action' span + let(:span) { spans.last } # Skip 'perform_action' span it 'traces transmit event' do perform - expect(all_spans).to have(2).items + expect(spans).to have(2).items expect(span.service).to eq('action_cable') expect(span.name).to eq('action_cable.transmit') expect(span.span_type).to eq('web') diff --git a/spec/ddtrace/contrib/active_model_serializers/patcher_spec.rb b/spec/ddtrace/contrib/active_model_serializers/patcher_spec.rb index 45a19a49553..58a3d15efd3 100644 --- a/spec/ddtrace/contrib/active_model_serializers/patcher_spec.rb +++ b/spec/ddtrace/contrib/active_model_serializers/patcher_spec.rb @@ -11,12 +11,7 @@ RSpec.describe 'ActiveModelSerializers patcher' do include_context 'AMS serializer' - let(:tracer) { get_test_tracer } - let(:configuration_options) { { tracer: tracer } } - - def all_spans - tracer.writer.spans(:keep) - end + let(:configuration_options) { {} } before(:each) do # Supress active_model_serializers log output in the test run @@ -56,7 +51,7 @@ def all_spans end let(:active_model_serializers_span) do - all_spans.select { |s| s.name == name }.first + spans.select { |s| s.name == name }.first end if ActiveModelSerializersHelpers.ams_0_10_or_newer? diff --git a/spec/ddtrace/contrib/active_record/multi_db_spec.rb b/spec/ddtrace/contrib/active_record/multi_db_spec.rb index a5b26f0a830..ad9cc52b7a6 100644 --- a/spec/ddtrace/contrib/active_record/multi_db_spec.rb +++ b/spec/ddtrace/contrib/active_record/multi_db_spec.rb @@ -6,8 +6,7 @@ require 'sqlite3' RSpec.describe 'ActiveRecord multi-database implementation' do - let(:tracer) { get_test_tracer } - let(:configuration_options) { { tracer: tracer, service_name: default_db_service_name } } + let(:configuration_options) { { service_name: default_db_service_name } } let(:default_db_service_name) { 'default-db' } let(:mysql) do @@ -71,10 +70,9 @@ def mysql_connection_string end end - subject(:spans) do + subject(:count) do gadget_class.count widget_class.count - tracer.writer.spans end let(:gadget_span) { spans[0] } @@ -133,18 +131,17 @@ def mysql_connection_string Datadog.configure do |c| c.use :active_record, describes: :gadget do |gadget_db| - gadget_db.tracer = tracer gadget_db.service_name = gadget_db_service_name end c.use :active_record, describes: :widget do |widget_db| - widget_db.tracer = tracer widget_db.service_name = widget_db_service_name end end end it do + count # Gadget is configured to show up as its own database service expect(gadget_span.service).to eq(gadget_db_service_name) # Widget is configured to show up as its own database service @@ -158,13 +155,13 @@ def mysql_connection_string before(:each) do Datadog.configure do |c| c.use :active_record, describes: mysql_connection_string do |gadget_db| - gadget_db.tracer = tracer gadget_db.service_name = gadget_db_service_name end end end it do + count # Gadget is configured to show up as its own database service expect(gadget_span.service).to eq(gadget_db_service_name) # Widget isn't, ends up assigned to the default database service @@ -176,13 +173,13 @@ def mysql_connection_string before(:each) do Datadog.configure do |c| c.use :active_record, describes: 'sqlite3::memory:' do |widget_db| - widget_db.tracer = tracer widget_db.service_name = widget_db_service_name end end end it do + count # Gadget belongs to the default database expect(gadget_span.service).to eq(default_db_service_name) # Widget belongs to its own database @@ -197,13 +194,13 @@ def mysql_connection_string Datadog.configure do |c| c.use :active_record, describes: widget_db_connection_hash do |widget_db| - widget_db.tracer = tracer widget_db.service_name = widget_db_service_name end end end it do + count # Gadget belongs to the default database expect(gadget_span.service).to eq(default_db_service_name) # Widget belongs to its own database diff --git a/spec/ddtrace/contrib/active_record/performance_spec.rb b/spec/ddtrace/contrib/active_record/performance_spec.rb index 4e86cffb9b5..39d5efbfcff 100644 --- a/spec/ddtrace/contrib/active_record/performance_spec.rb +++ b/spec/ddtrace/contrib/active_record/performance_spec.rb @@ -5,9 +5,7 @@ require 'sqlite3' RSpec.describe 'ActiveRecord tracing performance' do - let(:tracer) { get_test_tracer } - let(:options) { { tracer: tracer } } - let(:spans) { tracer.writer.spans } + let(:options) { {} } before(:each) do skip('Performance test does not run in CI.') @@ -42,7 +40,7 @@ def measure(iterations = 1) measure(10) # Discard warm-up spans - tracer.writer.spans + clear_spans! end it 'produces a measurement' do diff --git a/spec/ddtrace/contrib/active_record/tracer_spec.rb b/spec/ddtrace/contrib/active_record/tracer_spec.rb index 748426020d0..bd715209305 100644 --- a/spec/ddtrace/contrib/active_record/tracer_spec.rb +++ b/spec/ddtrace/contrib/active_record/tracer_spec.rb @@ -5,8 +5,7 @@ require_relative 'app' RSpec.describe 'ActiveRecord instrumentation' do - let(:tracer) { get_test_tracer } - let(:configuration_options) { { tracer: tracer } } + let(:configuration_options) { {} } before(:each) do # Prevent extra spans during tests @@ -30,9 +29,6 @@ context 'when query is made' do before(:each) { Article.count } - let(:spans) { tracer.writer.spans } - let(:span) { spans.first } - it_behaves_like 'analytics for integration' do let(:analytics_enabled_var) { Datadog::Contrib::ActiveRecord::Ext::ENV_ANALYTICS_ENABLED } let(:analytics_sample_rate_var) { Datadog::Contrib::ActiveRecord::Ext::ENV_ANALYTICS_SAMPLE_RATE } @@ -41,9 +37,6 @@ it_behaves_like 'measured span for integration', false it 'calls the instrumentation when is used standalone' do - # expect service and trace is sent - expect(spans.size).to eq(1) - expect(span.service).to eq('mysql2') expect(span.name).to eq('mysql2.query') expect(span.span_type).to eq('sql') diff --git a/spec/ddtrace/contrib/active_support/notifications/subscription_spec.rb b/spec/ddtrace/contrib/active_support/notifications/subscription_spec.rb index e4b448eeeeb..de3cce43448 100644 --- a/spec/ddtrace/contrib/active_support/notifications/subscription_spec.rb +++ b/spec/ddtrace/contrib/active_support/notifications/subscription_spec.rb @@ -7,7 +7,6 @@ RSpec.describe Datadog::Contrib::ActiveSupport::Notifications::Subscription do describe 'instance' do subject(:subscription) { described_class.new(tracer, span_name, options, &block) } - let(:tracer) { get_test_tracer } let(:span_name) { double('span_name') } let(:options) { {} } let(:payload) { {} } diff --git a/spec/ddtrace/contrib/analytics_examples.rb b/spec/ddtrace/contrib/analytics_examples.rb index 2d4efd93b2b..90a670c829e 100644 --- a/spec/ddtrace/contrib/analytics_examples.rb +++ b/spec/ddtrace/contrib/analytics_examples.rb @@ -153,6 +153,13 @@ end end + shared_context 'analytics setting' do |analytics_enabled| + let(:analytics_enabled) { defined?(super) ? super() : analytics_enabled } + + before { Datadog.configuration.analytics.enabled = analytics_enabled } + after { Datadog.configuration.reset! } + end + context 'when configured by configuration options' do context 'and explicitly enabled' do let(:configuration_options) { super().merge(analytics_enabled: true) } @@ -175,24 +182,12 @@ end context 'is explicitly enabled' do - around do |example| - Datadog.configuration.analytics.enabled = Datadog.configuration.analytics.enabled.tap do - Datadog.configuration.analytics.enabled = true - example.run - end - end - + include_context 'analytics setting', true it_behaves_like 'sample rate value' end context 'is explicitly disabled' do - around do |example| - Datadog.configuration.analytics.enabled = Datadog.configuration.analytics.enabled.tap do - Datadog.configuration.analytics.enabled = false - example.run - end - end - + include_context 'analytics setting', false it_behaves_like 'sample rate value' end end @@ -219,24 +214,12 @@ end context 'is explicitly enabled' do - around do |example| - Datadog.configuration.analytics.enabled = Datadog.configuration.analytics.enabled.tap do - Datadog.configuration.analytics.enabled = true - example.run - end - end - + include_context 'analytics setting', true it_behaves_like 'sample rate value' end context 'is explicitly disabled' do - around do |example| - Datadog.configuration.analytics.enabled = Datadog.configuration.analytics.enabled.tap do - Datadog.configuration.analytics.enabled = false - example.run - end - end - + include_context 'analytics setting', false it_behaves_like 'sample rate value' end end diff --git a/spec/ddtrace/contrib/aws/instrumentation_spec.rb b/spec/ddtrace/contrib/aws/instrumentation_spec.rb index 41f437d91f6..4523611f96d 100644 --- a/spec/ddtrace/contrib/aws/instrumentation_spec.rb +++ b/spec/ddtrace/contrib/aws/instrumentation_spec.rb @@ -7,15 +7,11 @@ require 'ddtrace/ext/http' RSpec.describe 'AWS instrumentation' do - let(:tracer) { get_test_tracer } - let(:configuration_options) { { tracer: tracer } } + let(:configuration_options) { {} } let(:client) { ::Aws::S3::Client.new(stub_responses: responses) } let(:responses) { true } - let(:span) { spans.first } - let(:spans) { tracer.writer.spans(:keep) } - before(:each) do Datadog.configure do |c| c.use :aws, configuration_options diff --git a/spec/ddtrace/contrib/concurrent_ruby/integration_test_spec.rb b/spec/ddtrace/contrib/concurrent_ruby/integration_test_spec.rb index c1e69dfd72f..98e66982214 100644 --- a/spec/ddtrace/contrib/concurrent_ruby/integration_test_spec.rb +++ b/spec/ddtrace/contrib/concurrent_ruby/integration_test_spec.rb @@ -4,34 +4,31 @@ require 'ddtrace' RSpec.describe 'ConcurrentRuby integration tests' do - around do |example| - unmodified_future = ::Concurrent::Future.dup - example.run + # DEV We save an unmodified copy of Concurrent::Future. + let!(:unmodified_future) { ::Concurrent::Future.dup } + + # DEV We then restore Concurrent::Future, a dangerous game. + after do ::Concurrent.send(:remove_const, :Future) ::Concurrent.const_set('Future', unmodified_future) remove_patch!(:concurrent_ruby) end - let(:tracer) { get_test_tracer } - let(:configuration_options) { { tracer: tracer } } + let(:configuration_options) { {} } subject(:deferred_execution) do outer_span = tracer.trace('outer_span') - inner_span = nil future = Concurrent::Future.new do - inner_span = tracer.trace('inner_span') - inner_span.finish + tracer.trace('inner_span') {} end future.execute future.wait outer_span.finish - - { outer_span: outer_span, inner_span: inner_span } end - let(:outer_span) { deferred_execution[:outer_span] } - let(:inner_span) { deferred_execution[:inner_span] } + let(:outer_span) { spans.find { |s| s.name == 'outer_span' } } + let(:inner_span) { spans.find { |s| s.name == 'inner_span' } } shared_examples_for 'deferred execution' do before do @@ -43,18 +40,18 @@ end it 'writes inner span to tracer' do - expect(tracer.writer.spans).to include(inner_span) + expect(spans).to include(inner_span) end it 'writes outer span to tracer' do - expect(tracer.writer.spans).to include(outer_span) + expect(spans).to include(outer_span) end end describe 'patching' do subject(:patch) do Datadog.configure do |c| - c.use :concurrent_ruby, tracer: tracer + c.use :concurrent_ruby end end @@ -68,20 +65,22 @@ it_should_behave_like 'deferred execution' it 'inner span should not have parent' do + deferred_execution expect(inner_span.parent).to be_nil end end context 'when context propagation is enabled' do - it_should_behave_like 'deferred execution' - before do Datadog.configure do |c| - c.use :concurrent_ruby, tracer: tracer + c.use :concurrent_ruby end end + it_should_behave_like 'deferred execution' + it 'inner span parent should be included in outer span' do + deferred_execution expect(inner_span.parent).to eq(outer_span) end end diff --git a/spec/ddtrace/contrib/configuration/settings_spec.rb b/spec/ddtrace/contrib/configuration/settings_spec.rb index 71010342655..6ca9cbcf49f 100644 --- a/spec/ddtrace/contrib/configuration/settings_spec.rb +++ b/spec/ddtrace/contrib/configuration/settings_spec.rb @@ -17,6 +17,15 @@ subject(:tracer) { settings.tracer } it { expect(settings.tracer).to be Datadog.tracer } it { expect(settings[:tracer]).to be Datadog.tracer } + + context 'setting the tracer value' do + subject(:set) { settings.tracer = double } + + it 'outputs a deprecation warning' do + expect(Datadog.logger).to receive(:warn).with(include('DEPRECATED')) + set + end + end end describe '#analytics_enabled' do diff --git a/spec/ddtrace/contrib/dalli/instrumentation_spec.rb b/spec/ddtrace/contrib/dalli/instrumentation_spec.rb index 8516d99ec74..0874a3de820 100644 --- a/spec/ddtrace/contrib/dalli/instrumentation_spec.rb +++ b/spec/ddtrace/contrib/dalli/instrumentation_spec.rb @@ -10,14 +10,7 @@ let(:test_port) { ENV.fetch('TEST_MEMCACHED_PORT', '11211') } let(:client) { ::Dalli::Client.new("#{test_host}:#{test_port}") } - let(:tracer) { get_test_tracer } - let(:configuration_options) { { tracer: tracer } } - - def all_spans - tracer.writer.spans(:keep) - end - - let(:span) { all_spans.first } + let(:configuration_options) { {} } # Enable the test tracer before(:each) do @@ -36,7 +29,7 @@ def all_spans describe 'when a client calls #set' do before do client.set('abc', 123) - try_wait_until { all_spans.any? } + try_wait_until { fetch_spans.any? } end it_behaves_like 'analytics for integration' do @@ -47,7 +40,7 @@ def all_spans it_behaves_like 'measured span for integration', false it 'calls instrumentation' do - expect(all_spans.size).to eq(1) + expect(spans.size).to eq(1) expect(span.service).to eq('memcached') expect(span.name).to eq('memcached.command') expect(span.span_type).to eq('memcached') @@ -63,18 +56,18 @@ def all_spans before do Datadog.configure do |c| - c.use :dalli, describes: "#{test_host}:#{test_port}", tracer: tracer, service_name: service_name + c.use :dalli, describes: "#{test_host}:#{test_port}", service_name: service_name end end context 'and #set is called' do before do client.set('abc', 123) - try_wait_until { all_spans.any? } + try_wait_until { fetch_spans.any? } end it 'calls instrumentation' do - expect(all_spans.size).to eq(1) + expect(spans.size).to eq(1) expect(span.service).to eq(service_name) expect(span.name).to eq('memcached.command') expect(span.span_type).to eq('memcached') diff --git a/spec/ddtrace/contrib/dalli/patcher_spec.rb b/spec/ddtrace/contrib/dalli/patcher_spec.rb index 121039567f9..279001c138b 100644 --- a/spec/ddtrace/contrib/dalli/patcher_spec.rb +++ b/spec/ddtrace/contrib/dalli/patcher_spec.rb @@ -7,8 +7,7 @@ RSpec.describe 'Dalli instrumentation' do include_context 'tracer logging' - let(:tracer) { get_test_tracer } - let(:configuration_options) { { tracer: tracer } } + let(:configuration_options) { {} } # Enable the test tracer before(:each) do diff --git a/spec/ddtrace/contrib/delayed_job/plugin_spec.rb b/spec/ddtrace/contrib/delayed_job/plugin_spec.rb index 281f6e60732..6281bb4eb5e 100644 --- a/spec/ddtrace/contrib/delayed_job/plugin_spec.rb +++ b/spec/ddtrace/contrib/delayed_job/plugin_spec.rb @@ -26,8 +26,7 @@ def job_data end) end - let(:tracer) { get_test_tracer } - let(:configuration_options) { { tracer: tracer } } + let(:configuration_options) { {} } before do Datadog.configure { |c| c.use :delayed_job, configuration_options } @@ -65,12 +64,11 @@ def job_data subject(:job_run) { Delayed::Job.enqueue(sample_job_object.new, job_params) } it 'creates a span' do - expect { job_run }.to change { tracer.writer.spans.first }.to be_instance_of(Datadog::Span) + expect { job_run }.to change { fetch_spans.first }.to be_instance_of(Datadog::Span) end context 'when the job looks like Active Job' do subject(:job_run) { Delayed::Job.enqueue(active_job_sample_job_object.new, job_params) } - subject(:span) { tracer.writer.spans.first } before { job_run } @@ -80,8 +78,6 @@ def job_data end describe 'created span' do - subject(:span) { tracer.writer.spans.first } - before { job_run } it 'has service name taken from configuration' do diff --git a/spec/ddtrace/contrib/elasticsearch/patcher_spec.rb b/spec/ddtrace/contrib/elasticsearch/patcher_spec.rb index 1f31d101c93..01a3fd09b54 100644 --- a/spec/ddtrace/contrib/elasticsearch/patcher_spec.rb +++ b/spec/ddtrace/contrib/elasticsearch/patcher_spec.rb @@ -10,8 +10,7 @@ let(:server) { "http://#{host}:#{port}" } let(:client) { Elasticsearch::Client.new(url: server) } - let(:configuration_options) { { tracer: tracer } } - let(:tracer) { get_test_tracer } + let(:configuration_options) { {} } before do Datadog.configure do |c| @@ -32,7 +31,7 @@ subject(:request) { client.perform_request 'GET', '_cluster/health' } it 'creates a span' do - expect { request }.to change { tracer.writer.spans.first }.to Datadog::Span + expect { request }.to change { fetch_spans.first }.to Datadog::Span end context 'inside a span' do @@ -45,13 +44,13 @@ end it 'creates a child request span' do - expect { request_inside_a_span }.to change { tracer.writer.spans.length }.to 2 + expect { request_inside_a_span }.to change { fetch_spans.length }.to 2 end it 'sets request span parent id and trace id' do request_inside_a_span - child, parent = tracer.writer.spans + child, parent = spans expect(child.parent_id).to eq(parent.span_id) expect(child.trace_id).to eq(parent.trace_id) @@ -61,8 +60,6 @@ describe 'health request span' do before { request } - subject(:span) { tracer.writer.spans.first } - it { expect(span.name).to eq('elasticsearch.query') } it { expect(span.service).to eq('elasticsearch') } it { expect(span.resource).to eq('GET _cluster/health') } @@ -76,8 +73,6 @@ request end - subject(:span) { tracer.writer.spans.first } - it { expect(span.name).to eq('elasticsearch.query') } it { expect(span.service).to eq('elasticsearch') } it { expect(span.resource).to eq('GET _cluster/health') } @@ -108,12 +103,11 @@ subject(:request) { client.perform_request 'PUT', "#{index_name}/#{document_type}/#{document_id}", {}, document_body } it 'creates a span' do - expect { request }.to change { tracer.writer.spans.first }.to Datadog::Span + expect { request }.to change { fetch_spans.first }.to Datadog::Span end describe 'index request span' do before { request } - subject(:span) { tracer.writer.spans.first } it_behaves_like 'analytics for integration' do let(:analytics_enabled_var) { Datadog::Contrib::Elasticsearch::Ext::ENV_ANALYTICS_ENABLED } diff --git a/spec/ddtrace/contrib/elasticsearch/transport_spec.rb b/spec/ddtrace/contrib/elasticsearch/transport_spec.rb index 824df8c4d0b..850cf30116c 100644 --- a/spec/ddtrace/contrib/elasticsearch/transport_spec.rb +++ b/spec/ddtrace/contrib/elasticsearch/transport_spec.rb @@ -22,11 +22,7 @@ let(:server) { "http://#{host}:#{port}" } let(:client) { Elasticsearch::Client.new(url: server) } - let(:tracer) { get_test_tracer } - let(:configuration_options) { { tracer: tracer } } - - let(:spans) { tracer.writer.spans } - let(:span) { spans.first } + let(:configuration_options) { {} } before(:each) do Datadog.configure do |c| diff --git a/spec/ddtrace/contrib/ethon/easy_patch_spec.rb b/spec/ddtrace/contrib/ethon/easy_patch_spec.rb index d7931d23c21..497a7ee2add 100644 --- a/spec/ddtrace/contrib/ethon/easy_patch_spec.rb +++ b/spec/ddtrace/contrib/ethon/easy_patch_spec.rb @@ -1,11 +1,12 @@ +require 'ddtrace/contrib/support/spec_helper' + require 'ethon' require 'ddtrace/contrib/ethon/easy_patch' require 'ddtrace/contrib/ethon/shared_examples' require 'ddtrace/contrib/analytics_examples' RSpec.describe Datadog::Contrib::Ethon::EasyPatch do - let(:tracer) { get_test_tracer } - let(:configuration_options) { { tracer: tracer } } + let(:configuration_options) { {} } before do Datadog.configure do |c| @@ -104,8 +105,6 @@ # Note: perform calls complete subject { easy.complete } - let(:span) { tracer.writer.spans.first } - before do expect(easy).to receive(:url).and_return('http://example.com/test').at_least(:once) allow(easy).to receive(:mirror).and_return(double('Fake mirror', options: { response_code: 200 })) @@ -113,7 +112,7 @@ end it 'creates a span' do - expect { subject }.to change { tracer.writer.spans.first }.to be_instance_of(Datadog::Span) + expect { subject }.to change { fetch_spans.first }.to be_instance_of(Datadog::Span) end it 'cleans up span stored on easy' do diff --git a/spec/ddtrace/contrib/ethon/integration_context.rb b/spec/ddtrace/contrib/ethon/integration_context.rb index fc555473796..a1422bf1635 100644 --- a/spec/ddtrace/contrib/ethon/integration_context.rb +++ b/spec/ddtrace/contrib/ethon/integration_context.rb @@ -1,3 +1,5 @@ +require 'webrick' + RSpec.shared_context 'integration context' do before(:all) do @log_buffer = StringIO.new # set to $stderr to debug @@ -54,8 +56,7 @@ url end - let(:tracer) { get_test_tracer } - let(:configuration_options) { { tracer: tracer } } + let(:configuration_options) { {} } before do Datadog.configure do |c| diff --git a/spec/ddtrace/contrib/ethon/multi_patch_spec.rb b/spec/ddtrace/contrib/ethon/multi_patch_spec.rb index 284dd152322..fda6901a7e8 100644 --- a/spec/ddtrace/contrib/ethon/multi_patch_spec.rb +++ b/spec/ddtrace/contrib/ethon/multi_patch_spec.rb @@ -1,11 +1,12 @@ +require 'ddtrace/contrib/support/spec_helper' + require 'ethon' -require 'ddtrace/contrib/ethon/easy_patch' +require 'ddtrace/contrib/ethon/multi_patch' require 'ddtrace/contrib/ethon/shared_examples' require 'ddtrace/contrib/analytics_examples' RSpec.describe Datadog::Contrib::Ethon::MultiPatch do - let(:tracer) { get_test_tracer } - let(:configuration_options) { { tracer: tracer } } + let(:configuration_options) { {} } before do Datadog.configure do |c| @@ -60,13 +61,12 @@ let(:multi) { ::Ethon::Multi.new } subject { multi.perform } - let(:spans) { tracer.writer.spans } let(:easy_span) { spans.select { |span| span.name == 'ethon.request' }.first } let(:multi_span) { spans.select { |span| span.name == 'ethon.multi.request' }.first } context 'with no easy added to multi' do it 'does not trace' do - expect { subject }.to change { tracer.writer.spans.count }.by 0 + expect { subject }.to change { fetch_spans.count }.by 0 end end @@ -97,7 +97,7 @@ end it 'submits parent and child traces' do - expect { subject }.to change { tracer.writer.spans.count }.by 2 + expect { subject }.to change { fetch_spans.count }.by 2 end it 'cleans up multi span variable' do @@ -117,7 +117,7 @@ multi.add easy multi.perform multi.perform - end.to change { tracer.writer.spans.count }.by 2 + end.to change { fetch_spans.count }.by 2 end it 'creates extra traces for each extra valid call to perform' do @@ -126,7 +126,7 @@ multi.perform multi.add easy multi.perform - end.to change { tracer.writer.spans.count }.by 4 + end.to change { fetch_spans.count }.by 4 end end end diff --git a/spec/ddtrace/contrib/ethon/shared_examples.rb b/spec/ddtrace/contrib/ethon/shared_examples.rb index cf06d3a7043..e4bb38c9e77 100644 --- a/spec/ddtrace/contrib/ethon/shared_examples.rb +++ b/spec/ddtrace/contrib/ethon/shared_examples.rb @@ -44,7 +44,7 @@ describe 'instrumented request' do it 'creates a span' do - expect { request }.to change { tracer.writer.spans.first }.to be_instance_of(Datadog::Span) + expect { request }.to change { fetch_spans.first }.to be_instance_of(Datadog::Span) end it 'returns response' do @@ -53,7 +53,7 @@ describe 'created span' do subject(:span) do - tracer.writer.spans.select { |span| span.name == 'ethon.request' }.first + spans.select { |span| span.name == 'ethon.request' }.first end context 'response is successful' do @@ -113,7 +113,7 @@ context 'distributed tracing default' do let(:return_headers) { true } - let(:span) { tracer.writer.spans.select { |span| span.name == 'ethon.request' }.first } + let(:span) { spans.select { |span| span.name == 'ethon.request' }.first } shared_examples_for 'propagating distributed headers' do let(:return_headers) { true } diff --git a/spec/ddtrace/contrib/ethon/typhoeus_integration_spec.rb b/spec/ddtrace/contrib/ethon/typhoeus_integration_spec.rb index 9e80a3198b6..8caf12cb0d2 100644 --- a/spec/ddtrace/contrib/ethon/typhoeus_integration_spec.rb +++ b/spec/ddtrace/contrib/ethon/typhoeus_integration_spec.rb @@ -1,3 +1,5 @@ +require 'ddtrace/contrib/support/spec_helper' + require 'ddtrace/contrib/ethon/shared_examples' require 'ddtrace/contrib/ethon/integration_context' @@ -37,11 +39,10 @@ end it 'creates 3 spans' do - expect { request }.to change { tracer.writer.spans.count }.to 3 + expect { request }.to change { fetch_spans.count }.to 3 end describe 'created spans' do - subject(:spans) { tracer.writer.spans } let(:span_get) { spans.select { |span| span.get_tag(Datadog::Ext::HTTP::METHOD) == 'GET' }.first } let(:span_post) { spans.select { |span| span.get_tag(Datadog::Ext::HTTP::METHOD) == 'POST' }.first } let(:span_parent) { spans.select { |span| span.name == 'ethon.multi.request' }.first } diff --git a/spec/ddtrace/contrib/excon/instrumentation_spec.rb b/spec/ddtrace/contrib/excon/instrumentation_spec.rb index dc70e6561a8..fda255bf8ef 100644 --- a/spec/ddtrace/contrib/excon/instrumentation_spec.rb +++ b/spec/ddtrace/contrib/excon/instrumentation_spec.rb @@ -6,18 +6,16 @@ require 'ddtrace/contrib/excon/middleware' RSpec.describe Datadog::Contrib::Excon::Middleware do - let(:tracer) { get_test_tracer } - let(:connection_options) { { mock: true } } let(:middleware_options) { {} } - let(:configuration_options) { { tracer: tracer } } + let(:configuration_options) { {} } let(:request_span) do - tracer.writer.spans(:keep).find { |span| span.name == Datadog::Contrib::Excon::Ext::SPAN_REQUEST } + spans.find { |span| span.name == Datadog::Contrib::Excon::Ext::SPAN_REQUEST } end let(:all_request_spans) do - tracer.writer.spans(:keep).find_all { |span| span.name == Datadog::Contrib::Excon::Ext::SPAN_REQUEST } + spans.find_all { |span| span.name == Datadog::Contrib::Excon::Ext::SPAN_REQUEST } end before(:each) do diff --git a/spec/ddtrace/contrib/faraday/middleware_spec.rb b/spec/ddtrace/contrib/faraday/middleware_spec.rb index 31e2a899662..0f87d2c1a12 100644 --- a/spec/ddtrace/contrib/faraday/middleware_spec.rb +++ b/spec/ddtrace/contrib/faraday/middleware_spec.rb @@ -6,8 +6,6 @@ require 'ddtrace/ext/distributed' RSpec.describe 'Faraday middleware' do - let(:tracer) { get_test_tracer } - let(:client) do ::Faraday.new('http://example.com') do |builder| builder.use(:ddtrace, middleware_options) if use_middleware @@ -22,10 +20,10 @@ let(:use_middleware) { true } let(:middleware_options) { {} } - let(:configuration_options) { { tracer: tracer } } + let(:configuration_options) { {} } let(:request_span) do - tracer.writer.spans(:keep).find { |span| span.name == Datadog::Contrib::Faraday::Ext::SPAN_REQUEST } + spans.find { |span| span.name == Datadog::Contrib::Faraday::Ext::SPAN_REQUEST } end before(:each) do diff --git a/spec/ddtrace/contrib/faraday/patcher_spec.rb b/spec/ddtrace/contrib/faraday/patcher_spec.rb index 6cb3e356e68..5e6c8131217 100644 --- a/spec/ddtrace/contrib/faraday/patcher_spec.rb +++ b/spec/ddtrace/contrib/faraday/patcher_spec.rb @@ -7,8 +7,7 @@ RSpec.describe 'Faraday instrumentation' do include_context 'tracer logging' - let(:tracer) { get_test_tracer } - let(:configuration_options) { { tracer: tracer } } + let(:configuration_options) { {} } # Enable the test tracer before(:each) do diff --git a/spec/ddtrace/contrib/graphql/tracer_spec.rb b/spec/ddtrace/contrib/graphql/tracer_spec.rb index 3de45a2eb50..b830cd20518 100644 --- a/spec/ddtrace/contrib/graphql/tracer_spec.rb +++ b/spec/ddtrace/contrib/graphql/tracer_spec.rb @@ -21,7 +21,6 @@ Datadog.configure do |c| c.use :graphql, service_name: 'graphql-test', - tracer: tracer, schemas: [schema] end end diff --git a/spec/ddtrace/contrib/grpc/datadog_interceptor/client_spec.rb b/spec/ddtrace/contrib/grpc/datadog_interceptor/client_spec.rb index 2c72dd863f8..936778c4da2 100644 --- a/spec/ddtrace/contrib/grpc/datadog_interceptor/client_spec.rb +++ b/spec/ddtrace/contrib/grpc/datadog_interceptor/client_spec.rb @@ -6,10 +6,7 @@ RSpec.describe 'tracing on the client connection' do subject(:client) { Datadog::Contrib::GRPC::DatadogInterceptor::Client.new } - let(:tracer) { get_test_tracer } - let(:configuration_options) { { tracer: tracer, service_name: 'rspec' } } - - let(:span) { tracer.writer.spans.first } + let(:configuration_options) { { service_name: 'rspec' } } before do Datadog.configure do |c| @@ -44,11 +41,13 @@ it 'replaces default service name' do default_client_interceptor.request_response(keywords) {} - span = tracer.writer.spans.first + span = fetch_spans.first expect(span.service).to eq 'rspec' + clear_spans! + configured_client_interceptor.request_response(keywords) {} - span = tracer.writer.spans.first + span = fetch_spans.first expect(span.service).to eq 'cepsr' end end diff --git a/spec/ddtrace/contrib/grpc/datadog_interceptor/server_spec.rb b/spec/ddtrace/contrib/grpc/datadog_interceptor/server_spec.rb index 01e9e1c08bc..e1c424ecb16 100644 --- a/spec/ddtrace/contrib/grpc/datadog_interceptor/server_spec.rb +++ b/spec/ddtrace/contrib/grpc/datadog_interceptor/server_spec.rb @@ -6,8 +6,7 @@ RSpec.describe 'tracing on the server connection' do subject(:server) { Datadog::Contrib::GRPC::DatadogInterceptor::Server.new } - let(:tracer) { get_test_tracer } - let(:configuration_options) { { tracer: tracer, service_name: 'rspec' } } + let(:configuration_options) { { service_name: 'rspec' } } before do Datadog.configure do |c| @@ -22,8 +21,6 @@ Datadog.registry[:grpc].reset_configuration! end - let(:span) { tracer.writer.spans.first } - shared_examples 'span data contents' do specify { expect(span.name).to eq 'grpc.service' } specify { expect(span.span_type).to eq 'web' } diff --git a/spec/ddtrace/contrib/grpc/integration_test_spec.rb b/spec/ddtrace/contrib/grpc/integration_test_spec.rb index 189ca46ebd0..368af407cca 100644 --- a/spec/ddtrace/contrib/grpc/integration_test_spec.rb +++ b/spec/ddtrace/contrib/grpc/integration_test_spec.rb @@ -5,15 +5,9 @@ RSpec.describe 'gRPC integration test' do include GRPCHelper - let(:tracer) { get_test_tracer } - - let(:spans) do - tracer.writer.spans - end - before do Datadog.configure do |c| - c.use :grpc, tracer: tracer, service_name: 'rspec' + c.use :grpc, service_name: 'rspec' end end @@ -37,8 +31,10 @@ span = spans.first expect(span.service).to eq 'rspec' + clear_spans! + run_request_reply(endpoint, alternate_client) - span = configured_interceptor.datadog_pin.tracer.writer.spans.first + span = fetch_spans(configured_interceptor.datadog_pin.tracer).first expect(span.service).to eq 'awesome sauce' end end diff --git a/spec/ddtrace/contrib/grpc/interception_context_spec.rb b/spec/ddtrace/contrib/grpc/interception_context_spec.rb index ed88148b138..8839e696982 100644 --- a/spec/ddtrace/contrib/grpc/interception_context_spec.rb +++ b/spec/ddtrace/contrib/grpc/interception_context_spec.rb @@ -6,12 +6,9 @@ RSpec.describe GRPC::InterceptionContext do subject(:interception_context) { described_class.new } - let(:tracer) { get_test_tracer } - let(:configuration_options) { { tracer: tracer, service_name: 'rspec' } } + let(:configuration_options) { { service_name: 'rspec' } } describe '#intercept!' do - let(:span) { tracer.writer.spans.first } - before do Datadog.configure do |c| c.use :grpc, configuration_options diff --git a/spec/ddtrace/contrib/grpc/patcher_spec.rb b/spec/ddtrace/contrib/grpc/patcher_spec.rb index 56f2e6a2cf5..aea657c157f 100644 --- a/spec/ddtrace/contrib/grpc/patcher_spec.rb +++ b/spec/ddtrace/contrib/grpc/patcher_spec.rb @@ -7,8 +7,7 @@ RSpec.describe 'GRPC instrumentation' do include_context 'tracer logging' - let(:tracer) { get_test_tracer } - let(:configuration_options) { { tracer: tracer } } + let(:configuration_options) { {} } # Enable the test tracer before(:each) do diff --git a/spec/ddtrace/contrib/http/circuit_breaker_spec.rb b/spec/ddtrace/contrib/http/circuit_breaker_spec.rb index 0882f0130e7..33b0aa461f6 100644 --- a/spec/ddtrace/contrib/http/circuit_breaker_spec.rb +++ b/spec/ddtrace/contrib/http/circuit_breaker_spec.rb @@ -71,7 +71,7 @@ context 'given a request from' do let(:request) { @request } - before do + subject(:send_traces) do # Capture the HTTP request directly from the transport, # to make sure we have legitimate example. expect(::Net::HTTP::Post).to receive(:new).and_wrap_original do |m, *args| @@ -84,10 +84,13 @@ # Send a request, and make sure we captured it. transport.send_traces(get_test_traces(1)) + expect(@request).to be_a_kind_of(::Net::HTTP::Post) end context 'a Datadog Net::HTTP transport' do + before { expect(::Net::HTTP).to receive(:start) } + let(:transport) { Datadog::Transport::HTTP.default } it { is_expected.to be true } end diff --git a/spec/ddtrace/contrib/http/miniapp_spec.rb b/spec/ddtrace/contrib/http/miniapp_spec.rb index 95b8bbcb271..d5fcb7cfd20 100644 --- a/spec/ddtrace/contrib/http/miniapp_spec.rb +++ b/spec/ddtrace/contrib/http/miniapp_spec.rb @@ -15,10 +15,8 @@ let(:uri) { "http://#{host}:#{port}" } let(:client) { Net::HTTP.new(host, port) } - let(:tracer) { get_test_tracer } - before(:each) do - Datadog.configure { |c| c.use :http, tracer: tracer } + Datadog.configure { |c| c.use :http } end context 'when performing a trace around HTTP calls' do @@ -39,7 +37,6 @@ end let(:path) { '/my/path' } - let(:spans) { tracer.writer.spans } let(:parent_span) { spans[2] } let(:http_spans) { spans[0..1] } let(:trace_id) { spans[2].trace_id } diff --git a/spec/ddtrace/contrib/http/patcher_spec.rb b/spec/ddtrace/contrib/http/patcher_spec.rb index 698c6f51824..5c8f677c436 100644 --- a/spec/ddtrace/contrib/http/patcher_spec.rb +++ b/spec/ddtrace/contrib/http/patcher_spec.rb @@ -3,7 +3,6 @@ require 'net/http' RSpec.describe 'net/http patcher' do - let(:tracer) { get_test_tracer } let(:host) { 'example.com' } before do @@ -14,12 +13,12 @@ Datadog.configuration[:http].reset! Datadog.configure do |c| - c.use :http, tracer: tracer + c.use :http end end let(:request_span) do - tracer.writer.spans(:keep).find { |span| span.name == Datadog::Contrib::HTTP::Ext::SPAN_REQUEST } + spans.find { |span| span.name == Datadog::Contrib::HTTP::Ext::SPAN_REQUEST } end describe 'with default configuration' do @@ -35,7 +34,7 @@ before do Datadog.configure do |c| - c.use :http, tracer: tracer, service_name: new_service_name + c.use :http, service_name: new_service_name end end diff --git a/spec/ddtrace/contrib/http/request_spec.rb b/spec/ddtrace/contrib/http/request_spec.rb index c9b7c531806..1882d825a12 100644 --- a/spec/ddtrace/contrib/http/request_spec.rb +++ b/spec/ddtrace/contrib/http/request_spec.rb @@ -18,10 +18,7 @@ let(:uri) { "http://#{host}:#{port}" } let(:client) { Net::HTTP.new(host, port) } - let(:tracer) { get_test_tracer } - let(:configuration_options) { { tracer: tracer } } - - let(:spans) { tracer.writer.spans } + let(:configuration_options) { {} } before do Datadog.configure { |c| c.use :http, configuration_options } diff --git a/spec/ddtrace/contrib/mongodb/client_spec.rb b/spec/ddtrace/contrib/mongodb/client_spec.rb index 90f547052cf..224f613608e 100644 --- a/spec/ddtrace/contrib/mongodb/client_spec.rb +++ b/spec/ddtrace/contrib/mongodb/client_spec.rb @@ -5,8 +5,7 @@ require 'mongo' RSpec.describe 'Mongo::Client instrumentation' do - let(:tracer) { get_test_tracer } - let(:configuration_options) { { tracer: tracer } } + let(:configuration_options) { {} } let(:client) { Mongo::Client.new(["#{host}:#{port}"], client_options) } let(:client_options) { { database: database } } @@ -15,15 +14,8 @@ let(:database) { 'test' } let(:collection) { :artists } - let(:spans) { tracer.writer.spans(:keep) } - let(:span) { spans.first } - let(:mongo_gem_version) { Gem.loaded_specs['mongo'].version } - def discard_spans! - tracer.writer.spans - end - before(:each) do # Disable Mongo logging Mongo::Logger.logger.level = ::Logger::WARN @@ -209,7 +201,7 @@ def quantized?(object, options = {}) before(:each) do # Insert a document client[collection].insert_one(name: 'Steve', hobbies: ['hiking', 'tennis', 'fly fishing']) - discard_spans! + clear_spans! # Do #find_all operation client[collection].find.each do |document| @@ -235,7 +227,7 @@ def quantized?(object, options = {}) before(:each) do # Insert a document client[collection].insert_one(name: 'Steve', hobbies: ['hiking']) - discard_spans! + clear_spans! # Do #find operation result = client[collection].find(name: 'Steve').first[:hobbies] @@ -260,7 +252,7 @@ def quantized?(object, options = {}) before(:each) do # Insert a document client[collection].insert_one(name: 'Sally', hobbies: ['skiing', 'stamp collecting']) - discard_spans! + clear_spans! # Do #update_one operation client[collection].update_one({ name: 'Sally' }, '$set' => { 'phone_number' => '555-555-5555' }) @@ -295,7 +287,7 @@ def quantized?(object, options = {}) before(:each) do # Insert documents client[collection].insert_many(documents) - discard_spans! + clear_spans! # Do #update_many operation client[collection].update_many({}, '$set' => { 'phone_number' => '555-555-5555' }) @@ -326,7 +318,7 @@ def quantized?(object, options = {}) before(:each) do # Insert a document client[collection].insert_one(name: 'Sally', hobbies: ['skiing', 'stamp collecting']) - discard_spans! + clear_spans! # Do #delete_one operation client[collection].delete_one(name: 'Sally') @@ -361,7 +353,7 @@ def quantized?(object, options = {}) before(:each) do # Insert documents client[collection].insert_many(documents) - discard_spans! + clear_spans! # Do #delete_many operation client[collection].delete_many(name: /$S*/) diff --git a/spec/ddtrace/contrib/mysql2/patcher_spec.rb b/spec/ddtrace/contrib/mysql2/patcher_spec.rb index 326b1b1b40a..7e3277b846c 100644 --- a/spec/ddtrace/contrib/mysql2/patcher_spec.rb +++ b/spec/ddtrace/contrib/mysql2/patcher_spec.rb @@ -5,9 +5,8 @@ require 'mysql2' RSpec.describe 'Mysql2::Client patcher' do - let(:tracer) { get_test_tracer } let(:service_name) { 'my-sql' } - let(:configuration_options) { { tracer: tracer, service_name: service_name } } + let(:configuration_options) { { service_name: service_name } } let(:client) do Mysql2::Client.new( @@ -25,9 +24,6 @@ let(:username) { ENV.fetch('TEST_MYSQL_USER') { 'root' } } let(:password) { ENV.fetch('TEST_MYSQL_PASSWORD') { 'root' } } - let(:spans) { tracer.writer.spans(:keep) } - let(:span) { spans.first } - before(:each) do Datadog.configure do |c| c.use :mysql2, configuration_options diff --git a/spec/ddtrace/contrib/presto/client_spec.rb b/spec/ddtrace/contrib/presto/client_spec.rb index a660d5435c6..61557a0f2b6 100644 --- a/spec/ddtrace/contrib/presto/client_spec.rb +++ b/spec/ddtrace/contrib/presto/client_spec.rb @@ -6,8 +6,7 @@ require 'ddtrace/contrib/analytics_examples' RSpec.describe 'Presto::Client instrumentation' do - let(:tracer) { get_test_tracer } - let(:configuration_options) { { tracer: tracer } } + let(:configuration_options) { {} } let(:client) do Presto::Client.new( @@ -32,15 +31,8 @@ let(:http_proxy) { 'proxy.example.com:8080' } let(:model_version) { '0.205' } - let(:spans) { tracer.writer.spans(:keep) } - let(:span) { spans.first } - let(:presto_client_gem_version) { Gem.loaded_specs['presto-client'].version } - def discard_spans! - tracer.writer.spans - end - before(:each) do Datadog.configure do |c| c.use :presto, configuration_options @@ -60,11 +52,18 @@ def suppress_warnings Datadog.registry[:presto].reset_configuration! example.run Datadog.registry[:presto].reset_configuration! + Datadog.configuration.reset! end end context 'when the tracer is disabled' do - before(:each) { tracer.enabled = false } + before do + Datadog.configure do |c| + c.tracer.enabled = false + end + end + + after { Datadog.configuration.tracer.reset! } it 'does not produce spans' do client.run('SELECT 1') @@ -92,7 +91,7 @@ def suppress_warnings context 'when the client is configured' do context 'with a different service name' do let(:service) { 'presto-primary' } - let(:configuration_options) { { tracer: tracer, service_name: service } } + let(:configuration_options) { { service_name: service } } it_behaves_like 'a Presto trace' end @@ -223,7 +222,7 @@ def suppress_warnings context 'a failed query' do before(:each) do - discard_spans! + clear_spans! begin client.run('SELECT banana') # rubocop:disable Lint/HandleExceptions diff --git a/spec/ddtrace/contrib/racecar/patcher_spec.rb b/spec/ddtrace/contrib/racecar/patcher_spec.rb index 604ada9ef4f..e59e54503b6 100644 --- a/spec/ddtrace/contrib/racecar/patcher_spec.rb +++ b/spec/ddtrace/contrib/racecar/patcher_spec.rb @@ -6,12 +6,7 @@ require 'active_support' require 'ddtrace' RSpec.describe 'Racecar patcher' do - let(:tracer) { get_test_tracer } - let(:configuration_options) { { tracer: tracer } } - - def all_spans - tracer.writer.spans(:keep) - end + let(:configuration_options) { {} } before(:each) do Datadog.configure do |c| @@ -41,7 +36,7 @@ def all_spans end let(:span) do - all_spans.select { |s| s.name == Datadog::Contrib::Racecar::Ext::SPAN_MESSAGE }.first + spans.select { |s| s.name == Datadog::Contrib::Racecar::Ext::SPAN_MESSAGE }.first end context 'that doesn\'t raise an error' do @@ -119,7 +114,7 @@ def all_spans end let(:span) do - all_spans.select { |s| s.name == Datadog::Contrib::Racecar::Ext::SPAN_BATCH }.first + spans.select { |s| s.name == Datadog::Contrib::Racecar::Ext::SPAN_BATCH }.first end context 'that doesn\'t raise an error' do diff --git a/spec/ddtrace/contrib/rack/configuration_spec.rb b/spec/ddtrace/contrib/rack/configuration_spec.rb index 15929792101..6bcb9eadd4c 100644 --- a/spec/ddtrace/contrib/rack/configuration_spec.rb +++ b/spec/ddtrace/contrib/rack/configuration_spec.rb @@ -9,11 +9,7 @@ RSpec.describe 'Rack integration configuration' do include Rack::Test::Methods - let(:tracer) { get_test_tracer } - let(:configuration_options) { { tracer: tracer } } - - let(:spans) { tracer.writer.spans } - let(:span) { spans.first } + let(:configuration_options) { {} } before(:each) do Datadog.configure do |c| diff --git a/spec/ddtrace/contrib/rack/distributed_spec.rb b/spec/ddtrace/contrib/rack/distributed_spec.rb index 2cd1fd557b0..0f48920dc7f 100644 --- a/spec/ddtrace/contrib/rack/distributed_spec.rb +++ b/spec/ddtrace/contrib/rack/distributed_spec.rb @@ -8,11 +8,7 @@ RSpec.describe 'Rack integration distributed tracing' do include Rack::Test::Methods - let(:tracer) { get_test_tracer } - let(:rack_options) { { tracer: tracer } } - - let(:spans) { tracer.writer.spans } - let(:span) { spans.first } + let(:rack_options) { {} } before(:each) do Datadog.configure do |c| diff --git a/spec/ddtrace/contrib/rack/integration_test_spec.rb b/spec/ddtrace/contrib/rack/integration_test_spec.rb index 9a75536b2d5..ed338f670ba 100644 --- a/spec/ddtrace/contrib/rack/integration_test_spec.rb +++ b/spec/ddtrace/contrib/rack/integration_test_spec.rb @@ -9,11 +9,7 @@ RSpec.describe 'Rack integration tests' do include Rack::Test::Methods - let(:tracer) { get_test_tracer } - let(:rack_options) { { tracer: tracer } } - - let(:spans) { tracer.writer.spans } - let(:span) { spans.first } + let(:rack_options) { {} } before(:each) do Datadog.configure do |c| diff --git a/spec/ddtrace/contrib/rack/middleware_spec.rb b/spec/ddtrace/contrib/rack/middleware_spec.rb index b1d16d798b0..317775f83b0 100644 --- a/spec/ddtrace/contrib/rack/middleware_spec.rb +++ b/spec/ddtrace/contrib/rack/middleware_spec.rb @@ -8,8 +8,7 @@ subject(:middleware) { described_class.new(app) } let(:app) { instance_double(Rack::Builder) } - let(:tracer) { get_test_tracer } - let(:configuration_options) { { tracer: tracer } } + let(:configuration_options) { {} } before(:each) do Datadog.configure do |c| diff --git a/spec/ddtrace/contrib/rack/resource_name_spec.rb b/spec/ddtrace/contrib/rack/resource_name_spec.rb index 49ee55437ed..efa69d20869 100644 --- a/spec/ddtrace/contrib/rack/resource_name_spec.rb +++ b/spec/ddtrace/contrib/rack/resource_name_spec.rb @@ -8,18 +8,13 @@ RSpec.describe 'Rack integration with other middleware' do include Rack::Test::Methods - let(:tracer) { get_test_tracer } let(:rack_options) do { application: app, - middleware_names: true, - tracer: tracer + middleware_names: true } end - let(:spans) { tracer.writer.spans } - let(:span) { spans.first } - before(:each) do # Undo the Rack middleware name patch Datadog.registry[:rack].patcher::PATCHERS.each do |patcher| diff --git a/spec/ddtrace/contrib/rails/action_controller_spec.rb b/spec/ddtrace/contrib/rails/action_controller_spec.rb index b8760e749ea..7e7cf8b90f0 100644 --- a/spec/ddtrace/contrib/rails/action_controller_spec.rb +++ b/spec/ddtrace/contrib/rails/action_controller_spec.rb @@ -1,8 +1,7 @@ require 'ddtrace/contrib/rails/rails_helper' RSpec.describe 'Rails ActionController' do - let(:tracer) { get_test_tracer } - let(:rails_options) { { tracer: tracer } } + let(:rails_options) { {} } before do Datadog.configure do |c| @@ -15,10 +14,6 @@ end end - def all_spans - tracer.writer.spans(:keep) - end - let(:controller) do stub_const('TestController', Class.new(base_class) do def index @@ -39,8 +34,8 @@ def index expect { result }.to_not raise_error expect(result).to be_a_kind_of(Array) expect(result).to have(3).items - expect(all_spans).to have(1).items - expect(all_spans.first.name).to eq('rails.action_controller') + expect(spans).to have(1).items + expect(spans.first.name).to eq('rails.action_controller') end end @@ -68,8 +63,8 @@ def index expect { result }.to_not raise_error expect(result).to be_a_kind_of(Array) expect(result).to include(200, headers, body) - expect(all_spans).to have(1).items - expect(all_spans.first.name).to eq('rails.action_controller') + expect(spans).to have(1).items + expect(spans.first.name).to eq('rails.action_controller') end end @@ -94,8 +89,8 @@ def index expect { result }.to_not raise_error expect(result).to be_a_kind_of(Array) expect(result).to have(3).items - expect(all_spans).to have(1).items - expect(all_spans.first.name).to eq('rails.action_controller') + expect(spans).to have(1).items + expect(spans.first.name).to eq('rails.action_controller') end end end diff --git a/spec/ddtrace/contrib/rails/analytics_spec.rb b/spec/ddtrace/contrib/rails/analytics_spec.rb index 934bd183c6f..278bace9581 100644 --- a/spec/ddtrace/contrib/rails/analytics_spec.rb +++ b/spec/ddtrace/contrib/rails/analytics_spec.rb @@ -2,8 +2,7 @@ require 'ddtrace/contrib/rails/rails_helper' RSpec.describe 'Rails trace analytics' do - let(:tracer) { get_test_tracer } - let(:configuration_options) { { tracer: tracer } } + let(:configuration_options) { {} } before(:each) do Datadog.configure do |c| @@ -25,9 +24,6 @@ Datadog.registry[:action_pack].reset_configuration! end - let(:span) { spans.first } - let(:spans) { tracer.writer.spans(:keep) } - describe 'for a controller action' do subject(:result) { action.call(env) } let(:controller) do diff --git a/spec/ddtrace/contrib/rails/cache_spec.rb b/spec/ddtrace/contrib/rails/cache_spec.rb index 5ca1fc6d463..1f35c89dd91 100644 --- a/spec/ddtrace/contrib/rails/cache_spec.rb +++ b/spec/ddtrace/contrib/rails/cache_spec.rb @@ -1,3 +1,6 @@ +require 'spec_helper' +require 'ddtrace/contrib/analytics_examples' + require 'securerandom' require 'ddtrace/contrib/rails/ext' diff --git a/spec/ddtrace/contrib/rails/database_spec.rb b/spec/ddtrace/contrib/rails/database_spec.rb index fe0909735c6..b969429fafb 100644 --- a/spec/ddtrace/contrib/rails/database_spec.rb +++ b/spec/ddtrace/contrib/rails/database_spec.rb @@ -18,7 +18,7 @@ stub_const('Article', Class.new(ActiveRecord::Base)) Article.count # Ensure warm up queries are executed before tests - clear_spans + clear_spans! end after { Article.delete_all } @@ -44,7 +44,7 @@ context 'on record creation' do before do Article.create(title: 'Instantiation test') - clear_spans + clear_spans! end context 'with instantiation support' do @@ -102,7 +102,7 @@ Article.count expect(span.get_tag('active_record.db.cached')).to be_nil - clear_spans + clear_spans! Article.count expect(span.get_tag('active_record.db.cached')).to eq('true') diff --git a/spec/ddtrace/contrib/rails/defaults_spec.rb b/spec/ddtrace/contrib/rails/defaults_spec.rb index bc94364288f..0a04de54a95 100644 --- a/spec/ddtrace/contrib/rails/defaults_spec.rb +++ b/spec/ddtrace/contrib/rails/defaults_spec.rb @@ -5,11 +5,11 @@ context 'when Datadog.configuration.service' do before do - Datadog.configuration.service = default_service + Datadog.configure { |c| c.service = default_service } app end - after { Datadog.configuration.service = nil } + after { Datadog.configure { |c| c.service = nil } } context 'is not configured' do let(:default_service) { nil } diff --git a/spec/ddtrace/contrib/rails/middleware_spec.rb b/spec/ddtrace/contrib/rails/middleware_spec.rb index 293065c6f07..716cf0ca4cb 100644 --- a/spec/ddtrace/contrib/rails/middleware_spec.rb +++ b/spec/ddtrace/contrib/rails/middleware_spec.rb @@ -33,7 +33,7 @@ def index end let(:use_rack) { true } - let(:rails_options) { { tracer: tracer } } + let(:rails_options) { {} } context 'with middleware' do context 'that does nothing' do diff --git a/spec/ddtrace/contrib/rails/rails_active_job_spec.rb b/spec/ddtrace/contrib/rails/rails_active_job_spec.rb index c8653cc1135..720f50e9ef9 100644 --- a/spec/ddtrace/contrib/rails/rails_active_job_spec.rb +++ b/spec/ddtrace/contrib/rails/rails_active_job_spec.rb @@ -22,8 +22,6 @@ end before do - Datadog.configuration[:sidekiq][:tracer] = tracer - Sidekiq.configure_client do |config| config.redis = { url: ENV['REDIS_URL'] } end diff --git a/spec/ddtrace/contrib/rails/redis_cache_spec.rb b/spec/ddtrace/contrib/rails/redis_cache_spec.rb index d0266651822..99d54a64daf 100644 --- a/spec/ddtrace/contrib/rails/redis_cache_spec.rb +++ b/spec/ddtrace/contrib/rails/redis_cache_spec.rb @@ -29,7 +29,7 @@ before { app } before do - Datadog.configure { |c| c.use :redis, tracer: tracer } + Datadog.configure { |c| c.use :redis } Datadog.configure(client_from_driver(driver)) end @@ -102,7 +102,7 @@ # check that the value is really updated, and persistent expect(cache.read(key)).to eq(51) - clear_spans + clear_spans! # if value exists, fetch returns it and does no update expect(cache.fetch(key) { 7 }).to eq(51) @@ -136,7 +136,7 @@ end end - context '#write' do + context '#delete' do subject!(:write) { cache.delete(key) } it do diff --git a/spec/ddtrace/contrib/rails/support/application.rb b/spec/ddtrace/contrib/rails/support/application.rb index 8ca3af351e2..0bff05a0d48 100644 --- a/spec/ddtrace/contrib/rails/support/application.rb +++ b/spec/ddtrace/contrib/rails/support/application.rb @@ -5,7 +5,6 @@ before do Datadog.configuration[:rails].reset_options! - Datadog.configuration[:rails][:tracer] = tracer reset_rails_configuration! end @@ -33,10 +32,8 @@ def initialize_app! rails_test_application.test_initialize! end - # Clear out any garbage spans generated by initialization - if defined?(tracer) - tracer.writer.spans if tracer.writer.class <= FauxWriter - end + # Clear out any spans generated during initialization + clear_spans! end if Rails.version < '4.0' @@ -67,7 +64,7 @@ def initialize_app! logger.error 'A Rails app for this version is not found!' end - let(:tracer_options) { { tracer: tracer } } + let(:tracer_options) { {} } let(:app_name) { Datadog::Contrib::Rails::Utils.app_name } diff --git a/spec/ddtrace/contrib/rake/instrumentation_spec.rb b/spec/ddtrace/contrib/rake/instrumentation_spec.rb index 6f3f3f6713e..cf2e3f78ed9 100644 --- a/spec/ddtrace/contrib/rake/instrumentation_spec.rb +++ b/spec/ddtrace/contrib/rake/instrumentation_spec.rb @@ -8,10 +8,7 @@ require 'ddtrace/contrib/rake/patcher' RSpec.describe Datadog::Contrib::Rake::Instrumentation do - let(:tracer) { get_test_tracer } - let(:configuration_options) { { tracer: tracer, enabled: true } } - let(:spans) { tracer.writer.spans } - let(:span) { spans.first } + let(:configuration_options) { { enabled: true } } before(:each) do skip('Rake integration incompatible.') unless Datadog::Contrib::Rake::Integration.compatible? diff --git a/spec/ddtrace/contrib/redis/instrumentation_spec.rb b/spec/ddtrace/contrib/redis/instrumentation_spec.rb index 8bfe3cc9b5e..49e4f79adb4 100644 --- a/spec/ddtrace/contrib/redis/instrumentation_spec.rb +++ b/spec/ddtrace/contrib/redis/instrumentation_spec.rb @@ -9,13 +9,7 @@ let(:test_port) { ENV.fetch('TEST_REDIS_PORT', 6379).to_i } let(:client) { Redis.new(host: test_host, port: test_port) } - let(:tracer) { get_test_tracer } - let(:configuration_options) { { tracer: tracer } } - - def all_spans - tracer.writer.spans(:keep) - end - let(:span) { all_spans.first } + let(:configuration_options) { {} } around do |example| # Reset before and after each example; don't allow global state to linger. @@ -36,19 +30,19 @@ def all_spans before do Datadog.configure do |c| - c.use :redis, tracer: tracer, service_name: default_service_name - c.use :redis, describes: { url: redis_url }, tracer: tracer, service_name: service_name + c.use :redis, service_name: default_service_name + c.use :redis, describes: { url: redis_url }, service_name: service_name end end context 'and #set is called' do before do client.set('abc', 123) - try_wait_until { all_spans.any? } + try_wait_until { fetch_spans.any? } end it 'calls instrumentation' do - expect(all_spans.size).to eq(1) + expect(spans.size).to eq(1) expect(span.service).to eq(service_name) expect(span.name).to eq('redis.command') expect(span.span_type).to eq('redis') @@ -67,19 +61,19 @@ def all_spans before do Datadog.configure do |c| - c.use :redis, tracer: tracer, service_name: default_service_name - c.use :redis, describes: { host: test_host, port: test_port }, tracer: tracer, service_name: service_name + c.use :redis, service_name: default_service_name + c.use :redis, describes: { host: test_host, port: test_port }, service_name: service_name end end context 'and #set is called' do before do client.set('abc', 123) - try_wait_until { all_spans.any? } + try_wait_until { fetch_spans.any? } end it 'calls instrumentation' do - expect(all_spans.size).to eq(1) + expect(spans.size).to eq(1) expect(span.service).to eq(service_name) expect(span.name).to eq('redis.command') expect(span.span_type).to eq('redis') diff --git a/spec/ddtrace/contrib/redis/integration_test_spec.rb b/spec/ddtrace/contrib/redis/integration_test_spec.rb index cbc0834e7f7..416fe8a81a3 100644 --- a/spec/ddtrace/contrib/redis/integration_test_spec.rb +++ b/spec/ddtrace/contrib/redis/integration_test_spec.rb @@ -6,24 +6,19 @@ require 'ddtrace' RSpec.describe 'Redis integration test' do - # Use real tracer - let(:tracer) do - Datadog::Tracer.new - end - before(:each) do skip unless ENV['TEST_DATADOG_INTEGRATION'] - # Make sure to reset default tracer + use_real_tracer! + Datadog.configure do |c| - c.use :redis, tracer: tracer + c.use :redis end end after(:each) do - Datadog.configure do |c| - c.use :redis - end + Datadog.registry[:redis].reset_configuration! + Datadog.configuration.reset! end let(:redis) { Redis.new(host: host, port: port) } diff --git a/spec/ddtrace/contrib/redis/miniapp_spec.rb b/spec/ddtrace/contrib/redis/miniapp_spec.rb index c75dbf1fc78..ae946b9bdcf 100644 --- a/spec/ddtrace/contrib/redis/miniapp_spec.rb +++ b/spec/ddtrace/contrib/redis/miniapp_spec.rb @@ -8,14 +8,8 @@ RSpec.describe 'Redis mini app test' do before(:each) { skip unless ENV['TEST_DATADOG_INTEGRATION'] } - let(:tracer) { get_test_tracer } - - def all_spans - tracer.writer.spans(:keep) - end - before(:each) do - Datadog.configure { |c| c.use :redis, tracer: tracer } + Datadog.configure { |c| c.use :redis } # Configure client instance with custom options Datadog.configure(client, service_name: 'test-service') @@ -58,12 +52,12 @@ def all_spans # \ # |-----> span[2] (redis_cmd1_span) # \-----> span[3] (redis_cmd2_span) - let(:publish_span) { all_spans[1] } - let(:process_span) { all_spans[0] } - let(:redis_cmd1_span) { all_spans[2] } - let(:redis_cmd2_span) { all_spans[3] } + let(:publish_span) { spans[1] } + let(:process_span) { spans[0] } + let(:redis_cmd1_span) { spans[2] } + let(:redis_cmd2_span) { spans[3] } - it { expect(all_spans).to have(4).items } + it { expect(spans).to have(4).items } describe '"publish span"' do it do diff --git a/spec/ddtrace/contrib/redis/redis_spec.rb b/spec/ddtrace/contrib/redis/redis_spec.rb index 9ea0bd0f632..0b6c1446a86 100644 --- a/spec/ddtrace/contrib/redis/redis_spec.rb +++ b/spec/ddtrace/contrib/redis/redis_spec.rb @@ -7,12 +7,7 @@ require 'ddtrace' RSpec.describe 'Redis test' do - let(:tracer) { get_test_tracer } - let(:configuration_options) { { tracer: tracer } } - - def all_spans - tracer.writer.spans(:keep) - end + let(:configuration_options) { {} } before(:each) do Datadog.configure do |c| @@ -81,10 +76,10 @@ def all_spans expect(redis.get('FOO')).to eq('bar') end - it { expect(all_spans).to have(2).items } + it { expect(spans).to have(2).items } describe 'set span' do - subject(:span) { all_spans[-1] } + subject(:span) { spans[-1] } it do expect(span.name).to eq('redis.command') @@ -97,7 +92,7 @@ def all_spans end describe 'get span' do - subject(:span) { all_spans[0] } + subject(:span) { spans[0] } it do expect(span.name).to eq('redis.command') @@ -115,10 +110,10 @@ def all_spans expect(redis.call([:set, 'FOO', 'bar'])).to eq('OK') end - it { expect(all_spans).to have(1).item } + it { expect(spans).to have(1).item } describe 'span' do - subject(:span) { all_spans[-1] } + subject(:span) { spans[-1] } it do expect(span.resource).to eq('SET FOO bar') @@ -142,11 +137,11 @@ def all_spans it do expect(responses.map(&:value)).to eq(['OK', 'OK', 1, 1, 2]) - expect(all_spans).to have(1).items + expect(spans).to have(1).items end describe 'span' do - subject(:span) { all_spans[-1] } + subject(:span) { spans[-1] } it do expect(span.get_metric('redis.pipeline_length')).to eq(5) @@ -170,11 +165,11 @@ def all_spans end it do - expect(all_spans).to have(1).items + expect(spans).to have(1).items end describe 'span' do - subject(:span) { all_spans[-1] } + subject(:span) { spans[-1] } it do expect(span.name).to eq('redis.command') @@ -193,12 +188,9 @@ def all_spans context 'quantize' do describe 'set span' do - subject(:span) { all_spans.first } - before { expect(redis.set('K', 'x' * 500)).to eq('OK') } it do - expect(all_spans).to have(1).items expect(span.name).to eq('redis.command') expect(span.service).to eq('redis') expect(span.resource).to eq('SET K ' + 'x' * 47 + '...') @@ -209,7 +201,7 @@ def all_spans end describe 'get span' do - subject(:span) { all_spans.first } + subject(:span) { spans.first } before do expect(redis.set('K', 'x' * 500)).to eq('OK') @@ -217,7 +209,7 @@ def all_spans end it do - expect(all_spans).to have(2).items + expect(spans).to have(2).items expect(span.name).to eq('redis.command') expect(span.service).to eq('redis') expect(span.resource).to eq('GET K') @@ -230,12 +222,9 @@ def all_spans describe 'auth span' do include_context 'password-protected Redis server' - subject(:span) { all_spans.first } - before { redis.auth(password) } it do - expect(all_spans).to have(1).items expect(span.name).to eq('redis.command') expect(span.service).to eq('redis') expect(span.resource).to eq('AUTH ?') diff --git a/spec/ddtrace/contrib/resque/instrumentation_spec.rb b/spec/ddtrace/contrib/resque/instrumentation_spec.rb index aaa01b6d3c2..3a5eb63592e 100644 --- a/spec/ddtrace/contrib/resque/instrumentation_spec.rb +++ b/spec/ddtrace/contrib/resque/instrumentation_spec.rb @@ -7,15 +7,11 @@ RSpec.describe 'Resque instrumentation' do include_context 'Resque job' - let(:tracer) { get_test_tracer } - let(:spans) { tracer.writer.spans } - let(:span) { spans.first } - let(:url) { "redis://#{host}:#{port}" } let(:host) { ENV.fetch('TEST_REDIS_HOST', '127.0.0.1') } let(:port) { ENV.fetch('TEST_REDIS_PORT', 6379) } - let(:configuration_options) { { tracer: tracer } } + let(:configuration_options) { {} } before(:each) do # Setup Resque to use Redis @@ -128,7 +124,7 @@ end # On completion of the fork, `Datadog.tracer.shutdown!` will be invoked. - expect(tracer.writer).to receive(:stop) + expect(tracer).to receive(:shutdown!) tracer.trace('main.process') do perform_job(job_class) diff --git a/spec/ddtrace/contrib/rest_client/request_patch_spec.rb b/spec/ddtrace/contrib/rest_client/request_patch_spec.rb index a871d9d558f..2566c03c083 100644 --- a/spec/ddtrace/contrib/rest_client/request_patch_spec.rb +++ b/spec/ddtrace/contrib/rest_client/request_patch_spec.rb @@ -7,8 +7,7 @@ require 'restclient/request' RSpec.describe Datadog::Contrib::RestClient::RequestPatch do - let(:tracer) { get_test_tracer } - let(:configuration_options) { { tracer: tracer } } + let(:configuration_options) { {} } before do Datadog.configure do |c| @@ -41,7 +40,7 @@ shared_examples_for 'instrumented request' do it 'creates a span' do - expect { request }.to change { tracer.writer.spans.first }.to be_instance_of(Datadog::Span) + expect { request }.to change { fetch_spans.first }.to be_instance_of(Datadog::Span) end it 'returns response' do @@ -49,8 +48,6 @@ end describe 'created span' do - subject(:span) { tracer.writer.spans.first } - context 'response is successfull' do before { request } @@ -145,7 +142,7 @@ let(:response) { nil } it 'creates a span' do - expect { request }.to change { tracer.writer.spans.first }.to be_instance_of(Datadog::Span) + expect { request }.to change { fetch_spans.first }.to be_instance_of(Datadog::Span) end it 'returns response' do @@ -153,8 +150,6 @@ end describe 'created span' do - subject(:span) { tracer.writer.spans.first } - context 'response is successfull' do before { request } @@ -198,8 +193,6 @@ it_behaves_like 'instrumented request' shared_examples_for 'propagating distributed headers' do - let(:span) { tracer.writer.spans.first } - it 'propagates the headers' do request @@ -236,8 +229,6 @@ it_behaves_like 'instrumented request' shared_examples_for 'does not propagate distributed headers' do - let(:span) { tracer.writer.spans.first } - it 'does not propagate the headers' do request diff --git a/spec/ddtrace/contrib/sequel/configuration_spec.rb b/spec/ddtrace/contrib/sequel/configuration_spec.rb index c0675fb763e..64812fa9f01 100644 --- a/spec/ddtrace/contrib/sequel/configuration_spec.rb +++ b/spec/ddtrace/contrib/sequel/configuration_spec.rb @@ -6,14 +6,12 @@ require 'ddtrace/contrib/sequel/patcher' RSpec.describe 'Sequel configuration' do - let(:tracer) { get_test_tracer } - let(:spans) { tracer.writer.spans } - let(:span) { spans.first } - before(:each) do skip unless Datadog::Contrib::Sequel::Integration.compatible? end + let(:span) { spans.first } + describe 'for a SQLite database' do let(:sequel) do Sequel.sqlite(':memory:').tap do |db| @@ -33,7 +31,7 @@ def perform_query! context 'only with defaults' do # Expect it to be the normalized adapter name. it do - Datadog.configure { |c| c.use :sequel, tracer: tracer } + Datadog.configure { |c| c.use :sequel } perform_query! expect(span.service).to eq('sqlite') end @@ -43,7 +41,7 @@ def perform_query! let(:service_name) { 'my-sequel' } it do - Datadog.configure { |c| c.use :sequel, tracer: tracer, service_name: service_name } + Datadog.configure { |c| c.use :sequel, service_name: service_name } perform_query! expect(span.service).to eq(service_name) end @@ -53,7 +51,7 @@ def perform_query! let(:service_name) { 'custom-sequel' } it do - Datadog.configure { |c| c.use :sequel, tracer: tracer } + Datadog.configure { |c| c.use :sequel } Datadog.configure(sequel, service_name: service_name) perform_query! expect(span.service).to eq(service_name) @@ -66,7 +64,7 @@ def perform_query! # no way to unpatch it once its happened in other tests. it do sequel - Datadog.configure { |c| c.use :sequel, tracer: tracer } + Datadog.configure { |c| c.use :sequel } perform_query! expect(span.service).to eq('sqlite') end diff --git a/spec/ddtrace/contrib/sequel/instrumentation_spec.rb b/spec/ddtrace/contrib/sequel/instrumentation_spec.rb index 777463f4a32..410d1086659 100644 --- a/spec/ddtrace/contrib/sequel/instrumentation_spec.rb +++ b/spec/ddtrace/contrib/sequel/instrumentation_spec.rb @@ -7,16 +7,13 @@ require 'ddtrace/contrib/sequel/integration' RSpec.describe 'Sequel instrumentation' do - let(:tracer) { get_test_tracer } - let(:configuration_options) { { tracer: tracer } } + let(:configuration_options) { {} } let(:sequel) do Sequel.sqlite(':memory:').tap do |s| - Datadog.configure(s, tracer: tracer) + Datadog.configure(s) end end - let(:spans) { tracer.writer.spans } - before(:each) do skip('Sequel not compatible.') unless Datadog::Contrib::Sequel::Integration.compatible? diff --git a/spec/ddtrace/contrib/shoryuken/tracer_spec.rb b/spec/ddtrace/contrib/shoryuken/tracer_spec.rb index 1849be67eae..a90b2b83b66 100644 --- a/spec/ddtrace/contrib/shoryuken/tracer_spec.rb +++ b/spec/ddtrace/contrib/shoryuken/tracer_spec.rb @@ -6,11 +6,7 @@ RSpec.describe Datadog::Contrib::Shoryuken::Tracer do let(:shoryuken_tracer) { described_class.new } - - let(:tracer) { get_test_tracer } - let(:configuration_options) { { tracer: tracer } } - let(:spans) { tracer.writer.spans } - let(:span) { spans.first } + let(:configuration_options) { {} } before do Shoryuken.worker_executor = Shoryuken::Worker::InlineExecutor diff --git a/spec/ddtrace/contrib/sinatra/activerecord_spec.rb b/spec/ddtrace/contrib/sinatra/activerecord_spec.rb index edd7cfb0b93..fdafbaf1364 100644 --- a/spec/ddtrace/contrib/sinatra/activerecord_spec.rb +++ b/spec/ddtrace/contrib/sinatra/activerecord_spec.rb @@ -11,11 +11,7 @@ RSpec.describe 'Sinatra instrumentation with ActiveRecord' do include Rack::Test::Methods - let(:tracer) { get_test_tracer } - let(:options) { { tracer: tracer } } - - let(:span) { spans.first } - let(:spans) { tracer.writer.spans } + let(:options) { {} } before do Datadog.configure do |c| diff --git a/spec/ddtrace/contrib/sinatra/multi_app_spec.rb b/spec/ddtrace/contrib/sinatra/multi_app_spec.rb index 2f9b3411298..8d46fb26c91 100644 --- a/spec/ddtrace/contrib/sinatra/multi_app_spec.rb +++ b/spec/ddtrace/contrib/sinatra/multi_app_spec.rb @@ -9,11 +9,7 @@ RSpec.describe 'Sinatra instrumentation for multi-apps' do include Rack::Test::Methods - let(:tracer) { get_test_tracer } - let(:options) { { tracer: tracer } } - - let(:span) { spans.first } - let(:spans) { tracer.writer.spans } + let(:options) { {} } before do Datadog.configure do |c| diff --git a/spec/ddtrace/contrib/sinatra/tracer_spec.rb b/spec/ddtrace/contrib/sinatra/tracer_spec.rb index 37675962f9c..d0ade1fceeb 100644 --- a/spec/ddtrace/contrib/sinatra/tracer_spec.rb +++ b/spec/ddtrace/contrib/sinatra/tracer_spec.rb @@ -10,12 +10,10 @@ RSpec.describe 'Sinatra instrumentation' do include Rack::Test::Methods - let(:tracer) { get_test_tracer } - let(:configuration_options) { { tracer: tracer } } + let(:configuration_options) { {} } let(:span) { spans.find { |x| x.name == Datadog::Contrib::Sinatra::Ext::SPAN_REQUEST } } let(:route_span) { spans.find { |x| x.name == Datadog::Contrib::Sinatra::Ext::SPAN_ROUTE } } - let(:spans) { tracer.writer.spans } let(:app) { sinatra_app } diff --git a/spec/ddtrace/contrib/support/spec_helper.rb b/spec/ddtrace/contrib/support/spec_helper.rb index 01990535f1b..b83106df68b 100644 --- a/spec/ddtrace/contrib/support/spec_helper.rb +++ b/spec/ddtrace/contrib/support/spec_helper.rb @@ -1,10 +1,24 @@ require 'spec_helper' +require_relative 'tracer_helpers' + RSpec.configure do |config| + config.include Contrib::TracerHelpers + # Raise error when patching an integration fails. # This can be disabled by unstubbing +CommonMethods#on_patch_error+ require 'ddtrace/contrib/patcher' config.before(:each) do allow_any_instance_of(Datadog::Contrib::Patcher::CommonMethods).to(receive(:on_patch_error)) { |_, e| raise e } end + + # Ensure tracer environment is clean before running tests. + # + # This is done :before and not :after because doing so after + # can create noise for test assertions. For example: + # +expect(Datadog).to receive(:shutdown!).once+ + config.before(:each) do + Datadog.shutdown! + Datadog.configuration.reset! + end end diff --git a/spec/ddtrace/contrib/support/tracer_helpers.rb b/spec/ddtrace/contrib/support/tracer_helpers.rb new file mode 100644 index 00000000000..629fbd5dbc1 --- /dev/null +++ b/spec/ddtrace/contrib/support/tracer_helpers.rb @@ -0,0 +1,73 @@ +require 'ddtrace/tracer' +require 'ddtrace/span' +require 'support/faux_writer' + +module Contrib + # Contrib-specific tracer helpers. + # For contrib, we only allow one tracer to be active: + # the global +Datadog.tracer+. + module TracerHelpers + # Returns the current tracer instance + def tracer + Datadog.tracer + end + + # Returns spans and caches it (similar to +let(:spans)+). + def spans + @spans ||= fetch_spans + end + + # Retrieves and sorts all spans in the current tracer instance. + # This method does not cache its results. + def fetch_spans(tracer = self.tracer) + spans = tracer.instance_variable_get(:@spans) || [] + spans.flatten.sort! do |a, b| + if a.name == b.name + if a.resource == b.resource + if a.start_time == b.start_time + a.end_time <=> b.end_time + else + a.start_time <=> b.start_time + end + else + a.resource <=> b.resource + end + else + a.name <=> b.name + end + end + end + + # Remove all traces from the current tracer instance and + # busts cache of +#spans+ and +#span+. + def clear_spans! + tracer.instance_variable_set(:@spans, []) + + @spans = nil + @span = nil + end + + RSpec.configure do |config| + # Capture spans from the global tracer + config.before(:each) do + clear_spans! + + # The mutex must be eagerly initialized to prevent race conditions on lazy initialization + write_lock = Mutex.new + allow_any_instance_of(Datadog::Tracer).to receive(:write) do |tracer, trace| + tracer.instance_exec do + write_lock.synchronize do + @spans ||= [] + @spans << trace + end + end + end + end + end + + # Useful for integration testing. + def use_real_tracer! + allow_any_instance_of(Datadog::Tracer).to receive(:write).and_call_original + end + end +end diff --git a/spec/ddtrace/integration_spec.rb b/spec/ddtrace/integration_spec.rb index 5027390ed37..f656b9d06c6 100644 --- a/spec/ddtrace/integration_spec.rb +++ b/spec/ddtrace/integration_spec.rb @@ -297,7 +297,7 @@ def agent_receives_span_step3(previous_success) end.finish end.finish - try_wait_until { tracer.writer.spans(:keep).any? } + try_wait_until { tracer.writer.spans.any? } end it do @@ -323,7 +323,7 @@ def agent_receives_span_step3(previous_success) parent_span.context.origin = 'synthetics' end.finish - try_wait_until { tracer.writer.spans(:keep).any? } + try_wait_until { tracer.writer.spans.any? } end it { is_expected.to eq('synthetics') } diff --git a/spec/ddtrace/sync_writer_spec.rb b/spec/ddtrace/sync_writer_spec.rb index 02cd279ab97..b29062bd089 100644 --- a/spec/ddtrace/sync_writer_spec.rb +++ b/spec/ddtrace/sync_writer_spec.rb @@ -26,12 +26,8 @@ end context 'enabled' do - around do |example| - Datadog.configuration.report_hostname = Datadog.configuration.report_hostname.tap do - Datadog.configuration.report_hostname = true - example.run - end - end + before { Datadog.configuration.report_hostname = true } + after { Datadog.configuration.reset! } it do expect(sync_writer.transport).to receive(:send_traces) do |traces| @@ -47,12 +43,8 @@ end context 'disabled' do - around do |example| - Datadog.configuration.report_hostname = Datadog.configuration.report_hostname.tap do - Datadog.configuration.report_hostname = false - example.run - end - end + before { Datadog.configuration.report_hostname = false } + after { Datadog.configuration.reset! } it do expect(sync_writer.transport).to receive(:send_traces) do |traces| diff --git a/spec/ddtrace/writer_spec.rb b/spec/ddtrace/writer_spec.rb index 0c54a701cc4..df36519da7f 100644 --- a/spec/ddtrace/writer_spec.rb +++ b/spec/ddtrace/writer_spec.rb @@ -201,12 +201,8 @@ end context 'enabled' do - around do |example| - Datadog.configuration.report_hostname = Datadog.configuration.report_hostname.tap do - Datadog.configuration.report_hostname = true - example.run - end - end + before { Datadog.configuration.report_hostname = true } + after { Datadog.configuration.reset! } it do expect(transport).to receive(:send_traces) do |traces| @@ -220,12 +216,8 @@ end context 'disabled' do - around do |example| - Datadog.configuration.report_hostname = Datadog.configuration.report_hostname.tap do - Datadog.configuration.report_hostname = false - example.run - end - end + before { Datadog.configuration.report_hostname = false } + after { Datadog.configuration.reset! } it do expect(writer.transport).to receive(:send_traces) do |traces| diff --git a/spec/support/tracer_helpers.rb b/spec/support/tracer_helpers.rb index dc7baea47bb..19c6e6c519d 100644 --- a/spec/support/tracer_helpers.rb +++ b/spec/support/tracer_helpers.rb @@ -141,12 +141,12 @@ def spans # one span is available. def span @span ||= begin - expect(spans).to have(1).item, "Requested the only span, but #{spans.size} spans are available" - spans.first - end + expect(spans).to have(1).item, "Requested the only span, but #{spans.size} spans are available" + spans.first + end end - def clear_spans + def clear_spans! writer.spans(:clear) @spans = nil diff --git a/test/contrib/grape/app.rb b/test/contrib/grape/app.rb index 37ed7cdaab1..72d6964a846 100644 --- a/test/contrib/grape/app.rb +++ b/test/contrib/grape/app.rb @@ -54,10 +54,4 @@ class BaseAPITest < MiniTest::Test def app TestingAPI end - - def setup - # use a dummy tracer - @tracer = get_test_tracer() - Datadog.configuration[:grape][:tracer] = @tracer - end end diff --git a/test/contrib/grape/rack_app.rb b/test/contrib/grape/rack_app.rb index 10387b39844..bdca9cb9aef 100644 --- a/test/contrib/grape/rack_app.rb +++ b/test/contrib/grape/rack_app.rb @@ -25,6 +25,18 @@ class RackTestingAPI < Grape::API class BaseRackAPITest < MiniTest::Test include Rack::Test::Methods + include TestTracerHelper + + def integration_name + :grape + end + + def configure + Datadog.configure do |c| + c.use :grape + c.use :rack + end + end def app # create a custom Rack application with the Rack middleware and a Grape API @@ -36,17 +48,6 @@ def app end.to_app end - def setup - super - # store the configuration and use a DummyTracer - @tracer = get_test_tracer - - Datadog.configure do |c| - c.use :grape, tracer: @tracer - c.use :rack, tracer: @tracer - end - end - def teardown super # reset the configuration diff --git a/test/contrib/grape/rack_integration_test.rb b/test/contrib/grape/rack_integration_test.rb index c098338a1b0..5b14ea9f6ac 100644 --- a/test/contrib/grape/rack_integration_test.rb +++ b/test/contrib/grape/rack_integration_test.rb @@ -8,7 +8,6 @@ def test_traced_api_with_rack assert last_response.ok? assert_equal('OK', last_response.body) - spans = @tracer.writer.spans() assert_equal(spans.length, 3) render = spans[0] run = spans[1] @@ -43,7 +42,6 @@ def test_traced_api_failure_with_rack get '/api/hard_failure' end - spans = @tracer.writer.spans() assert_equal(spans.length, 3) render = spans[0] run = spans[1] @@ -78,7 +76,6 @@ def test_traced_api_404_with_rack # it should not impact the Rack integration that must work as usual get '/api/not_existing' - spans = @tracer.writer.spans() assert_equal(spans.length, 1) rack = spans[0] diff --git a/test/contrib/grape/request_test.rb b/test/contrib/grape/request_test.rb index d096387fa0e..8e2f7e6a4be 100644 --- a/test/contrib/grape/request_test.rb +++ b/test/contrib/grape/request_test.rb @@ -1,14 +1,28 @@ +require 'helper' + +require 'ddtrace' require 'contrib/grape/app' # rubocop:disable Metrics/AbcSize class TracedAPITest < BaseAPITest + include TestTracerHelper + + def integration_name + :grape + end + + def configure + Datadog.configure do |c| + c.use :grape + end + end + def test_traced_api_success # it should trace the endpoint body get '/base/success' assert last_response.ok? assert_equal('OK', last_response.body) - spans = @tracer.writer.spans() assert_equal(spans.length, 2) render = spans[0] run = spans[1] @@ -36,7 +50,6 @@ def test_traced_api_exception get '/base/hard_failure' end - spans = @tracer.writer.spans() assert_equal(spans.length, 2) render = spans[0] run = spans[1] @@ -70,7 +83,6 @@ def test_traced_api_before_after_filters assert last_response.ok? assert_equal('OK', last_response.body) - spans = @tracer.writer.spans() assert_equal(spans.length, 4) render, run, before, after = spans @@ -114,7 +126,6 @@ def test_traced_api_before_after_filters_exceptions get '/filtered_exception/before' end - spans = @tracer.writer.spans() assert_equal(spans.length, 2) run, before = spans diff --git a/test/contrib/rails/apps/rails3.rb b/test/contrib/rails/apps/rails3.rb index 5c023898f2e..886ecea5206 100644 --- a/test/contrib/rails/apps/rails3.rb +++ b/test/contrib/rails/apps/rails3.rb @@ -15,14 +15,19 @@ class Rails3 < Rails::Application config.middleware.delete ActionDispatch::DebugExceptions if Rails.version >= '3.2.22.5' end -# Enables the auto-instrumentation for the testing application -Datadog.configure do |c| - c.use :rails - c.use :redis if Gem.loaded_specs['redis'] && defined?(::Redis) -end - # Initialize the Rails application require 'contrib/rails/apps/routes' require 'contrib/rails/apps/controllers' -Rails3.initialize! -require 'contrib/rails/apps/models' + +def initialize_rails! + Rails3.initialize! + require 'contrib/rails/apps/models' + + # Rails < 4 doesn't keep good track internally if it's been + # initialized or not, so we have to do it. + Rails.instance_variable_set(:@dd_rails_initialized, true) +end + +def rails_initialized? + Rails.instance_variable_get(:@dd_rails_initialized) +end diff --git a/test/contrib/rails/apps/rails4.rb b/test/contrib/rails/apps/rails4.rb index 9fc73376282..d6a055711f0 100644 --- a/test/contrib/rails/apps/rails4.rb +++ b/test/contrib/rails/apps/rails4.rb @@ -6,4 +6,10 @@ class Application < RailsTrace::TestApplication end end -Rails4::Application.test_config() +def initialize_rails! + Rails4::Application.test_config() +end + +def rails_initialized? + Rails.application.initialized? +end diff --git a/test/contrib/rails/apps/rails5.rb b/test/contrib/rails/apps/rails5.rb index a6f16cfd693..566bc87fb07 100644 --- a/test/contrib/rails/apps/rails5.rb +++ b/test/contrib/rails/apps/rails5.rb @@ -5,4 +5,10 @@ class Application < RailsTrace::TestApplication end end -Rails5::Application.test_config() +def initialize_rails! + Rails5::Application.test_config() +end + +def rails_initialized? + Rails.application.initialized? +end diff --git a/test/contrib/rails/apps/rails6.rb b/test/contrib/rails/apps/rails6.rb index df493d9f0cd..99dafc2a4d1 100644 --- a/test/contrib/rails/apps/rails6.rb +++ b/test/contrib/rails/apps/rails6.rb @@ -12,7 +12,14 @@ class Application < RailsTrace::TestApplication # Enabling `cache_template_loading` forces ActionView to cache templates on first load, # and disables any attempt of refresh from the file system. config.action_view.cache_template_loading = true + config.hosts.clear end end -Rails6::Application.test_config() +def initialize_rails! + Rails6::Application.test_config() +end + +def rails_initialized? + Rails.application.initialized? +end diff --git a/test/contrib/rails/controller_test.rb b/test/contrib/rails/controller_test.rb index bfca8bc4a2d..1293c902a6c 100644 --- a/test/contrib/rails/controller_test.rb +++ b/test/contrib/rails/controller_test.rb @@ -1,27 +1,17 @@ require 'helper' +require 'minitest/around/unit' require 'contrib/rails/test_helper' +require 'ddtrace' # rubocop:disable Metrics/ClassLength class TracingControllerTest < ActionController::TestCase - setup do - @original_tracer = Datadog.configuration[:rails][:tracer] - @tracer = get_test_tracer - - Datadog.configure do |c| - c.use :rails, tracer: @tracer - end - end - - teardown do - Datadog.configuration[:rails][:tracer] = @original_tracer - end + include RailsTest test 'request is properly traced' do # make the request and assert the proper span get :index assert_response :success - spans = @tracer.writer.spans() assert_equal(spans.length, 2) span = spans[0] @@ -51,7 +41,6 @@ class TracingControllerTest < ActionController::TestCase # render the template and assert the proper span get :index assert_response :success - spans = @tracer.writer.spans() assert_equal(spans.length, 2) span = spans[1] assert_equal(span.name, 'rails.render_template') @@ -72,7 +61,6 @@ class TracingControllerTest < ActionController::TestCase # render the template and assert the proper span get :index assert_response :success - spans = @tracer.writer.spans() assert_equal(spans.length, 2) span = spans[1] assert_equal(span.name, 'rails.render_template') @@ -91,7 +79,6 @@ class TracingControllerTest < ActionController::TestCase # render the template and assert the proper span get :partial assert_response :success - spans = @tracer.writer.spans() assert_equal(spans.length, 3) _, span_partial, span_template = spans @@ -110,10 +97,9 @@ class TracingControllerTest < ActionController::TestCase assert_response :success # Verify all spans have closed - assert_equal(true, @tracer.call_context.trace.all?(&:finished?)) + assert_equal(true, tracer.call_context.trace.all?(&:finished?)) # Verify correct number of spans - spans = @tracer.writer.spans assert_equal(spans.length, 4) _, span_inner_partial, span_outer_partial, span_template = spans @@ -143,8 +129,6 @@ class TracingControllerTest < ActionController::TestCase # render the endpoint get :full assert_response :success - spans = @tracer.writer.spans - # rubocop:disable Style/IdenticalConditionalBranches if Datadog::Contrib::ActiveRecord::Events::Instantiation.supported? assert_equal(spans.length, 5) @@ -201,7 +185,6 @@ class TracingControllerTest < ActionController::TestCase err = true end assert_equal(true, err, 'should have raised an error') - spans = @tracer.writer.spans() assert_equal(1, spans.length) span = spans[0] assert_equal('rails.action_controller', span.name) @@ -219,7 +202,6 @@ class TracingControllerTest < ActionController::TestCase err = true end assert_equal(true, err, 'should have raised an error') - spans = @tracer.writer.spans assert_equal(1, spans.length) span = spans[0] assert_equal('rails.action_controller', span.name) @@ -237,7 +219,6 @@ class TracingControllerTest < ActionController::TestCase test 'http error code should be trapped and reported as such, even with no exception' do get :soft_error - spans = @tracer.writer.spans() if Rails::VERSION::MAJOR.to_i >= 5 assert_equal(1, spans.length) else @@ -255,7 +236,6 @@ class TracingControllerTest < ActionController::TestCase test 'custom resource names can be set' do get :custom_resource assert_response :success - spans = @tracer.writer.spans assert_equal(spans.length, 1) spans.first.tap do |span| @@ -266,7 +246,6 @@ class TracingControllerTest < ActionController::TestCase test 'custom tags can be set' do get :custom_tag assert_response :success - spans = @tracer.writer.spans assert_equal(spans.length, 1) spans.first.tap do |span| @@ -275,14 +254,13 @@ class TracingControllerTest < ActionController::TestCase end test 'combining rails and custom tracing is supported' do - @tracer.trace('a-parent') do + tracer.trace('a-parent') do get :index assert_response :success - @tracer.trace('a-brother') do + tracer.trace('a-brother') do end end - spans = @tracer.writer.spans() assert_equal(4, spans.length) brother_span, parent_span, controller_span, = spans diff --git a/test/contrib/rails/errors_test.rb b/test/contrib/rails/errors_test.rb index 6db5975066d..80a0e52f6a9 100644 --- a/test/contrib/rails/errors_test.rb +++ b/test/contrib/rails/errors_test.rb @@ -1,27 +1,17 @@ require 'helper' +require 'minitest/around/unit' require 'contrib/rails/test_helper' +require 'ddtrace' # rubocop:disable Metrics/ClassLength class TracingControllerTest < ActionController::TestCase - setup do - @original_tracer = Datadog.configuration[:rails][:tracer] - @tracer = get_test_tracer - - Datadog.configure do |c| - c.use :rails, tracer: @tracer - end - end - - teardown do - Datadog.configuration[:rails][:tracer] = @original_tracer - end + include RailsTest test 'error in the controller must be traced' do assert_raises ZeroDivisionError do get :error end - spans = @tracer.writer.spans() assert_equal(spans.length, 1) span = spans[0] @@ -40,7 +30,6 @@ class TracingControllerTest < ActionController::TestCase get :not_found end - spans = @tracer.writer.spans() assert_equal(spans.length, 1) span = spans[0] @@ -64,7 +53,6 @@ class TracingControllerTest < ActionController::TestCase assert_raises ::ActionView::MissingTemplate do get :missing_template end - spans = @tracer.writer.spans() assert_equal(spans.length, 2) span_request, span_template = spans @@ -103,7 +91,6 @@ class TracingControllerTest < ActionController::TestCase 'Missing partial tracing/ouch.html' end - spans = @tracer.writer.spans() assert_equal(spans.length, 3) span_request, span_partial, span_template = spans @@ -139,7 +126,6 @@ class TracingControllerTest < ActionController::TestCase assert_raises ::ActionView::Template::Error do get :error_template end - spans = @tracer.writer.spans() assert_equal(spans.length, 2) span_request, span_template = spans @@ -176,7 +162,6 @@ class TracingControllerTest < ActionController::TestCase assert_raises ::ActionView::Template::Error do get :error_partial end - spans = @tracer.writer.spans() assert_equal(spans.length, 3) span_request, span_partial, span_template = spans diff --git a/test/contrib/rails/rack_middleware_test.rb b/test/contrib/rails/rack_middleware_test.rb index 5c87082784b..e99b14aa3e6 100644 --- a/test/contrib/rails/rack_middleware_test.rb +++ b/test/contrib/rails/rack_middleware_test.rb @@ -1,30 +1,18 @@ require 'helper' +require 'minitest/around/unit' require 'contrib/rails/test_helper' +require 'ddtrace' # rubocop:disable Metrics/ClassLength class FullStackTest < ActionDispatch::IntegrationTest - setup do - @original_tracer = Datadog.configuration[:rails][:tracer] - @tracer = get_test_tracer - - Datadog.configure do |c| - c.use :rails, tracer: @tracer - end - end - - teardown do - Datadog.configuration[:rails][:tracer] = @original_tracer - end + include RailsTest test 'a full request is properly traced' do # make the request and assert the proper span get '/full' assert_response :success - # get spans - spans = @tracer.writer.spans - # spans are sorted alphabetically, and ... controller names start # either by m or p (MySQL or PostGreSQL) so the database span is always # the first one. Would fail with an adapter named z-something. @@ -88,7 +76,6 @@ class FullStackTest < ActionDispatch::IntegrationTest assert_response :error # get spans - spans = @tracer.writer.spans() assert_operator(spans.length, :>=, 2, 'there should be at least 2 spans') request_span, controller_span = spans @@ -116,7 +103,6 @@ class FullStackTest < ActionDispatch::IntegrationTest # assert_response 520 # get spans - spans = @tracer.writer.spans() assert_operator(spans.length, :>=, 2, 'there should be at least 2 spans') request_span, controller_span = spans @@ -142,7 +128,6 @@ class FullStackTest < ActionDispatch::IntegrationTest assert_response :error # get spans - spans = @tracer.writer.spans() assert_operator(spans.length, :>=, 2, 'there should be at least 2 spans') request_span, controller_span = spans @@ -181,7 +166,6 @@ class FullStackTest < ActionDispatch::IntegrationTest assert_response :error # Check spans - spans = @tracer.writer.spans assert_equal(2, spans.length) rack_span = spans.first @@ -202,7 +186,6 @@ class FullStackTest < ActionDispatch::IntegrationTest assert_response 404 # get spans - spans = @tracer.writer.spans() assert_operator(spans.length, :>=, 1, 'there should be at least 1 span') request_span = spans[0] diff --git a/test/contrib/rails/test_helper.rb b/test/contrib/rails/test_helper.rb index efe83c06d40..97a3c4fe0ea 100644 --- a/test/contrib/rails/test_helper.rb +++ b/test/contrib/rails/test_helper.rb @@ -103,3 +103,48 @@ def database_configuration def app_name Datadog::Contrib::Rails::Utils.app_name end + +module RailsTest + include TestTracerHelper + + # Because we Rails initialization has irreversible side effects, we manually + # reconfigure the test suite before running each test. + def before_each + if !@initialized && !rails_initialized? + Datadog.configure do |c| + c.use :rails + c.use :redis if Gem.loaded_specs['redis'] && defined?(::Redis) + end + + initialize_rails! + + @initialized = true + end + + clear_spans! + + if defined?(integration_session) && integration_session + integration_session.instance_variable_set(:@app, Rails.application) + end + end + + def spans + @spans ||= fetch_spans.reject { |x| x.resource == 'BEGIN' } + end + + if Rails::VERSION::MAJOR >= 4 + def before_setup + before_each + super + end + else + def setup + before_each + super + end + + def run(*_) + with_stubbed_tracer { super } + end + end +end diff --git a/test/contrib/rails/utils_test.rb b/test/contrib/rails/utils_test.rb index 7130d1bba68..5b72ae73bd3 100644 --- a/test/contrib/rails/utils_test.rb +++ b/test/contrib/rails/utils_test.rb @@ -1,47 +1,46 @@ require 'helper' +require 'ddtrace' -require 'ddtrace/contrib/action_view/utils' - -class UtilsTest < ActiveSupport::TestCase - setup do +class UtilsTest < Minitest::Test + def setup @default_base_template = Datadog.configuration[:rails][:template_base_path] end - teardown do + def teardown Datadog.configuration[:rails][:template_base_path] = @default_base_template end - test 'normalize_template_name' do + def test_normalize_template_name full_template_name = '/opt/rails/app/views/welcome/index.html.erb' template_name = Datadog::Contrib::ActionView::Utils.normalize_template_name(full_template_name) assert_equal(template_name, 'welcome/index.html.erb') end - test 'normalize_template_name_nil' do + def test_normalize_template_name_nil template_name = Datadog::Contrib::ActionView::Utils.normalize_template_name(nil) assert_nil(template_name) end - test 'normalize_template_name_not_a_path' do + def test_normalize_template_name_not_a_path full_template_name = 'index.html.erb' template_name = Datadog::Contrib::ActionView::Utils.normalize_template_name(full_template_name) assert_equal(template_name, 'index.html.erb') end - test 'normalize_template_name_without_views_prefix' do + def test_normalize_template_name_without_views_prefix full_template_name = '/opt/rails/app/custom/welcome/index.html.erb' template_name = Datadog::Contrib::ActionView::Utils.normalize_template_name(full_template_name) assert_equal(template_name, 'index.html.erb') end - test 'normalize_template_name_with_custom_prefix' do + def test_normalize_template_name_with_custom_prefix Datadog.configuration[:rails][:template_base_path] = 'custom/' full_template_name = '/opt/rails/app/custom/welcome/index.html.erb' template_name = Datadog::Contrib::ActionView::Utils.normalize_template_name(full_template_name) assert_equal(template_name, 'welcome/index.html.erb') end - test 'normalize_template_wrong_usage' do + def test_normalize_template_wrong_usage template_name = Datadog::Contrib::ActionView::Utils.normalize_template_name({}) assert_equal(template_name, '{}') end diff --git a/test/contrib/sidekiq/client_tracer_test.rb b/test/contrib/sidekiq/client_tracer_test.rb index ee12d7ca771..7e41345193a 100644 --- a/test/contrib/sidekiq/client_tracer_test.rb +++ b/test/contrib/sidekiq/client_tracer_test.rb @@ -18,8 +18,7 @@ def setup config.client_middleware.clear config.client_middleware do |chain| - chain.add(Datadog::Contrib::Sidekiq::ClientTracer, - tracer: @tracer, enabled: true) + chain.add(Datadog::Contrib::Sidekiq::ClientTracer, enabled: true) end end @@ -28,11 +27,10 @@ def setup end def test_empty - @tracer.trace('parent.span', service: 'parent-service') do + tracer.trace('parent.span', service: 'parent-service') do EmptyWorker.perform_async end - spans = @writer.spans assert_equal(2, spans.length) parent_span, child_span = spans @@ -52,7 +50,6 @@ def test_empty def test_empty_parentless EmptyWorker.perform_async - spans = @writer.spans assert_equal(1, spans.length) span = spans.first @@ -66,6 +63,6 @@ def test_empty_parentless def test_delayed_extensions DelayableClass.delay.do_work - assert_equal('ClientTracerTest::DelayableClass.do_work', @writer.spans.first.resource) + assert_equal('ClientTracerTest::DelayableClass.do_work', spans.first.resource) end end diff --git a/test/contrib/sidekiq/disabled_tracer_test.rb b/test/contrib/sidekiq/disabled_tracer_test.rb index b10f15cdca4..30c52269386 100644 --- a/test/contrib/sidekiq/disabled_tracer_test.rb +++ b/test/contrib/sidekiq/disabled_tracer_test.rb @@ -12,15 +12,14 @@ def setup super Sidekiq::Testing.server_middleware do |chain| - @tracer.configure(enabled: false) - chain.add(Datadog::Contrib::Sidekiq::ServerTracer, tracer: @tracer) + Datadog.tracer.configure(enabled: false) + chain.add(Datadog::Contrib::Sidekiq::ServerTracer) end end def test_empty EmptyWorker.perform_async() - spans = @writer.spans() assert_equal(0, spans.length) end end diff --git a/test/contrib/sidekiq/server_tracer_test.rb b/test/contrib/sidekiq/server_tracer_test.rb index 0c9f0610613..5590ebedcf1 100644 --- a/test/contrib/sidekiq/server_tracer_test.rb +++ b/test/contrib/sidekiq/server_tracer_test.rb @@ -35,8 +35,7 @@ def setup super Sidekiq::Testing.server_middleware do |chain| - chain.add(Datadog::Contrib::Sidekiq::ServerTracer, - tracer: @tracer, enabled: true) + chain.add(Datadog::Contrib::Sidekiq::ServerTracer, enabled: true) end Sidekiq::Extensions.enable_delay! if Sidekiq::VERSION > '5.0.0' end @@ -44,10 +43,9 @@ def setup def test_empty EmptyWorker.perform_async() - spans = @writer.spans() - assert_equal(1, spans.length) + assert_equal(2, spans.length) - span = spans[0] + span, _push = spans assert_equal('sidekiq', span.service) assert_equal('ServerTracerTest::EmptyWorker', span.resource) assert_equal('default', span.get_tag('sidekiq.job.queue')) @@ -65,10 +63,9 @@ def test_error rescue TestError end - spans = @writer.spans() - assert_equal(1, spans.length) + assert_equal(2, spans.length) - span = spans[0] + span, _push = spans assert_equal('sidekiq', span.service) assert_equal('ServerTracerTest::ErrorWorker', span.resource) assert_equal('default', span.get_tag('sidekiq.job.queue')) @@ -85,10 +82,9 @@ def test_custom EmptyWorker.perform_async() CustomWorker.perform_async('random_id') - spans = @writer.spans() - assert_equal(2, spans.length) + assert_equal(4, spans.length) - custom, empty = spans + custom, empty, _push, _push = spans assert_equal('sidekiq', empty.service) assert_equal('ServerTracerTest::EmptyWorker', empty.resource) @@ -109,6 +105,6 @@ def test_custom def test_delayed_extensions DelayableClass.delay.do_work - assert_equal('ServerTracerTest::DelayableClass.do_work', @writer.spans.first.resource) + assert_equal('ServerTracerTest::DelayableClass.do_work', spans.first.resource) end end diff --git a/test/contrib/sidekiq/tracer_configure_test.rb b/test/contrib/sidekiq/tracer_configure_test.rb index ef9155abfb5..ca3b404d263 100644 --- a/test/contrib/sidekiq/tracer_configure_test.rb +++ b/test/contrib/sidekiq/tracer_configure_test.rb @@ -10,18 +10,17 @@ def perform(); end def test_configuration_defaults # it should configure the tracer with reasonable defaults Sidekiq::Testing.server_middleware do |chain| - chain.add(Datadog::Contrib::Sidekiq::ServerTracer, tracer: @tracer) + chain.add(Datadog::Contrib::Sidekiq::ServerTracer) end EmptyWorker.perform_async() end def test_configuration_custom # it should configure the tracer with users' settings - @tracer.configure(enabled: false) + Datadog.tracer.configure(enabled: false) Sidekiq::Testing.server_middleware do |chain| chain.add( Datadog::Contrib::Sidekiq::ServerTracer, - tracer: @tracer, service_name: 'my-sidekiq' ) end diff --git a/test/contrib/sidekiq/tracer_test_base.rb b/test/contrib/sidekiq/tracer_test_base.rb index 47630666e2b..73f795225a9 100644 --- a/test/contrib/sidekiq/tracer_test_base.rb +++ b/test/contrib/sidekiq/tracer_test_base.rb @@ -6,12 +6,15 @@ require 'helper' class TracerTestBase < Minitest::Test + include TestTracerHelper + REDIS_HOST = ENV.fetch('TEST_REDIS_HOST', '127.0.0.1').freeze REDIS_PORT = ENV.fetch('TEST_REDIS_PORT', 6379) - def setup - @tracer = get_test_tracer - @writer = @tracer.writer + def configure + Datadog.configure do |c| + c.use :sidekiq + end redis_url = "redis://#{REDIS_HOST}:#{REDIS_PORT}" @@ -25,4 +28,8 @@ def setup Sidekiq::Testing.inline! end + + def writer + @tracer.writer + end end diff --git a/test/contrib/sucker_punch/patcher_test.rb b/test/contrib/sucker_punch/patcher_test.rb index 2fb14eccd55..8f748b818ed 100644 --- a/test/contrib/sucker_punch/patcher_test.rb +++ b/test/contrib/sucker_punch/patcher_test.rb @@ -7,11 +7,14 @@ module Datadog module Contrib module SuckerPunch class PatcherTest < Minitest::Test - def setup - @tracer = get_test_tracer + include TestTracerHelper + def integration_name + :sucker_punch + end + def configure Datadog.configure do |c| - c.use :sucker_punch, tracer: @tracer + c.use :sucker_punch end ::SuckerPunch::Queue.clear @@ -22,15 +25,15 @@ def test_two_spans_per_job # One span when pushing to the queue # One span for the job execution itself ::DummyWorker.perform_async - try_wait_until { all_spans.length == 2 } - assert_equal(2, all_spans.length) + try_wait_until { fetch_spans.length == 2 } + assert_equal(2, spans.length) end def test_successful_job ::DummyWorker.perform_async - try_wait_until { all_spans.length == 2 } + try_wait_until { fetch_spans.length == 2 } - span = all_spans.find { |s| s.resource[/PROCESS/] } + span = spans.find { |s| s.resource[/PROCESS/] } assert_equal('sucker_punch', span.service) assert_equal('sucker_punch.perform', span.name) assert_equal('PROCESS DummyWorker', span.resource) @@ -41,9 +44,9 @@ def test_successful_job def test_failed_job ::DummyWorker.perform_async(:fail) - try_wait_until { all_spans.length == 2 } + try_wait_until { fetch_spans.length == 2 } - span = all_spans.find { |s| s.resource[/PROCESS/] } + span = spans.find { |s| s.resource[/PROCESS/] } assert_equal('sucker_punch', span.service) assert_equal('sucker_punch.perform', span.name) assert_equal('PROCESS DummyWorker', span.resource) @@ -56,9 +59,9 @@ def test_failed_job def test_async_enqueueing ::DummyWorker.perform_async - try_wait_until { all_spans.any? } + try_wait_until { fetch_spans.any? } - span = all_spans.find { |s| s.resource[/ENQUEUE/] } + span = spans.find { |s| s.resource[/ENQUEUE/] } assert_equal('sucker_punch', span.service) assert_equal('sucker_punch.perform_async', span.name) assert_equal('ENQUEUE DummyWorker', span.resource) @@ -68,9 +71,9 @@ def test_async_enqueueing def test_delayed_enqueueing ::DummyWorker.perform_in(0) - try_wait_until { all_spans.any? } + try_wait_until { fetch_spans.any? } - span = all_spans.find { |s| s.resource[/ENQUEUE/] } + span = spans.find { |s| s.resource[/ENQUEUE/] } assert_equal('sucker_punch', span.service) assert_equal('sucker_punch.perform_in', span.name) assert_equal('ENQUEUE DummyWorker', span.resource) @@ -81,12 +84,6 @@ def test_delayed_enqueueing private - attr_reader :tracer - - def all_spans - tracer.writer.spans(:keep) - end - def pin ::SuckerPunch.datadog_pin end diff --git a/test/helper.rb b/test/helper.rb index 32644c1516c..bb20d16c9fb 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -244,3 +244,79 @@ def on_patch_error(e) raise e end end) + +require 'minitest/around/unit' +require 'minitest/stub_any_instance' + +module TestTracerHelper + # Integration name for settings cleanup + def integration_name; end + + def around(&block) + if integration_name + Datadog.registry[integration_name].reset_configuration! + Datadog.configuration[integration_name].reset_options! + end + + with_stubbed_tracer(&block) + + if integration_name + Datadog.registry[integration_name].reset_configuration! + Datadog.configuration[integration_name].reset_options! + end + end + + def with_stubbed_tracer + # The mutex must be eagerly initialized to prevent race conditions on lazy initialization + write_lock = Mutex.new + mock = lambda { |trace| + write_lock.synchronize do + @spans ||= [] + @spans << trace + end + } + + Datadog::Tracer.stub_any_instance(:write, mock) do + configure if defined?(configure) + + yield + end + end + + def spans + @spans ||= fetch_spans + end + + def tracer + Datadog.tracer + end + + # Retrieves and sorts all spans in the current tracer instance. + # This method does not cache its results. + def fetch_spans(tracer = self.tracer) + spans = tracer.instance_variable_get(:@spans) || [] + spans.flatten.sort! do |a, b| + if a.name == b.name + if a.resource == b.resource + if a.start_time == b.start_time + a.end_time <=> b.end_time + else + a.start_time <=> b.start_time + end + else + a.resource <=> b.resource + end + else + a.name <=> b.name + end + end + end + + # Remove all traces from the current tracer instance and + # busts cache of +#spans+. + def clear_spans! + tracer.instance_variable_set(:@spans, []) + + @spans = nil + end +end