Skip to content

Commit

Permalink
Fix database connection using a socket on CI
Browse files Browse the repository at this point in the history
  • Loading branch information
Fryguy committed Jul 27, 2023
1 parent 6b71cf0 commit b3d147c
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 82 deletions.
11 changes: 10 additions & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
env:
POSTGRESQL_USER: root
POSTGRESQL_PASSWORD: smartvm
POSTGRESQL_DATABASE: vmdb_production
POSTGRESQL_DATABASE: temp
options: >-
--name postgres
--volume /tmp/postgresql-cfg/:/opt/app-root/src/postgresql-cfg/
Expand All @@ -42,9 +42,18 @@ jobs:
ruby-version: ${{ matrix.ruby-version }}
bundler-cache: true
timeout-minutes: 30
- name: Set up tests
run: bundle exec rake spec:setup
env:
POSTGRESQL_HOST: localhost
POSTGRESQL_USER: root
POSTGRESQL_PASSWORD: smartvm
- name: Run tests
run: bundle exec rake
env:
POSTGRESQL_HOST: localhost
POSTGRESQL_USER: root
POSTGRESQL_PASSWORD: smartvm
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
- if: ${{ github.ref == 'refs/heads/master' && matrix.ruby-version == '2.7' }}
name: Report code coverage
Expand Down
8 changes: 4 additions & 4 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
require "bundler/gem_tasks"
require "rspec/core/rake_task"

require_relative "spec/support/connection_helper"

def create_database(dbname)
require "pg"
c = PG::Connection.new(:dbname => "postgres")
c = ConnectionHelper.connection_for("postgres")
c.async_exec("CREATE DATABASE #{dbname}")
rescue PG::DuplicateDatabase => err
raise unless err.message =~ /already exists/
end

def drop_database(dbname)
require "pg"
c = PG::Connection.new(:dbname => "postgres")
c = ConnectionHelper.connection_for("postgres")
c.async_exec("DROP DATABASE #{dbname}")
rescue PG::InvalidCatalogName => err
raise unless err.message =~ /does not exist/
Expand Down
78 changes: 1 addition & 77 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,80 +4,4 @@
$LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
require "pg-logical_replication"

module ConnectionHelper
def self.source_database_connection
@source_database_connection ||= PG::Connection.new(:dbname => "logical_test").tap do |c|
c.set_notice_receiver { |r| nil }
end
end

def self.target_database_connection
@target_database_connection ||= PG::Connection.new(:dbname => "logical_test_target").tap do |c|
c.set_notice_receiver { |r| nil }
end
end

def self.with_each_connection
[source_database_connection, target_database_connection].each do |conn|
yield conn
end
end
end

module DatabaseHelper
def self.tables
%w(table1 table2 table3 table4)
end

def self.create_tables
ConnectionHelper.with_each_connection do |conn|
tables.each do |t|
conn.async_exec(<<-SQL)
CREATE TABLE IF NOT EXISTS #{t} (
id SERIAL PRIMARY KEY,
data VARCHAR(50)
)
SQL
end
end
end

def self.drop_tables
ConnectionHelper.with_each_connection do |conn|
tables.each { |t| conn.async_exec("DROP TABLE IF EXISTS #{t}") }
end
end

def self.drop_subscriptions
conn = ConnectionHelper.target_database_connection
# Subscriptions are visible from all databases in the cluster so we need to specify only the subs from the target database.
conn.async_exec("SELECT subname::TEXT FROM pg_subscription AS sub JOIN pg_database ON sub.subdbid = pg_database.oid WHERE pg_database.datname = current_database()").values.flatten.each do |s|
conn.async_exec("ALTER subscription #{s} DISABLE")
conn.async_exec("ALTER subscription #{s} SET (slot_name = NONE)")
conn.async_exec("DROP SUBSCRIPTION #{s}")
end
end

def self.drop_publications
conn = ConnectionHelper.source_database_connection
conn.async_exec("SELECT pubname::TEXT from pg_publication").values.flatten.each do |p|
conn.async_exec("DROP PUBLICATION #{p}")
end
end

def self.drop_replication_slots
conn = ConnectionHelper.source_database_connection
# replication_slots are visible from all databases in the cluster so we need to specify only the slots from the source database.
conn.async_exec("SELECT slot_name::TEXT FROM pg_replication_slots WHERE slot_type = 'logical' AND NOT active AND database = current_database()").values.flatten.each do |slot|
conn.async_exec("SELECT pg_drop_replication_slot('#{slot}')")
end
end

def self.with_clean_environment
yield
ensure
drop_subscriptions
drop_publications
drop_replication_slots
end
end
Dir[File.join(__dir__, "support/**/*.rb")].each { |f| require f }
32 changes: 32 additions & 0 deletions spec/support/connection_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
module ConnectionHelper
def self.connection_for(dbname)
require "pg"

options = {
:host => ENV["POSTGRESQL_HOST"],
:user => ENV["POSTGRESQL_USER"],
:password => ENV["POSTGRESQL_PASSWORD"],
:dbname => dbname
}.compact

PG::Connection.new(options)
end

def self.source_database_connection
@source_database_connection ||= connection_for("logical_test").tap do |c|
c.set_notice_receiver { |r| nil }
end
end

def self.target_database_connection
@target_database_connection ||= connection_for("logical_test_target").tap do |c|
c.set_notice_receiver { |r| nil }
end
end

def self.with_each_connection
[source_database_connection, target_database_connection].each do |conn|
yield conn
end
end
end
59 changes: 59 additions & 0 deletions spec/support/database_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
require_relative "connection_helper"

module DatabaseHelper
def self.tables
%w(table1 table2 table3 table4)
end

def self.create_tables
ConnectionHelper.with_each_connection do |conn|
tables.each do |t|
conn.async_exec(<<-SQL)
CREATE TABLE IF NOT EXISTS #{t} (
id SERIAL PRIMARY KEY,
data VARCHAR(50)
)
SQL
end
end
end

def self.drop_tables
ConnectionHelper.with_each_connection do |conn|
tables.each { |t| conn.async_exec("DROP TABLE IF EXISTS #{t}") }
end
end

def self.drop_subscriptions
conn = ConnectionHelper.target_database_connection
# Subscriptions are visible from all databases in the cluster so we need to specify only the subs from the target database.
conn.async_exec("SELECT subname::TEXT FROM pg_subscription AS sub JOIN pg_database ON sub.subdbid = pg_database.oid WHERE pg_database.datname = current_database()").values.flatten.each do |s|
conn.async_exec("ALTER subscription #{s} DISABLE")
conn.async_exec("ALTER subscription #{s} SET (slot_name = NONE)")
conn.async_exec("DROP SUBSCRIPTION #{s}")
end
end

def self.drop_publications
conn = ConnectionHelper.source_database_connection
conn.async_exec("SELECT pubname::TEXT from pg_publication").values.flatten.each do |p|
conn.async_exec("DROP PUBLICATION #{p}")
end
end

def self.drop_replication_slots
conn = ConnectionHelper.source_database_connection
# replication_slots are visible from all databases in the cluster so we need to specify only the slots from the source database.
conn.async_exec("SELECT slot_name::TEXT FROM pg_replication_slots WHERE slot_type = 'logical' AND NOT active AND database = current_database()").values.flatten.each do |slot|
conn.async_exec("SELECT pg_drop_replication_slot('#{slot}')")
end
end

def self.with_clean_environment
yield
ensure
drop_subscriptions
drop_publications
drop_replication_slots
end
end

0 comments on commit b3d147c

Please sign in to comment.