diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml index a85243cba..c1b43d651 100644 --- a/.devcontainer/docker-compose.yml +++ b/.devcontainer/docker-compose.yml @@ -16,8 +16,12 @@ services: <<: *sentry-build entrypoint: ".devcontainer/run --service dev" command: "sleep infinity" + links: + - redis + - postgres depends_on: - redis + - postgres sentry-test: <<: *sentry-build @@ -27,6 +31,15 @@ services: - "${SENTRY_E2E_RAILS_APP_PORT}:4000" - "${SENTRY_E2E_SVELTE_APP_PORT}:4001" + postgres: + image: postgres:15 + environment: + - POSTGRES_USER=postgres + - POSTGRES_PASSWORD=postgres + - POSTGRES_DB=sentry + ports: + - "5432:5432" + redis: image: redis:latest environment: diff --git a/.github/workflows/sentry_rails_test.yml b/.github/workflows/sentry_rails_test.yml index c7210a5df..3f6cf4379 100644 --- a/.github/workflows/sentry_rails_test.yml +++ b/.github/workflows/sentry_rails_test.yml @@ -17,49 +17,80 @@ jobs: defaults: run: working-directory: sentry-rails - name: Ruby ${{ matrix.ruby_version }} & Rails ${{ matrix.rails_version }}, options - ${{ toJson(matrix.options) }} + name: "Ruby ${{ matrix.ruby_version }} & Rails ${{ matrix.rails_version }} (${{ matrix.database }}) - ${{ toJson(matrix.options) }}" runs-on: ubuntu-latest timeout-minutes: 10 + services: + postgres: + image: postgres:15 + env: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: sentry + ports: + - 5432:5432 + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 env: RUBYOPT: ${{ matrix.options.rubyopt }} BUNDLE_GEMFILE: ${{ github.workspace }}/sentry-rails/Gemfile BUNDLE_WITHOUT: rubocop RAILS_VERSION: ${{ matrix.rails_version }} + DATABASE: ${{ matrix.database }} + DATABASE_HOST: "localhost" JRUBY_OPTS: "--debug" # for more accurate test coverage strategy: fail-fast: false matrix: ruby_version: ${{ fromJson(inputs.versions) }} rails_version: [6.1.0, 7.0.0, 7.1.0] + database: + - "sqlite3" + - "postgresql" include: - ruby_version: "2.7" - rails_version: 5.2.0 + rails_version: "5.2.0" + database: "sqlite3" - ruby_version: "2.7" - rails_version: 6.0.0 + rails_version: "6.0.0" + database: "sqlite3" - ruby_version: "2.7" - rails_version: 6.1.0 + rails_version: "6.1.0" + database: "sqlite3" - ruby_version: "3.1" - rails_version: 7.2.0 + rails_version: "7.2.0" + database: "sqlite3" - ruby_version: "3.2" - rails_version: 7.2.0 + rails_version: "7.2.0" + database: "sqlite3" - ruby_version: "3.3" - rails_version: 7.2.0 + rails_version: "7.2.0" + database: "sqlite3" - ruby_version: "3.4" - rails_version: 7.2.0 + rails_version: "7.2.0" + database: "sqlite3" + - ruby_version: "3.2" + rails_version: "7.1.0" + database: "sqlite3" + options: + rubyopt: "--enable-frozen-string-literal --debug=frozen-string-literal" + - ruby_version: "3.2" + rails_version: "7.1.0" - ruby_version: "3.2" rails_version: "8.0.0" + database: "sqlite3" - ruby_version: "3.3" rails_version: "8.0.0" + database: "sqlite3" - ruby_version: "3.4" rails_version: "8.0.0" + database: "postgresql" - ruby_version: "3.4" rails_version: "8.1.0" - - ruby_version: "3.2" - rails_version: 7.1.0 - options: - rubyopt: "--enable-frozen-string-literal --debug=frozen-string-literal" - - ruby_version: "3.2" - rails_version: 7.1.0 + database: "postgresql" exclude: - ruby_version: head - ruby_version: jruby-head @@ -70,12 +101,7 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Install sqlite and ImageMagick - run: | - # See https://github.community/t5/GitHub-Actions/ubuntu-latest-Apt-repository-list-issues/td-p/41122/page/2 - for apt_file in `grep -lr microsoft /etc/apt/sources.list.d/`; do sudo rm $apt_file; done - sudo apt-get update - sudo apt-get install libsqlite3-dev imagemagick + - name: Set up Ruby ${{ matrix.ruby_version }} uses: ruby/setup-ruby@v1 with: diff --git a/sentry-rails/Gemfile b/sentry-rails/Gemfile index d58657d5b..2fa6b4bf2 100644 --- a/sentry-rails/Gemfile +++ b/sentry-rails/Gemfile @@ -11,6 +11,7 @@ gem "sentry-ruby", path: "../sentry-ruby" platform :jruby do gem "activerecord-jdbcmysql-adapter" + gem "activerecord-jdbcpostgresql-adapter" gem "jdbc-sqlite3" end @@ -29,6 +30,7 @@ end rails_version = Gem::Version.new(rails_version) gem "rails", "~> #{rails_version}" +gem "pg", platform: :ruby if rails_version >= Gem::Version.new("8.1.0") gem "rspec-rails", "~> 8.0.0" diff --git a/sentry-rails/spec/dummy/test_rails_app/config/application.rb b/sentry-rails/spec/dummy/test_rails_app/config/application.rb index b8c43b5c3..867edc055 100644 --- a/sentry-rails/spec/dummy/test_rails_app/config/application.rb +++ b/sentry-rails/spec/dummy/test_rails_app/config/application.rb @@ -45,10 +45,50 @@ def self.schema_file @schema_file ||= root_path.join("db/schema.rb") end + def self.database_url + @__database_url__ ||= + begin + url = ENV["DATABASE_URL"] + + if url + url + else + url = + case ENV["DATABASE"].to_s + when "sqlite3" then "sqlite3://#{db_path}" + when "postgresql" then "postgresql://postgres:postgres@#{db_host}:5432/sentry" + else + raise "Unsupported database for tests: #{ENV["DATABASE"].inspect}" + end + + # Set it too to make AR happy + ENV["DATABASE_URL"] = url + + url + end + end + end + def self.db_path @db_path ||= root_path.join("db", "db.sqlite3") end + def self.db_host + @db_host ||= (ENV["DATABASE_HOST"] || "postgres") + end + + def self.db_uri + @db_url ||= URI(database_url) + end + + def self.db_system + @db_system ||= db_uri.scheme + end + + def self.db_name + @db_name ||= File.basename(db_uri.path[1..-1]) + end + def self.application_file @application_file ||= begin current = Dir[root_path.join("config/applications/rails-*.rb")] @@ -61,14 +101,29 @@ def self.application_file def self.load_test_schema @__schema_loaded__ ||= begin - # This is more reliable than setting config/database.yml - ENV["DATABASE_URL"] = "sqlite3://#{db_path}" - # Silence migrations output ActiveRecord::Migration.verbose = false # We need to connect manually here - ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: db_path) + case db_uri.scheme + when "postgresql" + ActiveRecord::Base.establish_connection( + adapter: db_uri.scheme, + host: db_uri.host, + username: db_uri.user, + password: db_uri.password, + database: db_name + ) + when "sqlite3" + ActiveRecord::Base.establish_connection( + adapter: db_uri.scheme, + database: db_path.to_s + ) + else + ActiveRecord::Base.establish_connection( + adapter: db_uri.scheme, database: db_name + ) + end # Load schema from db/schema.rb into the current connection require Test::Application.schema_file diff --git a/sentry-rails/spec/dummy/test_rails_app/db/.gitkeep b/sentry-rails/spec/dummy/test_rails_app/db/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/sentry-rails/spec/sentry/rails/log_subscribers/active_record_subscriber_spec.rb b/sentry-rails/spec/sentry/rails/log_subscribers/active_record_subscriber_spec.rb index e0683fa5a..ee7920b93 100644 --- a/sentry-rails/spec/sentry/rails/log_subscribers/active_record_subscriber_spec.rb +++ b/sentry-rails/spec/sentry/rails/log_subscribers/active_record_subscriber_spec.rb @@ -274,8 +274,8 @@ expect(log_event).not_to be_nil attributes = log_event[:attributes] - expect(attributes[:db_system][:value]).to eq("sqlite3") - expect(attributes[:db_name][:value]).to eq("db.sqlite3") + expect(attributes[:db_system][:value]).to eq(Rails.application.db_uri.scheme) + expect(attributes[:db_name][:value]).to eq(Rails.application.db_name) end end end diff --git a/sentry-rails/spec/sentry/rails/tracing/active_record_subscriber_spec.rb b/sentry-rails/spec/sentry/rails/tracing/active_record_subscriber_spec.rb index 45b80d321..5126141e0 100644 --- a/sentry-rails/spec/sentry/rails/tracing/active_record_subscriber_spec.rb +++ b/sentry-rails/spec/sentry/rails/tracing/active_record_subscriber_spec.rb @@ -42,8 +42,8 @@ expect(span[:trace_id]).to eq(transaction.dig(:contexts, :trace, :trace_id)) data = span[:data] - expect(data["db.name"]).to include("db") - expect(data["db.system"]).to eq("sqlite3") + expect(data["db.name"]).to include(Rails.application.db_name) + expect(data["db.system"]).to eql(Rails.application.db_system) end context "when query source location is avaialble", skip: RUBY_VERSION.to_f < 3.2 || Rails.version.to_f < 7.1 do @@ -74,7 +74,7 @@ def foo span = transaction[:spans][0] data = span[:data] - expect(data["db.name"]).to include("db") + expect(data["db.name"]).to include(Rails.application.db_name) expect(data["code.filepath"]).to eq(nil) expect(data["code.lineno"]).to eq(nil) expect(data["code.function"]).to eq(nil) @@ -116,7 +116,7 @@ def foo span = transaction[:spans][0] data = span[:data] - expect(data["db.name"]).to include("db.sqlite3") + expect(data["db.name"]).to include(Rails.application.db_name) expect(data["code.filepath"]).to eq(nil) expect(data["code.lineno"]).to eq(nil) expect(data["code.function"]).to eq(nil) @@ -148,8 +148,8 @@ def foo expect(cached_query_span[:tags]).to include({ cached: true }) data = cached_query_span[:data] - expect(data["db.name"]).to include("db.sqlite3") - expect(data["db.system"]).to eq("sqlite3") + expect(data["db.name"]).to include(Rails.application.db_name) + expect(data["db.system"]).to eql(Rails.application.db_system) end end diff --git a/sentry-rails/spec/sentry/rails/tracing_spec.rb b/sentry-rails/spec/sentry/rails/tracing_spec.rb index aee2c38f9..bb78569b9 100644 --- a/sentry-rails/spec/sentry/rails/tracing_spec.rb +++ b/sentry-rails/spec/sentry/rails/tracing_spec.rb @@ -86,8 +86,8 @@ second_span = transaction[:spans][1] expect(second_span[:op]).to eq("db.sql.active_record") expect(second_span[:origin]).to eq("auto.db.rails") - expect(second_span[:description].squeeze("\s")).to eq( - 'SELECT "posts".* FROM "posts" WHERE "posts"."id" = ? LIMIT ?' + expect(second_span[:description].squeeze("\s")).to match( + /SELECT "posts"\.\* FROM "posts" WHERE "posts"\."id" = (\?|\$1) LIMIT (\?|\$2)/ ) expect(second_span[:parent_span_id]).to eq(first_span[:span_id]) diff --git a/sentry-rails/spec/spec_helper.rb b/sentry-rails/spec/spec_helper.rb index 420f47dfa..b90673846 100644 --- a/sentry-rails/spec/spec_helper.rb +++ b/sentry-rails/spec/spec_helper.rb @@ -4,6 +4,10 @@ ENV["RAILS_ENV"] = "test" +# We run tests against sqlite3 by default +# See SentryRailsTest application for more info +ENV["DATABASE"] ||= "sqlite3" + begin require "debug/prelude" rescue LoadError