diff --git a/features/.gitignore b/features/.gitignore new file mode 100644 index 000000000..eb601e3bf --- /dev/null +++ b/features/.gitignore @@ -0,0 +1 @@ +temp-bugsnag-lib \ No newline at end of file diff --git a/features/delayed_job.feature b/features/delayed_job.feature index bf7d3394d..db6357fed 100644 --- a/features/delayed_job.feature +++ b/features/delayed_job.feature @@ -2,26 +2,43 @@ Feature: Bugsnag detects errors in Delayed job workers Background: Given I set environment variable "BUGSNAG_API_KEY" to "a35a2a72bd230ac0aa0f52715bbdc6aa" - Given I set environment variable "MAZE_API_KEY" to "a35a2a72bd230ac0aa0f52715bbdc6aa" + And I set environment variable "MAZE_API_KEY" to "a35a2a72bd230ac0aa0f52715bbdc6aa" And I configure the bugsnag endpoint -Scenario: An unhandled RuntimeError sends a report - And I set environment variable "RUBY_VERSION" to "2.5" +Scenario: An unhandled RuntimeError sends a report with arguments + Given I set environment variable "RUBY_VERSION" to "2.5" And I start the service "delayed_job" - And I run the command "bundle exec rails runner 'TestModel.delay.fail'" on the service "delayed_job" - And I wait for 1 seconds + And I run the command "bundle exec rails runner 'TestModel.delay.fail_with_args(\"Test\")'" on the service "delayed_job" + And I wait for 5 seconds Then I should receive a request And the request used the Ruby notifier And the request used payload v4 headers And the request contained the api key "a35a2a72bd230ac0aa0f52715bbdc6aa" And the event "unhandled" is true And the event "severity" is "error" - And the event "context" is null + And the event "context" is "jobs:work" And the event "severityReason.type" is "unhandledExceptionMiddleware" - And the event "severityReason.attributes.framework" is "delayed_job" + And the event "severityReason.attributes.framework" is "DelayedJob" + And the exception "errorClass" equals "RuntimeError" + And the event "metaData.job.class" equals "Delayed::Backend::ActiveRecord::Job" + And the event "metaData.job.id" is not null + And the event "metaData.job.attempts" equals "1 / 1" + And the event "metaData.job.payload.display_name" equals "TestModel.fail_with_args" + And the event "metaData.job.payload.method_name" equals "fail_with_args" + And the payload field "events.0.metaData.job.payload.args" is an array with 1 element + And the payload field "events.0.metaData.job.payload.args.0" equals "Test" + +Scenario: A handled exception sends a report + Given I set environment variable "RUBY_VERSION" to "2.5" + And I start the service "delayed_job" + And I run the command "bundle exec rails runner 'TestModel.delay.notify'" on the service "delayed_job" + And I wait for 5 seconds + Then I should receive a request + And the request used the Ruby notifier + And the request used payload v4 headers + And the request contained the api key "a35a2a72bd230ac0aa0f52715bbdc6aa" + And the event "unhandled" is false + And the event "severity" is "warning" + And the event "context" is "jobs:work" + And the event "severityReason.type" is "handledException" And the exception "errorClass" equals "RuntimeError" - And the "file" of stack frame 0 equals "/usr/src/app.rb" - And the "lineNumber" of stack frame 0 equals 33 - And the payload field "events.0.metaData.sidekiq" matches the JSON fixture in "features/fixtures/sidekiq/payloads/unhandled_metadata_ca_.json" - And the event "metaData.sidekiq.msg.created_at" is a parsable timestamp in seconds - And the event "metaData.sidekiq.msg.enqueued_at" is a parsable timestamp in seconds \ No newline at end of file diff --git a/features/fixtures/delayed_job/Dockerfile b/features/fixtures/delayed_job/Dockerfile index c47e364ca..8ea2c2b95 100644 --- a/features/fixtures/delayed_job/Dockerfile +++ b/features/fixtures/delayed_job/Dockerfile @@ -1,15 +1,17 @@ ARG ruby_version FROM ruby:$ruby_version -RUN mkdir -p /usr/src/app -WORKDIR /usr/src/app +WORKDIR /bugsnag +COPY temp-bugsnag-lib ./ +WORKDIR /usr/src/app COPY app/Gemfile /usr/src/app/ RUN bundle install COPY app/ /usr/src/app -RUN bundle exec rails generate delayed_job:active_record +RUN bundle exec rake rails:update:bin +RUN bundle exec bin/rails generate delayed_job:active_record RUN bundle exec rake db:migrate CMD ["bundle", "exec", "rake", "jobs:work"] diff --git a/features/fixtures/delayed_job/app/Gemfile b/features/fixtures/delayed_job/app/Gemfile index 40cc3ac3c..ba901939d 100644 --- a/features/fixtures/delayed_job/app/Gemfile +++ b/features/fixtures/delayed_job/app/Gemfile @@ -5,7 +5,7 @@ git_source(:github) do |repo_name| "https://github.com/#{repo_name}.git" end -gem 'bugsnag'#, path: '../../../../' +gem 'bugsnag', path: '/bugsnag' gem 'delayed_job' gem 'delayed_job_active_record' gem 'therubyracer' diff --git a/features/fixtures/delayed_job/app/app/models/test_model.rb b/features/fixtures/delayed_job/app/app/models/test_model.rb index c77dee930..b5c675c27 100644 --- a/features/fixtures/delayed_job/app/app/models/test_model.rb +++ b/features/fixtures/delayed_job/app/app/models/test_model.rb @@ -1,13 +1,10 @@ class TestModel < ApplicationRecord - def self.print - puts "yo" - end - def self.fail + def self.fail_with_args(a) raise "uh oh" end - def self.fail_with_args(a) - raise "uh oh" + def self.notify + Bugsnag.notify(RuntimeError.new("Handled exception")) end end diff --git a/features/fixtures/delayed_job/app/config/initializers/bugsnag.rb b/features/fixtures/delayed_job/app/config/initializers/bugsnag.rb index c2aa28bc9..001b5f430 100644 --- a/features/fixtures/delayed_job/app/config/initializers/bugsnag.rb +++ b/features/fixtures/delayed_job/app/config/initializers/bugsnag.rb @@ -1,3 +1,14 @@ Bugsnag.configure do |config| - config.api_key = "0a336f52d5bc59451e518f3e682209c7" + config.api_key = ENV["BUGSNAG_API_KEY"] || ENV["MAZE_API_KEY"] + config.endpoint = ENV["BUGSNAG_ENDPOINT"] || ENV["MAZE_ENDPOINT"] + config.session_endpoint = ENV["BUGSNAG_ENDPOINT"] || ENV["MAZE_ENDPOINT"] + config.app_type = ENV["MAZE_APP_TYPE"] if ENV.include? "MAZE_APP_TYPE" + config.app_version = ENV["MAZE_APP_VERSION"] if ENV.include? "MAZE_APP_VERSION" + config.auto_notify = ENV["MAZE_AUTO_NOTIFY"] != "false" + config.project_root = ENV["MAZE_PROJECT_ROOT"] if ENV.include? "MAZE_PROJECT_ROOT" + config.ignore_classes << lambda { |ex| ex.class.to_s == ENV["MAZE_IGNORE_CLASS"] } if ENV.include? "MAZE_IGNORE_CLASS" + config.auto_capture_sessions = ENV["MAZE_AUTO_CAPTURE_SESSIONS"] == "true" + config.release_stage = ENV["MAZE_RELEASE_STAGE"] if ENV.include? "MAZE_RELEASE_STAGE" + config.send_code = ENV["MAZE_SEND_CODE"] != "false" + config.send_environment = ENV["MAZE_SEND_ENVIRONMENT"] == "true" end diff --git a/features/fixtures/delayed_job/app/config/initializers/delayed_job.rb b/features/fixtures/delayed_job/app/config/initializers/delayed_job.rb new file mode 100644 index 000000000..fe6b2130e --- /dev/null +++ b/features/fixtures/delayed_job/app/config/initializers/delayed_job.rb @@ -0,0 +1,3 @@ +require 'delayed_job' + +Delayed::Worker.max_attempts = 1 \ No newline at end of file diff --git a/features/fixtures/docker-compose.yml b/features/fixtures/docker-compose.yml index a2118dada..182d8184a 100644 --- a/features/fixtures/docker-compose.yml +++ b/features/fixtures/docker-compose.yml @@ -43,7 +43,29 @@ services: args: ruby_version: 2.5 environment: - - endpoint + - BUGSNAG_API_KEY + - http_proxy + - MAZE_API_KEY + - MAZE_APP_TYPE + - MAZE_APP_VERSION + - MAZE_AUTO_CAPTURE_SESSIONS + - MAZE_AUTO_NOTIFY + - MAZE_ENDPOINT + - MAZE_IGNORE_CLASS + - MAZE_IGNORE_MESSAGE + - MAZE_META_DATA_FILTERS + - MAZE_NOTIFY_RELEASE_STAGE + - MAZE_PROJECT_ROOT + - MAZE_PROXY_HOST + - MAZE_PROXY_PASSWORD + - MAZE_PROXY_PORT + - MAZE_PROXY_USER + - MAZE_RELEASE_STAGE + - MAZE_SEND_CODE + - MAZE_SEND_ENVIRONMENT + - MAZE_SESSION_ENDPOINT + - MAZE_TIMEOUT + - CALLBACK_INITIATOR restart: "no" rack1: diff --git a/features/support/env.rb b/features/support/env.rb index c58b7ddcb..e837a8d9c 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -18,6 +18,22 @@ def output_logs end end +def install_fixture_gems + gem_dir = File.expand_path('../../../', __FILE__) + Dir.chdir(gem_dir) do + `rm bugsnag-*.gem` + `gem build bugsnag.gemspec` + Dir.foreach('features/fixtures') do |entry| + target_dir = "features/fixtures/#{entry}" + if File.directory? (target_dir) + `cp bugsnag-*.gem #{target_dir}` + `gem unpack #{target_dir}/bugsnag-*.gem --target #{target_dir}/temp-bugsnag-lib` + end + end + `rm bugsnag-*.gem` + end +end + def current_ip if OS.mac? 'host.docker.internal' @@ -27,3 +43,5 @@ def current_ip ip_list.captures.first end end + +install_fixture_gems