From 5554165dfcf85c508179156a3e02c329b2f1eacd Mon Sep 17 00:00:00 2001 From: Abdelkader Boudih Date: Fri, 19 Jan 2024 17:44:26 +0100 Subject: [PATCH 1/3] chore: add dummy rails application --- .github/workflows/ci.yml | 2 +- .gitignore | 3 +- Gemfile | 5 +++ Rakefile | 5 +++ bin/rails | 13 ++++++ gemfiles/activerecord_6.1.gemfile | 1 + gemfiles/activerecord_7.0.gemfile | 1 + gemfiles/activerecord_7.1.gemfile | 1 + test/active_record_query_cache_test.rb | 14 ++++++ test/dummy/Rakefile | 5 +++ test/dummy/app/models/application_record.rb | 5 +++ test/dummy/app/models/concerns/.keep | 0 test/dummy/app/models/label.rb | 4 ++ test/dummy/app/models/tag.rb | 8 ++++ test/dummy/app/models/tag_audit.rb | 4 ++ test/dummy/bin/rails | 6 +++ test/dummy/bin/rake | 6 +++ test/dummy/bin/setup | 35 +++++++++++++++ test/dummy/config.ru | 6 +++ test/dummy/config/application.rb | 15 +++++++ test/dummy/config/boot.rb | 7 +++ test/dummy/config/database.yml | 4 ++ test/dummy/config/environment.rb | 7 +++ test/dummy/config/environments/test.rb | 44 +++++++++++++++++++ test/dummy/db/migrate/0_initial_schema.rb | 13 ++++++ test/dummy/db/schema.rb | 30 +++++++++++++ test/dummy/log/.keep | 0 test/parallelism_test.rb | 6 +-- test/shared_test.rb | 4 +- test/test_helper.rb | 36 +++------------ test/test_models.rb | 26 ----------- test/thread_test.rb | 4 +- test/transaction_test.rb | 2 +- ....rb => with_advisory_lock_concern_test.rb} | 12 ----- 34 files changed, 255 insertions(+), 79 deletions(-) create mode 100755 bin/rails create mode 100644 test/active_record_query_cache_test.rb create mode 100644 test/dummy/Rakefile create mode 100644 test/dummy/app/models/application_record.rb create mode 100644 test/dummy/app/models/concerns/.keep create mode 100644 test/dummy/app/models/label.rb create mode 100644 test/dummy/app/models/tag.rb create mode 100644 test/dummy/app/models/tag_audit.rb create mode 100755 test/dummy/bin/rails create mode 100755 test/dummy/bin/rake create mode 100755 test/dummy/bin/setup create mode 100644 test/dummy/config.ru create mode 100644 test/dummy/config/application.rb create mode 100644 test/dummy/config/boot.rb create mode 100644 test/dummy/config/database.yml create mode 100644 test/dummy/config/environment.rb create mode 100644 test/dummy/config/environments/test.rb create mode 100644 test/dummy/db/migrate/0_initial_schema.rb create mode 100644 test/dummy/db/schema.rb create mode 100644 test/dummy/log/.keep delete mode 100644 test/test_models.rb rename test/{concern_test.rb => with_advisory_lock_concern_test.rb} (60%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 69336b5..17306f9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -77,4 +77,4 @@ jobs: BUNDLE_GEMFILE: gemfiles/${{ matrix.rails }}.gemfile DATABASE_URL: ${{ matrix.adapter }} WITH_ADVISORY_LOCK_PREFIX: ${{ github.run_id }} - run: bundle exec rake + run: bin/rails db:create db:migrate test diff --git a/.gitignore b/.gitignore index d4f7e62..1d0f4a4 100644 --- a/.gitignore +++ b/.gitignore @@ -19,4 +19,5 @@ test/version_tmp tmp *.iml test/sqlite.db -.env \ No newline at end of file +.env +/test/dummy/log/ diff --git a/Gemfile b/Gemfile index fa75df1..7e29b04 100644 --- a/Gemfile +++ b/Gemfile @@ -1,3 +1,8 @@ source 'https://rubygems.org' gemspec + +gem 'railties' + +gem 'pg' +gem 'sqlite3' \ No newline at end of file diff --git a/Rakefile b/Rakefile index f791690..b05143f 100644 --- a/Rakefile +++ b/Rakefile @@ -5,6 +5,8 @@ YARD::Rake::YardocTask.new do |t| t.files = ['lib/**/*.rb', 'README.md'] end +APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__) +load APP_RAKEFILE require 'rake/testtask' Rake::TestTask.new do |t| @@ -15,3 +17,6 @@ Rake::TestTask.new do |t| end task :default => :test +## +# load task from the dummy app + diff --git a/bin/rails b/bin/rails new file mode 100755 index 0000000..6223410 --- /dev/null +++ b/bin/rails @@ -0,0 +1,13 @@ +#!/usr/bin/env ruby +# This command will automatically be run when you run "rails" with Rails gems +# installed from the root of your application. + +ENGINE_ROOT = File.expand_path("..", __dir__) +APP_PATH = File.expand_path("../test/dummy/config/application", __dir__) +ENV["RAILS_ENV"] ||= "test" +# Set up gems listed in the Gemfile. +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) +require "bundler/setup" if File.exist?(ENV["BUNDLE_GEMFILE"]) + +require "rails/all" +require "rails/engine/commands" diff --git a/gemfiles/activerecord_6.1.gemfile b/gemfiles/activerecord_6.1.gemfile index b87ebba..22af5e5 100644 --- a/gemfiles/activerecord_6.1.gemfile +++ b/gemfiles/activerecord_6.1.gemfile @@ -2,6 +2,7 @@ source "https://rubygems.org" +gem "railties" gem "activerecord", "~> 6.1.0" platforms :ruby do diff --git a/gemfiles/activerecord_7.0.gemfile b/gemfiles/activerecord_7.0.gemfile index 3ef6b18..924024a 100644 --- a/gemfiles/activerecord_7.0.gemfile +++ b/gemfiles/activerecord_7.0.gemfile @@ -2,6 +2,7 @@ source "https://rubygems.org" +gem "railties" gem "activerecord", "~> 7.0.0" platforms :ruby do diff --git a/gemfiles/activerecord_7.1.gemfile b/gemfiles/activerecord_7.1.gemfile index a9455ae..1db2d1c 100644 --- a/gemfiles/activerecord_7.1.gemfile +++ b/gemfiles/activerecord_7.1.gemfile @@ -2,6 +2,7 @@ source "https://rubygems.org" +gem "railties" gem "activerecord", "~> 7.1.0" platforms :ruby do diff --git a/test/active_record_query_cache_test.rb b/test/active_record_query_cache_test.rb new file mode 100644 index 0000000..370a416 --- /dev/null +++ b/test/active_record_query_cache_test.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +require 'test_helper' +class ActiveRecordQueryCacheTest < GemTestCase + test 'does not disable quary cache by default' do + ActiveRecord::Base.expects(:uncached).never + Tag.with_advisory_lock('lock') { Tag.first } + end + + test 'can disable ActiveRecord query cache' do + ActiveRecord::Base.expects(:uncached).once + Tag.with_advisory_lock('a-lock', disable_query_cache: true) { Tag.first } + end +end diff --git a/test/dummy/Rakefile b/test/dummy/Rakefile new file mode 100644 index 0000000..6d1041e --- /dev/null +++ b/test/dummy/Rakefile @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +require_relative 'config/application' + +Rails.application.load_tasks diff --git a/test/dummy/app/models/application_record.rb b/test/dummy/app/models/application_record.rb new file mode 100644 index 0000000..08dc537 --- /dev/null +++ b/test/dummy/app/models/application_record.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +class ApplicationRecord < ActiveRecord::Base + primary_abstract_class +end diff --git a/test/dummy/app/models/concerns/.keep b/test/dummy/app/models/concerns/.keep new file mode 100644 index 0000000..e69de29 diff --git a/test/dummy/app/models/label.rb b/test/dummy/app/models/label.rb new file mode 100644 index 0000000..dc5ac22 --- /dev/null +++ b/test/dummy/app/models/label.rb @@ -0,0 +1,4 @@ +# frozen_string_literal: true + +class Label < ApplicationRecord +end diff --git a/test/dummy/app/models/tag.rb b/test/dummy/app/models/tag.rb new file mode 100644 index 0000000..a58b419 --- /dev/null +++ b/test/dummy/app/models/tag.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +class Tag < ApplicationRecord + after_save do + TagAudit.create(tag_name: name) + Label.create(name: name) + end +end diff --git a/test/dummy/app/models/tag_audit.rb b/test/dummy/app/models/tag_audit.rb new file mode 100644 index 0000000..46bc1b3 --- /dev/null +++ b/test/dummy/app/models/tag_audit.rb @@ -0,0 +1,4 @@ +# frozen_string_literal: true + +class TagAudit < ApplicationRecord +end diff --git a/test/dummy/bin/rails b/test/dummy/bin/rails new file mode 100755 index 0000000..a31728a --- /dev/null +++ b/test/dummy/bin/rails @@ -0,0 +1,6 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +APP_PATH = File.expand_path('../config/application', __dir__) +require_relative '../config/boot' +require 'rails/commands' diff --git a/test/dummy/bin/rake b/test/dummy/bin/rake new file mode 100755 index 0000000..c199955 --- /dev/null +++ b/test/dummy/bin/rake @@ -0,0 +1,6 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +require_relative '../config/boot' +require 'rake' +Rake.application.run diff --git a/test/dummy/bin/setup b/test/dummy/bin/setup new file mode 100755 index 0000000..3a74034 --- /dev/null +++ b/test/dummy/bin/setup @@ -0,0 +1,35 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +require 'fileutils' + +# path to your application root. +APP_ROOT = File.expand_path('..', __dir__) + +def system!(*args) + system(*args, exception: true) +end + +FileUtils.chdir APP_ROOT do + # This script is a way to set up or update your development environment automatically. + # This script is idempotent, so that you can run it at any time and get an expectable outcome. + # Add necessary setup steps to this file. + + puts '== Installing dependencies ==' + system! 'gem install bundler --conservative' + system('bundle check') || system!('bundle install') + + # puts "\n== Copying sample files ==" + # unless File.exist?("config/database.yml") + # FileUtils.cp "config/database.yml.sample", "config/database.yml" + # end + + puts "\n== Preparing database ==" + system! 'bin/rails db:prepare' + + puts "\n== Removing old logs and tempfiles ==" + system! 'bin/rails log:clear tmp:clear' + + puts "\n== Restarting application server ==" + system! 'bin/rails restart' +end diff --git a/test/dummy/config.ru b/test/dummy/config.ru new file mode 100644 index 0000000..5df2ee2 --- /dev/null +++ b/test/dummy/config.ru @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +require_relative 'config/environment' + +run Rails.application +Rails.application.load_server diff --git a/test/dummy/config/application.rb b/test/dummy/config/application.rb new file mode 100644 index 0000000..d4b4dcd --- /dev/null +++ b/test/dummy/config/application.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +require_relative 'boot' + +require 'rails' +require 'active_record/railtie' +require 'with_advisory_lock' + +Bundler.require(*Rails.groups) + +module Dummy + class Application < Rails::Application + config.load_defaults Rails::VERSION::STRING.to_f + end +end diff --git a/test/dummy/config/boot.rb b/test/dummy/config/boot.rb new file mode 100644 index 0000000..6d2cba0 --- /dev/null +++ b/test/dummy/config/boot.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +# Set up gems listed in the Gemfile. +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../Gemfile', __dir__) + +require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE']) +$LOAD_PATH.unshift File.expand_path('../../../lib', __dir__) diff --git a/test/dummy/config/database.yml b/test/dummy/config/database.yml new file mode 100644 index 0000000..6a64690 --- /dev/null +++ b/test/dummy/config/database.yml @@ -0,0 +1,4 @@ +test: + database: <%= ENV.fetch('DATABASE_URL', "sqlite3://#{Dir.tmpdir}/#{SecureRandom.hex}.sqlite3") %> + properties: + allowPublicKeyRetrieval: true \ No newline at end of file diff --git a/test/dummy/config/environment.rb b/test/dummy/config/environment.rb new file mode 100644 index 0000000..d5abe55 --- /dev/null +++ b/test/dummy/config/environment.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +# Load the Rails application. +require_relative 'application' + +# Initialize the Rails application. +Rails.application.initialize! diff --git a/test/dummy/config/environments/test.rb b/test/dummy/config/environments/test.rb new file mode 100644 index 0000000..788f8d4 --- /dev/null +++ b/test/dummy/config/environments/test.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +require 'active_support/core_ext/integer/time' + +# The test environment is used exclusively to run your application's +# test suite. You never need to work with it otherwise. Remember that +# your test database is "scratch space" for the test suite and is wiped +# and recreated between test runs. Don't rely on the data there! + +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # While tests run files are not watched, reloading is not necessary. + config.enable_reloading = false + + # Eager loading loads your entire application. When running a single test locally, + # this is usually not necessary, and can slow down your test suite. However, it's + # recommended that you enable it in continuous integration systems to ensure eager + # loading is working properly before deploying your code. + config.eager_load = ENV['CI'].present? + + # Configure public file server for tests with Cache-Control for performance. + config.public_file_server.enabled = true + config.public_file_server.headers = { + 'Cache-Control' => "public, max-age=#{1.hour.to_i}" + } + + # Show full error reports and disable caching. + config.consider_all_requests_local = true + config.action_controller.perform_caching = false + config.cache_store = :null_store + + # Render exception templates for rescuable exceptions and raise for other exceptions. + config.action_dispatch.show_exceptions = :rescuable + + # Print deprecation notices to the stderr. + config.active_support.deprecation = :stderr + + # Raise exceptions for disallowed deprecations. + config.active_support.disallowed_deprecation = :raise + + # Tell Active Support which deprecation messages to disallow. + config.active_support.disallowed_deprecation_warnings = [] +end diff --git a/test/dummy/db/migrate/0_initial_schema.rb b/test/dummy/db/migrate/0_initial_schema.rb new file mode 100644 index 0000000..8c7994b --- /dev/null +++ b/test/dummy/db/migrate/0_initial_schema.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +class InitialSchema < ActiveRecord::Migration[6.1] + create_table 'tags' do |t| + t.string 'name' + end + create_table 'tag_audits', id: false do |t| + t.string 'tag_name' + end + create_table 'labels', id: false do |t| + t.string 'name' + end +end diff --git a/test/dummy/db/schema.rb b/test/dummy/db/schema.rb new file mode 100644 index 0000000..0d9b545 --- /dev/null +++ b/test/dummy/db/schema.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +# This file is auto-generated from the current state of the database. Instead +# of editing this file, please use the migrations feature of Active Record to +# incrementally modify your database, and then regenerate this schema definition. +# +# This file is the source Rails uses to define your schema when running `bin/rails +# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to +# be faster and is potentially less error prone than running all of your +# migrations from scratch. Old migrations may fail to apply correctly if those +# migrations use external dependencies or application code. +# +# It's strongly recommended that you check this file into your version control system. + +ActiveRecord::Schema.define(version: 0) do + # These are extensions that must be enabled in order to support this database + enable_extension 'plpgsql' + + create_table 'labels', id: false, force: :cascade do |t| + t.string 'name' + end + + create_table 'tag_audits', id: false, force: :cascade do |t| + t.string 'tag_name' + end + + create_table 'tags', force: :cascade do |t| + t.string 'name' + end +end diff --git a/test/dummy/log/.keep b/test/dummy/log/.keep new file mode 100644 index 0000000..e69de29 diff --git a/test/parallelism_test.rb b/test/parallelism_test.rb index d8eb688..56f6a20 100644 --- a/test/parallelism_test.rb +++ b/test/parallelism_test.rb @@ -15,7 +15,7 @@ def initialize(name, use_advisory_lock) def work_later sleep - ActiveRecord::Base.connection_pool.with_connection do + ApplicationRecord.connection_pool.with_connection do if @use_advisory_lock Tag.with_advisory_lock(@name) { work } else @@ -46,11 +46,11 @@ def run_workers workers.each(&:join) end # Ensure we're still connected: - ActiveRecord::Base.connection_pool.connection + ApplicationRecord.connection_pool.connection end setup do - ActiveRecord::Base.connection.reconnect! + ApplicationRecord.connection.reconnect! @workers = 10 end diff --git a/test/shared_test.rb b/test/shared_test.rb index 83a0c1d..7cd23a4 100644 --- a/test/shared_test.rb +++ b/test/shared_test.rb @@ -24,7 +24,7 @@ def cleanup! private def work - ActiveRecord::Base.connection_pool.with_connection do + ApplicationRecord.connection_pool.with_connection do Tag.with_advisory_lock('test', timeout_seconds: 0, shared: @shared) do @locked = true sleep 0.01 until @cleanup @@ -117,7 +117,7 @@ class PostgreSQLTest < SupportedEnvironmentTest end def pg_lock_modes - ActiveRecord::Base.connection.select_values("SELECT mode FROM pg_locks WHERE locktype = 'advisory';") + ApplicationRecord.connection.select_values("SELECT mode FROM pg_locks WHERE locktype = 'advisory';") end test 'allows shared lock to be upgraded to an exclusive lock' do diff --git a/test/test_helper.rb b/test/test_helper.rb index 2a8c43f..44ac58c 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,48 +1,22 @@ # frozen_string_literal: true -require 'erb' -require 'active_record' -require 'with_advisory_lock' -require 'tmpdir' -require 'securerandom' -begin - require 'activerecord-trilogy-adapter' - ActiveSupport.on_load(:active_record) do - require "trilogy_adapter/connection" - ActiveRecord::Base.public_send :extend, TrilogyAdapter::Connection - end -rescue LoadError - # do nothing -end +ENV['RAILS_ENV'] = 'test' -ActiveRecord::Base.configurations = { - default_env: { - url: ENV.fetch('DATABASE_URL', "sqlite3://#{Dir.tmpdir}/#{SecureRandom.hex}.sqlite3"), - properties: { allowPublicKeyRetrieval: true } # for JRuby madness - } -} +require_relative 'dummy/config/environment' +ActiveRecord::Migrator.migrations_paths = [File.expand_path('../test/dummy/db/migrate', __dir__)] +require 'rails/test_help' ENV['WITH_ADVISORY_LOCK_PREFIX'] ||= SecureRandom.hex -ActiveRecord::Base.establish_connection - def env_db - @env_db ||= ActiveRecord::Base.connection_db_config.adapter.to_sym + @env_db ||= ApplicationRecord.connection_db_config.adapter.to_sym end -ActiveRecord::Migration.verbose = false - -require 'test_models' -require 'minitest' -require 'maxitest/autorun' require 'mocha/minitest' class GemTestCase < ActiveSupport::TestCase setup do ENV['FLOCK_DIR'] = Dir.mktmpdir - Tag.delete_all - TagAudit.delete_all - Label.delete_all end teardown do FileUtils.remove_entry_secure ENV['FLOCK_DIR'] diff --git a/test/test_models.rb b/test/test_models.rb deleted file mode 100644 index 016be2e..0000000 --- a/test/test_models.rb +++ /dev/null @@ -1,26 +0,0 @@ -# frozen_string_literal: true - -ActiveRecord::Schema.define(version: 0) do - create_table 'tags', force: true do |t| - t.string 'name' - end - create_table 'tag_audits', id: false, force: true do |t| - t.string 'tag_name' - end - create_table 'labels', id: false, force: true do |t| - t.string 'name' - end -end - -class Tag < ActiveRecord::Base - after_save do - TagAudit.create(tag_name: name) - Label.create(name: name) - end -end - -class TagAudit < ActiveRecord::Base -end - -class Label < ActiveRecord::Base -end diff --git a/test/thread_test.rb b/test/thread_test.rb index e4156bf..2c86be0 100644 --- a/test/thread_test.rb +++ b/test/thread_test.rb @@ -10,7 +10,7 @@ class SeparateThreadTest < GemTestCase @t1_return_value = nil @t1 = Thread.new do - ActiveRecord::Base.connection_pool.with_connection do + ApplicationRecord.connection_pool.with_connection do @t1_return_value = Label.with_advisory_lock(@lock_name) do @mutex.synchronize { @t1_acquired_lock = true } sleep @@ -21,7 +21,7 @@ class SeparateThreadTest < GemTestCase # Wait for the thread to acquire the lock: sleep(0.1) until @mutex.synchronize { @t1_acquired_lock } - ActiveRecord::Base.connection.reconnect! + ApplicationRecord.connection.reconnect! end teardown do diff --git a/test/transaction_test.rb b/test/transaction_test.rb index e7d951b..559f55c 100644 --- a/test/transaction_test.rb +++ b/test/transaction_test.rb @@ -25,7 +25,7 @@ class PostgresqlTest < TransactionScopingTest setup do skip unless env_db == :postgresql @pg_lock_count = lambda do - ActiveRecord::Base.connection.select_value("SELECT COUNT(*) FROM pg_locks WHERE locktype = 'advisory';").to_i + ApplicationRecord.connection.select_value("SELECT COUNT(*) FROM pg_locks WHERE locktype = 'advisory';").to_i end end diff --git a/test/concern_test.rb b/test/with_advisory_lock_concern_test.rb similarity index 60% rename from test/concern_test.rb rename to test/with_advisory_lock_concern_test.rb index 1299b3a..f2e144b 100644 --- a/test/concern_test.rb +++ b/test/with_advisory_lock_concern_test.rb @@ -19,15 +19,3 @@ class WithAdvisoryLockConcernTest < GemTestCase assert_respond_to(Label.new, :advisory_lock_exists?) end end - -class ActiveRecordQueryCacheTest < GemTestCase - test 'does not disable quary cache by default' do - ActiveRecord::Base.expects(:uncached).never - Tag.with_advisory_lock('lock') { Tag.first } - end - - test 'can disable ActiveRecord query cache' do - ActiveRecord::Base.expects(:uncached).once - Tag.with_advisory_lock('a-lock', disable_query_cache: true) { Tag.first } - end -end From 1e3d06a130e67b51560d30b99af684ef0ef4e25c Mon Sep 17 00:00:00 2001 From: Abdelkader Boudih Date: Sat, 20 Jan 2024 22:30:47 +0100 Subject: [PATCH 2/3] wip --- .github/workflows/ci.yml | 2 +- Rakefile | 3 -- gemfiles/activerecord_6.1.gemfile | 2 + gemfiles/activerecord_7.0.gemfile | 2 + gemfiles/activerecord_7.1.gemfile | 2 + test/dummy/config/application.rb | 3 +- test/dummy/config/database.yml | 2 +- .../active_record_query_cache_test.rb | 0 test/{ => with_advisory_lock}/lock_test.rb | 0 test/{ => with_advisory_lock}/nesting_test.rb | 0 test/{ => with_advisory_lock}/options_test.rb | 0 .../parallelism_test.rb | 39 ++++++++++--------- test/{ => with_advisory_lock}/shared_test.rb | 0 test/{ => with_advisory_lock}/thread_test.rb | 0 .../transaction_test.rb | 0 .../with_advisory_lock_concern_test.rb | 0 16 files changed, 29 insertions(+), 26 deletions(-) rename test/{ => with_advisory_lock}/active_record_query_cache_test.rb (100%) rename test/{ => with_advisory_lock}/lock_test.rb (100%) rename test/{ => with_advisory_lock}/nesting_test.rb (100%) rename test/{ => with_advisory_lock}/options_test.rb (100%) rename test/{ => with_advisory_lock}/parallelism_test.rb (77%) rename test/{ => with_advisory_lock}/shared_test.rb (100%) rename test/{ => with_advisory_lock}/thread_test.rb (100%) rename test/{ => with_advisory_lock}/transaction_test.rb (100%) rename test/{ => with_advisory_lock}/with_advisory_lock_concern_test.rb (100%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 17306f9..38ec9e0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -77,4 +77,4 @@ jobs: BUNDLE_GEMFILE: gemfiles/${{ matrix.rails }}.gemfile DATABASE_URL: ${{ matrix.adapter }} WITH_ADVISORY_LOCK_PREFIX: ${{ github.run_id }} - run: bin/rails db:create db:migrate test + run: bin/rails db:reset test diff --git a/Rakefile b/Rakefile index b05143f..79e247e 100644 --- a/Rakefile +++ b/Rakefile @@ -17,6 +17,3 @@ Rake::TestTask.new do |t| end task :default => :test -## -# load task from the dummy app - diff --git a/gemfiles/activerecord_6.1.gemfile b/gemfiles/activerecord_6.1.gemfile index 22af5e5..1d10fc7 100644 --- a/gemfiles/activerecord_6.1.gemfile +++ b/gemfiles/activerecord_6.1.gemfile @@ -3,6 +3,8 @@ source "https://rubygems.org" gem "railties" +gem "pg" +gem "sqlite3" gem "activerecord", "~> 6.1.0" platforms :ruby do diff --git a/gemfiles/activerecord_7.0.gemfile b/gemfiles/activerecord_7.0.gemfile index 924024a..bc2bb97 100644 --- a/gemfiles/activerecord_7.0.gemfile +++ b/gemfiles/activerecord_7.0.gemfile @@ -3,6 +3,8 @@ source "https://rubygems.org" gem "railties" +gem "pg" +gem "sqlite3" gem "activerecord", "~> 7.0.0" platforms :ruby do diff --git a/gemfiles/activerecord_7.1.gemfile b/gemfiles/activerecord_7.1.gemfile index 1db2d1c..0c67dcf 100644 --- a/gemfiles/activerecord_7.1.gemfile +++ b/gemfiles/activerecord_7.1.gemfile @@ -3,6 +3,8 @@ source "https://rubygems.org" gem "railties" +gem "pg" +gem "sqlite3" gem "activerecord", "~> 7.1.0" platforms :ruby do diff --git a/test/dummy/config/application.rb b/test/dummy/config/application.rb index d4b4dcd..fe4c3e0 100644 --- a/test/dummy/config/application.rb +++ b/test/dummy/config/application.rb @@ -4,9 +4,8 @@ require 'rails' require 'active_record/railtie' -require 'with_advisory_lock' - Bundler.require(*Rails.groups) +require 'with_advisory_lock' module Dummy class Application < Rails::Application diff --git a/test/dummy/config/database.yml b/test/dummy/config/database.yml index 6a64690..6534a94 100644 --- a/test/dummy/config/database.yml +++ b/test/dummy/config/database.yml @@ -1,4 +1,4 @@ test: - database: <%= ENV.fetch('DATABASE_URL', "sqlite3://#{Dir.tmpdir}/#{SecureRandom.hex}.sqlite3") %> + url: <%= ENV.fetch('DATABASE_URL', "sqlite3://#{Dir.tmpdir}/with_advisory_lock-#{Rails.gem_version}-#{RUBY_VERSION}.sqlite3") %> properties: allowPublicKeyRetrieval: true \ No newline at end of file diff --git a/test/active_record_query_cache_test.rb b/test/with_advisory_lock/active_record_query_cache_test.rb similarity index 100% rename from test/active_record_query_cache_test.rb rename to test/with_advisory_lock/active_record_query_cache_test.rb diff --git a/test/lock_test.rb b/test/with_advisory_lock/lock_test.rb similarity index 100% rename from test/lock_test.rb rename to test/with_advisory_lock/lock_test.rb diff --git a/test/nesting_test.rb b/test/with_advisory_lock/nesting_test.rb similarity index 100% rename from test/nesting_test.rb rename to test/with_advisory_lock/nesting_test.rb diff --git a/test/options_test.rb b/test/with_advisory_lock/options_test.rb similarity index 100% rename from test/options_test.rb rename to test/with_advisory_lock/options_test.rb diff --git a/test/parallelism_test.rb b/test/with_advisory_lock/parallelism_test.rb similarity index 77% rename from test/parallelism_test.rb rename to test/with_advisory_lock/parallelism_test.rb index 56f6a20..3ba0f16 100644 --- a/test/parallelism_test.rb +++ b/test/with_advisory_lock/parallelism_test.rb @@ -4,32 +4,32 @@ require 'forwardable' class FindOrCreateWorker - extend Forwardable - def_delegators :@thread, :join, :wakeup, :status, :to_s +extend Forwardable +def_delegators :@thread, :join, :wakeup, :status, :to_s - def initialize(name, use_advisory_lock) - @name = name - @use_advisory_lock = use_advisory_lock - @thread = Thread.new { work_later } - end +def initialize(name, use_advisory_lock) + @name = name + @use_advisory_lock = use_advisory_lock + @thread = Thread.new { work_later } +end - def work_later - sleep - ApplicationRecord.connection_pool.with_connection do - if @use_advisory_lock - Tag.with_advisory_lock(@name) { work } - else - work - end +def work_later + sleep + ApplicationRecord.connection_pool.with_connection do + if @use_advisory_lock + Tag.with_advisory_lock(@name) { work } + else + work end end +end - def work - Tag.transaction do - Tag.where(name: @name).first_or_create - end +def work + Tag.transaction do + Tag.where(name: @name).first_or_create end end +end class ParallelismTest < GemTestCase def run_workers @@ -56,6 +56,7 @@ def run_workers test 'creates multiple duplicate rows without advisory locks' do skip if %i[sqlite3 jdbcsqlite3].include?(env_db) + erererere @use_advisory_lock = false @iterations = 1 run_workers diff --git a/test/shared_test.rb b/test/with_advisory_lock/shared_test.rb similarity index 100% rename from test/shared_test.rb rename to test/with_advisory_lock/shared_test.rb diff --git a/test/thread_test.rb b/test/with_advisory_lock/thread_test.rb similarity index 100% rename from test/thread_test.rb rename to test/with_advisory_lock/thread_test.rb diff --git a/test/transaction_test.rb b/test/with_advisory_lock/transaction_test.rb similarity index 100% rename from test/transaction_test.rb rename to test/with_advisory_lock/transaction_test.rb diff --git a/test/with_advisory_lock_concern_test.rb b/test/with_advisory_lock/with_advisory_lock_concern_test.rb similarity index 100% rename from test/with_advisory_lock_concern_test.rb rename to test/with_advisory_lock/with_advisory_lock_concern_test.rb From 73da8f0c690aed4fded0a6017f1fb2be3129578e Mon Sep 17 00:00:00 2001 From: Abdelkader Boudih Date: Sat, 20 Jan 2024 23:07:44 +0100 Subject: [PATCH 3/3] wip --- .../database_adapter_support.rb | 2 +- test/dummy/app/models/application_record.rb | 2 +- test/test_helper.rb | 20 +++++++++++++------ test/with_advisory_lock/parallelism_test.rb | 3 +-- test/with_advisory_lock/shared_test.rb | 10 +++------- test/with_advisory_lock/transaction_test.rb | 8 ++------ 6 files changed, 22 insertions(+), 23 deletions(-) diff --git a/lib/with_advisory_lock/database_adapter_support.rb b/lib/with_advisory_lock/database_adapter_support.rb index 640c9bc..1ef8f0f 100644 --- a/lib/with_advisory_lock/database_adapter_support.rb +++ b/lib/with_advisory_lock/database_adapter_support.rb @@ -20,7 +20,7 @@ def postgresql? end def sqlite? - @sym_name == :sqlite3 + [:sqlite3, :sqlite].include? @sym_name end end end diff --git a/test/dummy/app/models/application_record.rb b/test/dummy/app/models/application_record.rb index 08dc537..71fbba5 100644 --- a/test/dummy/app/models/application_record.rb +++ b/test/dummy/app/models/application_record.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class ApplicationRecord < ActiveRecord::Base - primary_abstract_class + self.abstract_class = true end diff --git a/test/test_helper.rb b/test/test_helper.rb index 44ac58c..88b9e09 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -8,19 +8,27 @@ ENV['WITH_ADVISORY_LOCK_PREFIX'] ||= SecureRandom.hex -def env_db - @env_db ||= ApplicationRecord.connection_db_config.adapter.to_sym -end + require 'mocha/minitest' class GemTestCase < ActiveSupport::TestCase + + parallelize(workers: 1) + def adapter_support + @adapter_support ||= WithAdvisoryLock::DatabaseAdapterSupport.new(ActiveRecord::Base.connection) + end + def is_sqlite3_adapter?; adapter_support.sqlite?; end + def is_mysql_adapter?; adapter_support.mysql?; end + def is_postgresql_adapter?; adapter_support.postgresql?; end + setup do - ENV['FLOCK_DIR'] = Dir.mktmpdir + ENV['FLOCK_DIR'] = Dir.mktmpdir if is_sqlite3_adapter? end + teardown do - FileUtils.remove_entry_secure ENV['FLOCK_DIR'] + FileUtils.remove_entry_secure(ENV['FLOCK_DIR'], true) if is_sqlite3_adapter? end end -puts "Testing with #{env_db} database, ActiveRecord #{ActiveRecord.gem_version} and #{RUBY_ENGINE} #{RUBY_ENGINE_VERSION} as #{RUBY_VERSION}" +# puts "Testing with #{env_db} database, ActiveRecord #{ActiveRecord.gem_version} and #{RUBY_ENGINE} #{RUBY_ENGINE_VERSION} as #{RUBY_VERSION}" diff --git a/test/with_advisory_lock/parallelism_test.rb b/test/with_advisory_lock/parallelism_test.rb index 3ba0f16..792abca 100644 --- a/test/with_advisory_lock/parallelism_test.rb +++ b/test/with_advisory_lock/parallelism_test.rb @@ -55,8 +55,7 @@ def run_workers end test 'creates multiple duplicate rows without advisory locks' do - skip if %i[sqlite3 jdbcsqlite3].include?(env_db) - erererere + skip if is_sqlite3_adapter? @use_advisory_lock = false @iterations = 1 run_workers diff --git a/test/with_advisory_lock/shared_test.rb b/test/with_advisory_lock/shared_test.rb index 7cd23a4..461fa61 100644 --- a/test/with_advisory_lock/shared_test.rb +++ b/test/with_advisory_lock/shared_test.rb @@ -36,10 +36,6 @@ def work end class SharedLocksTest < GemTestCase - def supported? - %i[trilogy mysql2 jdbcmysql].exclude?(env_db) - end - test 'does not allow two exclusive locks' do one = SharedTestWorker.new(false) assert_predicate(one, :locked?) @@ -54,7 +50,7 @@ def supported? class NotSupportedEnvironmentTest < SharedLocksTest setup do - skip if supported? + skip if is_mysql_adapter? end test 'raises an error when attempting to use a shared lock' do @@ -71,7 +67,7 @@ class NotSupportedEnvironmentTest < SharedLocksTest class SupportedEnvironmentTest < SharedLocksTest setup do - skip unless supported? + skip unless is_mysql_adapter? end test 'does allow two shared locks' do @@ -113,7 +109,7 @@ class SupportedEnvironmentTest < SharedLocksTest class PostgreSQLTest < SupportedEnvironmentTest setup do - skip unless env_db == :postgresql + skip unless is_postgresql_adapter? end def pg_lock_modes diff --git a/test/with_advisory_lock/transaction_test.rb b/test/with_advisory_lock/transaction_test.rb index 559f55c..22fb79b 100644 --- a/test/with_advisory_lock/transaction_test.rb +++ b/test/with_advisory_lock/transaction_test.rb @@ -3,12 +3,8 @@ require 'test_helper' class TransactionScopingTest < GemTestCase - def supported? - %i[postgresql jdbcpostgresql].include?(env_db) - end - test 'raises an error when attempting to use transaction level locks if not supported' do - skip if supported? + skip if is_postgresql_adapter? Tag.transaction do exception = assert_raises(ArgumentError) do @@ -23,7 +19,7 @@ def supported? class PostgresqlTest < TransactionScopingTest setup do - skip unless env_db == :postgresql + skip unless is_postgresql_adapter? @pg_lock_count = lambda do ApplicationRecord.connection.select_value("SELECT COUNT(*) FROM pg_locks WHERE locktype = 'advisory';").to_i end