Repository: rucio/rucio
Issue: New psycopg2-binary release incompatible with current sqlalchemy version

Motivation
----------
Yesterday a new release (2.8) of `psycopg2-binary` was published. With this release, the tests do not run through, as exceptions are handled differently with our current version of sqlalchemy.
https://pypi.org/project/psycopg2-binary/2.8/

Modification
------------
For now we will fix `setup_rucio.py` to not install the 2.8 version thus:
`psycopg2-binary>=2.4.2<2.8'

Once we update sqlalchemy to a newer version, this can be relaxed.

Changed files:
lib/rucio/tests/test_judge_injector.py, setup_rucio.py, lib/rucio/core/rule.py

diff --git a/lib/rucio/core/rule.py b/lib/rucio/core/rule.py
index cd811be24..1025460ab 100644
--- a/lib/rucio/core/rule.py
+++ b/lib/rucio/core/rule.py
@@ -610,6 +610,11 @@ def inject_rule(rule_id, session=None):
     except NoResultFound:
         raise RuleNotFound('No rule with the id %s found' % (rule_id))
 
+    # Check if rule will expire in the next 5 minutes:
+    if rule.child_rule_id is None and rule.expires_at is not None and rule.expires_at < datetime.utcnow() + timedelta(seconds=300):
+        logging.info('Rule %s expiring soon, skipping', str(rule.id))
+        return
+
     # Special R2D2 container handling
     if (rule.did_type == DIDType.CONTAINER and '.r2d2_request.' in rule.name) or (rule.split_container and rule.did_type == DIDType.CONTAINER):
         logging.debug("Creating dataset rules for Split Container rule %s", str(rule.id))
diff --git a/lib/rucio/tests/test_judge_injector.py b/lib/rucio/tests/test_judge_injector.py
index 215718f0a..47f091891 100644
--- a/lib/rucio/tests/test_judge_injector.py
+++ b/lib/rucio/tests/test_judge_injector.py
@@ -6,7 +6,7 @@
 # http://www.apache.org/licenses/LICENSE-2.0
 #
 # Authors:
-# - Martin Barisits, <martin.barisits@cern.ch>, 2015-2016
+# - Martin Barisits, <martin.barisits@cern.ch>, 2015-2019
 
 from nose.tools import assert_raises
 
@@ -136,7 +136,7 @@ class TestJudgeEvaluator():
             add_did(scope, dataset, DIDType.from_sym('DATASET'), 'jdoe')
             attach_dids(scope, dataset, files, 'jdoe')
             attach_dids(scope, container, [{'scope': scope, 'name': dataset}], 'jdoe')
-        rule_id = add_rule(dids=[{'scope': scope, 'name': container}], account='jdoe', copies=1, rse_expression=self.rse1, grouping='DATASET', weight=None, lifetime=100, locked=False, subscription_id=None, ask_approval=True)[0]
+        rule_id = add_rule(dids=[{'scope': scope, 'name': container}], account='jdoe', copies=1, rse_expression=self.rse1, grouping='DATASET', weight=None, lifetime=900, locked=False, subscription_id=None, ask_approval=True)[0]
         approve_rule(rule_id, approver='root')
         assert(get_rule(rule_id)['state'] == RuleState.INJECT)
         rule_injector(once=True)
@@ -159,8 +159,8 @@ class TestJudgeEvaluator():
             add_did(scope, dataset, DIDType.from_sym('DATASET'), 'jdoe')
             attach_dids(scope, dataset, files, 'jdoe')
             attach_dids(scope, container, [{'scope': scope, 'name': dataset}], 'jdoe')
-        add_rule(dids=[{'scope': scope, 'name': dataset}], account='jdoe', copies=1, rse_expression=self.rse1, grouping='DATASET', weight=None, lifetime=100, locked=False, subscription_id=None, ask_approval=False)
-        rule_id = add_rule(dids=[{'scope': scope, 'name': container}], account='jdoe', copies=1, rse_expression=self.rse1, grouping='DATASET', weight=None, lifetime=100, locked=False, subscription_id=None, ask_approval=True)[0]
+        add_rule(dids=[{'scope': scope, 'name': dataset}], account='jdoe', copies=1, rse_expression=self.rse1, grouping='DATASET', weight=None, lifetime=900, locked=False, subscription_id=None, ask_approval=False)
+        rule_id = add_rule(dids=[{'scope': scope, 'name': container}], account='jdoe', copies=1, rse_expression=self.rse1, grouping='DATASET', weight=None, lifetime=900, locked=False, subscription_id=None, ask_approval=True)[0]
         approve_rule(rule_id, approver='root')
         assert(get_rule(rule_id)['state'] == RuleState.INJECT)
         rule_injector(once=True)
diff --git a/setup_rucio.py b/setup_rucio.py
index d7e4d3a6a..7729b7c82 100644
--- a/setup_rucio.py
+++ b/setup_rucio.py
@@ -15,7 +15,7 @@
 # Authors:
 # - Vincent Garonne <vgaronne@gmail.com>, 2014-2018
 # - Thomas Beermann <thomas.beermann@cern.ch>, 2014-2018
-# - Martin Barisits <martin.barisits@cern.ch>, 2016-2018
+# - Martin Barisits <martin.barisits@cern.ch>, 2016-2019
 # - Mario Lassnig <mario.lassnig@cern.ch>, 2019
 
 '''
@@ -164,7 +164,7 @@ def write_requirements():
 
 
 oracle_extras = ['cx_oracle==6.3.1']
-postgresql_extras = ['psycopg2-binary>=2.4.2']
+postgresql_extras = ['psycopg2-binary>=2.4.2,<2.8']
 mysql_extras = ['PyMySQL']
 kerberos_extras = ['kerberos>=1.3.0', 'pykerberos>=1.2.1', 'requests-kerberos>=0.12.0']
 dev_extras = parse_requirements(requirements_files=['tools/pip-requires-test', ])