ec2-api/ec2api/tests/tools.py

84 lines
2.3 KiB
Python

# Copyright 2014
# The Cloudscaling Group, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import copy
import re
from lxml import etree
import mock
from ec2api.api import ec2utils
def update_dict(dict1, dict2):
"""Get a copy of union of two dicts."""
res = copy.deepcopy(dict1)
res.update(dict2)
return res
def purge_dict(dict1, trash_keys):
"""Get a copy of dict, removed keys."""
res = copy.deepcopy(dict1)
for key in trash_keys:
res.pop(key, None)
return res
def patch_dict(dict1, dict2, trash_iter):
"""Get a copy of union of two dicts, removed keys."""
res = update_dict(dict1, dict2)
res = purge_dict(res, trash_iter)
return res
class CopyingMock(mock.MagicMock):
"""Mock class for calls with mutable arguments.
See https://docs.python.org/3/library/unittest.mock-examples.html#
coping-with-mutable-arguments
"""
def __call__(self, *args, **kwargs):
args = copy.deepcopy(args)
kwargs = copy.deepcopy(kwargs)
return super(CopyingMock, self).__call__(*args, **kwargs)
_xml_scheme = re.compile('\sxmlns=".*"')
def parse_xml(xml_string):
xml_string = _xml_scheme.sub('', xml_string)
xml = etree.fromstring(xml_string)
def convert_node(node):
children = list(node)
if len(children):
if children[0].tag == 'item':
val = list(convert_node(child)[1] for child in children)
else:
val = dict(convert_node(child) for child in children)
elif node.tag.endswith('Set'):
val = []
else:
# TODO(ft): do not use private function
val = (ec2utils._try_convert(node.text)
if node.text
else node.text)
return node.tag, val
return dict([convert_node(xml)])