From ada550098ac874cdd3ca7c6637421edf6c7f7163 Mon Sep 17 00:00:00 2001 From: Jinwoo 'Joseph' Suh Date: Mon, 20 Aug 2012 07:43:21 -0400 Subject: [PATCH] Debugged extra_specs_ops.py The current extra_specs_ops.py under nova/scheduler/filters has a bug: it crahses if is not followed by a word. For example, if " gpu " is given in extra_specs, current code tries to pop a word after the second that causes a crash. This patch lets it ignore the "" keyword if no word follows the second "" keyword. Debugged bug 1038979 Change-Id: I80a6eafd7ee57a2f3ccbf2fb869655ab84e92cf2 --- nova/scheduler/filters/extra_specs_ops.py | 6 ++++-- nova/tests/scheduler/test_host_filters.py | 24 +++++++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/nova/scheduler/filters/extra_specs_ops.py b/nova/scheduler/filters/extra_specs_ops.py index 3720a2c9e6f0..c77cd7b60ec9 100644 --- a/nova/scheduler/filters/extra_specs_ops.py +++ b/nova/scheduler/filters/extra_specs_ops.py @@ -18,7 +18,7 @@ import operator # 1. The following operations are supported: # =, s==, s!=, s>=, s>, s<=, s<, , , ==, !=, >=, <= # 2. Note that 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), '': 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 + if not words: + break return False if words and method(value, words[0]): diff --git a/nova/tests/scheduler/test_host_filters.py b/nova/tests/scheduler/test_host_filters.py index d6f0835763f6..9cda0ccde8c6 100644 --- a/nova/tests/scheduler/test_host_filters.py +++ b/nova/tests/scheduler/test_host_filters.py @@ -670,24 +670,48 @@ class HostFiltersTestCase(test.TestCase): especs={'opt1': ' 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': ' 12311321 '}, + 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': ' 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': ' 11 '}, + 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': ' 11 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': ' 11 12 '}, + 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': ' 11 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': ' 11 12 '}, + 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},