Fix usage of iterator/list on Python 3
* CombinationEvaluator: convert states (built using zip) to a list because states is consumed more than once. On Python 3, zip() returns an iterator which can only be consumed once. * Replace dict.keys()[0] with list(dict.keys())[0]. On Python 3, keys() returns an iterator which is not indexable. * test_event_scenarios: replace filter() with a list-comprehension, the test expects a list whereas filter() returns on iterator on Python 3. * mongo/utils.py: replace obj.keys()[0] with list(obj.keys())[0], and replace obj.values()[0] with list(obj.values())[0] * Add the following API v2 tests to tox.ini in Python 3.4: - test_event_scenarios.TestEventAPI.test_get_events_filter_datetime_trait Change-Id: I28bcb65940edbc226c8dbb272f4e3c040ebc37a1
This commit is contained in:
parent
5213933b5f
commit
86ffa59c73
@ -16,9 +16,8 @@
|
||||
# under the License.
|
||||
|
||||
|
||||
from six import moves
|
||||
|
||||
from oslo_log import log
|
||||
from six import moves
|
||||
|
||||
from ceilometer.alarm import evaluator
|
||||
from ceilometer.i18n import _
|
||||
@ -108,6 +107,8 @@ class CombinationEvaluator(evaluator.Evaluator):
|
||||
|
||||
states = zip(alarm.rule['alarm_ids'],
|
||||
moves.map(self._get_alarm_state, alarm.rule['alarm_ids']))
|
||||
# states is consumed more than once, we need a list
|
||||
states = list(states)
|
||||
|
||||
if self._sufficient_states(alarm, states):
|
||||
self._transition(alarm, states)
|
||||
|
@ -289,8 +289,8 @@ class QueryTransformer(object):
|
||||
orderby_filter = []
|
||||
|
||||
for field in orderby:
|
||||
field_name = field.keys()[0]
|
||||
ordering = self.ordering_functions[field.values()[0]]
|
||||
field_name = list(field.keys())[0]
|
||||
ordering = self.ordering_functions[list(field.values())[0]]
|
||||
orderby_filter.append((field_name, ordering))
|
||||
return orderby_filter
|
||||
|
||||
@ -312,12 +312,12 @@ class QueryTransformer(object):
|
||||
del tree["not"]
|
||||
|
||||
def transform(subtree):
|
||||
op = subtree.keys()[0]
|
||||
op = list(subtree.keys())[0]
|
||||
if op in ["and", "or"]:
|
||||
[transform(child) for child in subtree[op]]
|
||||
elif op == "not":
|
||||
negated_tree = subtree[op]
|
||||
negated_op = negated_tree.keys()[0]
|
||||
negated_op = list(negated_tree.keys())[0]
|
||||
if negated_op == "and":
|
||||
_apply_de_morgan(subtree, negated_tree, negated_op)
|
||||
transform(subtree)
|
||||
@ -326,7 +326,8 @@ class QueryTransformer(object):
|
||||
transform(subtree)
|
||||
elif negated_op == "not":
|
||||
# two consecutive not annihilates themselves
|
||||
new_op = negated_tree.values()[0].keys()[0]
|
||||
value = list(negated_tree.values())[0]
|
||||
new_op = list(value.keys())[0]
|
||||
subtree[new_op] = negated_tree[negated_op][new_op]
|
||||
del subtree["not"]
|
||||
transform(subtree)
|
||||
@ -352,8 +353,8 @@ class QueryTransformer(object):
|
||||
def _handle_not_op(self, negated_tree):
|
||||
# assumes that not is moved to the leaf already
|
||||
# so we are next to a leaf
|
||||
negated_op = negated_tree.keys()[0]
|
||||
negated_field = negated_tree[negated_op].keys()[0]
|
||||
negated_op = list(negated_tree.keys())[0]
|
||||
negated_field = list(negated_tree[negated_op].keys())[0]
|
||||
value = negated_tree[negated_op][negated_field]
|
||||
if negated_op == "=":
|
||||
return {negated_field: {"$ne": value}}
|
||||
@ -364,8 +365,8 @@ class QueryTransformer(object):
|
||||
{self.operators[negated_op]: value}}}
|
||||
|
||||
def _handle_simple_op(self, simple_op, nodes):
|
||||
field_name = nodes.keys()[0]
|
||||
field_value = nodes.values()[0]
|
||||
field_name = list(nodes.keys())[0]
|
||||
field_value = list(nodes.values())[0]
|
||||
|
||||
# no operator for equal in Mongo
|
||||
if simple_op == "=":
|
||||
@ -377,8 +378,8 @@ class QueryTransformer(object):
|
||||
return op
|
||||
|
||||
def _process_json_tree(self, condition_tree):
|
||||
operator_node = condition_tree.keys()[0]
|
||||
nodes = condition_tree.values()[0]
|
||||
operator_node = list(condition_tree.keys())[0]
|
||||
nodes = list(condition_tree.values())[0]
|
||||
|
||||
if operator_node in self.complex_operators:
|
||||
return self._handle_complex_op(operator_node, nodes)
|
||||
|
@ -102,14 +102,14 @@ class TestComplexQuery(base.BaseTestCase):
|
||||
filter_expr = {"AND": [{"=": {"project_id": 42}},
|
||||
{"=": {"project_id": 44}}]}
|
||||
self.query._convert_operator_to_lower_case(filter_expr)
|
||||
self.assertEqual("and", filter_expr.keys()[0])
|
||||
self.assertEqual("and", list(filter_expr.keys())[0])
|
||||
|
||||
filter_expr = {"Or": [{"=": {"project_id": 43}},
|
||||
{"anD": [{"=": {"project_id": 44}},
|
||||
{"=": {"project_id": 42}}]}]}
|
||||
self.query._convert_operator_to_lower_case(filter_expr)
|
||||
self.assertEqual("or", filter_expr.keys()[0])
|
||||
self.assertEqual("and", filter_expr["or"][1].keys()[0])
|
||||
self.assertEqual("or", list(filter_expr.keys())[0])
|
||||
self.assertEqual("and", list(filter_expr["or"][1].keys())[0])
|
||||
|
||||
def test_invalid_filter_misstyped_field_name_samples(self):
|
||||
filter = {"=": {"project_id11": 42}}
|
||||
|
@ -223,7 +223,7 @@ class TestEventAPI(EventTestBase):
|
||||
self.assertEqual(1, len(data))
|
||||
self.assertEqual('Bar', data[0]['event_type'])
|
||||
|
||||
traits = filter(lambda x: x['name'] == 'trait_B', data[0]['traits'])
|
||||
traits = [x for x in data[0]['traits'] if x['name'] == 'trait_B']
|
||||
self.assertEqual(1, len(traits))
|
||||
self.assertEqual('integer', traits[0]['type'])
|
||||
self.assertEqual('101', traits[0]['value'])
|
||||
@ -236,7 +236,7 @@ class TestEventAPI(EventTestBase):
|
||||
self.assertEqual(1, len(data))
|
||||
self.assertEqual('Zoo', data[0]['event_type'])
|
||||
|
||||
traits = filter(lambda x: x['name'] == 'trait_C', data[0]['traits'])
|
||||
traits = [x for x in data[0]['traits'] if x['name'] == 'trait_C']
|
||||
self.assertEqual(1, len(traits))
|
||||
self.assertEqual('float', traits[0]['type'])
|
||||
self.assertEqual('200.123456', traits[0]['value'])
|
||||
@ -247,7 +247,7 @@ class TestEventAPI(EventTestBase):
|
||||
'value': '2014-01-01T05:00:00',
|
||||
'type': 'datetime'}])
|
||||
self.assertEqual(1, len(data))
|
||||
traits = filter(lambda x: x['name'] == 'trait_D', data[0]['traits'])
|
||||
traits = [x for x in data[0]['traits'] if x['name'] == 'trait_D']
|
||||
self.assertEqual(1, len(traits))
|
||||
self.assertEqual('datetime', traits[0]['type'])
|
||||
self.assertEqual('2014-01-01T05:00:00', traits[0]['value'])
|
||||
|
@ -231,7 +231,7 @@ class AggregatorTransformer(ScalingTransformer):
|
||||
self.retention_time))
|
||||
full = self.aggregated_samples >= self.size
|
||||
if full or expired:
|
||||
x = self.samples.values()
|
||||
x = list(self.samples.values())
|
||||
# gauge aggregates need to be averages
|
||||
for s in x:
|
||||
if s.type == sample.TYPE_GAUGE:
|
||||
|
1
tox.ini
1
tox.ini
@ -50,6 +50,7 @@ commands = python -m testtools.run \
|
||||
ceilometer.tests.api.v2.test_alarm_scenarios.TestAlarms.test_alarms_query_with_timestamp \
|
||||
ceilometer.tests.api.v2.test_app \
|
||||
ceilometer.tests.api.v2.test_complex_query_scenarios.TestQueryMetersController.test_query_with_isotime \
|
||||
ceilometer.tests.api.v2.test_event_scenarios.TestEventAPI.test_get_events_filter_datetime_trait \
|
||||
ceilometer.tests.api.v2.test_list_resources_scenarios.TestListResources.test_with_invalid_resource_id \
|
||||
ceilometer.tests.api.v2.test_query \
|
||||
ceilometer.tests.compute.virt.libvirt.test_inspector \
|
||||
|
Loading…
Reference in New Issue
Block a user