Fix DriverFilter/GoodnessWeigher string evaluations

When trying to compare two values that are non-numeric using the driver
filter, the filter function will give an error. This is not desirable as
it might be interesting to support comparatives with non-numeric values
provided by the filter objects (share, host, etc). For example, the
following formula failed before the fix:

filter_function = '(share.project_id == "bb212f09317a4f4a8952ef3f729c2551")'

Copied from cinder 87a7e80a2c

Closes-Bug: #1975715
Change-Id: Icbfabb3bc0f608ebdd0784337db0921cc7763c53
This commit is contained in:
Maurice Escher
2022-05-25 11:38:46 +02:00
committed by Kiran Pawar
parent c81ff020f3
commit a2ebe1eb9a
3 changed files with 17 additions and 9 deletions

View File

@@ -56,9 +56,9 @@ class EvalConstant(object):
except ValueError: except ValueError:
try: try:
result = float(result) result = float(result)
except ValueError as e: except ValueError:
msg = _("ValueError: %s") % e if isinstance(result, str):
raise exception.EvaluatorParseException(reason=msg) result = result.replace('"', '').replace('\'', '')
return result return result
@@ -233,6 +233,7 @@ def _def_parser():
Combine = pyparsing.Combine Combine = pyparsing.Combine
Forward = pyparsing.Forward Forward = pyparsing.Forward
nums = pyparsing.nums nums = pyparsing.nums
quoted_string = pyparsing.quotedString
oneOf = pyparsing.oneOf oneOf = pyparsing.oneOf
opAssoc = pyparsing.opAssoc opAssoc = pyparsing.opAssoc
infixNotation = pyparsing.infixNotation infixNotation = pyparsing.infixNotation
@@ -244,7 +245,7 @@ def _def_parser():
number = real | integer number = real | integer
expr = Forward() expr = Forward()
fn = Word(alphas + '_' + '.') fn = Word(alphas + '_' + '.')
operand = number | variable | fn operand = number | variable | fn | quoted_string
signop = oneOf('+ -') signop = oneOf('+ -')
addop = oneOf('+ -') addop = oneOf('+ -')

View File

@@ -128,11 +128,12 @@ class EvaluatorTestCase(test.TestCase):
def test_nonnumber_comparison(self): def test_nonnumber_comparison(self):
nonnumber = {'test': 'foo'} nonnumber = {'test': 'foo'}
request = {'test': 'bar'} request = {'test': 'bar'}
self.assertRaises( self.assertTrue(
exception.EvaluatorParseException, evaluator.evaluate("nonnumber.test != request.test",
evaluator.evaluate, nonnumber=nonnumber, request=request))
"nonnumber.test != request.test", self.assertFalse(
nonnumber=nonnumber, request=request) evaluator.evaluate("nonnumber.test == request.test",
nonnumber=nonnumber, request=request))
def test_div_zero(self): def test_div_zero(self):
self.assertRaises(exception.EvaluatorParseException, self.assertRaises(exception.EvaluatorParseException,

View File

@@ -0,0 +1,6 @@
---
fixes:
- |
Goodness_function expects integer or float else raise parseException. This
causes example such as "(share.share_proto == 'CIFS') ? 100 : 50" to fail
during evaluation. Fix it by adding support of string evalution.