Skip to content

Commit 882f06b

Browse files
TakoB222dragomirp
andauthored
Added test for relations coherence (#450)
* Added test for relations coherence * updated * updated * Updated * Updated * Updated * fix lint * updated * updated * Updated --------- Co-authored-by: Dragomir Penev <[email protected]>
1 parent 7c306c8 commit 882f06b

File tree

1 file changed

+161
-0
lines changed

1 file changed

+161
-0
lines changed
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
#!/usr/bin/env python3
2+
# Copyright 2022 Canonical Ltd.
3+
# See LICENSE file for licensing details.
4+
import logging
5+
import secrets
6+
import string
7+
8+
import psycopg2
9+
import pytest
10+
from pytest_operator.plugin import OpsTest
11+
12+
from ..helpers import CHARM_SERIES, DATABASE_APP_NAME
13+
from .helpers import build_connection_string
14+
from .test_new_relations import DATA_INTEGRATOR_APP_NAME
15+
16+
logger = logging.getLogger(__name__)
17+
18+
APPLICATION_APP_NAME = "postgresql-test-app"
19+
APP_NAMES = [DATABASE_APP_NAME, DATA_INTEGRATOR_APP_NAME]
20+
FIRST_DATABASE_RELATION_NAME = "first-database"
21+
22+
23+
@pytest.mark.group(1)
24+
@pytest.mark.abort_on_fail
25+
async def test_relations(ops_test: OpsTest, charm):
26+
"""Test that check relation data."""
27+
async with ops_test.fast_forward():
28+
await ops_test.model.deploy(
29+
charm,
30+
application_name=DATABASE_APP_NAME,
31+
num_units=1,
32+
series=CHARM_SERIES,
33+
config={"profile": "testing"},
34+
)
35+
await ops_test.model.wait_for_idle(apps=[DATABASE_APP_NAME], status="active", timeout=3000)
36+
37+
# Creating first time relation with user role
38+
await ops_test.model.deploy(DATA_INTEGRATOR_APP_NAME)
39+
await ops_test.model.applications[DATA_INTEGRATOR_APP_NAME].set_config({
40+
"database-name": DATA_INTEGRATOR_APP_NAME.replace("-", "_"),
41+
})
42+
await ops_test.model.wait_for_idle(apps=[DATA_INTEGRATOR_APP_NAME], status="blocked")
43+
await ops_test.model.add_relation(DATA_INTEGRATOR_APP_NAME, DATABASE_APP_NAME)
44+
await ops_test.model.wait_for_idle(apps=APP_NAMES, status="active")
45+
46+
connection_string = await build_connection_string(
47+
ops_test,
48+
DATA_INTEGRATOR_APP_NAME,
49+
"postgresql",
50+
database=DATA_INTEGRATOR_APP_NAME.replace("-", "_"),
51+
)
52+
53+
connection = psycopg2.connect(connection_string)
54+
connection.autocommit = True
55+
cursor = connection.cursor()
56+
try:
57+
random_name = (
58+
f"test_{''.join(secrets.choice(string.ascii_lowercase) for _ in range(10))}"
59+
)
60+
cursor.execute(f"CREATE DATABASE {random_name};")
61+
assert False, "user role was able to create database"
62+
except psycopg2.errors.InsufficientPrivilege:
63+
pass
64+
finally:
65+
connection.close()
66+
67+
with psycopg2.connect(connection_string) as connection:
68+
connection.autocommit = True
69+
with connection.cursor() as cursor:
70+
# Check that it's possible to write and read data from the database that
71+
# was created for the application.
72+
cursor.execute("DROP TABLE IF EXISTS test;")
73+
cursor.execute("CREATE TABLE test(data TEXT);")
74+
cursor.execute("INSERT INTO test(data) VALUES('some data');")
75+
cursor.execute("SELECT data FROM test;")
76+
data = cursor.fetchone()
77+
assert data[0] == "some data"
78+
connection.close()
79+
80+
await ops_test.model.applications[DATABASE_APP_NAME].remove_relation(
81+
f"{DATABASE_APP_NAME}:database", f"{DATA_INTEGRATOR_APP_NAME}:postgresql"
82+
)
83+
84+
# Re-relation with admin role with checking permission
85+
await ops_test.model.applications[DATA_INTEGRATOR_APP_NAME].set_config({
86+
"database-name": DATA_INTEGRATOR_APP_NAME.replace("-", "_"),
87+
"extra-user-roles": "admin",
88+
})
89+
await ops_test.model.wait_for_idle(apps=[DATA_INTEGRATOR_APP_NAME], status="blocked")
90+
await ops_test.model.add_relation(DATA_INTEGRATOR_APP_NAME, DATABASE_APP_NAME)
91+
await ops_test.model.wait_for_idle(apps=APP_NAMES, status="active")
92+
93+
connection_string = await build_connection_string(
94+
ops_test,
95+
DATA_INTEGRATOR_APP_NAME,
96+
"postgresql",
97+
database=DATA_INTEGRATOR_APP_NAME.replace("-", "_"),
98+
)
99+
try:
100+
connection = psycopg2.connect(connection_string)
101+
connection.autocommit = True
102+
cursor = connection.cursor()
103+
random_name = (
104+
f"test_{''.join(secrets.choice(string.ascii_lowercase) for _ in range(10))}"
105+
)
106+
cursor.execute(f"CREATE DATABASE {random_name};")
107+
except psycopg2.errors.InsufficientPrivilege:
108+
assert (
109+
False
110+
), f"failed connect to {random_name} or run a statement in the following database"
111+
finally:
112+
connection.close()
113+
114+
await ops_test.model.applications[DATABASE_APP_NAME].remove_relation(
115+
f"{DATABASE_APP_NAME}:database", f"{DATA_INTEGRATOR_APP_NAME}:postgresql"
116+
)
117+
118+
# Re-relation again with user role and checking write data
119+
await ops_test.model.applications[DATA_INTEGRATOR_APP_NAME].set_config({
120+
"database-name": DATA_INTEGRATOR_APP_NAME.replace("-", "_"),
121+
"extra-user-roles": "",
122+
})
123+
await ops_test.model.wait_for_idle(apps=[DATA_INTEGRATOR_APP_NAME], status="blocked")
124+
await ops_test.model.add_relation(DATA_INTEGRATOR_APP_NAME, DATABASE_APP_NAME)
125+
await ops_test.model.wait_for_idle(apps=APP_NAMES, status="active")
126+
127+
for database in [
128+
DATA_INTEGRATOR_APP_NAME.replace("-", "_"),
129+
"postgres",
130+
]:
131+
logger.info(f"connecting to the following database: {database}")
132+
connection_string = await build_connection_string(
133+
ops_test, DATA_INTEGRATOR_APP_NAME, "postgresql", database=database
134+
)
135+
connection = None
136+
should_fail = database == "postgres"
137+
try:
138+
with psycopg2.connect(
139+
connection_string
140+
) as connection, connection.cursor() as cursor:
141+
cursor.execute("SELECT data FROM test;")
142+
data = cursor.fetchone()
143+
assert data[0] == "some data"
144+
145+
# Write some data (it should fail in the "postgres" database).
146+
random_name = f"test_{''.join(secrets.choice(string.ascii_lowercase) for _ in range(10))}"
147+
cursor.execute(f"CREATE TABLE {random_name}(data TEXT);")
148+
if should_fail:
149+
assert (
150+
False
151+
), f"failed to run a statement in the following database: {database}"
152+
except psycopg2.errors.InsufficientPrivilege as e:
153+
if not should_fail:
154+
logger.exception(e)
155+
assert False, f"failed to connect to or run a statement in the following database: {database}"
156+
except psycopg2.OperationalError as e:
157+
if not should_fail:
158+
logger.exception(e)
159+
finally:
160+
if connection is not None:
161+
connection.close()

0 commit comments

Comments
 (0)