module PG::Testing
A PostgreSQL server for tests: the one PG_TEST_URL names, or else a
throwaway cluster this module makes with the server's own programs
(initdb and pg_ctl from /usr/lib/postgresql/*/bin), in a temporary
directory, on a random port of 127.0.0.1 and a private socket
directory, with SCRAM-SHA-256 for every connection, removed when it is
stopped. For tests only: it starts processes and writes files, and its
password comes from the default random generator, which a test's
srand makes predictable.
PG::Testing.with_cluster do |url|
conn = PG.connect(url)
conn.exec("CREATE TABLE t (id int)")
end
In a Test::Case, start one for the class and omit its tests when
there is none:
class UsersTest < Test::Case
SERVER = Atom[PG::Testing::Server | String].new("not started")
def self.startup
SERVER.set(PG::Testing.start_or_reason)
end
def self.shutdown
case SERVER.get
in PG::Testing::Server => s then s.stop
else nil
end
end
def url -> String
case SERVER.get
in PG::Testing::Server => s then s.url
in String => why then omit(why)
end
end
end
Classes and modules
PG::Testing::ServerA server to test against: PG_TEST_URL's, or a cluster of ours.PG::Testing::UnavailableNeither PG_TEST_URL nor the server's programs to make a cluster.
Class methods
def self.start(*, hba: Array[String] = …, certificate: String? = …, private_key: String? = …) -> PG::Testing::Server
A server: PG_TEST_URL's when it is set, else a new cluster, whose
superuser is quarz and whose pg_hba.conf starts with the lines
hba gives ("host all md5_user 127.0.0.1/32 md5"), before
SCRAM-SHA-256 for every connection (hba does nothing to
PG_TEST_URL's server: check Server#ours? before relying on it).
Raises Unavailable when there is neither.
Given a certificate (PEM, the server's own first) and its
private_key (PEM), it is always a new cluster, with TLS on (ssl = on, those files as ssl_cert_file and ssl_key_file): PG_TEST_URL's
server is not used, and a hostssl line in hba takes effect.
def self.start_or_reason(*, hba: Array[String] = …, certificate: String? = …, private_key: String? = …) -> PG::Testing::Server | String
start, or why there is no server: for a test class's startup,
whose tests then omit with the reason.
def self.with_cluster[R](*, hba: Array[String] = …, certificate: String? = …, private_key: String? = …, &: (String) -> R) -> R
Runs the block with the URL of a server (start), and stops it
afterwards (hba, certificate and private_key as for start).