Skip to content

Commit df0de8e

Browse files
GitHKAndrei Neagu
and
Andrei Neagu
authored
garbage collector system overhaul and extras (#1724)
* guests without projects are now removed * makes no senso for GUEST users * garbage collection should result more descirptive * added more notes * added more notes * minor refactor * fixed error * functions have been split into smaller self contained entities * removed outdated description * moved code blocks up * removed unused function * moved function position * changed import name * gc takes into consideration access rights when removing users * fixed pylint issues * removed unused code * refactored code * updated changelog * added link in changelog * PRs are now linked in the changelog * marking container nvidia-smi for autoremove * during testing aiohttp logs are displayed - applied black reformat * removed unencessary comments * fixed issue which caused silent 401 - @sanderegg there was an error but no traceback was presnet * replaced with a more updated version * added empty_project_data and trapped a new error * updated dependencies * removed unused import * added tests for garbage collection * fixed some dependencies * conftest refactoring * now creates a template db to be used between tests * tests correctly run in integration testing * refactored tests implemnted T4 * fixed an issue with project ownership detection test_t5 was implemented * implemented t6 * implemented t7 * implemented t8 * implemented t9 * updated changelog * removed usless test module * @sanderegg suggestion * @sanderegg should adds clarity to the reasoning * @sanderegg renaming function to something more clear * removed typo * @sanderegg removed redundant comments * @sanderegg refactored fixture into a function * fixing out more typos * minor refactor and cleanup * introduce tests to handle multiple user deletion - fixed a bug - added 2 tests * removed uneeded comment * used @pcrespov suggestion and refactored * reverting depenencies for fugure upgrade @pcrespov * moved in a more adequate palce * changed outdated pytest fixture Co-authored-by: Andrei Neagu <[email protected]>
1 parent fc5b858 commit df0de8e

File tree

21 files changed

+1489
-268
lines changed

21 files changed

+1489
-268
lines changed

CHANGELOG.md

+38-35
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,15 @@ FIXME: Compare shows single commit. SEE https://github.com/ITISFoundation/osparc
1212
### Added
1313

1414
- Started this *human-readable* CHANGELOG
15-
- ``migration`` service that discovers postgres service and upgrades main database (#1714)
16-
- Every group can register official classifiers for studies and services. Diplayed as a tree in UI (#1670, #1719, #1722)
15+
- ``migration`` service that discovers postgres service and upgrades main database [#1714](https://github.com/ITISFoundation/osparc-simcore/pull/1714)
16+
- Every group can register official classifiers for studies and services. Diplayed as a tree in UI [#1670](https://github.com/ITISFoundation/osparc-simcore/pull/1670), [#1719](https://github.com/ITISFoundation/osparc-simcore/pull/1719) , [#1722](https://github.com/ITISFoundation/osparc-simcore/pull/1722)
17+
- GC tests are run in isolation with a template database [#1724](https://github.com/ITISFoundation/osparc-simcore/pull/1724)
1718

1819
### Changed
1920

20-
- Speedup testing by splitting webserver (#1711)
21+
- Speedup testing by splitting webserver [#1711](https://github.com/ITISFoundation/osparc-simcore/pull/1711)
22+
- Refactored garbage collector and added tests [#1724](https://github.com/ITISFoundation/osparc-simcore/pull/1724)
23+
- Logs are now displayed during testing [#1724](https://github.com/ITISFoundation/osparc-simcore/pull/1724)
2124

2225
<!-- ### Deprecated -->
2326
<!-- ### Removed -->
@@ -28,45 +31,45 @@ FIXME: Compare shows single commit. SEE https://github.com/ITISFoundation/osparc
2831
## [0.0.25] - 2020-08-04
2932

3033
### Added
31-
- add traefik endpoint to api-gateway (#1555)
32-
- Shared project concurrency (frontend) (#1591)
33-
- Homogenize studies and services (#1569)
34+
- add traefik endpoint to api-gateway [#1555](https://github.com/ITISFoundation/osparc-simcore/pull/1555)
35+
- Shared project concurrency (frontend) [#1591](https://github.com/ITISFoundation/osparc-simcore/pull/1591)
36+
- Homogenize studies and services [#1569](https://github.com/ITISFoundation/osparc-simcore/pull/1569)
3437
- UI Fine grained access - project locking and notification
35-
- Adds support for GPU scheduling of computational services (#1553)
38+
- Adds support for GPU scheduling of computational services [#1553](https://github.com/ITISFoundation/osparc-simcore/pull/1553)
3639

3740
### Changed
38-
- UI/UX improvements (#1657)
39-
- Improving storage performance (#1659)
40-
- Theming (#1656)
41-
- Reduce cardinality of metrics (#1593)
41+
- UI/UX improvements [#1657](https://github.com/ITISFoundation/osparc-simcore/pull/1657)
42+
- Improving storage performance [#1659](https://github.com/ITISFoundation/osparc-simcore/pull/1659)
43+
- Theming [#1656](https://github.com/ITISFoundation/osparc-simcore/pull/1656)
44+
- Reduce cardinality of metrics [#1593](https://github.com/ITISFoundation/osparc-simcore/pull/1593)
4245

4346
### Fixed
44-
- Platform stability: (#1645)
45-
- Fix, improves and re-activate e2e CI testing (#1594, #1620, #1631, #1600)
46-
- Fixes defaults (#1640)
47-
- Upgrade storage service (#1585, #1586)
48-
- UPgrade catalog service (#1582)
49-
- Fixes on publish studies handling (#1632)
50-
- Invalidate cache before starting a study (#1602)
51-
- Some enhancements and bug fixes (#1608)
52-
- filter studies by name before deleting them (#1629)
53-
- Bugfix/apiserver does not need sslheaders (#1564)
54-
- fix testing if node has gpu support (#1604)
55-
- /study fails 500 (#1570, #1572)
56-
- fix codecov reports (#1568)
47+
- Platform stability: [#1645](https://github.com/ITISFoundation/osparc-simcore/pull/1645)
48+
- Fix, improves and re-activate e2e CI testing [#1594](https://github.com/ITISFoundation/osparc-simcore/pull/1594), [#1620](https://github.com/ITISFoundation/osparc-simcore/pull/1620), [#1631](https://github.com/ITISFoundation/osparc-simcore/pull/1631), [#1600](https://github.com/ITISFoundation/osparc-simcore/pull/1600)
49+
- Fixes defaults [#1640](https://github.com/ITISFoundation/osparc-simcore/pull/1640)
50+
- Upgrade storage service [#1585](https://github.com/ITISFoundation/osparc-simcore/pull/1585), [#1586](https://github.com/ITISFoundation/osparc-simcore/pull/1586)
51+
- UPgrade catalog service [#1582](https://github.com/ITISFoundation/osparc-simcore/pull/1582)
52+
- Fixes on publish studies handling [#1632](https://github.com/ITISFoundation/osparc-simcore/pull/1632)
53+
- Invalidate cache before starting a study [#1602](https://github.com/ITISFoundation/osparc-simcore/pull/1602)
54+
- Some enhancements and bug fixes [#1608](https://github.com/ITISFoundation/osparc-simcore/pull/1608)
55+
- filter studies by name before deleting them [#1629](https://github.com/ITISFoundation/osparc-simcore/pull/1629)
56+
- Bugfix/apiserver does not need sslheaders [#1564](https://github.com/ITISFoundation/osparc-simcore/pull/1564)
57+
- fix testing if node has gpu support [#1604](https://github.com/ITISFoundation/osparc-simcore/pull/1604)
58+
- /study fails 500 [#1570](https://github.com/ITISFoundation/osparc-simcore/pull/1570), [#1572](https://github.com/ITISFoundation/osparc-simcore/pull/1572)
59+
- fix codecov reports [#1568](https://github.com/ITISFoundation/osparc-simcore/pull/1568)
5760

5861
### Security
59-
- Bump yarl from 1.4.2 to 1.5.1 in /packages/postgres-database (#1665)
60-
- Bump ujson from 3.0.0 to 3.1.0 in /packages/service-library (#1664)
61-
- Bump pytest-docker from 0.7.2 to 0.8.0 in /packages/service-library (#1647)
62-
- Bump aiozipkin from 0.6.0 to 0.7.0 in /packages/service-library (#1642)
63-
- Bump lodash from 4.17.15 to 4.17.19 (#1639)
64-
- Maintenance/upgrades test tools (#1628)
65-
- Bugfix/concurent opening projects (#1598)
66-
- Bugfix/allow reading groups anonymous user (#1615)
67-
- Bump docker from 4.2.1 to 4.2.2 in /packages/postgres-database (#1605)
68-
- Bump faker from 4.1.0 to 4.1.1 in /packages/postgres-database (#1573)
69-
- Maintenance/upgrades and tooling (#1546)
62+
- Bump yarl from 1.4.2 to 1.5.1 in /packages/postgres-database [#1665](https://github.com/ITISFoundation/osparc-simcore/pull/1665)
63+
- Bump ujson from 3.0.0 to 3.1.0 in /packages/service-library [#1664](https://github.com/ITISFoundation/osparc-simcore/pull/1664)
64+
- Bump pytest-docker from 0.7.2 to 0.8.0 in /packages/service-library [#1647](https://github.com/ITISFoundation/osparc-simcore/pull/1647)
65+
- Bump aiozipkin from 0.6.0 to 0.7.0 in /packages/service-library [#1642](https://github.com/ITISFoundation/osparc-simcore/pull/1642)
66+
- Bump lodash from 4.17.15 to 4.17.19 [#1639](https://github.com/ITISFoundation/osparc-simcore/pull/1639)
67+
- Maintenance/upgrades test tools [#1628](https://github.com/ITISFoundation/osparc-simcore/pull/1628)
68+
- Bugfix/concurent opening projects [#1598](https://github.com/ITISFoundation/osparc-simcore/pull/1598)
69+
- Bugfix/allow reading groups anonymous user [#1615](https://github.com/ITISFoundation/osparc-simcore/pull/1615)
70+
- Bump docker from 4.2.1 to 4.2.2 in /packages/postgres-database [#1605](https://github.com/ITISFoundation/osparc-simcore/pull/1605)
71+
- Bump faker from 4.1.0 to 4.1.1 in /packages/postgres-database [#1573](https://github.com/ITISFoundation/osparc-simcore/pull/1573)
72+
- Maintenance/upgrades and tooling [#1546](https://github.com/ITISFoundation/osparc-simcore/pull/1546)
7073

7174

7275
---

packages/postgres-database/src/simcore_postgres_database/cli.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,11 @@
3737
discovered_cache = os.path.expanduser("~/.simcore_postgres_database_cache.json")
3838

3939
log = logging.getLogger("root")
40-
fileConfig(default_ini)
40+
41+
if __name__ == "__main__":
42+
# swallows up all log messages from tests
43+
# only enable it during cli invocation
44+
fileConfig(default_ini)
4145

4246

4347
def safe(if_fails_return=False):

packages/postgres-database/src/simcore_postgres_database/migration/env.py

+7-8
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
from logging.config import fileConfig
32

43
from alembic import context
@@ -12,7 +11,11 @@
1211

1312
# Interpret the config file for Python logging.
1413
# This line sets up loggers basically.
15-
fileConfig(config.config_file_name)
14+
15+
if __name__ == "__main__":
16+
# swallows up all log messages from tests
17+
# only enable it during cli invocation
18+
fileConfig(config.config_file_name)
1619

1720
# add your model's MetaData object here
1821
# for 'autogenerate' support
@@ -38,9 +41,7 @@ def run_migrations_offline():
3841
"""
3942
# pylint: disable=no-member
4043
url = config.get_main_option("sqlalchemy.url")
41-
context.configure(
42-
url=url, target_metadata=target_metadata, literal_binds=True
43-
)
44+
context.configure(url=url, target_metadata=target_metadata, literal_binds=True)
4445

4546
with context.begin_transaction():
4647
context.run_migrations()
@@ -61,9 +62,7 @@ def run_migrations_online():
6162
)
6263

6364
with connectable.connect() as connection:
64-
context.configure(
65-
connection=connection, target_metadata=target_metadata
66-
)
65+
context.configure(connection=connection, target_metadata=target_metadata)
6766

6867
with context.begin_transaction():
6968
context.run_migrations()

packages/pytest-simcore/src/pytest_simcore/helpers/utils_projects.py

+16-2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import re
1111
import uuid as uuidlib
1212
from typing import Dict
13+
from simcore_service_webserver.utils import now_str
1314

1415
from aiohttp import web
1516

@@ -32,6 +33,19 @@
3233
]
3334

3435

36+
def empty_project_data():
37+
return {
38+
"uuid": f"project-{uuidlib.uuid4()}",
39+
"name": "Empty name",
40+
"description": "some description of an empty project",
41+
"prjOwner": "I'm the empty project owner, hi!",
42+
"creationDate": now_str(),
43+
"lastChangeDate": now_str(),
44+
"thumbnail": "",
45+
"workbench": {},
46+
}
47+
48+
3549
def load_data(name):
3650
with resources.stream(name) as fp:
3751
return json.load(fp)
@@ -62,7 +76,7 @@ async def create_project(
6276
try:
6377
uuidlib.UUID(project_data["uuid"])
6478
assert new_project["uuid"] == project_data["uuid"]
65-
except ValueError:
79+
except (ValueError, AssertionError):
6680
# in that case the uuid gets replaced
6781
assert new_project["uuid"] != project_data["uuid"]
6882
project_data["uuid"] = new_project["uuid"]
@@ -90,7 +104,7 @@ def __init__(
90104
clear_all=True,
91105
user_id=None,
92106
*,
93-
force_uuid=False
107+
force_uuid=False,
94108
):
95109
self.params = params
96110
self.user_id = user_id

packages/pytest-simcore/src/pytest_simcore/postgres_service.py

+117-5
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,134 @@
22
# pylint:disable=unused-argument
33
# pylint:disable=redefined-outer-name
44

5-
import os
6-
from typing import Dict
75
import logging
6+
import asyncio
7+
import os
8+
from typing import Dict, List
89

910
import pytest
11+
import simcore_postgres_database.cli as pg_cli
1012
import sqlalchemy as sa
1113
import tenacity
12-
from sqlalchemy.orm import sessionmaker
13-
14-
import simcore_postgres_database.cli as pg_cli
1514
from simcore_postgres_database.models.base import metadata
15+
from sqlalchemy.orm import sessionmaker
1616

1717
from .helpers.utils_docker import get_service_published_port
1818

1919
log = logging.getLogger(__name__)
2020

21+
TEMPLATE_DB_TO_RESTORE = "template_simcore_db"
22+
23+
24+
def execute_queries(
25+
postgres_engine: sa.engine.Engine,
26+
sql_statements: List[str],
27+
ignore_errors: bool = False,
28+
) -> None:
29+
"""runs the queries in the list in order"""
30+
with postgres_engine.connect() as con:
31+
for statement in sql_statements:
32+
try:
33+
con.execution_options(autocommit=True).execute(statement)
34+
except Exception as e: # pylint: disable=broad-except
35+
# when running tests initially the TEMPLATE_DB_TO_RESTORE dose not exist and will cause an error
36+
# which can safely be ignored. The debug message is here to catch future errors which and
37+
# avoid time wasting
38+
log.debug("SQL error which can be ignored %s", str(e))
39+
40+
41+
def create_template_db(postgres_dsn: Dict, postgres_engine: sa.engine.Engine) -> None:
42+
# create a template db, the removal is necessary to allow for the usage of --keep-docker-up
43+
queries = [
44+
# disconnect existing users
45+
f"""
46+
SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity
47+
WHERE pg_stat_activity.datname = '{postgres_dsn["database"]}' AND pid <> pg_backend_pid();
48+
""",
49+
# drop template database
50+
f"ALTER DATABASE {TEMPLATE_DB_TO_RESTORE} is_template false;",
51+
f"DROP DATABASE {TEMPLATE_DB_TO_RESTORE};",
52+
# create template database
53+
"""
54+
CREATE DATABASE {template_db} WITH TEMPLATE {original_db} OWNER {db_user};
55+
""".format(
56+
template_db=TEMPLATE_DB_TO_RESTORE,
57+
original_db=postgres_dsn["database"],
58+
db_user=postgres_dsn["user"],
59+
),
60+
]
61+
execute_queries(postgres_engine, queries, ignore_errors=True)
62+
63+
64+
def drop_template_db(postgres_engine: sa.engine.Engine) -> None:
65+
# remove the template db
66+
queries = [
67+
# drop template database
68+
f"ALTER DATABASE {TEMPLATE_DB_TO_RESTORE} is_template false;",
69+
f"DROP DATABASE {TEMPLATE_DB_TO_RESTORE};",
70+
]
71+
execute_queries(postgres_engine, queries)
72+
73+
74+
@pytest.fixture(scope="module")
75+
def loop(request):
76+
loop = asyncio.get_event_loop_policy().new_event_loop()
77+
yield loop
78+
loop.close()
79+
80+
81+
@pytest.fixture(scope="module")
82+
def postgres_with_template_db(
83+
postgres_db: sa.engine.Engine, postgres_dsn: Dict, postgres_engine: sa.engine.Engine
84+
) -> sa.engine.Engine:
85+
create_template_db(postgres_dsn, postgres_engine)
86+
yield postgres_engine
87+
drop_template_db(postgres_engine)
88+
89+
90+
@pytest.fixture
91+
def drop_db_engine(postgres_dsn: Dict) -> sa.engine.Engine:
92+
postgres_dsn_copy = postgres_dsn.copy() # make a copy to change these parameters
93+
postgres_dsn_copy["database"] = "postgres"
94+
dsn = "postgresql://{user}:{password}@{host}:{port}/{database}".format(
95+
**postgres_dsn_copy
96+
)
97+
return sa.create_engine(dsn, isolation_level="AUTOCOMMIT")
98+
99+
100+
@pytest.fixture
101+
def database_from_template_before_each_function(
102+
postgres_dsn: Dict, drop_db_engine: sa.engine.Engine, postgres_db
103+
) -> None:
104+
"""
105+
Will recrate the db before running each test.
106+
107+
**Note: must be implemented in the module where the the
108+
`postgres_with_template_db` is used and mark autouse=True**
109+
110+
It is possible to drop the application database by ussing another one like
111+
the posgtres database. The db will be recrated from the previously created template
112+
113+
The postgres_db fixture is required for the template database to be created.
114+
"""
115+
116+
queries = [
117+
# terminate existing connections to the database
118+
f"""
119+
SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity
120+
WHERE pg_stat_activity.datname = '{postgres_dsn["database"]}';
121+
""",
122+
# drop database
123+
f"DROP DATABASE {postgres_dsn['database']};",
124+
# create from template database
125+
f"CREATE DATABASE {postgres_dsn['database']} TEMPLATE template_simcore_db;",
126+
]
127+
128+
execute_queries(drop_db_engine, queries)
129+
130+
yield
131+
# do nothing on teadown
132+
21133

22134
@pytest.fixture(scope="module")
23135
def postgres_dsn(docker_stack: Dict, devel_environ: Dict) -> Dict[str, str]:

0 commit comments

Comments
 (0)