From 229396009471d57fe623407eb94db04a6b6f908f Mon Sep 17 00:00:00 2001 From: d-w-moore Date: Sat, 22 Aug 2026 10:07:57 -0400 Subject: [PATCH 1/3] [_823] add change and test for enabling RuleExec's context member --- irods/models.py | 6 +----- irods/test/rule_test.py | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/irods/models.py b/irods/models.py index 5b87bb34d..8986d6a22 100644 --- a/irods/models.py +++ b/irods/models.py @@ -33,11 +33,7 @@ class RuleExec(Model): last_exe_time = Column(DateTime, "RULE_EXEC_LAST_EXE_TIME", 1010) frequency = Column(String, "RULE_EXEC_FREQUENCY", 1006) priority = Column(String, "RULE_EXEC_PRIORITY", 1007) - - -# # If needed in 4.2.9, we can update the Query class to dynamically -# # attach this field based on server version: -# context = Column(String, 'RULE_EXEC_CONTEXT', 1012) + context = Column(String, 'RULE_EXEC_CONTEXT', 1012, min_version=(4, 3, 0)) # # These are either unused or usually absent: # exec_status = Column(String,'RULE_EXEC_STATUS', 1011) diff --git a/irods/test/rule_test.py b/irods/test/rule_test.py index dccc07a6f..dd2b290e1 100644 --- a/irods/test/rule_test.py +++ b/irods/test/rule_test.py @@ -437,6 +437,28 @@ def test_rulefile_in_file_like_object_2__336(self): self.assertRegex(lines[1], r"\[STRING\]\[A String\]") + def test_rule_exec_context(self): + rule_id = -1 + if self.sess.server_version == (4, 2, 1): + self.skipTest("""RuleExec's "context" attribute not available before 4.3.0""") + try: + n_minutes = 15 + random_int = random.randint(1<<30, (1<<31)-1) + r = Rule( + self.sess, + body=f'''delay("{n_minutes}m") {{writeLine("serverLog","{random_int}")}}''' + ) + r.execute() + l = list(self.sess.query(RuleExec).filter(Like(RuleExec.name,f'%"{random_int}"%'))) + rule_id = l[0][RuleExec.id] + + # Assert context exists, is of string type, and is not empty. + self.assertGreater(l[0][RuleExec.context], "") + finally: + if rule_id >= 0: + r.remove_by_id(rule_id) + + if __name__ == "__main__": # let the tests find the parent irods lib sys.path.insert(0, os.path.abspath("../..")) From 66343f5340d0a2b43d56196e151bf470a4526cff Mon Sep 17 00:00:00 2001 From: d-w-moore Date: Fri, 28 Aug 2026 10:04:05 -0400 Subject: [PATCH 2/3] extras to make test run --- irods/test/rule_test.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/irods/test/rule_test.py b/irods/test/rule_test.py index dd2b290e1..57519ea29 100644 --- a/irods/test/rule_test.py +++ b/irods/test/rule_test.py @@ -3,10 +3,12 @@ import os import sys +import random import time import textwrap import unittest -from irods.models import DataObject +from irods.column import Like +from irods.models import DataObject, RuleExec from irods.exception import ( FAIL_ACTION_ENCOUNTERED_ERR, RULE_ENGINE_ERROR, From 74896ccb392519a6fa66ab870caaeff18b5c7f84 Mon Sep 17 00:00:00 2001 From: d-w-moore Date: Fri, 28 Aug 2026 10:17:24 -0400 Subject: [PATCH 3/3] comments --- irods/test/rule_test.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/irods/test/rule_test.py b/irods/test/rule_test.py index 57519ea29..0ee7718fc 100644 --- a/irods/test/rule_test.py +++ b/irods/test/rule_test.py @@ -440,10 +440,13 @@ def test_rulefile_in_file_like_object_2__336(self): def test_rule_exec_context(self): - rule_id = -1 - if self.sess.server_version == (4, 2, 1): + if self.sess.server_version < (4, 3): self.skipTest("""RuleExec's "context" attribute not available before 4.3.0""") + + rule_id = -1 + try: + # Schedule a delayed rule. n_minutes = 15 random_int = random.randint(1<<30, (1<<31)-1) r = Rule( @@ -451,12 +454,15 @@ def test_rule_exec_context(self): body=f'''delay("{n_minutes}m") {{writeLine("serverLog","{random_int}")}}''' ) r.execute() + + # Get the delayed rule's ID, needed for cancellation. l = list(self.sess.query(RuleExec).filter(Like(RuleExec.name,f'%"{random_int}"%'))) rule_id = l[0][RuleExec.id] # Assert context exists, is of string type, and is not empty. self.assertGreater(l[0][RuleExec.context], "") finally: + # Remove the delayed rule from the queue. if rule_id >= 0: r.remove_by_id(rule_id)