[openstack-dev] [nova] [ironic] Input types for scheduler filters

Miles Gould mgould at redhat.com
Thu Jul 7 16:43:39 UTC 2016


Hi everyone,

tl;dr: the tests for the <all-in> operator in 
nova.scheduler.filters.extra_specs_ops do not test what it looks like 
they're meant to test. This is confusing us, and holding up work in 
Ironic. Does it match its arguments against a list of strings, or 
against a single string?

--------------------------

Over in Ironic, we need a more flexible language for specifying 
root-device hints, and we thought it would be a Good Thing to adopt the 
scheduler filter language used in Nova. There's already a review in 
progress to move that code into oslo.utils 
(https://review.openstack.org/#/c/308398) and another to clean it up 
with a well-defined formal grammar 
(https://review.openstack.org/#/c/313699/), so this ought to be an easy 
win. But! We're not sure that we've correctly understood the semantics 
of the language, which in turn means we can't tell if it's suitable for 
our use.

Here are two representative tests for the <all-in> operator:

     def test_extra_specs_matches_one_with_op_allin(self):
         values = ['aes', 'mmx', 'aux']
         self._do_extra_specs_ops_test(
             value=str(values),
             req='<all-in> aes mmx',
             matches=True)

     def test_extra_specs_fails_with_op_allin(self):
         values = ['aes', 'mmx', 'aux']
         self._do_extra_specs_ops_test(
             value=str(values),
             req='<all-in>  txt',
             matches=False)

So it looks like <all-in> takes a list of strings, and matches against a 
`value` which is also a list of strings, and returns True iff every 
argument is in `value`. But look closer. Those tests actually check 
matching against str(values), which is the literal string "['aes', 
'mmx', 'aux']". This is also a valid Python collection, to which the 
Python `in` operator applies just fine, so what these tests actually 
check is if every argument string is a *substring* of str(values). This 
means that the following test passes:

     def test_extra_specs_matches_all_with_op_allin(self):
         values = ['aes', 'mmx', 'aux']
         self._do_extra_specs_ops_test(
             value=str(values),
             req='<all-in> e',
             matches=True)

[Don't believe me? See https://review.openstack.org/#/c/336094]

Is this the intended behaviour? When this is called as part of a real 
scheduler filter, is the list of values stringified before matching like 
this?

Further evidence that this isn't the intended behaviour: if you remove 
all the calls to str(), then the original tests still pass, but the 
'<all-in> e' (substring matching) one doesn't.

So, is <all-in> meant to be doing substring matching? Or are the tests 
in error?

Thanks!
Miles



More information about the OpenStack-dev mailing list