scout_apm 3.0.0.pre20 → 3.0.0.pre21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +8 -3
- data/.travis.yml +14 -0
- data/CHANGELOG.markdown +12 -0
- data/Gemfile +8 -0
- data/README.markdown +2 -0
- data/lib/scout_apm.rb +1 -0
- data/lib/scout_apm/agent/preconditions.rb +15 -3
- data/lib/scout_apm/instruments/middleware_detailed.rb +1 -1
- data/lib/scout_apm/tracer.rb +30 -26
- data/lib/scout_apm/tracked_request.rb +17 -0
- data/lib/scout_apm/transaction.rb +13 -0
- data/lib/scout_apm/version.rb +1 -1
- data/scout_apm.gemspec +8 -4
- data/test/test_helper.rb +21 -0
- data/test/unit/config_test.rb +1 -1
- data/test/unit/db_query_metric_set_test.rb +10 -6
- data/test/unit/db_query_metric_stats_test.rb +17 -17
- data/test/unit/histogram_test.rb +11 -4
- data/test/unit/ignored_uris_test.rb +1 -1
- data/test/unit/instruments/net_http_test.rb +7 -2
- data/test/unit/layer_converters/depth_first_walker_test.rb +4 -0
- data/test/unit/layer_converters/metric_converter_test.rb +1 -1
- data/test/unit/layer_converters/stubs.rb +2 -2
- data/test/unit/limited_layer_test.rb +1 -1
- data/test/unit/logger_test.rb +1 -1
- data/test/unit/serializers/payload_serializer_test.rb +4 -3
- data/test/unit/sql_sanitizer_test.rb +6 -0
- data/test/unit/tracer_test.rb +76 -0
- data/test/unit/{test_tracked_request.rb → tracked_request_test.rb} +33 -13
- data/test/unit/transaction_test.rb +14 -0
- data/test/unit/utils/backtrace_parser_test.rb +1 -1
- data/test/unit/utils/numbers_test.rb +1 -1
- data/test/unit/utils/scm.rb +2 -2
- metadata +29 -9
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: eb5a7880c0007cdc98449e7598022481be64b83f
         | 
| 4 | 
            +
              data.tar.gz: b195f2ea2a704b97be089d38af6cb84145d96856
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 3d181d12bf746066430840488485e2e96370a33ebfc6db4b7e6c25d9cb07763d380867bf6aabf3595044451ba1a657a6d03b1d739b567e430da431f2de854a59
         | 
| 7 | 
            +
              data.tar.gz: f4149e4757f16f481ca9e9d4a3ababc1ec9ba3cb66718bffe2de207ae12b01f56fa81d0f14cf0d1b3348d7c8cf97d28809a6ec75ad6bdbb1a3af573a2de684bd
         | 
    
        data/.rubocop.yml
    CHANGED
    
    | @@ -1,8 +1,13 @@ | |
| 1 | 
            +
            # Disable all cops by default
         | 
| 2 | 
            +
            AllCops:
         | 
| 3 | 
            +
              DisabledByDefault: true
         | 
| 4 | 
            +
             | 
| 1 5 | 
             
            # 80 is stifling, especially with a few levels of nesting before we even start.
         | 
| 2 6 | 
             
            # So bump it to 100 to keep really long lines from creeping in.
         | 
| 3 7 | 
             
            Metrics/LineLength:
         | 
| 8 | 
            +
              Enabled: false
         | 
| 4 9 | 
             
              Max: 100
         | 
| 5 10 |  | 
| 6 | 
            -
            Style/ | 
| 7 | 
            -
             | 
| 8 | 
            -
             | 
| 11 | 
            +
            Style/HashSyntax:
         | 
| 12 | 
            +
              Enabled: true
         | 
| 13 | 
            +
              EnforcedStyle: hash_rockets
         | 
    
        data/.travis.yml
    ADDED
    
    
    
        data/CHANGELOG.markdown
    CHANGED
    
    | @@ -2,6 +2,18 @@ | |
| 2 2 |  | 
| 3 3 | 
             
            * ScoutProf BETA
         | 
| 4 4 |  | 
| 5 | 
            +
            # 2.4.9
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            * ScoutApm::Transaction#rename and #ignore API
         | 
| 8 | 
            +
            * Explicit custom instrumentation with ScoutApm::Tracer#instrument blocks,
         | 
| 9 | 
            +
              without needing to include a module
         | 
| 10 | 
            +
            * Quieter logging in normal startup cases
         | 
| 11 | 
            +
            * Upgraded testing infrastructure
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            # 2.4.8
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            * Fix issue with detailed middleware instrumentation
         | 
| 16 | 
            +
             | 
| 5 17 | 
             
            # 2.4.7
         | 
| 6 18 |  | 
| 7 19 | 
             
            * Fix issue recording backtraces
         | 
    
        data/Gemfile
    CHANGED
    
    | @@ -2,3 +2,11 @@ source "http://rubygems.org" | |
| 2 2 |  | 
| 3 3 | 
             
            # Specify your gem's dependencies in scout_apm.gemspec
         | 
| 4 4 | 
             
            gemspec
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            # Pin development dependencies more conservatively for Ruby 1.8.7
         | 
| 7 | 
            +
            if RUBY_VERSION <= "1.8.7"
         | 
| 8 | 
            +
              gem "activesupport", "~> 3.2"
         | 
| 9 | 
            +
              gem "i18n", "~> 0.6.11"
         | 
| 10 | 
            +
              gem "pry", "~> 0.9.12"
         | 
| 11 | 
            +
              gem "rake", "~> 10.5"
         | 
| 12 | 
            +
            end
         | 
    
        data/README.markdown
    CHANGED
    
    | @@ -1,5 +1,7 @@ | |
| 1 1 | 
             
            # ScoutApm Ruby Agent
         | 
| 2 2 |  | 
| 3 | 
            +
            [](https://travis-ci.org/scoutapp/scout_apm_ruby)
         | 
| 4 | 
            +
             | 
| 3 5 | 
             
            A Ruby gem for detailed Rails application performance analysis. Metrics are
         | 
| 4 6 | 
             
            reported to [Scout](https://scoutapp.com), a hosted application monitoring
         | 
| 5 7 | 
             
            service.
         | 
    
        data/lib/scout_apm.rb
    CHANGED
    
    | @@ -129,6 +129,7 @@ require 'scout_apm/db_query_metric_set' | |
| 129 129 | 
             
            require 'scout_apm/store'
         | 
| 130 130 | 
             
            require 'scout_apm/fake_store'
         | 
| 131 131 | 
             
            require 'scout_apm/tracer'
         | 
| 132 | 
            +
            require 'scout_apm/transaction'
         | 
| 132 133 | 
             
            require 'scout_apm/context'
         | 
| 133 134 | 
             
            require 'scout_apm/instant_reporting'
         | 
| 134 135 | 
             
            require 'scout_apm/trace_compactor'
         | 
| @@ -4,20 +4,24 @@ module ScoutApm | |
| 4 4 | 
             
                  # The preconditions here must be a 2 element hash, with :message and :check.
         | 
| 5 5 | 
             
                  # message: Proc that takes the environment, and returns a string
         | 
| 6 6 | 
             
                  # check: Proc that takes an AgentContext and returns true if precondition was met, if false, we shouldn't start.
         | 
| 7 | 
            +
                  # severity: Severity of the log message (one of: :debug, :info, :warn, :error or :fatal)
         | 
| 7 8 | 
             
                  PRECONDITIONS = [
         | 
| 8 9 | 
             
                    PRECONDITION_ENABLED = {
         | 
| 9 10 | 
             
                      :message => proc {|environ| "Monitoring isn't enabled for the [#{environ.env}] environment." },
         | 
| 10 11 | 
             
                      :check => proc { |context| context.config.value('monitor') },
         | 
| 12 | 
            +
                      :severity => :info,
         | 
| 11 13 | 
             
                    },
         | 
| 12 14 |  | 
| 13 15 | 
             
                    PRECONDITION_APP_NAME = {
         | 
| 14 16 | 
             
                      :message => proc {|environ| "An application name could not be determined. Specify the :name value in scout_apm.yml." },
         | 
| 15 17 | 
             
                      :check => proc { |context| context.environment.application_name },
         | 
| 18 | 
            +
                      :severity => :warn,
         | 
| 16 19 | 
             
                    },
         | 
| 17 20 |  | 
| 18 21 | 
             
                    PRECONDITION_INTERACTIVE = {
         | 
| 19 22 | 
             
                      :message => proc {|environ| "Agent attempting to load in interactive mode." },
         | 
| 20 23 | 
             
                      :check => proc { |context| ! context.environment.interactive? },
         | 
| 24 | 
            +
                      :severity => :info,
         | 
| 21 25 | 
             
                    },
         | 
| 22 26 |  | 
| 23 27 | 
             
                    PRECONDITION_DETECTED_SERVER = {
         | 
| @@ -28,16 +32,19 @@ module ScoutApm | |
| 28 32 |  | 
| 29 33 | 
             
                        !app_server_missing && !background_job_missing
         | 
| 30 34 | 
             
                      },
         | 
| 35 | 
            +
                      :severity => :info,
         | 
| 31 36 | 
             
                    },
         | 
| 32 37 |  | 
| 33 38 | 
             
                    PRECONDITION_ALREADY_STARTED = {
         | 
| 34 39 | 
             
                      :message => proc {|environ| "Already started agent." },
         | 
| 35 40 | 
             
                      :check => proc { |context| !context.started? },
         | 
| 41 | 
            +
                      :severity => :info,
         | 
| 36 42 | 
             
                    },
         | 
| 37 43 |  | 
| 38 44 | 
             
                    PRECONDITION_OLD_SCOUT_RAILS = {
         | 
| 39 45 | 
             
                      :message => proc {|environ| "ScoutAPM is incompatible with the old Scout Rails plugin. Please remove scout_rails from your Gemfile" },
         | 
| 40 46 | 
             
                      :check => proc { !defined?(::ScoutRails) },
         | 
| 47 | 
            +
                      :severity => :warn,
         | 
| 41 48 | 
             
                    },
         | 
| 42 49 | 
             
                  ]
         | 
| 43 50 |  | 
| @@ -45,13 +52,18 @@ module ScoutApm | |
| 45 52 | 
             
                    @check_result ||=
         | 
| 46 53 | 
             
                      begin
         | 
| 47 54 | 
             
                        failed_preconditions = PRECONDITIONS.inject(Array.new) { |errors, condition|
         | 
| 48 | 
            -
                           | 
| 49 | 
            -
             | 
| 55 | 
            +
                          unless condition[:check].call(context)
         | 
| 56 | 
            +
                            errors << {
         | 
| 57 | 
            +
                              :severity => condition[:severity],
         | 
| 58 | 
            +
                              :message => condition[:message].call(context.environment),
         | 
| 59 | 
            +
                            }
         | 
| 60 | 
            +
                          end
         | 
| 61 | 
            +
             | 
| 50 62 | 
             
                          errors
         | 
| 51 63 | 
             
                        }
         | 
| 52 64 |  | 
| 53 65 | 
             
                        if failed_preconditions.any?
         | 
| 54 | 
            -
                          failed_preconditions.each {| | 
| 66 | 
            +
                          failed_preconditions.each {|error| context.logger.send(error[:severity], error[:message]) }
         | 
| 55 67 | 
             
                          force? # if forced, return true anyway
         | 
| 56 68 | 
             
                        else
         | 
| 57 69 | 
             
                          # No errors, we met preconditions
         | 
| @@ -30,7 +30,7 @@ module ScoutApm | |
| 30 30 |  | 
| 31 31 | 
             
                      ActionDispatch::MiddlewareStack::Middleware.class_eval do
         | 
| 32 32 | 
             
                        def build(app)
         | 
| 33 | 
            -
                          logger.info(" | 
| 33 | 
            +
                          ScoutApm::Agent.instance.context.logger.info("Instrumenting Middleware #{klass.name}")
         | 
| 34 34 | 
             
                          new_mw = klass.new(app, *args, &block)
         | 
| 35 35 | 
             
                          MiddlewareWrapper.new(new_mw, klass.name)
         | 
| 36 36 | 
             
                        end
         | 
    
        data/lib/scout_apm/tracer.rb
    CHANGED
    
    | @@ -12,31 +12,36 @@ module ScoutApm | |
| 12 12 | 
             
                  klass.extend ClassMethods
         | 
| 13 13 | 
             
                end
         | 
| 14 14 |  | 
| 15 | 
            +
                # Type: the Layer type - "View" or similar
         | 
| 16 | 
            +
                # Name: specific name - "users/_gravatar". The object must respond to "#to_s". This allows us to be more efficient - in most cases, the metric name isn't needed unless we are processing a slow transaction.
         | 
| 17 | 
            +
                # A Block: The code to be instrumented
         | 
| 18 | 
            +
                #
         | 
| 19 | 
            +
                # Options:
         | 
| 20 | 
            +
                # * :ignore_children - will not instrument any method calls beneath this call. Example use case: InfluxDB uses Net::HTTP, which is instrumented. However, we can provide more specific data if we know we're doing an influx call, so we'd rather just instrument the Influx call and ignore Net::HTTP.
         | 
| 21 | 
            +
                #   when rendering the transaction tree in the UI.
         | 
| 22 | 
            +
                # * :desc - Additional capture, SQL, or HTTP url or similar
         | 
| 23 | 
            +
                # * :scope - set to true if you want to make this layer a subscope
         | 
| 24 | 
            +
                def self.instrument(type, name, options={}) # Takes a block
         | 
| 25 | 
            +
                  layer = ScoutApm::Layer.new(type, name)
         | 
| 26 | 
            +
                  layer.desc = options[:desc] if options[:desc]
         | 
| 27 | 
            +
                  layer.subscopable!          if options[:scope]
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                  req = ScoutApm::RequestManager.lookup
         | 
| 30 | 
            +
                  req.start_layer(layer)
         | 
| 31 | 
            +
                  req.ignore_children! if options[:ignore_children]
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                  begin
         | 
| 34 | 
            +
                    yield
         | 
| 35 | 
            +
                  ensure
         | 
| 36 | 
            +
                    req.acknowledge_children! if options[:ignore_children]
         | 
| 37 | 
            +
                    req.stop_layer
         | 
| 38 | 
            +
                  end
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
             | 
| 15 41 | 
             
                module ClassMethods
         | 
| 16 | 
            -
                  #  | 
| 17 | 
            -
                   | 
| 18 | 
            -
             | 
| 19 | 
            -
                  #
         | 
| 20 | 
            -
                  # Options:
         | 
| 21 | 
            -
                  # * :ignore_children - will not instrument any method calls beneath this call. Example use case: InfluxDB uses Net::HTTP, which is instrumented. However, we can provide more specific data if we know we're doing an influx call, so we'd rather just instrument the Influx call and ignore Net::HTTP.
         | 
| 22 | 
            -
                  #   when rendering the transaction tree in the UI.
         | 
| 23 | 
            -
                  # * :desc - Additional capture, SQL, or HTTP url or similar
         | 
| 24 | 
            -
                  # * :scope - set to true if you want to make this layer a subscope
         | 
| 25 | 
            -
                  def instrument(type, name, options={}) # Takes a block
         | 
| 26 | 
            -
                    layer = ScoutApm::Layer.new(type, name)
         | 
| 27 | 
            -
                    layer.desc = options[:desc] if options[:desc]
         | 
| 28 | 
            -
                    layer.subscopable!          if options[:scope]
         | 
| 29 | 
            -
             | 
| 30 | 
            -
                    req = ScoutApm::RequestManager.lookup
         | 
| 31 | 
            -
                    req.start_layer(layer)
         | 
| 32 | 
            -
                    req.ignore_children! if options[:ignore_children]
         | 
| 33 | 
            -
             | 
| 34 | 
            -
                    begin
         | 
| 35 | 
            -
                      yield
         | 
| 36 | 
            -
                    ensure
         | 
| 37 | 
            -
                      req.acknowledge_children! if options[:ignore_children]
         | 
| 38 | 
            -
                      req.stop_layer
         | 
| 39 | 
            -
                    end
         | 
| 42 | 
            +
                  # See ScoutApm::Tracer.instrument
         | 
| 43 | 
            +
                  def instrument(type, name, options={}, &block)
         | 
| 44 | 
            +
                    ScoutApm::Tracer.instrument(type, name, options, &block)
         | 
| 40 45 | 
             
                  end
         | 
| 41 46 |  | 
| 42 47 | 
             
                  # Wraps a method in a call to #instrument via aggressive monkey patching.
         | 
| @@ -85,7 +90,6 @@ module ScoutApm | |
| 85 90 | 
             
                  end
         | 
| 86 91 |  | 
| 87 92 | 
             
                  def _instrumented_method_string(instrumented_name, uninstrumented_name, type, name, options={})
         | 
| 88 | 
            -
                    klass = (self === Module) ? "self" : "self.class"
         | 
| 89 93 | 
             
                    method_str = <<-EOF
         | 
| 90 94 | 
             
                    def #{instrumented_name}(*args, &block)
         | 
| 91 95 | 
             
                      name = begin
         | 
| @@ -95,7 +99,7 @@ module ScoutApm | |
| 95 99 | 
             
                               "Unknown"
         | 
| 96 100 | 
             
                             end
         | 
| 97 101 |  | 
| 98 | 
            -
                       | 
| 102 | 
            +
                      ::ScoutApm::Tracer.instrument( "#{type}",
         | 
| 99 103 | 
             
                                           name,
         | 
| 100 104 | 
             
                                           {:scope => #{options[:scope] || false}}
         | 
| 101 105 | 
             
                                         ) do
         | 
| @@ -38,6 +38,10 @@ module ScoutApm | |
| 38 38 | 
             
                # An object that responds to `record!(TrackedRequest)` to store this tracked request
         | 
| 39 39 | 
             
                attr_reader :recorder
         | 
| 40 40 |  | 
| 41 | 
            +
                # If specified, an override for the name of the request. If unspecified,
         | 
| 42 | 
            +
                # the name is determined from the name of the Controller or Job layer.
         | 
| 43 | 
            +
                attr_accessor :name_override
         | 
| 44 | 
            +
             | 
| 41 45 | 
             
                # When we see these layers, it means a real request is going through the
         | 
| 42 46 | 
             
                # system. We toggle a flag to turn on some slightly more expensive
         | 
| 43 47 | 
             
                # instrumentation (backtrace collection and the like) that would be too
         | 
| @@ -294,6 +298,8 @@ module ScoutApm | |
| 294 298 | 
             
                  # Bail out early if the user asked us to ignore this uri
         | 
| 295 299 | 
             
                  return if @agent_context.ignored_uris.ignore?(annotations[:uri])
         | 
| 296 300 |  | 
| 301 | 
            +
                  apply_name_override
         | 
| 302 | 
            +
             | 
| 297 303 | 
             
                  converters = [
         | 
| 298 304 | 
             
                    LayerConverters::Histograms,
         | 
| 299 305 | 
             
                    LayerConverters::MetricConverter,
         | 
| @@ -491,5 +497,16 @@ module ScoutApm | |
| 491 497 | 
             
                  @recorder = @agent_context.recorder
         | 
| 492 498 | 
             
                  @store = @agent_context.store
         | 
| 493 499 | 
             
                end
         | 
| 500 | 
            +
             | 
| 501 | 
            +
                private
         | 
| 502 | 
            +
             | 
| 503 | 
            +
                def apply_name_override
         | 
| 504 | 
            +
                  return unless name_override
         | 
| 505 | 
            +
             | 
| 506 | 
            +
                  scope_layer = layer_finder.scope
         | 
| 507 | 
            +
                  if scope_layer
         | 
| 508 | 
            +
                    scope_layer.name = name_override
         | 
| 509 | 
            +
                  end
         | 
| 510 | 
            +
                end
         | 
| 494 511 | 
             
              end
         | 
| 495 512 | 
             
            end
         | 
| @@ -0,0 +1,13 @@ | |
| 1 | 
            +
            module ScoutApm
         | 
| 2 | 
            +
              module Transaction
         | 
| 3 | 
            +
                # Ignores the current request
         | 
| 4 | 
            +
                def self.ignore!
         | 
| 5 | 
            +
                  ::ScoutApm::RequestManager.lookup.ignore_request!
         | 
| 6 | 
            +
                end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                # Renames the last Controller or Job layer
         | 
| 9 | 
            +
                def self.rename(name)
         | 
| 10 | 
            +
                  ::ScoutApm::RequestManager.lookup.name_override = name
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
            end
         | 
    
        data/lib/scout_apm/version.rb
    CHANGED
    
    
    
        data/scout_apm.gemspec
    CHANGED
    
    | @@ -23,13 +23,17 @@ Gem::Specification.new do |s| | |
| 23 23 | 
             
              s.extensions << 'ext/rusage/extconf.rb'
         | 
| 24 24 |  | 
| 25 25 | 
             
              s.add_development_dependency "minitest"
         | 
| 26 | 
            -
              s.add_development_dependency  | 
| 26 | 
            +
              s.add_development_dependency "mocha"
         | 
| 27 27 | 
             
              s.add_development_dependency "pry"
         | 
| 28 | 
            -
              s.add_development_dependency "m"
         | 
| 29 28 | 
             
              s.add_development_dependency "simplecov"
         | 
| 30 29 | 
             
              s.add_development_dependency "rake-compiler"
         | 
| 31 30 | 
             
              s.add_development_dependency "addressable"
         | 
| 32 | 
            -
              s.add_development_dependency "guard"
         | 
| 33 | 
            -
              s.add_development_dependency "guard-minitest"
         | 
| 34 31 | 
             
              s.add_development_dependency "activesupport"
         | 
| 32 | 
            +
             | 
| 33 | 
            +
              if RUBY_VERSION >= "1.9.3"
         | 
| 34 | 
            +
                s.add_development_dependency "rubocop"
         | 
| 35 | 
            +
                s.add_development_dependency "guard"
         | 
| 36 | 
            +
                s.add_development_dependency "guard-minitest"
         | 
| 37 | 
            +
                s.add_development_dependency "m"
         | 
| 38 | 
            +
              end
         | 
| 35 39 | 
             
            end
         | 
    
        data/test/test_helper.rb
    CHANGED
    
    | @@ -68,6 +68,7 @@ end | |
| 68 68 | 
             
            # Helpers available to all tests
         | 
| 69 69 | 
             
            class Minitest::Test
         | 
| 70 70 | 
             
              def setup
         | 
| 71 | 
            +
                Thread.current[:scout_request] = nil
         | 
| 71 72 | 
             
                reopen_logger
         | 
| 72 73 | 
             
                FileUtils.mkdir_p(DATA_FILE_DIR)
         | 
| 73 74 | 
             
                ENV['SCOUT_DATA_FILE'] = DATA_FILE_PATH
         | 
| @@ -106,6 +107,26 @@ class Minitest::Test | |
| 106 107 | 
             
              DATA_FILE_PATH = "#{DATA_FILE_DIR}/scout_apm.db"
         | 
| 107 108 | 
             
            end
         | 
| 108 109 |  | 
| 110 | 
            +
            class FakeRecorder
         | 
| 111 | 
            +
              attr_reader :requests
         | 
| 112 | 
            +
             | 
| 113 | 
            +
              def initialize
         | 
| 114 | 
            +
                @requests = []
         | 
| 115 | 
            +
              end
         | 
| 116 | 
            +
             | 
| 117 | 
            +
              def start
         | 
| 118 | 
            +
                # nothing to do
         | 
| 119 | 
            +
                self
         | 
| 120 | 
            +
              end
         | 
| 121 | 
            +
             | 
| 122 | 
            +
              def stop
         | 
| 123 | 
            +
                # nothing to do
         | 
| 124 | 
            +
              end
         | 
| 125 | 
            +
             | 
| 126 | 
            +
              def record!(request)
         | 
| 127 | 
            +
                @requests << request
         | 
| 128 | 
            +
              end
         | 
| 129 | 
            +
            end
         | 
| 109 130 |  | 
| 110 131 | 
             
            module CustomAsserts
         | 
| 111 132 | 
             
              def assert_false(thing)
         | 
    
        data/test/unit/config_test.rb
    CHANGED
    
    | @@ -33,7 +33,7 @@ class ConfigTest < Minitest::Test | |
| 33 33 |  | 
| 34 34 | 
             
              def test_loading_file_without_env_in_file
         | 
| 35 35 | 
             
                conf_file = File.expand_path("../../data/config_test_1.yml", __FILE__)
         | 
| 36 | 
            -
                conf = ScoutApm::Config.with_file(@context, conf_file, environment | 
| 36 | 
            +
                conf = ScoutApm::Config.with_file(@context, conf_file, :environment => "staging")
         | 
| 37 37 |  | 
| 38 38 | 
             
                assert_equal "info", conf.value('log_level') # the default value
         | 
| 39 39 | 
             
                assert_nil nil, conf.value('name')         # the default value
         | 
| @@ -7,7 +7,8 @@ class DbQueryMetricSetTest < Minitest::Test | |
| 7 7 | 
             
              def test_hard_limit
         | 
| 8 8 | 
             
                config = make_fake_config(
         | 
| 9 9 | 
             
                  'database_metric_limit' => 5, # The hard limit on db metrics
         | 
| 10 | 
            -
                  'database_metric_report_limit' => 2 | 
| 10 | 
            +
                  'database_metric_report_limit' => 2
         | 
| 11 | 
            +
                )
         | 
| 11 12 | 
             
                context = ScoutApm::AgentContext.new().tap{|c| c.config = config }
         | 
| 12 13 | 
             
                set = DbQueryMetricSet.new(context)
         | 
| 13 14 |  | 
| @@ -24,7 +25,8 @@ class DbQueryMetricSetTest < Minitest::Test | |
| 24 25 | 
             
              def test_report_limit
         | 
| 25 26 | 
             
                config = make_fake_config(
         | 
| 26 27 | 
             
                  'database_metric_limit' => 50, # much larger max, uninterested in hitting it.
         | 
| 27 | 
            -
                  'database_metric_report_limit' => 2 | 
| 28 | 
            +
                  'database_metric_report_limit' => 2
         | 
| 29 | 
            +
                )
         | 
| 28 30 | 
             
                context = ScoutApm::AgentContext.new().tap{|c| c.config = config }
         | 
| 29 31 | 
             
                set = DbQueryMetricSet.new(context)
         | 
| 30 32 | 
             
                set << fake_stat("a", 10)
         | 
| @@ -41,7 +43,8 @@ class DbQueryMetricSetTest < Minitest::Test | |
| 41 43 | 
             
              def test_combine
         | 
| 42 44 | 
             
                config = make_fake_config(
         | 
| 43 45 | 
             
                  'database_metric_limit' => 5, # The hard limit on db metrics
         | 
| 44 | 
            -
                  'database_metric_report_limit' => 2 | 
| 46 | 
            +
                  'database_metric_report_limit' => 2
         | 
| 47 | 
            +
                )
         | 
| 45 48 | 
             
                context = ScoutApm::AgentContext.new().tap{|c| c.config = config }
         | 
| 46 49 | 
             
                set1 = DbQueryMetricSet.new(context)
         | 
| 47 50 | 
             
                set1 << fake_stat("a", 10)
         | 
| @@ -51,13 +54,14 @@ class DbQueryMetricSetTest < Minitest::Test | |
| 51 54 | 
             
                set2 << fake_stat("d", 20)
         | 
| 52 55 |  | 
| 53 56 | 
             
                combined = set1.combine!(set2)
         | 
| 54 | 
            -
                assert_equal ["a", "b", "c", "d"], combined.metrics.map{|_k, m| m.key}
         | 
| 57 | 
            +
                assert_equal ["a", "b", "c", "d"], combined.metrics.map{|_k, m| m.key}.sort
         | 
| 55 58 | 
             
              end
         | 
| 56 59 |  | 
| 57 60 | 
             
              def fake_stat(key, call_time)
         | 
| 58 61 | 
             
                OpenStruct.new(
         | 
| 59 | 
            -
                  key | 
| 60 | 
            -
                  call_time | 
| 62 | 
            +
                  :key => key,
         | 
| 63 | 
            +
                  :call_time => call_time
         | 
| 64 | 
            +
                )
         | 
| 61 65 | 
             
              end
         | 
| 62 66 | 
             
            end
         | 
| 63 67 | 
             
            end
         | 
| @@ -8,20 +8,20 @@ class DbQueryMetricStatsTest < Minitest::Test | |
| 8 8 | 
             
                stat = build("table", "op", "Controller/public/index", 1, 10, 20)
         | 
| 9 9 |  | 
| 10 10 | 
             
                assert_equal({
         | 
| 11 | 
            -
                  model_name | 
| 12 | 
            -
                  operation | 
| 13 | 
            -
                  call_count | 
| 14 | 
            -
                  transaction_count | 
| 15 | 
            -
                  scope | 
| 16 | 
            -
                  histogram | 
| 17 | 
            -
             | 
| 18 | 
            -
                  max_call_time | 
| 19 | 
            -
                  min_call_time | 
| 20 | 
            -
                  call_time | 
| 21 | 
            -
             | 
| 22 | 
            -
                  max_rows_returned | 
| 23 | 
            -
                  min_rows_returned | 
| 24 | 
            -
                  rows_returned | 
| 11 | 
            +
                  :model_name => "table",
         | 
| 12 | 
            +
                  :operation => "op",
         | 
| 13 | 
            +
                  :call_count => 1,
         | 
| 14 | 
            +
                  :transaction_count => 0,
         | 
| 15 | 
            +
                  :scope => "Controller/public/index",
         | 
| 16 | 
            +
                  :histogram => [[10.0, 1]],
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                  :max_call_time => 10.0,
         | 
| 19 | 
            +
                  :min_call_time => 10.0,
         | 
| 20 | 
            +
                  :call_time => 10.0,
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  :max_rows_returned => 20,
         | 
| 23 | 
            +
                  :min_rows_returned => 20,
         | 
| 24 | 
            +
                  :rows_returned => 20,
         | 
| 25 25 | 
             
                }, stat.as_json)
         | 
| 26 26 | 
             
              end
         | 
| 27 27 |  | 
| @@ -90,9 +90,9 @@ class DbQueryMetricStatsTest < Minitest::Test | |
| 90 90 | 
             
              #  Helpers  #
         | 
| 91 91 | 
             
              #############
         | 
| 92 92 | 
             
              DEFAULTS = {
         | 
| 93 | 
            -
                call_count | 
| 94 | 
            -
                call_time | 
| 95 | 
            -
                rows_returned | 
| 93 | 
            +
                :call_count => 1,
         | 
| 94 | 
            +
                :call_time => 10.0,
         | 
| 95 | 
            +
                :rows_returned => 20,
         | 
| 96 96 | 
             
              }
         | 
| 97 97 |  | 
| 98 98 | 
             
              def build(model_name="User",
         | 
    
        data/test/unit/histogram_test.rb
    CHANGED
    
    | @@ -35,8 +35,8 @@ class HistogramTest < Minitest::Test | |
| 35 35 | 
             
                  end
         | 
| 36 36 | 
             
                }
         | 
| 37 37 |  | 
| 38 | 
            -
                assert_equal 1.5, hist.quantile(0) | 
| 39 | 
            -
                assert_equal 9.5, hist.quantile(100) | 
| 38 | 
            +
                assert_equal 1.5, round(hist.quantile(0), 1)
         | 
| 39 | 
            +
                assert_equal 9.5, round(hist.quantile(100), 1)
         | 
| 40 40 | 
             
              end
         | 
| 41 41 |  | 
| 42 42 | 
             
              def test_combine
         | 
| @@ -55,8 +55,8 @@ class HistogramTest < Minitest::Test | |
| 55 55 | 
             
                }
         | 
| 56 56 |  | 
| 57 57 | 
             
                combined = hist1.combine!(hist2)
         | 
| 58 | 
            -
                assert_equal 1.5, combined.quantile(0) | 
| 59 | 
            -
                assert_equal 9.5, combined.quantile(100) | 
| 58 | 
            +
                assert_equal 1.5, round(combined.quantile(0), 1)
         | 
| 59 | 
            +
                assert_equal 9.5, round(combined.quantile(100), 1)
         | 
| 60 60 | 
             
                assert_equal 200, combined.total
         | 
| 61 61 | 
             
              end
         | 
| 62 62 |  | 
| @@ -103,5 +103,12 @@ class HistogramTest < Minitest::Test | |
| 103 103 |  | 
| 104 104 | 
             
                assert_equal 5.5, hist.mean
         | 
| 105 105 | 
             
              end
         | 
| 106 | 
            +
             | 
| 107 | 
            +
              private
         | 
| 108 | 
            +
             | 
| 109 | 
            +
              # Ruby 1.8 compatible round with precision
         | 
| 110 | 
            +
              def round(number, precision)
         | 
| 111 | 
            +
                ((number * 10**precision).round.to_f) / (10**precision)
         | 
| 112 | 
            +
              end
         | 
| 106 113 | 
             
            end
         | 
| 107 114 |  | 
| @@ -2,7 +2,7 @@ require 'test_helper' | |
| 2 2 |  | 
| 3 3 | 
             
            require 'scout_apm/instruments/net_http'
         | 
| 4 4 |  | 
| 5 | 
            -
            require 'addressable'
         | 
| 5 | 
            +
            require 'addressable/uri'
         | 
| 6 6 |  | 
| 7 7 | 
             
            class NetHttpTest < Minitest::Test
         | 
| 8 8 | 
             
              def setup
         | 
| @@ -11,7 +11,12 @@ class NetHttpTest < Minitest::Test | |
| 11 11 | 
             
              end
         | 
| 12 12 |  | 
| 13 13 | 
             
              def test_request_scout_description_for_uri
         | 
| 14 | 
            -
                 | 
| 14 | 
            +
                if RUBY_VERSION <= '1.9.3'
         | 
| 15 | 
            +
                  req = Net::HTTP::Get.new('/here')
         | 
| 16 | 
            +
                else
         | 
| 17 | 
            +
                  req = Net::HTTP::Get.new(URI('http://example.org/here'))
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
             | 
| 15 20 | 
             
                assert_equal '/here', Net::HTTP.new('').request_scout_description(req)
         | 
| 16 21 | 
             
              end
         | 
| 17 22 |  | 
| @@ -25,6 +25,10 @@ class DepthFirstWalkerTest < Minitest::Test | |
| 25 25 | 
             
              # / \
         | 
| 26 26 | 
             
              # F  G
         | 
| 27 27 | 
             
              def test_walk_interesting_tree
         | 
| 28 | 
            +
                # The test could be rewritten to support 1.8.7, but it would likely be much
         | 
| 29 | 
            +
                # harder to read.
         | 
| 30 | 
            +
                skip "Lack of set ordering in Ruby 1.8.7 prevents this test from running correctly" if RUBY_VERSION.start_with?("1.8.")
         | 
| 31 | 
            +
             | 
| 28 32 | 
             
                calls = []
         | 
| 29 33 | 
             
                a = Layer.new("A", "x")
         | 
| 30 34 | 
             
                b = Layer.new("B", "x")
         | 
| @@ -4,7 +4,7 @@ | |
| 4 4 | 
             
            module ScoutApm
         | 
| 5 5 | 
             
              module LayerConverters
         | 
| 6 6 | 
             
                module Stubs
         | 
| 7 | 
            -
                  def faux_walker(subscope_stubs | 
| 7 | 
            +
                  def faux_walker(subscope_stubs = true)
         | 
| 8 8 | 
             
                    @w ||= stub
         | 
| 9 9 |  | 
| 10 10 | 
             
                    if subscope_stubs && !@w_set_subscope_stubs
         | 
| @@ -21,7 +21,7 @@ module ScoutApm | |
| 21 21 |  | 
| 22 22 | 
             
                  def faux_layer_finder
         | 
| 23 23 | 
             
                    @layer_finder ||= stub
         | 
| 24 | 
            -
                    @layer_finder.stubs(scope | 
| 24 | 
            +
                    @layer_finder.stubs(:scope => stub)
         | 
| 25 25 | 
             
                    @layer_finder
         | 
| 26 26 | 
             
                  end
         | 
| 27 27 |  | 
    
        data/test/unit/logger_test.rb
    CHANGED
    
    | @@ -5,7 +5,7 @@ require 'scout_apm/logger' | |
| 5 5 |  | 
| 6 6 | 
             
            class LoggerTest < Minitest::Test
         | 
| 7 7 | 
             
              def setup
         | 
| 8 | 
            -
                @env_root = Pathname.new(File.dirname(__FILE__) | 
| 8 | 
            +
                @env_root = Pathname.new(File.expand_path(File.join(File.dirname(__FILE__), "..", "..")))
         | 
| 9 9 | 
             
                FileUtils.mkdir_p(@env_root + "log")
         | 
| 10 10 | 
             
              end
         | 
| 11 11 |  | 
| @@ -46,7 +46,7 @@ class PayloadSerializerTest < Minitest::Test | |
| 46 46 | 
             
                    stats.min_call_time = 0.034881757
         | 
| 47 47 | 
             
                    stats.sum_of_squares = 0.007382350213180609
         | 
| 48 48 | 
             
                    stats.total_call_time = 0.113403176
         | 
| 49 | 
            -
                    stats.total_exclusive_time = 0. | 
| 49 | 
            +
                    stats.total_exclusive_time = 0.078132088
         | 
| 50 50 | 
             
                  }
         | 
| 51 51 | 
             
                }
         | 
| 52 52 | 
             
                payload = ScoutApm::Serializers::PayloadSerializerToJson.serialize({}, metrics, {}, [], [], [], {})
         | 
| @@ -83,11 +83,12 @@ class PayloadSerializerTest < Minitest::Test | |
| 83 83 | 
             
                    "max_call_time" => 0.078521419,
         | 
| 84 84 | 
             
                    "min_call_time" => 0.034881757,
         | 
| 85 85 | 
             
                    "total_call_time" => 0.113403176,
         | 
| 86 | 
            -
                    "total_exclusive_time" => 0. | 
| 86 | 
            +
                    "total_exclusive_time" => 0.078132088,
         | 
| 87 87 | 
             
                    "traces" => []
         | 
| 88 88 | 
             
                  }
         | 
| 89 89 | 
             
                ]
         | 
| 90 | 
            -
                assert_equal formatted_metrics, | 
| 90 | 
            +
                assert_equal formatted_metrics,
         | 
| 91 | 
            +
                  JSON.parse(payload)["metrics"].sort_by { |m| m["key"]["bucket"] }
         | 
| 91 92 | 
             
              end
         | 
| 92 93 |  | 
| 93 94 | 
             
              def test_escapes_json_quotes
         | 
| @@ -10,6 +10,8 @@ module ScoutApm | |
| 10 10 | 
             
                  end
         | 
| 11 11 |  | 
| 12 12 | 
             
                  def test_postgres_simple_select_of_first
         | 
| 13 | 
            +
                    skip "Broken on Ruby 1.8.7 because regular expressions do not support look-behinds" if RUBY_VERSION.start_with?("1.8.")
         | 
| 14 | 
            +
             | 
| 13 15 | 
             
                    sql = %q|SELECT  "users".* FROM "users"  ORDER BY "users"."id" ASC LIMIT 1|
         | 
| 14 16 | 
             
                    ss = SqlSanitizer.new(sql).tap{ |it| it.database_engine = :postgres }
         | 
| 15 17 | 
             
                    assert_equal %q|SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT 1|, ss.to_s
         | 
| @@ -55,6 +57,8 @@ module ScoutApm | |
| 55 57 | 
             
                  end
         | 
| 56 58 |  | 
| 57 59 | 
             
                  def test_mysql_limit
         | 
| 60 | 
            +
                    skip "Broken on Ruby 1.8.7 because regular expressions do not support look-behinds" if RUBY_VERSION.start_with?("1.8.")
         | 
| 61 | 
            +
             | 
| 58 62 | 
             
                    sql = %q|SELECT  `blogs`.* FROM `blogs`  ORDER BY `blogs`.`id` ASC LIMIT 1|
         | 
| 59 63 | 
             
                    ss = SqlSanitizer.new(sql).tap{ |it| it.database_engine = :mysql }
         | 
| 60 64 | 
             
                    assert_equal %q|SELECT  `blogs`.* FROM `blogs`  ORDER BY `blogs`.`id` ASC LIMIT 1|, ss.to_s
         | 
| @@ -86,6 +90,8 @@ module ScoutApm | |
| 86 90 | 
             
                  end
         | 
| 87 91 |  | 
| 88 92 | 
             
                  def test_scrubs_invalid_encoding
         | 
| 93 | 
            +
                    skip "Ruby 1.8.7 has no concept of encoding" if RUBY_VERSION.start_with?("1.8.")
         | 
| 94 | 
            +
             | 
| 89 95 | 
             
                    sql = "SELECT `blogs`.* FROM `blogs` WHERE (title = 'a\255c')".force_encoding('UTF-8')
         | 
| 90 96 | 
             
                    assert_equal false, sql.valid_encoding?
         | 
| 91 97 | 
             
                    ss = SqlSanitizer.new(sql).tap{ |it| it.database_engine = :mysql }
         | 
| @@ -0,0 +1,76 @@ | |
| 1 | 
            +
            require 'test_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            class TracerTest < Minitest::Test
         | 
| 4 | 
            +
              def test_instrument
         | 
| 5 | 
            +
                recorder = FakeRecorder.new
         | 
| 6 | 
            +
                ScoutApm::Agent.instance.context.recorder = recorder
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                invoked = false
         | 
| 9 | 
            +
                ScoutApm::Tracer.instrument("Test", "name") do
         | 
| 10 | 
            +
                  invoked = true
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                assert invoked, "instrumented code was not invoked"
         | 
| 14 | 
            +
                assert_recorded(recorder, "Test", "name")
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              def test_instrument_included
         | 
| 18 | 
            +
                recorder = FakeRecorder.new
         | 
| 19 | 
            +
                ScoutApm::Agent.instance.context.recorder = recorder
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                klass = Class.new { include ScoutApm::Tracer }
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                invoked = false
         | 
| 24 | 
            +
                klass.instrument("Test", "name") do
         | 
| 25 | 
            +
                  invoked = true
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                assert invoked, "instrumented code was not invoked"
         | 
| 29 | 
            +
                assert_recorded(recorder, "Test", "name")
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
              def test_instrument_inside_method
         | 
| 33 | 
            +
                recorder = FakeRecorder.new
         | 
| 34 | 
            +
                ScoutApm::Agent.instance.context.recorder = recorder
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                klass = Class.new { include ScoutApm::Tracer }
         | 
| 37 | 
            +
                klass.class_eval %q{
         | 
| 38 | 
            +
                attr_reader :invoked
         | 
| 39 | 
            +
                def work
         | 
| 40 | 
            +
                  ScoutApm::Tracer.instrument("Test", "name") do
         | 
| 41 | 
            +
                    @invoked = true
         | 
| 42 | 
            +
                  end
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
                }
         | 
| 45 | 
            +
                klass_instance = klass.new
         | 
| 46 | 
            +
                klass_instance.work
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                assert klass_instance.invoked, "instrumented code was not invoked"
         | 
| 49 | 
            +
                assert_recorded(recorder, "Test", "name")
         | 
| 50 | 
            +
              end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
              def test_instrument_method
         | 
| 53 | 
            +
                recorder = FakeRecorder.new
         | 
| 54 | 
            +
                ScoutApm::Agent.instance.context.recorder = recorder
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                klass = Class.new { include ScoutApm::Tracer }
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                invoked = false
         | 
| 59 | 
            +
                klass.send(:define_method, :work) { invoked = true }
         | 
| 60 | 
            +
                klass.instrument_method(:work, :type => "Test", :name => "name")
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                klass.new.work
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                assert invoked, "instrumented code was not invoked"
         | 
| 65 | 
            +
                assert_recorded(recorder, "Test", "name")
         | 
| 66 | 
            +
              end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
              private
         | 
| 69 | 
            +
             | 
| 70 | 
            +
              def assert_recorded(recorder, type, name)
         | 
| 71 | 
            +
                req = recorder.requests.first
         | 
| 72 | 
            +
                assert req, "recorder recorded no layers"
         | 
| 73 | 
            +
                assert_equal type, req.root_layer.type
         | 
| 74 | 
            +
                assert_equal name, req.root_layer.name
         | 
| 75 | 
            +
              end
         | 
| 76 | 
            +
            end
         | 
| @@ -10,19 +10,6 @@ class TrackedRequestDumpAndLoadTest < Minitest::Test | |
| 10 10 | 
             
                loaded = Marshal.load(dumped)
         | 
| 11 11 | 
             
                assert_false loaded.nil?
         | 
| 12 12 | 
             
              end
         | 
| 13 | 
            -
             | 
| 14 | 
            -
              def test_restore_store
         | 
| 15 | 
            -
                faux_store = ScoutApm::FakeStore.new
         | 
| 16 | 
            -
                context = ScoutApm::AgentContext.new
         | 
| 17 | 
            -
                tr = ScoutApm::TrackedRequest.new(context, faux_store)
         | 
| 18 | 
            -
                assert_equal faux_store, tr.instance_variable_get("@store")
         | 
| 19 | 
            -
             | 
| 20 | 
            -
                tr.prepare_to_dump!
         | 
| 21 | 
            -
                assert_nil tr.instance_variable_get("@store")
         | 
| 22 | 
            -
             | 
| 23 | 
            -
                tr.restore_store
         | 
| 24 | 
            -
                assert_equal context.store, tr.instance_variable_get("@store")
         | 
| 25 | 
            -
              end
         | 
| 26 13 | 
             
            end
         | 
| 27 14 |  | 
| 28 15 | 
             
            class TrackedRequestLayerManipulationTest < Minitest::Test
         | 
| @@ -48,4 +35,37 @@ class TrackedRequestLayerManipulationTest < Minitest::Test | |
| 48 35 |  | 
| 49 36 | 
             
                assert_equal "Controller", tr.current_layer.type
         | 
| 50 37 | 
             
              end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
              def test_name_override_controller
         | 
| 40 | 
            +
                # layers are Middleware -> Controller
         | 
| 41 | 
            +
                middleware_layer = ScoutApm::Layer.new("Middleware", "foo")
         | 
| 42 | 
            +
                controller_layer = ScoutApm::Layer.new("Controller", "users/index")
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                tr = ScoutApm::TrackedRequest.new(ScoutApm::AgentContext.new, ScoutApm::FakeStore.new)
         | 
| 45 | 
            +
                tr.start_layer(middleware_layer)
         | 
| 46 | 
            +
                tr.name_override = "override"
         | 
| 47 | 
            +
                tr.start_layer(controller_layer)
         | 
| 48 | 
            +
                tr.stop_layer
         | 
| 49 | 
            +
                tr.stop_layer
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                assert_equal "override", controller_layer.name
         | 
| 52 | 
            +
              end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
              def test_name_override_job
         | 
| 55 | 
            +
                # layers are Middleware -> Queue -> Job
         | 
| 56 | 
            +
                middleware_layer = ScoutApm::Layer.new("Middleware", "foo")
         | 
| 57 | 
            +
                queue_layer = ScoutApm::Layer.new("Queue", "bar")
         | 
| 58 | 
            +
                job_layer = ScoutApm::Layer.new("Job", "FooJob")
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                tr = ScoutApm::TrackedRequest.new(ScoutApm::AgentContext.new, ScoutApm::FakeStore.new)
         | 
| 61 | 
            +
                tr.start_layer(middleware_layer)
         | 
| 62 | 
            +
                tr.name_override = "override"
         | 
| 63 | 
            +
                tr.start_layer(queue_layer)
         | 
| 64 | 
            +
                tr.start_layer(job_layer)
         | 
| 65 | 
            +
                tr.stop_layer
         | 
| 66 | 
            +
                tr.stop_layer
         | 
| 67 | 
            +
                tr.stop_layer
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                assert_equal "override", job_layer.name
         | 
| 70 | 
            +
              end
         | 
| 51 71 | 
             
            end
         | 
| @@ -0,0 +1,14 @@ | |
| 1 | 
            +
            require 'test_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            class TransactionTest < Minitest::Test
         | 
| 4 | 
            +
              def test_ignore
         | 
| 5 | 
            +
                recorder = FakeRecorder.new
         | 
| 6 | 
            +
                ScoutApm::Agent.instance.context.recorder = recorder
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                ScoutApm::Tracer.instrument("Controller", "foo/bar") do
         | 
| 9 | 
            +
                  ScoutApm::Transaction.ignore!
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                assert_equal 0, recorder.requests.length
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
            end
         | 
    
        data/test/unit/utils/scm.rb
    CHANGED
    
    | @@ -1,4 +1,4 @@ | |
| 1 | 
            -
             | 
| 1 | 
            +
            require 'test_helper'
         | 
| 2 2 | 
             
            require 'scout_apm/utils/scm'
         | 
| 3 3 |  | 
| 4 4 | 
             
            class ScmTest < Minitest::Test
         | 
| @@ -14,4 +14,4 @@ class ScmTest < Minitest::Test | |
| 14 14 | 
             
              def test_relative_scm_path_not_blank_with_slashes
         | 
| 15 15 | 
             
                assert_equal 'src/app/models/person.rb', ScoutApm::Utils::Scm.relative_scm_path('app/models/person.rb', '/src/')
         | 
| 16 16 | 
             
              end
         | 
| 17 | 
            -
            end
         | 
| 17 | 
            +
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: scout_apm
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 3.0.0. | 
| 4 | 
            +
              version: 3.0.0.pre21
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Derek Haynes
         | 
| @@ -9,7 +9,7 @@ authors: | |
| 9 9 | 
             
            autorequire: 
         | 
| 10 10 | 
             
            bindir: bin
         | 
| 11 11 | 
             
            cert_chain: []
         | 
| 12 | 
            -
            date: 2018- | 
| 12 | 
            +
            date: 2018-03-06 00:00:00.000000000 Z
         | 
| 13 13 | 
             
            dependencies:
         | 
| 14 14 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 15 15 | 
             
              name: minitest
         | 
| @@ -54,7 +54,7 @@ dependencies: | |
| 54 54 | 
             
                  - !ruby/object:Gem::Version
         | 
| 55 55 | 
             
                    version: '0'
         | 
| 56 56 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 57 | 
            -
              name:  | 
| 57 | 
            +
              name: simplecov
         | 
| 58 58 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 59 59 | 
             
                requirements:
         | 
| 60 60 | 
             
                - - ">="
         | 
| @@ -68,7 +68,7 @@ dependencies: | |
| 68 68 | 
             
                  - !ruby/object:Gem::Version
         | 
| 69 69 | 
             
                    version: '0'
         | 
| 70 70 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 71 | 
            -
              name:  | 
| 71 | 
            +
              name: rake-compiler
         | 
| 72 72 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 73 73 | 
             
                requirements:
         | 
| 74 74 | 
             
                - - ">="
         | 
| @@ -82,7 +82,7 @@ dependencies: | |
| 82 82 | 
             
                  - !ruby/object:Gem::Version
         | 
| 83 83 | 
             
                    version: '0'
         | 
| 84 84 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 85 | 
            -
              name:  | 
| 85 | 
            +
              name: addressable
         | 
| 86 86 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 87 87 | 
             
                requirements:
         | 
| 88 88 | 
             
                - - ">="
         | 
| @@ -96,7 +96,21 @@ dependencies: | |
| 96 96 | 
             
                  - !ruby/object:Gem::Version
         | 
| 97 97 | 
             
                    version: '0'
         | 
| 98 98 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 99 | 
            -
              name:  | 
| 99 | 
            +
              name: activesupport
         | 
| 100 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 101 | 
            +
                requirements:
         | 
| 102 | 
            +
                - - ">="
         | 
| 103 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 104 | 
            +
                    version: '0'
         | 
| 105 | 
            +
              type: :development
         | 
| 106 | 
            +
              prerelease: false
         | 
| 107 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 108 | 
            +
                requirements:
         | 
| 109 | 
            +
                - - ">="
         | 
| 110 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 111 | 
            +
                    version: '0'
         | 
| 112 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 113 | 
            +
              name: rubocop
         | 
| 100 114 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 101 115 | 
             
                requirements:
         | 
| 102 116 | 
             
                - - ">="
         | 
| @@ -138,7 +152,7 @@ dependencies: | |
| 138 152 | 
             
                  - !ruby/object:Gem::Version
         | 
| 139 153 | 
             
                    version: '0'
         | 
| 140 154 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 141 | 
            -
              name:  | 
| 155 | 
            +
              name: m
         | 
| 142 156 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 143 157 | 
             
                requirements:
         | 
| 144 158 | 
             
                - - ">="
         | 
| @@ -163,6 +177,7 @@ extra_rdoc_files: [] | |
| 163 177 | 
             
            files:
         | 
| 164 178 | 
             
            - ".gitignore"
         | 
| 165 179 | 
             
            - ".rubocop.yml"
         | 
| 180 | 
            +
            - ".travis.yml"
         | 
| 166 181 | 
             
            - CHANGELOG.markdown
         | 
| 167 182 | 
             
            - Gemfile
         | 
| 168 183 | 
             
            - Guardfile
         | 
| @@ -297,6 +312,7 @@ files: | |
| 297 312 | 
             
            - lib/scout_apm/trace_compactor.rb
         | 
| 298 313 | 
             
            - lib/scout_apm/tracer.rb
         | 
| 299 314 | 
             
            - lib/scout_apm/tracked_request.rb
         | 
| 315 | 
            +
            - lib/scout_apm/transaction.rb
         | 
| 300 316 | 
             
            - lib/scout_apm/utils/active_record_metric_name.rb
         | 
| 301 317 | 
             
            - lib/scout_apm/utils/backtrace_parser.rb
         | 
| 302 318 | 
             
            - lib/scout_apm/utils/fake_stacks.rb
         | 
| @@ -346,7 +362,9 @@ files: | |
| 346 362 | 
             
            - test/unit/slow_request_policy_test.rb
         | 
| 347 363 | 
             
            - test/unit/sql_sanitizer_test.rb
         | 
| 348 364 | 
             
            - test/unit/store_test.rb
         | 
| 349 | 
            -
            - test/unit/ | 
| 365 | 
            +
            - test/unit/tracer_test.rb
         | 
| 366 | 
            +
            - test/unit/tracked_request_test.rb
         | 
| 367 | 
            +
            - test/unit/transaction_test.rb
         | 
| 350 368 | 
             
            - test/unit/utils/active_record_metric_name_test.rb
         | 
| 351 369 | 
             
            - test/unit/utils/backtrace_parser_test.rb
         | 
| 352 370 | 
             
            - test/unit/utils/numbers_test.rb
         | 
| @@ -411,7 +429,9 @@ test_files: | |
| 411 429 | 
             
            - test/unit/slow_request_policy_test.rb
         | 
| 412 430 | 
             
            - test/unit/sql_sanitizer_test.rb
         | 
| 413 431 | 
             
            - test/unit/store_test.rb
         | 
| 414 | 
            -
            - test/unit/ | 
| 432 | 
            +
            - test/unit/tracer_test.rb
         | 
| 433 | 
            +
            - test/unit/tracked_request_test.rb
         | 
| 434 | 
            +
            - test/unit/transaction_test.rb
         | 
| 415 435 | 
             
            - test/unit/utils/active_record_metric_name_test.rb
         | 
| 416 436 | 
             
            - test/unit/utils/backtrace_parser_test.rb
         | 
| 417 437 | 
             
            - test/unit/utils/numbers_test.rb
         |