diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 69336b5..efdd5e8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,6 +39,7 @@ jobs: - '3.1' - '3.0' - '2.7' + - '3.3' - 'truffleruby' rails: - activerecord_7.1 diff --git a/lib/with_advisory_lock/base.rb b/lib/with_advisory_lock/base.rb index 197f4d4..35e5d2b 100644 --- a/lib/with_advisory_lock/base.rb +++ b/lib/with_advisory_lock/base.rb @@ -56,7 +56,9 @@ def already_locked? def with_advisory_lock_if_needed(&block) if disable_query_cache return lock_and_yield do - ActiveRecord::Base.uncached(&block) + connection.uncached do + yield + end end end diff --git a/test/test_helper.rb b/test/test_helper.rb index 2a8c43f..14b0d01 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -17,7 +17,7 @@ ActiveRecord::Base.configurations = { default_env: { - url: ENV.fetch('DATABASE_URL', "sqlite3://#{Dir.tmpdir}/#{SecureRandom.hex}.sqlite3"), + url: ENV.fetch('DATABASE_URL', "sqlite3://#{Dir.tmpdir}/with_advisory_lock_test#{RUBY_VERSION}-#{ActiveRecord.gem_version}.sqlite3"), properties: { allowPublicKeyRetrieval: true } # for JRuby madness } } @@ -38,14 +38,24 @@ def env_db 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? Tag.delete_all TagAudit.delete_all Label.delete_all end + teardown do - FileUtils.remove_entry_secure ENV['FLOCK_DIR'] + FileUtils.remove_entry_secure(ENV['FLOCK_DIR'], true) if is_sqlite3_adapter? end end diff --git a/test/test_models.rb b/test/test_models.rb index 016be2e..8d6fda1 100644 --- a/test/test_models.rb +++ b/test/test_models.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -ActiveRecord::Schema.define(version: 0) do +ActiveRecord::Schema.define(version: 1) do create_table 'tags', force: true do |t| t.string 'name' end @@ -12,15 +12,19 @@ end end -class Tag < ActiveRecord::Base +class ApplicationRecord < ActiveRecord::Base + self.abstract_class = true +end + +class Tag < ApplicationRecord after_save do TagAudit.create(tag_name: name) Label.create(name: name) end end -class TagAudit < ActiveRecord::Base +class TagAudit < ApplicationRecord end -class Label < ActiveRecord::Base +class Label < ApplicationRecord end diff --git a/test/concern_test.rb b/test/with_advisory_lock/concern_test.rb similarity index 90% rename from test/concern_test.rb rename to test/with_advisory_lock/concern_test.rb index 1299b3a..7e5f79c 100644 --- a/test/concern_test.rb +++ b/test/with_advisory_lock/concern_test.rb @@ -22,12 +22,12 @@ class WithAdvisoryLockConcernTest < GemTestCase class ActiveRecordQueryCacheTest < GemTestCase test 'does not disable quary cache by default' do - ActiveRecord::Base.expects(:uncached).never + Tag.connection.expects(:uncached).never Tag.with_advisory_lock('lock') { Tag.first } end test 'can disable ActiveRecord query cache' do - ActiveRecord::Base.expects(:uncached).once + Tag.connection.expects(:uncached).once Tag.with_advisory_lock('a-lock', disable_query_cache: true) { Tag.first } end end 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 93% rename from test/parallelism_test.rb rename to test/with_advisory_lock/parallelism_test.rb index d8eb688..56f6a20 100644 --- a/test/parallelism_test.rb +++ b/test/with_advisory_lock/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/with_advisory_lock/shared_test.rb similarity index 94% rename from test/shared_test.rb rename to test/with_advisory_lock/shared_test.rb index 83a0c1d..7cd23a4 100644 --- a/test/shared_test.rb +++ b/test/with_advisory_lock/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/thread_test.rb b/test/with_advisory_lock/thread_test.rb similarity index 93% rename from test/thread_test.rb rename to test/with_advisory_lock/thread_test.rb index e4156bf..2c86be0 100644 --- a/test/thread_test.rb +++ b/test/with_advisory_lock/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/with_advisory_lock/transaction_test.rb similarity index 94% rename from test/transaction_test.rb rename to test/with_advisory_lock/transaction_test.rb index e7d951b..559f55c 100644 --- a/test/transaction_test.rb +++ b/test/with_advisory_lock/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