From 861c8dee486e49f5089d42efe0d62e6a33d5118b Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Wed, 30 May 2018 16:09:27 +0200 Subject: [PATCH 1/2] Update RuleEnforcementDB constructor to set status field to failed for old / existing object in the database which pre-date status field and have failure_reason field populated. --- .../st2common/models/db/rule_enforcement.py | 11 ++++ .../tests/unit/test_db_rule_enforcement.py | 58 +++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/st2common/st2common/models/db/rule_enforcement.py b/st2common/st2common/models/db/rule_enforcement.py index cf801b5fc0..5e5d7c1847 100644 --- a/st2common/st2common/models/db/rule_enforcement.py +++ b/st2common/st2common/models/db/rule_enforcement.py @@ -22,6 +22,7 @@ from st2common.models.db import stormbase from st2common.util import date as date_utils from st2common.constants.rule_enforcement import RULE_ENFORCEMENT_STATUS_SUCCEEDED +from st2common.constants.rule_enforcement import RULE_ENFORCEMENT_STATUS_FAILED __all__ = [ 'RuleReferenceSpecDB', @@ -77,6 +78,16 @@ class RuleEnforcementDB(stormbase.StormFoundationDB, stormbase.TagsMixin): ] + stormbase.TagsMixin.get_indices() } + def __init__(self, *args, **values): + super(RuleEnforcementDB, self).__init__(*args, **values) + + # Set status to succeeded for old / existing RuleEnforcementDB which predate status field + status = getattr(self, 'status', None) + failure_reason = getattr(self, 'failure_reason', None) + + if status in [None, RULE_ENFORCEMENT_STATUS_SUCCEEDED] and failure_reason: + self.status = RULE_ENFORCEMENT_STATUS_FAILED + # NOTE: Note the following method is exposed so loggers in rbac resolvers can log objects # with a consistent get_uid interface. def get_uid(self): diff --git a/st2common/tests/unit/test_db_rule_enforcement.py b/st2common/tests/unit/test_db_rule_enforcement.py index d3df6d7275..17cd4ad287 100644 --- a/st2common/tests/unit/test_db_rule_enforcement.py +++ b/st2common/tests/unit/test_db_rule_enforcement.py @@ -20,11 +20,18 @@ from st2common.models.db.rule_enforcement import RuleEnforcementDB from st2common.persistence.rule_enforcement import RuleEnforcement from st2common.transport.publishers import PoolPublisher +from st2common.constants.rule_enforcement import RULE_ENFORCEMENT_STATUS_SUCCEEDED +from st2common.constants.rule_enforcement import RULE_ENFORCEMENT_STATUS_FAILED from st2common.exceptions.db import StackStormDBObjectNotFoundError + from st2tests import DbTestCase SKIP_DELETE = False +__all__ = [ + 'RuleEnforcementModelTest' +] + @mock.patch.object(PoolPublisher, 'publish', mock.MagicMock()) class RuleEnforcementModelTest(DbTestCase): @@ -51,6 +58,57 @@ def test_ruleenforcment_crud(self): retrieved = None self.assertIsNone(retrieved, 'managed to retrieve after delete.') + def test_status_set_to_failed_for_objects_which_predate_status_field(self): + rule = { + 'ref': 'foo_pack.foo_rule', + 'uid': 'rule:foo_pack:foo_rule' + } + + # 1. No status field explicitly set and no failure reason + enforcement_db = RuleEnforcementDB(trigger_instance_id=str(bson.ObjectId()), + rule=rule, + execution_id=str(bson.ObjectId())) + enforcement_db = RuleEnforcement.add_or_update(enforcement_db) + + self.assertEqual(enforcement_db.status, RULE_ENFORCEMENT_STATUS_SUCCEEDED) + + # 2. No status field, with failure reason, status should be set to failed + enforcement_db = RuleEnforcementDB(trigger_instance_id=str(bson.ObjectId()), + rule=rule, + execution_id=str(bson.ObjectId()), + failure_reason='so much fail') + enforcement_db = RuleEnforcement.add_or_update(enforcement_db) + + self.assertEqual(enforcement_db.status, RULE_ENFORCEMENT_STATUS_FAILED) + + # 3. Explcit status field - succeeded + failure reasun + enforcement_db = RuleEnforcementDB(trigger_instance_id=str(bson.ObjectId()), + rule=rule, + execution_id=str(bson.ObjectId()), + status=RULE_ENFORCEMENT_STATUS_SUCCEEDED, + failure_reason='so much fail') + enforcement_db = RuleEnforcement.add_or_update(enforcement_db) + + self.assertEqual(enforcement_db.status, RULE_ENFORCEMENT_STATUS_FAILED) + + # 4. Explcit status field - succeeded + no failure reasun + enforcement_db = RuleEnforcementDB(trigger_instance_id=str(bson.ObjectId()), + rule=rule, + execution_id=str(bson.ObjectId()), + status=RULE_ENFORCEMENT_STATUS_SUCCEEDED) + enforcement_db = RuleEnforcement.add_or_update(enforcement_db) + + self.assertEqual(enforcement_db.status, RULE_ENFORCEMENT_STATUS_SUCCEEDED) + + # 5. Explcit status field - failed + no failure reasun + enforcement_db = RuleEnforcementDB(trigger_instance_id=str(bson.ObjectId()), + rule=rule, + execution_id=str(bson.ObjectId()), + status=RULE_ENFORCEMENT_STATUS_FAILED) + enforcement_db = RuleEnforcement.add_or_update(enforcement_db) + + self.assertEqual(enforcement_db.status, RULE_ENFORCEMENT_STATUS_FAILED) + @staticmethod def _create_save_rule_enforcement(): created = RuleEnforcementDB(trigger_instance_id=str(bson.ObjectId()), From a1ad685f3ad3dee45f0e76ba1b5a45168592d7a9 Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Wed, 30 May 2018 16:42:10 +0200 Subject: [PATCH 2/2] Update changelog. --- CHANGELOG.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index e6ac1bff52..e2d4c3af49 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -23,7 +23,7 @@ Added * Add new ``status`` field to the ``RuleEnforcement`` model. This field can contain the following values - ``succeeded`` (trigger instance matched a rule and action execution was triggered successfully), ``failed`` (trigger instance matched a rule, but it didn't result in an action - execution due to Jinja rendering failure or other exception). (improvement) #4134 + execution due to Jinja rendering failure or other exception). (improvement) #4134 #4152 * Add trigger type reference based filtering to the ``/v1/triggerinstances`` API endpoint - e.g. ``/v1/triggerinstances?trigger_type=core.st2.webhook``. (new feature) #4151