From 934eb31cf2dee5db22b0480b864e1c010b94d950 Mon Sep 17 00:00:00 2001 From: fgermano Date: Tue, 2 Feb 2021 11:12:56 -0300 Subject: [PATCH] Extend PGWebServiceClient features Changes: * It is possible to set the name of the manifest in case it is necessary renaming it. * It is possible to set the password related to the PG web service. --- Gemfile | 2 + Gemfile.lock | 59 +++++++++++-------- lib/unit_tests_utils/postgresql_client.rb | 42 +++++++++++++ .../postgresql_web_service_client.rb | 39 +++++++----- .../postgresql_web_service_client_spec.rb | 38 ++++++++++++ unit_tests_utils.gemspec | 1 + 6 files changed, 140 insertions(+), 41 deletions(-) create mode 100644 lib/unit_tests_utils/postgresql_client.rb create mode 100644 spec/lib/unit_tests_utils/postgresql_web_service_client_spec.rb diff --git a/Gemfile b/Gemfile index 9dae170..b7d4960 100644 --- a/Gemfile +++ b/Gemfile @@ -3,3 +3,5 @@ source 'https://rubygems.org' gem 'rspec' gem 'rubocop' gem 'destructor' +gem 'httparty', '0.15.6' +gem 'pg', '0.19' diff --git a/Gemfile.lock b/Gemfile.lock index 3f34d28..5d515b4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,44 +1,53 @@ GEM remote: https://rubygems.org/ specs: - ast (2.4.0) + ast (2.4.2) destructor (0.1.0) - diff-lcs (1.3) - jaro_winkler (1.5.2) - parallel (1.17.0) - parser (2.6.2.1) - ast (~> 2.4.0) - psych (3.1.0) + diff-lcs (1.4.4) + httparty (0.15.6) + multi_xml (>= 0.5.2) + multi_xml (0.6.0) + parallel (1.20.1) + parser (3.0.0.0) + ast (~> 2.4.1) + pg (0.19.0) rainbow (3.0.0) - rspec (3.8.0) - rspec-core (~> 3.8.0) - rspec-expectations (~> 3.8.0) - rspec-mocks (~> 3.8.0) - rspec-core (3.8.0) - rspec-support (~> 3.8.0) - rspec-expectations (3.8.2) + regexp_parser (2.0.3) + rexml (3.2.4) + rspec (3.10.0) + rspec-core (~> 3.10.0) + rspec-expectations (~> 3.10.0) + rspec-mocks (~> 3.10.0) + rspec-core (3.10.1) + rspec-support (~> 3.10.0) + rspec-expectations (3.10.1) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.8.0) - rspec-mocks (3.8.0) + rspec-support (~> 3.10.0) + rspec-mocks (3.10.2) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.8.0) - rspec-support (3.8.0) - rubocop (0.67.2) - jaro_winkler (~> 1.5.1) + rspec-support (~> 3.10.0) + rspec-support (3.10.2) + rubocop (1.9.1) parallel (~> 1.10) - parser (>= 2.5, != 2.5.1.1) - psych (>= 3.1.0) + parser (>= 3.0.0.0) rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 1.8, < 3.0) + rexml + rubocop-ast (>= 1.2.0, < 2.0) ruby-progressbar (~> 1.7) - unicode-display_width (>= 1.4.0, < 1.6) - ruby-progressbar (1.10.0) - unicode-display_width (1.5.0) + unicode-display_width (>= 1.4.0, < 3.0) + rubocop-ast (1.4.1) + parser (>= 2.7.1.5) + ruby-progressbar (1.11.0) + unicode-display_width (2.0.0) PLATFORMS ruby DEPENDENCIES destructor + httparty (= 0.15.6) + pg (= 0.19) rspec rubocop diff --git a/lib/unit_tests_utils/postgresql_client.rb b/lib/unit_tests_utils/postgresql_client.rb new file mode 100644 index 0000000..3641a69 --- /dev/null +++ b/lib/unit_tests_utils/postgresql_client.rb @@ -0,0 +1,42 @@ +require 'pg' + +class UnitTestsUtils::PostgreSQLClient + attr_reader :args + + POSTGRESQL_PROPERTIES_PATH = '/instance_groups/name=pg/jobs/name=postgresql-ha/properties' + + def initialize(args) + @args = args + @args[:dbname] ||= 'area51' + @args[:sslmode] ||= 'disable' + end + + def self.create_from_manifest(manifest, host = nil) + host = manifest.hostname unless host + user = manifest.properties['postgresql-ha']['admin_credentials']['username'] + password = manifest.properties['postgresql-ha']['admin_credentials']['password'] + if manifest.properties("#{POSTGRESQL_PROPERTIES_PATH}/postgresql-ha/ssl?/enable") + sslmode = "require" + end + + self.new(host: host, user: user, password: password, sslmode: sslmode) + end + + def ping + logger.debug("* Creating ping with args: *#{args}*") + return PG::Connection.ping(args) + end + + def connect(extra_args = {}) + args.merge!(extra_args) + logger.debug("* Creating connection with args: *#{args}*") + return PG::Connection.new(args) + end + + def execute(sql, args = {}) + conn = connect(args) + return conn.exec(sql) + ensure + conn.close if !conn.nil? + end +end diff --git a/lib/unit_tests_utils/postgresql_web_service_client.rb b/lib/unit_tests_utils/postgresql_web_service_client.rb index cd876ae..1e85b7d 100644 --- a/lib/unit_tests_utils/postgresql_web_service_client.rb +++ b/lib/unit_tests_utils/postgresql_web_service_client.rb @@ -1,9 +1,15 @@ require 'httparty' +require_relative 'postgresql_client' class UnitTestsUtils::PGWebServiceClient - attr_reader :manifest + attr_reader :manifest, :manifest_name, :password + + DEFAULT_WEB_SERVICE_PASSWORD = 'password' + + def initialize(manifest, options = {}) + @manifest_name = options[:new_manifest_name] || manifest.name + @password = options[:pg_web_service_password] || DEFAULT_WEB_SERVICE_PASSWORD - def initialize(manifest) @manifest = manifest end @@ -12,7 +18,7 @@ def self.master_hostname(manifest) end def node_ips - instances = UnitTestsUtils::Bosh.instance_status(manifest.name, manifest.instance_names.first) + instances = UnitTestsUtils::Bosh.instance_status(manifest_name, manifest.instance_names.first) instances.map { |instance| instance["ips"] } end @@ -147,7 +153,7 @@ def all_standby_nodes_unblocked(tolerance = 120) standby_nodes = cluster_nodes.select { |node| node["data"]["pg_mode"] == "standby" } standby_nodes.each do |node| - pg_client = PostgreSQLClient.create_from_manifest(manifest, node["data"]["node"]["ip"]) + pg_client = UnitTestsUtils::PostgreSQLClient.create_from_manifest(manifest, node["data"]["node"]["ip"]) begin if pg_client.ping > 0 @@ -178,13 +184,13 @@ def cluster_is_sync host = master_ip logger.debug("Checking if cluster has replicated the data - host: #{host}") - pg_client = PostgreSQLClient.create_from_manifest(manifest, host) + pg_client = UnitTestsUtils::PostgreSQLClient.create_from_manifest(manifest, host) res = pg_client.execute("SELECT pg_current_wal_lsn();", { dbname: "postgres" }) master_lsn = lsn_to_i(res.values.flatten.first) standby_ips.each do |node| - pg_client = PostgreSQLClient.create_from_manifest(manifest, node) + pg_client = UnitTestsUtils::PostgreSQLClient.create_from_manifest(manifest, node) res = pg_client.execute("SELECT pg_last_wal_receive_lsn();", { dbname: "postgres" }) standby_lsn = lsn_to_i(res.values.flatten.first) @@ -278,11 +284,21 @@ def cluster_status nodes.select { |node| node != nil } end + def is_cluster_ready + logger.debug("Getting cluster status...") + nodes_status = cluster_status + logger.debug("Cluster status: #{nodes_status}") + nodes = nodes_status.select { |node_status| node_status["status"] == "succeeded" && node_status["data"]["status"] == "running" } + + return nodes.length == nodes_status.length && has_a_master(nodes_status) + end + private + def webservice_credentials { :username => "admin", - :password => "password" + :password => password } end @@ -297,15 +313,6 @@ def has_a_master(nodes) return masters.length > 0 end - def is_cluster_ready - logger.debug("Getting cluster status...") - nodes_status = cluster_status - logger.debug("Cluster status: #{nodes_status}") - nodes = nodes_status.select { |node_status| node_status["status"] == "succeeded" && node_status["data"]["status"] == "running" } - - return nodes.length == nodes_status.length && has_a_master(nodes_status) - end - def lsn_to_i(lsn) split_lsn = lsn.split("/") split_lsn[0].hex << 32 | split_lsn[1].hex diff --git a/spec/lib/unit_tests_utils/postgresql_web_service_client_spec.rb b/spec/lib/unit_tests_utils/postgresql_web_service_client_spec.rb new file mode 100644 index 0000000..bedccd3 --- /dev/null +++ b/spec/lib/unit_tests_utils/postgresql_web_service_client_spec.rb @@ -0,0 +1,38 @@ +require 'spec_helper' + +describe UnitTestsUtils::PGWebServiceClient do + describe "#initialize" do + let(:manifest_id) { 'manifest_id' } + let(:manifest) do + manifest_mocked = double('') + allow(manifest_mocked).to receive(:name).and_return(manifest_id) + manifest_mocked + end + subject(:pg_web_service_client) { UnitTestsUtils::PGWebServiceClient.new(manifest, pg_web_service_options) } + + context 'when there are not options' do + let(:pg_web_service_options) { {} } + + specify do + expect(pg_web_service_client.password).to eq UnitTestsUtils::PGWebServiceClient::DEFAULT_WEB_SERVICE_PASSWORD + expect(pg_web_service_client.manifest_name).to eq manifest_id + end + end + + context 'when there are options' do + let(:manifest_name) { 'manifest_name' } + let(:password) { UnitTestsUtils::PGWebServiceClient::DEFAULT_WEB_SERVICE_PASSWORD } + let(:pg_web_service_options) do + { + new_manifest_name: manifest_name, + pg_web_service_password: password + } + end + + specify do + expect(pg_web_service_client.password).to eq password + expect(pg_web_service_client.manifest_name).to eq manifest_name + end + end + end +end diff --git a/unit_tests_utils.gemspec b/unit_tests_utils.gemspec index 385695d..1ce97ae 100644 --- a/unit_tests_utils.gemspec +++ b/unit_tests_utils.gemspec @@ -24,4 +24,5 @@ Gem::Specification.new do |s| s.license = 'Nonstandard' s.add_runtime_dependency 'httparty', '0.15.6' + s.add_runtime_dependency 'pg', '0.19' end