84 lines
2.3 KiB
Python
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)])
|