Skip to content

Commit

Permalink
Simplify discard tests
Browse files Browse the repository at this point in the history
  • Loading branch information
flavorjones committed Sep 18, 2024
1 parent 2933f27 commit 9d66662
Showing 1 changed file with 72 additions and 72 deletions.
144 changes: 72 additions & 72 deletions test/test_discarding.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,54 @@

module SQLite3
class TestDiscardDatabase < SQLite3::TestCase
DBPATH = "test.db"

def setup
FileUtils.rm_f(DBPATH)
super
end

def teardown
super
FileUtils.rm_f(DBPATH)
end

def in_a_forked_process
@read, @write = IO.pipe
old_stderr, $stderr = $stderr, StringIO.new

Process.fork do
@read.close
begin
yield @write
rescue StandardError => e
old_stderr.write("child exception: #{e.message}")
end
@write.write($stderr.string)
@write.close
exit!
end

$stderr = old_stderr
@write.close
*@results = *@read.readlines
@read.close
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
skip("ruby 3.0 doesn't have Process._fork") if RUBY_VERSION < "3.1.0"

GC.start
begin
db = SQLite3::Database.new("test.db")
read, write = IO.pipe

old_stderr, $stderr = $stderr, StringIO.new
Process.fork do
read.close
db = SQLite3::Database.new(DBPATH)

in_a_forked_process do |write|
write.write(db.closed? ? "ok\n" : "fail\n")
write.write($stderr.string)

write.close
exit!
end
$stderr = old_stderr
write.close
assertion, *stderr = *read.readlines
read.close

assertion, *stderr = *@results

assert_equal("ok", assertion.chomp, "closed? did not return true")
assert_equal(1, stderr.count, "unexpected output on stderr: #{stderr.inspect}")
Expand All @@ -35,8 +59,7 @@ def test_fork_discards_an_open_readwrite_connection
"expected warning was not emitted"
)
ensure
db.close
FileUtils.rm_f("test.db")
db&.close
end
end

Expand All @@ -46,29 +69,22 @@ def test_fork_does_not_discard_closed_connections

GC.start
begin
db = SQLite3::Database.new("test.db")
read, write = IO.pipe

db = SQLite3::Database.new(DBPATH)
db.close

old_stderr, $stderr = $stderr, StringIO.new
Process.fork do
read.close

write.write($stderr.string)

write.close
exit!
in_a_forked_process do |write|
write.write(db.closed? ? "ok\n" : "fail\n")
write.write($stderr.string) # should be empty write, no warnings emitted
write.write("done\n")
end
$stderr = old_stderr
write.close
stderr = read.readlines
read.close

assert_equal(0, stderr.count, "unexpected output on stderr: #{stderr.inspect}")
assertion, *rest = *@results

assert_equal("ok", assertion.chomp, "closed? did not return true")
assert_equal(1, rest.count, "unexpected output on stderr: #{rest.inspect}")
assert_equal("done", rest.first.chomp, "unexpected output on stderr: #{rest.inspect}")
ensure
db.close
FileUtils.rm_f("test.db")
db&.close
end
end

Expand All @@ -78,36 +94,28 @@ def test_fork_does_not_discard_readonly_connections

GC.start
begin
SQLite3::Database.open("test.db") do |db|
SQLite3::Database.open(DBPATH) do |db|
db.execute("create table foo (bar int)")
db.execute("insert into foo values (1)")
end

db = SQLite3::Database.new("test.db", readonly: true)
read, write = IO.pipe

old_stderr, $stderr = $stderr, StringIO.new
Process.fork do
read.close
db = SQLite3::Database.new(DBPATH, readonly: true)

in_a_forked_process do |write|
write.write(db.closed? ? "fail\n" : "ok\n") # should be open and readable
write.write((db.execute("select * from foo") == [[1]]) ? "ok\n" : "fail\n")
write.write($stderr.string)

write.close
exit!
write.write($stderr.string) # should be an empty write, no warnings emitted
write.write("done\n")
end
$stderr = old_stderr
write.close
assertion1, assertion2, *stderr = *read.readlines
read.close

assertion1, assertion2, *rest = *@results

assert_equal("ok", assertion1.chomp, "closed? did not return false")
assert_equal("ok", assertion2.chomp, "could not read from database")
assert_equal(0, stderr.count, "unexpected output on stderr: #{stderr.inspect}")
assert_equal(1, rest.count, "unexpected output on stderr: #{rest.inspect}")
assert_equal("done", rest.first.chomp, "unexpected output on stderr: #{rest.inspect}")
ensure
db&.close
FileUtils.rm_f("test.db")
end
end

Expand All @@ -117,42 +125,35 @@ def test_close_does_not_discard_readonly_connections

GC.start
begin
SQLite3::Database.open("test.db") do |db|
SQLite3::Database.open(DBPATH) do |db|
db.execute("create table foo (bar int)")
db.execute("insert into foo values (1)")
end

db = SQLite3::Database.new("test.db", readonly: true)
read, write = IO.pipe

old_stderr, $stderr = $stderr, StringIO.new
Process.fork do
read.close
db = SQLite3::Database.new(DBPATH, readonly: true)

in_a_forked_process do |write|
write.write(db.closed? ? "fail\n" : "ok\n") # should be open and readable
db.close

write.write($stderr.string)

write.close
exit!
write.write($stderr.string) # should be an empty write, no warnings emitted
write.write("done\n")
end
$stderr = old_stderr
write.close
stderr = read.readlines
read.close

assert_equal(0, stderr.count, "unexpected output on stderr: #{stderr.inspect}")
assertion, *rest = *@results

assert_equal("ok", assertion.chomp, "closed? did not return false")
assert_equal(1, rest.count, "unexpected output on stderr: #{rest.inspect}")
assert_equal("done", rest.first.chomp, "unexpected output on stderr: #{rest.inspect}")
ensure
db&.close
FileUtils.rm_f("test.db")
end
end

def test_a_discarded_connection_with_statements
skip("discard leaks memory") if i_am_running_in_valgrind

begin
db = SQLite3::Database.new("test.db")
db = SQLite3::Database.new(DBPATH)
db.execute("create table foo (bar int)")
db.execute("insert into foo values (1)")
stmt = db.prepare("select * from foo")
Expand All @@ -165,8 +166,7 @@ def test_a_discarded_connection_with_statements
assert_nothing_raised { stmt.close }
assert_predicate(stmt, :closed?)
ensure
db.close
FileUtils.rm_f("test.db")
db&.close
end
end
end
Expand Down

0 comments on commit 9d66662

Please sign in to comment.