#2939 [policy]: AdvancedMatchTest and FindTest
Closed 2 years ago by julian8628. Opened 2 years ago by julian8628.
julian8628/koji policy  into  master

file modified
+66
@@ -141,6 +141,72 @@ 

          return False

  

  

+ class AdvancedMatchTest(BaseSimpleTest):

+     """Matches a field in the data against glob patterns

+ 

+     The field could be the same as match test,

+     or a dot-splited string which indicates key in a (nested) dict

+ 

+     True if any of the expressions match, else False

+     This test can be used as-is, or it can be subclassed to

+     test a specific field

+ 

+     Syntax:

+         adv_match field[.sub_field ...] pattern1 [pattern2 ...]

+ 

+     """

+     name = 'adv_match'

+     field = None

+ 

+     def run(self, data):

+         args = self.str.split()[1:]

+         if self.field is None:

+             field = args[0]

+             args = args[1:]

+         else:

+             # expected when we are subclassed

+             field = self.field

+         fields = field.split('.')

+         tgt = data

+         for i, f in enumerate(fields):

+             if not isinstance(tgt, dict):

+                 return False

+             if f not in tgt:

+                 return False

+             tgt = tgt.get(f)

+ 

+         for pattern in args:

+             if fnmatch.fnmatch(tgt, pattern):

+                 return True

+         return False

+ 

+ 

+ class FindTest(BaseSimpleTest):

+     """Matches any item of a list/tuple/set value in the data against glob patterns

+ 

+     True if any of the expressions matches any item in the list/tuple/set, else False.

+     If the field doesn't exist or isn't a list/tuple/set, the test returns False

+ 

+     Syntax:

+         find field pattern1 [pattern2 ...]

+ 

+     """

+     name = 'find'

+     field = None

+ 

+     def run(self, data):

+         args = self.str.split()[1:]

+         self.field = args[0]

+         args = args[1:]

+         tgt = data.get(self.field)

+         if tgt and isinstance(tgt, (list, tuple, set)):

+             for pattern in args:

+                 for i in tgt:

+                     if fnmatch.fnmatch(i, pattern):

+                         return True

+         return False

+ 

+ 

  class TargetTest(MatchTest):

      """Matches target in the data against glob patterns

  

@@ -66,6 +66,30 @@ 

          self.assertTrue(obj.run({'thing': 'elseplus'}))

          self.assertFalse(obj.run({}))

  

+     def test_adv_match_test(self):

+         obj = koji.policy.AdvancedMatchTest('not_important foo *bar*')

+         self.assertTrue(obj.run({'foo': 'foobar'}))

+         self.assertFalse(obj.run({'foo': 'nah...'}))

+         obj = koji.policy.AdvancedMatchTest('not_important foo.bar.hello world?')

+         self.assertTrue(obj.run({'foo': {

+             'bar': {

+                 'hello': 'world!'

+             }

+         }}))

+         self.assertFalse(obj.run({'foo': 'nah???'}))

+         self.assertFalse(obj.run({'foo': {

+             'bar': {

+                 'hello': 'world!!'

+             }

+         }}))

+ 

+     def test_find_test(self):

+         obj = koji.policy.FindTest('not_important foo *bar*')

+         self.assertTrue(obj.run({'foo': ['barrrr', 'any']}))

+         self.assertFalse(obj.run({'foo': ['nah....']}))

+         self.assertFalse(obj.run({'foo': 'nah...'}))

+         self.assertFalse(obj.run({'bar': ['any']}))

+ 

      def test_target_test(self):

          obj = koji.policy.TargetTest('target valid')

          self.assertTrue(obj.run({'target': 'valid'}))
@@ -124,6 +148,8 @@ 

              'false': koji.policy.FalseTest,

              'has': koji.policy.HasTest,

              'match': koji.policy.MatchTest,

+             'adv_match': koji.policy.AdvancedMatchTest,

+             'find': koji.policy.FindTest,

              'none': koji.policy.NoneTest,

              'target': koji.policy.TargetTest,

              'true': koji.policy.TrueTest,

  • new AdvancedMatchTest (adv_match) for nested dict matching
  • FindTest for list item matching
    fixes: #2938

1 new commit added

  • [policy] FindTest for list item matching
2 years ago

add FindTest for iterable value (list, tuple, set) too

Pull-Request has been closed by julian8628

2 years ago