From 51f1f1bc6f30ff176e5f7bf6c1a771c39b14eb79 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Mon, 26 Oct 2026 13:35:50 -0400 Subject: [PATCH] test: close leaked writable connections before fork tests The fork tests in `test_discarding.rb` failed intermittently when a writable connection leaked by an earlier test was still reachable at fork time. `GC.start` cannot free a reachable connection, so the child emitted the fork-safety warning. Close leaked writable connections before each fork test opens its own. ref: https://github.com/sparklemotion/sqlite3-ruby/actions/runs/31534307777/job/93923543997 --- test/test_discarding.rb | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/test/test_discarding.rb b/test/test_discarding.rb index 5877c9a4..dd3d526b 100644 --- a/test/test_discarding.rb +++ b/test/test_discarding.rb @@ -36,11 +36,19 @@ def in_a_forked_process @read.close end + # A writable connection leaked by an earlier test triggers the fork-safety warning. GC.start + # cannot free a leaked connection that is still reachable, so close it instead. + def close_leaked_writable_connections + ObjectSpace.each_object(SQLite3::Database) do |db| + db.close unless db.closed? || db.readonly? + end + end + def test_fork_discards_an_open_readwrite_connection skip("interpreter doesn't support fork") unless Process.respond_to?(:fork) skip("valgrind doesn't handle forking") if i_am_running_in_valgrind - GC.start + close_leaked_writable_connections begin db = SQLite3::Database.new(DBPATH) @@ -66,7 +74,7 @@ def test_fork_does_not_discard_closed_connections skip("interpreter doesn't support fork") unless Process.respond_to?(:fork) skip("valgrind doesn't handle forking") if i_am_running_in_valgrind - GC.start + close_leaked_writable_connections begin db = SQLite3::Database.new(DBPATH) db.close @@ -91,7 +99,7 @@ def test_fork_does_not_discard_readonly_connections skip("interpreter doesn't support fork") unless Process.respond_to?(:fork) skip("valgrind doesn't handle forking") if i_am_running_in_valgrind - GC.start + close_leaked_writable_connections begin SQLite3::Database.open(DBPATH) do |db| db.execute("create table foo (bar int)") @@ -122,7 +130,7 @@ def test_close_does_not_discard_readonly_connections skip("interpreter doesn't support fork") unless Process.respond_to?(:fork) skip("valgrind doesn't handle forking") if i_am_running_in_valgrind - GC.start + close_leaked_writable_connections begin SQLite3::Database.open(DBPATH) do |db| db.execute("create table foo (bar int)")