Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tests against latest stable releases of Postgres 11, 12, & 13 #67

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
12 changes: 12 additions & 0 deletions .travis.yml
Expand Up @@ -21,6 +21,18 @@ jobs:
env: SUPPORTED_PG_VERSIONS=10.4
script: sudo make test

- stage: # Intentionally left blank to parallelize
env: SUPPORTED_PG_VERSIONS=11.11
script: sudo make test

- stage: # Intentionally left blank to parallelize
env: SUPPORTED_PG_VERSIONS=12.6
script: sudo make test

- stage: # Intentionally left blank to parallelize
env: SUPPORTED_PG_VERSIONS=13.2
script: sudo make test

- stage: # Intentionally left blank to parallelize
install: pip install -e . -r requirements-docs.txt
script: make docs
Expand Down
2 changes: 1 addition & 1 deletion Makefile
@@ -1,6 +1,6 @@
.PHONY: attach build build_tester clean coverage create_network docs psql release_pypi release_pypitest release_quay remove_network start_postgres stop_postgres test test_one_pg_version test27 test36 view_docs wait_for_postgres

SUPPORTED_PG_VERSIONS ?= 9.5.13 9.6.4 10.4
SUPPORTED_PG_VERSIONS ?= 9.5.13 9.6.4 10.4 11.11 12.6 13.2
# The default Postgres that will be used in individual targets
POSTGRES_VERSION ?= 10.4

Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
@@ -1,6 +1,6 @@
Cerberus==1.1
click==6.7
Jinja2==2.10.1
MarkupSafe==1.0
MarkupSafe==1.1.1
psycopg2==2.7.3
PyYAML==5.2
118 changes: 85 additions & 33 deletions tests/conftest.py
Expand Up @@ -67,7 +67,9 @@ def drop_users_and_objects(cursor):
WHERE rolname NOT IN (
'test_user', 'postgres', 'pg_signal_backend',
-- Roles introduced in Postgres 10:
'pg_monitor', 'pg_read_all_settings', 'pg_read_all_stats', 'pg_stat_scan_tables'
'pg_monitor', 'pg_read_all_settings', 'pg_read_all_stats', 'pg_stat_scan_tables',
-- Roles introduced in Postgres 11:
'pg_execute_server_program', 'pg_read_server_files', 'pg_write_server_files'
);
""")
users = [u[0] for u in cursor.fetchall()]
Expand All @@ -79,42 +81,64 @@ def drop_users_and_objects(cursor):
@pytest.fixture
def base_spec(cursor):
""" A spec with the existing state of the test database before anything has been done """
spec = dedent("""
postgres:
attributes:
- BYPASSRLS
- CREATEDB
- CREATEROLE
- REPLICATION
can_login: true
is_superuser: true
owns:
schemas:
- information_schema
- pg_catalog
- public
tables:
- information_schema.*
- pg_catalog.*
privileges:
schemas:
write:
cursor.execute("SELECT substring(version from 'PostgreSQL ([0-9.]*) ') FROM version()")
pg_version = int(cursor.fetchone()[0].split('.')[0])
spec = ""

# Before version 10 Postgres creates a `postgres` user plus the `test_user`
if pg_version <= 10:
spec += dedent("""
postgres:
attributes:
- BYPASSRLS
- CREATEDB
- CREATEROLE
- REPLICATION
can_login: true
is_superuser: true
owns:
schemas:
- information_schema
- pg_catalog
- public
tables:
- information_schema.*
- pg_catalog.*
privileges:
schemas:
write:
- information_schema
- pg_catalog
- public

test_user:
attributes:
- PASSWORD "test_password"
can_login: yes
is_superuser: yes
""")

# In version 10 we have some more roles to deal with
if pg_version == 10:
spec += dedent("""
pg_monitor:
member_of:
- pg_read_all_settings
- pg_read_all_stats
- pg_stat_scan_tables

test_user:
attributes:
- PASSWORD "test_password"
can_login: yes
is_superuser: yes
pg_read_all_settings:

pg_read_all_stats:

pg_stat_scan_tables:
""")

# Postgres 10 introduces several new roles that we have to account for
cursor.execute("SELECT substring(version from 'PostgreSQL ([0-9.]*) ') FROM version()")
pg_version = cursor.fetchone()[0]
if pg_version.startswith('10.'):
spec += dedent("""
# In version 11 and onwards Posgres only creates the `test_user` we specify
# Postgres 11 introduces several new roles that we have to account for
if pg_version >= 11:
spec = dedent("""
pg_execute_server_program:

pg_read_all_settings:

Expand All @@ -127,7 +151,35 @@ def base_spec(cursor):
- pg_read_all_settings
- pg_stat_scan_tables
- pg_read_all_stats
""")

pg_read_server_files:

pg_write_server_files:

test_user:
attributes:
- BYPASSRLS
- CREATEDB
- CREATEROLE
- PASSWORD "test_password"
- REPLICATION
can_login: true
is_superuser: true
owns:
schemas:
- information_schema
- pg_catalog
- public
tables:
- information_schema.*
- pg_catalog.*
privileges:
schemas:
write:
- information_schema
- pg_catalog
- public
""")

return spec

Expand All @@ -141,7 +193,7 @@ def spec_with_new_user(tmpdir, base_spec):
{new_user}:
has_personal_schema: yes
member_of:
- postgres
- test_user
privileges:
tables:
read:
Expand Down
35 changes: 27 additions & 8 deletions tests/test_context.py
Expand Up @@ -14,6 +14,8 @@
TABLES = tuple('table{}'.format(i) for i in range(6))
SEQUENCES = tuple('seq{}'.format(i) for i in range(6))
DUMMY = 'foo'
TEST_USER='test_user'
POSTGRES_USER='postgres'


@run_setup_sql(
Expand Down Expand Up @@ -322,14 +324,27 @@ def test_get_all_personal_schemas(cursor):
def test_get_all_role_attributes(cursor):
dbcontext = context.DatabaseContext(cursor, verbose=True)

expected = set(['test_user', 'postgres', ROLES[0], ROLES[1]])
pg_version = dbcontext.get_version_info().postgres_version
expected = set(['test_user', ROLES[0], ROLES[1]])

pg_version = int(dbcontext.get_version_info().postgres_version.split('.')[0])

if pg_version <= 10:
expected.update(set([
'postgres']
))

# Postgres 10 introduces several new roles that we have to account for
if pg_version.startswith('10.'):
if pg_version >= 10:
expected.update(set([
'pg_read_all_settings', 'pg_stat_scan_tables', 'pg_read_all_stats', 'pg_monitor']
))

# Postgres 11 introduces several new roles that we have to account for
if pg_version >= 11:
expected.update(set([
'pg_read_server_files', 'pg_write_server_files', 'pg_execute_server_program']
))

actual = dbcontext.get_all_role_attributes()
assert set(actual.keys()) == expected

Expand Down Expand Up @@ -385,15 +400,18 @@ def test_is_superuser(all_role_attributes, expected):
])
def test_get_all_schemas_and_owners(cursor):
dbcontext = context.DatabaseContext(cursor, verbose=True)
pg_version = int(dbcontext.get_version_info().postgres_version.split('.')[0])

expected_owner = TEST_USER if pg_version >= 11 else POSTGRES_USER
expected = {
common.ObjectName(SCHEMAS[0]): ROLES[0],
common.ObjectName(SCHEMAS[1]): ROLES[0],
common.ObjectName(SCHEMAS[2]): ROLES[1],
common.ObjectName(ROLES[1]): ROLES[1],
# These already existed
common.ObjectName('public'): 'postgres',
common.ObjectName('information_schema'): 'postgres',
common.ObjectName('pg_catalog'): 'postgres',
common.ObjectName('public'): expected_owner,
common.ObjectName('information_schema'): expected_owner,
common.ObjectName('pg_catalog'): expected_owner,
}

actual = dbcontext.get_all_schemas_and_owners()
Expand All @@ -420,9 +438,10 @@ def test_get_all_memberships(cursor):
dbcontext = context.DatabaseContext(cursor, verbose=True)

expected = set([('role1', 'role0'), ('role2', 'role1')])
pg_version = dbcontext.get_version_info().postgres_version
pg_version = int(dbcontext.get_version_info().postgres_version.split('.')[0])

# Postgres 10 introduces several new roles and memberships that we have to account for
if pg_version.startswith('10.'):
if pg_version >= 10:
expected.update(set([
('pg_monitor', 'pg_stat_scan_tables'),
('pg_monitor', 'pg_read_all_stats'),
Expand Down
2 changes: 1 addition & 1 deletion tests/test_core_configure.py
Expand Up @@ -78,7 +78,7 @@ def test_configure_live_mode_works(capsys, cursor, spec_with_new_user, db_config
assert cursor.rowcount == expected

if live_mode:
cursor.execute(Q_HAS_ROLE.format(NEW_USER, 'postgres'))
cursor.execute(Q_HAS_ROLE.format(NEW_USER, 'test_user'))
assert cursor.rowcount == expected

cursor.execute(Q_HAS_PRIVILEGE.format(NEW_USER, 'pg_catalog.pg_class'))
Expand Down