diff --git a/spec/acceptance/db_spec.rb b/spec/acceptance/db_spec.rb index 2e89d32..76d3ce1 100644 --- a/spec/acceptance/db_spec.rb +++ b/spec/acceptance/db_spec.rb @@ -1,57 +1,55 @@ require 'spec_helper_acceptance' describe 'postgresql::server::db', unless: UNSUPPORTED_PLATFORMS.include?(fact('osfamily')) do - # rubocop:disable RSpec/ExampleLength - # rubocop:disable RSpec/MultipleExpectations # rubocop:disable Metrics/LineLength it 'creates a database' do begin tmpdir = default.tmpdir('postgresql') pp = <<-MANIFEST class { 'postgresql::server': postgres_password => 'space password', } postgresql::server::tablespace { 'postgresql-test-db': location => '#{tmpdir}', } -> postgresql::server::db { 'postgresql-test-db': comment => 'testcomment', user => 'test-user', password => 'test1', tablespace => 'postgresql-test-db', } MANIFEST apply_manifest(pp, catch_failures: true) apply_manifest(pp, catch_changes: true) # Verify that the postgres password works shell("echo 'localhost:*:*:postgres:\'space password\'' > /root/.pgpass") shell('chmod 600 /root/.pgpass') shell("psql -U postgres -h localhost --command='\\l'") psql('--command="select datname from pg_database" "postgresql-test-db"') do |r| expect(r.stdout).to match(%r{postgresql-test-db}) expect(r.stderr).to eq('') end psql('--command="SELECT 1 FROM pg_roles WHERE rolname=\'test-user\'"') do |r| expect(r.stdout).to match(%r{\(1 row\)}) end result = shell('psql --version') version = result.stdout.match(%r{\s(\d\.\d)})[1] comment_information_function = if version > '8.1' 'shobj_description' else 'obj_description' end psql("--dbname postgresql-test-db --command=\"SELECT pg_catalog.#{comment_information_function}(d.oid, 'pg_database') FROM pg_catalog.pg_database d WHERE datname = 'postgresql-test-db' AND pg_catalog.#{comment_information_function}(d.oid, 'pg_database') = 'testcomment'\"") do |r| expect(r.stdout).to match(%r{\(1 row\)}) end ensure psql('--command=\'drop database "postgresql-test-db" postgres\'') psql('--command="DROP USER test"') end end end diff --git a/spec/acceptance/postgresql_conn_validator_spec.rb b/spec/acceptance/postgresql_conn_validator_spec.rb index dfc116e..1b718b2 100644 --- a/spec/acceptance/postgresql_conn_validator_spec.rb +++ b/spec/acceptance/postgresql_conn_validator_spec.rb @@ -1,73 +1,73 @@ require 'spec_helper_acceptance' describe 'postgresql_conn_validator', unless: UNSUPPORTED_PLATFORMS.include?(fact('osfamily')) do let(:install_pp) do <<-MANIFEST class { 'postgresql::server': postgres_password => 'space password', }-> postgresql::server::role { 'testuser': password_hash => postgresql_password('testuser','test1'), }-> postgresql::server::database { 'testdb': owner => 'testuser', require => Postgresql::Server::Role['testuser'] }-> postgresql::server::database_grant { 'allow connect for testuser': privilege => 'ALL', db => 'testdb', role => 'testuser', } MANIFEST end context 'local connection' do - it 'validates successfully with defaults' do # rubocop:disable RSpec/ExampleLength + it 'validates successfully with defaults' do pp = <<-MANIFEST #{install_pp}-> postgresql_conn_validator { 'validate this': db_name => 'testdb', db_username => 'testuser', db_password => 'test1', host => 'localhost', psql_path => '/usr/bin/psql', } MANIFEST apply_manifest(pp, catch_failures: true) apply_manifest(pp, catch_changes: true) end - it 'works with connect settings hash' do # rubocop:disable RSpec/ExampleLength + it 'works with connect settings hash' do pp = <<-MANIFEST #{install_pp}-> postgresql_conn_validator { 'validate this': connect_settings => { 'PGDATABASE' => 'testdb', 'PGPORT' => '5432', 'PGUSER' => 'testuser', 'PGPASSWORD' => 'test1', 'PGHOST' => 'localhost' }, psql_path => '/usr/bin/psql' } MANIFEST apply_manifest(pp, catch_failures: true) apply_manifest(pp, catch_changes: true) end - it 'fails gracefully' do # rubocop:disable RSpec/ExampleLength + it 'fails gracefully' do pp = <<-MANIFEST #{install_pp}-> postgresql_conn_validator { 'validate this': psql_path => '/usr/bin/psql', tries => 3 } MANIFEST result = apply_manifest(pp) expect(result.stderr).to match %r{Unable to connect to PostgreSQL server} end end end diff --git a/spec/acceptance/postgresql_psql_spec.rb b/spec/acceptance/postgresql_psql_spec.rb index 6362bc9..7f5ce79 100644 --- a/spec/acceptance/postgresql_psql_spec.rb +++ b/spec/acceptance/postgresql_psql_spec.rb @@ -1,173 +1,173 @@ require 'spec_helper_acceptance' describe 'postgresql_psql', unless: UNSUPPORTED_PLATFORMS.include?(fact('osfamily')) do pp_one = <<-MANIFEST class { 'postgresql::server': } -> postgresql_psql { 'foobar': db => 'postgres', psql_user => 'postgres', command => 'select 1', } MANIFEST it 'alwayses run SQL' do apply_manifest(pp_one, catch_failures: true) apply_manifest(pp_one, expect_changes: true) end pp_two = <<-MANIFEST class { 'postgresql::server': } -> postgresql_psql { 'foobar': db => 'postgres', psql_user => 'postgres', command => 'select 1', unless => 'select 1 where 1=2', } MANIFEST it 'runs some SQL when the unless query returns no rows' do apply_manifest(pp_two, catch_failures: true) apply_manifest(pp_two, expect_changes: true) end pp_three = <<-MANIFEST class { 'postgresql::server': } -> postgresql_psql { 'foobar': db => 'postgres', psql_user => 'postgres', command => 'select * from pg_database limit 1', unless => 'select 1 where 1=1', } MANIFEST it 'does not run SQL when the unless query returns rows' do apply_manifest(pp_three, catch_failures: true) apply_manifest(pp_three, catch_changes: true) end pp_four = <<-MANIFEST class { 'postgresql::server': } -> notify { 'trigger': } ~> postgresql_psql { 'foobar': db => 'postgres', psql_user => 'postgres', command => 'invalid sql statement', unless => 'select 1 where 1=1', } MANIFEST it 'does not run SQL when refreshed and the unless query returns rows' do apply_manifest(pp_four, catch_failures: true) apply_manifest(pp_four, expect_changes: true) end context 'with refreshonly' do pp_five = <<-MANIFEST class { 'postgresql::server': } -> postgresql_psql { 'foobar': db => 'postgres', psql_user => 'postgres', command => 'select 1', unless => 'select 1 where 1=2', refreshonly => true, } MANIFEST it 'does not run SQL when the unless query returns no rows' do apply_manifest(pp_five, catch_failures: true) apply_manifest(pp_five, catch_changes: true) end pp_six = <<-MANIFEST.unindent class { 'postgresql::server': } -> notify { 'trigger': } ~> postgresql_psql { 'foobar': db => 'postgres', psql_user => 'postgres', command => 'select 1', unless => 'select 1 where 1=2', refreshonly => true, } MANIFEST it 'runs SQL when refreshed and the unless query returns no rows' do apply_manifest(pp_six, catch_failures: true) apply_manifest(pp_six, expect_changes: true) end pp_seven = <<-MANIFEST.unindent class { 'postgresql::server': } -> notify { 'trigger': } ~> postgresql_psql { 'foobar': db => 'postgres', psql_user => 'postgres', command => 'invalid sql query', unless => 'select 1 where 1=1', refreshonly => true, } MANIFEST it 'does not run SQL when refreshed and the unless query returns rows' do apply_manifest(pp_seven, catch_failures: true) apply_manifest(pp_seven, expect_changes: true) end end pp_eight = <<-MANIFEST class { 'postgresql::server': } -> postgresql_psql { 'foobar': db => 'postgres', psql_user => 'postgres', command => 'select 1', onlyif => 'select 1 where 1=2', } MANIFEST it 'does not run some SQL when the onlyif query returns no rows' do apply_manifest(pp_eight, catch_failures: true) apply_manifest(pp_eight, catch_changes: true) end pp_nine = <<-MANIFEST class { 'postgresql::server': } -> postgresql_psql { 'foobar': db => 'postgres', psql_user => 'postgres', command => 'select * from pg_database limit 1', onlyif => 'select 1 where 1=1', } MANIFEST it 'runs SQL when the onlyif query returns rows' do apply_manifest(pp_nine, catch_failures: true) apply_manifest(pp_nine, expect_changes: true) end context 'with secure password passing by environment' do - it 'runs SQL that contanins password passed by environment' do # rubocop:disable RSpec/ExampleLength + it 'runs SQL that contanins password passed by environment' do select = "select \\'$PASS_TO_EMBED\\'" pp = <<-MANIFEST.unindent class { 'postgresql::server': } -> postgresql_psql { 'password embedded by environment: #{select}': db => 'postgres', psql_user => 'postgres', command => '#{select}', environment => [ 'PASS_TO_EMBED=pa$swD', ], } MANIFEST apply_manifest(pp, catch_failures: true) apply_manifest(pp, expect_changes: false) end - it 'runs SQL that contanins password passed by environment in check' do # rubocop:disable RSpec/ExampleLength + it 'runs SQL that contanins password passed by environment in check' do select = "select 1 where \\'$PASS_TO_EMBED\\'=\\'passwD\\'" pp = <<-MANIFEST.unindent class { 'postgresql::server': } -> postgresql_psql { 'password embedded by environment in check: #{select}': db => 'postgres', psql_user => 'postgres', command => 'invalid sql query', unless => '#{select}', environment => [ 'PASS_TO_EMBED=passwD', ], } MANIFEST apply_manifest(pp, catch_failures: true) apply_manifest(pp, expect_changes: false) end end end diff --git a/spec/acceptance/server/grant_role_spec.rb b/spec/acceptance/server/grant_role_spec.rb index 90d62ab..b8da0ad 100644 --- a/spec/acceptance/server/grant_role_spec.rb +++ b/spec/acceptance/server/grant_role_spec.rb @@ -1,263 +1,261 @@ require 'spec_helper_acceptance' describe 'postgresql::server::grant_role:', unless: UNSUPPORTED_PLATFORMS.include?(fact('osfamily')) do let(:db) { 'grant_role_test' } let(:user) { 'psql_grant_role_tester' } let(:group) { 'test_group' } let(:password) { 'psql_grant_role_pw' } let(:version) do if fact('osfamily') == 'RedHat' && fact('operatingsystemrelease') =~ %r{5} '8.1' end end let(:pp_one) do <<-MANIFEST.unindent $db = #{db} $user = #{user} $group = #{group} $password = #{password} $version = '#{version}' class { 'postgresql::server': } # Since we are not testing pg_hba or any of that, make a local user for ident auth user { $user: ensure => present, } postgresql::server::role { $user: password_hash => postgresql_password($user, $password), } postgresql::server::database { $db: owner => $user, require => Postgresql::Server::Role[$user], } # Lets setup the base rules $local_auth_option = $version ? { '8.1' => 'sameuser', default => undef, } # Create a rule for the user postgresql::server::pg_hba_rule { "allow ${user}": type => 'local', database => $db, user => $user, auth_method => 'ident', auth_option => $local_auth_option, order => 1, } # Create a role to grant to the user postgresql::server::role { $group: db => $db, login => false, require => Postgresql::Server::Database[$db], } # Grant the role to the user postgresql::server::grant_role { "grant_role ${group} to ${user}": role => $user, group => $group, } MANIFEST end let(:pp_two) do <<-MANIFEST.unindent $db = #{db} $user = #{user} $group = #{group} $password = #{password} $version = '#{version}' class { 'postgresql::server': } # Since we are not testing pg_hba or any of that, make a local user for ident auth user { $user: ensure => present, } postgresql::server::role { $user: password_hash => postgresql_password($user, $password), } postgresql::server::database { $db: owner => $user, require => Postgresql::Server::Role[$user], } # Lets setup the base rules $local_auth_option = $version ? { '8.1' => 'sameuser', default => undef, } # Create a rule for the user postgresql::server::pg_hba_rule { "allow ${user}": type => 'local', database => $db, user => $user, auth_method => 'ident', auth_option => $local_auth_option, order => 1, } # Create a role to grant to the user postgresql::server::role { $group: db => $db, login => false, require => Postgresql::Server::Database[$db], } # Grant the role to the user postgresql::server::grant_role { "grant_role ${group} to ${user}": role => $user, group => $group, } MANIFEST end let(:pp_three) do <<-MANIFEST $db = "#{db}" $user = "#{user}" $group = "#{group}" $password = #{password} $version = '#{version}' class { 'postgresql::server': } # Since we are not testing pg_hba or any of that, make a local user for ident auth user { $user: ensure => present, } postgresql::server::role { $user: password_hash => postgresql_password($user, $password), } postgresql::server::database { $db: owner => $user, require => Postgresql::Server::Role[$user], } # Lets setup the base rules $local_auth_option = $version ? { '8.1' => 'sameuser', default => undef, } # Create a rule for the user postgresql::server::pg_hba_rule { "allow ${user}": type => 'local', database => $db, user => $user, auth_method => 'ident', auth_option => $local_auth_option, order => 1, } # Create a role to grant to the user postgresql::server::role { $group: db => $db, login => false, require => Postgresql::Server::Database[$db], } # Grant the role to the user postgresql::server::grant_role { "grant_role ${group} to ${user}": role => $user, group => $group, } postgresql::server::grant_role {"revoke ${group} from ${user}": ensure => absent, role => $user, group => $group, } MANIFEST end let(:pp_four) do <<-MANIFEST $db = "#{db}" $user = "#{user}" $group = "#{group}" $password = #{password} class { 'postgresql::server': } # Since we are not testing pg_hba or any of that, make a local user for ident auth user { $user: ensure => absent, } postgresql::server::database { $db: } # Create a role to grant to the nonexistent user postgresql::server::role { $group: db => $db, login => false, require => Postgresql::Server::Database[$db], } # Grant the role to the nonexistent user postgresql::server::grant_role { "grant_role ${group} to ${user}": role => $user group => $group, } MANIFEST end - # rubocop:disable RSpec/ExampleLength - # rubocop:disable RSpec/MultipleExpectations it 'grants a role to a user' do begin apply_manifest(pp_one, catch_failures: true) apply_manifest(pp_one, catch_changes: true) ## Check that the role was granted to the user psql('--command="SELECT 1 WHERE pg_has_role(\'psql_grant_role_tester\', \'test_group\', \'MEMBER\') = true" grant_role_test', 'psql_grant_role_tester') do |r| expect(r.stdout).to match(%r{\(1 row\)}) expect(r.stderr).to eq('') end end end it 'grants a role to a superuser' do begin apply_manifest(pp_two, catch_failures: true) apply_manifest(pp_two, catch_changes: true) ## Check that the role was granted to the user psql('--command="SELECT 1 FROM pg_roles AS r_role JOIN pg_auth_members AS am ON r_role.oid = am.member JOIN pg_roles AS r_group ON r_group.oid = am.roleid WHERE r_group.rolname = \'test_group\' AND r_role.rolname = \'psql_grant_role_tester\'" grant_role_test', 'psql_grant_role_tester') do |r| # rubocop:disable Metrics/LineLength expect(r.stdout).to match(%r{\(1 row\)}) expect(r.stderr).to eq('') end end end it 'revokes a role from a user' do begin apply_manifest(pp_three, catch_failures: true) apply_manifest(pp_three, expect_changes: true) psql('--command="SELECT 1 WHERE pg_has_role(\'psql_grant_role_tester\', \'test_group\', \'MEMBER\') = true" grant_role_test', 'psql_grant_role_tester') do |r| expect(r.stdout).to match(%r{\(0 rows\)}) expect(r.stderr).to eq('') end end end it 'does not grant permission to a nonexistent user' do begin apply_manifest(pp_four, expect_failures: true) psql('--command="SELECT 1 WHERE pg_has_role(\'psql_grant_role_tester\', \'test_group\', \'MEMBER\') = true" grant_role_test', 'psql_grant_role_tester') do |r| expect(r.stdout).to match(%r{\(0 rows\)}) expect(r.stderr).to eq('') end end end end diff --git a/spec/acceptance/server/grant_spec.rb b/spec/acceptance/server/grant_spec.rb index dd7f8a7..0046b0f 100644 --- a/spec/acceptance/server/grant_spec.rb +++ b/spec/acceptance/server/grant_spec.rb @@ -1,307 +1,305 @@ require 'spec_helper_acceptance' describe 'postgresql::server::grant:', unless: UNSUPPORTED_PLATFORMS.include?(fact('osfamily')) do - # rubocop:disable RSpec/ExampleLength - # rubocop:disable RSpec/MultipleExpectations let(:db) { 'grant_priv_test' } let(:owner) { 'psql_grant_priv_owner' } let(:user) { 'psql_grant_priv_tester' } let(:password) { 'psql_grant_role_pw' } let(:pp_install) { "class {'postgresql::server': }" } let(:pp_setup) do <<-MANIFEST.unindent $db = #{db} $owner = #{owner} $user = #{user} $password = #{password} class { 'postgresql::server': } postgresql::server::role { $owner: password_hash => postgresql_password($owner, $password), } # Since we are not testing pg_hba or any of that, make a local user for ident auth user { $owner: ensure => present, } postgresql::server::database { $db: owner => $owner, require => Postgresql::Server::Role[$owner], } # Create a user to grant privileges to postgresql::server::role { $user: db => $db, require => Postgresql::Server::Database[$db], } # Make a local user for ident auth user { $user: ensure => present, } # Grant them connect to the database postgresql::server::database_grant { "allow connect for ${user}": privilege => 'CONNECT', db => $db, role => $user, } MANIFEST end context 'LANGUAGE' do describe 'GRANT * ON LANGUAGE' do # testing grants on language requires a superuser let(:superuser) { 'postgres' } let(:pp_lang) do pp_setup + <<-MANIFEST.unindent postgresql_psql { 'make sure plpgsql exists': command => 'CREATE LANGUAGE plpgsql', db => $db, psql_user => '#{superuser}', unless => "SELECT 1 from pg_language where lanname = 'plpgsql'", require => Postgresql::Server::Database[$db], } postgresql::server::grant { 'grant usage on plpgsql': psql_user => '#{superuser}', privilege => 'USAGE', object_type => 'LANGUAGE', object_name => 'plpgsql', role => $user, db => $db, require => [ Postgresql_psql['make sure plpgsql exists'], Postgresql::Server::Role[$user], ] } MANIFEST end let(:pp_onlyif) do pp_setup + <<-MANIFEST.unindent postgresql::server::grant { 'grant usage on BSql': psql_user => '#{superuser}', privilege => 'USAGE', object_type => 'LANGUAGE', object_name => 'bsql', role => $user, db => $db, onlyif_exists => true, } MANIFEST end it 'is expected to run idempotently' do apply_manifest(pp_install) # postgres version result = shell('psql --version') version = result.stdout.match(%r{\s(\d\.\d)})[1] if version >= '8.4.0' apply_manifest(pp_lang, catch_failures: true) apply_manifest(pp_lang, catch_changes: true) end end it 'is expected to GRANT USAGE ON LANGUAGE plpgsql to ROLE' do result = shell('psql --version') version = result.stdout.match(%r{\s(\d\.\d)})[1] if version >= '8.4.0' ## Check that the privilege was granted to the user psql("-d #{db} --command=\"SELECT 1 WHERE has_language_privilege('#{user}', 'plpgsql', 'USAGE')\"", superuser) do |r| expect(r.stdout).to match(%r{\(1 row\)}) expect(r.stderr).to eq('') end end end # test onlyif_exists function it 'is expected to not GRANT USAGE ON (dummy)LANGUAGE BSql to ROLE' do apply_manifest(pp_install) # postgres version result = shell('psql --version') version = result.stdout.match(%r{\s(\d\.\d)})[1] if version >= '8.4.0' apply_manifest(pp_onlyif, catch_failures: true) apply_manifest(pp_onlyif, catch_changes: true) end end end end context 'sequence' do let(:pp_one) do pp_setup + <<-MANIFEST.unindent postgresql_psql { 'create test sequence': command => 'CREATE SEQUENCE test_seq', db => $db, psql_user => $owner, unless => "SELECT 1 FROM information_schema.sequences WHERE sequence_name = 'test_seq'", require => Postgresql::Server::Database[$db], } postgresql::server::grant { 'grant usage on test_seq': privilege => 'USAGE', object_type => 'SEQUENCE', object_name => 'test_seq', db => $db, role => $user, require => [ Postgresql_psql['create test sequence'], Postgresql::Server::Role[$user], ] } MANIFEST end let(:pp_two) do pp_setup + <<-MANIFEST.unindent postgresql_psql { 'create test sequence': command => 'CREATE SEQUENCE test_seq', db => $db, psql_user => $owner, unless => "SELECT 1 FROM information_schema.sequences WHERE sequence_name = 'test_seq'", require => Postgresql::Server::Database[$db], } postgresql::server::grant { 'grant update on test_seq': privilege => 'UPDATE', object_type => 'SEQUENCE', object_name => 'test_seq', db => $db, role => $user, require => [ Postgresql_psql['create test sequence'], Postgresql::Server::Role[$user], ] } MANIFEST end let(:result) do shell('psql --version') end let(:version) do result.stdout.match(%r{\s(\d\.\d)})[1] end before(:each) do apply_manifest(pp_install, catch_failures: true) end it 'grants usage on a sequence to a user' do begin if version >= '9.0' apply_manifest(pp_one, catch_failures: true) apply_manifest(pp_one, catch_changes: true) ## Check that the privilege was granted to the user psql("-d #{db} --command=\"SELECT 1 WHERE has_sequence_privilege('#{user}', 'test_seq', 'USAGE')\"", user) do |r| expect(r.stdout).to match(%r{\(1 row\)}) expect(r.stderr).to eq('') end end end end it 'grants update on a sequence to a user' do begin if version >= '9.0' apply_manifest(pp_two, catch_failures: true) apply_manifest(pp_two, catch_changes: true) ## Check that the privilege was granted to the user psql("-d #{db} --command=\"SELECT 1 WHERE has_sequence_privilege('#{user}', 'test_seq', 'UPDATE')\"", user) do |r| expect(r.stdout).to match(%r{\(1 row\)}) expect(r.stderr).to eq('') end end end end end context 'all sequences' do let(:pp_one) do pp_setup + <<-MANIFEST.unindent postgresql_psql { 'create test sequences': command => 'CREATE SEQUENCE test_seq2; CREATE SEQUENCE test_seq3;', db => $db, psql_user => $owner, unless => "SELECT 1 FROM information_schema.sequences WHERE sequence_name = 'test_seq2'", require => Postgresql::Server::Database[$db], } postgresql::server::grant { 'grant usage on all sequences': privilege => 'USAGE', object_type => 'ALL SEQUENCES IN SCHEMA', object_name => 'public', db => $db, role => $user, require => [ Postgresql_psql['create test sequences'], Postgresql::Server::Role[$user], ] } MANIFEST end let(:pp_two) do pp_setup + <<-MANIFEST.unindent postgresql_psql { 'create test sequences': command => 'CREATE SEQUENCE test_seq2; CREATE SEQUENCE test_seq3;', db => $db, psql_user => $owner, unless => "SELECT 1 FROM information_schema.sequences WHERE sequence_name = 'test_seq2'", require => Postgresql::Server::Database[$db], } postgresql::server::grant { 'grant usage on all sequences': privilege => 'UPDATE', object_type => 'ALL SEQUENCES IN SCHEMA', object_name => 'public', db => $db, role => $user, require => [ Postgresql_psql['create test sequences'], Postgresql::Server::Role[$user], ] } MANIFEST end let(:result) do shell('psql --version') end let(:version) do result.stdout.match(%r{\s(\d\.\d)})[1] end before(:each) do apply_manifest(pp_install, catch_failures: true) end it 'grants usage on all sequences to a user' do begin if version >= '9.0' apply_manifest(pp_one, catch_failures: true) apply_manifest(pp_one, catch_changes: true) ## Check that the privileges were granted to the user, this check is not available on version < 9.0 psql("-d #{db} --command=\"SELECT 1 WHERE has_sequence_privilege('#{user}', 'test_seq2', 'USAGE') AND has_sequence_privilege('#{user}', 'test_seq3', 'USAGE')\"", user) do |r| expect(r.stdout).to match(%r{\(1 row\)}) expect(r.stderr).to eq('') end end end end it 'grants update on all sequences to a user' do begin if version >= '9.0' apply_manifest(pp_two, catch_failures: true) apply_manifest(pp_two, catch_changes: true) ## Check that the privileges were granted to the user psql("-d #{db} --command=\"SELECT 1 WHERE has_sequence_privilege('#{user}', 'test_seq2', 'UPDATE') AND has_sequence_privilege('#{user}', 'test_seq3', 'UPDATE')\"", user) do |r| expect(r.stdout).to match(%r{\(1 row\)}) expect(r.stderr).to eq('') end end end end end end diff --git a/spec/acceptance/server/reassign_owned_by_spec.rb b/spec/acceptance/server/reassign_owned_by_spec.rb index 86db4c1..44eea11 100644 --- a/spec/acceptance/server/reassign_owned_by_spec.rb +++ b/spec/acceptance/server/reassign_owned_by_spec.rb @@ -1,140 +1,138 @@ require 'spec_helper_acceptance' describe 'postgresql::server::reassign_owned_by:', unless: UNSUPPORTED_PLATFORMS.include?(fact('osfamily')) do let(:db) { 'reassign_test' } let(:old_owner) { 'psql_reassign_old_owner' } let(:new_owner) { 'psql_reassign_new_owner' } let(:password) { 'psql_reassign_pw' } let(:superuser) { 'postgres' } let(:pp_setup) do <<-MANIFEST.unindent $db = #{db} $old_owner = #{old_owner} $new_owner = #{new_owner} $password = #{password} class { 'postgresql::server': } postgresql::server::role { $old_owner: password_hash => postgresql_password($old_owner, $password), } # Since we are not testing pg_hba or any of that, make a local user for ident auth user { $old_owner: ensure => present, } # Create a user to reassign ownership to postgresql::server::role { $new_owner: db => $db, require => Postgresql::Server::Database[$db], } # Make a local user for ident auth user { $new_owner: ensure => present, } # Grant the new owner membership of the old owner (must have both for REASSIGN OWNED BY to work) postgresql::server::grant_role { "grant_role to ${new_owner}": role => $new_owner, group => $old_owner, } # Grant them connect to the database postgresql::server::database_grant { "allow connect for ${old_owner}": privilege => 'CONNECT', db => $db, role => $old_owner, } MANIFEST end let(:pp_db_old_owner) do <<-MANIFEST.unindent postgresql::server::database { $db: owner => $old_owner, require => Postgresql::Server::Role[$old_owner], } MANIFEST end let(:pp_db_no_owner) do <<-MANIFEST.unindent postgresql::server::database { $db: } MANIFEST end context 'reassign_owned_by' do describe 'REASSIGN OWNED BY tests' do let(:db) { 'reassign_test' } let(:old_owner) { 'psql_reassign_old_owner' } let(:new_owner) { 'psql_reassign_new_owner' } let(:pp_setup_objects) do <<-MANIFEST.unindent postgresql_psql { 'create test table': command => 'CREATE TABLE test_tbl (col1 integer)', db => '#{db}', psql_user => '#{old_owner}', unless => "SELECT tablename FROM pg_catalog.pg_tables WHERE tablename = 'test_tbl'", require => Postgresql::Server::Database['#{db}'], } postgresql_psql { 'create test sequence': command => 'CREATE SEQUENCE test_seq', db => '#{db}', psql_user => '#{old_owner}', unless => "SELECT relname FROM pg_catalog.pg_class WHERE relkind='S' AND relname = 'test_seq'", require => [ Postgresql_psql['create test table'], Postgresql::Server::Database['#{db}'] ], } MANIFEST end let(:pp_reassign_owned_by) do <<-MANIFEST.unindent postgresql::server::reassign_owned_by { 'test reassign to new_owner': db => '#{db}', old_role => '#{old_owner}', new_role => '#{new_owner}', psql_user => '#{new_owner}', } MANIFEST end - # rubocop:disable RSpec/ExampleLength - # rubocop:disable RSpec/MultipleExpectations it 'reassigns all objects to new_owner' do begin # postgres version result = shell('psql --version') version = result.stdout.match(%r{\s(\d\.\d)})[1] if version >= '9.0' apply_manifest(pp_setup + pp_db_old_owner + pp_setup_objects, catch_failures: true) apply_manifest(pp_setup + pp_db_no_owner + pp_reassign_owned_by, catch_failures: true) apply_manifest(pp_setup + pp_db_no_owner + pp_reassign_owned_by, catch_changes: true) ## Check that the ownership was transferred psql("-d #{db} --tuples-only --no-align --command=\"SELECT tablename,tableowner FROM pg_catalog.pg_tables WHERE schemaname NOT IN ('pg_catalog', 'information_schema')\"", superuser) do |r| expect(r.stdout).to match(%r{test_tbl.#{new_owner}}) expect(r.stderr).to eq('') end psql("-d #{db} --tuples-only --no-align --command=\"SELECT relname,pg_get_userbyid(relowner) FROM pg_catalog.pg_class c WHERE relkind='S'\"", superuser) do |r| expect(r.stdout).to match(%r{test_seq.#{new_owner}}) expect(r.stderr).to eq('') end if version >= '9.3' psql("-d #{db} --tuples-only --no-align --command=\"SELECT pg_get_userbyid(datdba) FROM pg_database WHERE datname = current_database()\"", superuser) do |r| expect(r.stdout).to match(%r{#{new_owner}}) expect(r.stderr).to eq('') end end end end end # it should reassign all objects end end ##################### end diff --git a/spec/acceptance/server/schema_spec.rb b/spec/acceptance/server/schema_spec.rb index 1c10d1a..41fcf05 100644 --- a/spec/acceptance/server/schema_spec.rb +++ b/spec/acceptance/server/schema_spec.rb @@ -1,72 +1,70 @@ require 'spec_helper_acceptance' describe 'postgresql::server::schema:', unless: UNSUPPORTED_PLATFORMS.include?(fact('osfamily')) do let(:version) do if fact('osfamily') == 'RedHat' && fact('operatingsystemrelease') =~ %r{5} '8.1' end end let(:pp) do <<-MANIFEST.unindent $db = 'schema_test' $user = 'psql_schema_tester' $password = 'psql_schema_pw' $version = '#{version}' class { 'postgresql::server': } # Since we are not testing pg_hba or any of that, make a local user for ident auth user { $user: ensure => present, } postgresql::server::role { $user: password_hash => postgresql_password($user, $password), } postgresql::server::database { $db: owner => $user, require => Postgresql::Server::Role[$user], } # Lets setup the base rules $local_auth_option = $version ? { '8.1' => 'sameuser', default => undef, } # Create a rule for the user postgresql::server::pg_hba_rule { "allow ${user}": type => 'local', database => $db, user => $user, auth_method => 'ident', auth_option => $local_auth_option, order => 1, } postgresql::server::schema { $user: db => $db, owner => $user, require => Postgresql::Server::Database[$db], } MANIFEST end - # rubocop:disable RSpec/ExampleLength - # rubocop:disable RSpec/MultipleExpectations it 'creates a schema for a user' do begin apply_manifest(pp, catch_failures: true) apply_manifest(pp, catch_changes: true) ## Check that the user can create a table in the database psql('--command="create table psql_schema_tester.foo (foo int)" schema_test', 'psql_schema_tester') do |r| expect(r.stdout).to match(%r{CREATE TABLE}) expect(r.stderr).to eq('') end ensure psql('--command="drop table psql_schema_tester.foo" schema_test', 'psql_schema_tester') end end end diff --git a/spec/unit/classes/lib/devel_spec.rb b/spec/unit/classes/lib/devel_spec.rb index 8317a4d..835bf51 100644 --- a/spec/unit/classes/lib/devel_spec.rb +++ b/spec/unit/classes/lib/devel_spec.rb @@ -1,84 +1,84 @@ require 'spec_helper' describe 'postgresql::lib::devel', type: :class do let :facts do { osfamily: 'Debian', operatingsystem: 'Debian', operatingsystemrelease: '6.0', } end it { is_expected.to contain_class('postgresql::lib::devel') } describe 'link pg_config to /usr/bin' do it { is_expected.not_to contain_file('/usr/bin/pg_config') \ .with_ensure('link') \ .with_target('/usr/lib/postgresql/8.4/bin/pg_config') } end describe 'disable link_pg_config' do let(:params) do { link_pg_config: false, } end it { is_expected.not_to contain_file('/usr/bin/pg_config') } end describe 'should not link pg_config on RedHat with default version' do let(:facts) do { osfamily: 'RedHat', operatingsystem: 'CentOS', operatingsystemrelease: '6.3', operatingsystemmajrelease: '6', } end it { is_expected.not_to contain_file('/usr/bin/pg_config') } end describe 'link pg_config on RedHat with non-default version' do let(:facts) do { osfamily: 'RedHat', operatingsystem: 'CentOS', operatingsystemrelease: '6.3', operatingsystemmajrelease: '6', } end let :pre_condition do "class { '::postgresql::globals': version => '9.3' }" end it { is_expected.to contain_file('/usr/bin/pg_config') \ .with_ensure('link') \ .with_target('/usr/pgsql-9.3/bin/pg_config') } end describe 'on Gentoo' do let :facts do { osfamily: 'Gentoo', operatingsystem: 'Gentoo', } end let :params do { link_pg_config: false, } end - it 'fails to compile' do # rubocop:disable RSpec/MultipleExpectations + it 'fails to compile' do expect { is_expected.to compile }.to raise_error(%r{is not supported}) end end end diff --git a/spec/unit/classes/server/contrib_spec.rb b/spec/unit/classes/server/contrib_spec.rb index 221c857..d118ca0 100644 --- a/spec/unit/classes/server/contrib_spec.rb +++ b/spec/unit/classes/server/contrib_spec.rb @@ -1,55 +1,55 @@ require 'spec_helper' describe 'postgresql::server::contrib', type: :class do let :pre_condition do "class { 'postgresql::server': }" end let :facts do { osfamily: 'Debian', operatingsystem: 'Debian', operatingsystemrelease: '6.0', kernel: 'Linux', concat_basedir: tmpfilename('contrib'), id: 'root', path: '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin', } end describe 'with parameters' do let(:params) do { package_name: 'mypackage', package_ensure: 'absent', } end it 'creates package with correct params' do is_expected.to contain_package('postgresql-contrib').with(ensure: 'absent', name: 'mypackage', tag: 'postgresql') end end describe 'with no parameters' do it 'creates package with postgresql tag' do is_expected.to contain_package('postgresql-contrib').with(tag: 'postgresql') end end describe 'on Gentoo' do let :facts do { osfamily: 'Gentoo', operatingsystem: 'Gentoo', } end - it 'fails to compile' do # rubocop:disable RSpec/MultipleExpectations + it 'fails to compile' do expect { is_expected.to compile }.to raise_error(%r{is not supported}) end end end diff --git a/spec/unit/puppet/provider/postgresql_conn_validator/ruby_spec.rb b/spec/unit/puppet/provider/postgresql_conn_validator/ruby_spec.rb index d4989ab..88cab60 100644 --- a/spec/unit/puppet/provider/postgresql_conn_validator/ruby_spec.rb +++ b/spec/unit/puppet/provider/postgresql_conn_validator/ruby_spec.rb @@ -1,65 +1,65 @@ require 'spec_helper' describe Puppet::Type.type(:postgresql_conn_validator).provider(:ruby) do let(:resource) do Puppet::Type.type(:postgresql_conn_validator).new({ name: 'testname', }.merge(attributes)) end let(:provider) { resource.provider } let(:attributes) do { psql_path: '/usr/bin/psql', host: 'db.test.com', port: 4444, db_username: 'testuser', db_password: 'testpass', } end let(:connect_settings) do { connect_settings: { PGPASSWORD: 'testpass', PGHOST: 'db.test.com', PGPORT: '1234', }, } end describe '#build_psql_cmd' do it 'contains expected commandline options' do expect(provider.validator.build_psql_cmd).to match %r{/usr/bin/psql.*--host.*--port.*--username.*} end end describe '#parse_connect_settings' do it 'returns array if password is present' do expect(provider.validator.parse_connect_settings).to eq(['PGPASSWORD=testpass']) end it 'returns an empty array if password is nil' do attributes.delete(:db_password) expect(provider.validator.parse_connect_settings).to eq([]) end it 'returns an array of settings' do attributes.delete(:db_password) attributes.merge! connect_settings expect(provider.validator.parse_connect_settings).to eq(['PGPASSWORD=testpass', 'PGHOST=db.test.com', 'PGPORT=1234']) end end describe '#attempt_connection' do let(:sleep_length) { 1 } let(:tries) { 3 } let(:exec) do provider.validator.stub(:execute_command).and_return(true) end it 'tries the correct number of times' do - expect(provider.validator).to receive(:execute_command).exactly(3).times # rubocop:disable RSpec/MessageSpies + expect(provider.validator).to receive(:execute_command).exactly(3).times provider.validator.attempt_connection(sleep_length, tries) end end end diff --git a/spec/unit/puppet/provider/postgresql_psql/ruby_spec.rb b/spec/unit/puppet/provider/postgresql_psql/ruby_spec.rb index ee1444f..bc53367 100644 --- a/spec/unit/puppet/provider/postgresql_psql/ruby_spec.rb +++ b/spec/unit/puppet/provider/postgresql_psql/ruby_spec.rb @@ -1,109 +1,107 @@ require 'spec_helper' describe Puppet::Type.type(:postgresql_psql).provider(:ruby) do - # rubocop:disable RSpec/MessageSpies let(:name) { 'rspec psql test' } let(:resource) do Puppet::Type.type(:postgresql_psql).new({ name: name, provider: :ruby }.merge(attributes)) end let(:provider) { resource.provider } context('#run_sql_command') do describe 'with default attributes' do let(:attributes) { { db: 'spec_db' } } it 'executes with the given psql_path on the given DB' do expect(provider).to receive(:run_command).with(['psql', '-d', attributes[:db], '-t', '-c', '"SELECT \'something\' as \"Custom column\""'], 'postgres', 'postgres', {}) provider.run_sql_command('SELECT \'something\' as "Custom column"') end end describe 'with psql_path and db' do let(:attributes) do { psql_path: '/opt/postgres/psql', psql_user: 'spec_user', psql_group: 'spec_group', cwd: '/spec', db: 'spec_db', } end - it 'executes with the given psql_path on the given DB' do # rubocop:disable RSpec/MultipleExpectations + it 'executes with the given psql_path on the given DB' do expect(Dir).to receive(:chdir).with(attributes[:cwd]).and_yield expect(provider).to receive(:run_command).with([attributes[:psql_path], '-d', attributes[:db], '-t', '-c', '"SELECT \'something\' as \"Custom column\""'], attributes[:psql_user], attributes[:psql_group], {}) provider.run_sql_command('SELECT \'something\' as "Custom column"') end end describe 'with search_path string' do let(:attributes) do { search_path: 'schema1', } end it 'executes with the given search_path' do expect(provider).to receive(:run_command).with(['psql', '-t', '-c', '"set search_path to schema1; SELECT \'something\' as \"Custom column\""'], 'postgres', 'postgres', {}) provider.run_sql_command('SELECT \'something\' as "Custom column"') end end describe 'with search_path array' do let(:attributes) do { search_path: %w[schema1 schema2], } end it 'executes with the given search_path' do expect(provider).to receive(:run_command).with(['psql', '-t', '-c', '"set search_path to schema1,schema2; SELECT \'something\' as \"Custom column\""'], 'postgres', 'postgres', {}) provider.run_sql_command('SELECT \'something\' as "Custom column"') end end end describe 'with port string' do let(:attributes) { { port: '5555' } } it 'executes with the given port' do expect(provider).to receive(:run_command).with(['psql', '-p', '5555', '-t', '-c', '"SELECT something"'], 'postgres', 'postgres', {}) provider.run_sql_command('SELECT something') end end describe 'with connect_settings' do let(:attributes) { { connect_settings: { 'PGHOST' => '127.0.0.1' } } } it 'executes with the given host' do expect(provider).to receive(:run_command).with(['psql', '-t', '-c', '"SELECT something"'], 'postgres', 'postgres', 'PGHOST' => '127.0.0.1') provider.run_sql_command('SELECT something') end end context('#run_unless_sql_command') do let(:attributes) { {} } it 'calls #run_sql_command with SQL' do expect(provider).to receive(:run_sql_command).with('SELECT COUNT(*) FROM (SELECT 1) count') provider.run_unless_sql_command('SELECT 1') end end - # rubocop:enable RSpec/MessageSpies end diff --git a/spec/unit/puppet/type/postgresql_psql_spec.rb b/spec/unit/puppet/type/postgresql_psql_spec.rb index 85e844f..ff90022 100644 --- a/spec/unit/puppet/type/postgresql_psql_spec.rb +++ b/spec/unit/puppet/type/postgresql_psql_spec.rb @@ -1,268 +1,265 @@ require 'spec_helper' describe Puppet::Type.type(:postgresql_psql) do # rubocop:disable RSpec/MultipleDescribes context 'when validating attributes' do [:name, :unless, :db, :psql_path, :psql_user, :psql_group, :connect_settings].each do |attr| it "should have a #{attr} parameter" do expect(Puppet::Type.type(:postgresql_psql).attrtype(attr)).to eq(:param) end end [:command].each do |attr| it "should have a #{attr} property" do expect(Puppet::Type.type(:postgresql_psql).attrtype(attr)).to eq(:property) end end end end describe Puppet::Type.type(:postgresql_psql), unless: Puppet.features.microsoft_windows? do subject do Puppet::Type.type(:postgresql_psql).new({ name: 'rspec' }.merge(attributes)) end describe 'available attributes' do { name: 'rspec', command: 'SELECT stuff', unless: 'SELECT other,stuff', db: 'postgres', psql_path: '/bin/false', psql_user: 'postgres', psql_group: 'postgres', cwd: '/var/lib', refreshonly: :true, search_path: %w[schema1 schema2], connect_settings: { 'PGHOST' => 'postgres-db-server', 'DBVERSION' => '9.1' }, }.each do |attr, value| context attr do describe [attr] subject { super()[attr] } let(:attributes) { { attr => value } } it { is_expected.to eq(value) } end end let(:attributes) { {} } context 'default value: [:psql_path]' do subject { super()[:psql_path] } it { is_expected.to eq('psql') } end context 'default value: [:psql_user]' do subject { super()[:psql_user] } it { is_expected.to eq('postgres') } end context 'default value: [:psql_group]' do subject { super()[:psql_group] } it { is_expected.to eq('postgres') } end context 'default value: [:cwd]' do subject { super()[:cwd] } it { is_expected.to eq('/tmp') } end context 'default value: #refreshonly?' do subject { super().refreshonly? } it { is_expected.to be_falsey } end end - # rubocop:disable RSpec/MultipleExpectations - # rubocop:disable RSpec/MessageSpies # rubocop:disable RSpec/NamedSubject # rubocop:disable RSpec/SubjectStub describe '#command' do let(:attributes) { { command: 'SELECT stuff' } } it 'will have the value :notrun if the command should execute' do expect(subject).to receive(:should_run_sql).and_return(true) expect(subject.property(:command).retrieve).to eq(:notrun) end it "will be the 'should' value if the command should not execute" do expect(subject).to receive(:should_run_sql).and_return(false) expect(subject.property(:command).retrieve).to eq('SELECT stuff') end it 'will call provider#run_sql_command on sync' do expect(subject.provider).to receive(:run_sql_command).with('SELECT stuff').and_return(['done', 0]) subject.property(:command).sync end end describe '#unless' do let(:attributes) { { unless: 'SELECT something' } } describe '#matches' do it 'does not fail when the status is successful' do expect(subject.provider).to receive(:run_unless_sql_command).and_return ['1 row returned', 0] subject.parameter(:unless).matches('SELECT something') end it 'returns true when rows are returned' do expect(subject.provider).to receive(:run_unless_sql_command).and_return ['1 row returned', 0] expect(subject.parameter(:unless).matches('SELECT something')).to be_truthy end it 'returns false when no rows are returned' do expect(subject.provider).to receive(:run_unless_sql_command).and_return ['0 rows returned', 0] expect(subject.parameter(:unless).matches('SELECT something')).to be_falsey end it 'raises an error when the sql command fails' do allow(subject.provider).to receive(:run_unless_sql_command).and_return ['Something went wrong', 1] expect { subject.parameter(:unless).matches('SELECT something') }.to raise_error(Puppet::Error, %r{Something went wrong}) end end end - # rubocop:enable RSpec/MultipleExpectations describe "#should_run_sql without 'unless'" do [true, :true].each do |refreshonly| context "refreshonly => #{refreshonly.inspect}" do let(:attributes) do { refreshonly: refreshonly } end context 'not refreshing' it { expect(subject.should_run_sql).to be_falsey } end context "refreshonly => #{refreshonly.inspect}" do let(:attributes) do { refreshonly: refreshonly } end context 'refreshing' it { expect(subject.should_run_sql(true)).to be_truthy } end end [false, :false].each do |refreshonly| context "refreshonly => #{refreshonly.inspect}" do let(:attributes) do { refreshonly: refreshonly } end context 'not refreshing' it { expect(subject.should_run_sql).to be_truthy } end context "refreshonly => #{refreshonly.inspect}" do let(:attributes) do { refreshonly: refreshonly } end context 'refreshing' it { expect(subject.should_run_sql(true)).to be_truthy } end end end describe "#should_run_sql with matching 'unless'" do before(:each) { expect(subject.parameter(:unless)).to receive(:matches).with('SELECT something').and_return(true) } # rubocop:disable RSpec/ExpectInHook [true, :true].each do |refreshonly| context "refreshonly => #{refreshonly.inspect}" do let(:attributes) do { refreshonly: refreshonly, unless: 'SELECT something' } end context 'not refreshing' it { expect(subject.should_run_sql).to be_falsey } end context "refreshonly => #{refreshonly.inspect}" do let(:attributes) do { refreshonly: refreshonly, unless: 'SELECT something' } end context 'refreshing' it { expect(subject.should_run_sql(true)).to be_falsey } end end [false, :false].each do |refreshonly| context "refreshonly => #{refreshonly.inspect}" do let(:attributes) do { refreshonly: refreshonly, unless: 'SELECT something' } end context 'not refreshing' it { expect(subject.should_run_sql).to be_falsey } end context "refreshonly => #{refreshonly.inspect}" do let(:attributes) do { refreshonly: refreshonly, unless: 'SELECT something' } end context 'refreshing' it { expect(subject.should_run_sql(true)).to be_falsey } end end end describe "#should_run_sql when not matching 'unless'" do before(:each) { expect(subject.parameter(:unless)).to receive(:matches).with('SELECT something').and_return(false) } # rubocop:disable RSpec/ExpectInHook [true, :true].each do |refreshonly| context "refreshonly => #{refreshonly.inspect}" do let(:attributes) do { refreshonly: refreshonly, unless: 'SELECT something' } end context 'not refreshing' it { expect(subject.should_run_sql).to be_falsey } end context "refreshonly => #{refreshonly.inspect}" do let(:attributes) do { refreshonly: refreshonly, unless: 'SELECT something' } end context 'refreshing' it { expect(subject.should_run_sql(true)).to be_truthy } end end [false, :false].each do |refreshonly| context "refreshonly => #{refreshonly.inspect}" do let(:attributes) do { refreshonly: refreshonly, unless: 'SELECT something' } end context 'not refreshing' it { expect(subject.should_run_sql).to be_truthy } end context "refreshonly => #{refreshonly.inspect}" do let(:attributes) do { refreshonly: refreshonly, unless: 'SELECT something' } end context 'refreshing' it { expect(subject.should_run_sql(true)).to be_truthy } end end end describe '#refresh' do let(:attributes) { {} } - it 'syncs command property when command should run' do # rubocop:disable RSpec/MultipleExpectations + it 'syncs command property when command should run' do expect(subject).to receive(:should_run_sql).with(true).and_return(true) expect(subject.property(:command)).to receive(:sync) subject.refresh end - it 'does not sync command property when command should not run' do # rubocop:disable RSpec/MultipleExpectations + it 'does not sync command property when command should not run' do expect(subject).to receive(:should_run_sql).with(true).and_return(false) expect(subject.property(:command)).not_to receive(:sync) subject.refresh end end end