From 45537a9f657f8e9b509adbff607466dfbd36265c Mon Sep 17 00:00:00 2001 From: Leopold Talirz Date: Thu, 14 Feb 2019 15:14:03 +0100 Subject: [PATCH 1/4] prevent tests from deleting the default user PR #2214 stripped of safeguards that prevented the default user from being deleted in between tests. Since AiiDA expects a default user in many operations, leaving the DB in a state with no default user is not ideal. This commit reintroduces safeguards that result in the default user remaining untouched. --- aiida/backends/djsite/db/testbase.py | 6 +++++- aiida/backends/testimplbase.py | 15 ++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/aiida/backends/djsite/db/testbase.py b/aiida/backends/djsite/db/testbase.py index 1d5400f9d2..7210a20ffe 100644 --- a/aiida/backends/djsite/db/testbase.py +++ b/aiida/backends/djsite/db/testbase.py @@ -43,6 +43,9 @@ def setUpClass_method(self): def clean_db(self): from aiida.backends.djsite.db import models + from aiida.manage import get_config + + email = get_config().current_profile.default_user_email # I first need to delete the links, because in principle I could not delete input nodes, only outputs. # For simplicity, since I am deleting everything, I delete the links first @@ -52,7 +55,8 @@ def clean_db(self): models.DbLog.objects.all().delete() models.DbNode.objects.all().delete() # pylint: disable=no-member models.DbWorkflow.objects.all().delete() # pylint: disable=no-member - models.DbUser.objects.all().delete() # pylint: disable=no-member + # The default user is needed for many operations in AiiDA; do not delete it. + models.DbUser.objects.exclude(email=email).delete() # pylint: disable=no-member models.DbComputer.objects.all().delete() models.DbGroup.objects.all().delete() diff --git a/aiida/backends/testimplbase.py b/aiida/backends/testimplbase.py index 320ffed7ec..b26f002d7b 100644 --- a/aiida/backends/testimplbase.py +++ b/aiida/backends/testimplbase.py @@ -14,7 +14,7 @@ import six -from aiida.common.exceptions import InternalError +from aiida.common.exceptions import InternalError, NotExistent from aiida import orm @@ -87,10 +87,15 @@ def insert_data(self): backend=self.backend ).store() - config = get_config() - email = config.current_profile.default_user_email - self.user = orm.User(email=email).store() - self.user_email = email + # Since the default user is needed for many operations in AiiDA, it is not deleted by clean_db. + # In principle, it should therefore always exist - if not we create it anyhow. + default_user_email = get_config().current_profile.default_user_email + try: + self.user = orm.User.objects.get(email=default_user_email) + except NotExistent: + self.user = orm.User(email=email).store() + + self.user_email = self.user.email def get_computer(self): """ From bdfac5e45d92f0bab457d0085b13eaa686ec7934 Mon Sep 17 00:00:00 2001 From: Leopold Talirz Date: Thu, 14 Feb 2019 15:21:14 +0100 Subject: [PATCH 2/4] minor fix --- aiida/backends/testimplbase.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/aiida/backends/testimplbase.py b/aiida/backends/testimplbase.py index b26f002d7b..f0af024020 100644 --- a/aiida/backends/testimplbase.py +++ b/aiida/backends/testimplbase.py @@ -87,15 +87,14 @@ def insert_data(self): backend=self.backend ).store() + self.user_email = get_config().current_profile.default_user_email + # Since the default user is needed for many operations in AiiDA, it is not deleted by clean_db. # In principle, it should therefore always exist - if not we create it anyhow. - default_user_email = get_config().current_profile.default_user_email try: - self.user = orm.User.objects.get(email=default_user_email) + self.user = orm.User.objects.get(email=self.user_email) except NotExistent: - self.user = orm.User(email=email).store() - - self.user_email = self.user.email + self.user = orm.User(email=self.user_email).store() def get_computer(self): """ From 7cf88a1977390d3bbfb41b82749e47a5cde1809e Mon Sep 17 00:00:00 2001 From: Leopold Talirz Date: Thu, 14 Feb 2019 15:31:35 +0100 Subject: [PATCH 3/4] add fix also for sqla --- aiida/backends/sqlalchemy/tests/testbase.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/aiida/backends/sqlalchemy/tests/testbase.py b/aiida/backends/sqlalchemy/tests/testbase.py index 094f6f02b8..c97e7b0e35 100644 --- a/aiida/backends/sqlalchemy/tests/testbase.py +++ b/aiida/backends/sqlalchemy/tests/testbase.py @@ -89,6 +89,9 @@ def clean_db(self): from aiida.backends.sqlalchemy.models.log import DbLog from aiida.backends.sqlalchemy.models.user import DbUser from aiida.backends.sqlalchemy.models.workflow import DbWorkflow + from aiida.manage import get_config + + email = get_config().current_profile.default_user_email # Empty the relationship dbgroup.dbnode dbgroups = self.test_session.query(DbGroup).all() @@ -105,7 +108,7 @@ def clean_db(self): # Then I delete the nodes, otherwise I cannot delete computers and users self.test_session.query(DbNode).delete() self.test_session.query(DbWorkflow).delete() - self.test_session.query(DbUser).delete() + self.test_session.query(DbUser).filter(DbUser.email != email).delete() self.test_session.query(DbComputer).delete() self.test_session.query(DbLog).delete() From edec57f17cabc951e13c3feb3e974684817f2fa9 Mon Sep 17 00:00:00 2001 From: Leopold Talirz Date: Thu, 14 Feb 2019 15:36:23 +0100 Subject: [PATCH 4/4] add testimplbase to pre-commit --- .pre-commit-config.yaml | 1 - aiida/backends/testimplbase.py | 17 +++++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a3112376fa..6dedb7f092 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -87,7 +87,6 @@ aiida/backends/sqlalchemy/transition_06dj_to_07sqla.py| aiida/backends/sqlalchemy/utils.py| aiida/backends/testbase.py| - aiida/backends/testimplbase.py| aiida/backends/tests/backup_script.py| aiida/backends/tests/backup_setup_script.py| aiida/backends/tests/base_dataclasses.py| diff --git a/aiida/backends/testimplbase.py b/aiida/backends/testimplbase.py index f0af024020..1a1147728d 100644 --- a/aiida/backends/testimplbase.py +++ b/aiida/backends/testimplbase.py @@ -7,6 +7,11 @@ # For further information on the license, see the LICENSE.txt file # # For further information please visit http://www.aiida.net # ########################################################################### +"""Base implementation of unittest classes for AiiDA. + +The base implementation is extended by the different backends. +""" + from __future__ import division from __future__ import print_function from __future__ import absolute_import @@ -45,7 +50,7 @@ class AiidaTestImplementation(object): user_email = None # type: str @abstractmethod - def setUpClass_method(self): + def setUpClass_method(self): # pylint: disable=invalid-name """ This class prepares the database (cleans it up and installs some basic entries). You have also to set a self.computer and a self.user_email as explained in the docstring of the @@ -53,13 +58,14 @@ def setUpClass_method(self): """ pass - def setUp_method(self): + def setUp_method(self): # pylint: disable=invalid-name pass - def tearDown_method(self): + def tearDown_method(self): # pylint: disable=invalid-name + pass - def tearDownClass_method(self): + def tearDownClass_method(self): # pylint: disable=invalid-name """ This class implements the tear down methods (e.g. cleans up the DB). """ @@ -84,8 +90,7 @@ def insert_data(self): transport_type='local', scheduler_type='pbspro', workdir='/tmp/aiida', - backend=self.backend - ).store() + backend=self.backend).store() self.user_email = get_config().current_profile.default_user_email