Debugged extra_specs_ops.py

The current extra_specs_ops.py under nova/scheduler/filters has a bug:
it crahses if <or> is not followed by a word. For example, if
"<or> gpu <or>" is given in extra_specs, current code tries to pop a
word after the second <or> that causes a crash. This patch lets it
ignore the "<or>" keyword if no word follows the second "<or>" keyword.

Debugged bug 1038979

Change-Id: I80a6eafd7ee57a2f3ccbf2fb869655ab84e92cf2
This commit is contained in:
Jinwoo 'Joseph' Suh 2012-08-20 07:43:21 -04:00
parent 0272c063bb
commit ada550098a
2 changed files with 28 additions and 2 deletions

View File

@ -18,7 +18,7 @@ import operator
# 1. The following operations are supported:
# =, s==, s!=, s>=, s>, s<=, s<, <in>, <or>, ==, !=, >=, <=
# 2. Note that <or> is handled in a different way below.
# 3. If the first word in the capability is not one of the operators,
# 3. If the first word in the extra_specs is not one of the operators,
# it is ignored.
_op_methods = {'=': lambda x, y: float(x) >= float(y),
'<in>': lambda x, y: y in x,
@ -54,7 +54,9 @@ def match(value, req):
return True
if not words:
break
op = words.pop(0)
op = words.pop(0) # remove a keyword <or>
if not words:
break
return False
if words and method(value, words[0]):

View File

@ -670,24 +670,48 @@ class HostFiltersTestCase(test.TestCase):
especs={'opt1': '<in> 12311321'},
passes=True)
def test_compute_filter_passes_extra_specs_with_op_in3(self):
self._do_test_compute_filter_extra_specs(
ecaps={'opt1': '12311321'},
especs={'opt1': '<in> 12311321 <in>'},
passes=True)
def test_compute_filter_fails_extra_specs_with_op_in(self):
self._do_test_compute_filter_extra_specs(
ecaps={'opt1': '12310321'},
especs={'opt1': '<in> 11'},
passes=False)
def test_compute_filter_fails_extra_specs_with_op_in2(self):
self._do_test_compute_filter_extra_specs(
ecaps={'opt1': '12310321'},
especs={'opt1': '<in> 11 <in>'},
passes=False)
def test_compute_filter_passes_extra_specs_with_op_or(self):
self._do_test_compute_filter_extra_specs(
ecaps={'opt1': '12'},
especs={'opt1': '<or> 11 <or> 12'},
passes=True)
def test_compute_filter_passes_extra_specs_with_op_or2(self):
self._do_test_compute_filter_extra_specs(
ecaps={'opt1': '12'},
especs={'opt1': '<or> 11 <or> 12 <or>'},
passes=True)
def test_compute_filter_fails_extra_specs_with_op_or(self):
self._do_test_compute_filter_extra_specs(
ecaps={'opt1': '13'},
especs={'opt1': '<or> 11 <or> 12'},
passes=False)
def test_compute_filter_fails_extra_specs_with_op_or2(self):
self._do_test_compute_filter_extra_specs(
ecaps={'opt1': '13'},
especs={'opt1': '<or> 11 <or> 12 <or>'},
passes=False)
def test_compute_filter_passes_extra_specs_with_op_le(self):
self._do_test_compute_filter_extra_specs(
ecaps={'opt1': 2, 'opt2': 2},