From 0c1d56dde527a5fe7852b502e94f4490dc3614aa Mon Sep 17 00:00:00 2001 From: Christopher Dearborn Date: Wed, 25 Jan 2017 10:47:59 -0500 Subject: [PATCH] WSMAN enumerate fails to return all entries When querying an enumeration using the WSMAN enumerate method, not all entries are returned if there are more than max_elems (default of 100) in the enumeration. When querying an enumeration, the first response returns in the body. Successive pulls, however, contain . The old code always queried for , which caused the first batch of attributes to be dropped only when the number of entries in the enumeration exceeded max_elems. This patch queries for in the first response, and for in successive responses. Change-Id: I2e9036b562c7d7ba5af188dd552b6c67388bb02c Closes-Bug: #1659052 --- dracclient/tests/test_wsman.py | 2 +- .../tests/wsman_mocks/wsman-enum_context-1.xml | 9 ++++++++- .../tests/wsman_mocks/wsman-enum_context-2.xml | 2 +- .../tests/wsman_mocks/wsman-enum_context-3.xml | 4 ++-- .../tests/wsman_mocks/wsman-enum_context-4.xml | 2 +- dracclient/wsman.py | 18 ++++++++++-------- 6 files changed, 23 insertions(+), 14 deletions(-) diff --git a/dracclient/tests/test_wsman.py b/dracclient/tests/test_wsman.py index 09f7701..5f008f9 100644 --- a/dracclient/tests/test_wsman.py +++ b/dracclient/tests/test_wsman.py @@ -68,7 +68,7 @@ class ClientTestCase(base.BaseTest): foo_resource_uri = 'http://FooResource' bar_resource_uri = 'http://BarResource' self.assertEqual( - 3, len(resp_xml.findall('.//{%s}FooResource' % foo_resource_uri))) + 4, len(resp_xml.findall('.//{%s}FooResource' % foo_resource_uri))) self.assertEqual( 1, len(resp_xml.findall('.//{%s}BazResource' % bar_resource_uri))) self.assertEqual( diff --git a/dracclient/tests/wsman_mocks/wsman-enum_context-1.xml b/dracclient/tests/wsman_mocks/wsman-enum_context-1.xml index e9b265b..002cb69 100644 --- a/dracclient/tests/wsman_mocks/wsman-enum_context-1.xml +++ b/dracclient/tests/wsman_mocks/wsman-enum_context-1.xml @@ -1,6 +1,8 @@ + xmlns:wsen="http://schemas.xmlsoap.org/ws/2004/09/enumeration" + xmlns:wsman="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd" + xmlns:n1="http://FooResource"> http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous http://schemas.xmlsoap.org/ws/2004/09/enumeration/EnumerateResponse @@ -10,6 +12,11 @@ enum-context-uuid + + + 1 + + diff --git a/dracclient/tests/wsman_mocks/wsman-enum_context-2.xml b/dracclient/tests/wsman_mocks/wsman-enum_context-2.xml index cab5e11..a2ae36c 100644 --- a/dracclient/tests/wsman_mocks/wsman-enum_context-2.xml +++ b/dracclient/tests/wsman_mocks/wsman-enum_context-2.xml @@ -14,7 +14,7 @@ enum-context-uuid - 1 + 2 diff --git a/dracclient/tests/wsman_mocks/wsman-enum_context-3.xml b/dracclient/tests/wsman_mocks/wsman-enum_context-3.xml index 38190c7..1516a9a 100644 --- a/dracclient/tests/wsman_mocks/wsman-enum_context-3.xml +++ b/dracclient/tests/wsman_mocks/wsman-enum_context-3.xml @@ -13,10 +13,10 @@ enum-context-uuid - 2 + 3 - 3 + 4 diff --git a/dracclient/tests/wsman_mocks/wsman-enum_context-4.xml b/dracclient/tests/wsman_mocks/wsman-enum_context-4.xml index 15e0490..81ddbf5 100644 --- a/dracclient/tests/wsman_mocks/wsman-enum_context-4.xml +++ b/dracclient/tests/wsman_mocks/wsman-enum_context-4.xml @@ -12,7 +12,7 @@ - 4 + 5 diff --git a/dracclient/wsman.py b/dracclient/wsman.py index 737df72..cd94f02 100644 --- a/dracclient/wsman.py +++ b/dracclient/wsman.py @@ -105,21 +105,23 @@ class Client(object): resp_xml = ElementTree.fromstring(resp.content) if auto_pull: - find_items_query = './/{%s}Items' % NS_WSMAN_ENUM + # The first response returns "" + find_items_wsman_query = './/{%s}Items' % NS_WSMAN + + # Successive pulls return "" + find_items_enum_query = './/{%s}Items' % NS_WSMAN_ENUM + full_resp_xml = resp_xml + items_xml = full_resp_xml.find(find_items_wsman_query) context = self._enum_context(full_resp_xml) while context is not None: resp_xml = self.pull(resource_uri, context, max_elems) context = self._enum_context(resp_xml) - items_xml = full_resp_xml.find(find_items_query) - if items_xml is not None: - # merge enumeration items - for item in resp_xml.find(find_items_query): - items_xml.append(item) - else: - full_resp_xml = resp_xml + # Merge in next batch of enumeration items + for item in resp_xml.find(find_items_enum_query): + items_xml.append(item) # remove enumeration context because items are already merged enum_context_elem = full_resp_xml.find('.//{%s}EnumerationContext'